Esempio n. 1
0
 def is_snubbed(self):
     if (self.interested and not self.choked
             and clock() - self.last2 > self.downloader.snub_time):
         for index, begin, length in self.active_requests:
             self.connection.send_cancel(index, begin, length)
         self.got_choke()  # treat it just like a choke
     return clock() - self.last > self.downloader.snub_time
Esempio n. 2
0
 def is_snubbed(self):
     if ( self.interested and not self.choked
          and clock() - self.last2 > self.downloader.snub_time ):
         for index, begin, length in self.active_requests:
             self.connection.send_cancel(index, begin, length)
         self.got_choke()    # treat it just like a choke
     return clock() - self.last > self.downloader.snub_time
Esempio n. 3
0
 def __init__(self, storage, picker, backlog, max_rate_period, numpieces,
              chunksize, measurefunc, snub_time, kickbans_ok, kickfunc,
              banfunc):
     self.storage = storage
     self.picker = picker
     self.backlog = backlog
     self.max_rate_period = max_rate_period
     self.measurefunc = measurefunc
     self.totalmeasure = Measure(max_rate_period * storage.piece_length /
                                 storage.request_size)
     self.numpieces = numpieces
     self.chunksize = chunksize
     self.snub_time = snub_time
     self.kickfunc = kickfunc
     self.banfunc = banfunc
     self.disconnectedseeds = {}
     self.downloads = []
     self.perip = {}
     self.gotbaddata = {}
     self.kicked = {}
     self.banned = {}
     self.kickbans_ok = kickbans_ok
     self.kickbans_halted = False
     self.super_seeding = False
     self.endgamemode = False
     self.endgame_queued_pieces = []
     self.all_requests = []
     self.discarded = 0L
     #        self.download_rate = 25000  # 25K/s test rate
     self.download_rate = 0
     self.bytes_requested = 0
     self.last_time = clock()
     self.queued_out = {}
     self.requeueing = False
     self.paused = False
Esempio n. 4
0
    def __init__(self, storage, picker, backlog, max_rate_period,
                 numpieces, chunksize, measurefunc, snub_time,
                 kickbans_ok, kickfunc, banfunc):
        self.storage = storage
        self.picker = picker
        self.backlog = backlog
        self.max_rate_period = max_rate_period
        self.measurefunc = measurefunc
        self.totalmeasure = Measure(max_rate_period*storage.piece_length/storage.request_size)
        self.numpieces = numpieces
        self.chunksize = chunksize
        self.snub_time = snub_time
        self.kickfunc = kickfunc
        self.banfunc = banfunc
        self.disconnectedseeds = {}
        self.downloads = []
        self.perip = {}
        self.gotbaddata = {}
        self.kicked = {}
        self.banned = {}
        self.kickbans_ok = kickbans_ok
        self.kickbans_halted = False
        self.super_seeding = False
        self.endgamemode = False
        self.endgame_queued_pieces = []
        self.all_requests = []
        self.discarded = 0L
#        self.download_rate = 25000  # 25K/s test rate
        self.download_rate = 0
        self.bytes_requested = 0
        self.last_time = clock()
        self.queued_out = {}
        self.requeueing = False
        self.paused = False
Esempio n. 5
0
    def _round_robin(self):
        self.schedule(self._round_robin, 5)
        curTime = time.time()
        toBeClosed = []
        maxInactiveTime = self.config['max_inactive_time']
        #NOTE:  this is a weird place for this maybe, but it had to be added somewhere...
        #if we have lots of connections
        if len(self.connections)+5 >= self.config['max_initiate']:
          #and there are other peers in the swarm to try:
          if self.get_swarm_size() > 1.5*len(self.connections):
            #close any connections that timed out
            for c in self.connections:
                #ignore seeds:
                if c.download.get_peer_completion() >= 1.0:
                  continue
                if c.lastActive + maxInactiveTime < curTime:
                  toBeClosed.append(c)
            for c in toBeClosed:
              c.protocol.close()

        if self.super_seed:
            cons = range(len(self.connections))
            to_close = []
            count = self.config['min_uploads']-self.last_preferred
            if count > 0:   # optimization
                shuffle(cons)
            for c in cons:
                i = self.picker.next_have(self.connections[c], count > 0)
                if i is None:
                    continue
                if i < 0:
                    to_close.append(self.connections[c])
                    continue
                self.connections[c].send_have(i)
                count -= 1
            for c in to_close:
                c.close()
        if self.last_round_robin + self.round_robin_period < clock():
            self.last_round_robin = clock()
            self.perCircuit = {}
            for i in xrange(1, len(self.connections)):
                c = self.connections[i]
                u = c.get_upload()
                if u.is_choked() and u.is_interested():
                    self.connections = self.connections[i:] + self.connections[:i]
                    break
        self._rechoke()
Esempio n. 6
0
 def next_have(self, connection, looser_upload):
     if self.seed_time is None:
         self.seed_time = clock()
         return None
     if clock(
     ) < self.seed_time + 10:  # wait 10 seconds after seeing the first peers
         return None  # to give time to grab have lists
     if not connection.upload.super_seeding:
         return None
     olddl = self.seed_connections.get(connection)
     if olddl is None:
         ip = connection.get_ip()
         olddl = self.past_ips.get(ip)
         if olddl is not None:  # peer reconnected
             self.seed_connections[connection] = olddl
             if not looser_upload:
                 self.seed_got_haves[olddl] -= 1  # penalize
     if olddl is not None:
         if looser_upload:
             num = 1  # send a new have even if it hasn't spread that piece elsewhere
         else:
             num = 2
         if self.seed_got_haves[olddl] < num:
             return None
         if not connection.upload.was_ever_interested:  # it never downloaded it?
             connection.upload.skipped_count += 1
             if connection.upload.skipped_count >= 3:  # probably another stealthed seed
                 return -1  # signal to close it
     for tier in self.interests:
         for piece in tier:
             if not connection.download.have[piece]:
                 seedint = self.level_in_interests[piece]
                 self.level_in_interests[
                     piece] += 1  # tweak it up one, so you don't duplicate effort
                 if seedint == len(self.interests) - 1:
                     self.interests.append([])
                 self._shift_over(piece, self.interests[seedint],
                                  self.interests[seedint + 1])
                 self.seed_got_haves[piece] = 0  # reset this
                 self.seed_connections[connection] = piece
                 connection.upload.seed_have_list.append(piece)
                 return piece
     return -1  # something screwy; terminate connection
Esempio n. 7
0
 def num_disconnected_seeds(self):
     # first expire old ones
     expired = []
     for id, t in self.disconnectedseeds.items():
         if clock() - t > EXPIRE_TIME:  #Expire old seeds after so long
             expired.append(id)
     for id in expired:
         #            self.picker.seed_disappeared()
         del self.disconnectedseeds[id]
     return len(self.disconnectedseeds)
Esempio n. 8
0
    def num_disconnected_seeds(self):
        # first expire old ones
        expired = []
        for id,t in self.disconnectedseeds.items():
            if clock() - t > EXPIRE_TIME:     #Expire old seeds after so long
                expired.append(id)
        for id in expired:
#            self.picker.seed_disappeared()
            del self.disconnectedseeds[id]
        return len(self.disconnectedseeds)
Esempio n. 9
0
 def send_unchoke(self):
     if self.send_choke_queued:
         self.send_choke_queued = False
         log_msg('%s CHOKE SUPPRESSED' % (self.ccount), 4, "btconn")
     else:
         self._send_message(UNCHOKE)
         if ( self.partial_message or self.just_unchoked is None
              or not self.upload.interested or self.download.active_requests ):
             self.just_unchoked = 0
         else:
             self.just_unchoked = clock()
Esempio n. 10
0
 def next_have(self, connection, looser_upload):
     if self.seed_time is None:
         self.seed_time = clock()
         return None
     if clock() < self.seed_time+10:  # wait 10 seconds after seeing the first peers
         return None                 # to give time to grab have lists
     if not connection.upload.super_seeding:
         return None
     olddl = self.seed_connections.get(connection)
     if olddl is None:
         ip = connection.get_ip()
         olddl = self.past_ips.get(ip)
         if olddl is not None:                           # peer reconnected
             self.seed_connections[connection] = olddl
             if not looser_upload:
                 self.seed_got_haves[olddl] -= 1         # penalize
     if olddl is not None:
         if looser_upload:
             num = 1     # send a new have even if it hasn't spread that piece elsewhere
         else:
             num = 2
         if self.seed_got_haves[olddl] < num:
             return None
         if not connection.upload.was_ever_interested:   # it never downloaded it?
             connection.upload.skipped_count += 1
             if connection.upload.skipped_count >= 3:    # probably another stealthed seed
                 return -1                               # signal to close it
     for tier in self.interests:
         for piece in tier:
             if not connection.download.have[piece]:
                 seedint = self.level_in_interests[piece]
                 self.level_in_interests[piece] += 1  # tweak it up one, so you don't duplicate effort
                 if seedint == len(self.interests) - 1:
                     self.interests.append([])
                 self._shift_over(piece,
                             self.interests[seedint], self.interests[seedint + 1])
                 self.seed_got_haves[piece] = 0       # reset this
                 self.seed_connections[connection] = piece
                 connection.upload.seed_have_list.append(piece)
                 return piece
     return -1       # something screwy; terminate connection
Esempio n. 11
0
 def send_unchoke(self):
     if self.send_choke_queued:
         self.send_choke_queued = False
         log_msg('%s CHOKE SUPPRESSED' % (self.ccount), 4, "btconn")
     else:
         self._send_message(UNCHOKE)
         if (self.partial_message or self.just_unchoked is None
                 or not self.upload.interested
                 or self.download.active_requests):
             self.just_unchoked = 0
         else:
             self.just_unchoked = clock()
Esempio n. 12
0
 def got_piece(self, index, begin, piece):
     length = len(piece)
     try:
         self.active_requests.remove((index, begin, length))
     except ValueError:
         self.downloader.discarded += length
         return False
     if self.downloader.endgamemode:
         self.downloader.all_requests.remove((index, begin, length))
     self.last = clock()
     self.last2 = clock()
     self.measure.update_rate(length)
     self.downloader.measurefunc(length)
     if not self.downloader.storage.piece_came_in(index, begin, piece,
                                                  self.guard):
         self.downloader.piece_flunked(index)
         return False
     if self.downloader.storage.do_I_have(index):
         self.downloader.picker.complete(index)
     if self.downloader.endgamemode:
         for d in self.downloader.downloads:
             if d is not self:
                 if d.interested:
                     if d.choked:
                         assert not d.active_requests
                         d.fix_download_endgame()
                     else:
                         try:
                             d.active_requests.remove(
                                 (index, begin, length))
                         except ValueError:
                             continue
                         d.connection.send_cancel(index, begin, length)
                         d.fix_download_endgame()
                 else:
                     assert not d.active_requests
     self._request_more()
     self.downloader.check_complete(index)
     return self.downloader.storage.do_I_have(index)
Esempio n. 13
0
 def __init__(self, config, schedule, picker, done, swarmSize):
     self.config = config
     self.round_robin_period = config['round_robin_period']
     self.schedule = schedule
     self.picker = picker
     self.connections = []
     self.last_preferred = 0
     self.last_round_robin = clock()
     self.done = done
     self.super_seed = False
     self.paused = False
     self.perCircuit = {}
     self.get_swarm_size = swarmSize
     schedule(self._round_robin, 5)
Esempio n. 14
0
 def got_piece(self, index, begin, piece):
     length = len(piece)
     try:
         self.active_requests.remove((index, begin, length))
     except ValueError:
         self.downloader.discarded += length
         return False
     if self.downloader.endgamemode:
         self.downloader.all_requests.remove((index, begin, length))
     self.last = clock()
     self.last2 = clock()
     self.measure.update_rate(length)
     self.downloader.measurefunc(length)
     if not self.downloader.storage.piece_came_in(index, begin, piece, self.guard):
         self.downloader.piece_flunked(index)
         return False
     if self.downloader.storage.do_I_have(index):
         self.downloader.picker.complete(index)
     if self.downloader.endgamemode:
         for d in self.downloader.downloads:
             if d is not self:
               if d.interested:
                 if d.choked:
                     assert not d.active_requests
                     d.fix_download_endgame()
                 else:
                     try:
                         d.active_requests.remove((index, begin, length))
                     except ValueError:
                         continue
                     d.connection.send_cancel(index, begin, length)
                     d.fix_download_endgame()
               else:
                   assert not d.active_requests
     self._request_more()
     self.downloader.check_complete(index)
     return self.downloader.storage.do_I_have(index)
Esempio n. 15
0
 def queue_limit(self):
     if not self.download_rate:
         return 10e10  # that's a big queue!
     t = clock()
     self.bytes_requested -= (t - self.last_time) * self.download_rate
     self.last_time = t
     if not self.requeueing and self.queued_out and self.bytes_requested < 0:
         self.requeueing = True
         q = self.queued_out.keys()
         shuffle(q)
         self.queued_out = {}
         for d in q:
             d._request_more()
         self.requeueing = False
     if -self.bytes_requested > 5 * self.download_rate:
         self.bytes_requested = -5 * self.download_rate
     return max(int(-self.bytes_requested / self.chunksize), 0)
Esempio n. 16
0
 def queue_limit(self):
     if not self.download_rate:
         return 10e10    # that's a big queue!
     t = clock()
     self.bytes_requested -= (t - self.last_time) * self.download_rate
     self.last_time = t
     if not self.requeueing and self.queued_out and self.bytes_requested < 0:
         self.requeueing = True
         q = self.queued_out.keys()
         shuffle(q)
         self.queued_out = {}
         for d in q:
             d._request_more()
         self.requeueing = False
     if -self.bytes_requested > 5*self.download_rate:
         self.bytes_requested = -5*self.download_rate
     return max(int(-self.bytes_requested/self.chunksize),0)
Esempio n. 17
0
 def got_request(self, i, p, l):
     self.upload.got_request(i, p, l)
     if self.just_unchoked:
         self.connecter.ratelimiter.ping(clock() - self.just_unchoked)
         self.just_unchoked = 0
Esempio n. 18
0
 def add_disconnected_seed(self, id):
     #        if not self.disconnectedseeds.has_key(id):
     #            self.picker.seed_seen_recently()
     self.disconnectedseeds[id] = clock()
Esempio n. 19
0
 def got_unchoke(self):
     if self.choked:
         self.choked = False
         if self.interested:
             self._request_more(new_unchoke = True)
         self.last2 = clock()
Esempio n. 20
0
 def send_interested(self):
     if not self.interested:
         self.interested = True
         self.connection.send_interested()
         if not self.choked:
             self.last2 = clock()
Esempio n. 21
0
 def send_interested(self):
     if not self.interested:
         self.interested = True
         self.connection.send_interested()
         if not self.choked:
             self.last2 = clock()
Esempio n. 22
0
 def got_unchoke(self):
     if self.choked:
         self.choked = False
         if self.interested:
             self._request_more(new_unchoke=True)
         self.last2 = clock()
Esempio n. 23
0
 def got_request(self, i, p, l):
     self.upload.got_request(i, p, l)
     if self.just_unchoked:
         self.connecter.ratelimiter.ping(clock() - self.just_unchoked)
         self.just_unchoked = 0
Esempio n. 24
0
    def add_disconnected_seed(self, id):
#        if not self.disconnectedseeds.has_key(id):
#            self.picker.seed_seen_recently()
        self.disconnectedseeds[id]=clock()