Example #1
0
 def __init__(self,
              port=0,
              router=None,
              interface='',
              logger_name='tcp',
              recv_buffer=5000,
              queue_length=0,
              loglevel='info'):
     '''
     :param int port: the port to bind the socket. If zero an empty one will be used.
     :param router: class which provides `route_tcp_msg(fkie_iop_node_manager.message.Message)` method. If `None` receive will be disabled.
     :param str interface: The interface to bind to. If empty, it binds to all interfaces
     '''
     self._closed = False
     self._lock = threading.RLock()
     self.logger = NMLogger('%s[%s:%d]' % (logger_name, interface, port),
                            loglevel)
     self.interface = interface
     self.port = port
     self._router = router
     self._recv_buffer = recv_buffer
     self._queue_length = queue_length
     self._socket_type = socket.AF_INET
     bind_ip = self.interface
     if self.interface:
         addrinfo = getaddrinfo(self.interface)
         self._socket_type = addrinfo[0]
         bind_ip = addrinfo[4][0]
     socket.socket.__init__(self, self._socket_type, socket.SOCK_STREAM)
     self._address = (bind_ip, self.port)
     self._message_parser = {}
     self._clients = {}
     self._thread_bind = threading.Thread(target=self._bind_with_retry)
     self._thread_bind.start()
Example #2
0
 def __init__(self,
              name,
              remove_on_close=False,
              force_bind=False,
              root_path='/tmp',
              recv_buffer=5000,
              loglevel='info'):
     self._closed = False
     self.logger = NMLogger('uds[%s]' % name, loglevel)
     self._remove_on_close = remove_on_close
     self._recv_buffer = recv_buffer
     socket.socket.__init__(self, socket.AF_UNIX, socket.SOCK_DGRAM)
     self.setblocking(True)
     self._socket_path = os.path.join(root_path, name)
     self._parser = MessageParser(AddressBook.Endpoint(
         AddressBook.Endpoint.UDS, self._socket_path),
                                  loglevel=loglevel)
     if os.path.exists(self._socket_path) and not force_bind:
         self.logger.debug("Connect to local socket %s" % self._socket_path)
         self.connect(self._socket_path)
     else:
         self.logger.debug("Create local socket connection %s" %
                           self._socket_path)
         if os.path.exists(self._socket_path):
             os.unlink(self._socket_path)
         self.bind(self._socket_path)
         os.chmod(self._socket_path,
                  stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
Example #3
0
 def __init__(self, host='', port=0, router=None, interface='', logger_name='tcp_client', recv_buffer=5000, queue_length=0, loglevel='info'):
     '''
     :param str host: destination host.
     :param int port: destination port.
     :param router: class which provides `route_tcp_msg(fkie_iop_node_manager.message.Message)` method. If `None` receive will be disabled.
     '''
     self._closed = False
     self._connected = False
     self._connection_error_printed = False
     self.logger = NMLogger('%s[%s:%d]' % (logger_name, host, port), loglevel)
     self._router = router
     self._recv_buffer = recv_buffer
     self._queue_length = queue_length
     self._socket_type = socket.AF_INET
     self._queue_send = queue.PQueue(queue_length, 'queue_%s_send_%s:%d' % (logger_name, host, port), loglevel=loglevel)
     self._raddr = (host, port)
     self.interface = interface
     self._first_send_msg = True
     if self.interface:
         addrinfo = getaddrinfo(self.interface)
         self._socket_type = addrinfo[0]
     self._endpoint_client = AddressBook.Endpoint(AddressBook.Endpoint.TCP, host, port)
     self._message_parser = MessageParser(self._endpoint_client, stream=True, loglevel=loglevel)
     self._thread_connect = threading.Thread(target=self._connect, args=(self._raddr,))
     self._thread_connect.start()
     self._thread_send = threading.Thread(target=self._loop_send)
     self._thread_send.start()
Example #4
0
 def __init__(self, sender, stream=False, loglevel='info'):
     '''
     :param AddressBook.Endpoint sender: the socket where the packed was received or the sender.
     :param bool stream: if stream is `True` received data will be concatenated. In this case the message version byte will be checked only in first message.
     '''
     self._sender = sender
     self._version_only_first = stream
     self._stream = stream
     name = sender
     if name is not None:
         name = sender.address.replace('.', '_')
     self.logger = NMLogger('msg[%s]' % name, loglevel)
     self._data = b''
     self._version = None
Example #5
0
 def __init__(self, cfg_file, version='', params={}):
     self.cfg = Config(cfg_file, version, params)
     loglevel = self.cfg.param('global/loglevel', 'info')
     self.logger = NMLogger('server', loglevel)
     self.cfg.init_cfgif()
     self._stop = False
     default_port = self.cfg.param('transport/udp/port', 3794)
     addrbook_udp = self.cfg.param('addrbook/udp', {})
     addrbook_tcp = self.cfg.param('addrbook/tcp', {})
     self.addrbook = AddressBook(default_port=default_port, addrbook_udp=addrbook_udp, addrbook_tcp=addrbook_tcp, loglevel=loglevel)
     self.statistics = Collector(self.cfg)
     self._local_mngr = None
     self._udp = None
     self._tcp_server = None
     self._lock = threading.RLock()
Example #6
0
 def __init__(self,
              default_port=3794,
              addrbook_udp={},
              addrbook_tcp={},
              loglevel='info'):
     '''
     :param fkie_iop_node_manager.config.Config cfg: configuration
     '''
     self.logger = NMLogger('addrbook', loglevel)
     self._default_port = default_port
     self._map = {}
     self._static_tcp_port_map = {}
     self._static_udp = self._read_static_addr(addrbook_udp,
                                               AddressBook.Endpoint.UDP)
     self._static_tcp = self._read_static_addr(addrbook_tcp,
                                               AddressBook.Endpoint.TCP)
     self.logger.debug('AddressBook initialized with %s' % self)
Example #7
0
 def __init__(self,
              connection,
              router=None,
              logger_name='tcp_input',
              recv_buffer=5000,
              queue_length=0,
              close_callback=None,
              loglevel='info'):
     '''
     :param (str,int) connection: client address.
     :param router: class which provides `route_tcp_msg(fkie_iop_node_manager.message.Message)` method. If `None` receive will be disabled.
     '''
     self._closed = False
     self._send_error_printed = False
     self._connection = connection
     self._raddr = connection.getpeername()
     self.logger = NMLogger(
         '%s[%s:%d]' % (logger_name, self._raddr[0], self._raddr[1]),
         loglevel)
     self._router = router
     self._recv_buffer = recv_buffer
     self._queue_length = queue_length
     self._close_callback = close_callback
     self._first_send_msg = True
     self._queue_send = queue.PQueue(
         queue_length,
         'queue_%s_send_%s:%d' %
         (logger_name, self._raddr[0], self._raddr[1]),
         loglevel=loglevel)
     self._endpoint_client = AddressBook.Endpoint(AddressBook.Endpoint.TCP,
                                                  self._raddr[0],
                                                  self._raddr[1])
     self._message_parser = MessageParser(self._endpoint_client,
                                          stream=True,
                                          loglevel=loglevel)
     self._thread_send = threading.Thread(target=self._loop_send)
     self._thread_send.start()
     if self._router is not None:
         self._thread_recv = threading.Thread(target=self._loop_recv)
         self._thread_recv.start()
Example #8
0
 def __init__(self, filename='', version='', params={}):
     self._stop = False
     self._mutex = threading.RLock()
     self.version = version
     self.filename = filename
     if not self.filename:
         self.filename = os.path.expanduser('~/.config/iop.fkie/iop_node_manager.yaml')
     cfg_path = os.path.dirname(self.filename)
     if not os.path.isdir(cfg_path):
         os.makedirs(cfg_path)
     self._reload_callbacks = []
     self._param_callbacks = {}
     self._cfg = None
     self.logger = NMLogger('config')
     self.reload()
     NMLogger.setall_loglevel(self.param('global/loglevel', 'info'))
     self.apply(params, save=False)
     self.msg_ids = {}  # (int)id: (str)Name
     self._read_msg_ids()
     self._cfgif = None
     self._cfgif_address = None
     self.add_param_listener('global/loglevel', self._callback_change_loglevel)
Example #9
0
 def __init__(self, router, cfg, addrbook, statistics):
     self._stop = False
     self._cfg = cfg
     self._addrbook = addrbook
     self._statistics = statistics
     loglevel = self._cfg.param('global/loglevel', 'info')
     self.logger = NMLogger('uds_server', loglevel)
     override_priority = cfg.param('priority/override', True)
     ormap = cfg.param('priority/map', {})
     self._priority_map = {}
     if override_priority:
         # create overide map
         try:
             for msg_id, prio in ormap.items():
                 try:
                     msgid = int(msg_id, 16)
                     self.logger.info("Override priority for 0x%.4X to %d" %
                                      (msgid, prio))
                     if prio >= 0 and prio <= 3:
                         self._priority_map[msgid] = prio
                     else:
                         self.logger.warning(
                             "Ignored invalid priority for %s: %d" %
                             (msg_id, prio))
                 except ValueError as ve:
                     self.logger.warning(
                         "Ignored invalid message id %s: %s" % (msg_id, ve))
         except Exception as err:
             import traceback
             print(traceback.format_exc())
             self.logger.warning("Can not read priority override map: %s" %
                                 err)
     self._local_sockets = {}
     self._recv_buffer = cfg.RECV_BUFFER
     self._root_path = cfg.param('transport/local/root', '/tmp')
     self._socket_path_server = os.path.join(
         self._root_path, cfg.param('transport/local/nm_path'))
     self.logger.info("Listen for local connections @%s" %
                      (self._socket_path_server))
     if os.path.exists(self._socket_path_server):
         os.unlink(self._socket_path_server)
     self._local_socket = UDSSocket(cfg.param('transport/local/nm_path'),
                                    remove_on_close=True,
                                    force_bind=True,
                                    root_path=self._root_path,
                                    loglevel=self._cfg.param(
                                        'global/loglevel', 'info'))
     self._udp_looback = None
     self._udp_looback_dest = None
     if cfg.param('transport/loopback_debug/enable', False):
         self._init_loopback()
     # Listen for incoming connections
     self._router = router
     self._queue_send = queue.PQueue(cfg.param(
         'transport/local/queue_length', 0),
                                     'queue_uds_send',
                                     loglevel=loglevel)
     self._thread_send = threading.Thread(
         target=self._loop_handle_send_queue)
     self._thread_send.start()
     self._thread_recv = threading.Thread(
         target=self._loop_recv_local_socket)
     self._thread_recv.start()
Example #10
0
    def __init__(self,
                 port,
                 mgroup,
                 router=None,
                 ttl=16,
                 interface='',
                 logger_name='udp_mc',
                 send_buffer=0,
                 recv_buffer=0,
                 queue_length=0,
                 loglevel='info'):
        '''
        Creates a socket, bind it to a given port and join to a given multicast
        group. IPv4 and IPv6 are supported.

        :param int port: the port to bind the socket
        :param str mgroup: the multicast group to join
        :param router: class which provides `route_udp_msg(fkie_iop_node_manager.message.Message)` method. If `None` receive will be disabled.
        :param type: fkie_iop_node_manager.queue
        :param int ttl: time to leave (Default: 20)
        :param str interface: IP of interface to bind (Default: '').
        '''
        self.logger = NMLogger(
            '%s[%s:%d]' % (logger_name, mgroup.replace('.', '_'), port),
            loglevel)
        self.port = port
        self.mgroup = mgroup
        self._lock = threading.RLock()
        self._closed = False
        self._recv_buffer = recv_buffer
        self._locals = [ip for _ifname, ip in localifs()]
        self._locals.append('localhost')
        self._sender_endpoints = {}
        self.sock_5_error_printed = []
        self.SOKET_ERRORS_NEEDS_RECONNECT = False
        self.interface = interface
        # get the AF_INET information for group to ensure that the address family
        # of group is the same as for interface
        addrinfo = getaddrinfo(self.mgroup)
        self.interface_ip = ''
        if self.interface:
            addrinfo = getaddrinfo(self.interface, addrinfo[0])
            if addrinfo is not None:
                self.interface_ip = addrinfo[4][0]
        self.logger.debug("destination: %s" % self.mgroup)
        self.logger.debug("interface : %s (detected ip: %s)" %
                          (self.interface, self.interface_ip))
        self.logger.debug("inet: %s" % str(addrinfo))

        socket.socket.__init__(self, addrinfo[0], socket.SOCK_DGRAM,
                               socket.IPPROTO_UDP)
        self.logger.info("Create multicast socket @('%s', %d)" %
                         (self.mgroup, port))
        # initialize multicast socket
        # Allow multiple copies of this program on one machine
        if hasattr(socket, "SO_REUSEPORT"):
            try:
                self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
            except Exception:
                self.logger.warning(
                    "SO_REUSEPORT failed: Protocol not available, some functions are not available."
                )
        # Set Time-to-live (optional) and loop count
        ttl_bin = struct.pack('@i', ttl)
        if addrinfo[0] == socket.AF_INET:  # IPv4
            self.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL,
                            ttl_bin)
            self.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
        else:  # IPv6
            self.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS,
                            ttl_bin)
            self.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)

        try:
            if addrinfo[0] == socket.AF_INET:  # IPv4
                # Create group_bin for de-register later
                # Set socket options for multicast specific interface or general
                if not self.interface_ip:
                    self.group_bin = socket.inet_pton(
                        socket.AF_INET, self.mgroup) + struct.pack(
                            '=I', socket.INADDR_ANY)
                    self.setsockopt(socket.IPPROTO_IP,
                                    socket.IP_ADD_MEMBERSHIP, self.group_bin)
                else:
                    self.group_bin = socket.inet_aton(
                        self.mgroup) + socket.inet_aton(self.interface_ip)
                    self.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF,
                                    socket.inet_aton(self.interface_ip))
                    self.setsockopt(socket.IPPROTO_IP,
                                    socket.IP_ADD_MEMBERSHIP, self.group_bin)
            else:  # IPv6
                # Create group_bin for de-register later
                # Set socket options for multicast
                self.group_bin = socket.inet_pton(addrinfo[0],
                                                  self.mgroup) + struct.pack(
                                                      '@I', socket.INADDR_ANY)
                self.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP,
                                self.group_bin)
        except socket.error as errobj:
            msg = str(errobj)
            if errobj.errno in [errno.ENODEV]:
                msg = "socket.error[%d]: %s,\nis multicast route set? e.g. sudo route add -net 224.0.0.0 netmask 224.0.0.0 eth0" % (
                    errobj.errno, msg)
            raise Exception(msg)

        # set buffer size if configured
        if send_buffer:
            old_bufsize = self.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
            if old_bufsize != send_buffer:
                self.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF,
                                send_buffer)
                bufsize = self.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
                self.logger.debug("Changed buffer size from %d to %d" %
                                  (old_bufsize, bufsize))

        # Bind to the port
        try:
            # bind to default interfaces if not unicast socket was created
            self.bind((self.interface_ip, port))
        except socket.error as errobj:
            msg = str(errobj)
            self.logger.critical(
                "Unable to bind multicast to interface: %s, check that it exists: %s"
                % (self.mgroup, msg))
            raise
        self._router = router
        self._queue_send = queue.PQueue(queue_length,
                                        'queue_udp_send',
                                        loglevel=loglevel)
        self._parser_mcast = MessageParser(None, loglevel=loglevel)
        self.addrinfo = addrinfo
        # create a thread to handle the received multicast messages
        if self._router is not None:
            self._thread_recv = threading.Thread(target=self._loop_recv)
            self._thread_recv.start()
        self._thread_send = threading.Thread(target=self._loop_send)
        self._thread_send.start()
Example #11
0
    def __init__(self,
                 port=0,
                 router=None,
                 interface='',
                 logger_name='udp',
                 default_dst=None,
                 send_buffer=0,
                 recv_buffer=0,
                 queue_length=0,
                 loglevel='info'):
        '''
        Creates a socket, bind it to a given interface+port for unicast send/receive.
        IPv4 and IPv6 are supported.

        :param int port: the port to bind the socket. If zero an empty one will be used.
        :param router: class which provides `route_udp_msg(fkie_iop_node_manager.message.Message)` method. If `None` receive will be disabled.
        :param str interface: The interface to bind to. If empty, it binds to all interfaces
        :param tuple(str,int) default_dst: used for loopback to send messages to predefined destination.
        '''
        self._closed = False
        self.logger = NMLogger('%s[%s:%d]' % (logger_name, interface, port),
                               loglevel)
        self.interface = interface
        self.port = port
        self._router = router
        self._default_dst = default_dst
        self._recv_buffer = recv_buffer
        self._sender_endpoints = {}
        self.sock_5_error_printed = []
        # If interface isn't specified, try to find an non localhost interface to
        # get some info for binding. Otherwise use localhost
        # if not self.interface:
        #     ifaces = localifs()
        #     for iface in ifaces:
        #         if not (iface[1].startswith('127') or iface[1].startswith('::1')):
        #             self.interface = iface[1]
        #             break
        self.logger.info("+ Bind to unicast socket @(%s:%s)" %
                         (self.interface, port))
        socket_type = socket.AF_INET
        bind_ip = self.interface
        if self.interface:
            addrinfo = getaddrinfo(self.interface)
            socket_type = addrinfo[0]
            bind_ip = addrinfo[4][0]
            # Configure socket type
        socket.socket.__init__(self, socket_type, socket.SOCK_DGRAM,
                               socket.IPPROTO_UDP)
        # Bind to the port
        try:
            self.logger.debug("Ucast bind to: (%s:%s)" % (bind_ip, port))
            self.bind((bind_ip, port))
        except socket.error as errobj:
            msg = str(errobj)
            self.logger.critical(
                "Unable to bind unicast to interface: %s, check that it exists: %s"
                % (bind_ip, msg))
            raise
        if self.port == 0:
            self.port = self.getsockname()[1]
        if send_buffer:
            # update buffer size
            old_bufsize = self.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
            if old_bufsize != send_buffer:
                self.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF,
                                send_buffer)
                #                self.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, buffersize)
                bufsize = self.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
                self.logger.debug("Changed buffer size from %d to %d" %
                                  (old_bufsize, bufsize))
        self._parser_ucast = MessageParser(None, loglevel=loglevel)
        self._queue_send = queue.PQueue(queue_length,
                                        'queue_%s_send' % logger_name,
                                        loglevel=loglevel)
        # create a thread to handle the received unicast messages
        if self._router is not None:
            self._thread_recv = threading.Thread(target=self._loop_recv)
            self._thread_recv.start()
        self._thread_send = threading.Thread(target=self._loop_send)
        self._thread_send.start()