Package: bittornado
Version: 0.3.18-8dfd~002
Severity: minor
Tags: patch

BitTornado connects to peers using any outgoing port and not using an existing 
connection which means many connections get blocked when using a restrictive 
firewall (many syslog messages).  The attached patches are the patch to add to 
the quilt series that adds the functionality and the man page patch to document 
the new parameters.

The new patch allows you to specify range of ports which BitTornado will use to 
make outgoing connections.  This allows one to specify the port range to bt and 
the firewall so that there aren't blocked connection for traffic we want.

-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-1-686 (SMP w/1 CPU core)
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages bittornado depends on:
ii  python                        2.5.2-2    An interactive high-level object-o
ii  python-support                0.8.4      automated rebuilding support for P

Versions of packages bittornado recommends:
ii  mime-support             3.44-1          MIME files 'mime.types' & 'mailcap
ii  python-crypto            2.0.1+dfsg1-2.3 cryptographic algorithms and proto

Versions of packages bittornado suggests:
pn  bittornado-gui                <none>     (no description available)
pn  python-psyco                  <none>     (no description available)

-- no debconf information
Index: bittornado-0.3.18/BitTornado/RawServer.py
===================================================================
--- bittornado-0.3.18.orig/BitTornado/RawServer.py	2008-09-20 20:45:29.000000000 -0400
+++ bittornado-0.3.18/BitTornado/RawServer.py	2008-09-20 20:45:30.000000000 -0400
@@ -43,11 +43,13 @@
 READSIZE = 32768
 
 class RawServer:
-    def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True,
+    def __init__(self, doneflag, timeout_check_interval, timeout, config,
+                 noisy = True,
                  ipv6_enable = True, failfunc = lambda x: None, errorfunc = None,
                  sockethandler = None, excflag = Event()):
         self.timeout_check_interval = timeout_check_interval
         self.timeout = timeout
+        self.config = config
         self.servers = {}
         self.single_sockets = {}
         self.dead_from_write = []
@@ -63,7 +65,8 @@
         self.excflag = excflag
         
         if sockethandler is None:
-            sockethandler = SocketHandler(timeout, ipv6_enable, READSIZE)
+            sockethandler = SocketHandler(timeout, ipv6_enable, config,
+                                          READSIZE)
         self.sockethandler = sockethandler
         self.add_task(self.scan_for_timeouts, timeout_check_interval)
 
Index: bittornado-0.3.18/BitTornado/SocketHandler.py
===================================================================
--- bittornado-0.3.18.orig/BitTornado/SocketHandler.py	2008-09-20 20:45:30.000000000 -0400
+++ bittornado-0.3.18/BitTornado/SocketHandler.py	2008-09-20 20:49:18.000000000 -0400
@@ -121,8 +121,9 @@
         self.handler = handler
 
 class SocketHandler:
-    def __init__(self, timeout, ipv6_enable, readsize = 100000):
+    def __init__(self, timeout, ipv6_enable, config, readsize = 100000):
         self.timeout = timeout
+        self.config = config
         self.ipv6_enable = ipv6_enable
         self.readsize = readsize
         self.poll = poll()
@@ -231,11 +232,69 @@
     def set_handler(self, handler):
         self.handler = handler
 
+    def bind_send(self, port, bind = '', reuse = False, ipv6_socket_style = 1, upnp = 0):
+        port = int(port)
+        addrinfos = []
+        interfaces = []
+        # if bind != "" thread it as a comma seperated list and bind to all
+        # addresses (can be ips or hostnames) else bind to default ipv6 and
+        # ipv4 address
+        if bind:
+            if self.ipv6_enable:
+                socktype = socket.AF_UNSPEC
+            else:
+                socktype = socket.AF_INET
+
+            if sys.version_info < (2,2):
+                addrinfo = (socket.AF_INET, None, None, None, (addr, port))
+            else:
+                addrinfo = (socket.getaddrinfo(addr, port,
+                                               socktype, socket.SOCK_STREAM))
+        else:
+            if self.ipv6_enable:
+                addrinfo  =  ([socket.AF_INET6, None, None, None, ('', port)])
+            if not addrinfo or ipv6_socket_style != 0:
+                addrinfo = ([socket.AF_INET, None, None, None, ('', port)])
+        try:
+            socket = socket.socket(addrinfo[0], socket.SOCK_STREAM)
+            if reuse:
+                server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            socket.setblocking(0)
+            socket.bind(addrinfo[4])
+        except socket.error, e:
+            socket.close()
+            if self.ipv6_enable and ipv6_socket_style == 0 and servers:
+                raise socket.error('blocked port (may require ipv6_binds_v4 to be set)')
+            raise socket.error(str(e))
+        if not socket:
+            raise socket.error('unable to open send port')
+        return socket
+
+    def find_and_bind_send(self, minport, maxport, bind = '', reuse = False,
+                      ipv6_socket_style = 1, randomizer = False):
+        send_port = -1
+        e = 'maxport less than minport - no ports to check'
+        portrange = range(minport, maxport+1)
+        if randomizer:
+            shuffle(portrange)
+
+        for send_port in portrange:
+            try:
+                send_socket = self.bind_send(send_port, bind,
+                          ipv6_socket_style = ipv6_socket_style)
+                return send_socket
+            except socket.error, e:
+                pass
+        raise socket.error(str(e))
 
     def start_connection_raw(self, dns, socktype = socket.AF_INET, handler = None):
+        minsrcport = self.config['minsrcport']
+        maxsrcport = self.config['maxsrcport']
+
         if handler is None:
             handler = self.handler
-        sock = socket.socket(socktype, socket.SOCK_STREAM)
+
+        sock = self.find_and_bind_send(minsrcport, maxsrcport, ipv6_socket_style = config['ipv6_binds_v4'], randomizer = config['random_port'])
         sock.setblocking(0)
         try:
             sock.connect_ex(dns)
@@ -248,7 +307,6 @@
         self.single_sockets[sock.fileno()] = s
         return s
 
-
     def start_connection(self, dns, handler = None, randomize = False):
         if handler is None:
             handler = self.handler
Index: bittornado-0.3.18/BitTornado/download_bt1.py
===================================================================
--- bittornado-0.3.18.orig/BitTornado/download_bt1.py	2008-09-20 20:45:30.000000000 -0400
+++ bittornado-0.3.18/BitTornado/download_bt1.py	2008-09-20 20:45:30.000000000 -0400
@@ -57,6 +57,8 @@
         "ip to report you have to the tracker."),
     ('minport', 10000, 'minimum port to listen on, counts up if unavailable'),
     ('maxport', 60000, 'maximum port to listen on'),
+    ('minsrcport', 10000, 'minimum port to send on, counts up if unavailable'),
+    ('maxsrcport', 60000, 'maximum port to send on'),
     ('random_port', 1, 'whether to choose randomly inside the port range ' +
         'instead of counting up linearly'),
     ('responsefile', '',
@@ -188,7 +190,7 @@
     seed(myid)
 
     rawserver = RawServer(doneflag, config['timeout_check_interval'],
-                          config['timeout'], ipv6_enable = config['ipv6_enabled'],
+                          config['timeout'], config, ipv6_enable = config['ipv6_enabled'],
                           failfunc = failed, errorfunc = exchandler)
 
     upnp_type = 0
Index: bittornado-0.3.18/BitTornado/launchmanycore.py
===================================================================
--- bittornado-0.3.18.orig/BitTornado/launchmanycore.py	2008-09-20 20:45:30.000000000 -0400
+++ bittornado-0.3.18/BitTornado/launchmanycore.py	2008-09-20 20:45:30.000000000 -0400
@@ -167,7 +167,7 @@
             self.hashcheck_current = None
             
             self.rawserver = RawServer(self.doneflag, config['timeout_check_interval'],
-                              config['timeout'], ipv6_enable = config['ipv6_enabled'],
+                              config['timeout'], config, ipv6_enable = config['ipv6_enabled'],
                               failfunc = self.failed, errorfunc = self.exchandler)
             upnp_type = 0
             while True:
Index: bittornado-0.3.18/BitTornado/BT1/track.py
===================================================================
--- bittornado-0.3.18.orig/BitTornado/BT1/track.py	2008-09-20 20:45:30.000000000 -0400
+++ bittornado-0.3.18/BitTornado/BT1/track.py	2008-09-20 20:45:30.000000000 -0400
@@ -1120,7 +1120,8 @@
         print 'run with no arguments for parameter explanations'
         return
     r = RawServer(Event(), config['timeout_check_interval'],
-                  config['socket_timeout'], ipv6_enable = config['ipv6_enabled'])
+                  config['socket_timeout'], config,
+                  ipv6_enable = config['ipv6_enabled'])
     t = Tracker(config, r)
     r.bind(config['port'], config['bind'],
            reuse = True, ipv6_socket_style = config['ipv6_binds_v4'])
--- ../bittornado_0.3.18-7/debian/bittorrent-downloader.bittornado.sgml 
2008-09-20 07:35:03.000000000 -0400
+++ ../bittornado-0.3.18/debian/bittorrent-downloader.bittornado.sgml   
2008-09-20 21:03:36.000000000 -0400
@@ -154,6 +154,18 @@
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><option>--minsrcport 
<replaceable>port</replaceable></option></term>
+        <listitem>
+          <para>the minimum <replaceable>port</replaceable> to send on 
(defaults to 10000)</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--maxsrcport 
<replaceable>port</replaceable></option></term>
+        <listitem>
+          <para>the maximum <replaceable>port</replaceable> to send on 
(defaults to 60000)</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><option>--responsefile 
<replaceable>file</replaceable></option></term>
         <listitem>
           <para>the <replaceable>file</replaceable> the server response was 
stored in, as an alternative to --url. If this option is used,

Reply via email to