Exemplo n.º 1
0
    def test_09_Message_List_decode_01(self):
        decoded = decode(
            "d5:peersd1:0d4:ipv49:192.0.2.14:porti34567e8:username8:xlogin00e1:1d4:ipv49:192.0.2.24:porti45678e8:username8:xnigol99ee4:txidi123e4:type4:liste"
        )
        records = Peer_Records()
        for i in range(len(decoded[str.encode("peers")].keys())):
            rec = Peer_Record(decoded[str.encode("peers")][str.encode(
                str(i))][str.encode("username")],
                              decoded[str.encode("peers")][str.encode(
                                  str(i))][str.encode("ipv4")],
                              decoded[str.encode("peers")][str.encode(
                                  str(i))][str.encode("port")],
                              bytes_=True)
            records.add_record(rec)

        msg = Message_List(decoded[str.encode("type")],
                           decoded[str.encode("txid")],
                           records,
                           bytes_=True)

        self.assertEqual(msg.type_, 'list')
        self.assertEqual(msg.txid_, 123)
        self.assertEqual(msg.peers_.records[0].username_, 'xlogin00')
        self.assertEqual(msg.peers_.records[0].ipv4_, '192.0.2.1')
        self.assertEqual(msg.peers_.records[0].port_, 34567)
        self.assertEqual(msg.peers_.records[1].username_, 'xnigol99')
        self.assertEqual(msg.peers_.records[1].ipv4_, '192.0.2.2')
        self.assertEqual(msg.peers_.records[1].port_, 45678)
Exemplo n.º 2
0
    def __init__(self, args):
        self.id = args.id_
        self.username = args.username
        self.chat_ipv4 = args.chat_ipv4
        self.chat_port = args.chat_port
        self.reg_ipv4 = args.reg_ipv4
        self.reg_port = args.reg_port
        self.debug = args.debug

        self.peers = Peer_Records()
        self.pipe = get_pipe_name("peer", self.id)

        self.txid = 0
        self.last_hello = 0
        self.missing_acks = []

        self.acks = {}

        self.print_ack = False
        self.actual_peers = False
        self.print_nextlist = False

        try:
            self.chat_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.chat_sock.bind((self.chat_ipv4, self.chat_port))
        except:
            err_print("Cannot assign requested chat address or port.")
            sys.exit(-1)
Exemplo n.º 3
0
    def test_13_Message_Update_decode_01(self):
        decoded = decode(
            "d2:dbd17:192.0.2.198,12345d1:0d4:ipv49:192.0.2.14:porti34567e8:username8:xlogin00e1:1d4:ipv49:192.0.2.24:porti45678e8:username8:xnigol99ee17:192.0.2.199,12345d1:0d4:ipv49:192.0.2.34:porti65432e8:username8:xtestx00eee4:txidi123e4:type6:updatee"
        )
        db_records = Db_Records()

        for e, elem in enumerate(sorted(decoded[str.encode("db")].keys())):
            p_records = Peer_Records()
            for i in range(len(decoded[str.encode("db")][elem].keys())):
                rec_l = Peer_Record(decoded[str.encode("db")][elem][str.encode(
                    str(i))][str.encode("username")],
                                    decoded[str.encode("db")][elem][str.encode(
                                        str(i))][str.encode("ipv4")],
                                    decoded[str.encode("db")][elem][str.encode(
                                        str(i))][str.encode("port")],
                                    bytes_=True)
                p_records.add_record(rec_l)

            rec_h = Db_Record(
                elem.decode('UTF-8').split(",")[0],
                int(elem.decode('UTF-8').split(",")[1]), p_records)
            db_records.add_record(rec_h)

        msg = Message_Update(decoded[str.encode("type")],
                             decoded[str.encode("txid")],
                             db_records,
                             bytes_=True)
        self.assertEqual(msg.type_, 'update')
        self.assertEqual(msg.txid_, 123)
        self.assertEqual(msg.db_.records[0].dotted_decimal_IP_, '192.0.2.198')
        self.assertEqual(msg.db_.records[0].ushort_port_, 12345)
        self.assertEqual(msg.db_.records[0].peers_.records[0].username_,
                         'xlogin00')
        self.assertEqual(msg.db_.records[0].peers_.records[0].ipv4_,
                         '192.0.2.1')
        self.assertEqual(msg.db_.records[0].peers_.records[0].port_, 34567)
        self.assertEqual(msg.db_.records[0].peers_.records[1].username_,
                         'xnigol99')
        self.assertEqual(msg.db_.records[0].peers_.records[1].ipv4_,
                         '192.0.2.2')
        self.assertEqual(msg.db_.records[0].peers_.records[1].port_, 45678)
        self.assertEqual(msg.db_.records[1].dotted_decimal_IP_, '192.0.2.199')
        self.assertEqual(msg.db_.records[1].ushort_port_, 12345)
        self.assertEqual(msg.db_.records[1].peers_.records[0].username_,
                         'xtestx00')
        self.assertEqual(msg.db_.records[1].peers_.records[0].ipv4_,
                         '192.0.2.3')
        self.assertEqual(msg.db_.records[1].peers_.records[0].port_, 65432)
Exemplo n.º 4
0
    def test_14_Message_Update_encode_01(self):
        recs = Db_Records()

        records = Peer_Records()
        rec_01 = Peer_Record("xlogin00", "192.0.2.1", 34567)
        records.add_record(rec_01)
        rec_02 = Peer_Record("xnigol99", "192.0.2.2", 45678)
        records.add_record(rec_02)
        rec_db_01 = Db_Record("192.0.2.198", 12345, records)
        recs.records.append(rec_db_01)

        records = Peer_Records()
        rec_01 = Peer_Record("xtestx00", "192.0.2.3", 65432)
        records.add_record(rec_01)
        rec_db_02 = Db_Record("192.0.2.199", 12345, records)

        recs.records.append(rec_db_02)

        msg = Message_Update('update', 123, recs)
        encoded = msg.encoded_msg()
        self.assertEqual(
            str.encode(
                "d2:dbd17:192.0.2.198,12345d1:0d4:ipv49:192.0.2.14:porti34567e8:username8:xlogin00e1:1d4:ipv49:192.0.2.24:porti45678e8:username8:xnigol99ee17:192.0.2.199,12345d1:0d4:ipv49:192.0.2.34:porti65432e8:username8:xtestx00eee4:txidi123e4:type6:updatee"
            ), encoded)
Exemplo n.º 5
0
    def test_10_Message_List_encode_01(self):
        records = Peer_Records()
        rec_01 = Peer_Record("xlogin00", "192.0.2.1", 34567)
        records.add_record(rec_01)
        rec_02 = Peer_Record("xnigol99", "192.0.2.2", 45678)
        records.add_record(rec_02)

        msg = Message_List('list', 123, records)
        encoded = msg.encoded_msg()
        self.assertEqual(
            str.encode(
                "d5:peersd1:0d4:ipv49:192.0.2.14:porti34567e8:username8:xlogin00e1:1d4:ipv49:192.0.2.24:porti45678e8:username8:xnigol99ee4:txidi123e4:type4:liste"
            ), encoded)
Exemplo n.º 6
0
    def timeout_hanle(self):
        """
        method for handeling of timeouts
        """
        while True:
            try:
                #delete inactive peers
                to_delete = []
                for i, item in enumerate(self.local_peers_timeouts):
                    if (timer() - item) > 30:
                        to_delete.append(i)

                for i, item in enumerate(reversed(to_delete)):
                    del self.local_peers[i]
                    del self.local_peers_timeouts[i]

                #delete inactive nodes
                to_delete = []
                for i, item in enumerate(self.nodes_timeouts.keys()):
                    if (timer() - self.nodes_timeouts[item]) > 12:
                        to_delete.append(item)

                for i, item in enumerate(to_delete):
                    del self.nodes[item]
                    del self.nodes_timeouts[item]
                    del self.nodes_last_notification[item]

                #waiting for ACKs
                to_delete = []
                for i, item in enumerate(self.acks.keys()):
                    if (timer() - self.acks[item][0]) > 2:
                        msg = Message_Error('error', self.txid, "ACK for message with txid {} wasn't recieved." .format(item))
                        msg_b = msg.encoded_msg()
                        self.send_message_to(msg_b, self.acks[item][2], self.acks[item][3])

                        err_print("ACK for message with txid {} wasn't recieved." .format(item))
                        to_delete.append(item)

                for i, item in enumerate(to_delete):
                    del self.acks[item]

                #send notification to nodes
                for i, item in enumerate(self.nodes_last_notification.keys()):
                    if (timer() - self.nodes_last_notification[item]) > 4:
                        recs = Db_Records()

                        records = Peer_Records()
                        for e, elem in enumerate(self.local_peers):
                            records.add_record(elem)

                        rec_db = Db_Record(self.reg_ipv4, self.reg_port, records)
                        recs.records.append(rec_db)

                        for e, elem in enumerate(self.nodes.keys()):
                            if self.nodes[elem] != -1:
                                rec_db = Db_Record(elem.split(",")[0], int(elem.split(",")[1]), self.nodes[elem])
                                recs.records.append(rec_db)

                        msg = Message_Update('update', self.txid, recs)
                        msg_b = msg.encoded_msg()
                        self.send_message_to(msg_b, item.split(",")[0], int(item.split(",")[1]))
                        self.nodes_last_notification[item] = timer()

                time.sleep(0.5)
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                err_print(exc_type, fname, exc_tb.tb_lineno)
Exemplo n.º 7
0
    def listen_pipe(self):
        """
        method for handeling of named pipe listening
        """
        while True:
            try:
                with open(self.pipe) as p:
                    data = p.read()
                data = data.split()
                if self.debug:
                    err_print(data)


                if data[0] == "database":
                    counter = 0
                    string = "{"
                    for i, item in enumerate(self.local_peers):
                        string += str(item) + ','
                        counter += 1

                    for i, item in enumerate(self.nodes.keys()):
                        if self.nodes[item] != -1:
                            for e, elem in enumerate(self.nodes[item].records):
                                string += str(elem) + ','
                                counter += 1

                    if counter != 0:
                        string = string[:-1]

                    string += "}"

                    err_print(string)


                elif data[0] == "neighbors":
                    string = "{"
                    for i, item in enumerate(self.nodes.keys()):
                        string += "{\'ipv4\': \'" + item.split(',')[0] + "\', \'port\': " + str(int(item.split(',')[1])) + "}"
                        string += ','

                    if len(self.nodes) != 0:
                        string = string[:-1]

                    string += "}"

                    err_print(string)


                elif data[0] == "connect":
                    recs = Db_Records()

                    records = Peer_Records()
                    for i, item in enumerate(self.local_peers):
                        records.add_record(item)

                    rec_db = Db_Record(self.reg_ipv4, self.reg_port, records)
                    recs.records.append(rec_db)

                    for i, item in enumerate(self.nodes.keys()):
                        if self.nodes[item] != -1:
                            rec_db = Db_Record(item.split(",")[0], int(item.split(",")[1]), self.nodes[item])
                            recs.records.append(rec_db)

                    msg = Message_Update('update', self.txid, recs)
                    msg_b = msg.encoded_msg()
                    self.send_message_to(msg_b, data[1], int(data[2]))
                    self.nodes_last_notification[data[1]+','+str(data[2])] = timer()


                elif data[0] == "disconnect":
                    for i, item in enumerate(list(self.nodes.keys())):
                        msg = Message_Disconnect('disconnect', self.txid)
                        msg_b = msg.encoded_msg()
                        self.acks[self.txid] = [timer(), "disconnect", item.split(",")[0], int(item.split(",")[1])]
                        self.send_message_to(msg_b, item.split(",")[0], int(item.split(",")[1]))
                    self.nodes = {}
                    self.nodes_timeouts = {}
                    self.nodes_last_notification = {}


                elif data[0] == "sync":
                    recs = Db_Records()

                    records = Peer_Records()
                    for i, item in enumerate(self.local_peers):
                        records.add_record(item)

                    rec_db = Db_Record(self.reg_ipv4, self.reg_port, records)
                    recs.records.append(rec_db)

                    for i, item in enumerate(self.nodes.keys()):
                        if self.nodes[item] != -1:
                            rec_db = Db_Record(item.split(",")[0], int(item.split(",")[1]), self.nodes[item])
                            recs.records.append(rec_db)

                    for i, item in enumerate(self.nodes.keys()):
                        msg = Message_Update('update', self.txid, recs)
                        msg_b = msg.encoded_msg()
                        self.send_message_to(msg_b, item.split(",")[0], int(item.split(",")[1]))
                        self.nodes_last_notification[item] = timer()

                else:
                    #ignore other pipe messages
                    pass
            except Exception as e:
                if type(e).__name__ != 'FileNotFoundError': #pipe is not created
                    exc_type, exc_obj, exc_tb = sys.exc_info()
                    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                    err_print(exc_type, fname, exc_tb.tb_lineno)
Exemplo n.º 8
0
    def listen_reg(self):
        """
        method for handeling of network listening
        """
        while True:
            try:
                data, addr = self.reg_sock.recvfrom(buffer_size)
                data = decode(data)
                if self.debug:
                    err_print(addr, data)
                type_ = data[str.encode("type")]
                type_ = type_.decode('UTF-8')


                if type_ == "hello":
                    if data[str.encode("ipv4")].decode('UTF-8') == "0.0.0.0" and data[str.encode("port")] == 0:
                        for i, item in enumerate(self.local_peers):
                            if data[str.encode("username")].decode('UTF-8') == item.username_:
                                del self.local_peers[i]
                                del self.local_peers_timeouts[i]
                    else:
                        record = Peer_Record(data[str.encode("username")], data[str.encode("ipv4")], data[str.encode("port")], bytes_=True)
                        existing = False
                        for i, item in enumerate(self.local_peers):
                            if item.username_ == record.username_ and item.ipv4_ == record.ipv4_ and item.port_ == record.port_:
                                self.local_peers_timeouts[i] = timer()
                                existing = True
                        if not existing:
                            self.local_peers.append(record)
                            self.local_peers_timeouts.append(timer())


                elif type_ == "getlist":
                    is_authorized = False
                    for i, item in enumerate(self.local_peers):
                        if item.ipv4_ == addr[0] and item.port_ == addr[1]:
                            is_authorized = True
                            self.acknowlidge(addr[0], addr[1], data[str.encode("txid")])

                    if not is_authorized:
                        msg = Message_Error('error', data[str.encode("txid")], "You aren't logged to this node, you don't have a permission to get LIST.")
                        encoded = msg.encoded_msg()
                        self.send_message_to(msg_b, addr[0], addr[1])
                        err_print("Not logged peer asked for LIST message.")
                    else:
                        records = Peer_Records()
                        for i, item in enumerate(self.local_peers):
                            records.add_record(item)

                        for i, item in enumerate(self.nodes.keys()):
                            if self.nodes[item] != -1:
                                for i, item in enumerate(self.nodes[item].records):
                                    records.add_record(item)

                        msg = Message_List('list', self.txid, records)
                        msg_b = msg.encoded_msg()
                        self.acks[self.txid] = [timer(), "list", addr[0], addr[1]]
                        self.send_message_to(msg_b, addr[0], addr[1])


                elif type_ == "error":
                    err_print(data[str.encode("verbose")].decode('UTF-8'))


                elif type_ == "update":
                    if (addr[0]+','+str(addr[1])) in self.nodes.keys():
                        new = False
                    else:
                        new = True

                    for e, elem in enumerate(sorted(data[str.encode("db")].keys())):
                        #authoritative record
                        if elem.decode('UTF-8').split(",")[0] == addr[0] and int(elem.decode('UTF-8').split(",")[1]) == addr[1]:
                            p_records = Peer_Records()
                            for i in range(len(data[str.encode("db")][elem].keys())):

                                rec_l = Peer_Record(data[str.encode("db")][elem][str.encode(str(i))][str.encode("username")], data[str.encode("db")][elem][str.encode(str(i))][str.encode("ipv4")], data[str.encode("db")][elem][str.encode(str(i))][str.encode("port")], bytes_=True)
                                p_records.add_record(rec_l)

                            self.nodes[elem.decode('UTF-8')] = p_records
                            self.nodes_timeouts[elem.decode('UTF-8')] = timer()
                        #nonauthoritative record
                        else:
                            if elem.decode('UTF-8').split(",")[0] == self.reg_ipv4 and int(elem.decode('UTF-8').split(",")[1]) == self.reg_port:
                                pass
                            elif elem.decode('UTF-8') not in self.nodes:
                            
                                self.nodes[elem.decode('UTF-8')] = -1
                                self.nodes_timeouts[elem.decode('UTF-8')] = timer()

                    for i, item in enumerate(self.nodes.keys()):
                        if self.nodes[item] == -1 or (addr[0] == item.split(",")[0] and addr[1] == int(item.split(",")[1]) and new):
                            recs = Db_Records()

                            records = Peer_Records()
                            for e, elem in enumerate(self.local_peers):
                                records.add_record(elem)

                            rec_db = Db_Record(self.reg_ipv4, self.reg_port, records)
                            recs.records.append(rec_db)

                            for e, elem in enumerate(self.nodes.keys()):
                                if self.nodes[elem] != -1:
                                    rec_db = Db_Record(elem.split(",")[0], int(elem.split(",")[1]), self.nodes[elem])
                                    recs.records.append(rec_db)

                            msg = Message_Update('update', self.txid, recs)
                            msg_b = msg.encoded_msg()
                            self.send_message_to(msg_b, item.split(",")[0], int(item.split(",")[1]))
                            self.nodes_last_notification[item] = timer()


                elif type_ == "disconnect":
                    if addr[0]+','+str(addr[1]) in self.nodes:
                        del self.nodes[addr[0]+','+str(addr[1])]
                        del self.nodes_timeouts[addr[0]+','+str(addr[1])]
                        del self.nodes_last_notification[addr[0]+','+str(addr[1])]
                    
                    self.acknowlidge(addr[0], addr[1], data[str.encode("txid")])


                elif type_ == "ack":
                    if data[str.encode("txid")] in self.acks:
                        del self.acks[data[str.encode("txid")]]
                    else:
                        err_print("Unexpected ACK with txid {} received." .format(data[str.encode("txid")]))


                else:
                    #ignore other messages
                    pass
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                err_print(exc_type, fname, exc_tb.tb_lineno)
Exemplo n.º 9
0
class Peer(object):
    def __init__(self, args):
        self.id = args.id_
        self.username = args.username
        self.chat_ipv4 = args.chat_ipv4
        self.chat_port = args.chat_port
        self.reg_ipv4 = args.reg_ipv4
        self.reg_port = args.reg_port
        self.debug = args.debug

        self.peers = Peer_Records()
        self.pipe = get_pipe_name("peer", self.id)

        self.txid = 0
        self.last_hello = 0
        self.missing_acks = []

        self.acks = {}

        self.print_ack = False
        self.actual_peers = False
        self.print_nextlist = False

        try:
            self.chat_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.chat_sock.bind((self.chat_ipv4, self.chat_port))
        except:
            err_print("Cannot assign requested chat address or port.")
            sys.exit(-1)

    def run(self):
        """
        main method
        """
        _thread.start_new_thread(self.timeout_hanle, ())
        _thread.start_new_thread(self.listen_chat, ())
        _thread.start_new_thread(self.listen_pipe, ())

        while True:
            pass

    def timeout_hanle(self):
        """
        method for handeling of timeouts
        """
        while True:
            try:
                #hello sending
                if (timer() - self.last_hello) > 10:
                    msg = Message_Hello('hello', self.txid, self.username,
                                        self.chat_ipv4, self.chat_port)
                    msg_b = msg.encoded_msg()
                    self.send_message(msg_b)
                    self.last_hello = timer()

                #waiting for ACKs
                to_delete = []
                for i, item in enumerate(self.acks.keys()):
                    if (timer() - self.acks[item][0]) > 2:
                        msg = Message_Error(
                            'error', self.txid,
                            "ACK for message with txid {} wasn't recieved.".
                            format(item))
                        msg_b = msg.encoded_msg()
                        self.send_message_to(msg_b, self.acks[item][2],
                                             self.acks[item][3])

                        err_print(
                            "ACK for message with txid {} wasn't recieved.".
                            format(item))
                        to_delete.append(item)
                        self.missing_acks.append(item)

                for i, item in enumerate(to_delete):
                    del self.acks[item]

                time.sleep(0.5)
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                err_print(exc_type, fname, exc_tb.tb_lineno)

    def listen_chat(self):
        """
        method for handeling of network listening
        """
        while True:
            try:
                data, addr = self.chat_sock.recvfrom(buffer_size)
                data = decode(data)
                if self.debug:
                    err_print(data)
                type_ = data[str.encode("type")]
                type_ = type_.decode('UTF-8')

                if type_ == "error":
                    err_print(data[str.encode("verbose")].decode('UTF-8'))

                elif type_ == "list":
                    self.peers = Peer_Records()
                    for i, item in enumerate(data[str.encode("peers")].keys()):
                        rec = Peer_Record(
                            data[str.encode("peers")][str.encode(
                                item.decode('UTF-8'))][str.encode("username")],
                            data[str.encode("peers")][str.encode(
                                item.decode('UTF-8'))][str.encode("ipv4")],
                            data[str.encode("peers")][str.encode(
                                item.decode('UTF-8'))][str.encode("port")],
                            bytes_=True)
                        self.peers.add_record(rec)

                    self.actual_peers = True

                    if self.print_nextlist:
                        string = "{"
                        for i, item in enumerate(self.peers.records):
                            string += str(item) + ','

                        if self.peers != 0:
                            string = string[:-1]

                        string += "}"
                        err_print(string)
                        self.print_nextlist = False

                    self.acknowlidge(addr[0], addr[1],
                                     data[str.encode("txid")])

                elif type_ == "message":
                    print(data[str.encode("message")].decode('UTF-8'))
                    self.acknowlidge(addr[0], addr[1],
                                     data[str.encode("txid")])

                elif type_ == "ack":
                    if data[str.encode("txid")] in self.acks:
                        del self.acks[data[str.encode("txid")]]
                    else:
                        err_print(
                            "Unexpected ACK with txid {} received.".format(
                                data[str.encode("txid")]))

                    if self.print_ack:
                        err_print("Message GETLIST with txid {} acknowlidged.".
                                  format(data[str.encode("txid")]))
                        self.print_ack = False

                else:
                    #ignore other messages
                    pass
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                err_print(exc_type, fname, exc_tb.tb_lineno)

    def listen_pipe(self):
        """
        method for handeling of named pipe listening
        """
        while True:
            try:
                with open(self.pipe) as p:
                    data = p.read()
                data = data.split()
                if self.debug:
                    err_print(data)

                if data[0] == "message":
                    self.actual_peers = False

                    msg = Message_GetList('getlist', self.txid)
                    msg_b = msg.encoded_msg()
                    stamp = self.txid
                    self.acks[stamp] = [
                        timer(), "list", self.reg_ipv4, self.reg_port
                    ]
                    self.send_message(msg_b)

                    while True:
                        if stamp not in self.acks and stamp not in self.missing_acks:
                            break

                    start = timer()
                    while True:
                        if self.actual_peers or (timer() - start) > 2:
                            break

                    if data[1] == self.username:
                        reachable = False
                        for i, item in enumerate(self.peers.records):
                            if data[2] == item.username_:
                                reachable = True
                                text = ""
                                for e, elem in enumerate(data[3:]):
                                    if e == 0:
                                        text += elem
                                    else:
                                        text += " " + elem

                                msg = Message_Message('message', self.txid,
                                                      self.username,
                                                      item.username_, text)
                                msg_b = msg.encoded_msg()
                                self.acks[self.txid] = [
                                    timer(), "message", item.ipv4_, item.port_
                                ]
                                self.send_message_to(msg_b, item.ipv4_,
                                                     item.port_)
                        if not reachable:
                            err_print("User is unreachable.")

                elif data[0] == "getlist":
                    msg = Message_GetList('getlist', self.txid)
                    msg_b = msg.encoded_msg()
                    self.print_ack = True
                    self.acks[self.txid] = [
                        timer(), "list", self.reg_ipv4, self.reg_port
                    ]
                    self.send_message(msg_b)

                elif data[0] == "peers":
                    msg = Message_GetList('getlist', self.txid)
                    msg_b = msg.encoded_msg()
                    self.print_nextlist = True
                    self.acks[self.txid] = [
                        timer(), "list", self.reg_ipv4, self.reg_port
                    ]
                    self.send_message(msg_b)

                elif data[0] == "reconnect":
                    msg = Message_Hello('hello', self.txid, self.username,
                                        '0.0.0.0', 0)
                    msg_b = msg.encoded_msg()
                    self.send_message(msg_b)

                    self.reg_ipv4 = data[1]
                    self.reg_port = int(data[2])

                    msg = Message_Hello('hello', self.txid, self.username,
                                        self.chat_ipv4, self.chat_port)
                    msg_b = msg.encoded_msg()
                    self.send_message(msg_b)

                else:
                    #ignore other pipe messages
                    pass
            except Exception as e:
                if type(
                        e
                ).__name__ != 'FileNotFoundError':  #pipe is not created exception
                    exc_type, exc_obj, exc_tb = sys.exc_info()
                    fname = os.path.split(
                        exc_tb.tb_frame.f_code.co_filename)[1]
                    err_print(exc_type, fname, exc_tb.tb_lineno)

    def next_txid(self):
        """
        iterator method for txid indexing
        """
        if self.txid == 65535:
            self.txid = 0
        else:
            self.txid += 1

    def send_message(self, msg_b):
        """
        method sends message to registred node
        """
        self.chat_sock.sendto(msg_b, (self.reg_ipv4, self.reg_port))
        self.next_txid()

    def send_message_to(self, msg_b, ipv4, port):
        """
        method sends message to someone
        """
        self.chat_sock.sendto(msg_b, (ipv4, port))
        self.next_txid()

    def acknowlidge(self, ipv4, port, txid):
        """
        method sends ACK message to someone
        """
        msg = Message_Ack('ack', txid)
        msg_b = msg.encoded_msg()
        self.chat_sock.sendto(msg_b, (ipv4, port))
Exemplo n.º 10
0
    def listen_chat(self):
        """
        method for handeling of network listening
        """
        while True:
            try:
                data, addr = self.chat_sock.recvfrom(buffer_size)
                data = decode(data)
                if self.debug:
                    err_print(data)
                type_ = data[str.encode("type")]
                type_ = type_.decode('UTF-8')

                if type_ == "error":
                    err_print(data[str.encode("verbose")].decode('UTF-8'))

                elif type_ == "list":
                    self.peers = Peer_Records()
                    for i, item in enumerate(data[str.encode("peers")].keys()):
                        rec = Peer_Record(
                            data[str.encode("peers")][str.encode(
                                item.decode('UTF-8'))][str.encode("username")],
                            data[str.encode("peers")][str.encode(
                                item.decode('UTF-8'))][str.encode("ipv4")],
                            data[str.encode("peers")][str.encode(
                                item.decode('UTF-8'))][str.encode("port")],
                            bytes_=True)
                        self.peers.add_record(rec)

                    self.actual_peers = True

                    if self.print_nextlist:
                        string = "{"
                        for i, item in enumerate(self.peers.records):
                            string += str(item) + ','

                        if self.peers != 0:
                            string = string[:-1]

                        string += "}"
                        err_print(string)
                        self.print_nextlist = False

                    self.acknowlidge(addr[0], addr[1],
                                     data[str.encode("txid")])

                elif type_ == "message":
                    print(data[str.encode("message")].decode('UTF-8'))
                    self.acknowlidge(addr[0], addr[1],
                                     data[str.encode("txid")])

                elif type_ == "ack":
                    if data[str.encode("txid")] in self.acks:
                        del self.acks[data[str.encode("txid")]]
                    else:
                        err_print(
                            "Unexpected ACK with txid {} received.".format(
                                data[str.encode("txid")]))

                    if self.print_ack:
                        err_print("Message GETLIST with txid {} acknowlidged.".
                                  format(data[str.encode("txid")]))
                        self.print_ack = False

                else:
                    #ignore other messages
                    pass
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                err_print(exc_type, fname, exc_tb.tb_lineno)