def service_connection_handler(sock, client_addr, header): """ Process incoming service connection. For use with TCPROSServer. Reads in service name from handshake and creates the appropriate service handler for the connection. @param sock: socket connection @type sock: socket @param client_addr: client address @type client_addr: (str, int) @param header: key/value pairs from handshake header @type header: dict @return: error string or None @rtype: str """ for required in ['service', 'md5sum', 'callerid']: if not required in header: return "Missing required '%s' field" % required else: logger.debug("connection from %s:%s", client_addr[0], client_addr[1]) service_name = header['service'] """ check again if the client request is authorized """ auth_logger.info( "received service connection for %s from %s (%s:%s)" % (service_name, header["callerid"], client_addr[0], client_addr[1])) client_ip_address = client_addr[0] if not is_requester_authorized(service_name, client_ip_address): auth_logger.warn( "service connection for %s from %s (%s) not authorized" % (service_name, header["callerid"], client_ip_address)) return "Client [%s] wants service connection for %s, but %s is not authorized" % ( header['callerid'], service_name, client_ip_address) auth_logger.info("service connection for %s from %s (%s) OK" % (service_name, header["callerid"], client_ip_address)) #TODO: make service manager configurable. I think the right #thing to do is to make these singletons private members of a #Node instance and enable rospy to have multiple node #instances. sm = get_service_manager() md5sum = header['md5sum'] service = sm.get_service(service_name) if not service: return "[%s] is not a provider of [%s]" % ( rospy.names.get_caller_id(), service_name) elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum: return "request from [%s]: md5sums do not match: [%s] vs. [%s]" % ( header['callerid'], md5sum, service.service_class._md5sum) else: transport = TCPROSTransport(service.protocol, service_name, header=header) transport.set_socket(sock, header['callerid']) transport.write_header() # using threadpool reduced performance by an order of # magnitude, need to investigate better t = threading.Thread(target=service.handle, args=(transport, header)) t.setDaemon(True) t.start()
def inbound_handler(sock, addr): print "%s connected." % (str(addr)) t = TCPROSTransport(TestServerProtocol(), "testservice") t.set_socket(sock, "client") t.write_header() t.read_header() inputs.append(sock)
def service_connection_handler(sock, client_addr, header): """ Process incoming service connection. For use with TCPROSServer. Reads in service name from handshake and creates the appropriate service handler for the connection. @param sock: socket connection @type sock: socket @param client_addr: client address @type client_addr: (str, int) @param header: key/value pairs from handshake header @type header: dict @return: error string or None @rtype: str """ for required in ['service', 'md5sum', 'callerid']: if not required in header: return "Missing required '%s' field"%required else: logger.debug("connection from %s:%s", client_addr[0], client_addr[1]) service_name = header['service'] #TODO: make service manager configurable. I think the right #thing to do is to make these singletons private members of a #Node instance and enable rospy to have multiple node #instances. sm = get_service_manager() md5sum = header['md5sum'] service = sm.get_service(service_name) if not service: return "[%s] is not a provider of [%s]"%(rospy.names.get_caller_id(), service_name) elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum: return "request from [%s]: md5sums do not match: [%s] vs. [%s]"%(header['callerid'], md5sum, service.service_class._md5sum) else: transport = TCPROSTransport(service.protocol, service_name, header=header) transport.set_socket(sock, header['callerid']) transport.write_header() # using threadpool reduced performance by an order of # magnitude, need to investigate better t = threading.Thread(target=service.handle, args=(transport, header)) t.setDaemon(True) t.start()
def service_connection_handler(self, sock, client_addr, header): """ @param sock: socket connection @type sock: socket @param client_addr: client address @type client_addr: (str, int) @param header: key/value pairs from handshake header @type header: dict @return: error string or None @rtype: str """ # This is a cturtle hack. rospy's service_connection_handler # is wired to the ServiceManager singleton. If we replace the # singleton with something more configurable, then we simply # have to run our own ServiceManager to handle the forwarding # behavior. for required in ['service', 'md5sum', 'callerid']: if not required in header: return "Missing required '%s' field" % required else: #logger.debug("connection from %s:%s", client_addr[0], client_addr[1]) service_name = header['service'] sm = self.service_manager md5sum = header['md5sum'] service = sm.get_service(service_name) if not service: return "[%s] is not a provider of [%s]" % ( rospy.names.get_caller_id(), service_name) elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum: return "request from [%s]: md5sums do not match: [%s] vs. [%s]" % ( header['callerid'], md5sum, service.service_class._md5sum) else: transport = TCPROSTransport(service.protocol, service_name, header=header) transport.set_socket(sock, header['callerid']) transport.write_header() thread.start_new_thread(service.handle, (transport, header))
def service_connection_handler(self, sock, client_addr, header): """ @param sock: socket connection @type sock: socket @param client_addr: client address @type client_addr: (str, int) @param header: key/value pairs from handshake header @type header: dict @return: error string or None @rtype: str """ # This is a cturtle hack. rospy's service_connection_handler # is wired to the ServiceManager singleton. If we replace the # singleton with something more configurable, then we simply # have to run our own ServiceManager to handle the forwarding # behavior. for required in ['service', 'md5sum', 'callerid']: if not required in header: return "Missing required '%s' field"%required else: #logger.debug("connection from %s:%s", client_addr[0], client_addr[1]) service_name = header['service'] sm = self.service_manager md5sum = header['md5sum'] service = sm.get_service(service_name) if not service: return "[%s] is not a provider of [%s]"%(rospy.names.get_caller_id(), service_name) elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum: return "request from [%s]: md5sums do not match: [%s] vs. [%s]"%(header['callerid'], md5sum, service.service_class._md5sum) else: transport = TCPROSTransport(service.protocol, service_name, header=header) transport.set_socket(sock, header['callerid']) transport.write_header() thread.start_new_thread(service.handle, (transport, header))