Package: gajim Severity: wishlist Tags: patch Hi there,
please enable IPv6 support in Gajim through the attached patch (taken from the Gajim bug tracker). IPv6 support is a release goal for Etch, so it would be nice to see it included. The patch worked well for me for a few weeks now, with both IPv4 and IPv6 Jabber servers. Thank you for your work! If you need your upload sponsored, just let me know. Kind regards, Philipp Kern
--- gajim-0.10.1.orig/debian/patches/00_ipv6.patch +++ gajim-0.10.1/debian/patches/00_ipv6.patch @@ -0,0 +1,266 @@ +diff -Nru gajim-20060727/src/common/xmpp/transports_nb.py gajim-20060727-ipv6/src/common/xmpp/transports_nb.py +--- gajim-20060727/src/common/xmpp/transports_nb.py 2006-07-26 14:49:11.000000000 +0200 ++++ gajim-20060727-ipv6/src/common/xmpp/transports_nb.py 2006-07-27 22:48:24.000000000 +0200 +@@ -60,6 +60,11 @@ + # -2 - disconnected + self.state = 0 + ++ # server information (IPv6 or IPv4 addresses to try connect to) ++ self._addrinfo = None ++ # socket address information used to connect to server ++ self._serveraddr = None ++ + # queue with messages to be send + self.sendqueue = [] + +@@ -90,9 +95,16 @@ + + def read_timeout(self): + if self.state == 0: +- self.idlequeue.unplug_idle(self.fd) +- if self.on_connect_failure: +- self.on_connect_failure() ++ # connect with this server address failed ++ self.DEBUG("Failed to connect to %s:%d with address [%s]:%d (timeout)"%(self._server[0],self._server[1],self._serveraddr[0],self._serveraddr[1]),'info') ++ self._addrinfo.pop(0) ++ # try another server address if possible, otherwise failure ++ if len(self._addrinfo) > 0: ++ self.connect() ++ else: ++ self.idlequeue.unplug_idle(self.fd) ++ if self.on_connect_failure: ++ self.on_connect_failure() + else: + if self.on_timeout: + self.on_timeout() +@@ -105,14 +117,39 @@ + else: + self._server = server + self.state = 0 +- try: +- self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +- self._sock.setblocking(False) +- except: ++ ++ # get server addresses (either IPv6 or IPv4) if not already done ++ if self._addrinfo is None: ++ self._addrinfo = socket.getaddrinfo(server[0], server[1], socket.AF_UNSPEC, socket.SOCK_STREAM) ++ ++ # try to connect to server with one of its addresses ++ self._sock = None ++ for res in self._addrinfo: ++ af, socktype, proto, canonname, sa = res ++ ++ self.DEBUG("Connect to %s:%d with address [%s]:%d"%(server[0],server[1],sa[0],sa[1]),'info') ++ try: ++ self._sock = socket.socket(af, socktype, proto) ++ self._sock.setblocking(False) ++ except socket.error, msg: ++ self._sock = None ++ self._addrinfo.pop(0) ++ self.DEBUG("Failed to connect to %s:%d with address [%s]:%d (socket() failed)"%(server[0],server[1],sa[0],sa[1]),'info') ++ continue ++ ++ self._serveraddr = sa ++ break ++ ++ # if socket creation failed and no more addresses are available, ++ # failure ++ if self._sock is None: + sys.exc_clear() + if self.on_connect_failure: + self.on_connect_failure() + return False ++ ++ # if socket creation with one server address is successful, ++ # try to connect + self.fd = self._sock.fileno() + self.idlequeue.plug_idle(self, True, False) + self.set_timeout(CONNECT_TIMEOUT_SECONDS) +@@ -285,7 +322,7 @@ + self._sock.setblocking(False) + errnum = 0 + try: +- self._sock.connect(self._server) ++ self._sock.connect(self._serveraddr) + except socket.error, e: + errnum = e[0] + sys.exc_clear() +@@ -295,10 +332,18 @@ + # 10056 - already connected, only on win32 + # code 'WS*' is not available on GNU, so we use its numeric value + elif errnum not in (0, 10056, errno.EISCONN): ++ self.DEBUG("Failed to connect to %s:%d with address [%s]:%d (connect() failed with error %d)"%(self._server[0],self._server[1],self._serveraddr[0],self._serveraddr[1],errnum),'info') + self.remove_timeout() +- if self.on_connect_failure: +- self.on_connect_failure() ++ self._sock.close() ++ self._addrinfo.pop(0) ++ # try another server address if possible, otherwise failure ++ if len(self._addrinfo) > 0: ++ self.connect() ++ else: ++ if self.on_connect_failure: ++ self.on_connect_failure() + return ++ + self.remove_timeout() + self._owner.Connection=self + self.state = 1 +diff -Nru gajim-20060727/src/common/xmpp/transports.py gajim-20060727-ipv6/src/common/xmpp/transports.py +--- gajim-20060727/src/common/xmpp/transports.py 2006-01-20 14:23:38.000000000 +0100 ++++ gajim-20060727-ipv6/src/common/xmpp/transports.py 2006-07-27 22:53:14.000000000 +0200 +@@ -94,15 +94,30 @@ + + def connect(self,server=None): + """ Try to connect. Returns non-empty string on success. """ +- try: +- if not server: server=self._server +- self._sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM) +- self._sock.connect(server) +- self._send=self._sock.sendall +- self._recv=self._sock.recv +- self.DEBUG("Successfully connected to remote host %s"%`server`,'start') +- return 'ok' +- except: pass ++ if not server: server=self._server ++ s = None ++ for res in socket.getaddrinfo(server[0], server[1], socket.AF_UNSPEC, socket.SOCK_STREAM): ++ af, socktype, proto, canonname, sa = res ++ self.DEBUG("Connect to %s:%d with address [%s]:%d"%(server[0],server[1],sa[0],sa[1]),'info') ++ try: ++ s = socket.socket(af, socktype, proto) ++ except socket.error, msg: ++ self.DEBUG("Failed to connect to %s:%d with address [%s]:%d (socket() failed)"%(server[0],server[1],sa[0],sa[1]),'info') ++ s = None ++ continue ++ try: ++ s.connect(sa) ++ except socket.error, msg: ++ self.DEBUG("Failed to connect to %s:%d with address [%s]:%d (connect() failed)"%(server[0],server[1],sa[0],sa[1]),'info') ++ s.close() ++ s = None ++ continue ++ self.DEBUG("Successfully connected to remote host %s:%d with address [%s]:%d"%(server[0],server[1],sa[0],sa[1]),'info') ++ break ++ if s is None: ++ self.DEBUG("Failed to connect to remote host %s:%s"%(server[0],server[1]),'info') ++ pass ++ return 'ok' + + def plugout(self): + """ Disconnect from the remote server and unregister self.disconnected method from +diff -Nru gajim-20060727/THANKS gajim-20060727-ipv6/THANKS +--- gajim-20060727/THANKS 2006-07-04 00:08:50.000000000 +0200 ++++ gajim-20060727-ipv6/THANKS 2006-07-27 22:51:41.000000000 +0200 +@@ -10,6 +10,7 @@ + Christoph Neuroth + David Campey + Dennis Craven ++Didier Barvaux (IPv6 support) + Fabian Neumann + Filippos Papadopoulos + Francisco Alburquerque Parra (Membris Khan) +diff -uNr gajim-0.10.1/src/common/connection_handlers.py gajim-0.10.1-new/src/common/connection_handlers.py +- --- gajim-0.10.1/src/common/connection_handlers.py 2006-06-05 14:03:08.000000000 +0200 ++++ gajim-0.10.1-new/src/common/connection_handlers.py 2006-06-30 05:08:18.000000000 +0200 +@@ -33,6 +33,7 @@ + from common import helpers + from common import gajim + from common import i18n ++from ipv6addr import ipv6addrlist + _ = i18n._ + + STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd', +@@ -187,7 +188,16 @@ + query.setNamespace(common.xmpp.NS_BYTESTREAM) + query.setAttr('mode', 'tcp') + query.setAttr('sid', file_props['sid']) +- - streamhost = query.setTag('streamhost') ++ # IPv6 go first ++ if socket.has_ipv6: ++ for ipv6addr in ipv6addrlist(): ++ streamhost = common.xmpp.Node(tag = 'streamhost') ++ query.addChild(node=streamhost) ++ streamhost.setAttr('port', unicode(port)) ++ streamhost.setAttr('host', ipv6addr) ++ streamhost.setAttr('jid', sender) ++ streamhost = common.xmpp.Node(tag = 'streamhost') ++ query.addChild(node=streamhost) + streamhost.setAttr('port', unicode(port)) + streamhost.setAttr('host', ft_override_host_to_send) + streamhost.setAttr('jid', sender) +diff -uNr gajim-0.10.1/src/common/socks5.py gajim-0.10.1-new/src/common/socks5.py +- --- gajim-0.10.1/src/common/socks5.py 2006-06-05 14:03:08.000000000 +0200 ++++ gajim-0.10.1-new/src/common/socks5.py 2006-06-30 05:14:10.000000000 +0200 +@@ -803,13 +803,21 @@ + self.fd = -1 + + def bind(self): +- - self._serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ++ if socket.has_ipv6: ++ family = socket.AF_INET6 ++ addr_any = '::' ++ else: ++ family = socket.AF_INET ++ addr_any = '0.0.0.0' ++ self._serv = socket.socket(family, socket.SOCK_STREAM) + self._serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self._serv.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) + self._serv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) ++ if socket.has_ipv6: ++ self._serv.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) + # will fail when port as busy, or we don't have rights to bind + try: +- - self._serv.bind(('0.0.0.0', self.port)) ++ self._serv.bind((addr_any, self.port)) + except Exception, e: + # unable to bind, show error dialog + return None +diff -uNr gajim-0.10.1/src/ipv6addr.py gajim-0.10.1-new/src/ipv6addr.py +- --- gajim-0.10.1/src/ipv6addr.py 1970-01-01 01:00:00.000000000 +0100 ++++ gajim-0.10.1-new/src/ipv6addr.py 2006-06-30 05:15:24.000000000 +0200 +@@ -0,0 +1,43 @@ ++import struct,sys ++ ++ADDRFILE = '/proc/net/if_inet6' ++ ++class ipv6addrlist(list): ++ def __init__(self): ++ if sys.platform[:-1] == 'linux' : self.getLinux() ++ elif sys.platform[:-1] == 'freebsd': self.getFreeBSD() ++ elif sys.platform == 'win32': self.getWindows() ++ ++ def getFreeBSD(self): ++ return ++ ++ def getWindows(self): ++ return ++ ++ def getLinux(self): ++ try: ++ f = open(ADDRFILE, 'r') ++ ++ l = f.readline() ++ while l: ++ addr = l.split() ++ ++ # global scope addresses only ++ if addr[3] != '00': ++ l = f.readline() ++ continue ++ ++ # split by four characters ++ addr=struct.unpack('4s4s4s4s4s4s4s4s', addr[0]) ++ self.append(':'.join(addr)) ++ ++ l = f.readline() ++ except IOError, e: ++ self[:] = [] ++ return None ++ ++ ++if __name__ == '__main__': ++ A = ipv6addrlist() ++ for a in A: ++ print a
signature.asc
Description: OpenPGP digital signature