📄 track.py
字号:
return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': 'Requested download is not authorized for use with this tracker.'})) if self.config['allowed_controls']: if self.allowed[infohash].has_key('failure reason'): return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': self.allowed[infohash]['failure reason']})) if paramslist.has_key('tracker'): if ( self.config['multitracker_allowed'] == 'none' or # turned off paramslist['peer_id'][0] == self.trackerid ): # oops! contacted myself return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': 'disallowed'})) if ( self.config['multitracker_allowed'] == 'autodetect' and not self.allowed[infohash].has_key('announce-list') ): return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': 'Requested download is not authorized for multitracker use.'})) return None def add_data(self, infohash, event, ip, paramslist): peers = self.downloads.setdefault(infohash, {}) ts = self.times.setdefault(infohash, {}) self.completed.setdefault(infohash, 0) self.seedcount.setdefault(infohash, 0) def params(key, default = None, l = paramslist): if l.has_key(key): return l[key][0] return default myid = params('peer_id','') if len(myid) != 20: raise ValueError, 'id not of length 20' if event not in ['started', 'completed', 'stopped', 'snooped', None]: raise ValueError, 'invalid event' port = params('cryptoport') if port is None: port = params('port','') port = long(port) if port < 0 or port > 65535: raise ValueError, 'invalid port' left = long(params('left','')) if left < 0: raise ValueError, 'invalid amount left' uploaded = long(params('uploaded','')) downloaded = long(params('downloaded','')) if params('supportcrypto'): supportcrypto = 1 try: s = int(params['requirecrypto']) chr(s) except: s = 0 requirecrypto = s else: supportcrypto = 0 requirecrypto = 0 peer = peers.get(myid) islocal = local_IPs.includes(ip) mykey = params('key') if peer: auth = peer.get('key',-1) == mykey or peer.get('ip') == ip gip = params('ip') if is_valid_ip(gip) and (islocal or not self.only_local_override_ip): ip1 = gip else: ip1 = ip if params('numwant') is not None: rsize = min(int(params('numwant')),self.response_size) else: rsize = self.response_size if event == 'stopped': if peer: if auth: self.delete_peer(infohash,myid) elif not peer: ts[myid] = clock() peer = { 'ip': ip, 'port': port, 'left': left, 'supportcrypto': supportcrypto, 'requirecrypto': requirecrypto } if mykey: peer['key'] = mykey if gip: peer['given ip'] = gip if port: if not self.natcheck or islocal: peer['nat'] = 0 self.natcheckOK(infohash,myid,ip1,port,peer) else: NatCheck(self.connectback_result,infohash,myid,ip1,port, self.rawserver,encrypted=requirecrypto) else: peer['nat'] = 2**30 if event == 'completed': self.completed[infohash] += 1 if not left: self.seedcount[infohash] += 1 peers[myid] = peer else: if not auth: return rsize # return w/o changing stats ts[myid] = clock() if not left and peer['left']: self.completed[infohash] += 1 self.seedcount[infohash] += 1 if not peer.get('nat', -1): for bc in self.becache[infohash]: bc[1][myid] = bc[0][myid] del bc[0][myid] elif left and not peer['left']: self.completed[infohash] -= 1 self.seedcount[infohash] -= 1 if not peer.get('nat', -1): for bc in self.becache[infohash]: bc[0][myid] = bc[1][myid] del bc[1][myid] peer['left'] = left if port: recheck = False if ip != peer['ip']: peer['ip'] = ip recheck = True if gip != peer.get('given ip'): if gip: peer['given ip'] = gip elif peer.has_key('given ip'): del peer['given ip'] recheck = True natted = peer.get('nat', -1) if recheck: if natted == 0: l = self.becache[infohash] y = not peer['left'] for x in l: del x[y][myid] if natted >= 0: del peer['nat'] # restart NAT testing if natted and natted < self.natcheck: recheck = True if recheck: if not self.natcheck or islocal: peer['nat'] = 0 self.natcheckOK(infohash,myid,ip1,port,peer) else: NatCheck(self.connectback_result,infohash,myid,ip1,port, self.rawserver,encrypted=requirecrypto) return rsize def peerlist(self, infohash, stopped, tracker, is_seed, return_type, rsize, supportcrypto): data = {} # return data seeds = self.seedcount[infohash] data['complete'] = seeds data['incomplete'] = len(self.downloads[infohash]) - seeds if ( self.config['allowed_controls'] and self.allowed[infohash].has_key('warning message') ): data['warning message'] = self.allowed[infohash]['warning message'] if tracker: data['interval'] = self.config['multitracker_reannounce_interval'] if not rsize: return data cache = self.cached_t.setdefault(infohash, None) if ( not cache or len(cache[1]) < rsize or cache[0] + self.config['min_time_between_cache_refreshes'] < clock() ): bc = self.becache.setdefault(infohash,self.cache_default) cache = [ clock(), bc[0][0].values() + bc[0][1].values() ] self.cached_t[infohash] = cache shuffle(cache[1]) cache = cache[1] data['peers'] = cache[-rsize:] del cache[-rsize:] return data data['interval'] = self.reannounce_interval if stopped or not rsize: # save some bandwidth data['peers'] = [] return data bc = self.becache.setdefault(infohash,self.cache_default) len_l = len(bc[2][0]) len_s = len(bc[2][1]) if not (len_l+len_s): # caches are empty! data['peers'] = [] return data l_get_size = int(float(rsize)*(len_l)/(len_l+len_s)) cache = self.cached.setdefault(infohash,[None,None,None])[return_type] if cache and ( not cache[1] or (is_seed and len(cache[1]) < rsize) or len(cache[1]) < l_get_size or cache[0]+self.config['min_time_between_cache_refreshes'] < self.cachetime ): cache = None if not cache: peers = self.downloads[infohash] if self.config['compact_reqd']: vv = ([],[],[]) else: vv = ([],[],[],[],[]) for key, ip, port in self.t2tlist.harvest(infohash): # empty if disabled if not peers.has_key(key): cp = compact_peer_info(ip, port) vv[0].append(cp) vv[2].append((cp,'\x00')) if not self.config['compact_reqd']: vv[3].append({'ip': ip, 'port': port, 'peer id': key}) vv[4].append({'ip': ip, 'port': port}) cache = [ self.cachetime, bc[return_type][0].values()+vv[return_type], bc[return_type][1].values() ] shuffle(cache[1]) shuffle(cache[2]) self.cached[infohash][return_type] = cache for rr in xrange(len(self.cached[infohash])): if rr != return_type: try: self.cached[infohash][rr][1].extend(vv[rr]) except: pass if len(cache[1]) < l_get_size: peerdata = cache[1] if not is_seed: peerdata.extend(cache[2]) cache[1] = [] cache[2] = [] else: if not is_seed: peerdata = cache[2][l_get_size-rsize:] del cache[2][l_get_size-rsize:] rsize -= len(peerdata) else: peerdata = [] if rsize: peerdata.extend(cache[1][-rsize:]) del cache[1][-rsize:] if return_type == 0: data['peers'] = ''.join(peerdata) elif return_type == 1: data['crypto_flags'] = "0x01"*len(peerdata) data['peers'] = ''.join(peerdata) elif return_type == 2: data['crypto_flags'] = ''.join([p[1] for p in peerdata]) data['peers'] = ''.join([p[0] for p in peerdata]) else: data['peers'] = peerdata return data def get(self, connection, path, headers): real_ip = connection.get_ip() ip = real_ip if is_ipv4(ip): ipv4 = True else: try: ip = ipv6_to_ipv4(ip) ipv4 = True except ValueError: ipv4 = False if ( (self.allowed_IPs and not self.allowed_IPs.includes(ip)) or (self.banned_IPs and self.banned_IPs.includes(ip)) ): return (400, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': 'your IP is not allowed on this tracker'})) nip = get_forwarded_ip(headers)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -