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()
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)
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()
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
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()
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)
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()
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)
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()
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()
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()