def handle_state_announce(self): assert self.conn_id if self.conn_id_expires < time.time(): print timestamp(), self, "Connection ID expired" self.goto_state_conn_id() return if not self.current_swarm in [ x for x in Swarm.list() if not x.closed ]: self.goto_state_swarm() return if time.time() < self.announce_next_attempt: return retry_text = '' if self.announce_retry > 0: retry_text = ', retry %d' % self.announce_retry print timestamp(), self, "Sending announce for %s%s" % (self.current_swarm, retry_text) buf = '' buf += struct.pack('!QLL', self.conn_id, 1, self.transaction_id) buf += self.current_swarm.sha.decode('hex') buf += hashlib.sha1(Peer.my_peerid).digest() buf += struct.pack('!QQQLLLlH', 0, 0, 0, 1, 0, self.key, -1, self.listen_port) self.send(buf) self.announce_next_attempt = time.time() + config.tracker_retry_time * 2**min(self.announce_retry, 4) self.announce_retry += 1
def on_heartbeat(self): # Kludge for now. Just have every tracker announce every swarm for x in Swarm.list(): self.add_swarm(x) # Cleanup old swarms for x in [x for x in self.swarms.keys() if x.closed or x not in Swarm.list()]: print timestamp(), self, "Swarm seems to have gone away, removing:", x del self.swarms[x] if self.state == STATE_SOCK: self.handle_state_sock() elif self.state == STATE_SWARM: self.handle_state_swarm() elif self.state == STATE_CONN_ID: self.handle_state_conn_id() elif self.state == STATE_ANNOUNCE: self.handle_state_announce() elif self.state == STATE_MUTE: self.handle_state_mute() else: raise Exception("State machine broken?")