def lookup(self, dest_ip6):
     logging.pktdump("Lookup: {0} pending lookup:{1}".format(dest_ip6, self.lookup_req))
     if dest_ip6 in self.lookup_req:
         return
     # If no response from the lookup_request message at a certain time. Cancel the 
     # request 
     self.lookup_req[dest_ip6] = { "ttl" : CONFIG["multihop_ihc"]}
     timer = Timer(CONFIG["multihop_tl"], self.lookup_timeout, args=[dest_ip6])
     timer.start()
     self.flood(dest_ip6, CONFIG["multihop_ihc"])
Beispiel #2
0
 def lookup(self, dest_ip6):
     logging.pktdump("Lookup: {0} pending lookup:{1}".format(dest_ip6, \
                     self.lookup_req))
     if dest_ip6 in self.lookup_req:
         return
     # If no response from the lookup_request message at a certain time.
     # Cancel the request 
     self.lookup_req[dest_ip6] = { "ttl" : CONFIG["multihop_ihc"]}
     timer = Timer(CONFIG["multihop_tl"], self.lookup_timeout, \
                   args=[dest_ip6])
     timer.start()
     self.flood(dest_ip6, CONFIG["multihop_ihc"])
Beispiel #3
0
    def multihop_handle(self, data):
        if data[0] != ipop_ver:
            logging.error("ipop version mismatch: tincan:{0} controller:{1}"
                          "".format(data[0].encode("hex"),
                                    ipop_ver.encode("hex")))
        if data[1] == tincan_control:
            msg = json.loads(data[2:])
            logging.debug("multihop control message recv {0}".format(msg))
            msg_type = msg.get("msg_type", None)
            if msg_type == "lookup_request":

                #If this message visit here before, just drop it
                for via in msg["via"][:-1]:
                    if self.ipop_state["_ip6"] == via:
                        return

                # found in peer, do lookup_reply
                for k, v in self.peers.iteritems():
                    if "ip6" in v and v["ip6"] == msg["target_ip6"]:
                        # IP is found in my peers,
                        # send reply message back to previous sender
                        make_remote_call(sock=self.cc_sock,\
                          dest_addr=msg["via"][-2],\
                          dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                          payload=None, msg_type="lookup_reply",\
                          target_ip6=msg["target_ip6"], via=msg["via"], via_idx=-2)
                        return

                # not found in peer, add current node to via then flood
                # lookup_request
                for k, v in self.peers.iteritems():
                    #Do not send lookup_request back to previous hop
                    logging.pktdump("k:{0}, v:{1}".format(k, v))
                    if "ip6" in v and msg["via"][-2] == v["ip6"]:
                        continue
                    # Flood lookup_request
                    if "ip6" in v and msg["ttl"] > 1:
                        make_remote_call(sock=self.cc_sock, dest_addr=v["ip6"],\
                          dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                          payload=None, msg_type="lookup_request",\
                          ttl=msg["ttl"]-1, target_ip6=msg["target_ip6"],\
                          via=msg["via"] + [v["ip6"]])

            if msg_type == "lookup_reply":
                if CONFIG["multihop_sr"]:
                    if ~msg["via_idx"] + 1 == len(msg["via"]):
                        # In source route mode, only source node updates route
                        # information
                        self.update_farpeers(msg["target_ip6"],
                                             len(msg["via"]), msg["via"])
                        if msg["target_ip6"] in self.lookup_req:
                            del self.lookup_req[msg["target_ip6"]]
                        return
                else:
                    # Non source route mode, route information is kept at each
                    # hop. Each node only keeps the next hop info
                    self.update_farpeers(msg["target_ip6"], len(msg["via"]),\
                                     msg["via"][msg["via_idx"]+1])

                # Send lookup_reply message back to the source
                make_remote_call(sock=self.cc_sock,\
                  dest_addr=msg["via"][msg["via_idx"]-1],\
                  dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                  payload=None, msg_type="lookup_reply",\
                  target_ip6=msg["target_ip6"],\
                  via=msg["via"], via_idx=msg["via_idx"]-1)

            if msg_type == "route_error":
                if msg["index"] == 0:
                    del self.far_peers[msg["via"][-1]]
                else:
                    make_remote_call(sock=self.cc_sock,\
                      dest_addr=msg["via"][msg["index"]-1],\
                      dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                      payload=None, msg_type="route_error",\
                      index=msg["index"]-1, via=msg["via"])\

        if data[1] == tincan_packet:
            target_ip6 = ip6_b2a(data[40:56])
            logging.pktdump(
                "Multihop Packet Destined to {0}".format(target_ip6))
            if target_ip6 == self.ipop_state["_ip6"]:
                make_call(self.sock, payload=null_uid + null_uid + data[2:])
                return

            # The packet destined to its direct peers
            for k, v in self.peers.iteritems():
                if "ip6" in v and v["ip6"] == target_ip6:
                    make_remote_call(sock=self.cc_sock, dest_addr=target_ip6,\
                      dest_port=CONFIG["icc_port"], m_type=tincan_packet,\
                      payload=data[2:])
                    return

            # The packet is not in direct peers but have route information
            if ip6_b2a(data[40:56]) in self.far_peers:
                make_remote_call(sock=self.cc_sock,\
                  dest_addr=self.far_peers[target_ip6]["via"],\
                  dest_port=CONFIG["icc_port"], m_type=tincan_packet,\
                  payload=data[2:])
                return
            logging.error("Unroutable packet. Oops this should not happen")

        if data[1] == tincan_sr6:
            logging.pktdump("Multihop packet received", dump=data)
            hop_index = ord(data[2]) + 1
            hop_count = ord(data[3])
            if hop_index == hop_count:
                make_call(self.sock, payload=null_uid + null_uid +\
                  data[4+(hop_index)*16:])
                return
            packet = chr(hop_index)
            packet += data[3:]
            next_addr_offset = 4 + (hop_index) * 16
            next_hop_addr = data[next_addr_offset:next_addr_offset + 16]
            for k, v in self.peers.iteritems():
                if v["ip6"] == ip6_b2a(
                        next_hop_addr) and v["status"] == "online":
                    make_remote_call(sock=self.cc_sock,\
                      dest_addr=ip6_b2a(next_hop_addr),\
                      dest_port=CONFIG["icc_port"], m_type=tincan_sr6,\
                      payload=packet)
                    return
            via = []
            for i in range(hop_count):
                via.append(ip6_b2a(data[4 + i * 16:4 + 16 * i + 16]))
            make_remote_call(sock=self.cc_sock, dest_addr=via[hop_index-2],\
              dest_port=CONFIG["icc_port"], m_type=tincan_control,\
              payload=None, msg_type="route_error", via=via, index=hop_index-2)
            logging.debug(
                "Link lost send back route_error message to source{0}"
                "".format(via[hop_index - 2]))
    def multihop_handle(self, data):
        if data[0] != ipop_ver:
             logging.error("ipop version mismatch: tincan:{0} controller:{1}"
                     "".format(data[0].encode("hex"), ipop_ver.encode("hex")))
        if data[1] == tincan_control: 
            msg = json.loads(data[2:])
            logging.debug("multihop control message recv {0}".format(msg))
            msg_type = msg.get("msg_type", None)
            if msg_type == "lookup_request":

                #If this message visit here before, just drop it
                for via in msg["via"][:-1]:
                    if self.ipop_state["_ip6"] == via:
                        return

                # found in peer, do lookup_reply
                for k, v in self.peers.iteritems():
                    if "ip6" in v and v["ip6"] == msg["target_ip6"]:
                        # IP is found in my peers,  
                        # send reply message back to previous sender
                        make_remote_call(sock=self.cc_sock,\
                          dest_addr=msg["via"][-2],\
                          dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                          payload=None, msg_type="lookup_reply",\
                          target_ip6=msg["target_ip6"], via=msg["via"], via_idx=-2)
                        return

                # not found in peer, add current node to via then flood 
                # lookup_request
                for k, v in self.peers.iteritems():
                    #Do not send lookup_request back to previous hop
                    logging.pktdump("k:{0}, v:{1}".format(k, v))
                    if "ip6" in v and msg["via"][-2] == v["ip6"]:
                        continue
                    # Flood lookup_request
                    if "ip6" in v and msg["ttl"] > 1:
                        make_remote_call(sock=self.cc_sock, dest_addr=v["ip6"],\
                          dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                          payload=None, msg_type="lookup_request",\
                          ttl=msg["ttl"]-1, target_ip6=msg["target_ip6"],\
                          via=msg["via"] + [v["ip6"]])

            if msg_type == "lookup_reply":
                if CONFIG["multihop_sr"]:
                    if  ~msg["via_idx"]+1==len(msg["via"]):
                        # In source route mode, only source node updates route 
                        # information
                        self.update_farpeers(msg["target_ip6"],len(msg["via"]), 
                                             msg["via"])
                        if msg["target_ip6"] in self.lookup_req:
                            del self.lookup_req[msg["target_ip6"]]
                        return
                else:
                    # Non source route mode, route information is kept at each
                    # hop. Each node only keeps the next hop info
                    self.update_farpeers(msg["target_ip6"], len(msg["via"]),\
                                     msg["via"][msg["via_idx"]+1]) 

                # Send lookup_reply message back to the source
                make_remote_call(sock=self.cc_sock,\
                  dest_addr=msg["via"][msg["via_idx"]-1],\
                  dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                  payload=None, msg_type="lookup_reply",\
                  target_ip6=msg["target_ip6"],\
                  via=msg["via"], via_idx=msg["via_idx"]-1)

            if msg_type == "route_error":
                if msg["index"] == 0:
                    del self.far_peers[msg["via"][-1]]
                else:
                    make_remote_call(sock=self.cc_sock,\
                      dest_addr=msg["via"][msg["index"]-1],\
                      dest_port=CONFIG["icc_port"], m_type=tincan_control,\
                      payload=None, msg_type="route_error",\
                      index=msg["index"]-1, via=msg["via"])\

        if data[1] == tincan_packet: 
            target_ip6=ip6_b2a(data[40:56])
            logging.pktdump("Multihop Packet Destined to {0}".format(target_ip6))
            if target_ip6 == self.ipop_state["_ip6"]:
                make_call(self.sock, payload=null_uid + null_uid + data[2:])
                return

            # The packet destined to its direct peers
            for k, v in self.peers.iteritems():
                if "ip6" in v and v["ip6"] == target_ip6:
                    make_remote_call(sock=self.cc_sock, dest_addr=target_ip6,\
                      dest_port=CONFIG["icc_port"], m_type=tincan_packet,\
                      payload=data[2:])
                    return

            # The packet is not in direct peers but have route information
            if ip6_b2a(data[40:56]) in self.far_peers: 
                make_remote_call(sock=self.cc_sock,\
                  dest_addr=self.far_peers[target_ip6]["via"],\
                  dest_port=CONFIG["icc_port"], m_type=tincan_packet,\
                  payload=data[2:])
                return
            logging.error("Unroutable packet. Oops this should not happen")

        if data[1] == tincan_sr6: 
            logging.pktdump("Multihop packet received", dump=data)
            hop_index = ord(data[2]) + 1
            hop_count = ord(data[3])
            if hop_index == hop_count:
                make_call(self.sock, payload=null_uid + null_uid +\
                  data[4+(hop_index)*16:])
                return
            packet = chr(hop_index)
            packet += data[3:]
            next_addr_offset = 4+(hop_index)*16
            next_hop_addr = data[next_addr_offset:next_addr_offset+16] 
            for k, v in self.peers.iteritems():
                if v["ip6"]==ip6_b2a(next_hop_addr) and v["status"]=="online":
                    make_remote_call(sock=self.cc_sock,\
                      dest_addr=ip6_b2a(next_hop_addr),\
                      dest_port=CONFIG["icc_port"], m_type=tincan_sr6,\
                      payload=packet)
                    return
            via = []
            for i in range(hop_count):
                via.append(ip6_b2a(data[4+i*16:4+16*i+16]))
            make_remote_call(sock=self.cc_sock, dest_addr=via[hop_index-2],\
              dest_port=CONFIG["icc_port"], m_type=tincan_control,\
              payload=None, msg_type="route_error", via=via, index=hop_index-2)
            logging.debug("Link lost send back route_error message to source{0}"
                          "".format(via[hop_index-2]))