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