def handle_rpccmd_message(self, context, dest_id, src_id, msg_type, payload): # logger.debug("got RPCCMD message from src_id %s:\n%s" % (MPTN.ID_TO_STRING(src_id), MPTN.formatted_print([payload]))) if not self._is_id_valid(dest_id): logger.error("invalid RPCCMD dest ID %X: not found in network" % dest_id) return None if src_id != MPTN.MASTER_ID: logger.error("invalid RPCCMD src ID %X: should be master" % src_id) return None if payload is None: logger.error("packet RPCCMD should have the payload") return None try: request = self._rpc_protocol.parse_request(payload) except RPCError as e: response = e.error_respond() else: response = self._rpc_dispatcher.dispatch(request) if response is None: response = str(None) else: response = response.serialize() message = MPTN.create_packet_to_str(src_id, dest_id, MPTN.MPTN_MSGTYPE_RPCREP, response) MPTN.socket_send(context, src_id, message) return
def rtping_forever(self): while True: message = MPTN.create_packet_to_str(MPTN.MASTER_ID, self._id, MPTN.MPTN_MSGTYPE_RTPING, self._nexthop_hash) MPTN.socket_send(None, MPTN.MASTER_ID, message) gevent.sleep(5)
def _forward_to_next_hop(self, context, dest_id, message): packet = MPTN.socket_send(context, dest_id, message, expect_reply=True) if packet is None: log_msg = MPTN.formatted_print(MPTN.split_packet_to_list(message)) logger.error( "_forward_to_next_hop cannot forward packet to %s due to network problem\n%s" % (str(dest_id), log_msg)) return False # log_msg = MPTN.formatted_print(MPTN.split_packet_to_list(packet)) dest_id, src_id, msg_type, payload = packet if payload is None: logger.error( "_forward_to_next_hop FWDACK/NAK from master might have the payload" ) return False if msg_type == MPTN.MPTN_MSGTYPE_FWDNAK: logger.error( "_forward_to_next_hop forward via %s fails with error %s" % (str(dest_id), payload)) return False if msg_type != MPTN.MPTN_MSGTYPE_FWDACK: logger.error( "_forward_to_next_hop get unexpected msg type (%d) instead of FWDACK/NAK" % msg_type) return False # TODO: may need retransmittion? Could be redundant since WKPF has it. return True
def clear_id_req_queue(self): wait_sec = CONFIG.UNITTEST_WAIT_SEC while True: message = self._id_req_queue.get() if MPTN.socket_send( None, MPTN.MASTER_ID, message, expect_reply=True) is None: self._id_req_queue.put_nowait(message) gevent.sleep(wait_sec) gevent.sleep(wait_sec / 2)
def handle_rtping_message(self, context, dest_id, src_id, msg_type, payload): if payload is None: logger.error("RTPING should have the payload") return if dest_id != self._id: logger.error("RTPING dest_id should be me") return if not self._is_id_master(src_id): logger.error("RTPING src ID %X %s should be Master 0" % (src_id, MPTN.ID_TO_STRING(src_id))) return if payload != self._nexthop_hash: logger.debug( "RTPING got different hash %s. mine is %s. need to update routing table" % (str(map(ord, payload)), str(map(ord, self._nexthop_hash)))) message = MPTN.create_packet_to_str(MPTN.MASTER_ID, self._id, MPTN.MPTN_MSGTYPE_RTREQ, None) MPTN.socket_send(None, MPTN.MASTER_ID, message)
def handle_fwdreq_message(self, context, dest_id, src_id, msg_type, payload): if payload is None: logger.error("FWDREQ should have the payload") return if not self.is_id_valid(src_id): logger.error("invalid FWDREQ src ID %X %s: not found in network" % (src_id, MPTN.ID_TO_STRING(src_id))) return if self._is_id_master(dest_id): logger.debug("FWDREQ is to master") message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) if not self._forward_to_next_hop(context, dest_id, message): logger.error("FWDREQ to master failed") return # no need to return FWDACK back via transport interface if self._is_id_gwself(dest_id): logger.debug("FWDREQ the message is to me") if context.direction == MPTN.ONLY_FROM_TRANSPORT_INTERFACE: payload = map(ord, payload) handler = self._app_handler.get(payload[0]) if handler is not None: handler(context.address, payload[1:]) gevent.sleep(0.001) else: logger.error( "FWDREQ receives invalid gateway application %d" % payload[0]) else: logger.error( "FWDREQ receives invalid message to me from Master or other gateways" ) return if self._is_id_in_gwself_network(dest_id): logger.debug("FWDREQ to transport interface directly") message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) ret = self._transport_if_send(self._get_address_from_id(dest_id), message) msg_type = MPTN.MPTN_MSGTYPE_FWDACK if not ret[0]: msg_type = MPTN.MPTN_MSGTYPE_FWDNAK logger.error("FWDREQ to transport address %X fail" % self._get_address_from_id(dest_id)) if not self._is_id_in_gwself_network(src_id): message = MPTN.create_packet_to_str(src_id, dest_id, msg_type, payload) MPTN.socket_send(context, context.id, message) return logger.debug("FWDREQ may be sent to other gateway's network") message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) if self._forward_to_next_hop(context, dest_id, message): return logger.error( "FWDREQ dest ID %X %s is neither the master, the gateway, nor within MPTN" % (dest_id, MPTN.ID_TO_STRING(dest_id))) return
def handle_idreq_message(self, context, dest_id, src_id, msg_type, payload): if not self._is_id_master(dest_id): logger.error("IDREQ dest ID should be 0 not %X (%s)" % (dest_id, MPTN.ID_TO_STRING(dest_id))) return if src_id != MPTN.MPTN_MAX_ID: logger.error("IDREQ src ID should be 0xFFFFFFFF not %X (%s)" % (dest_id, MPTN.ID_TO_STRING(dest_id))) return if payload is None or len(payload) != MPTN.IDREQ_PAYLOAD_LEN: logger.error("IDREQ length of payload %d should be %d" % (len(payload), MPTN.IDREQ_PAYLOAD_LEN)) return uuid = payload try: temp_addr = int(context.address) except Exception as e: logger.error( "IDREQ cannot turn interface address %s into integer" % str(context.address)) exit(-1) if self._transport_if_addr_len == 1 or self._transport_if_addr_len == 2: temp_id = self._id_prefix | temp_addr elif self._transport_if_addr_len == 4: temp_id = temp_addr dest_id = self._id src_id = temp_id # New addresss from transport interface if not self.is_addr_valid(temp_addr): if CONFIG.UNITTEST_MODE: message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, uuid) self._id_req_queue.put_nowait(message) dest_id = temp_id src_id = MPTN.MASTER_ID msg_type = MPTN.MPTN_MSGTYPE_IDACK message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, uuid) self._transport_if_send(temp_addr, message) return else: message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, uuid) packet = MPTN.socket_send(context, MPTN.MASTER_ID, message, expect_reply=True) if packet is None: logger.error( "IDREQ cannot be confirmed ID=%d (%s) Addr=%d" % (temp_id, MPTN.ID_TO_STRING(temp_id), temp_addr)) return dest_id, src_id, msg_type, payload = packet if dest_id != temp_id or src_id != MPTN.MASTER_ID or ( msg_type not in [ MPTN.MPTN_MSGTYPE_IDACK, MPTN.MPTN_MSGTYPE_IDNAK ]): logger.error( "IDREQ invalid response for dest ID=%X (%s), src ID=%X (%s), msg_type=%X" % (dest_id, MPTN.ID_TO_STRING(dest_id), src_id, MPTN.ID_TO_STRING(src_id), msg_type)) return if msg_type == MPTN.MPTN_MSGTYPE_IDNAK: logger.error("IDREQ for %X (%s) is refused by Master" % (temp_id, MPTN.ID_TO_STRING(temp_id))) return self._alloc_address(temp_addr, uuid) message = MPTN.create_packet_to_str(dest_id, src_id, MPTN.MPTN_MSGTYPE_IDACK, None) self._transport_if_send(temp_addr, message) return # Known address to check uuid elif True: #self._addr_db[temp_addr] == payload: dest_id = temp_id message = MPTN.create_packet_to_str(dest_id, MPTN.MASTER_ID, MPTN.MPTN_MSGTYPE_IDACK, None) self._transport_if_send(temp_addr, message) return else: logger.error( "IDREQ comes with a valid addr=%d, ID=%d or %s, but an unknown uuid %s" % (temp_addr, temp_id, MPTN.ID_TO_STRING(temp_id), str(map(ord, uuid))))
def _init_get_prefix_from_master(self): if "GTWSELF_ID" not in self._settings_db: self._settings_db["GTWSELF_ID"] = MPTN.MPTN_MAX_ID self._id = self._settings_db["GTWSELF_ID"] MPTN.set_self_id(self._id) if self._id != MPTN.MPTN_MAX_ID: self._network = MPTN.ID_NETWORK_FROM_TUPLE( MPTN.ID_TO_STRING(self._id), str(self._id_prefix_len)) self._id_prefix = self._id & self._id_netmask dest_id = MPTN.MASTER_ID src_id = self._id msg_type = MPTN.MPTN_MSGTYPE_GWIDREQ payload = json.dumps({ "IFADDR": self._transport_if_addr, "IFADDRLEN": self._transport_if_addr_len, "IFNETMASK": self._id_netmask, "PORT": CONFIG.SELF_TCP_SERVER_PORT, "UUID": self._settings_db["GTWSELF_UNIQUE_VALUE"] }) # payload = "IFADDR=%d;IFADDRLEN=%d;IFNETMASK=%d;PORT=%d;VAL=%s" % (self._transport_if_addr, # self._transport_if_addr_len, self._id_netmask, CONFIG.SELF_TCP_SERVER_PORT, # struct.pack("!%dB"%MPTN.GWIDREQ_PAYLOAD_LEN, *self._settings_db["GTWSELF_UNIQUE_VALUE"])) message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) packet = MPTN.socket_send(None, MPTN.MASTER_ID, message, expect_reply=True) if packet is None: logger.error( "GWIDREQ cannot get GWIDACK/NAK from master due to network problem" ) return None # log_msg = MPTN.formatted_print(MPTN.split_packet_to_list(message)) dest_id, src_id, msg_type, payload = packet if msg_type == MPTN.MPTN_MSGTYPE_GWIDNAK: logger.error("GWIDREQ GWIDREQ is refused by master") return None elif msg_type != MPTN.MPTN_MSGTYPE_GWIDACK: logger.error( "GWIDREQ get unexpected msg type (%d) instead of GWIDACK/NAK from master" % msg_type) return None elif dest_id != self._id: if self._id == MPTN.MPTN_MAX_ID: self._settings_db["GTWSELF_ID"] = dest_id self._id = dest_id MPTN.set_self_id(self._id) self._network = MPTN.ID_NETWORK_FROM_TUPLE( MPTN.ID_TO_STRING(self._id), str(self._id_prefix_len)) self._id_prefix = dest_id & self._id_netmask logger.info( "GWIDREQ successfully get new ID %s including prefix" % MPTN.ID_TO_STRING(dest_id)) else: logger.error( "GWIDREQ get an ID %d %s different from old one %d %s" % (dest_id, MPTN.ID_TO_STRING(dest_id), self._id, MPTN.ID_TO_STRING(self._id))) exit(-1) else: logger.info("GWIDREQ successfully check the ID %s with master" % MPTN.ID_TO_STRING(dest_id))