def post_init(self): # recreate the underlying socket with self.lock: if self._sock is not None: self._sock.close() self._sock = SocketBase(AF_NETLINK, SOCK_DGRAM, self.family, self._fileno) for name in ('getsockname', 'getsockopt', 'makefile', 'setsockopt', 'setblocking', 'settimeout', 'gettimeout', 'shutdown', 'recvfrom', 'recvfrom_into', 'fileno'): setattr(self, name, getattr(self._sock, name)) self._sendto = getattr(self._sock, 'sendto') self._recv = getattr(self._sock, 'recv') self._recv_into = getattr(self._sock, 'recv_into') # setup fast-track self.recv_ft = getattr(self._sock, 'recv') self.sendto_gate = self._gate # monkey patch recv_into on Python 2.6 if sys.version_info[0] == 2 and sys.version_info[1] < 7: # --> monkey patch the socket log.warning('patching socket.recv_into()') def patch(data, bsize): data[0:] = self._sock.recv(bsize) self._sock.recv_into = patch self.setsockopt(SOL_SOCKET, SO_SNDBUF, 32768) self.setsockopt(SOL_SOCKET, SO_RCVBUF, 1024 * 1024)
def post_init(self): # recreate the underlying socket with self.lock: if self._sock is not None: self._sock.close() self._sock = SocketBase(AF_NETLINK, SOCK_DGRAM, self.family, self._fileno) for name in ('getsockname', 'getsockopt', 'makefile', 'setsockopt', 'setblocking', 'settimeout', 'gettimeout', 'shutdown', 'recvfrom', 'recv_into', 'recvfrom_into', 'fileno'): setattr(self, name, getattr(self._sock, name)) self._sendto = getattr(self._sock, 'sendto') self._recv = getattr(self._sock, 'recv') self.setsockopt(SOL_SOCKET, SO_SNDBUF, 32768) self.setsockopt(SOL_SOCKET, SO_RCVBUF, 1024 * 1024)
def post_init(self): # recreate the underlying socket with self.lock: if self._sock is not None: self._sock.close() self._sock = SocketBase(AF_NETLINK, SOCK_DGRAM, self.family, self._fileno) for name in ('getsockname', 'getsockopt', 'makefile', 'setsockopt', 'setblocking', 'settimeout', 'gettimeout', 'shutdown', 'recvfrom', 'recvfrom_into', 'fileno'): setattr(self, name, getattr(self._sock, name)) self._sendto = getattr(self._sock, 'sendto') self._recv = getattr(self._sock, 'recv') self._recv_into = getattr(self._sock, 'recv_into') # setup fast-track self.recv_ft = getattr(self._sock, 'recv') self.sendto_gate = self._gate self.setsockopt(SOL_SOCKET, SO_SNDBUF, 32768) self.setsockopt(SOL_SOCKET, SO_RCVBUF, 1024 * 1024)
class NetlinkSocket(NetlinkMixin): def post_init(self): # recreate the underlying socket with self.lock: if self._sock is not None: self._sock.close() self._sock = SocketBase(AF_NETLINK, SOCK_DGRAM, self.family, self._fileno) for name in ('getsockname', 'getsockopt', 'makefile', 'setsockopt', 'setblocking', 'settimeout', 'gettimeout', 'shutdown', 'recvfrom', 'recvfrom_into', 'fileno'): setattr(self, name, getattr(self._sock, name)) self._sendto = getattr(self._sock, 'sendto') self._recv = getattr(self._sock, 'recv') self._recv_into = getattr(self._sock, 'recv_into') # setup fast-track self.recv_ft = getattr(self._sock, 'recv') self.sendto_gate = self._gate # monkey patch recv_into on Python 2.6 if sys.version_info[0] == 2 and sys.version_info[1] < 7: # --> monkey patch the socket log.warning('patching socket.recv_into()') def patch(data, bsize): data[0:] = self._sock.recv(bsize) self._sock.recv_into = patch self.setsockopt(SOL_SOCKET, SO_SNDBUF, 32768) self.setsockopt(SOL_SOCKET, SO_RCVBUF, 1024 * 1024) def _gate(self, msg, addr): msg.reset() msg.encode() return self._sock.sendto(msg.data, addr) def bind(self, groups=0, pid=None, async=False): ''' Bind the socket to given multicast groups, using given pid. - If pid is None, use automatic port allocation - If pid == 0, use process' pid - If pid == <int>, use the value instead of pid ''' if pid is not None: self.port = 0 self.fixed = True self.pid = pid or os.getpid() self.groups = groups # if we have pre-defined port, use it strictly if self.fixed: self.epid = self.pid + (self.port << 22) self._sock.bind((self.epid, self.groups)) else: for port in range(1024): try: self.port = port self.epid = self.pid + (self.port << 22) self._sock.bind((self.epid, self.groups)) break except Exception: # create a new underlying socket -- on kernel 4 # one failed bind() makes the socket useless self.post_init() else: raise KeyError('no free address available') # all is OK till now, so start async recv, if we need if async: def recv_plugin(*argv, **kwarg): data_in = self.buffer_queue.get() if isinstance(data_in, Exception): raise data_in else: return data_in def recv_into_plugin(data, *argv, **kwarg): data_in = self.buffer_queue.get() if isinstance(data_in, Exception): raise data_in else: data[:] = data_in return len(data_in) self._recv = recv_plugin self._recv_into = recv_into_plugin self.recv_ft = recv_plugin self.pthread = threading.Thread(name="Netlink async cache", target=self.async_recv) self.pthread.setDaemon(True) self.pthread.start()