Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
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()