Exemple #1
0
    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
Exemple #2
0
 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)
Exemple #3
0
    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
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #6
0
    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
Exemple #7
0
    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))))
Exemple #8
0
    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))