diff options
Diffstat (limited to 'pysnmp/carrier/asyncore/base.py')
-rw-r--r-- | pysnmp/carrier/asyncore/base.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/pysnmp/carrier/asyncore/base.py b/pysnmp/carrier/asyncore/base.py new file mode 100644 index 0000000..45e2fb2 --- /dev/null +++ b/pysnmp/carrier/asyncore/base.py @@ -0,0 +1,89 @@ +# Defines standard API to asyncore-based transport +import socket, sys +import asyncore +from pysnmp.carrier import error +from pysnmp.carrier.base import AbstractTransport +from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher +from pysnmp import debug + +class AbstractSocketTransport(asyncore.dispatcher, AbstractTransport): + protoTransportDispatcher = AsyncoreDispatcher + sockFamily = sockType = None + retryCount = 0; retryInterval = 0 + bufferSize = 131070 + def __init__(self, sock=None, sockMap=None): + asyncore.dispatcher.__init__(self) + if sock is None: + if self.sockFamily is None: + raise error.CarrierError( + 'Address family %s not supported' % self.__class__.__name__ + ) + if self.sockType is None: + raise error.CarrierError( + 'Socket type %s not supported' % self.__class__.__name__ + ) + try: + sock = socket.socket(self.sockFamily, self.sockType) + except socket.error: + raise error.CarrierError('socket() failed: %s' % sys.exc_info()[1]) + + try: + for b in socket.SO_RCVBUF, socket.SO_SNDBUF: + bsize = sock.getsockopt(socket.SOL_SOCKET, b) + if bsize < self.bufferSize: + sock.setsockopt(socket.SOL_SOCKET, b, self.bufferSize) + debug.logger & debug.flagIO and debug.logger('%s: socket %d buffer size increased from %d to %d for buffer %d' % (self.__class__.__name__, sock.fileno(), bsize, self.bufferSize, b)) + except Exception: + debug.logger & debug.flagIO and debug.logger('%s: socket buffer size option mangling failure for buffer %d: %s' % (self.__class__.__name__, b, sys.exc_info()[1])) + + # The socket map is managed by the AsyncoreDispatcher on + # which this transport is registered. Here we just prepare + # socket and postpone transport registration at dispatcher + # till AsyncoreDispatcher invokes registerSocket() + + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setblocking(0) + self.set_socket(sock) + + def __hash__(self): return hash(self.socket) + + # The following two methods are part of base class so here we overwrite + # them to separate socket management from dispatcher registration tasks. + # These two are just for dispatcher registration. + def add_channel(self, map=None): + if map is not None: + map[self._fileno] = self + self.connected = True + + def del_channel(self, map=None): + if map is not None and self._fileno in map: + del map[self._fileno] + self.connected = False + + def registerSocket(self, sockMap=None): + self.add_channel(sockMap) + + def unregisterSocket(self, sockMap=None): + self.del_channel(sockMap) + + # Public API + + def openClientMode(self, iface=None): + raise error.CarrierError('Method not implemented') + + def openServerMode(self, iface=None): + raise error.CarrierError('Method not implemented') + + def sendMessage(self, outgoingMessage, transportAddress): + raise error.CarrierError('Method not implemented') + + def closeTransport(self): + AbstractTransport.closeTransport(self) + self.close() + + # asyncore API + def handle_close(self): raise error.CarrierError( + 'Transport unexpectedly closed' + ) + def handle_error(self): raise + |