Пример #1
0
    def test_order_closest(self):
        id0 = Id(BIN_ID0)
        ordered_list = [
            Id('\x00' * ID_SIZE_BYTES),
            Id(BIN_ID0[:-1] + '\x06'),
            Id(BIN_ID0[:9] + '\x01' * (ID_SIZE_BYTES - 9)),
            Id(BIN_ID0[:7] + '\xff' * (ID_SIZE_BYTES - 7)),
            Id(BIN_ID0[:7] + '\xff' * (ID_SIZE_BYTES - 7)),
            Id('\x00' + '\xff' * (ID_SIZE_BYTES - 1)),
            Id('\x53' * ID_SIZE_BYTES),
            Id('\xff' * ID_SIZE_BYTES),
            ]
        random_list = random.sample(ordered_list, len(ordered_list))

        random_list_copy = random_list[:]

        logger.debug('ordered list')
        for e in ordered_list: logger.debug('%s' % e)
        logger.debug('random order')
        for e in random_list: logger.debug('%s' % e)

        result_list = id0.order_closest(random_list)
        logger.debug('order_closest result')
        for e in result_list: logger.debug('%s' % e)
        logger.debug('random order (it should not change)')
        for e in random_list: logger.debug('%s' % e)

        # make sure order_closest does not modify random_list
        assert random_list == random_list_copy
        
        for i, ordered_id in enumerate(ordered_list):
            logger.debug('%d, %s, %s' % (i, ordered_id, result_list[i]))
            assert ordered_id.bin_id == result_list[i].bin_id
Пример #2
0
 def _get_id(self, k, kk=None):
     try:
         v = self._get_value(k, kk)
         v = Id(v)
     except (IdError):
         raise MsgError, 'Value (%s:%s,%s) must be a valid Id' % (k, kk, v)
     return v
Пример #3
0
 def handle(self, data, addr):
     #droid.log("New connection")
     if data == "KILL_DHT":
         return True  # stop DHT
     data_len = len(data)
     i = 0
     #print 'in: ',
     remote_cid = data[:CHANNEL_SIZE]
     i += CHANNEL_SIZE
     #print '%r' % remote_cid,
     channel = self.channel_m.get(remote_cid, addr)
     if not channel:
         #print 'Invalid channel id'
         return
     while i < data_len:
         msg_type = ord(data[i])
         i += 1
         if msg_type == HANDSHAKE:
             channel.remote_cid = data[i:i + CHANNEL_SIZE]
             i += CHANNEL_SIZE
         elif msg_type == DATA:
             i = data_len  # DATA always ends a datagram
         elif msg_type == ACK:
             i += TS_SIZE + BIN_SIZE
         elif msg_type == HAVE:
             i += BIN_SIZE
         elif msg_type == HASH:
             i += BIN_SIZE
             channel.rhash = Id(data[i:i + HASH_SIZE])
             i += HASH_SIZE
         elif msg_type == PEX_RES:
             i += 0  #no arguments
         elif msg_type == PEX_REQ:
             i += PEER_SIZE
         elif msg_type == SIGNED_HASH:
             print ` data `
             raise NotImplemented
         elif msg_type == HINT:
             i += BIN_SIZE
         elif msg_type == MSGTYPE_RCVD:
             print ` data `
             raise NotImplemented
         elif msg_type == VERSION:
             i += VERSION_SIZE
         else:
             print 'UNKNOWN: ', msg_type,
             print ` data `
             #raise NotImplemented
             return
     if remote_cid == CHANNEL_ZERO and channel.rhash:
         #droid.log(">>>>>>> DHT: got HANDSHAKE from swift <<<<<<<")
         self.pymdht.get_peers(channel, channel.rhash, self._on_peers_found,
                               channel.remote_addr[1])
         # need to complete handshake
         reply = ''.join((
             channel.remote_cid,
             chr(HANDSHAKE),
             channel.local_cid,
         ))
         self.socket.sendto(reply, channel.remote_addr)
Пример #4
0
 def load_state(self):
     self._my_id = None
     self.loaded_nodes = []
     try:
         f = open(self.state_filename)
     except(IOError):
         return
     # the first line contains this node's identifier
     hex_id = f.readline().strip()
     self._my_id = Id(hex_id)
     # the rest of the lines contain routing table nodes
     # FORMAT
     # log_distance hex_id ip port rtt
     for line in f:
         _, hex_id, ip, port, _ = line.split()
         addr = (ip, int(port))
         node_ = Node(addr, Id(hex_id))
         self.loaded_nodes.append(node_)
     f.close
Пример #5
0
def load(filename):
    my_id = None
    nodes = []
    try:
        f = open(filename)
        hex_id = f.readline().strip()
        my_id = Id(hex_id)
        for line in f:
            _, hex_id, _, ip, port, _, _ = line.split()
            addr = (ip, int(port))
            node_ = Node(addr, Id(hex_id))
            nodes.append(node_)
    except (IOError):
        logger.debug("No state saved, loading default.")
        return None, []
    except:
        logger.exception("Error when loading state, loading default.")
        #raise # debug only
        return None, []
    f.close
    return my_id, nodes
Пример #6
0
def uncompact_nodes2(c_nodes):
    nodes = []
    for c_node in c_nodes:
        node_id = Id(c_node[:ID_SIZE_BYTES])
        try:
            node_addr = uncompact_addr(c_node[ID_SIZE_BYTES:])
        except (AddrError):
            logger.warning('IPv6 addr in nodes2: %s' % c_node)
        else:
            node = Node(node_addr, node_id)
            nodes.append(node)
    return nodes
    def load_state(self):
        self._my_id = None
        self.loaded_nodes = []
        try:
            f = open(self.state_filename)
        except IOError:
            return

        try:
            hex_id = f.readline().strip()
            self._my_id = Id(hex_id)
            for line in f:
                _, hex_id, ip, port, _ = line.split()
                addr = (ip, int(port))
                node_ = Node(addr, Id(hex_id))
                self.loaded_nodes.append(node_)

            f.close()
        except:
            self._my_id = None
            self.loaded_nodes = []
            logger.error('state.dat is corrupted')
Пример #8
0
 def test_create(self):
     _ = Id(BIN_ID1)
     _ = RandomId()
     assert_raises(IdError, Id, 1)
     assert_raises(IdError, Id, '1')
     _ = Id('1' * 40)  # Hexadecimal
     assert_raises(IdError, Id, 'Z' * 40)
     eq_(Id('\x00' * 20).bin_id, Id('0' * 40).bin_id)
     eq_(Id('\xff' * 20), Id('f' * 40))
Пример #9
0
def _uncompact_nodes(c_nodes):
    if len(c_nodes) % C_NODE_SIZE != 0:
        raise MsgError, 'invalid size (%d) %s' % (len(c_nodes), c_nodes)
    nodes = []
    for begin in xrange(0, len(c_nodes), C_NODE_SIZE):
        node_id = Id(c_nodes[begin:begin + ID_SIZE_BYTES])
        try:
            node_addr = uncompact_addr(c_nodes[begin + ID_SIZE_BYTES:begin +
                                               C_NODE_SIZE])
        except AddrError:
            pass
        else:
            node = Node(node_addr, node_id)
            nodes.append(node)
    return nodes
Пример #10
0
def uncompact_nodes(c_nodes):
    if len(c_nodes) % C_NODE_SIZE != 0:
        logger.info('invalid size (%d) %s' % (len(c_nodes), c_nodes))
        return []
    nodes = []
    for begin in xrange(0, len(c_nodes), C_NODE_SIZE):
        node_id = Id(c_nodes[begin:begin + ID_SIZE_BYTES])
        try:
            node_addr = uncompact_addr(c_nodes[begin + ID_SIZE_BYTES:begin +
                                               C_NODE_SIZE])
        except AddrError:
            pass
        else:
            node = Node(node_addr, node_id, version=None)
            nodes.append(node)
    return nodes
Пример #11
0
    def test_log_distance(self):
        id0 = Id(BIN_ID0)
        id1 = Id(BIN_ID1)
        id2 = Id(BIN_ID2)
        eq_(id0.log_distance(id0), -1)
        eq_(id0.log_distance(id1), ID_SIZE_BITS - 8)
        eq_(id0.log_distance(id2), ID_SIZE_BITS - 7)

        id_log = (
            (Id('\x00' + '\xff' * (ID_SIZE_BYTES - 1)),
             BITS_PER_BYTE * (ID_SIZE_BYTES - 1) - 1),
            (Id('\x53' * ID_SIZE_BYTES), BITS_PER_BYTE * ID_SIZE_BYTES - 2),
            (Id(BIN_ID0[:7] + '\xff' * (ID_SIZE_BYTES - 7)),
             (ID_SIZE_BYTES - 7) * BITS_PER_BYTE - 1),
            (Id(BIN_ID0[:9] + '\x01' * (ID_SIZE_BYTES - 9)),
             (ID_SIZE_BYTES - 10) * BITS_PER_BYTE),
            (Id(BIN_ID0[:-1] + '\x06'), 2),
        )
        id2_log = (
            (Id('\x41' * ID_SIZE_BYTES), Id('\x41' * ID_SIZE_BYTES), -1),
            (Id('\x41' * ID_SIZE_BYTES), Id('\x01' * ID_SIZE_BYTES), 158),
            (Id('\x41' * ID_SIZE_BYTES), Id('\x43' * ID_SIZE_BYTES), 153),
        )

        for (id_, log_) in id_log:
            logger.debug('log_distance: %d' % id0.log_distance(id_))
            logger.debug('expected: %d' % log_)
            eq_(id0.log_distance(id_), log_)
        for id1, id2, expected in id2_log:
            eq_(id1.log_distance(id2), expected)

            z = Id('\0' * 20)
            eq_(z.log_distance(Id('\x00' * 19 + '\x00')), -1)
            eq_(z.log_distance(Id('\x00' * 19 + '\x00')), -1)
            eq_(z.log_distance(Id('\x00' * 19 + '\x00')), -1)
            eq_(z.log_distance(Id('\x00' * 19 + '\x00')), -1)
            eq_(z.log_distance(Id('\x00' * 19 + '\x00')), -1)
Пример #12
0
 def test_bin_id_read_only(self):
     id1 = Id(BIN_ID1)
     id1.bin_id = BIN_ID2
Пример #13
0
 def test_str(self):
     id1 = Id(BIN_ID1)
     assert BIN_ID1 == '%s' % id1
Пример #14
0
 def test_distance(self):
     id1 = Id(BIN_ID1)
     id2 = Id(BIN_ID2)
     dist1_2 = Id(DIST1_2)
     assert id1.distance(id2).bin_id == dist1_2.bin_id
     assert id2.distance(id1).bin_id == dist1_2.bin_id
Пример #15
0
 def test_equal(self):
     id1 = Id(BIN_ID0)
     assert id1 == id1  # same instance
     assert id1 == Id(BIN_ID0)  #different instance, same value
     assert id1 != Id(BIN_ID1)
Пример #16
0
 def test_bin_id_read_only(self):
     id1 = Id(BIN_ID1)
     id1.bin_id = BIN_ID2
Пример #17
0
 def test_is_hashable(self):
     d = {Id(BIN_ID1): 1}
Пример #18
0
 def handle(self, data, addr):
     droid.log("New connection")
     if data == "KILL_DHT":
         return True  # stop DHT
     data_len = len(data)
     i = 0
     print 'in: ',
     remote_cid = data[:CHANNEL_SIZE]
     i += CHANNEL_SIZE
     print '%r' % remote_cid,
     channel = self.channel_m.get(remote_cid, addr)
     if not channel:
         print 'Invalid channel id'
         return
     while i < data_len:
         msg_type = ord(data[i])
         i += 1
         if msg_type == HANDSHAKE:
             print 'HAND',
             channel.remote_cid = data[i:i + CHANNEL_SIZE]
             i += CHANNEL_SIZE
         elif msg_type == DATA:
             print 'DATA',
             i = data_len  # DATA always ends a datagram
         elif msg_type == ACK:
             print 'ACK',
             i += TS_SIZE + BIN_SIZE
         elif msg_type == HAVE:
             print 'HAVE',
             i += BIN_SIZE
         elif msg_type == HASH:
             print 'HASH',
             i += BIN_SIZE
             channel.rhash = Id(data[i:i + HASH_SIZE])
             i += HASH_SIZE
         elif msg_type == PEX_RES:
             print 'PRES',
             i += 0  #no arguments
         elif msg_type == PEX_REQ:
             print 'PREQ',
             i += PEER_SIZE
         elif msg_type == SIGNED_HASH:
             print 'SHASH',
             print ` data `
             raise NotImplemented
         elif msg_type == HINT:
             print 'HINT',
             i += BIN_SIZE
         elif msg_type == MSGTYPE_RCVD:
             print 'MSGTYPE > not implemented',
             print ` data `
             raise NotImplemented
         elif msg_type == VERSION:
             print 'VERSION',
             i += VERSION_SIZE
         else:
             print 'UNKNOWN: ', msg_type,
             print ` data `
             raise NotImplemented
     print
     if remote_cid == CHANNEL_ZERO and channel.rhash:
         droid.log(">>>>>>> DHT: got HANDSHAKE from swift <<<<<<<")
         self.dht.get_peers(channel, channel.rhash, self._on_peers_found, 0)
         # need to complete handshake
         reply = ''.join((
             channel.remote_cid,
             chr(HANDSHAKE),
             channel.local_cid,
         ))
         self.socket.sendto(reply, addr)
         droid.log('>>>>>>>>>>>>> GETTING PEERS <<<<<<<<<<<<<<')
         reply = ''.join((
             channel.remote_cid,
             chr(PEX_RES),
             socket.inet_aton('130.161.211.194'),  #Delft
             chr(20050 >> 8),
             chr(20050 % 256),
             chr(PEX_RES),
             socket.inet_aton('192.16.127.98'),  #KTH
             chr(20050 >> 8),
             chr(20050 % 256),
         ))
         self.socket.sendto(reply, addr)
Пример #19
0
 def test_distance(self):
     id1 = Id(BIN_ID1)
     id2 = Id(BIN_ID2)
     dist1_2 = Id(DIST1_2)
     assert id1.distance(id2).bin_id == dist1_2.bin_id
     assert id2.distance(id1).bin_id == dist1_2.bin_id 
Пример #20
0
 def test_has_repr(self):
     eq_(repr(Id(BIN_ID1)), '01' * ID_SIZE_BYTES)
Пример #21
0
    def test_order_closest(self):
        id0 = Id(BIN_ID0)
        ordered_list = [
            Id('\x00' * ID_SIZE_BYTES),
            Id(BIN_ID0[:-1] + '\x06'),
            Id(BIN_ID0[:9] + '\x01' * (ID_SIZE_BYTES - 9)),
            Id(BIN_ID0[:7] + '\xff' * (ID_SIZE_BYTES - 7)),
            Id(BIN_ID0[:7] + '\xff' * (ID_SIZE_BYTES - 7)),
            Id('\x00' + '\xff' * (ID_SIZE_BYTES - 1)),
            Id('\x53' * ID_SIZE_BYTES),
            Id('\xff' * ID_SIZE_BYTES),
        ]
        random_list = random.sample(ordered_list, len(ordered_list))

        random_list_copy = random_list[:]

        logger.debug('ordered list')
        for e in ordered_list:
            logger.debug('%s' % e)
        logger.debug('random order')
        for e in random_list:
            logger.debug('%s' % e)

        result_list = id0.order_closest(random_list)
        logger.debug('order_closest result')
        for e in result_list:
            logger.debug('%s' % e)
        logger.debug('random order (it should not change)')
        for e in random_list:
            logger.debug('%s' % e)

        # make sure order_closest does not modify random_list
        assert random_list == random_list_copy

        for i, ordered_id in enumerate(ordered_list):
            logger.debug('%d, %s, %s' % (i, ordered_id, result_list[i]))
            assert ordered_id.bin_id == result_list[i].bin_id
Пример #22
0
    def test_log_distance(self):
        id0 = Id(BIN_ID0)
        id1 = Id(BIN_ID1)
        id2 = Id(BIN_ID2)
        eq_(id0.log_distance(id0), -1)
        eq_(id0.log_distance(id1), ID_SIZE_BITS - 8)
        eq_(id0.log_distance(id2), ID_SIZE_BITS - 7)

        id_log = (
            (Id('\x00' + '\xff' * (ID_SIZE_BYTES - 1)),
             BITS_PER_BYTE * (ID_SIZE_BYTES - 1) - 1),
            
            (Id('\x53' * ID_SIZE_BYTES),
            BITS_PER_BYTE * ID_SIZE_BYTES - 2),
            
            (Id(BIN_ID0[:7] + '\xff' * (ID_SIZE_BYTES - 7)),
             (ID_SIZE_BYTES - 7) * BITS_PER_BYTE - 1),
            
            (Id(BIN_ID0[:9] + '\x01' * (ID_SIZE_BYTES - 9)),
             (ID_SIZE_BYTES - 10) * BITS_PER_BYTE),
            
            (Id(BIN_ID0[:-1] + '\x06'),
             2),
            )
        id2_log = (
            (Id('\x41' * ID_SIZE_BYTES),
             Id('\x41' * ID_SIZE_BYTES),
             -1),

            (Id('\x41' * ID_SIZE_BYTES),
             Id('\x01' * ID_SIZE_BYTES),
             158),

            (Id('\x41' * ID_SIZE_BYTES),
             Id('\x43' * ID_SIZE_BYTES),
             153),
            )

        for (id_, log_) in id_log:
            logger.debug('log_distance: %d' % id0.log_distance(id_))
            logger.debug('expected: %d' % log_)
            eq_(id0.log_distance(id_), log_)
        for id1, id2, expected in id2_log:
            eq_(id1.log_distance(id2), expected)

            z = Id('\0'*20)
            eq_(z.log_distance(Id('\x00'*19+'\x00')), -1)
            eq_(z.log_distance(Id('\x00'*19+'\x00')), -1)
            eq_(z.log_distance(Id('\x00'*19+'\x00')), -1)
            eq_(z.log_distance(Id('\x00'*19+'\x00')), -1)
            eq_(z.log_distance(Id('\x00'*19+'\x00')), -1)
Пример #23
0
from nose.tools import ok_, eq_, raises, assert_raises
import test_const as tc

import logging, logging_conf

import utils
from identifier import Id, ID_SIZE_BYTES
from node import Node, RoutingNode
import node

logging_conf.testing_setup(__name__)
logger = logging.getLogger('dht')

bin_id1 = '1' * ID_SIZE_BYTES
bin_id2 = '2' * ID_SIZE_BYTES
id1 = Id(bin_id1)
id2 = Id(bin_id2)
addr1 = ('127.0.0.1', 1111)
addr2 = ('127.0.0.1', 2222)


class TestNode:
    def setup(self):
        pass

    def test_node(self):
        node1 = Node(addr1, id1)
        node2 = Node(addr2, id2)
        node1b = Node(addr1, None)
        node1ip = Node(('127.0.0.2', 1111), id1)
        node1port = Node(addr2, id1)
Пример #24
0
              for i in xrange(100, 100+NUM_NODES)]
NODES2 = [node.Node(addr, node_id) \
              for addr, node_id in zip(ADDRS2, NODE2_IDS)]
PEERS2 = ADDRS2

IPS = ['1.2.3.' + str(i) for i in xrange(NUM_NODES)]

#TODO2: make this faster
num_nodes_per_ld = 20
NODES_LD_IH = [[]] * BITS_PER_BYTE
for ld in xrange(BITS_PER_BYTE, ID_SIZE_BITS):
    NODES_LD_IH.append([])
    common_id = INFO_HASH_ZERO.generate_close_id(ld)
    #eq_(common_id.log_distance(INFO_HASH_ZERO), ld)
    for i in xrange(num_nodes_per_ld):
        this_id = Id(common_id.bin_id[:-1] + chr(i))
        #eq_(this_id.log_distance(INFO_HASH_ZERO), ld)
        NODES_LD_IH[ld].append(
            node.Node(('128.0.0.' + str(i), ld), this_id))
num_nodes_per_ld = 50
NODES_LD_CL = [[]] * BITS_PER_BYTE
for ld in xrange(BITS_PER_BYTE, ID_SIZE_BITS):
    NODES_LD_CL.append([])
    common_id = CLIENT_ID.generate_close_id(ld)
    #eq_(common_id.log_distance(INFO_HASH_ZERO), ld)
    for i in xrange(num_nodes_per_ld):
        this_id = Id(common_id.bin_id[:-1] + chr(i))
        #eq_(this_id.log_distance(INFO_HASH_ZERO), ld)
        NODES_LD_CL[ld].append(
            node.Node(('128.0.0.' + str(i), ld), this_id))
Пример #25
0
 def test_bin_id(self):
     assert Id(BIN_ID1).bin_id == BIN_ID1
Пример #26
0
 def _get_id(self, k, kk=None):
     v = self._get_str(k, kk)
     try:
         return Id(v)
     except (IdError):
         raise MsgError('Value (%s:%s,%s) must be a valid Id' % (k, kk, v))
Пример #27
0
 def test_has_repr(self):
     eq_(repr(Id(BIN_ID1)), '<Id: ' + '01' * ID_SIZE_BYTES + '>')