def _test_bad(self,gen_drequest_func): options = '\x00\x00\x00\x00\x00\x10\x00\x00' s = BTConnection('localhost',self.hisport,user_option_pattern=options,user_infohash=self.infohash) print >> sys.stderr,"\ntest: ",gen_drequest_func hsmsg = self.create_good_tribler_extend_hs_v2() s.send(hsmsg) msg = gen_drequest_func() s.send(msg) time.sleep(5) # the other side should not like this and close the connection try: s.s.settimeout(10.0) s.read_handshake_medium_rare(close_ok = True) while True: resp = s.recv() if len(resp) > 0: print >>sys.stderr,"test: Got",getMessageName(resp[0]),"from peer" self.assert_(resp[0] == EXTEND or resp[0]==UNCHOKE) else: self.assert_(len(resp)==0) s.close() break except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't close connection" self.assert_(False)
def _test_response1(self, ss, gen_resp1, good): print >> sys.stderr, "test: myserver running:", gen_resp1 conn, addr = ss.accept() s = BTConnection('', 0, conn) s.read_handshake_medium_rare() # Read challenge msg = s.recv() self.testcase.assert_(msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) self.testcase.assert_(type(randomB) == StringType) self.testcase.assert_(len(randomB) == random_size) [randomA, resp1_data] = gen_resp1(randomB, s.get_his_id()) s.send(resp1_data) if good: # Read response2 msg = s.recv() self.testcase.assert_(msg[0] == RESPONSE2) self.check_response2(msg[1:], randomA, randomB, s.get_my_id()) # the connection should be intact, so this should not throw an # exception: time.sleep(5) s.send('bla') s.close() else: time.sleep(5) # the other side should not our bad RESPONSE1 this and close the # connection msg = s.recv() self.testcase.assert_(len(msg) == 0) s.close()
def singtest_connect_overlay(self): """ """ # 1. Accept the data connection Tribler wants to establish with us self.myss.settimeout(10.0) conn, addr = self.myss.accept() s = BTConnection('',0,conn,user_infohash=self.infohash,myid=self.myid) s.read_handshake_medium_rare() extmsg = self.create_good_tribler_extend_hs() s.send(extmsg) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr,"test: Data conn replies",getMessageName(resp[0]) # 2. Tribler should now try to establish an overlay connection with us self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' s2 = OLConnection(self.my_keypair,'',0,conn,mylistenport=self.mylistenport) # Desired behaviour is that the accept() succeeds. If not it will time # out, and throw an exception, causing this test to fail. time.sleep(3) s.close() s2.close()
class ConnecterConnection: def __init__(self,port): self.s = BTConnection('localhost',port) self.s.read_handshake_medium_rare() self.connection = EncrypterConnection(self.s.get_his_id()) def get_my_id(self): return self.s.get_my_id() def get_unauth_peer_id(self): return self.s.get_his_id() def is_locally_initiated(self): return True def send_message(self,msg): self.s.send(msg) def get_message(self): return self.s.recv() def set_permid(self,x): pass def set_auth_peer_id(self,x): pass def close(self): self.s.close()
def _test_good(self,msg_gen_func,options=None,infohash=None): if options is None and infohash is None: s = BTConnection('localhost',self.hisport) elif options is None: s = BTConnection('localhost',self.hisport,user_infohash=infohash) elif infohash is None: s = BTConnection('localhost',self.hisport,user_option_pattern=options) else: s = BTConnection('localhost',self.hisport,user_option_pattern=options,user_infohash=infohash) msg = msg_gen_func() s.send(msg) s.read_handshake_medium_rare() time.sleep(5) # Tribler should send an EXTEND message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >>sys.stderr,"test: Got reply",getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) #s.close() except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't reply with EXTEND message" self.assert_(False)
def subtest_old_tribler(self): # The tracker gives Tribler try: self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x10\x00\x00' s = BTConnection('', 0, conn, user_option_pattern=options, user_infohash=self.infohash, myid=self.myid) s.read_handshake_medium_rare() # Seeing that we're an T<=3.5.0 peer, he should directly # initiate an overlay conn with us conn2, addr2 = self.myss.accept() s2 = OLConnection(self.my_keypair, '', 0, conn2, self.mylistenport) time.sleep(5) # the other side should not have closed the connection, as # this is all valid, so this should not throw an exception: s.send('bla') s.close() s2.send('bla') s2.close() print >> sys.stderr, "test: Good, Tribler made overlay conn with us" except socket.timeout: print >> sys.stderr, "test: Bad, Tribler did not attempt to start an overlay conn with us" self.assert_(False)
def test_all(self): """ I want to start a Tribler client once and then connect to it many times. So there must be only one test method to prevent setUp() from creating a new client every time. The code is constructed so unittest will show the name of the (sub)test where the error occured in the traceback it prints. """ # myid needs to identify the connection as Tribler in order to # get the 'same' bit added.f myid = TRIBLER_PEERID_LETTER + "".join(map(chr, range(19))) # Create a fake other client, so the EXTEND ut_pex won't be empty msg2 = self.create_good_nontribler_extend_hs(listenport=4321) s2 = BTConnection('localhost',self.hisport,mylistenport=4321,user_option_pattern='\x00\x00\x00\x00\x00\x10\x00\x00',user_infohash=self.infohash,myid=myid) s2.read_handshake_medium_rare() s2.send(msg2) self.subtest_good_nontribler_ut_pex() self.subtest_good_nontribler_ut_pex_diff_id() self.subtest_good_tribler_ut_pex() self.subtest_bad_ut_pex() # now we add a second non-tribler peer. this peer should also # be in the pex message but should not have the 'same' bit set myid = "X" + "".join(map(chr, range(19))) msg3 = self.create_good_nontribler_extend_hs(listenport=4322) s3 = BTConnection('localhost',self.hisport,mylistenport=4322,user_option_pattern='\x00\x00\x00\x00\x00\x10\x00\x00',user_infohash=self.infohash,myid=myid) s3.read_handshake_medium_rare() s3.send(msg3) self.subtest_good_nontribler_ut_pex_same_and_nonsame()
def _test_response1(self,ss,gen_resp1,good): print >>sys.stderr,"test: myserver running:",gen_resp1 conn, addr = ss.accept() s = BTConnection('',0,conn) s.read_handshake_medium_rare() # Read challenge msg = s.recv() self.testcase.assert_(msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) self.testcase.assert_(type(randomB) == StringType) self.testcase.assert_(len(randomB) == random_size) [randomA,resp1_data] = gen_resp1(randomB,s.get_his_id()) s.send(resp1_data) if good: # Read response2 msg = s.recv() self.testcase.assert_(msg[0] == RESPONSE2) self.check_response2(msg[1:],randomA,randomB,s.get_my_id()) # the connection should be intact, so this should not throw an # exception: time.sleep(5) s.send('bla') s.close() else: time.sleep(5) # the other side should not our bad RESPONSE1 this and close the # connection msg = s.recv() self.testcase.assert_(len(msg)==0) s.close()
def subtest_old_tribler(self): # The tracker gives Tribler try: self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x10\x00\x00' s = BTConnection('',0,conn,user_option_pattern=options,user_infohash=self.infohash,myid=self.myid) s.read_handshake_medium_rare() # Seeing that we're an T<=3.5.0 peer, he should directly # initiate an overlay conn with us conn2, addr2 = self.myss.accept() s2 = OLConnection(self.my_keypair,'',0,conn2,self.mylistenport) time.sleep(5) # the other side should not have closed the connection, as # this is all valid, so this should not throw an exception: s.send('bla') s.close() s2.send('bla') s2.close() print >> sys.stderr,"test: Good, Tribler made overlay conn with us" except socket.timeout: print >> sys.stderr,"test: Bad, Tribler did not attempt to start an overlay conn with us" self.assert_(False)
def _test_good(self, msg_gen_func, options=None, infohash=None): if options is None and infohash is None: s = BTConnection('localhost', self.hisport) elif options is None: s = BTConnection('localhost', self.hisport, user_infohash=infohash) elif infohash is None: s = BTConnection('localhost', self.hisport, user_option_pattern=options) else: s = BTConnection('localhost', self.hisport, user_option_pattern=options, user_infohash=infohash) msg = msg_gen_func() s.send(msg) s.read_handshake_medium_rare() time.sleep(5) # Tribler should send an EXTEND message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) #s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply with EXTEND message" self.assert_(False)
class ConnecterConnection: def __init__(self, port): self.s = BTConnection('localhost', port) self.s.read_handshake_medium_rare() self.connection = EncrypterConnection(self.s.get_his_id()) def get_my_id(self): return self.s.get_my_id() def get_unauth_peer_id(self): return self.s.get_his_id() def is_locally_initiated(self): return True def send_message(self, msg): self.s.send(msg) def get_message(self): return self.s.recv() def set_permid(self, x): pass def set_auth_peer_id(self, x): pass def close(self): self.s.close()
def bad_request_and_disconnect(self, payload): conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) conn.send(EXTEND + chr(metadata_id) + bencode(payload)) self.read_extend_metadata_close(conn)
def _test_bad_challenge(self, gen_chal_func): s = BTConnection('localhost', self.hisport) s.read_handshake() [rB, chal_data] = gen_chal_func() s.send(chal_data) time.sleep(5) # the other side should not like this and close the connection msg = s.recv() self.assert_(len(msg) == 0) s.close()
def bad_request_and_disconnect(self, payload): conn = BTConnection("localhost", self.session.get_listen_port(), user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) conn.send(EXTEND + chr(metadata_id) + bencode(payload)) self.read_extend_metadata_close(conn)
def _test_bad_challenge(self, gen_chal_func): s = BTConnection("localhost", self.hisport) s.read_handshake() [rB, chal_data] = gen_chal_func() s.send(chal_data) time.sleep(5) # the other side should not like this and close the connection msg = s.recv() self.assert_(len(msg) == 0) s.close()
def _test_good(self,msg_gen_func,options=None,infohash=None,g2g_id=G2G_ID): if options is None and infohash is None: s = BTConnection('localhost',self.hisport) elif options is None: s = BTConnection('localhost',self.hisport,user_infohash=infohash) elif infohash is None: s = BTConnection('localhost',self.hisport,user_option_pattern=options) else: s = BTConnection('localhost',self.hisport,user_option_pattern=options,user_infohash=infohash) if DEBUG: print "test: Creating test HS message",msg_gen_func,"g2g_id",g2g_id msg = msg_gen_func(g2g_id=g2g_id) s.send(msg) s.read_handshake_medium_rare() # Send our g2g_v2 message to Tribler msg = self.create_good_g2g_v2(g2g_id=g2g_id) s.send(msg) time.sleep(5) # Tribler should send an EXTEND HS message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs_v2(resp[1:]) except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't reply with EXTEND HS message" self.assert_(False) # Tribler should send an g2g_v2 message after a while print "test: Setting 60 second timeout to see if Tribler sends periodic g2g_v2" # Extreme h4xor connlist = self.d.sd.dow.connecter.connections.values()[:] piece = '\xab' * (2 ** 14) for conn in connlist: conn.queue_g2g_piece_xfer(0,0,piece) try: s.s.settimeout(70.0) while True: resp = s.recv() self.assert_(len(resp) > 0) print "test: Tribler returns",getMessageName(resp[0]) if resp[0] == EXTEND: self.check_g2g_v2(resp[1:],g2g_id=g2g_id) s.close() break except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't reply with EXTEND g2g_v2 message" self.assert_(False)
def _test_good(self, msg_gen_func, options=None, infohash=None): print >> sys.stderr, "test: test good, gen_func", msg_gen_func if options is None and infohash is None: s = BTConnection("localhost", self.hisport, myid=self.myid) elif options is None: s = BTConnection("localhost", self.hisport, user_infohash=infohash, myid=self.myid) elif infohash is None: s = BTConnection("localhost", self.hisport, user_option_pattern=options, myid=self.myid) else: s = BTConnection( "localhost", self.hisport, user_option_pattern=options, user_infohash=infohash, myid=self.myid ) msg = msg_gen_func() s.send(msg) s.read_handshake_medium_rare() time.sleep(5) # Tribler should send an EXTEND message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply with EXTEND message" self.assert_(False) # Tribler should try to connect to our internal interface self.destss.settimeout(10.0) conn, addr = self.destss.accept() s2 = BTConnection("", 0, conn, user_infohash=self.infohash, myid=self.myid) s2.send(INTERESTED) s2.read_handshake_medium_rare() # Is it him? self.assert_(s.hisid == s2.hisid) # He should close original conn try: while True: resp = s.recv() if len(resp) > 0: print >> sys.stderr, "test: Got data on internal conn", getMessageName(resp[0]) else: break except socket.timeout: self.assert_(False) self.assert_(True)
def _test_dreply(self, gen_dreply, good, diff_ips_test=False): for i in range(self.NLISTENERS): print >> sys.stderr, "test: waiting for #", i, "listenport", self.mylistenport[ i] conn, addr = self.myss[i].accept() s = OLConnection(self.mykeypairs[i], '', 0, conn, self.mylistenport[i]) while True: msg = s.recv() self.assert_(len(msg) > 0) print >> sys.stderr, "test: Received overlay message", getMessageName( msg[0]) if msg[0] == DIALBACK_REQUEST: break self.assert_(msg[0] == DIALBACK_REQUEST) self.check_drequest(msg[1:]) # Proper behaviour is to try to send a reply using a new return connection s2 = BTConnection('localhost', self.hisport, mylistenport=self.mylistenport[i], user_infohash=dialback_infohash) s2.read_handshake_medium_rare(close_ok=True) if gen_dreply is not None: resp = gen_dreply(i) print >> sys.stderr, "test: sending DIALBACK_REPLY #", i s2.send(resp) time.sleep(2) # the other side should always close the # connection, either because we're done or he didn't like our # bad DIALBACK_REPLY message msg = s2.recv() if len(msg) > 0: print >> sys.stderr, "test: Received unexpected data", getMessageName( msg[0]) self.assert_(len(msg) == 0) s2.close() # Not really necessary, but helps with test_dialback_active2 s.close() ext_ip = self.session.get_external_ip() print >> sys.stderr, "test: External IP address after test is", ext_ip if diff_ips_test: if self.config.sessconfig['dialback_trust_superpeers'] == 1: good = True else: good = False if good: self.assert_(ext_ip == REPLY_IP) else: self.assert_(ext_ip == self.myoriginalip)
def _test_good(self, msg_gen_func, options=None, infohash=None, pex_id=1): if options is None and infohash is None: s = BTConnection('localhost', self.hisport) elif options is None: s = BTConnection('localhost', self.hisport, user_infohash=infohash) elif infohash is None: s = BTConnection('localhost', self.hisport, user_option_pattern=options) else: s = BTConnection('localhost', self.hisport, user_option_pattern=options, user_infohash=infohash) if DEBUG: print "test: Creating test HS message", msg_gen_func, "pex_id", pex_id msg = msg_gen_func(pex_id=pex_id) s.send(msg) s.read_handshake_medium_rare() # Send our ut_pex message to Tribler msg = self.create_good_ut_pex(pex_id=pex_id) s.send(msg) time.sleep(5) # Tribler should send an EXTEND HS message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply with EXTEND HS message" self.assert_(False) # Tribler should send an ut_pex message after a while print "test: Setting 60 second timeout to see if Tribler sends periodic ut_pex" try: s.s.settimeout(70.0) while True: resp = s.recv() self.assert_(len(resp) > 0) print "test: Tribler returns", getMessageName(resp[0]) if resp[0] == EXTEND: self.check_ut_pex(resp[1:], pex_id=pex_id) s.close() break except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply with EXTEND ut_pex message" self.assert_(False)
def _test_good(self,msg_gen_func,options=None,infohash=None): print >>sys.stderr,"test: test good, gen_func",msg_gen_func if options is None and infohash is None: s = BTConnection('localhost',self.hisport,myid=self.myid) elif options is None: s = BTConnection('localhost',self.hisport,user_infohash=infohash,myid=self.myid) elif infohash is None: s = BTConnection('localhost',self.hisport,user_option_pattern=options,myid=self.myid) else: s = BTConnection('localhost',self.hisport,user_option_pattern=options,user_infohash=infohash,myid=self.myid) msg = msg_gen_func() s.send(msg) s.read_handshake_medium_rare() time.sleep(5) # Tribler should send an EXTEND message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >>sys.stderr,"test: Got reply",getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) #s.close() except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't reply with EXTEND message" self.assert_(False) # Tribler should try to connect to our internal interface self.destss.settimeout(10.0) conn, addr = self.destss.accept() s2 = BTConnection('',0,conn,user_infohash=self.infohash,myid=self.myid) s2.send(INTERESTED) s2.read_handshake_medium_rare() # Is it him? self.assert_(s.hisid == s2.hisid) # He should close original conn try: while True: resp = s.recv() if len(resp) > 0: print >>sys.stderr,"test: Got data on internal conn",getMessageName(resp[0]) else: break except socket.timeout: self.assert_(False) self.assert_(True)
def subtest_good_flood(self): conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) for counter in xrange(len(self.metadata_list) * 2): piece = counter % len(self.metadata_list) conn.send(self.create_good_extend_metadata_request(metadata_id, piece)) if counter > len(self.metadata_list): self.read_extend_metadata_reject(conn, piece) else: self.read_extend_metadata_reply(conn, piece)
def test_good_transfer(self): def torrentdef_retrieved(meta_info): tags["metainfo"] = meta_info tags["retrieved"].set() tags = {"retrieved": threading.Event()} self.session.lm.ltmgr.get_metainfo(self.create_good_url(), torrentdef_retrieved, timeout=60) def do_supply(): # supply fake addresses (regular dht obviously wont work here) ltmgr = LibtorrentMgr.getInstance() for infohash in ltmgr.metainfo_requests: handle = ltmgr.ltsession.find_torrent( lt.big_number(infohash.decode('hex'))) handle.connect_peer( ("127.0.0.1", self.session.get_listen_port()), 0) self.session.lm.threadpool.add_task(do_supply, delay=5.0) # accept incoming connection # self.server.settimeout(10.0) sock, address = self.server.accept() assert sock, "No incoming connection" # handshakes conn = BTConnection(address[0], address[1], opensock=sock, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) # serve pieces for counter in xrange(len(self.metadata_list)): piece = self.read_extend_metadata_request(conn) assert 0 <= piece < len(self.metadata_list) conn.send( self.create_good_extend_metadata_reply(metadata_id, piece)) # no more metadata request may be send and the connection must # be closed self.read_extend_metadata_close(conn) assert tags["retrieved"].wait(5) assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
def _test_dreply(self,gen_dreply,good,diff_ips_test=False): for i in range(self.NLISTENERS): print >> sys.stderr,"test: waiting for #",i,"listenport",self.mylistenport[i] conn, addr = self.myss[i].accept() s = OLConnection(self.mykeypairs[i],'',0,conn,self.mylistenport[i]) while True: msg = s.recv() self.assert_(len(msg) > 0) print >> sys.stderr,"test: Received overlay message",getMessageName(msg[0]) if msg[0] == DIALBACK_REQUEST: break self.assert_(msg[0] == DIALBACK_REQUEST) self.check_drequest(msg[1:]) # Proper behaviour is to try to send a reply using a new return connection s2 = BTConnection('localhost',self.hisport,mylistenport=self.mylistenport[i],user_infohash=dialback_infohash) s2.read_handshake_medium_rare(close_ok = True) if gen_dreply is not None: resp = gen_dreply(i) print >> sys.stderr,"test: sending DIALBACK_REPLY #",i s2.send(resp) time.sleep(2) # the other side should always close the # connection, either because we're done or he didn't like our # bad DIALBACK_REPLY message msg = s2.recv() if len(msg) > 0: print >> sys.stderr,"test: Received unexpected data",getMessageName(msg[0]) self.assert_(len(msg)==0) s2.close() # Not really necessary, but helps with test_dialback_active2 s.close() ext_ip = self.session.get_external_ip() print >>sys.stderr,"test: External IP address after test is",ext_ip if diff_ips_test: if self.config.sessconfig['dialback_trust_superpeers'] == 1: good = True else: good = False if good: self.assert_(ext_ip == REPLY_IP) else: self.assert_(ext_ip == self.myoriginalip)
def _test_good(self,msg_gen_func,options=None,infohash=None,pex_id=1,connections={"tribler":1,"non-tribler":0}): if options is None and infohash is None: s = BTConnection('localhost',self.hisport) elif options is None: s = BTConnection('localhost',self.hisport,user_infohash=infohash) elif infohash is None: s = BTConnection('localhost',self.hisport,user_option_pattern=options) else: s = BTConnection('localhost',self.hisport,user_option_pattern=options,user_infohash=infohash) if DEBUG: print "test: Creating test HS message",msg_gen_func,"pex_id",pex_id msg = msg_gen_func(pex_id=pex_id) s.send(msg) s.read_handshake_medium_rare() # Send our ut_pex message to Tribler msg = self.create_good_ut_pex() s.send(msg) time.sleep(5) # Tribler should send an EXTEND HS message back try: s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) except socket.timeout: print >> sys.stderr,time.asctime(),'-', "test: Timeout, bad, peer didn't reply with EXTEND HS message" self.assert_(False) # Tribler should send an ut_pex message after a while print "test: Setting 60 second timeout to see if Tribler sends periodic ut_pex" try: s.s.settimeout(70.0) while True: resp = s.recv() self.assert_(len(resp) > 0) print "test: Tribler returns",getMessageName(resp[0]) if resp[0] == EXTEND: self.check_ut_pex(resp[1:],pex_id,connections) s.close() break except socket.timeout: print >> sys.stderr,time.asctime(),'-', "test: Timeout, bad, peer didn't reply with EXTEND ut_pex message" self.assert_(False)
def _test_bad_response2(self, gen_resp2_func): print >> sys.stderr, "test: bad response2", gen_resp2_func s = BTConnection('localhost', self.hisport) s.read_handshake() [rB, chal_data] = self.create_good_challenge() s.send(chal_data) resp1_data = s.recv() self.assert_(resp1_data[0] == RESPONSE1) resp1_dict = self.check_response1(resp1_data[1:], rB, s.get_my_id()) resp2_data = gen_resp2_func(rB, resp1_dict, s.get_his_id()) s.send(resp2_data) time.sleep(5) # the other side should not like this and close the connection msg = s.recv() self.assert_(len(msg) == 0) s.close()
def _test_bad_response2(self, gen_resp2_func): print >>sys.stderr, time.asctime(), "-", "test: bad response2", gen_resp2_func s = BTConnection("localhost", self.hisport) s.read_handshake() [rB, chal_data] = self.create_good_challenge() s.send(chal_data) resp1_data = s.recv() self.assert_(resp1_data[0] == RESPONSE1) resp1_dict = self.check_response1(resp1_data[1:], rB, s.get_my_id()) resp2_data = gen_resp2_func(rB, resp1_dict, s.get_his_id()) s.send(resp2_data) time.sleep(5) # the other side should not like this and close the connection msg = s.recv() self.assert_(len(msg) == 0) s.close()
def test_good_flood(self): conn = BTConnection("localhost", self.session.get_listen_port(), user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) for counter in xrange(len(self.metadata_list) * 2): piece = counter % len(self.metadata_list) conn.send( self.create_good_extend_metadata_request(metadata_id, piece)) if counter > len(self.metadata_list): self.read_extend_metadata_reject(conn, piece) else: self.read_extend_metadata_reply(conn, piece)
def test_all(self): """ I want to start a Tribler client once and then connect to it many times. So there must be only one test method to prevent setUp() from creating a new client every time. The code is constructed so unittest will show the name of the (sub)test where the error occured in the traceback it prints. """ # myid needs to identify the connection as Tribler in order to # get the 'same' bit added.f myid = TRIBLER_PEERID_LETTER + "".join(map(chr, range(19))) # Create a fake other client, so the EXTEND ut_pex won't be empty msg2 = self.create_good_nontribler_extend_hs(listenport=4321) s2 = BTConnection( 'localhost', self.hisport, mylistenport=4321, user_option_pattern='\x00\x00\x00\x00\x00\x10\x00\x00', user_infohash=self.infohash, myid=myid) s2.read_handshake_medium_rare() s2.send(msg2) self.subtest_good_nontribler_ut_pex() self.subtest_good_nontribler_ut_pex_diff_id() self.subtest_good_tribler_ut_pex() self.subtest_bad_ut_pex() # now we add a second non-tribler peer. this peer should also # be in the pex message but should not have the 'same' bit set myid = "X" + "".join(map(chr, range(19))) msg3 = self.create_good_nontribler_extend_hs(listenport=4322) s3 = BTConnection( 'localhost', self.hisport, mylistenport=4322, user_option_pattern='\x00\x00\x00\x00\x00\x10\x00\x00', user_infohash=self.infohash, myid=myid) s3.read_handshake_medium_rare() s3.send(msg3) self.subtest_good_nontribler_ut_pex_same_and_nonsame()
def test_all(self): """ I want to start a Tribler client once and then connect to it many times. So there must be only one test method to prevent setUp() from creating a new client every time. The code is constructed so unittest will show the name of the (sub)test where the error occured in the traceback it prints. """ # Create a fake other client, so the EXTEND ut_pex won't be empty msg2 = self.create_good_nontribler_extend_hs(listenport=4321) s2 = BTConnection('localhost',self.hisport,mylistenport=4321,user_option_pattern='\x00\x00\x00\x00\x00\x10\x00\x00',user_infohash=self.infohash) s2.read_handshake_medium_rare() s2.send(msg2) self.subtest_good_nontribler_ut_pex() self.subtest_good_nontribler_ut_pex_diff_id() self.subtest_good_tribler_ut_pex() self.subtest_bad_ut_pex()
def test_good_transfer(self): def torrentdef_retrieved(tdef): tags["retrieved"] = True tags["metainfo"] = tdef.get_metainfo() tags = {"retrieved": False} assert TorrentDef.retrieve_from_magnet(self.create_good_url(), torrentdef_retrieved) # supply fake addresses (regular dht obviously wont work here) for magnetlink in MagnetHandler.get_instance().get_magnets(): magnetlink._swarm.add_potential_peers([("localhost", LISTEN_PORT)]) # accept incoming connection self.server.settimeout(10.0) sock, address = self.server.accept() assert sock, "No incoming connection" # handshakes conn = BTConnection(address[0], address[1], opensock=sock, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) # serve pieces for counter in xrange(len(self.metadata_list)): piece = self.read_extend_metadata_request(conn) assert 0 <= piece < len(self.metadata_list) conn.send( self.create_good_extend_metadata_reply(metadata_id, piece)) # no more metadata request may be send and the connection must # be closed self.read_extend_metadata_close(conn) time.sleep(5) assert tags["retrieved"] assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
def test_good_transfer(self): def torrentdef_retrieved(tdef): tags["retrieved"].set() tags["metainfo"] = tdef.get_metainfo() tags = {"retrieved": threading.Event()} assert TorrentDef.retrieve_from_magnet(self.create_good_url(), torrentdef_retrieved, timeout=60) def do_supply(): # supply fake addresses (regular dht obviously wont work here) ltmgr = LibtorrentMgr.getInstance() for infohash in ltmgr.metainfo_requests: handle = ltmgr.ltsession.find_torrent(lt.big_number(infohash.decode('hex'))) handle.connect_peer(("127.0.0.1", LISTEN_PORT), 0) self.session.lm.rawserver.add_task(do_supply, delay=5.0) # accept incoming connection # self.server.settimeout(10.0) sock, address = self.server.accept() assert sock, "No incoming connection" # handshakes conn = BTConnection(address[0], address[1], opensock=sock, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) # serve pieces for counter in xrange(len(self.metadata_list)): piece = self.read_extend_metadata_request(conn) assert 0 <= piece < len(self.metadata_list) conn.send(self.create_good_extend_metadata_reply(metadata_id, piece)) # no more metadata request may be send and the connection must # be closed self.read_extend_metadata_close(conn) assert tags["retrieved"].wait(5) assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
def _test_good_request(self): options = '\x00\x00\x00\x00\x00\x10\x00\x00' myid = Rand.rand_bytes(20) s = BTConnection('localhost', self.hisport, user_option_pattern=options, user_infohash=self.infohash, myid=myid) msg = self.create_good_nontribler_extend_hs() s.send(msg) s.read_handshake_medium_rare() # Tribler should send an EXTEND message back try: print >> sys.stderr, "test: Waiting for reply" s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # 1. Pretend we're leecher: send INTERESTED msg = INTERESTED s.send(msg) print >> sys.stderr, "test: Pretend we are leecher" while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply2", getMessageName(resp[0]) if resp[0] == EXTEND: print >> sys.stderr, "test: Got EXTEND type", getMessageName(resp[1]) self.assert_(resp[0] == UNCHOKE or resp[0] == BITFIELD or resp[0] == EXTEND or resp[0] == HAVE) if resp[0] == UNCHOKE: # 2. Reply with REQUESTs for index in range(0, self.numpieces): plen = self.get_piece_length(index) for begin in range(0, plen, 2 ** 14): length = self.get_chunk_length(index, begin) print >> sys.stderr, "RETRIEVE", index, begin, length chunkid = (index, begin, length) msg = self.create_request(chunkid) s.send(msg) # s.send(NOT_INTERESTED) elif resp[0] == EXTEND and resp[1] == HASHPIECE: done = self.check_hashpiece(resp) if done: break elif resp[0] == BITFIELD: self.check_bitfield(resp) # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply in time" self.assert_(False) time.sleep(3) s.close()
def _test_good_request(self): options = "\x00\x00\x00\x00\x00\x10\x00\x00" myid = Rand.rand_bytes(20) s = BTConnection("localhost", self.hisport, user_option_pattern=options, user_infohash=self.infohash, myid=myid) msg = self.create_good_nontribler_extend_hs() s.send(msg) s.read_handshake_medium_rare() # Tribler should send an EXTEND message back try: print >> sys.stderr, "test: Waiting for reply" s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # 1. Pretend we're leecher: send INTERESTED msg = INTERESTED s.send(msg) print >> sys.stderr, "test: Pretend we are leecher" while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply2", getMessageName(resp[0]) if resp[0] == EXTEND: print >> sys.stderr, "test: Got EXTEND type", getMessageName(resp[1]) self.assert_(resp[0] == UNCHOKE or resp[0] == BITFIELD or resp[0] == EXTEND or resp[0] == HAVE) if resp[0] == UNCHOKE: # 2. Reply with REQUESTs for index in range(0, self.numpieces): plen = self.get_piece_length(index) for begin in range(0, plen, 2 ** 14): length = self.get_chunk_length(index, begin) print >> sys.stderr, "RETRIEVE", index, begin, length chunkid = (index, begin, length) msg = self.create_request(chunkid) s.send(msg) # s.send(NOT_INTERESTED) elif resp[0] == EXTEND and resp[1] == HASHPIECE: done = self.check_hashpiece(resp) if done: break elif resp[0] == BITFIELD: self.check_bitfield(resp) # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply in time" self.assert_(False) time.sleep(3) s.close()
def subtest_good_request(self): conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) # request metadata block 0, 2, 3, and the last conn.send(self.create_good_extend_metadata_request(metadata_id, 0)) conn.send(self.create_good_extend_metadata_request(metadata_id, 2)) conn.send(self.create_good_extend_metadata_request(metadata_id, 3)) conn.send(self.create_good_extend_metadata_request(metadata_id, len(self.metadata_list) - 1)) self.read_extend_metadata_reply(conn, 0) self.read_extend_metadata_reply(conn, 2) self.read_extend_metadata_reply(conn, 3) self.read_extend_metadata_reply(conn, len(self.metadata_list) - 1)
def test_good_transfer(self): def torrentdef_retrieved(tdef): tags["retrieved"] = True tags["metainfo"] = tdef.get_metainfo() tags = {"retrieved":False} assert TorrentDef.retrieve_from_magnet(self.create_good_url(), torrentdef_retrieved) # supply fake addresses (regular dht obviously wont work here) for magnetlink in MagnetHandler.get_instance().get_magnets(): magnetlink._swarm.add_potential_peers([("localhost", LISTEN_PORT)]) # accept incoming connection self.server.settimeout(10.0) sock, address = self.server.accept() assert sock, "No incoming connection" # handshakes conn = BTConnection(address[0], address[1], opensock=sock, user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) # serve pieces for counter in xrange(len(self.metadata_list)): piece = self.read_extend_metadata_request(conn) assert 0 <= piece < len(self.metadata_list) conn.send(self.create_good_extend_metadata_reply(metadata_id, piece)) # no more metadata request may be send and the connection must # be closed self.read_extend_metadata_close(conn) time.sleep(5) assert tags["retrieved"] assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
def test_all(self): """ I want to start a Tribler client once and then connect to it many times. So there must be only one test method to prevent setUp() from creating a new client every time. The code is constructed so unittest will show the name of the (sub)test where the error occured in the traceback it prints. """ # Create a fake other client, so the EXTEND ut_pex won't be empty msg2 = self.create_good_nontribler_extend_hs(listenport=4321) s2 = BTConnection( 'localhost', self.hisport, mylistenport=4321, user_option_pattern='\x00\x00\x00\x00\x00\x10\x00\x00', user_infohash=self.infohash) s2.read_handshake_medium_rare() s2.send(msg2) self.subtest_good_nontribler_ut_pex() self.subtest_good_nontribler_ut_pex_diff_id() self.subtest_good_tribler_ut_pex() self.subtest_bad_ut_pex()
def test_good_request(self): conn = BTConnection("localhost", self.session.get_listen_port(), user_infohash=self.tdef.get_infohash()) conn.send(self.create_good_extend_handshake()) conn.read_handshake_medium_rare() metadata_id = self.read_extend_handshake(conn) # request metadata block 0, 2, 3, and the last conn.send(self.create_good_extend_metadata_request(metadata_id, 0)) conn.send(self.create_good_extend_metadata_request(metadata_id, 2)) conn.send(self.create_good_extend_metadata_request(metadata_id, 3)) conn.send( self.create_good_extend_metadata_request( metadata_id, len(self.metadata_list) - 1)) self.read_extend_metadata_reply(conn, 0) self.read_extend_metadata_reply(conn, 2) self.read_extend_metadata_reply(conn, 3) self.read_extend_metadata_reply(conn, len(self.metadata_list) - 1)
def subtest_good_challenge_response2(self): """ test good challenge and response2 messages """ print >> sys.stderr, "test: good challenge/response" s = BTConnection('localhost', self.hisport) s.read_handshake() [rB, chal_data] = self.create_good_challenge() s.send(chal_data) resp1_data = s.recv() self.assert_(resp1_data[0] == RESPONSE1) resp1_dict = self.check_response1(resp1_data[1:], rB, s.get_my_id()) resp2_data = self.create_good_response2(rB, resp1_dict, s.get_his_id()) s.send(resp2_data) time.sleep(10) # the other side should not have closed the connection, as # this is all valid, so this should not throw an exception: s.send('bla') s.close()
def subtest_good_challenge_response2(self): """ test good challenge and response2 messages """ print >>sys.stderr, time.asctime(), "-", "test: good challenge/response" s = BTConnection("localhost", self.hisport) s.read_handshake() [rB, chal_data] = self.create_good_challenge() s.send(chal_data) resp1_data = s.recv() self.assert_(resp1_data[0] == RESPONSE1) resp1_dict = self.check_response1(resp1_data[1:], rB, s.get_my_id()) resp2_data = self.create_good_response2(rB, resp1_dict, s.get_his_id()) s.send(resp2_data) time.sleep(10) # the other side should not have closed the connection, as # this is all valid, so this should not throw an exception: s.send("bla") s.close()
def _test_2fast(self,genresdict): """ test ASK_FOR_HELP, METADATA, PIECES_RESERVED and STOP_DOWNLOAD_HELP sequence """ # 1. Establish overlay connection to Tribler s = OLConnection(self.my_keypair,'localhost',self.hisport,mylistenport=self.mylistenport2) (func,good) = genresdict[ASK_FOR_HELP] msg = func() s.send(msg) if good: resp = s.recv() self.assert_(resp[0] == GET_METADATA) self.check_get_metadata(resp[1:]) print >>sys.stderr,"test: Got GET_METADATA for torrent, good" else: resp = s.recv() self.assert_(len(resp)==0) s.close() return (func,good) = genresdict[METADATA] msg = func() s.send(msg) if good: # 2. Accept the data connection Tribler wants to establish with us, the coordinator self.myss2.settimeout(10.0) conn, addr = self.myss2.accept() s3 = BTConnection('',0,conn,user_infohash=self.infohash,myid=self.myid2) s3.read_handshake_medium_rare() msg = UNCHOKE s3.send(msg) print >>sys.stderr,"test: Got data connection to us, as coordinator, good" else: resp = s.recv() self.assert_(len(resp)==0) s.close() return # 3. Our tracker says there is another peer (also us) on port 4810 # Now accept a connection on that port and pretend we're a seeder self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' s2 = BTConnection('',0,conn,user_option_pattern=options,user_infohash=self.infohash,myid=self.myid) s2.read_handshake_medium_rare() numpieces = 10 # must correspond to the torrent in test/extend_hs_dir b = Bitfield(numpieces) for i in range(numpieces): b[i] = True self.assert_(b.complete()) msg = BITFIELD+b.tostring() s2.send(msg) msg = UNCHOKE s2.send(msg) print >>sys.stderr,"test: Got BT connection to us, as fake seeder, good" # 4. Await a RESERVE_PIECES message on the overlay connection resp = s.recv() self.assert_(resp[0] == RESERVE_PIECES) pieces = self.check_reserve_pieces(resp[1:]) print >>sys.stderr,"test: Got RESERVE_PIECES, good" (func,good) = genresdict[PIECES_RESERVED] # 5. Reply with PIECES_RESERVED msg = func(pieces) s.send(msg) if good: # 6. Await REQUEST on fake seeder try: while True: s2.s.settimeout(10.0) resp = s2.recv() self.assert_(len(resp) > 0) print "test: Fake seeder got message",getMessageName(resp[0]) if resp[0] == REQUEST: self.check_request(resp[1:],pieces) print >>sys.stderr,"test: Fake seeder got REQUEST for reserved piece, good" break except socket.timeout: print >> sys.stderr,"test: Timeout, bad, fake seeder didn't reply with message" self.assert_(False) else: resp = s.recv() self.assert_(len(resp)==0) s.close() return (func,good) = genresdict[STOP_DOWNLOAD_HELP] # 5. Reply with STOP_DOWNLOAD_HELP msg = func() s.send(msg) # the other side should close the connection, whether the msg was good or bad resp = s.recv() self.assert_(len(resp)==0) s.close()
def _test_good(self, msg_gen_func, oldstyle, extend_hs_gen_func, options=None, infohash=None): if options is None and infohash is None: s = BTConnection("localhost", self.hisport) elif options is None: s = BTConnection("localhost", self.hisport, user_infohash=infohash) elif infohash is None: s = BTConnection("localhost", self.hisport, user_option_pattern=options) else: s = BTConnection("localhost", self.hisport, user_option_pattern=options, user_infohash=infohash) print >> sys.stderr, "test: test_good: Create EXTEND HS" msg = extend_hs_gen_func() print >> sys.stderr, "test: test_good: Sending EXTEND HS", repr(msg) s.send(msg) print >> sys.stderr, "test: test_good: Waiting for BT HS" s.read_handshake_medium_rare() # Tribler should send an EXTEND message back try: print >> sys.stderr, "test: Waiting for reply" s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # 1. Pretend we're seeder: send BITFIELD and UNCHOKE msg = BITFIELD + self.seederbitfieldstr s.send(msg) msg = UNCHOKE s.send(msg) print >> sys.stderr, "test: Pretend we are seeder" while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply2", getMessageName(resp[0]) self.assert_( resp[0] == REQUEST or resp[0] == INTERESTED or resp[0] == UNCHOKE or resp[0] == HAVE or resp[0] == NOT_INTERESTED ) if resp[0] == REQUEST: chunkid = self.check_request(resp) # 2. Reply to REQUEST with HASHPIECE (oldstyle) or Tr_hashpiece msg = msg_gen_func(oldstyle, chunkid) s.send(msg) elif resp[0] == NOT_INTERESTED: break # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply in time" self.assert_(False) destfn = os.path.join(self.config_path, "file2.wmv") sf = open(self.sourcefn, "rb") df = open(destfn, "rb") n = self.tdef.get_piece_length() while True: sdata = sf.read(n) if len(sdata) == 0: break ddata = df.read(n) self.assert_(sdata == ddata) time.sleep(3) s.close()
class OLConnection: def __init__(self, my_keypair, hostname, port, opensock=None, mylistenport=481, myoversion=None): """ If opensock is not None, we assume this is a connection we accepted, and he initiates the Challenge/Response """ self.my_keypair = my_keypair self.b = BTConnection(hostname, port, opensock, mylistenport=mylistenport, myoversion=myoversion) if opensock: self.b.read_handshake_medium_rare() # Read challenge msg = self.b.recv() assert (msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) [randomA, resp1_data] = self.create_good_response1(randomB, self.b.get_his_id()) self.b.send(resp1_data) # Read response2 msg = self.b.recv() assert (msg[0] == RESPONSE2) else: self.b.read_handshake() [rB, chal_data] = self.create_good_challenge() self.b.send(chal_data) resp1_data = self.b.recv() if DEBUG: print >> sys.stderr, "olconn: recv", len(resp1_data), "bytes" resp1_dict = bdecode(resp1_data[1:]) resp2_data = self.create_good_response2(rB, resp1_dict, self.b.get_his_id()) self.b.send(resp2_data) if DEBUG: print >> sys.stderr, "olconn: sent", len(resp2_data), "bytes" def get_my_fake_listen_port(self): return self.b.get_my_fake_listen_port() # # Cut 'n paste from TestPermIDs # def create_good_challenge(self): r = "".zfill(cr_random_size) return [r, self.create_challenge_payload(r)] def create_good_response2(self, rB, resp1_dict, hisid): resp2 = {} resp2['certB'] = str(self.my_keypair.pub().get_der()) resp2['A'] = hisid sig_list = [rB, resp1_dict['rA'], hisid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() sig_asn1 = str(self.my_keypair.sign_dsa_asn1(sig_hash)) resp2['SB'] = sig_asn1 return self.create_response2_payload(resp2) def create_challenge_payload(self, r): return CHALLENGE + bencode(r) def create_response2_payload(self, dict): return RESPONSE2 + bencode(dict) # # Cut 'n paste from TestPermIDResponse1 # def create_good_response1(self, rB, hisid): resp1 = {} resp1['certA'] = str(self.my_keypair.pub().get_der()) resp1['rA'] = "".zfill(cr_random_size) resp1['B'] = hisid sig_list = [resp1['rA'], rB, hisid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() sig_asn1 = str(self.my_keypair.sign_dsa_asn1(sig_hash)) resp1['SA'] = sig_asn1 return [resp1['rA'], self.create_response1_payload(resp1)] def create_response1_payload(self, dict): return RESPONSE1 + bencode(dict) def send(self, data): """ send length-prefixed message """ self.b.send(data) def recv(self): """ received length-prefixed message """ return self.b.recv() def close(self): self.b.close()
def _test_bad(self, msg_gen_func, oldstyle): print >> sys.stderr, "test: test_BAD: Create EXTEND HS", repr(msg_gen_func), oldstyle if oldstyle: options = None exthsmsg = self.create_good_tribler_extend_hs() else: options = '\x00\x00\x00\x00\x00\x10\x00\x00' exthsmsg = self.create_good_nontribler_extend_hs() s = BTConnection('localhost', self.hisport, user_option_pattern=options, user_infohash=self.infohash) s.send(exthsmsg) s.read_handshake_medium_rare() # Tribler should send an EXTEND message back try: print >> sys.stderr, "test: Waiting for reply" s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # 1. Pretend we're seeder: send BITFIELD and UNCHOKE msg = BITFIELD + self.seederbitfieldstr s.send(msg) msg = UNCHOKE s.send(msg) print >> sys.stderr, "test: Pretend we are seeder" while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply 2", getMessageName(resp[0]) self.assert_(resp[0] == REQUEST or resp[0] == INTERESTED or resp[0] == UNCHOKE or resp[0] == HAVE or resp[0] == NOT_INTERESTED) if resp[0] == REQUEST: chunkid = self.check_request(resp) # 2. Reply to REQUEST with *bad* HASHPIECE msg = msg_gen_func(chunkid) if oldstyle: if len(msg) == 1: msg = '' else: msg = msg[1:] # Strip EXTEND byte s.send(msg) break # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply in time" self.assert_(False) time.sleep(3) # Should have closed the connection try: s.send(UNCHOKE) self.assert_(False) except: print_exc() s.close()
def _test_2fast(self, genresdict): """ test ASK_FOR_HELP, METADATA, PIECES_RESERVED and STOP_DOWNLOAD_HELP sequence """ # 1. Establish overlay connection to Tribler s = OLConnection(self.my_keypair, 'localhost', self.hisport, mylistenport=self.mylistenport2) (func, good) = genresdict[ASK_FOR_HELP] msg = func() s.send(msg) if good: resp = s.recv() self.assert_(resp[0] == GET_METADATA) self.check_get_metadata(resp[1:]) print >> sys.stderr, "test: Got GET_METADATA for torrent, good" else: resp = s.recv() self.assert_(len(resp) == 0) s.close() return (func, good) = genresdict[METADATA] msg = func() s.send(msg) if good: # 2. Accept the data connection Tribler wants to establish with us, the coordinator self.myss2.settimeout(10.0) conn, addr = self.myss2.accept() s3 = BTConnection('', 0, conn, user_infohash=self.infohash, myid=self.myid2) s3.read_handshake_medium_rare() msg = UNCHOKE s3.send(msg) print >> sys.stderr, "test: Got data connection to us, as coordinator, good" else: resp = s.recv() self.assert_(len(resp) == 0) s.close() return # 3. Our tracker says there is another peer (also us) on port 4810 # Now accept a connection on that port and pretend we're a seeder self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' s2 = BTConnection('', 0, conn, user_option_pattern=options, user_infohash=self.infohash, myid=self.myid) s2.read_handshake_medium_rare() numpieces = 10 # must correspond to the torrent in test/extend_hs_dir b = Bitfield(numpieces) for i in range(numpieces): b[i] = True self.assert_(b.complete()) msg = BITFIELD + b.tostring() s2.send(msg) msg = UNCHOKE s2.send(msg) print >> sys.stderr, "test: Got BT connection to us, as fake seeder, good" # 4. Await a RESERVE_PIECES message on the overlay connection resp = s.recv() self.assert_(resp[0] == RESERVE_PIECES) pieces = self.check_reserve_pieces(resp[1:]) print >> sys.stderr, "test: Got RESERVE_PIECES, good" (func, good) = genresdict[PIECES_RESERVED] # 5. Reply with PIECES_RESERVED msg = func(pieces) s.send(msg) if good: # 6. Await REQUEST on fake seeder while True: resp = s2.recv() self.assert_(len(resp) > 0) print "test: Fake seeder got message", getMessageName(resp[0]) if resp[0] == REQUEST: self.check_request(resp[1:], pieces) print >> sys.stderr, "test: Fake seeder got REQUEST for reserved piece, good" break else: resp = s.recv() self.assert_(len(resp) == 0) s.close() return (func, good) = genresdict[STOP_DOWNLOAD_HELP] # 5. Reply with STOP_DOWNLOAD_HELP msg = func() s.send(msg) # the other side should close the connection, whether the msg was good or bad resp = s.recv() self.assert_(len(resp) == 0) s.close()
def _test_good(self, msg_gen_func, oldstyle, extend_hs_gen_func, options=None, infohash=None): if options is None and infohash is None: s = BTConnection('localhost', self.hisport) elif options is None: s = BTConnection('localhost', self.hisport, user_infohash=infohash) elif infohash is None: s = BTConnection('localhost', self.hisport, user_option_pattern=options) else: s = BTConnection('localhost', self.hisport, user_option_pattern=options, user_infohash=infohash) print >> sys.stderr, "test: test_good: Create EXTEND HS" msg = extend_hs_gen_func() print >> sys.stderr, "test: test_good: Sending EXTEND HS", repr(msg) s.send(msg) print >> sys.stderr, "test: test_good: Waiting for BT HS" s.read_handshake_medium_rare() # Tribler should send an EXTEND message back try: print >> sys.stderr, "test: Waiting for reply" s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # 1. Pretend we're seeder: send BITFIELD and UNCHOKE msg = BITFIELD + self.seederbitfieldstr s.send(msg) msg = UNCHOKE s.send(msg) print >> sys.stderr, "test: Pretend we are seeder" while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply2", getMessageName(resp[0]) self.assert_(resp[0] == REQUEST or resp[0] == INTERESTED or resp[0] == UNCHOKE or resp[0] == HAVE or resp[0] == NOT_INTERESTED) if resp[0] == REQUEST: chunkid = self.check_request(resp) # 2. Reply to REQUEST with HASHPIECE (oldstyle) or Tr_hashpiece msg = msg_gen_func(oldstyle, chunkid) s.send(msg) elif resp[0] == NOT_INTERESTED: break # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply in time" self.assert_(False) destfn = os.path.join(self.config_path, "file2.wmv") sf = open(self.sourcefn, "rb") df = open(destfn, "rb") n = self.tdef.get_piece_length() while True: sdata = sf.read(n) if len(sdata) == 0: break ddata = df.read(n) self.assert_(sdata == ddata) time.sleep(3) s.close()
def _test_bad(self, msg_gen_func, oldstyle): print >> sys.stderr, "test: test_BAD: Create EXTEND HS", repr(msg_gen_func), oldstyle if oldstyle: options = None exthsmsg = self.create_good_tribler_extend_hs() else: options = "\x00\x00\x00\x00\x00\x10\x00\x00" exthsmsg = self.create_good_nontribler_extend_hs() s = BTConnection("localhost", self.hisport, user_option_pattern=options, user_infohash=self.infohash) s.send(exthsmsg) s.read_handshake_medium_rare() # Tribler should send an EXTEND message back try: print >> sys.stderr, "test: Waiting for reply" s.s.settimeout(10.0) resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply", getMessageName(resp[0]) self.assert_(resp[0] == EXTEND) self.check_tribler_extend_hs(resp[1:]) # 1. Pretend we're seeder: send BITFIELD and UNCHOKE msg = BITFIELD + self.seederbitfieldstr s.send(msg) msg = UNCHOKE s.send(msg) print >> sys.stderr, "test: Pretend we are seeder" while True: resp = s.recv() self.assert_(len(resp) > 0) print >> sys.stderr, "test: Got reply 2", getMessageName(resp[0]) self.assert_( resp[0] == REQUEST or resp[0] == INTERESTED or resp[0] == UNCHOKE or resp[0] == HAVE or resp[0] == NOT_INTERESTED ) if resp[0] == REQUEST: chunkid = self.check_request(resp) # 2. Reply to REQUEST with *bad* HASHPIECE msg = msg_gen_func(chunkid) if oldstyle: if len(msg) == 1: msg = "" else: msg = msg[1:] # Strip EXTEND byte s.send(msg) break # s.close() except socket.timeout: print >> sys.stderr, "test: Timeout, bad, peer didn't reply in time" self.assert_(False) time.sleep(3) # Should have closed the connection try: s.send(UNCHOKE) self.assert_(False) except: print_exc() s.close()
def _test_2fast(self,genresdict): """ test ASK_FOR_HELP, METADATA, PIECES_RESERVED and STOP_DOWNLOAD_HELP sequence """ # 1. Establish overlay connection to Tribler ol_connection = OLConnection(self.my_keypair, 'localhost', self.hisport, mylistenport=self.mylistenport2) # Send ASK_FOR_HELP (generate_data, sent_good_values) = genresdict[ASK_FOR_HELP] msg = generate_data() ol_connection.send(msg) if sent_good_values: resp = ol_connection.recv() self.assert_(resp[0] == GET_METADATA) self.check_get_metadata(resp[1:]) print >>sys.stderr,"test: Got GET_METADATA for torrent, sent_good_values" else: resp = ol_connection.recv() self.assert_(len(resp)==0) ol_connection.close() return # Send METADATA (generate_data,sent_good_values) = genresdict[METADATA] msg = generate_data() ol_connection.send(msg) if sent_good_values: # 2. Accept the data connection Tribler wants to establish with us, the coordinator self.myss2.settimeout(10.0) conn, addr = self.myss2.accept() #(self,hostname,port,opensock=None,user_option_pattern=None,user_infohash=None,myid=None,mylistenport=None,myoversion=None): bt_connection_2 = BTConnection('', 0, conn, user_infohash=self.infohash, myid=self.myid2) bt_connection_2.read_handshake_medium_rare() msg = UNCHOKE bt_connection_2.send(msg) print >>sys.stderr,"test: Got data connection to us, as coordinator, sent_good_values" else: resp = ol_connection.recv() self.assert_(len(resp)==0) ol_connection.close() return # 3. Our tracker says there is another peer (also us) on port 4810 # Now accept a connection on that port and pretend we're a seeder self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' bt_connection = BTConnection('', 0, conn, user_option_pattern=options, user_infohash=self.infohash, myid=self.myid) bt_connection.read_handshake_medium_rare() # Get the number of pieces from the .torrent file torrentfile_content = open(self.torrentfile, "rb") metadata_dict = bdecode(torrentfile_content.read()) torrentfile_content.close() if "length" in metadata_dict["info"]: length = metadata_dict["info"]["length"] else: length = 0 for file in metadata_dict["info"]["files"]: length += file["length"] numpieces = length / metadata_dict["info"]["piece length"] bitf = Bitfield(numpieces) for i in range(numpieces): bitf[i] = True self.assert_(bitf.complete()) msg = BITFIELD+bitf.tostring() bt_connection.send(msg) msg = UNCHOKE bt_connection.send(msg) print >>sys.stderr,"test: Got BT connection to us, as fake seeder, sent_good_values" # 4. Await a RESERVE_PIECES message on the overlay connection resp = ol_connection.recv() self.assert_(resp[0] == RESERVE_PIECES) pieces = self.check_reserve_pieces(resp[1:]) print >>sys.stderr,"test: Got RESERVE_PIECES, sent_good_values" # 5. Reply with PIECES_RESERVED (generate_data, sent_good_values) = genresdict[PIECES_RESERVED] msg = generate_data(pieces) ol_connection.send(msg) if sent_good_values: # 6. Await REQUEST on fake seeder while True: resp = bt_connection.recv() self.assert_(len(resp) > 0) print "test: Fake seeder got message",getMessageName(resp[0]) if resp[0] == REQUEST: self.check_request(resp[1:],pieces) print >>sys.stderr,"test: Fake seeder got REQUEST for reserved piece, sent_good_values" break else: resp = ol_connection.recv() self.assert_(len(resp)==0) ol_connection.close() return # 7. Reply with STOP_DOWNLOAD_HELP (generate_data, sent_good_values) = genresdict[STOP_DOWNLOAD_HELP] msg = generate_data() ol_connection.send(msg) # the other side should close the connection, whether the msg was sent_good_values or bad resp = ol_connection.recv() self.assert_(len(resp)==0) ol_connection.close()
def _test_proxy(self, genresdict): """ Send messages to the helper instance and test it. Testing ASK_FOR_HELP, STOP_HELPING, REQUEST_PIECES, CANCEL_PIECE and METADATA """ # 1. Establish overlay connection to Tribler ol_connection = OLConnection(self.my_keypair, 'localhost', self.hisport, mylistenport=self.mylistenport2) # 2. Send the ASK_FOR_HELP message (generate_data, sent_good_values) = genresdict[ASK_FOR_HELP] msg = generate_data() ol_connection.send(msg) if sent_good_values: # Read the helper's response resp = ol_connection.recv() # Check the helper's response # 3. At this point, the helper does not have the .torrent file, so it requests it with a METADATA message self.assert_(resp[0] == GET_METADATA) self.check_get_metadata(resp[1:]) print >> sys.stderr, "test: Got GET_METADATA for torrent, good" else: # Read the helper's response resp = ol_connection.recv() # Check the helper's response self.assert_(len(resp) == 0) ol_connection.close() return # 4. Send METADATA (generate_data, sent_good_values) = genresdict[METADATA] msg = generate_data() ol_connection.send(msg) if sent_good_values: # 5. At this point the helper is confirming his availability to help # Read the helper's response resp = ol_connection.recv() # Check the helper's response self.assert_(resp[0] == JOIN_HELPERS) self.check_ask_for_help(resp) print >> sys.stderr, "test: Got JOIN_HELPERS for torrent, good" # 6. At this point, the helper will contact the tracker and then wait for REQUEST_PIECES messages # So we send a request pieces message (generate_data, sent_good_values) = genresdict[REQUEST_PIECES] msg = generate_data() ol_connection.send(msg) # At this point the helper will contact the seeders in the swarm to download the requested piece # There is only one seeder in the swarm, the coordinator's twin # 8. Our tracker says there is another peer (also us) on port 4810 # Now accept a connection on that port and pretend we're a seeder self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' s2 = BTConnection('', 0, conn, user_option_pattern=options, user_infohash=self.infohash, myid=self.myid) s2.read_handshake_medium_rare() # Send a bitfield message to the helper (pretending we are a regular seeder) b = Bitfield(self.numpieces) for i in range(self.numpieces): b[i] = True self.assert_(b.complete()) msg = BITFIELD + b.tostring() s2.send(msg) msg = UNCHOKE s2.send(msg) print >> sys.stderr, "test: Got BT connection to us, as fake seeder, good" else: resp = ol_connection.recv() self.assert_(len(resp) == 0) ol_connection.close() return # 7. Accept the data connection the helper wants to establish with us, the coordinator. # The helper will send via this connection the pieces we request it to download. self.myss2.settimeout(10.0) conn, addr = self.myss2.accept() s3 = BTConnection('', 0, conn, user_infohash=self.infohash, myid=self.myid2) s3.read_handshake_medium_rare() msg = UNCHOKE s3.send(msg) print >> sys.stderr, "test: Got data connection to us, as coordinator, good" # 9. At this point the helper should sent a PROXY_HAVE message on the overlay connection # resp = ol_connection.recv() # self.assert_(resp[0] == PROXY_HAVE) # print >>sys.stderr,"test: Got PROXY)HAVE, good" # 10. Await REQUEST on fake seeder try: while True: s2.s.settimeout(10.0) resp = s2.recv() self.assert_(len(resp) > 0) print "test: Fake seeder got message", getMessageName(resp[0]) if resp[0] == REQUEST: self.check_request(resp[1:]) print >> sys.stderr, "test: Fake seeder got REQUEST for reserved piece, good" break except socket.timeout: print >> sys.stderr, "test: Timeout, bad, fake seeder didn't reply with message" self.assert_(False) # 11. Sent the helper a STOP_HELPING message (generate_data, sent_good_values) = genresdict[STOP_HELPING] msg = generate_data() ol_connection.send(msg) # The other side should close the connection, whether the msg was good or bad resp = ol_connection.recv() self.assert_(len(resp) == 0) ol_connection.close()
def _test_2fast(self, genresdict): """ test ASK_FOR_HELP, METADATA, PIECES_RESERVED and STOP_DOWNLOAD_HELP sequence """ # 1. Establish overlay connection to Tribler ol_connection = OLConnection(self.my_keypair, 'localhost', self.hisport, mylistenport=self.mylistenport2) # Send ASK_FOR_HELP (generate_data, sent_good_values) = genresdict[ASK_FOR_HELP] msg = generate_data() ol_connection.send(msg) if sent_good_values: resp = ol_connection.recv() self.assert_(resp[0] == GET_METADATA) self.check_get_metadata(resp[1:]) print >> sys.stderr, "test: Got GET_METADATA for torrent, sent_good_values" else: resp = ol_connection.recv() self.assert_(len(resp) == 0) ol_connection.close() return # Send METADATA (generate_data, sent_good_values) = genresdict[METADATA] msg = generate_data() ol_connection.send(msg) if sent_good_values: # 2. Accept the data connection Tribler wants to establish with us, the coordinator self.myss2.settimeout(10.0) conn, addr = self.myss2.accept() #(self,hostname,port,opensock=None,user_option_pattern=None,user_infohash=None,myid=None,mylistenport=None,myoversion=None): bt_connection_2 = BTConnection('', 0, conn, user_infohash=self.infohash, myid=self.myid2) bt_connection_2.read_handshake_medium_rare() msg = UNCHOKE bt_connection_2.send(msg) print >> sys.stderr, "test: Got data connection to us, as coordinator, sent_good_values" else: resp = ol_connection.recv() self.assert_(len(resp) == 0) ol_connection.close() return # 3. Our tracker says there is another peer (also us) on port 4810 # Now accept a connection on that port and pretend we're a seeder self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' bt_connection = BTConnection('', 0, conn, user_option_pattern=options, user_infohash=self.infohash, myid=self.myid) bt_connection.read_handshake_medium_rare() # Get the number of pieces from the .torrent file torrentfile_content = open(self.torrentfile, "rb") metadata_dict = bdecode(torrentfile_content.read()) torrentfile_content.close() if "length" in metadata_dict["info"]: length = metadata_dict["info"]["length"] else: length = 0 for file in metadata_dict["info"]["files"]: length += file["length"] numpieces = length / metadata_dict["info"]["piece length"] bitf = Bitfield(numpieces) for i in range(numpieces): bitf[i] = True self.assert_(bitf.complete()) msg = BITFIELD + bitf.tostring() bt_connection.send(msg) msg = UNCHOKE bt_connection.send(msg) print >> sys.stderr, "test: Got BT connection to us, as fake seeder, sent_good_values" # 4. Await a RESERVE_PIECES message on the overlay connection resp = ol_connection.recv() self.assert_(resp[0] == RESERVE_PIECES) pieces = self.check_reserve_pieces(resp[1:]) print >> sys.stderr, "test: Got RESERVE_PIECES, sent_good_values" # 5. Reply with PIECES_RESERVED (generate_data, sent_good_values) = genresdict[PIECES_RESERVED] msg = generate_data(pieces) ol_connection.send(msg) if sent_good_values: # 6. Await REQUEST on fake seeder while True: resp = bt_connection.recv() self.assert_(len(resp) > 0) print "test: Fake seeder got message", getMessageName(resp[0]) if resp[0] == REQUEST: self.check_request(resp[1:], pieces) print >> sys.stderr, "test: Fake seeder got REQUEST for reserved piece, sent_good_values" break else: resp = ol_connection.recv() self.assert_(len(resp) == 0) ol_connection.close() return # 7. Reply with STOP_DOWNLOAD_HELP (generate_data, sent_good_values) = genresdict[STOP_DOWNLOAD_HELP] msg = generate_data() ol_connection.send(msg) # the other side should close the connection, whether the msg was sent_good_values or bad resp = ol_connection.recv() self.assert_(len(resp) == 0) ol_connection.close()
class OLConnection: def __init__(self,my_keypair,hostname,port,opensock=None,mylistenport=481,myoversion=None): """ If opensock is not None, we assume this is a connection we accepted, and he initiates the Challenge/Response """ self.my_keypair = my_keypair self.b = BTConnection(hostname,port,opensock,mylistenport=mylistenport,myoversion=myoversion) if opensock: self.b.read_handshake_medium_rare() # Read challenge msg = self.b.recv() assert(msg[0] == CHALLENGE) randomB = bdecode(msg[1:]) [randomA,resp1_data] = self.create_good_response1(randomB,self.b.get_his_id()) self.b.send(resp1_data) # Read response2 msg = self.b.recv() assert(msg[0] == RESPONSE2) else: self.b.read_handshake() [rB,chal_data] = self.create_good_challenge() self.b.send(chal_data) resp1_data = self.b.recv() if DEBUG: print >>sys.stderr,"olconn: recv",len(resp1_data),"bytes" resp1_dict = bdecode(resp1_data[1:]) resp2_data = self.create_good_response2(rB,resp1_dict,self.b.get_his_id()) self.b.send(resp2_data) if DEBUG: print >>sys.stderr,"olconn: sent",len(resp2_data),"bytes" def get_my_fake_listen_port(self): return self.b.get_my_fake_listen_port() # # Cut 'n paste from TestPermIDs # def create_good_challenge(self): r = "".zfill(cr_random_size) return [r,self.create_challenge_payload(r)] def create_good_response2(self,rB,resp1_dict,hisid): resp2 = {} resp2['certB'] = str(self.my_keypair.pub().get_der()) resp2['A'] = hisid sig_list = [rB,resp1_dict['rA'],hisid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() sig_asn1 = str(self.my_keypair.sign_dsa_asn1(sig_hash)) resp2['SB'] = sig_asn1 return self.create_response2_payload(resp2) def create_challenge_payload(self,r): return CHALLENGE+bencode(r) def create_response2_payload(self,dict): return RESPONSE2+bencode(dict) # # Cut 'n paste from TestPermIDResponse1 # def create_good_response1(self,rB,hisid): resp1 = {} resp1['certA'] = str(self.my_keypair.pub().get_der()) resp1['rA'] = "".zfill(cr_random_size) resp1['B'] = hisid sig_list = [resp1['rA'],rB,hisid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() sig_asn1 = str(self.my_keypair.sign_dsa_asn1(sig_hash)) resp1['SA'] = sig_asn1 return [resp1['rA'],self.create_response1_payload(resp1)] def create_response1_payload(self,dict): return RESPONSE1+bencode(dict) def send(self,data): """ send length-prefixed message """ self.b.send(data) def recv(self): """ received length-prefixed message """ return self.b.recv() def close(self): self.b.close()
def _test_proxy(self,genresdict): """ Send messages to the helper instance and test it. Testing ASK_FOR_HELP, STOP_HELPING, REQUEST_PIECES, CANCEL_PIECE and METADATA """ # 1. Establish overlay connection to Tribler ol_connection = OLConnection(self.my_keypair, 'localhost', self.hisport, mylistenport=self.mylistenport2) # 2. Send the ASK_FOR_HELP message (generate_data,sent_good_values) = genresdict[ASK_FOR_HELP] msg = generate_data() ol_connection.send(msg) if sent_good_values: # Read the helper's response resp = ol_connection.recv() # Check the helper's response # 3. At this point, the helper does not have the .torrent file, so it requests it with a METADATA message self.assert_(resp[0] == GET_METADATA) self.check_get_metadata(resp[1:]) print >>sys.stderr,"test: Got GET_METADATA for torrent, good" else: # Read the helper's response resp = ol_connection.recv() # Check the helper's response self.assert_(len(resp)==0) ol_connection.close() return # 4. Send METADATA (generate_data,sent_good_values) = genresdict[METADATA] msg = generate_data() ol_connection.send(msg) if sent_good_values: # 5. At this point the helper is confirming his availability to help # Read the helper's response resp = ol_connection.recv() # Check the helper's response self.assert_(resp[0] == JOIN_HELPERS) self.check_ask_for_help(resp) print >>sys.stderr,"test: Got JOIN_HELPERS for torrent, good" # 6. At this point, the helper will contact the tracker and then wait for REQUEST_PIECES messages # So we send a request pieces message (generate_data,sent_good_values) = genresdict[REQUEST_PIECES] msg = generate_data() ol_connection.send(msg) # At this point the helper will contact the seeders in the swarm to download the requested piece # There is only one seeder in the swarm, the coordinator's twin # 8. Our tracker says there is another peer (also us) on port 4810 # Now accept a connection on that port and pretend we're a seeder self.myss.settimeout(10.0) conn, addr = self.myss.accept() options = '\x00\x00\x00\x00\x00\x00\x00\x00' s2 = BTConnection('',0,conn,user_option_pattern=options,user_infohash=self.infohash,myid=self.myid) s2.read_handshake_medium_rare() # Send a bitfield message to the helper (pretending we are a regular seeder) b = Bitfield(self.numpieces) for i in range(self.numpieces): b[i] = True self.assert_(b.complete()) msg = BITFIELD+b.tostring() s2.send(msg) msg = UNCHOKE s2.send(msg) print >>sys.stderr,"test: Got BT connection to us, as fake seeder, good" else: resp = ol_connection.recv() self.assert_(len(resp)==0) ol_connection.close() return # 7. Accept the data connection the helper wants to establish with us, the coordinator. # The helper will send via this connection the pieces we request it to download. self.myss2.settimeout(10.0) conn, addr = self.myss2.accept() s3 = BTConnection('',0,conn,user_infohash=self.infohash,myid=self.myid2) s3.read_handshake_medium_rare() msg = UNCHOKE s3.send(msg) print >>sys.stderr,"test: Got data connection to us, as coordinator, good" # 9. At this point the helper should sent a PROXY_HAVE message on the overlay connection # resp = ol_connection.recv() # self.assert_(resp[0] == PROXY_HAVE) # print >>sys.stderr,"test: Got PROXY)HAVE, good" # 10. Await REQUEST on fake seeder try: while True: s2.s.settimeout(10.0) resp = s2.recv() self.assert_(len(resp) > 0) print "test: Fake seeder got message",getMessageName(resp[0]) if resp[0] == REQUEST: self.check_request(resp[1:]) print >>sys.stderr,"test: Fake seeder got REQUEST for reserved piece, good" break except socket.timeout: print >> sys.stderr,"test: Timeout, bad, fake seeder didn't reply with message" self.assert_(False) # 11. Sent the helper a STOP_HELPING message (generate_data,sent_good_values) = genresdict[STOP_HELPING] msg = generate_data() ol_connection.send(msg) # The other side should close the connection, whether the msg was good or bad resp = ol_connection.recv() self.assert_(len(resp)==0) ol_connection.close()