From c1d0013cb0333efa153ba68a7da1b1eae9e0aacb Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Thu, 7 Jan 2010 18:02:05 +0100 Subject: [PATCH] ability to discover STUN server with SRV records of jabber server --- data/glade/preferences_window.glade | 22 +++++++++++++++++++--- src/common/config.py | 1 + src/common/connection.py | 8 ++++++++ src/common/connection_handlers.py | 3 +-- src/common/jingle_rtp.py | 21 ++++++++++++--------- src/config.py | 12 +++++++++++- 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/data/glade/preferences_window.glade b/data/glade/preferences_window.glade index 98301441a..fe877da9d 100644 --- a/data/glade/preferences_window.glade +++ b/data/glade/preferences_window.glade @@ -2128,7 +2128,7 @@ $T will be replaced by auto-not-available timeout True - 3 + 4 6 6 @@ -2148,8 +2148,8 @@ $T will be replaced by auto-not-available timeout True - 2 - 3 + 3 + 4 GTK_FILL @@ -2157,12 +2157,28 @@ $T will be replaced by auto-not-available timeout True True + STUN server hostname. If none given, Gajim will try +to discover one from server. + + 2 + 3 + + + + + True + True + False + True + + 1 2 + GTK_FILL diff --git a/src/common/config.py b/src/common/config.py index ad0b77cbc..adb3c701d 100644 --- a/src/common/config.py +++ b/src/common/config.py @@ -277,6 +277,7 @@ class Config: 'audio_output_device': [opt_str, 'autoaudiosink'], 'video_input_device': [opt_str, 'autovideosrc ! videoscale ! ffmpegcolorspace'], 'video_output_device': [opt_str, 'autovideosink'], + 'use_stun_server': [opt_bool, True, _('If True, Gajim will try to use a STUN server when using jingle. The one in "stun_server" option, or the one given by the jabber server.')], 'stun_server': [opt_str, '', _('STUN server to use when using jingle')], } diff --git a/src/common/connection.py b/src/common/connection.py index 347e30796..9639bbd15 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -150,6 +150,7 @@ class CommonConnection: self.private_storage_supported = False self.muc_jid = {} # jid of muc server for each transport type + self._stun_servers = [] # STUN servers of our jabber server self.get_config_values_or_default() @@ -1508,6 +1509,13 @@ class Connection(CommonConnection, ConnectionHandlers): self.discoverInfo(gajim.config.get_per('accounts', self.name, 'hostname'), id_prefix='Gajim_') self.privacy_rules_requested = False + # Discover Stun server(s) + gajim.resolver.resolve('_stun._udp.' + helpers.idn_to_ascii( + self.connected_hostname), self._on_stun_resolved) + + def _on_stun_resolved(self, host, result_array): + if len(result_array) != 0: + self._stun_servers = self._hosts = [i for i in result_array] def _request_privacy(self): iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '') diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index b91fe13b7..87336decb 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -213,8 +213,7 @@ class ConnectionDisco: continue items.append(attr) jid = helpers.get_full_jid_from_iq(iq_obj) - hostname = gajim.config.get_per('accounts', self.name, - 'hostname') + hostname = gajim.config.get_per('accounts', self.name, 'hostname') id_ = iq_obj.getID() if jid == hostname and id_[:6] == 'Gajim_': for item in items: diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py index 6d30f2da5..8a57bde97 100644 --- a/src/common/jingle_rtp.py +++ b/src/common/jingle_rtp.py @@ -72,15 +72,18 @@ class JingleRTPContent(JingleContent): # pidgin and telepathy-gabble don't follow the XEP, and it won't work # due to bad controlling-mode params = {'controlling-mode': self.session.weinitiate, 'debug': False} - stun_server = gajim.config.get('stun_server') - if stun_server: - try: - ip = socket.getaddrinfo(stun_server, 0, socket.AF_UNSPEC, - socket.SOCK_STREAM)[0][4][0] - except socket.gaierror, (errnum, errstr): - log.warn('Lookup of stun ip failed: %s' % errstr) - else: - params['stun-ip'] = ip + if gajim.config.get('use_stun_server'): + stun_server = gajim.config.get('stun_server') + if not stun_server and self._stun_servers: + stun_server = self._stun_servers[0]['host'] + if stun_server: + try: + ip = socket.getaddrinfo(stun_server, 0, socket.AF_UNSPEC, + socket.SOCK_STREAM)[0][4][0] + except socket.gaierror, (errnum, errstr): + log.warn('Lookup of stun ip failed: %s' % errstr) + else: + params['stun-ip'] = ip self.p2pstream = self.p2psession.new_stream(participant, farsight.DIRECTION_RECV, 'nice', params) diff --git a/src/config.py b/src/config.py index 95122baf1..e75d5eee8 100644 --- a/src/config.py +++ b/src/config.py @@ -452,9 +452,15 @@ class PreferencesWindow: combobox = self.xml.get_widget(opt_name + '_combobox') combobox.set_sensitive(False) - # Connection + # STUN + cb = self.xml.get_widget('stun_checkbutton') + st = gajim.config.get('use_stun_server') + cb.set_active(st) + entry = self.xml.get_widget('stun_server_entry') entry.set_text(gajim.config.get('stun_server')) + if not st: + entry.set_sensitive(False) ### Advanced tab ### # open links with @@ -1085,6 +1091,10 @@ class PreferencesWindow: def on_video_output_combobox_changed(self, widget): self.on_av_combobox_changed(widget, 'video_output') + def on_stun_checkbutton_toggled(self, widget): + self.on_checkbutton_toggled(widget, 'use_stun_server', + [self.xml.get_widget('stun_server_entry')]) + def stun_server_entry_changed(self, widget): gajim.config.set('stun_server', widget.get_text().decode('utf-8'))