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 getMetainfo(src, openoptions = 'rb', style = "file"): if src is None: return None metainfo = None try: metainfo_file = None # We're getting a url if style == "rawdata": return bdecode(src) elif style == "url": metainfo_file = urlopen(src) # We're getting a file that exists elif os.access(src, os.R_OK): metainfo_file = open(src, openoptions) if metainfo_file is not None: metainfo = bdecode(metainfo_file.read()) metainfo_file.close() except: if metainfo_file is not None: try: metainfo_file.close() except: pass metainfo = None return metainfo
def getMetainfo(src, openoptions='rb', style="file"): if src is None: return None metainfo = None try: metainfo_file = None # We're getting a url if style == "rawdata": return bdecode(src) elif style == "url": metainfo_file = urlopen(src) # We're getting a file that exists elif os.access(src, os.R_OK): metainfo_file = open(src, openoptions) if metainfo_file is not None: metainfo = bdecode(metainfo_file.read()) metainfo_file.close() except: print_exc() if metainfo_file is not None: try: metainfo_file.close() except: pass metainfo = None return metainfo
def subtest_channelcast(self): print >>sys.stderr,"test: channelcast----------------------" s = OLConnection(self.my_keypair,'localhost',self.hisport) chcast = ChannelCastCore(None, s, self.session, None, log = '', dnsindb = None) #Send Empty ChannelCast message chdata = {} print >> sys.stderr, "Test Good ChannelCast", `chdata` msg = CHANNELCAST+bencode(chdata) s.send(msg) resp = s.recv() if len(resp) > 0: print >>sys.stderr,"test: channelcast: got",getMessageName(resp[0]) self.assert_(resp[0]==CHANNELCAST) print >>sys.stderr, "test: channelcast: got msg", `bdecode(resp[1:])` chdata_rcvd = bdecode(resp[1:]) self.assert_(validChannelCastMsg(chdata_rcvd)==True) s.close() #Now, send a bad ChannelCast message. # The other side should close the connection # Create bad message by manipulating a good one #bad infohash chdata = deepcopy(chdata_rcvd) for k,v in chdata.items(): v['infohash'] = 234 self.subtest_bad_channelcast(chdata) #bad torrentname chdata = deepcopy(chdata_rcvd) for k,v in chdata.items(): v['torrentname'] = 1231 self.subtest_bad_channelcast(chdata) #bad signature.. temporarily disabled. # Got to enable when signature validation in validChannelCastMsg are enabled # chdata = deepcopy(chdata_rcvd) # value_list = chdata.values() # if len(value_list)>0: # chdata['sdfg234sadf'] = value_list[0] # self.subtest_bad_channelcast(chdata) #Bad message format chdata = {'2343ww34':''} self.subtest_bad_channelcast(chdata) #Bad print>>sys.stderr, "End of channelcast test---------------------------"
def StringToValue(self, value, type): # Assume that the value is already in the proper form # if it's not a string # (the case for some defaults) if value is not None: if not isinstance(value, unicode) and not isinstance(value, str): return value try: if type == "boolean": if value == "1": value = True else: value = False elif type == "int": value = int(value) elif type == "float": value = float(value) elif type == "color": red = int(value[0:3]) green = int(value[3:6]) blue = int(value[6:9]) value = wx.Colour(red, green, blue) elif type.startswith("bencode"): value = bdecode(value) except: value = None if value is None: value = self.defaultvalues[type] return value
def convert_BartercastDB(self): print >>sys.stderr, time.asctime(),'-', "convert_BartercastDB" db_path = os.path.join(self.bsddb_dir, 'bartercast.bsd') if not os.path.isfile(db_path): return bc_db = BarterCastDB.getInstance(self.bsddb_dir) insert_bc_sql = """ INSERT INTO BarterCast (peer_id_from, peer_id_to, downloaded, uploaded, last_seen, value) VALUES (?,?,?,?,?,?) """ values = [] for key,db_data in bc_db._data.iteritems(): try: permid_from, permid_to = bdecode(key) permid_id_from = self._getPeerID(permid_from) if permid_id_from is None: self._addPeerToDB(permid_from) permid_id_from = self._getPeerID(permid_from) permid_id_to = self._getPeerID(permid_to) if permid_id_to is None: self._addPeerToDB(permid_to) permid_id_to = self._getPeerID(permid_to) downloaded = db_data.get('downloaded', 0) uploaded = db_data.get('uploaded', 0) last_seen = db_data.get('last_seen', 0) value = db_data.get('value', 0) values.append((permid_id_from, permid_id_to, downloaded, uploaded, last_seen, value)) except Exception, msg: print >> sys.stderr, time.asctime(),'-', "error input for convert_BartercastDB:", key, db_data, Exception, msg
def check_response1(self,resp1_data,rB,myid): resp1 = bdecode(resp1_data) self.assert_(type(resp1) == DictType) self.assert_(resp1.has_key('certA')) self.assert_(resp1.has_key('rA')) self.assert_(resp1.has_key('B')) self.assert_(resp1.has_key('SA')) # show throw exception when key no good pubA = EC.pub_key_from_der(resp1['certA']) rA = resp1['rA'] self.assert_(type(rA) == StringType) self.assert_(len(rA) == random_size) B = resp1['B'] self.assert_(type(B) == StringType) self.assert_(B,myid) SA = resp1['SA'] self.assert_(type(SA) == StringType) # verify signature sig_list = [rA,rB,myid] sig_data = bencode(sig_list) sig_hash = sha(sig_data).digest() self.assert_(pubA.verify_dsa_asn1(sig_hash,SA)) # Cannot resign the data with his keypair to double check. Signing # appears to yield different, supposedly valid sigs each time. return resp1
def readTorrent(self, torrent): try: torrent_path = torrent['torrent_path'] if not path.isfile(torrent_path): #torrent not found, try filename + current torrent collection directory torrent_collection_dir = Session.get_instance( ).get_torrent_collecting_dir() _, torrent_filename = path.split(torrent_path) torrent_path = path.join(torrent_collection_dir, torrent_filename) if not path.isfile(torrent_path): #torrent still not found, determine filename + current torrent collection directory torrent_path = path.join( torrent_collection_dir, get_collected_torrent_filename(torrent['infohash'])) if path.isfile(torrent_path): f = open(torrent_path, 'rb') _data = f.read() f.close() data = bdecode(_data) assert 'info' in data del data['info'] torrent['info'] = data return torrent except Exception: #print_exc() return torrent
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 serialize(self): if self.signature is None: raise SerializationException("The content must be signed") pack = bdecode(self._packData()) pack.append(self.signature) return pack
def check_get_metadata(self,data): infohash = bdecode(data) self.check_infohash(infohash) # Extra check: he can only ask us for metadata for an infohash we # gave him. self.assert_(infohash in self.myprefs)
def gotChannelCastMessage(self, recv_msg, sender_permid, selversion): """ Receive and handle a ChannelCast message """ # ChannelCast feature starts from eleventh version; hence, do not receive from lower version peers # Arno, 2010-02-05: v12 uses a different on-the-wire format, ignore those. # Andrea: 2010-04-08: v14 can still receive v13 channelcast messages # Niels: 2011-02-02: Channelcast is now using dispersy, but we can still receive old messages if selversion < OLPROTO_VER_THIRTEENTH: if DEBUG: print >>sys.stderr, "channelcast: Do not receive from lower version peer:", selversion return True if DEBUG: print >>sys.stderr, "channelcast: Received a msg from ", show_permid_short(sender_permid) print >>sys.stderr, "channelcast: my_permid=", show_permid_short(self.my_permid) if not sender_permid or sender_permid == self.my_permid: if DEBUG: print >>sys.stderr, "channelcast: warning - got channelcastMsg from a None/Self peer", show_permid_short( sender_permid ), recv_msg return False channelcast_data = {} try: channelcast_data = bdecode(recv_msg) except: print >>sys.stderr, "channelcast: warning, invalid bencoded data" return False # check message-structure if not validChannelCastMsg(channelcast_data): print >>sys.stderr, "channelcast: invalid channelcast_message" return False # 19/02/10 Boudewijn: validChannelCastMsg passes when # PUBLISHER_NAME and TORRENTNAME are either string or # unicode-string. However, all further code requires that # these are unicode! for ch in channelcast_data.values(): if isinstance(ch["publisher_name"], str): ch["publisher_name"] = str2unicode(ch["publisher_name"]) if isinstance(ch["torrentname"], str): ch["torrentname"] = str2unicode(ch["torrentname"]) self.updateChannel(sender_permid, None, channelcast_data) # Log RECV_MSG of uncompressed message if self.log: dns = self.dnsindb(sender_permid) if dns: ip, port = dns MSG_ID = "CHANNELCAST" # 08/04/10 Andrea: representing the whole channelcast + metadata message msg = repr(channelcast_data) self.overlay_log("RECV_MSG", ip, port, show_permid(sender_permid), selversion, MSG_ID, msg) if self.TESTASSERVER: self.createAndSendChannelCastMessage(sender_permid, selversion) return True
def check_buddycast(self,data,oversion): d = bdecode(data) print >>sys.stderr,"test: Got BUDDYCAST",d.keys() #print >>sys.stderr,"test: Got CONTENT",`d` self.assert_(type(d) == DictType) self.assert_('ip' in d) self.assert_(type(d['ip']) == StringType) self.assert_('port' in d) self.assert_(type(d['port']) == IntType) self.assert_('name' in d) self.assert_(type(d['name']) == StringType) self.assert_('preferences' in d) self.check_preferences(d['preferences'],oversion) self.assert_('taste buddies' in d) self.check_taste_buddies(d['taste buddies'],oversion) self.assert_('random peers' in d) self.check_random_peers(d['random peers'],oversion ) if oversion >= 3: self.assert_('connectable' in d) #print >>sys.stderr,"CONNECTABLE TYPE",type(d['connectable']) self.assert_(type(d['connectable']) == IntType) if oversion >= 4: self.assert_('collected torrents' in d) self.check_collected_torrents(d['collected torrents'],oversion) if oversion >= 6: self.assert_('npeers' in d) self.assert_(type(d['npeers']) == IntType) self.assert_('nfiles' in d) self.assert_(type(d['nfiles']) == IntType) self.assert_('ndls' in d) self.assert_(type(d['ndls']) == IntType)
def run(self): announce = self._tracker + "?" + urlencode({"info_hash":self._swarm.get_info_hash(), "peer_id":self._swarm.get_peer_id(), "port":"12345", "compact":"1", "uploaded":"0", "downloaded":"0", "left":"-1", "event":"started"}) try: body = bdecode(urlopen(announce).read()) except: pass else: # using low-bandwidth binary format peers = [] peer_data = body["peers"] for x in range(0, len(peer_data), 6): # key = peer_data[x:x+6] ip = ".".join([str(ord(i)) for i in peer_data[x:x+4]]) port = (ord(peer_data[x+4]) << 8) | ord(peer_data[x+5]) peers.append((ip, port)) if DEBUG: print >> sys.stderr, "MiniTracker.run() received", len(peers), "peer addresses from tracker" self._swarm.add_potential_peers(peers)
def check_ut_pex(self, data, pex_id): self.assert_(data[0] == chr(pex_id)) d = bdecode(data[1:]) print >> sys.stderr, "test: d is", ` d ` self.assert_(type(d) == DictType) self.assert_('added' in d.keys()) cp = d['added'] apeers = self.check_compact_peers(cp) print >> sys.stderr, "test: apeers is", apeers self.assert_('added.f' in d.keys()) f = d['added.f'] print "test: Length of added.f", len(f) self.assert_(type(f) == StringType) self.assert_(len(apeers) == len(f)) self.assert_('dropped' in d.keys()) cp = d['dropped'] self.check_compact_peers(cp) # Check that the fake client we created is included self.assert_(len(apeers) == 1) self.assert_(apeers[0][1] == 4321)
def setUpPostSession(self): """ override TestAsServer """ TestAsServer.setUpPostSession(self) self.mypermid = str(self.my_keypair.pub().get_der()) self.hispermid = str(self.his_keypair.pub().get_der()) # Calculating the infohash for proxyservice.test.torrent self.torrentfile = os.path.join('extend_hs_dir','proxyservice.test.torrent') # Read torrentfile to calculate the infohash torrentfile_content = open(self.torrentfile, "rb") # Decode all the file metainfo = bdecode(torrentfile_content.read()) # Re-encode only the info section self.infohash = hashlib.sha1(bencode(metainfo['info'])).digest() # Close the torrentfile torrentfile_content.close() # Add us as friend, so he will accept the ASK_FOR_HELP if False: # TEMP friendsdb = FriendDBHandler.getInstance() friendsdb.addFriend(self.mypermid) else: self.session.set_overlay_request_policy(AllowAllRequestPolicy()) self.session.set_download_states_callback(self.states_callback)
def check_ut_pex(self,data,pex_id): self.assert_(data[0] == chr(pex_id)) d = bdecode(data[1:]) print >>sys.stderr,"test: d is",`d` self.assert_(type(d) == DictType) self.assert_('added' in d.keys()) cp = d['added'] apeers = self.check_compact_peers(cp) print >>sys.stderr,"test: apeers is",apeers self.assert_('added.f' in d.keys()) f = d['added.f'] print "test: Length of added.f",len(f) self.assert_(type(f) == StringType) self.assert_(len(apeers) == len(f)) self.assert_('dropped' in d.keys()) cp = d['dropped'] self.check_compact_peers(cp) # Check that the fake client we created is included self.assert_(len(apeers) == 1) self.assert_(apeers[0][1] == 4321)
def gotBarterCastMessage(self, recv_msg, sender_permid, selversion): """ Received a bartercast message and handle it. Reply if needed """ if DEBUG: print >> sys.stderr, 'bartercast: %s Received a BarterCast msg from %s' % ( ctime(now()), self.bartercastdb.getName(sender_permid)) if not sender_permid or sender_permid == self.bartercastdb.my_permid: print >> sys.stderr, "bartercast: error - got BarterCastMsg from a None peer", \ sender_permid, recv_msg return False if MAX_BARTERCAST_LENGTH > 0 and len(recv_msg) > MAX_BARTERCAST_LENGTH: print >> sys.stderr, "bartercast: warning - got large BarterCastMsg", len( recv_msg) return False bartercast_data = {} try: bartercast_data = bdecode(recv_msg) except: print >> sys.stderr, "bartercast: warning, invalid bencoded data" return False try: # check bartercast message self.validBarterCastMsg(bartercast_data) except RuntimeError, msg: print >> sys.stderr, msg return False
def getStatus(url, info_hash, info_hashes): returndict = {} try: resp = timeouturlopen.urlOpenTimeout(url, timeout=HTTP_TIMEOUT) response = resp.read() response_dict = bdecode(response) for cur_infohash, status in response_dict["files"].iteritems(): seeder = max(0, status["complete"]) leecher = max(0, status["incomplete"]) returndict[cur_infohash] = (seeder, leecher) return returndict except IOError: return {info_hash: (-1, -1)} except KeyError: try: if response_dict.has_key("flags"): # may be interval problem if response_dict["flags"].has_key("min_request_interval"): return {info_hash: (-3, -3)} except: pass except: pass return None
def test_createSingleResponseMessage(self): langUtil = LanguagesProvider.getLanguagesInstance() data = { 'permid' : testDestPermId, 'channel_id' : testChannelId, 'infohash' : testInfohash, 'subtitles' : {"eng" : "This is content 1", "nld": "This is content 2", "ita" : "This is content 3"}, 'selversion' : OLPROTO_VER_FOURTEENTH } langs = data['subtitles'].keys() bitmask = langUtil.langCodesToMask(langs) binaryBitmask = pack("!L", bitmask) expextedMessage = SUBS + \ bencode(( data['channel_id'], data['infohash'], binaryBitmask, [data['subtitles']['eng'], data['subtitles']['ita'], data['subtitles']['nld']] )) msg = self.underTest._createSingleResponseMessage(data) decoded = bdecode(msg[1:]) self.assertEquals(expextedMessage, msg)
def readTorrent(self, torrent): try: torrent_path = torrent['torrent_path'] if not path.isfile(torrent_path): #torrent not found, try filename + current torrent collection directory torrent_collection_dir = Session.get_instance().get_torrent_collecting_dir() _, torrent_filename = path.split(torrent_path) torrent_path = path.join(torrent_collection_dir, torrent_filename) if not path.isfile(torrent_path): #torrent still not found, determine filename + current torrent collection directory torrent_path = path.join(torrent_collection_dir, get_collected_torrent_filename(torrent['infohash'])) if path.isfile(torrent_path): f = open(torrent_path,'rb') _data = f.read() f.close() data = bdecode(_data) assert 'info' in data del data['info'] torrent['info'] = data return torrent except Exception: #print_exc() return torrent
def gotBarterCastMessage(self, recv_msg, sender_permid, selversion): """ Received a bartercast message and handle it. Reply if needed """ if DEBUG: print >>sys.stderr,'bartercast: %s Received a BarterCast msg from %s'% (ctime(now()), self.bartercastdb.getName(sender_permid)) if not sender_permid or sender_permid == self.bartercastdb.my_permid: print >> sys.stderr, "bartercast: error - got BarterCastMsg from a None peer", \ sender_permid, recv_msg return False if MAX_BARTERCAST_LENGTH > 0 and len(recv_msg) > MAX_BARTERCAST_LENGTH: print >> sys.stderr, "bartercast: warning - got large BarterCastMsg", len(recv_msg) return False bartercast_data = {} try: bartercast_data = bdecode(recv_msg) except: print >> sys.stderr, "bartercast: warning, invalid bencoded data" return False try: # check bartercast message self.validBarterCastMsg(bartercast_data) except RuntimeError, msg: print >> sys.stderr, msg return False
def recv_query_reply(self, permid, message, selversion): #print "****** recv query reply", len(message) if selversion < OLPROTO_VER_SIXTH: return False if len(message) > MAX_QUERY_REPLY_LEN: return True # don't close # Unpack try: d = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, "rquery: Cannot bdecode QUERY_REPLY message" return False if not isValidQueryReply(d, selversion): if DEBUG: print >> sys.stderr, "rquery: not valid QUERY_REPLY message" return False # Check auth queryrec = self.is_registered_query_id(d['id']) if not queryrec: if DEBUG: print >> sys.stderr, "rquery: QUERY_REPLY has unknown query ID" return False # Process self.process_query_reply(permid, queryrec['query'], queryrec['usercallback'], d) return True
def subtest_good_friendship_req_fromhim(self,mtype,fwd=None,mresp=None): print >>sys.stderr,"test: good FRIENDSHIP req from him",mtype,fwd # He should try to forward the request to us, his friend try: self.destss.settimeout(330.0) conn, addr = self.destss.accept() s = OLConnection(self.dest_keypair,'',0,conn,self.destport) while True: resp = s.recv() self.assert_(len(resp) > 0) print >>sys.stderr,"test: good FRIENDSHIP fwd: Dest got reply",getMessageName(resp[0]) if resp[0] == FRIENDSHIP: break elif resp[0] == SOCIAL_OVERLAP: d = bdecode(resp[1:]) print >>sys.stderr,"test: SOCIAL OVERLAP",`d` pass else: self.assert_(False) except socket.timeout: print >> sys.stderr,"test: Timeout, bad, peer didn't connect to FWD dest" self.assert_(False) self.check_friendship(resp[1:],mtype,fwd,mresp,source=self.hispermid,dest=self.mypermid)
def check_friendship(self,data,mtype,fwd,resp,dobdecode=True,source=None,dest=None): if dobdecode: d = bdecode(data) else: d = data print >>sys.stderr,"test: Got FRIENDSHIP",`d`,type(d) self.assert_(type(d) == DictType) self.assert_('msg type' in d) self.assert_(type(d['msg type']) == StringType) self.assert_(d['msg type'] == mtype) if mtype == RESP: self.assert_('response' in d) self.assert_(type(d['response']) == IntType) print >>sys.stderr,"test: COMPARE",`d['response']`,`resp` self.assert_(d['response'] == resp) elif mtype == FWD: self.assert_('source' in d) self.check_peer(d['source'],permid=source) self.assert_('dest' in d) self.check_peer(d['dest'],permid=dest) self.assert_('msg' in d) self.check_friendship(d['msg'],fwd,None,resp,dobdecode=False)
def handle_crawler_reply(self, permid, selversion, channel_id, channel_data, error, message, request_callback): """ Received a CRAWLER_FRIENDSHIP_STATS request. @param permid The Crawler permid @param selversion The overlay protocol version @param channel_id Identifies a CRAWLER_REQUEST/CRAWLER_REPLY pair @param error The error value. 0 indicates success. @param message The message payload @param request_callback Call this function one or more times to send the requests: request_callback(message_id, payload) """ if error: if DEBUG: print >> sys.stderr, "friendshipcrawler: handle_crawler_reply" print >> sys.stderr, "friendshipcrawler: error", error, message else: try: d = bdecode(message) except Exception: print_exc() else: if DEBUG: print >> sys.stderr, "friendshipcrawler: handle_crawler_reply" print >> sys.stderr, "friendshipcrawler: friendship: Got",`d` self.saveFriendshipStatistics(permid,d['current time'],d['stats']) return True
def convert_BartercastDB(self): print >> sys.stderr, "convert_BartercastDB" db_path = os.path.join(self.bsddb_dir, 'bartercast.bsd') if not os.path.isfile(db_path): return bc_db = BarterCastDB.getInstance(self.bsddb_dir) insert_bc_sql = """ INSERT INTO BarterCast (peer_id_from, peer_id_to, downloaded, uploaded, last_seen, value) VALUES (?,?,?,?,?,?) """ values = [] for key, db_data in bc_db._data.iteritems(): try: permid_from, permid_to = bdecode(key) permid_id_from = self._getPeerID(permid_from) if permid_id_from is None: self._addPeerToDB(permid_from) permid_id_from = self._getPeerID(permid_from) permid_id_to = self._getPeerID(permid_to) if permid_id_to is None: self._addPeerToDB(permid_to) permid_id_to = self._getPeerID(permid_to) downloaded = db_data.get('downloaded', 0) uploaded = db_data.get('uploaded', 0) last_seen = db_data.get('last_seen', 0) value = db_data.get('value', 0) values.append((permid_id_from, permid_id_to, downloaded, uploaded, last_seen, value)) except Exception, msg: print >> sys.stderr, "error input for convert_BartercastDB:", key, db_data, Exception, msg
def check_response1(self, resp1_data, rB, myid): resp1 = bdecode(resp1_data) self.assert_(type(resp1) == DictType) self.assert_(resp1.has_key('certA')) self.assert_(resp1.has_key('rA')) self.assert_(resp1.has_key('B')) self.assert_(resp1.has_key('SA')) # show throw exception when key no good pubA = EC.pub_key_from_der(resp1['certA']) rA = resp1['rA'] self.assert_(type(rA) == StringType) self.assert_(len(rA) == random_size) B = resp1['B'] self.assert_(type(B) == StringType) self.assert_(B, myid) SA = resp1['SA'] self.assert_(type(SA) == StringType) # verify signature sig_list = [rA, rB, myid] sig_data = bencode(sig_list) sig_hash = sha.sha(sig_data).digest() self.assert_(pubA.verify_dsa_asn1(sig_hash, SA)) # Cannot resign the data with his keypair to double check. Signing # appears to yield different, supposedly valid sigs each time. return resp1
def subtest_good_friendship_stats(self): """ Send a valid message-id from a registered crawler peer """ print >>sys.stderr, "-"*80, "\ntest: good friendship stats" s = OLConnection(self.my_keypair, "localhost", self.hisport) t = time.time() - 100.0 msg_dict = {'current time':int(t)} payload = bencode(msg_dict) self.send_crawler_request(s, CRAWLER_FRIENDSHIP_STATS, 0, 0, payload) error, payload = self.receive_crawler_reply(s, CRAWLER_FRIENDSHIP_STATS, 0) assert error == 0 d = bdecode(payload) if DEBUG: print >>sys.stderr, "test: Got FRIENDSHIPSTATISTICS",`d` stats = d['stats'] self.assert_(len(stats) == 1) record = d['stats'][0] self.assert_(record[0] == bin2str(self.his_permid)) # source_permid self.assert_(record[1] == bin2str(self.some_permid)) # target_permid self.assert_(record[2] == 0) # isForwarder time.sleep(1) s.close()
def recv_query(self,permid,message,selversion): if selversion < OLPROTO_VER_SIXTH: return False # Unpack try: d = bdecode(message[1:]) except: if DEBUG: print >>sys.stderr,"rquery: Cannot bdecode QUERY message" #print_exc() return False if not isValidQuery(d,selversion): if DEBUG: print >>sys.stderr,"rquery: QUERY invalid",`d` return False # ACCESS CONTROL, INCLUDING CHECKING IF PEER HAS NOT EXCEEDED # QUERY QUOTUM IS DONE in Tribler/Core/RequestPolicy.py # # Process self.process_query(permid, d, selversion) return True
def handle_crawler_reply(self, permid, selversion, channel_id, channel_data, error, message, request_callback): """ Received a CRAWLER_FRIENDSHIP_STATS request. @param permid The Crawler permid @param selversion The overlay protocol version @param channel_id Identifies a CRAWLER_REQUEST/CRAWLER_REPLY pair @param error The error value. 0 indicates success. @param message The message payload @param request_callback Call this function one or more times to send the requests: request_callback(message_id, payload) """ if error: if DEBUG: print >> sys.stderr, "friendshipcrawler: handle_crawler_reply" print >> sys.stderr, "friendshipcrawler: error", error, message else: try: d = bdecode(message) except Exception: print_exc() else: if DEBUG: print >> sys.stderr, "friendshipcrawler: handle_crawler_reply" print >> sys.stderr, "friendshipcrawler: friendship: Got", ` d ` self.saveFriendshipStatistics(permid, d['current time'], d['stats']) return True
def check_rquery_reply(self,querytype,data,goodtorrents): d = bdecode(data) print >>sys.stderr,"test: Got reply",`d` self.assert_(type(d) == DictType) self.assert_(d.has_key('a')) self.check_adict(d['a']) self.assert_(d.has_key('id')) id = d['id'] self.assert_(type(id) == StringType) k = d['a'].keys() self.assert_(len(k) == 2) var1 = k[0] == goodtorrents.keys()[0] and k[1] == goodtorrents.keys()[1] var2 = k[0] == goodtorrents.keys()[1] and k[1] == goodtorrents.keys()[0] self.assert_(var1 or var2) # OLPROTO_VER_NINETH must contain torrent_size for infohash, torrent in d['a'].iteritems(): self.assert_(torrent['torrent_size'], goodtorrents[infohash]) if querytype.startswith("SIMPLE+METADATA"): for infohash, torrent in d['a'].iteritems(): self.assert_('metadata' in torrent) bmetainfo = torrent['metadata'] self.assert_(bmetainfo == goodtorrents[infohash])
def handle_crawler_request(self, permid, selversion, channel_id, message, reply_callback): """ Received a CRAWLER_FRIENDSHIP_QUERY request. @param permid The Crawler permid @param selversion The overlay protocol version @param channel_id Identifies a CRAWLER_REQUEST/CRAWLER_REPLY pair @param message The message payload @param reply_callback Call this function once to send the reply: reply_callback(payload [, error=123]) """ if DEBUG: print >> sys.stderr, "FriendshipCrawler: handle_friendship_crawler_database_query_request", message try: d = bdecode(message) stats = self.getStaticsFromFriendshipStatisticsTable( self.session.get_permid(), d['current time']) msg_dict = {'current time': d['current time'], 'stats': stats} msg = bencode(msg_dict) reply_callback(msg) except Exception, e: print_exc() reply_callback(str(e), 1)
def subtest_valid_nat_check(self): """ Send a CRAWLER_NATCHECK message to the Tribler instance. A reply containing a nat type should be returned. """ print >>sys.stderr, "-"*80, "\ntest: subtest_valid_nat_check" # make sure that the OLConnection IS in the crawler_db crawler_db = CrawlerDBHandler.getInstance() crawler_db.temporarilyAddCrawler(self.my_permid) s = OLConnection(self.my_keypair, "localhost", self.hisport, mylistenport=self.listen_port) self.send_crawler_request(s, CRAWLER_NATCHECK, 42, 0, "") s.close() if DEBUG: print >>sys.stderr, "test_natcheck: the nat-check code allows for a 10 minute delay in reporting the nat stats" self.listen_socket.settimeout(11 * 60) # wait for reply try: conn, addr = self.listen_socket.accept() except socket.timeout: if DEBUG: print >> sys.stderr,"test_natcheck: timeout, bad, peer didn't connect to send the crawler reply" assert False, "test_natcheck: timeout, bad, peer didn't connect to send the crawler reply" s = OLConnection(self.my_keypair, "", 0, conn, mylistenport=self.listen_port) # read reply error, payload = self.receive_crawler_reply(s, CRAWLER_NATCHECK, 42) assert error == 0 if DEBUG: print >>sys.stderr, "test_natcheck:", bdecode(payload) time.sleep(1)
def getStatus(url, info_hash, info_hashes): returndict = {} try: resp = timeouturlopen.urlOpenTimeout(url,timeout=HTTP_TIMEOUT) response = resp.read() response_dict = bdecode(response) for cur_infohash, status in response_dict["files"].iteritems(): seeder = max(0, status["complete"]) leecher = max(0, status["incomplete"]) returndict[cur_infohash] = (seeder, leecher) return returndict except IOError: return {info_hash: (-1, -1)} except KeyError: try: if response_dict.has_key("flags"): # may be interval problem if response_dict["flags"].has_key("min_request_interval"): return {info_hash: (-3 ,-3)} except: pass except: pass return None
def run(self): announce = self._tracker + "?" + urlencode( { "info_hash": self._swarm.get_info_hash(), "peer_id": self._swarm.get_peer_id(), "port": "12345", "compact": "1", "uploaded": "0", "downloaded": "0", "left": "-1", "event": "started" }) try: body = bdecode(urlopen(announce).read()) except: pass else: # using low-bandwidth binary format peers = [] peer_data = body["peers"] for x in range(0, len(peer_data), 6): # key = peer_data[x:x+6] ip = ".".join([str(ord(i)) for i in peer_data[x:x + 4]]) port = (ord(peer_data[x + 4]) << 8) | ord(peer_data[x + 5]) peers.append((ip, port)) if DEBUG: print >> sys.stderr, "MiniTracker.run() received", len( peers), "peer addresses from tracker" self._swarm.add_potential_peers(peers)
def add_metadata_piece(self, piece, data): """ A metadata piece was received """ if not self._closed: for index, block_tuple in zip(xrange(len(self._metadata_blocks)), self._metadata_blocks): if block_tuple[1] == piece: block_tuple[0] = max(0, block_tuple[0] - 1) block_tuple[2] = data self._metadata_blocks.sort() break # def p(s): # if s is None: return 0 # return len(s) # if DEBUG: print >> sys.stderr, "Progress:", [p(t[2]) for t in self._metadata_blocks] # see if we are done for requested, piece, data in self._metadata_blocks: if data is None: break else: # _metadata_blocks is sorted by requested count. we need to sort it by piece-id metadata_blocks = [(piece, data) for _, piece, data in self._metadata_blocks] metadata_blocks.sort() metadata = "".join([data for _, data in metadata_blocks]) info_hash = sha(metadata).digest() if info_hash == self._info_hash: if DEBUG: print >> sys.stderr, "MiniBitTorrent.add_metadata_piece() Done!" # get nice list with recent BitTorrent peers, sorted # by most recently connected peers = [ (timestamp, address) for address, timestamp in self._good_peers.iteritems() ] peers.sort(reverse=True) peers = [address for _, address in peers] self._callback(bdecode(metadata), peers) else: # for piece, data in metadata_blocks: # open("failed-hash-{0}.data".format(piece), "w+").write(data) # todo: hash failed... now what? # quick solution... remove everything and try again if DEBUG: print >> sys.stderr, "MiniBitTorrent.add_metadata_piece() Failed hashcheck! Restarting all over again :(" self._metadata_blocks = [[ requested, piece, None ] for requested, piece, data in self._metadata_blocks]
def got_metadata(self, permid, message, selversion): """ receive torrent file from others """ # Arno, 2007-06-20: Disabled the following code. What's this? Somebody sends # us something and we refuse? Also doesn't take into account download help #and remote-query extension. #if self.upload_rate <= 0: # if no upload, no download, that's the game # return True # don't close connection try: message = bdecode(message[1:]) except: print_exc() return False if not isinstance(message, dict): return False try: infohash = message['torrent_hash'] if not isValidInfohash(infohash): return False if not infohash in self.requested_torrents: # got a torrent which was not requested return True if self.torrent_db.hasMetaData(infohash): return True metadata = message['metadata'] if not self.valid_metadata(infohash, metadata): return False if DEBUG: torrent_size = len(metadata) print >> sys.stderr,"metadata: Recvd torrent", `infohash`, sha(infohash).hexdigest(), torrent_size extra_info = {} if selversion >= OLPROTO_VER_FOURTH: try: extra_info = {'leecher': message.get('leecher', -1), 'seeder': message.get('seeder', -1), 'last_check_time': message.get('last_check_time', -1), 'status':message.get('status', 'unknown')} except Exception, msg: print_exc() print >> sys.stderr, "metadata: wrong extra info in msg - ", message extra_info = {} filename = self.save_torrent(infohash, metadata, extra_info=extra_info) self.requested_torrents.remove(infohash) if DEBUG: print >>sys.stderr,"metadata: Was I asked to dlhelp someone",self.dlhelper self.notify_torrent_is_in(infohash,metadata,filename) # BarterCast: add bytes of torrent to BarterCastDB # Save exchanged KBs in BarterCastDB if permid != None and BARTERCAST_TORRENTS: self.overlay_bridge.add_task(lambda:self.olthread_bartercast_torrentexchange(permid, 'downloaded'), 0)
def send_metadata(self, permid, message, selversion): try: infohash = bdecode(message[1:]) except: print_exc() if DEBUG: print >> sys.stderr,"metadata: GET_METADATA: error becoding" return False if not isValidInfohash(infohash): if DEBUG: print >> sys.stderr,"metadata: GET_METADATA: invalid hash" return False # TODO: res = self.torrent_db.getOne(('torrent_file_name', 'status_id'), infohash=bin2str(infohash)) if not res: if DEBUG: print >> sys.stderr,"metadata: GET_METADATA: not in database" return True # don't close connection because I don't have the torrent torrent_file_name, status_id = res if status_id == self.torrent_db._getStatusID('dead'): if DEBUG: print >> sys.stderr,"metadata: GET_METADATA: Torrent was dead" return True if not torrent_file_name: return True torrent_path = os.path.join(self.torrent_dir, torrent_file_name) if not os.path.isfile(torrent_path): if DEBUG: print >> sys.stderr,"metadata: GET_METADATA: not existing", res, torrent_path return True # # data = self.torrent_db.getTorrent(infohash) # if not data or not data['torrent_name']: # return True # don't close connection # live = data.get('status', 'unknown') # #print "**************** check live before send metadata", live # if live == 'dead': # return True # don't send dead torrents around # # torrent_path = None # try: # torrent_path = os.path.join(data['torrent_dir'], data['torrent_name']) # if not os.path.isfile(torrent_path): # torrent_path = None # except: # print_exc() # # if not torrent_path: # if DEBUG: # print >> sys.stderr,"metadata: GET_METADATA: not torrent path" # return True task = {'permid':permid, 'infohash':infohash, 'torrent_path':torrent_path, 'selversion':selversion} self.upload_queue.append(task) if int(time()) >= self.next_upload_time: self.checking_upload_queue() return True
def _read(stream): """ Internal class method that reads a torrent file from stream, checks it for correctness and sets self.input and self.metainfo accordingly. """ bdata = stream.read() stream.close() data = bdecode(bdata) return TorrentDef._create(data)
def subtest_channel_keyword_query(self,nickname): print >>sys.stderr,"test: chquery keyword-----------------------------" s = OLConnection(self.my_keypair,'localhost',self.hisport) data = {} uq = u'CHANNEL k '+nickname data['q'] = uq.encode("UTF-8") data['id'] = 'b' * 20 msg = QUERY + bencode(data) s.send(msg) resp = s.recv() #print >> sys.stderr, "printing resp", resp if len(resp) > 0: print >>sys.stderr,"test: chquery: got",getMessageName(resp[0]) self.assert_(resp[0]==QUERY_REPLY) self.check_chquery_reply(resp[1:],nickname) print >>sys.stderr,"test:",`bdecode(resp[1:])` s.close()
def gotUdpConnectReply(self, permid, selversion, channel_id, channel_data, error, mhr_msg, request_callback): if DEBUG: print >>sys.stderr, "NatCheckMsgHandler: gotMakeHoleReplyMessage" try: mhr_data = bdecode(mhr_msg) except: print_exc() print >>sys.stderr, "NatCheckMsgHandler: bad encoded data:", mhr_msg return False if DEBUG: print >>sys.stderr, "NatCheckMsgHandler: message is", mhr_data try: request_id, reply = mhr_data.split(":") except: print_exc() print >>sys.stderr, "NatCheckMsgHandler: error in received data:", mhr_data return False if DEBUG: print >>sys.stderr, "NatCheckMsgHandler: request_id is", request_id if request_id in self.trav: if DEBUG: print >>sys.stderr, "NatCheckMsgHandler: request_id is in the list" peer, value = self.trav[request_id] if peer == None: # first peer reply if DEBUG: print >>sys.stderr, "NatCheckMsgHandler: first peer reply" self.trav[request_id] = ((permid, self._secure_overlay.get_dns_from_peerdb(permid)), reply) elif type(peer) == TupleType: # second peer reply if DEBUG: print >>sys.stderr, "NatCheckMsgHandler: second peer reply" # Register peerinfo on file self._file2.write( "; ".join( ( strftime("%Y/%m/%d %H:%M:%S"), " REPLY", request_id, show_permid(peer[0]), str(peer[1]), value, show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), reply, "\n", ) ) ) del self.trav[request_id] self._file2.flush()
def _refresh(self): channel_url = None try: self.key_url_lock.acquire() channel_url = deepcopy(self.key_url) finally: self.key_url_lock.release() if channel_url: for key, urls in channel_url.iteritems(): if key in self.key_callbacks: for url in urls: if DEBUG: print >> sys.stderr, "RssParser: getting rss", url, len(urls) historyfile = self.gethistfilename(url, key) urls_already_seen = URLHistory(historyfile) urls_already_seen.read() newItems = self.readUrl(url, urls_already_seen) for title, new_urls, description, thumbnail in newItems: for new_url in new_urls: urls_already_seen.add(new_url) urls_already_seen.write() try: if DEBUG: print >> sys.stderr, "RssParser: trying", new_url referer = urlparse(new_url) referer = referer.scheme+"://"+referer.netloc+"/" stream = urlOpenTimeout(new_url, referer=referer) bdata = stream.read() stream.close() bddata = bdecode(bdata, 1) torrent = TorrentDef._create(bddata) def processCallbacks(key): for callback in self.key_callbacks[key]: try: callback(key, torrent, extraInfo = {'title':title, 'description': description, 'thumbnail': thumbnail}) except: print_exc() if self.remote_th.is_registered(): callback = lambda key=key: processCallbacks(key) self.remote_th.save_torrent(torrent, callback) else: processCallbacks(key) except: if DEBUG: print >> sys.stderr, "RssParser: could not download", new_url pass time.sleep(RSS_CHECK_FREQUENCY)
def check_challenge(cdata): try: randomB = bdecode(cdata) except: return None if len(randomB) != num_random_bits / 8: return None else: return randomB
def olthread_process_dialback_reply(self, dns, message): # Called by overlay thread # 1. Yes, we're reachable, now just matter of determining ext IP self.dbreach = True # 2. Authentication: did I ask this peer? permid = self.olthread_permid_of_asked_peer(dns) if permid is None: if DEBUG: print >> sys.stderr, "dialback: DIALBACK_REPLY: Got reply from peer I didn't ask", dns return False del self.peers_asked[permid] # 3. See what he sent us try: myip = bdecode(message[1:]) except: print_exc() if DEBUG: print >> sys.stderr, "dialback: DIALBACK_REPLY: error becoding" return False if not isValidIP(myip): if DEBUG: print >> sys.stderr, "dialback: DIALBACK_REPLY: invalid IP" return False # 4. See if superpeer, then we're done, trusted source if self.trust_superpeers: superpeers = self.superpeer_db.getSuperPeers() if permid in superpeers: if DEBUG: print >> sys.stderr, "dialback: DIALBACK_REPLY: superpeer said my IP address is", myip, "setting it to that" self.consensusip = myip self.fromsuperpeer = True else: # 5, 6. 7, 8. Record this peers opinion and see if we get a # majority vote. # self.myips, consensusip = tally_opinion(myip, self.myips, PEERS_TO_AGREE) if self.consensusip is None: self.consensusip = consensusip # 8. Change IP address if different if self.consensusip is not None: self.launchmany.dialback_got_ext_ip_callback(self.consensusip) if DEBUG: print >> sys.stderr, "dialback: DIALBACK_REPLY: I think my IP address is", self.old_ext_ip, "others say", self.consensusip, ", setting it to latter" # 9. Notify GUI that we are connectable self.launchmany.dialback_reachable_callback() return True
def check_reserve_pieces(self, data): # torrent_hash + 1-byte all_or_nothing + bencode([piece num,...]) self.assert_(len(data) > 21) infohash = data[0:20] allflag = data[20] plist = bdecode(data[21:]) self.assert_(infohash == self.infohash) self.assert_(type(plist) == ListType) return plist
def _decodeGETSUBSMessage(self, message): """ From a bencoded GET_SUBS messages, returns its decoded contents. Decodes and checks for validity a bencoded GET_SUBS messages. If the message is succesfully decoded returns the tuple (channel_id,infohash,languages). channel_id is the binary identifier of the chanel that published the requested subtitles. infohash is the binary identifier of the torrent wich the subtitle refers to languages is a list of 3 characters language codes, for the languages of the requested subtitles @return: (channel_id,infohash,languages) or None if something is wrong """ assert message[0] == GET_SUBS, SUBS_LOG_PREFIX + \ "Invalid GET_SUBS Message header: %s" % message[0] try: values = bdecode(message[1:]) except: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + "Error bdecoding message" return None if len(values) != 3: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + "Invalid number of fields in GET_SUBS" return None channel_id, infohash, bitmask = values[0], values[1], values[2] if not validPermid(channel_id): if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + "Invalid channel_id in GET_SUBS" return None elif not validInfohash(infohash): if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + "Invalid infohash in GET_SUBS" return None elif not isinstance(bitmask, str) or not len(bitmask) == 4: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + "Invalid bitmask in GET_SUBS" return None try: bitmask, = unpack("!L", bitmask) languages = self._languagesUtility.maskToLangCodes(bitmask) except: if DEBUG: print >> sys.stderr, SUBS_LOG_PREFIX + "Invalid bitmask in GET_SUBS" return None return channel_id, infohash, languages
def check_tribler_extend_hs(self, data): self.assert_(data[0] == chr(0)) d = bdecode(data[1:]) self.assert_(type(d) == DictType) self.assert_('m' in d.keys()) m = d['m'] self.assert_(type(m) == DictType) self.assert_('Tr_OVERLAYSWARM' in m.keys()) val = m['Tr_OVERLAYSWARM'] self.assert_(type(val) == IntType) self.assert_(val == 253)
def check_g2g_v2(self,data,g2g_id): self.assert_(data[0] == chr(g2g_id)) d = bdecode(data[1:]) print >>sys.stderr,"test: l is",`d` self.assert_(type(d) == DictType) for k,v in d.iteritems(): self.assert_(type(k) == StringType) self.assert_(type(v) == StringType) self.assert_(ord(k) > 0) self.assert_(ord(v) <= 100)
def got_reserve_pieces(self, permid, message,selversion): try: infohash = message[1:21] all_or_nothing = message[21] pieces = bdecode(message[22:]) except: print >> sys.stderr, "warning: bad data in RESERVE_PIECES" return False network_got_reserve_pieces_lambda = lambda:self.network_got_reserve_pieces(permid,infohash,pieces,all_or_nothing,selversion) self.launchmany.rawserver.add_task(network_got_reserve_pieces_lambda,0) return True
def check_rquery(self, data): d = bdecode(data) self.assert_(type(d) == DictType) self.assert_(d.has_key('q')) q = d['q'] self.assert_(type(q) == StringType) self.assert_(d.has_key('id')) id = d['id'] self.assert_(type(id) == StringType) self.assert_(q == TEST_QUERY_ONWIRE) return d['id']
def valid_metadata(self, infohash, metadata): try: metainfo = bdecode(metadata) got_infohash = sha(bencode(metainfo['info'])).digest() if infohash != got_infohash: print >> sys.stderr, "metadata: infohash doesn't match the torrent " + \ "hash. Required: " + `infohash` + ", but got: " + `got_infohash` return False return True except: print_exc() print >> sys.stderr, "problem metadata:", repr(metadata) return False
def gotUdpConnectReply(self, permid, selversion, channel_id, channel_data, error, mhr_msg, request_callback): if DEBUG: print >> sys.stderr, "NatCheckMsgHandler: gotMakeHoleReplyMessage" try: mhr_data = bdecode(mhr_msg) except: print_exc() print >> sys.stderr, "NatCheckMsgHandler: bad encoded data:", mhr_msg return False if DEBUG: print >> sys.stderr, "NatCheckMsgHandler: message is", mhr_data try: request_id, reply = mhr_data.split(":") except: print_exc() print >> sys.stderr, "NatCheckMsgHandler: error in received data:", mhr_data return False if DEBUG: print >> sys.stderr, "NatCheckMsgHandler: request_id is", request_id if request_id in self.trav: if DEBUG: print >> sys.stderr, "NatCheckMsgHandler: request_id is in the list" peer, value = self.trav[request_id] if peer == None: # first peer reply if DEBUG: print >> sys.stderr, "NatCheckMsgHandler: first peer reply" self.trav[request_id] = (( permid, self._secure_overlay.get_dns_from_peerdb(permid)), reply) elif type(peer) == TupleType: # second peer reply if DEBUG: print >> sys.stderr, "NatCheckMsgHandler: second peer reply" # Register peerinfo on file self._file2.write("; ".join( (strftime("%Y/%m/%d %H:%M:%S"), " REPLY", request_id, show_permid(peer[0]), str(peer[1]), value, show_permid(permid), str(self._secure_overlay.get_dns_from_peerdb(permid)), reply, "\n"))) del self.trav[request_id] self._file2.flush()
def valid_metadata(self, infohash, metadata): try: metainfo = bdecode(metadata) tdef = TorrentDef.load_from_dict(metainfo) got_infohash = tdef.get_infohash() if infohash != got_infohash: print >> sys.stderr, "metadata: infohash doesn't match the torrent " + \ "hash. Required: " + `infohash` + ", but got: " + `got_infohash` return False return True except: print_exc() #print >> sys.stderr, "problem metadata:", repr(metadata) return False
def check_rquery_reply(self, data): d = bdecode(data) self.assert_(type(d) == DictType) self.assert_(d.has_key('a')) self.check_adict(d['a']) self.assert_(d.has_key('id')) id = d['id'] self.assert_(type(id) == StringType) k = d['a'].keys() self.assert_(len(k) == 2) var1 = k[0] == ('b' * 20) and k[1] == ('c' * 20) var2 = k[0] == ('c' * 20) and k[1] == ('b' * 20) self.assert_(var1 or var2)
def got_pieces_reserved(self, permid, message, selversion): try: infohash = message[1:21] pieces = bdecode(message[21:]) except: print >> sys.stderr, "helper: warning: bad data in PIECES_RESERVED" return False network_got_pieces_reserved_lambda = lambda: self.network_got_pieces_reserved( permid, message, selversion, infohash, pieces) self.session.lm.rawserver.add_task(network_got_pieces_reserved_lambda, 0) return True