SRV lookup moved from xmpp to connection.py

This commit is contained in:
Yann Leboulanger 2005-09-18 19:52:06 +00:00
parent a7f4391083
commit 6d0bf25adc
3 changed files with 54 additions and 56 deletions

View File

@ -44,6 +44,19 @@ USE_GPG = GnuPG.USE_GPG
from common import i18n
_ = i18n._
# determine which DNS resolution library is available
HAVE_DNSPYTHON = False
HAVE_PYDNS = False
try:
import dns.resolver # http://dnspython.org/
HAVE_DNSPYTHON = True
except ImportError:
try:
import DNS # http://pydns.sf.net/
HAVE_PYDNS = True
except ImportError:
gajim.log.debug("Could not load one of the supported DNS libraries (dnspython or pydns). SRV records will not be queried and you may need to set custom hostname/port for some servers to be accessible.")
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
'invisible']
@ -1171,7 +1184,7 @@ class Connection:
if msg:
p.setStatus(msg)
if signed:
p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
if self.connection:
self.connection.send(p)
@ -1205,10 +1218,10 @@ class Connection:
if autojoin_val is None: # not there (it's optional)
autojoin_val == False
bm = { 'name': conf.getAttr('name'),
'jid': conf.getAttr('jid'),
'autojoin': autojoin_val,
'password': conf.getTagData('password'),
'nick': conf.getTagData('nick') }
'jid': conf.getAttr('jid'),
'autojoin': autojoin_val,
'password': conf.getTagData('password'),
'nick': conf.getTagData('nick') }
self.bookmarks.append(bm)
self.dispatch('BOOKMARKS', self.bookmarks)
@ -1336,7 +1349,34 @@ class Connection:
p = gajim.config.get_per('accounts', self.name, 'custom_port')
use_srv = False
con_type = con.connect((h, p), proxy=proxy, secure=secur, use_srv=use_srv)
# SRV resolver
if use_srv and (HAVE_DNSPYTHON or HAVE_PYDNS):
possible_queries = ['_xmpp-client._tcp.' + h]
for query in possible_queries:
try:
if HAVE_DNSPYTHON:
answers = [x for x in dns.resolver.query(query, 'SRV')]
if answers:
h = str(answers[0].target)
p = int(answers[0].port)
break
elif HAVE_PYDNS:
# ensure we haven't cached an old configuration
DNS.ParseResolvConf()
response = DNS.Request().req(query, qtype='SRV')
answers = response.answers
if len(answers) > 0:
# ignore the priority and weight for now
_t, _t, p, h = answers[0]['data']
del _t
p = int(port)
break
except:
gajim.log.debug('An error occurred while looking up %s' % query)
# end of SRV resolver
con_type = con.connect((h, p), proxy=proxy, secure=secur)
if not con_type:
gajim.log.debug("Couldn't connect to %s" % self.name)
if not self.retrycount:

View File

@ -156,11 +156,11 @@ class CommonClient:
if hasattr(self, 'Connection'):
return self.Connection._sock.getsockname()
def connect(self,server=None,proxy=None, ssl=None, use_srv=None):
def connect(self,server=None,proxy=None, ssl=None):
""" Make a tcp/ip connection, protect it with tls/ssl if possible and start XMPP stream. """
if not server: server=(self.Server,self.Port)
if proxy: connected=transports.HTTPPROXYsocket(proxy,server,use_srv).PlugIn(self)
else: connected=transports.TCPsocket(server,use_srv).PlugIn(self)
if proxy: connected=transports.HTTPPROXYsocket(proxy,server).PlugIn(self)
else: connected=transports.TCPsocket(server).PlugIn(self)
if not connected: return
self._Server,self._Proxy=server,proxy
self.connected='tcp'
@ -179,7 +179,7 @@ class CommonClient:
class Client(CommonClient):
""" Example client class, based on CommonClient. """
def connect(self,server=None,proxy=None,secure=None,use_srv=True):
def connect(self,server=None,proxy=None,secure=None):
""" Connect to jabber server. If you want to specify different ip/port to connect to you can
pass it as tuple as first parameter. If there is HTTP proxy between you and server -
specify it's address and credentials (if needed) in the second argument
@ -188,7 +188,7 @@ class Client(CommonClient):
If you want to disable tls/ssl support completely, set it to 0
Example: connect(('192.168.5.5',5222),{'host':'proxy.my.net','port':8080,'user':'me','password':'secret'})
Returns '' (on no connection) or 'tcp' or 'tls', depending on the result."""
if not CommonClient.connect(self,server,proxy,secure,use_srv) or secure<>None and not secure: return self.connected
if not CommonClient.connect(self,server,proxy,secure) or secure<>None and not secure: return self.connected
transports.TLS().PlugIn(self)
if not self.Dispatcher.Stream._document_attrs.has_key('version') or not self.Dispatcher.Stream._document_attrs['version']=='1.0': return self.connected
while not self.Dispatcher.Stream.features and self.Process(): pass # If we get version 1.0 stream the features tag MUST BE presented

View File

@ -33,19 +33,6 @@ from client import PlugIn
from protocol import *
import sys
# determine which DNS resolution library is available
HAVE_DNSPYTHON = False
HAVE_PYDNS = False
try:
import dns.resolver # http://dnspython.org/
HAVE_DNSPYTHON = True
except ImportError:
try:
import DNS # http://pydns.sf.net/
HAVE_PYDNS = True
except ImportError:
print >> sys.stderr, "Could not load one of the supported DNS libraries (dnspython or pydns). SRV records will not be queried and you may need to set custom hostname/port for some servers to be accessible."
DATA_RECEIVED='DATA RECEIVED'
DATA_SENT='DATA SENT'
@ -61,42 +48,13 @@ class error:
class TCPsocket(PlugIn):
""" This class defines direct TCP connection method. """
def __init__(self, server=None, use_srv=True):
def __init__(self, server=None):
""" Cache connection point 'server'. 'server' is the tuple of (host, port)
absolutely the same as standart tcp socket uses. """
PlugIn.__init__(self)
self.DBG_LINE='socket'
self._exported_methods=[self.send,self.disconnect]
# SRV resolver
if use_srv and (HAVE_DNSPYTHON or HAVE_PYDNS):
host, port = server
possible_queries = ['_xmpp-client._tcp.' + host]
for query in possible_queries:
try:
if HAVE_DNSPYTHON:
answers = [x for x in dns.resolver.query(query, 'SRV')]
if answers:
host = str(answers[0].target)
port = int(answers[0].port)
break
elif HAVE_PYDNS:
# ensure we haven't cached an old configuration
DNS.ParseResolvConf()
response = DNS.Request().req(query, qtype='SRV')
answers = response.answers
if len(answers) > 0:
# ignore the priority and weight for now
_, _, port, host = answers[0]['data']
del _
port = int(port)
break
except:
print >> sys.stderr, 'An error occurred while looking up %s' % query
server = (host, port)
# end of SRV resolver
self._server = server
def plugin(self, owner):
@ -189,12 +147,12 @@ class HTTPPROXYsocket(TCPsocket):
""" HTTP (CONNECT) proxy connection class. Uses TCPsocket as the base class
redefines only connect method. Allows to use HTTP proxies like squid with
(optionally) simple authentication (using login and password). """
def __init__(self,proxy,server,use_srv=True):
def __init__(self,proxy,server):
""" Caches proxy and target addresses.
'proxy' argument is a dictionary with mandatory keys 'host' and 'port' (proxy address)
and optional keys 'user' and 'password' to use for authentication.
'server' argument is a tuple of host and port - just like TCPsocket uses. """
TCPsocket.__init__(self,server,use_srv)
TCPsocket.__init__(self,server)
self.DBG_LINE=DBG_CONNECT_PROXY
self._proxy=proxy