-
Notifications
You must be signed in to change notification settings - Fork 69
/
test_dht.py
executable file
·93 lines (70 loc) · 1.94 KB
/
test_dht.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/python
import socket
import select
import sys
from bencode import bencode, bdecode
import random
def send_dht_message(msg, target):
try:
s.sendto(bencode(msg), 0, target)
except:
print msg
def random_key():
ret = ''
for i in range(0, 20):
ret += chr(random.randint(0, 255))
return ret
def test_message(query, args, verify):
tid = random.randint(0, 255)
node_id = random_key()
print '%s %d -> %s:%d' % (query, tid, sys.argv[1], int(sys.argv[2]))
msg = {'a': {'id': node_id}, 'q': query, 'y': 'q', 't': '%d' % tid}
for k,v in args.iteritems():
msg['a'][k] = v
send_dht_message(msg, (sys.argv[1], int(sys.argv[2])))
while 1:
n = select.select([s], [], [s], 5)
ret = False
if len(n[0]) == 0:
print 'socket timed out'
print '\n\n=== FAILED ===\n\n'
return False
# the socket became readable
response = s.recv(1000)
try:
response = bdecode(response)
if response['y'] != 'r':
print 'expected a response, received %s' % response
continue
# print '\n\n=== FAILED ===\n\n'
# return False
if response['t'] != '%d' % tid:
print 'incorrect tid: %s, expected %d' % (response['t'], tid)
print '\n\n=== FAILED ===\n\n'
return False
except:
print response
break
print '<-- ', response
ret = verify(response['r'])
if ret: print '*** Passed ***'
else: print '\n\n=== FAILED ===\n%s\n' % response
return ret
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
if len(sys.argv) < 3:
print 'usage: %s host port' % sys.argv[0]
sys.exit(1)
def verify_nodes(x):
if not 'nodes' in x:
print 'missing nodes entry'
return False
if len(x['nodes']) % (6+20) != 0:
print 'node response not divisible by 26 (%d)' % len(x['nodes'])
return False
print 'received %d nodes' % (len(x['nodes']) / 26)
return True
ret = True
print '=== TESTING DHT PING ==='
ret &= test_message('ping', {}, lambda x: True)
ret &= test_message('find_node', {'target': random_key()}, verify_nodes)
sys.exit(ret)