Index: src/common/xmpp/transports_nb.py
===================================================================
--- src/common/xmpp/transports_nb.py	(revisión: 8118)
+++ src/common/xmpp/transports_nb.py	(copia de trabajo)
@@ -251,7 +251,8 @@
 		self.printed_error = False
 		
 		#  0 - not connected
-		#  1 - connected
+		#  1 - connecting
+		#  2 - connected
 		# -1 - about to disconnect (when we wait for final events to complete)
 		# -2 - disconnected
 		self.state = 0
@@ -279,6 +280,7 @@
 			Called internally. '''
 		self.idlequeue = owner.idlequeue
 		self.printed_error = False
+		print self._owner.Server, owner, self._server
 		if not self._server: 
 			self._server=(self._owner.Server,5222)
 		if self.connect(self._server) is False:
@@ -305,19 +307,13 @@
 		self.state = 0
 		success = False
 		try:
-			for ai in socket.getaddrinfo(server[0],server[1],socket.AF_UNSPEC,socket.SOCK_STREAM):
-				try:
-					self._sock=socket.socket(*ai[:3])
-					self._sock.setblocking(False)
-					self._server=ai[4]
-					success = True
-					break
-				except:
-					if sys.exc_value[0] == errno.EINPROGRESS:
-						success = True
-						break
-					#for all errors, we try other addresses
-					continue
+			self.set_timeout(CONNECT_TIMEOUT_SECONDS)
+			if len(server) == 2 and type(server[0]) in (str, unicode):
+				self.ais = socket.getaddrinfo(server[0],server[1],socket.AF_UNSPEC,socket.SOCK_STREAM)
+				print "self.ais=", self.ais 
+			else:
+				self.ais = server
+			return self._do_connect()
 		except socket.gaierror, e:
 			log.info("Lookup failure for %s: %s[%s]", self.getName(), e[1], repr(e[0]), exc_info=True)
 		except:
@@ -326,13 +322,7 @@
 		if not success:
 			if self.on_connect_failure:
 				self.on_connect_failure()
-			return False
-
-		self.fd = self._sock.fileno()
-		self.idlequeue.plug_idle(self, True, False)
-		self.set_timeout(CONNECT_TIMEOUT_SECONDS)
-		self._do_connect()
-		return True
+		return success
 	
 	def _plug_idle(self):
 		readable = self.state != 0
@@ -532,46 +522,62 @@
 
 	def _do_connect(self):
 		if self.state != 0:
+			print "do_connect while connected"
 			return
-		self._sock.setblocking(False)
-		self._send = self._sock.send
-		self._recv = self._sock.recv
-		errnum = 0
-		try:
-			self._sock.connect(self._server)
-		except socket.error, e:
-			errnum = e[0]
+		for ai in self.ais:
+			success = False
+			try:
+				self._sock=socket.socket(*ai[:3])
+				self._sock.setblocking(False)
+				self._server=ai[4]
+				self.fd = self._sock.fileno()
+				self.idlequeue.plug_idle(self, True, False)
+				self._send = self._sock.send
+				self._recv = self._sock.recv
+				errnum = 0
 
-			# Ignore "Socket already connected". 
-			# FIXME: This happens when we switch an already
-			# connected socket to SSL (STARTTLS). Instead of
-			# ignoring the error, the socket should only be
-			# connected to once. See #2846.
-			workaround = (errno.EALREADY, 10056)
+				self._sock.connect(self._server)
+				print "connected"
+				success = True
+				self.state = 1
+				break
+			except socket.error, e:
+				print "exception1",sys.exc_value
+				errnum = e[0]
 
-			# 10035 - winsock equivalent of EINPROGRESS
-			if errnum not in (errno.EINPROGRESS, 10035) + workaround:
-				log.error("_do_connect:", exc_info=True)
-				#traceback.print_exc()
-		# in progress, or would block
-		if errnum in (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK): 
-			return
-		# 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.remove_timeout()
+				# Ignore "Socket already connected". 
+				# FIXME: This happens when we switch an already
+				# connected socket to SSL (STARTTLS). Instead of
+				# ignoring the error, the socket should only be
+				# connected to once. See #2846.
+				workaround = (errno.EALREADY, 10056)
+
+				# 10035 - winsock equivalent of EINPROGRESS
+				if errnum not in (errno.EINPROGRESS, 10035) + workaround:
+					log.error("_do_connect:", exc_info=True)
+					#traceback.print_exc()
+				# in progress, or would block
+				if errnum in (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK):
+					success = True
+					self.state = 1
+					break
+				# 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): 
+					continue
+
+		self.remove_timeout()
+		if not success:
 			if self.on_connect_failure:
 				self.on_connect_failure()
 			return
-		self.remove_timeout()
 		self._owner.Connection=self
 		self.state = 1
-		
 		self._sock.setblocking(False)
 		self._plug_idle()
 		if self.on_connect:
 			self.on_connect()
-			self.on_connect = None
+		self.on_connect = None
 		return True
 
 	def send(self, raw_data, now = False):
Index: src/common/xmpp/protocol.py
===================================================================
--- src/common/xmpp/protocol.py	(revisión: 8118)
+++ src/common/xmpp/protocol.py	(copia de trabajo)
@@ -27,6 +27,7 @@
 NS_AMP          ='http://jabber.org/protocol/amp'
 NS_AMP_ERRORS   =NS_AMP+'#errors'
 NS_AUTH         ='jabber:iq:auth'
+NS_AVATAR       ='jabber:iq:avatar'
 NS_BIND         ='urn:ietf:params:xml:ns:xmpp-bind'
 NS_BROWSE       ='jabber:iq:browse'
 NS_BYTESTREAM   ='http://jabber.org/protocol/bytestreams'               # JEP-0065
@@ -48,6 +49,7 @@
 NS_EVENT        ='jabber:x:event'                                       # JEP-0022
 NS_FEATURE      ='http://jabber.org/protocol/feature-neg'  
 NS_FILE         ='http://jabber.org/protocol/si/profile/file-transfer'  # JEP-0096
+NS_GATEWAY      ='jabber:iq:gateway'
 NS_GEOLOC       ='http://jabber.org/protocol/geoloc'                    # JEP-0080
 NS_GROUPCHAT    ='gc-1.0'
 NS_HTTP_AUTH    ='http://jabber.org/protocol/http-auth'         # JEP-0070
@@ -592,7 +594,7 @@
     """ This class is used in the DataForm class to describe the single data item.
         If you are working with jabber:x:data (JEP-0004, JEP-0068, JEP-0122) 
         then you will need to work with instances of this class. """
-    def __init__(self,name=None,value=None,typ=None,required=0,desc=None,options=[],node=None):
+    def __init__(self,name=None,value=None,typ=None,required=0,desc=None,label=None,options=[],node=None):
         """ Create new data field of specified name,value and type.
             Also 'required','desc' and 'options' fields can be set.
             Alternatively other XML object can be passed in as the 'node' parameted to replicate it as a new datafiled.
@@ -604,6 +606,7 @@
         if typ: self.setType(typ)
         elif not typ and not node: self.setType('text-single')
         if required: self.setRequired(required)
+        if label: self.setLabel(label)
         if desc: self.setDesc(desc)
         if options: self.setOptions(options)
     def setRequired(self,req=1):
@@ -615,6 +618,10 @@
     def isRequired(self):
         """ Returns in this field a required one. """
         return self.getTag('required')
+    def setLabel(self, label):
+        self.setAttr('label',label)
+    def getLabel(self):
+        self.getAttr('label')
     def setDesc(self,desc):
         """ Set the description of this field. """
         self.setTagData('desc',desc)
Index: src/common/xmpp/browser.py
===================================================================
--- src/common/xmpp/browser.py	(revisión: 8118)
+++ src/common/xmpp/browser.py	(copia de trabajo)
@@ -189,7 +189,7 @@
             self.DEBUG("No Handler for request with jid->%s node->%s ns->%s"%(request.getTo(),request.getQuerynode(),request.getQueryNS()),'error')
             conn.send(Error(request,ERR_ITEM_NOT_FOUND))
             raise NodeProcessed
-        self.DEBUG("Handling request with jid->%s node->%s ns->%s"%(request.getTo(),request.getQuerynode(),request.getQueryNS()),'ok')
+        self.DEBUG((u"Handling request with jid->%s node->%s ns->%s"%(request.getTo(),request.getQuerynode(),request.getQueryNS())).encode('utf-8'),'ok')
         rep=request.buildReply('result')
         if request.getQuerynode(): rep.setQuerynode(request.getQuerynode())
         q=rep.getTag('query')
Index: src/common/zeroconf/zeroconf.py
===================================================================
--- src/common/zeroconf/zeroconf.py	(revisión: 8118)
+++ src/common/zeroconf/zeroconf.py	(copia de trabajo)
@@ -185,9 +185,9 @@
 			self.create_service()
 		elif state == self.avahi.SERVER_COLLISION:
 			self.entrygroup.Reset()
-		elif state == self.avahi.CLIENT_FAILURE:
+		elif state == self.avahi.SERVER_FAILURE:
 			# does it ever go here?
-			gajim.log.debug('CLIENT FAILURE')
+			gajim.log.debug('SERVER FAILURE')
 
 	def entrygroup_state_changed_callback(self, state, error):
 		# the name is already present, so recreate
Index: src/common/socks5.py
===================================================================
--- src/common/socks5.py	(revisión: 8118)
+++ src/common/socks5.py	(copia de trabajo)
@@ -348,9 +348,10 @@
 	def __init__(self, idlequeue, host, port, initiator, target, sid):
 		if host is not None:
 			try:
-				self.host = socket.gethostbyname(host)
+				self.host = host
+				self.ais = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
 			except socket.gaierror:
-				self.host = None
+				self.ais = None
 		self.idlequeue = idlequeue
 		self.fd = -1
 		self.port = port
@@ -793,6 +794,8 @@
 		only pollin events though
 		'''
 		self.port = port
+		self.ais = socket.getaddrinfo(None, port, socket.AF_UNSPEC,
+					socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE)
 		self.queue_idx = -1	
 		self.idlequeue = idlequeue
 		self.queue = None
@@ -801,14 +804,21 @@
 		self.fd = -1
 		
 	def bind(self):
-		self._serv = socket.socket(socket.AF_INET, 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)
-		# will fail when port as busy, or we don't have rights to bind
-		try:
-			self._serv.bind(('0.0.0.0', self.port))
-		except Exception, e:
+		for ai in self.ais:
+			#try the different possibilities (ipv6, ipv4, etc.)
+			self._serv = socket.socket(*ai[:3])
+			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)
+			# will fail when port as busy, or we don't have rights to bind
+			try:
+				self._serv.bind(ai[4])
+				self.ai = ai
+				break
+			except:
+				self.ai = None
+				continue
+		if not self.ai:
 			# unable to bind, show error dialog
 			return None
 		self._serv.listen(socket.SOMAXCONN)
@@ -884,9 +894,18 @@
 	
 	def connect(self):
 		''' create the socket and plug it to the idlequeue '''
-		self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-		# this will not block the GUI
-		self._sock.setblocking(False)
+		for ai in self.ais:
+			try:
+				self._sock=socket.socket(*ai[:3])
+				# this will not block the GUI
+				self._sock.setblocking(False)
+				self._server=ai[4]
+				break
+			except:
+				if sys.exc_value[0] == errno.EINPROGRESS:
+					break
+				#for all errors, we try other addresses
+				continue
 		self.fd = self._sock.fileno()
 		self.state = 0 # about to be connected
 		self.idlequeue.plug_idle(self, True, False)
@@ -950,7 +969,7 @@
 	
 	def do_connect(self):
 		try:
-			self._sock.connect((self.host, self.port))
+			self._sock.connect(self._server)
 			self._sock.setblocking(False)
 			self._send=self._sock.send
 			self._recv=self._sock.recv
Index: src/common/contacts.py
===================================================================
--- src/common/contacts.py	(revisión: 8118)
+++ src/common/contacts.py	(copia de trabajo)
@@ -57,6 +57,32 @@
 	def get_shown_name(self):
 		if self.name:
 			return self.name
+		# see xep 0154
+		if hasattr(self, 'vcard'):
+			## nickname
+			if self.vcard.has_key('NICKNAME'):
+				return self.vcard['NICKNAME']
+			## display name
+			if self.vcard.has_key('FN'):
+				return self.vcard['FN']
+			# given "middle" family
+			name = ''
+			space_required = False
+			if self.vcard.has_key('N_GIVEN'):
+				name += self.vcard['N_GIVEN']
+				space_required = True
+			if self.vcard.has_key('N_MIDDLE'):
+				if space_required:
+					name += ' '
+				name += '"' + self.vcard['N_MIDDLE'] + '"'
+				space_required = True
+			if self.vcard.has_key('N_FAMILY'):
+				if space_required:
+					name += ' '
+				name += self.vcard['N_FAMILY']
+			if name:
+				return name
+		# username from the jid
 		return self.jid.split('@')[0]
 
 	def is_hidden_from_roster(self):
Index: src/common/connection.py
===================================================================
--- src/common/connection.py	(revisión: 8118)
+++ src/common/connection.py	(copia de trabajo)
@@ -357,21 +357,23 @@
 		# SRV resolver
 		self._proxy = proxy
 		self._secure = secur
-		self._hosts = [ {'host': h, 'port': p, 'prio': 10, 'weight': 10} ]
 		self._hostname = hostname
+		def _on_resolve(host, result_array):
+			# SRV query returned at least one valid result, we put it in hosts dict
+			if len(result_array) != 0:
+				self._hosts = [i for i in result_array]
+			else:
+				# TODO: BLOCKS protect exceptions in getaddrinfo
+				self._hosts = [ {'host': h, 'port': p, 'prio': 10, 'weight': 10, 'ais': socket.getaddrinfo(h,p,socket.AF_UNSPEC,socket.SOCK_STREAM)} ]
+			self.connect_to_next_host()
 		if use_srv:
 			# add request for srv query to the resolve, on result '_on_resolve'
 			# will be called
 			gajim.resolver.resolve('_xmpp-client._tcp.' + helpers.idn_to_ascii(h),
-				self._on_resolve)
+				_on_resolve)
 		else:
-			self._on_resolve('', [])
+			_on_resolve('', [])
 
-	def _on_resolve(self, host, result_array):
-		# SRV query returned at least one valid result, we put it in hosts dict
-		if len(result_array) != 0:
-			self._hosts = [i for i in result_array]
-		self.connect_to_next_host()
 
 	def on_proxy_failure(self, reason):
 		log.debug('Connection to proxy failed')
@@ -388,6 +390,7 @@
 				self.last_connection.socket.disconnect()
 				self.last_connection = None
 				self.connection = None
+			debug = []
 			if gajim.verbose:
 				con = common.xmpp.NonBlockingClient(self._hostname, caller = self,
 					on_connect = self.on_connect_success,
@@ -411,8 +414,12 @@
 				con.RegisterDisconnectHandler(self._on_new_account)
 
 			log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port'])
-			con.connect((host['host'], host['port']), proxy = self._proxy,
-				secure = self._secure)
+			if 'ai' in host:
+				con.connect(host['ai'][4][0:2], proxy = self._proxy,
+					secure = self._secure)
+			else:
+				con.connect((host['host'],host['port']), proxy = self._proxy,
+					secure = self._secure)
 		else:
 			if not retry and self.retrycount == 0:
 				log.debug("Out of hosts, giving up connecting to %s", self.name)
Index: src/common/nslookup.py
===================================================================
--- src/common/nslookup.py	(revisión: 8118)
+++ src/common/nslookup.py	(copia de trabajo)
@@ -15,6 +15,7 @@
 import sys
 import os
 import re
+import socket
 
 from xmpp.idlequeue import *
 
@@ -124,8 +125,10 @@
 					port = int(port)
 				except ValueError:
 					continue
-				hosts.append({'host': host, 'port': port,'weight': weight,
-						'prio': prio})
+				#TODO: wrap in try:except socket.aierror
+				for ai in socket.getaddrinfo(host,port,socket.AF_UNSPEC,socket.SOCK_STREAM):
+					hosts.append({'host': host, 'port': port,'weight': weight,
+						'prio': prio, 'ai':ai})
 		return hosts
 	
 	def _on_ready(self, host, result):
@@ -285,6 +288,15 @@
 		if self.result_handler:
 			self.result_handler(self.host, self.result)
 		self.result_handler = None
+
+class GetAddrInfo:
+	def __init__(self, idlequeue):
+		self.idlequeue = idlequeue
+		# dict {host : list of addrinfo records}
+		self.resolved_hosts = {} 
+		# dict {host : list of callbacks}
+		self.handlers = {}
+
 	
 # below lines is on how to use API and assist in testing
 if __name__ == '__main__':
