Example #1
0
 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)
Example #2
0
    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()
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()
Example #4
0
    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 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()
Example #6
0
    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 subtest_good_drequest(self):
        """ 
            test good DIALBACK_REQUEST messages
        """
        s = OLConnection(self.my_keypair,'localhost',self.hisport,mylistenport=self.mylistenport)
        msg = self.create_good_drequest()
        s.send(msg)
        time.sleep(5)

        # And connect back to us
        conn, addr = self.myss.accept()
        s2 = BTConnection('',0,conn,mylistenport=self.mylistenport,user_infohash=dialback_infohash)
        s2.read_handshake_medium_rare()
        resp = s2.recv()
        print >> sys.stderr,"test: Me got DIALBACK_REPLY from him, len",len(resp)
        self.assert_(resp[0] == DIALBACK_REPLY)
        self.check_drequest(resp[1:])
Example #8
0
 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 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)
Example #10
0
    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)
Example #11
0
    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_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)
Example #13
0
    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)
Example #14
0
    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"]
Example #15
0
    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"]
Example #16
0
 def __init__(self,port):
     self.s = BTConnection('localhost',port)
     self.s.read_handshake_medium_rare()
     self.connection = EncrypterConnection(self.s.get_his_id())
Example #17
0
 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()
Example #18
0
    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",`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()
Example #19
0
    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_2fast(self, genresdict):
        """ 
            test DOWNLOAD_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[DOWNLOAD_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()
Example #21
0
    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_nontribler_extend_hs()
        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_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()
Example #23
0
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_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_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()
Example #26
0
    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 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()
Example #28
0
    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)
Example #29
0
    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)
Example #30
0
    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()
Example #31
0
    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()
Example #32
0
 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()
Example #33
0
    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)
Example #34
0
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()
Example #35
0
    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()
Example #36
0
 def __init__(self, port):
     self.s = BTConnection('localhost', port)
     self.s.read_handshake_medium_rare()
     self.connection = EncrypterConnection(self.s.get_his_id())
Example #37
0
    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()
Example #38
0
 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()
Example #39
0
 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()
Example #40
0
    def _test_bad(self,msg_gen_func,oldstyle):
        print >>sys.stderr,"test: test_BAD: Create EXTEND HS",`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()
Example #41
0
    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)
Example #42
0
    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()
Example #43
0
    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()
Example #44
0
 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()
Example #45
0
    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)
Example #46
0
    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)
Example #47
0
    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()
Example #48
0
 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()