def send(self): """ This function send the message via the socket. """ if self.__sent_or_received: return #RAISE self.encode_message() # With SIDERUS_DEBUG=1 it will print stuff if os.environ.has_key('SIDERUS_DEBUG') and bool(int(os.environ['SIDERUS_DEBUG'])): sys.stdout.write("S: %s\n" % self.__string_message) self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) destination_dict = from_addr_to_dict(self.destination) pieces = self.__get_list_splitted_message() for pice in pieces: self.socket.sendto( pice, (destination_dict['addr'], destination_dict['port']) ) #Message empty to stop it self.socket.sendto( "", (destination_dict['addr'], destination_dict['port']) ) self.socket.settimeout(DEFAULT_SEND_MESSAGE_TIMEOUT) try: data, addr = self.socket.recvfrom(512) if data != "OK": self.__sent_or_received = False except socket.timeout: raise Exception("MessageTimedOut") self.socket.close() self.socket = None self.__sent_or_received = True
def __return_origin_to_use(self, address): """ This function return the correct origin to use in the message """ port = int(from_addr_to_dict(address)['port']) for network in self.networks: if is_addr_in_network(address, network): addr = self.networks[network]['addr'] return return_daemon_address(addr, port) raise Exception("NoDaemonAddress for '%s'" % address)
def analyze(self, message): """ This function decode and analyze the message. """ message.decode() if message.is_corrupted(): #reply with a new "error" message with the sent message.__hash. return destination = from_addr_to_dict(message.destination) if destination['app'] == "daemon": if is_local_address(message.destination): self.__analyze_message_from_local_app(message) return else: self.__analyze_message_from_remote_app(message) return else: self.__forward_message(message) return
def __forward_message(self, received_message): connection = return_daemon_address_by_giving_address(received_message.origin) if not connection in self.connections: return destination_dict = from_addr_to_dict(received_message.destination) if destination_dict['app'] in self.applications.keys(): destination_dict['port'] = int(self.applications[destination_dict['app']]) else: # If app "installed" but not active: cache the forwarded message! return destination_dict['addr'] = "127.0.0.1" new_destination = from_dict_to_addr(destination_dict) forward = Message() forward.content = received_message.content forward.origin = received_message.origin forward.destination = new_destination #if app is listening then send. Otherwise cache the message. forward.send()
def __analyze_message_from_remote_app(self, message): connection_dict = from_addr_to_dict(message.origin) daemon_address = return_daemon_address(connection_dict['addr'], connection_dict['port']) if message.content['intent'] == DAEMON_NODE_CONN_REQ: if daemon_address in self.connections: return self.connect(daemon_address) self.connections.append(daemon_address) elif message.content['intent'] == DAEMON_NODE_CONN_REF: self.connections.pop(self.connections.index(daemon_address)) elif message.content['intent'] == DAEMON_NODE_CONN_SHR_ASK: self.send_connections(daemon_address) elif message.content['intent'] == DAEMON_NODE_CONN_SHR_ANS: self.__connect_to_nodes(message.content['connections']) elif message.content['intent'] == DAEMON_NODE_CONN_CHK: return # Do Nothing... else: sys.stdout.write("What are you doing? - %s\n" % message.content) return
def __analyze_message_from_local_app(self, message): # Requestes arrived from local applications, es: list connections, connect, disconnect application = from_addr_to_dict(message.origin)['app'] if message.content['intent'] == DAEMON_APP_LCCN_REQ: self.add_application(application) return if not application in self.applications: return if message.content['intent'] == DAEMON_APP_LCCN_REF: self.appliations.pop(application) elif message.content['intent'] == DAEMON_APP_CONN_REQ: self.connect(message.content['node']) elif message.content['intent'] == DAEMON_APP_CONN_REF: self.disconnect(message.content['node']) elif message.content['intent'] == DAEMON_APP_CONN_LST_ASK: self.__send_app_connections(application) elif message.content['intent'] == DAEMON_APP_CONN_SHR_ASK: self.ask_connections(message.content['node']) return
def receive(self): """ This function receive the message via the socket but do not decode it """ if self.__sent_or_received: return port = from_addr_to_dict(self.destination)['port'] self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP cache = "" self.socket.bind(('', port)) #self.socket.listen(1) #second, addr = self.socket.accept() #These function should be executed in a different thread! while True: #data = second.recv(512) data, addrport = self.socket.recvfrom(512) if not data: break cache += data self.socket.sendto("OK", addrport) self.__string_message = cache self.socket.close() self.socket = None