r265 - in /debtorrent/trunk/DebTorrent: BT1/Encrypter.py BT1/Rerequester.py SocketHandler.py __init__.py

camrdale-guest at users.alioth.debian.org camrdale-guest at users.alioth.debian.org
Sat Aug 18 00:39:05 UTC 2007


Author: camrdale-guest
Date: Sat Aug 18 00:39:04 2007
New Revision: 265

URL: http://svn.debian.org/wsvn/debtorrent/?sc=1&rev=265
Log:
Only connect to unique peers from the tracker that are not already connected.

Modified:
    debtorrent/trunk/DebTorrent/BT1/Encrypter.py
    debtorrent/trunk/DebTorrent/BT1/Rerequester.py
    debtorrent/trunk/DebTorrent/SocketHandler.py
    debtorrent/trunk/DebTorrent/__init__.py

Modified: debtorrent/trunk/DebTorrent/BT1/Encrypter.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/DebTorrent/BT1/Encrypter.py?rev=265&op=diff
==============================================================================
--- debtorrent/trunk/DebTorrent/BT1/Encrypter.py (original)
+++ debtorrent/trunk/DebTorrent/BT1/Encrypter.py Sat Aug 18 00:39:04 2007
@@ -13,11 +13,6 @@
     outstanding before new connections to initiate get queued
 @type option_pattern: C{string}
 @var option_pattern: the supported options to send to all peers
- at type hexchars: C{string}
- at var hexchars: the hex characters
- at type hexmap: C{list} of C{string}
- at var hexmap: a mapping from the first 256 integers to their 2-byte hex
-    representation
 @type incompletecounter: L{IncompleteCounter}
 @var incompletecounter: the counter to use to track the number of incomplete
     connections outstanding
@@ -27,9 +22,8 @@
 from cStringIO import StringIO
 from binascii import b2a_hex
 from socket import error as socketerror
-from urllib import quote
 from DebTorrent.BTcrypto import Crypto
-from DebTorrent.__init__ import protocol_name
+from DebTorrent.__init__ import protocol_name, make_readable
 import logging
 
 try:
@@ -71,43 +65,6 @@
     
     return chr((i >> 8) & 0xFF) + chr(i & 0xFF)
 
-hexchars = '0123456789ABCDEF'
-hexmap = []
-for i in xrange(256):
-    hexmap.append(hexchars[(i&0xF0)/16]+hexchars[i&0x0F])
-
-def tohex(s):
-    """Convert a string of characters to it's hex representation.
-    
-    @type s: C{string}
-    @param s: the string to convert
-    @rtype: C{string}
-    @return: the resulting hex string
-    
-    """
-    
-    r = []
-    for c in s:
-        r.append(hexmap[ord(c)])
-    return ''.join(r)
-
-def make_readable(s):
-    """Convert a string to be human-readable.
-    
-    @type s: C{string}
-    @param s: the string to convert
-    @rtype: C{string}
-    @return: the resulting hex string, or the original string if it was already
-        readable
-    
-    """
-    
-    if not s:
-        return ''
-    if quote(s).find('%') >= 0:
-        return tohex(s)
-    return '"'+s+'"'
-   
 
 class IncompleteCounter:
     """Keep track of the number of oustanding incomplete connections.
@@ -154,6 +111,8 @@
     @ivar connection: the low-level connection to the peer
     @type connecter: L{Connecter.Connecter}
     @ivar connecter: the Connecter instance to use
+    @type dns: (C{string}, C{int})
+    @ivar dns: the IP address and port to connect to
     @type id: C{string}
     @ivar id: the peer ID of the peer
     @type locally_initiated: C{boolean}
@@ -211,7 +170,7 @@
 
     """
     
-    def __init__(self, Encoder, connection, id,
+    def __init__(self, Encoder, connection, dns, id,
                  ext_handshake=False, encrypted = None, options = None):
         """Initialize the instance and start handling the connection.
         
@@ -219,14 +178,17 @@
         @param Encoder: the collection of all connections
         @type connection: L{DebTorrent.SocketHandler.SingleSocket}
         @param connection: the low-level connection to the peer
+        @type dns: (C{string}, C{int})
+        @param dns: the IP address and port to connect to
         @type id: C{string}
         @param id: the peer ID of the peer to connect to (will be None if 
             the connection is being initiated locally)
         @type ext_handshake: C{boolean}
         @param ext_handshake: whether the connection has already been
             handshaked by another module (optional, defaults to False)
-        @type encrypted: C{DebTorrent.BT1Crypto.Crypto}
-        @param encrypted: the already created Crypto instance, if the connection
+        @type encrypted: C{int} or C{DebTorrent.BT1Crypto.Crypto}
+        @param encrypted: the type of encryption the connection supports
+            (0 for none), or the already created Crypto instance, if the connection
             was externally handshaked (optional, defaults to creating a new one)
         @type options: C{string}
         @param options: the options read from the externally handshaked
@@ -237,6 +199,7 @@
         self.Encoder = Encoder
         self.connection = connection
         self.connecter = Encoder.connecter
+        self.dns = dns
         self.id = id
         self.locally_initiated = (id != None)
         self.readable_id = make_readable(id)
@@ -1199,7 +1162,7 @@
             logger.info('Not connecting due to too many connections: '+str(len(self.connections))+' >= '+str(self.max_connections))
             return True
         if id == self.my_id:
-            logger.info('Not connecting due to it being my ID: '+id)
+            logger.info('Not connecting due to it being my ID: '+dns[0])
             return True
         if not self.check_ip(ip=dns[0]):
             logger.info('Not connecting due to the IP being banned: '+dns[0])
@@ -1220,10 +1183,12 @@
             if self.config['security'] and ip != 'unknown' and ip == dns[0]:
                 logger.info('Not connecting due to a matching IP: '+ip)
                 return True
+            if dns == v.dns:
+                logger.info('Not connecting due to already being connected: %r', dns)
         try:
             logger.debug('initiating connection to: '+str(dns)+', '+str(id)+', '+str(encrypted))
             c = self.raw_server.start_connection(dns)
-            con = Connection(self, c, id, encrypted = encrypted)
+            con = Connection(self, c, dns, id, encrypted = encrypted)
             self.connections[c] = con
             c.set_handler(con)
         except socketerror:
@@ -1320,7 +1285,9 @@
                             str(len(self.connections))+' >= '+str(self.max_connections))
             connection.close()
             return False
-        con = Connection(self, connection, None)
+        dns = connection.getpeername()
+        logger.info("Reveived a connection from: %r", dns)
+        con = Connection(self, connection, dns, None)
         self.connections[connection] = con
         connection.set_handler(con)
         return True
@@ -1357,7 +1324,9 @@
             logger.info('Not allowing external connection due to the IP being banned: '+dns[0])
             connection.close()
             return False
-        con = Connection(self, connection, None,
+        dns = connection.getpeername()
+        logger.info("Received an externally handled connection from: %r", dns)
+        con = Connection(self, connection, dns, None,
                 ext_handshake = True, encrypted = encrypted, options = options)
         self.connections[connection] = con
         connection.set_handler(con)

Modified: debtorrent/trunk/DebTorrent/BT1/Rerequester.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/DebTorrent/BT1/Rerequester.py?rev=265&op=diff
==============================================================================
--- debtorrent/trunk/DebTorrent/BT1/Rerequester.py (original)
+++ debtorrent/trunk/DebTorrent/BT1/Rerequester.py Sat Aug 18 00:39:04 2007
@@ -656,7 +656,7 @@
         self.last = r.get('last')
 #        ps = len(r['peers']) + self.howmany()
         p = r['peers']
-        peers = []
+        new_peers = {}
         if type(p) == type(''):
             lenpeers = len(p)/6
         else:
@@ -672,12 +672,17 @@
             for x in xrange(0, len(p), 6):
                 ip = '.'.join([str(ord(i)) for i in p[x:x+4]])
                 port = (ord(p[x+4]) << 8) | ord(p[x+5])
-                peers.append(((ip, port), 0, cflags[int(x/6)]))
+                new_peers[(ip, port)] = (0, cflags[int(x/6)])
         else:
             for i in xrange(len(p)):
                 x = p[i]
-                peers.append(((x['ip'].strip(), x['port']),
-                              x.get('peer id',0), cflags[i]))
+                new_peers[(x['ip'].strip(), x['port'])] = (x.get('peer id',0),
+                                                           cflags[i])
+        
+        # Now build the list of peers that are unique in the list
+        peers = []
+        for dns, (id, crypto) in new_peers.items():
+            peers.append((dns, id, crypto))
         logger.info('received from tracker: '+str(peers))
         ps = len(peers) + self.howmany()
         if ps < self.maxpeers:

Modified: debtorrent/trunk/DebTorrent/SocketHandler.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/DebTorrent/SocketHandler.py?rev=265&op=diff
==============================================================================
--- debtorrent/trunk/DebTorrent/SocketHandler.py (original)
+++ debtorrent/trunk/DebTorrent/SocketHandler.py Sat Aug 18 00:39:04 2007
@@ -56,12 +56,12 @@
     @ivar connected: whether this socket has received an event yet
     @type skipped: C{int}
     @ivar skipped: the number of consecutive writes to the socket that have failed
-    @type ip: C{string}
-    @ivar ip: the IP address to use if one can't be obtained from the socket
+    @type dns: (C{string}, C{int})
+    @ivar dns: the IP address and port to use if one can't be obtained from the socket
     
     """
     
-    def __init__(self, socket_handler, sock, handler, ip = None):
+    def __init__(self, socket_handler, sock, handler, dns = None):
         """
         
         @type socket_handler: L{SocketHandler}
@@ -86,13 +86,13 @@
         self.skipped = 0
 #        self.check = StreamCheck()
         try:
-            self.ip = self.socket.getpeername()[0]
+            self.dns = self.socket.getpeername()
         except:
-            if ip is None:
-                self.ip = 'unknown'
+            if dns is None:
+                self.dns = ('unknown', 0)
             else:
-                self.ip = ip
-        logger.debug('new socket: ' + self.ip)
+                self.dns = dns
+        logger.debug('new socket: %r', self.dns)
         
     def get_ip(self, real=False):
         """Get the IP address of the socket.
@@ -108,15 +108,34 @@
         
         if real:
             try:
-                self.ip = self.socket.getpeername()[0]
+                self.dns = self.socket.getpeername()
             except:
                 pass
-        return self.ip
+        return self.dns[0]
+        
+    def getpeername(self, real=False):
+        """Get the IP address and port of the socket.
+        
+        @type real: C{boolean}
+        @param real: whether to try and get the IP address directly from the 
+            socket or trust the one supplied when the instance was created 
+            (optional, defaults to False)
+        @rtype: (C{string}, C{int})
+        @return: the IP address and port of the remote connection
+        
+        """
+        
+        if real:
+            try:
+                self.dns = self.socket.getpeername()
+            except:
+                pass
+        return self.dns
         
     def close(self):
         """Close the socket."""
         assert self.socket
-        logger.debug('close socket')
+        logger.debug('close socket: %r', self.dns)
         self.connected = False
         sock = self.socket
         self.socket = None
@@ -134,7 +153,7 @@
         
         """
         
-        logger.debug('socket shutdown:'+str(val))
+        logger.debug('socket %r shutdown:'+str(val), self.dns)
         self.socket.shutdown(val)
 
     def is_flushed(self):
@@ -195,7 +214,7 @@
             if self.skipped >= 3:
                 dead = True
             if dead:
-                logger.debug('Socket is dead from write: '+self.ip)
+                logger.debug('Socket is dead from write: %r', self.dns)
                 self.socket_handler.dead_from_write.append(self)
                 return
         if self.buffer:
@@ -449,7 +468,7 @@
         except Exception, e:
             raise socket.error(str(e))
         self.poll.register(sock, POLLIN)
-        s = SingleSocket(self, sock, handler, dns[0])
+        s = SingleSocket(self, sock, handler, dns)
         self.single_sockets[sock.fileno()] = s
         return s
 

Modified: debtorrent/trunk/DebTorrent/__init__.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/trunk/DebTorrent/__init__.py?rev=265&op=diff
==============================================================================
--- debtorrent/trunk/DebTorrent/__init__.py (original)
+++ debtorrent/trunk/DebTorrent/__init__.py Sat Aug 18 00:39:04 2007
@@ -31,6 +31,7 @@
 from sha import sha
 from time import time, clock
 from binascii import b2a_hex
+from urllib import quote
 import logging
 try:
     from os import getpid
@@ -88,6 +89,23 @@
         
 resetPeerIDs()
 
+def make_readable(s):
+    """Convert a string peer ID to be human-readable.
+    
+    @type s: C{string}
+    @param s: the string to convert
+    @rtype: C{string}
+    @return: the resulting hex string, or the original string if it was already
+        readable
+    
+    """
+    
+    if not s:
+        return ''
+    if quote(s).find('%') >= 0:
+        return b2a_hex(s)
+    return '"'+s+'"'
+
 def createPeerID(ins = '---'):
     """Generate a somewhat random peer ID
     
@@ -102,5 +120,5 @@
     
     assert type(ins) is StringType
     assert len(ins) == 3
-    logger.info('New peer ID: '+b2a_hex(_idprefix + ins + _idrandom[0]))
+    logger.info('New peer ID: '+make_readable(_idprefix + ins + _idrandom[0]))
     return _idprefix + ins + _idrandom[0]




More information about the Debtorrent-commits mailing list