Example #1
0
    def run(self):
        while self.alive:
            succ = self.node.get_successor()
            if succ is not None and isinstance(succ, Address) == False:
                succ = Address.get_address_from_string(succ)
            if succ is None or succ == self.node.local_address:
                self.node.fillsuc()

            succ = self.node.get_successor()
            if succ is not None and succ != self.node.local_address:
                succ_pre_q = queryadd(succ, Message.getjson("get_your_pre"))
                if succ_pre_q is None:
                    self.node.delete_successor()
                else:
                    succ_pre = Address.get_address_from_string(
                        succ_pre_q["payload"])
                    if succ_pre is not None:
                        if succ_pre == succ:
                            self.node.notify(succ)
                        else:
                            succ_offset = find_offset(self.node.id,
                                                      hashadd(succ))
                            succ_pre_offset = find_offset(
                                self.node.id, hashadd(succ_pre))
                            if succ_pre_offset > 0 and succ_pre_offset < succ_offset:
                                self.node.update_ith_finger(1, succ_pre)

            time.sleep(1)
Example #2
0
    def join_(self, receiving_node_addr):

        response = queryadd(receiving_node_addr,
                            Message.getjson("find_succ_for_id", self.id))
        if response is not None and response["subject"] == "set_your_succ":
            self.update_ith_finger(
                1, Address.get_address_from_string(response["payload"]))

            response = queryadd(self.finger_table[1],
                                Message.getjson("get_your_pre"))
            if response is not None and response["subject"] == "my_pre":
                self.set_predecessor(
                    Address.get_address_from_string(response["payload"]))

            self.notify(self.finger_table[1])
Example #3
0
    def closestprecedfinger(self, search_id):
        if search_id is None:
            return

        search_id_offset = find_offset(self.id, search_id)

        for i in range(M, 0, -1):
            ith_finger = self.finger_table[i]
            if ith_finger is None:
                continue

            if isinstance(ith_finger,
                          Address) == False and len(ith_finger) > 10:
                ith_finger = Address.get_address_from_string(ith_finger)
            else:
                continue
            ith_finger_id = hashadd(ith_finger)
            ith_finger_offset = find_offset(self.id, ith_finger_id)

            if ith_finger_offset > 0 and ith_finger_offset < search_id_offset:
                query = queryadd(ith_finger, Message.getjson("areyoualive"))
                if query["subject"] == "iamalive":
                    return ith_finger

                self.finger_table[i] = None

        return self.local_address
Example #4
0
 def update_ith_finger(self, pos, address):
     if isinstance(address, Address) == False and address is not None:
         address = Address.get_address_from_string(address)
     if pos == 1:
         print("Successor for {0} set to id {1}".format(
             self.id, hashadd(address)))
     if pos > 0 and pos <= 2**M:
         self.finger_table[pos] = address
Example #5
0
    def __eq__(self, other):
        if self is None or other is None:
            return False

        if isinstance(other, Address) == False:
            if len(other) > 10:
                other = Address.get_address_from_string(other)
            else:
                return False
        return self.ipv4 == other.ipv4 and self.port == other.port
Example #6
0
def hashadd(addr):

    if addr is None:
        return None
    if isinstance(addr, Address) == False and len(addr) > 0:
        addr = Address.get_address_from_string(addr)

    s = "{0}:{1}".format(addr.port, addr.ipv4)
    hash = hashlib.sha1()
    hash.update(s.encode())
    hash_value = int(hash.hexdigest(), 16)
    return hash_value % (2**M)
Example #7
0
def queryadd(address, msg):
    if address is None or msg is None or len(msg) == 0:
        return

    if isinstance(address, Address) == False and len(address) > 0:
        address = Address.get_address_from_string(address)

    addr = (address.ipv4, address.port)
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect(addr)
    except Exception:
        return None
    return socketquery(sock, msg)
Example #8
0
    def ask_for_ip_port(self):
        if self.seed == False:
            while True:
                print(
                    "\nEnter the address of the node you wish to join. For example, 'localhost:8433' or '172.32.21.1:64356'."
                )
                print("Hit Return if you are the seed node.")
                join_addr = input()
                if len(join_addr) == 0:
                    break
                elif len(join_addr) > 10:
                    self.join_(Address.get_address_from_string(join_addr))
                    return
                else:
                    print("\nInvalid address. Please try again.\n")

        print(
            "\nSeed node initialized with address {0} and id {1}. Waiting for other nodes to join the chord network.\n"
            .format(self.local_address.to_string(), self.id))
Example #9
0
    def findsucc(self, search_id):
        if search_id is None:
            return

        if search_id == self.id:
            return self.get_successor()

        ret = self.get_successor()

        pre = self.findpredec(search_id)

        if pre is not None and pre != self.local_address:
            ret_q = queryadd(pre, Message.getjson("get_your_succ"))
            if ret_q is not None and ret_q["subject"] == "my_succ":
                ret = Address.get_address_from_string(ret_q["payload"])

        if ret is None:
            ret = self.local_address

        return ret
Example #10
0
    def handle_message(self, msg):
        msg_dict = Message.parse_message(msg)
        subject = msg_dict["subject"]
        payload = msg_dict["payload"]
        result = ""

        if subject == "find_succ_for_id":
            successor = self.node.findsucc(payload)
            result = Message.getjson("set_your_succ", str(successor))

        elif subject == "get_your_succ":
            result = Message.getjson("my_succ", str(self.node.get_successor()))

        elif subject == "get_your_pre":
            result = Message.getjson("my_pre", str(self.node.predecessor))

        elif subject == "find_closest_p":
            result = Message.getjson(
                "closest_p", str(self.node.closestprecedfinger(payload)))

        elif subject == "i_am_your_pre":
            addr = Address.get_address_from_string(payload)
            self.node.notified(addr)
            return

        elif subject == "get_your_finger_table":
            result = Message.getjson("my_finger_table", self.node.finger_table)

        elif subject == "log":
            print(str(payload))
            return

        elif subject == "areyoualive":
            result = Message.getjson("iamalive")

        else:
            result = Message.getjson("log", "Invalid command!")

        sendsock(self.from_socket, result)
Example #11
0
    def fillsuc(self):
        succ = self.get_successor()
        if succ is None or succ == self.local_address:
            for i in range(2, M + 1):
                ith_finger = self.finger_table[i]
                if ith_finger is not None and isinstance(
                        ith_finger, Address) == False and len(ith_finger) > 10:
                    ith_finger = Address.get_address_from_string(ith_finger)
                if ith_finger is not None and ith_finger != self.local_address:
                    # Push this value "up" in the table
                    for j in range(i - 1, 0, -1):
                        self.update_ith_finger(j, ith_finger)
                    break

        new_succ = self.get_successor()
        if (
                new_succ is None or new_succ == self.local_address
        ) and self.predecessor is not None and self.predecessor != self.local_address:
            self.update_ith_finger(1, self.predecessor)

        if (self.get_successor() is None and self.predecessor is None):
            self.update_ith_finger(1, self.local_address)
Example #12
0
    def findpredec(self, search_id):
        if search_id is None:
            return

        ret = self.local_address
        ret_succ = self.get_successor()
        most_recently_alive = self.local_address
        ret_succ_offset = 0

        if ret_succ is not None:
            ret_succ_offset = find_offset(hashadd(ret), hashadd(ret_succ))

        search_id_offset = find_offset(self.id, search_id)

        while not (search_id_offset > 0
                   and search_id_offset <= ret_succ_offset):
            curr_node_temp = ret

            if ret == self.local_address:
                ret = self.closestprecedfinger(search_id)

            else:
                result_q = queryadd(
                    ret, Message.getjson("find_closest_p", search_id))
                if result_q is not None and result_q["subject"] == "closest_p":
                    result = None if result_q[
                        "payload"] is None else Address.get_address_from_string(
                            result_q["payload"])
                else:
                    result = None

                if result is None:
                    ret = most_recently_alive
                    ret_succ_q = queryadd(ret,
                                          Message.getjson("get_your_succ"))
                    ret_succ = Address.get_address_from_string(
                        ret_succ_q["payload"]
                    ) if ret_succ_q is not None and ret_succ_q[
                        "subject"] == "my_succ" else None
                    if ret_succ is None:
                        return self.local_address
                    continue

                elif result == ret:
                    return result

                else:
                    most_recently_alive = ret
                    ret_succ_q = queryadd(result,
                                          Message.getjson("get_your_succ"))
                    ret_succ = Address.get_address_from_string(
                        ret_succ_q["payload"])
                    if ret_succ is not None:
                        ret = result
                    else:
                        ret_succ_q = queryadd(ret,
                                              Message.getjson("get_your_succ"))
                        ret_succ = Address.get_address_from_string(
                            ret_succ_q["payload"])

                ret_succ_offset = find_offset(hashadd(ret), hashadd(ret_succ))
                search_id_offset = find_offset(hashadd(ret), search_id)

            if curr_node_temp == ret:
                break

        return ret