Ticket #1969: ipv6.patch

File ipv6.patch, 15.8 KB (added by sgala, 3 years ago)

all my ipv6 (or protocol) related patches, current as of now

  • src/common/xmpp/transports_nb.py

     
    251251                self.printed_error = False 
    252252                 
    253253                #  0 - not connected 
    254                 #  1 - connected 
     254                #  1 - connecting 
     255                #  2 - connected 
    255256                # -1 - about to disconnect (when we wait for final events to complete) 
    256257                # -2 - disconnected 
    257258                self.state = 0 
     
    279280                        Called internally. ''' 
    280281                self.idlequeue = owner.idlequeue 
    281282                self.printed_error = False 
     283                print self._owner.Server, owner, self._server 
    282284                if not self._server:  
    283285                        self._server=(self._owner.Server,5222) 
    284286                if self.connect(self._server) is False: 
     
    305307                self.state = 0 
    306308                success = False 
    307309                try: 
    308                         for ai in socket.getaddrinfo(server[0],server[1],socket.AF_UNSPEC,socket.SOCK_STREAM): 
    309                                 try: 
    310                                         self._sock=socket.socket(*ai[:3]) 
    311                                         self._sock.setblocking(False) 
    312                                         self._server=ai[4] 
    313                                         success = True 
    314                                         break 
    315                                 except: 
    316                                         if sys.exc_value[0] == errno.EINPROGRESS: 
    317                                                 success = True 
    318                                                 break 
    319                                         #for all errors, we try other addresses 
    320                                         continue 
     310                        self.set_timeout(CONNECT_TIMEOUT_SECONDS) 
     311                        if len(server) == 2 and type(server[0]) in (str, unicode): 
     312                                self.ais = socket.getaddrinfo(server[0],server[1],socket.AF_UNSPEC,socket.SOCK_STREAM) 
     313                                print "self.ais=", self.ais  
     314                        else: 
     315                                self.ais = server 
     316                        return self._do_connect() 
    321317                except socket.gaierror, e: 
    322318                        log.info("Lookup failure for %s: %s[%s]", self.getName(), e[1], repr(e[0]), exc_info=True) 
    323319                except: 
     
    326322                if not success: 
    327323                        if self.on_connect_failure: 
    328324                                self.on_connect_failure() 
    329                         return False 
    330  
    331                 self.fd = self._sock.fileno() 
    332                 self.idlequeue.plug_idle(self, True, False) 
    333                 self.set_timeout(CONNECT_TIMEOUT_SECONDS) 
    334                 self._do_connect() 
    335                 return True 
     325                return success 
    336326         
    337327        def _plug_idle(self): 
    338328                readable = self.state != 0 
     
    532522 
    533523        def _do_connect(self): 
    534524                if self.state != 0: 
     525                        print "do_connect while connected" 
    535526                        return 
    536                 self._sock.setblocking(False) 
    537                 self._send = self._sock.send 
    538                 self._recv = self._sock.recv 
    539                 errnum = 0 
    540                 try: 
    541                         self._sock.connect(self._server) 
    542                 except socket.error, e: 
    543                         errnum = e[0] 
     527                for ai in self.ais: 
     528                        success = False 
     529                        try: 
     530                                self._sock=socket.socket(*ai[:3]) 
     531                                self._sock.setblocking(False) 
     532                                self._server=ai[4] 
     533                                self.fd = self._sock.fileno() 
     534                                self.idlequeue.plug_idle(self, True, False) 
     535                                self._send = self._sock.send 
     536                                self._recv = self._sock.recv 
     537                                errnum = 0 
    544538 
    545                         # Ignore "Socket already connected".  
    546                         # FIXME: This happens when we switch an already 
    547                         # connected socket to SSL (STARTTLS). Instead of 
    548                         # ignoring the error, the socket should only be 
    549                         # connected to once. See #2846. 
    550                         workaround = (errno.EALREADY, 10056) 
     539                                self._sock.connect(self._server) 
     540                                print "connected" 
     541                                success = True 
     542                                self.state = 1 
     543                                break 
     544                        except socket.error, e: 
     545                                print "exception1",sys.exc_value 
     546                                errnum = e[0] 
    551547 
    552                         # 10035 - winsock equivalent of EINPROGRESS 
    553                         if errnum not in (errno.EINPROGRESS, 10035) + workaround: 
    554                                 log.error("_do_connect:", exc_info=True) 
    555                                 #traceback.print_exc() 
    556                 # in progress, or would block 
    557                 if errnum in (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK):  
    558                         return 
    559                 # 10056  - already connected, only on win32 
    560                 # code 'WS*' is not available on GNU, so we use its numeric value 
    561                 elif errnum not in (0, 10056, errno.EISCONN):  
    562                         self.remove_timeout() 
     548                                # Ignore "Socket already connected".  
     549                                # FIXME: This happens when we switch an already 
     550                                # connected socket to SSL (STARTTLS). Instead of 
     551                                # ignoring the error, the socket should only be 
     552                                # connected to once. See #2846. 
     553                                workaround = (errno.EALREADY, 10056) 
     554 
     555                                # 10035 - winsock equivalent of EINPROGRESS 
     556                                if errnum not in (errno.EINPROGRESS, 10035) + workaround: 
     557                                        log.error("_do_connect:", exc_info=True) 
     558                                        #traceback.print_exc() 
     559                                # in progress, or would block 
     560                                if errnum in (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK): 
     561                                        success = True 
     562                                        self.state = 1 
     563                                        break 
     564                                # 10056  - already connected, only on win32 
     565                                # code 'WS*' is not available on GNU, so we use its numeric value 
     566                                elif errnum not in (0, 10056, errno.EISCONN):  
     567                                        continue 
     568 
     569                self.remove_timeout() 
     570                if not success: 
    563571                        if self.on_connect_failure: 
    564572                                self.on_connect_failure() 
    565573                        return 
    566                 self.remove_timeout() 
    567574                self._owner.Connection=self 
    568575                self.state = 1 
    569                  
    570576                self._sock.setblocking(False) 
    571577                self._plug_idle() 
    572578                if self.on_connect: 
    573579                        self.on_connect() 
    574                         self.on_connect = None 
     580                self.on_connect = None 
    575581                return True 
    576582 
    577583        def send(self, raw_data, now = False): 
  • src/common/xmpp/protocol.py

     
    2727NS_AMP          ='http://jabber.org/protocol/amp' 
    2828NS_AMP_ERRORS   =NS_AMP+'#errors' 
    2929NS_AUTH         ='jabber:iq:auth' 
     30NS_AVATAR       ='jabber:iq:avatar' 
    3031NS_BIND         ='urn:ietf:params:xml:ns:xmpp-bind' 
    3132NS_BROWSE       ='jabber:iq:browse' 
    3233NS_BYTESTREAM   ='http://jabber.org/protocol/bytestreams'               # JEP-0065 
     
    4849NS_EVENT        ='jabber:x:event'                                       # JEP-0022 
    4950NS_FEATURE      ='http://jabber.org/protocol/feature-neg'   
    5051NS_FILE         ='http://jabber.org/protocol/si/profile/file-transfer'  # JEP-0096 
     52NS_GATEWAY      ='jabber:iq:gateway' 
    5153NS_GEOLOC       ='http://jabber.org/protocol/geoloc'                    # JEP-0080 
    5254NS_GROUPCHAT    ='gc-1.0' 
    5355NS_HTTP_AUTH    ='http://jabber.org/protocol/http-auth'         # JEP-0070 
     
    592594    """ This class is used in the DataForm class to describe the single data item. 
    593595        If you are working with jabber:x:data (JEP-0004, JEP-0068, JEP-0122)  
    594596        then you will need to work with instances of this class. """ 
    595     def __init__(self,name=None,value=None,typ=None,required=0,desc=None,options=[],node=None): 
     597    def __init__(self,name=None,value=None,typ=None,required=0,desc=None,label=None,options=[],node=None): 
    596598        """ Create new data field of specified name,value and type. 
    597599            Also 'required','desc' and 'options' fields can be set. 
    598600            Alternatively other XML object can be passed in as the 'node' parameted to replicate it as a new datafiled. 
     
    604606        if typ: self.setType(typ) 
    605607        elif not typ and not node: self.setType('text-single') 
    606608        if required: self.setRequired(required) 
     609        if label: self.setLabel(label) 
    607610        if desc: self.setDesc(desc) 
    608611        if options: self.setOptions(options) 
    609612    def setRequired(self,req=1): 
     
    615618    def isRequired(self): 
    616619        """ Returns in this field a required one. """ 
    617620        return self.getTag('required') 
     621    def setLabel(self, label): 
     622        self.setAttr('label',label) 
     623    def getLabel(self): 
     624        self.getAttr('label') 
    618625    def setDesc(self,desc): 
    619626        """ Set the description of this field. """ 
    620627        self.setTagData('desc',desc) 
  • src/common/xmpp/browser.py

     
    189189            self.DEBUG("No Handler for request with jid->%s node->%s ns->%s"%(request.getTo(),request.getQuerynode(),request.getQueryNS()),'error') 
    190190            conn.send(Error(request,ERR_ITEM_NOT_FOUND)) 
    191191            raise NodeProcessed 
    192         self.DEBUG("Handling request with jid->%s node->%s ns->%s"%(request.getTo(),request.getQuerynode(),request.getQueryNS()),'ok') 
     192        self.DEBUG((u"Handling request with jid->%s node->%s ns->%s"%(request.getTo(),request.getQuerynode(),request.getQueryNS())).encode('utf-8'),'ok') 
    193193        rep=request.buildReply('result') 
    194194        if request.getQuerynode(): rep.setQuerynode(request.getQuerynode()) 
    195195        q=rep.getTag('query') 
  • src/common/zeroconf/zeroconf.py

     
    185185                        self.create_service() 
    186186                elif state == self.avahi.SERVER_COLLISION: 
    187187                        self.entrygroup.Reset() 
    188                 elif state == self.avahi.CLIENT_FAILURE: 
     188                elif state == self.avahi.SERVER_FAILURE: 
    189189                        # does it ever go here? 
    190                         gajim.log.debug('CLIENT FAILURE') 
     190                        gajim.log.debug('SERVER FAILURE') 
    191191 
    192192        def entrygroup_state_changed_callback(self, state, error): 
    193193                # the name is already present, so recreate 
  • src/common/socks5.py

     
    348348        def __init__(self, idlequeue, host, port, initiator, target, sid): 
    349349                if host is not None: 
    350350                        try: 
    351                                 self.host = socket.gethostbyname(host) 
     351                                self.host = host 
     352                                self.ais = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM) 
    352353                        except socket.gaierror: 
    353                                 self.host = None 
     354                                self.ais = None 
    354355                self.idlequeue = idlequeue 
    355356                self.fd = -1 
    356357                self.port = port 
     
    793794                only pollin events though 
    794795                ''' 
    795796                self.port = port 
     797                self.ais = socket.getaddrinfo(None, port, socket.AF_UNSPEC, 
     798                                        socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE) 
    796799                self.queue_idx = -1      
    797800                self.idlequeue = idlequeue 
    798801                self.queue = None 
     
    801804                self.fd = -1 
    802805                 
    803806        def bind(self): 
    804                 self._serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    805                 self._serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    806                 self._serv.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 
    807                 self._serv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 
    808                 # will fail when port as busy, or we don't have rights to bind 
    809                 try: 
    810                         self._serv.bind(('0.0.0.0', self.port)) 
    811                 except Exception, e: 
     807                for ai in self.ais: 
     808                        #try the different possibilities (ipv6, ipv4, etc.) 
     809                        self._serv = socket.socket(*ai[:3]) 
     810                        self._serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     811                        self._serv.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 
     812                        self._serv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 
     813                        # will fail when port as busy, or we don't have rights to bind 
     814                        try: 
     815                                self._serv.bind(ai[4]) 
     816                                self.ai = ai 
     817                                break 
     818                        except: 
     819                                self.ai = None 
     820                                continue 
     821                if not self.ai: 
    812822                        # unable to bind, show error dialog 
    813823                        return None 
    814824                self._serv.listen(socket.SOMAXCONN) 
     
    884894         
    885895        def connect(self): 
    886896                ''' create the socket and plug it to the idlequeue ''' 
    887                 self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    888                 # this will not block the GUI 
    889                 self._sock.setblocking(False) 
     897                for ai in self.ais: 
     898                        try: 
     899                                self._sock=socket.socket(*ai[:3]) 
     900                                # this will not block the GUI 
     901                                self._sock.setblocking(False) 
     902                                self._server=ai[4] 
     903                                break 
     904                        except: 
     905                                if sys.exc_value[0] == errno.EINPROGRESS: 
     906                                        break 
     907                                #for all errors, we try other addresses 
     908                                continue 
    890909                self.fd = self._sock.fileno() 
    891910                self.state = 0 # about to be connected 
    892911                self.idlequeue.plug_idle(self, True, False) 
     
    950969         
    951970        def do_connect(self): 
    952971                try: 
    953                         self._sock.connect((self.host, self.port)) 
     972                        self._sock.connect(self._server) 
    954973                        self._sock.setblocking(False) 
    955974                        self._send=self._sock.send 
    956975                        self._recv=self._sock.recv 
  • src/common/contacts.py

     
    5757        def get_shown_name(self): 
    5858                if self.name: 
    5959                        return self.name 
     60                # see xep 0154 
     61                if hasattr(self, 'vcard'): 
     62                        ## nickname 
     63                        if self.vcard.has_key('NICKNAME'): 
     64                                return self.vcard['NICKNAME'] 
     65                        ## display name 
     66                        if self.vcard.has_key('FN'): 
     67                                return self.vcard['FN'] 
     68                        # given "middle" family 
     69                        name = '' 
     70                        space_required = False 
     71                        if self.vcard.has_key('N_GIVEN'): 
     72                                name += self.vcard['N_GIVEN'] 
     73                                space_required = True 
     74                        if self.vcard.has_key('N_MIDDLE'): 
     75                                if space_required: 
     76                                        name += ' ' 
     77                                name += '"' + self.vcard['N_MIDDLE'] + '"' 
     78                                space_required = True 
     79                        if self.vcard.has_key('N_FAMILY'): 
     80                                if space_required: 
     81                                        name += ' ' 
     82                                name += self.vcard['N_FAMILY'] 
     83                        if name: 
     84                                return name 
     85                # username from the jid 
    6086                return self.jid.split('@')[0] 
    6187 
    6288        def is_hidden_from_roster(self): 
  • src/common/connection.py

     
    357357                # SRV resolver 
    358358                self._proxy = proxy 
    359359                self._secure = secur 
    360                 self._hosts = [ {'host': h, 'port': p, 'prio': 10, 'weight': 10} ] 
    361360                self._hostname = hostname 
     361                def _on_resolve(host, result_array): 
     362                        # SRV query returned at least one valid result, we put it in hosts dict 
     363                        if len(result_array) != 0: 
     364                                self._hosts = [i for i in result_array] 
     365                        else: 
     366                                # TODO: BLOCKS protect exceptions in getaddrinfo 
     367                                self._hosts = [ {'host': h, 'port': p, 'prio': 10, 'weight': 10, 'ais': socket.getaddrinfo(h,p,socket.AF_UNSPEC,socket.SOCK_STREAM)} ] 
     368                        self.connect_to_next_host() 
    362369                if use_srv: 
    363370                        # add request for srv query to the resolve, on result '_on_resolve' 
    364371                        # will be called 
    365372                        gajim.resolver.resolve('_xmpp-client._tcp.' + helpers.idn_to_ascii(h), 
    366                                 self._on_resolve) 
     373                                _on_resolve) 
    367374                else: 
    368                         self._on_resolve('', []) 
     375                        _on_resolve('', []) 
    369376 
    370         def _on_resolve(self, host, result_array): 
    371                 # SRV query returned at least one valid result, we put it in hosts dict 
    372                 if len(result_array) != 0: 
    373                         self._hosts = [i for i in result_array] 
    374                 self.connect_to_next_host() 
    375377 
    376378        def on_proxy_failure(self, reason): 
    377379                log.debug('Connection to proxy failed') 
     
    388390                                self.last_connection.socket.disconnect() 
    389391                                self.last_connection = None 
    390392                                self.connection = None 
     393                        debug = [] 
    391394                        if gajim.verbose: 
    392395                                con = common.xmpp.NonBlockingClient(self._hostname, caller = self, 
    393396                                        on_connect = self.on_connect_success, 
     
    411414                                con.RegisterDisconnectHandler(self._on_new_account) 
    412415 
    413416                        log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port']) 
    414                         con.connect((host['host'], host['port']), proxy = self._proxy, 
    415                                 secure = self._secure) 
     417                        if 'ai' in host: 
     418                                con.connect(host['ai'][4][0:2], proxy = self._proxy, 
     419                                        secure = self._secure) 
     420                        else: 
     421                                con.connect((host['host'],host['port']), proxy = self._proxy, 
     422                                        secure = self._secure) 
    416423                else: 
    417424                        if not retry and self.retrycount == 0: 
    418425                                log.debug("Out of hosts, giving up connecting to %s", self.name) 
  • src/common/nslookup.py

     
    1515import sys 
    1616import os 
    1717import re 
     18import socket 
    1819 
    1920from xmpp.idlequeue import * 
    2021 
     
    124125                                        port = int(port) 
    125126                                except ValueError: 
    126127                                        continue 
    127                                 hosts.append({'host': host, 'port': port,'weight': weight, 
    128                                                 'prio': prio}) 
     128                                #TODO: wrap in try:except socket.aierror 
     129                                for ai in socket.getaddrinfo(host,port,socket.AF_UNSPEC,socket.SOCK_STREAM): 
     130                                        hosts.append({'host': host, 'port': port,'weight': weight, 
     131                                                'prio': prio, 'ai':ai}) 
    129132                return hosts 
    130133         
    131134        def _on_ready(self, host, result): 
     
    285288                if self.result_handler: 
    286289                        self.result_handler(self.host, self.result) 
    287290                self.result_handler = None 
     291 
     292class GetAddrInfo: 
     293        def __init__(self, idlequeue): 
     294                self.idlequeue = idlequeue 
     295                # dict {host : list of addrinfo records} 
     296                self.resolved_hosts = {}  
     297                # dict {host : list of callbacks} 
     298                self.handlers = {} 
     299 
    288300         
    289301# below lines is on how to use API and assist in testing 
    290302if __name__ == '__main__':