Mercurial > pidgin.yaz
changeset 26132:ae3d25465d0f
Run an asynchronous DNS lookup for the STUN server IP (to set as a property
to the nice transmitter for media).
Also update the IP when the preference changes and when NetworkManager support
is present, when NM reports connected.
TODO: add code to run DNS lookup on Win32 when the network connection is ready
author | Marcus Lundblad <ml@update.uu.se> |
---|---|
date | Sat, 17 Jan 2009 01:38:44 +0000 |
parents | 6eeb500ce9a2 |
children | b68a88fb7458 |
files | libpurple/media.c libpurple/network.c libpurple/network.h pidgin/gtkprefs.c |
diffstat | 4 files changed, 127 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/media.c Wed Jan 14 09:32:48 2009 +0000 +++ b/libpurple/media.c Sat Jan 17 01:38:44 2009 +0000 @@ -32,6 +32,7 @@ #include "media.h" #include "marshallers.h" #include "mediamanager.h" +#include "network.h" #include "debug.h" @@ -1549,27 +1550,6 @@ g_timeout_add(0, (GSourceFunc)purple_media_connected_cb, stream); } -static gchar * -purple_media_get_stun_pref_ip() -{ - const gchar *stun_pref = - purple_prefs_get_string("/purple/network/stun_server"); - struct hostent *host; - - if ((host = gethostbyname(stun_pref)) && host->h_addr) { - gchar *stun_ip = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", - host->h_addr[0], host->h_addr[1], - host->h_addr[2], host->h_addr[3]); - purple_debug_info("media", "IP address for %s found: %s\n", - stun_pref, stun_ip); - return stun_ip; - } else { - purple_debug_info("media", "Unable to resolve %s IP address\n", - stun_pref); - return NULL; - } -} - static gboolean purple_media_add_stream_internal(PurpleMedia *media, const gchar *sess_id, const gchar *who, FsMediaType type, @@ -1653,22 +1633,25 @@ if (!stream) { GError *err = NULL; - gchar *stun_ip = NULL; FsStream *fsstream = NULL; - - if ((stun_ip = purple_media_get_stun_pref_ip())) { + const gchar *stun_ip = purple_network_get_stun_ip(); + + + if (stun_ip) { GParameter *param = g_new0(GParameter, num_params+1); memcpy(param, params, sizeof(GParameter) * num_params); + purple_debug_info("media", + "setting property stun-ip on new stream: %s\n", stun_ip); + param[num_params].name = "stun-ip"; g_value_init(¶m[num_params].value, G_TYPE_STRING); - g_value_take_string(¶m[num_params].value, stun_ip); + g_value_set_string(¶m[num_params].value, stun_ip); fsstream = fs_session_new_stream(session->session, participant, type_direction, transmitter, num_params+1, param, &err); g_free(param); - g_free(stun_ip); } else { fsstream = fs_session_new_stream(session->session, participant, type_direction,
--- a/libpurple/network.c Wed Jan 14 09:32:48 2009 +0000 +++ b/libpurple/network.c Sat Jan 17 01:38:44 2009 +0000 @@ -48,6 +48,7 @@ #include "prefs.h" #include "stun.h" #include "upnp.h" +#include "dnsquery.h" /* * Calling sizeof(struct ifreq) isn't always correct on @@ -92,6 +93,9 @@ static NMState nm_get_network_state(void); #endif +/* Cached IP address for STUN server */ +static gchar *stun_ip = NULL; + const unsigned char * purple_network_ip_atoi(const char *ip) { @@ -685,6 +689,12 @@ case NM_STATE_CONNECTED: /* Call res_init in case DNS servers have changed */ res_init(); + /* update STUN IP in case we it changed (theoretically we could + have gone from IPv4 to IPv6, f.ex. or we were previously + offline */ + purple_network_set_stun_server( + purple_prefs_get_string("/purple/network/stun_server")); + if (ui_ops != NULL && ui_ops->network_connected != NULL) ui_ops->network_connected(); break; @@ -746,6 +756,61 @@ #endif +static void +purple_network_stun_lookup_cb(GSList *hosts, gpointer data, + const char *error_message) +{ + if (error_message) { + purple_debug_error("network", "lookup of STUN server IP failed: %s\n", + error_message); + g_slist_free(hosts); + return; + } + + if (hosts && g_slist_next(hosts)) { + size_t addr_len = (size_t) hosts->data; + struct sockaddr *addr = g_slist_next(hosts)->data; + char dst[INET6_ADDRSTRLEN]; + + if (addr->sa_family == AF_INET6) { + inet_ntop(addr->sa_family, &((struct sockaddr_in6 *) addr)->sin6_addr, + dst, sizeof(dst)); + } else { + inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr, + dst, sizeof(dst)); + } + + stun_ip = g_strdup(dst); + purple_debug_info("network", "set STUN IP: %s\n", stun_ip); + } + + g_slist_free(hosts); +} + +void +purple_network_set_stun_server(const gchar *stun_server) +{ + if (stun_server && stun_server[0] != '\0') { + if (purple_network_is_available()) { + purple_debug_info("network", "running DNS query for STUN server\n"); + purple_dnsquery_a(stun_server, 3478, purple_network_stun_lookup_cb, + NULL); + } else { + purple_debug_info("network", + "network is unavailable, don't try to update STUN IP"); + } + } else if (stun_ip) { + g_free(stun_ip); + stun_ip = NULL; + } +} + +const gchar * +purple_network_get_stun_ip(void) +{ + return stun_ip; +} + void * purple_network_get_handle(void) { @@ -777,6 +842,7 @@ #endif purple_prefs_add_none ("/purple/network"); + purple_prefs_add_string("/purple/network/stun_server", ""); purple_prefs_add_bool ("/purple/network/auto_ip", TRUE); purple_prefs_add_string("/purple/network/public_ip", ""); purple_prefs_add_bool ("/purple/network/map_ports", TRUE); @@ -815,6 +881,9 @@ purple_pmp_init(); purple_upnp_init(); + + purple_network_set_stun_server( + purple_prefs_get_string("/purple/network/stun_server")); } void @@ -854,4 +923,7 @@ #endif purple_signal_unregister(purple_network_get_handle(), "network-configuration-changed"); + + if (stun_ip) + g_free(stun_ip); }
--- a/libpurple/network.h Wed Jan 14 09:32:48 2009 +0000 +++ b/libpurple/network.h Sat Jan 17 01:38:44 2009 +0000 @@ -214,6 +214,21 @@ */ void *purple_network_get_handle(void); +/** + * Update the STUN server name + * Will result in a DNS query being executed asynchronous + * + * @param stun_server The host name of the STUN server to set + */ +void purple_network_set_stun_server(const gchar *stun_server); + +/** + * Get the IP address of the STUN server as a string representation + * + * @return the IP address + */ +const gchar *purple_network_get_stun_ip(void); + /** * Initializes the network subsystem. */
--- a/pidgin/gtkprefs.c Wed Jan 14 09:32:48 2009 +0000 +++ b/pidgin/gtkprefs.c Sat Jan 17 01:38:44 2009 +0000 @@ -1142,6 +1142,17 @@ purple_network_set_public_ip(gtk_entry_get_text(entry)); } +static gboolean network_stun_server_changed_cb(GtkWidget *widget, + GdkEventFocus *event, gpointer data) +{ + GtkEntry *entry = GTK_ENTRY(widget); + purple_prefs_set_string("/purple/network/stun_server", + gtk_entry_get_text(entry)); + purple_network_set_stun_server(gtk_entry_get_text(entry)); + + return FALSE; +} + static void proxy_changed_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) @@ -1206,10 +1217,27 @@ gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); vbox = pidgin_make_frame (ret, _("IP Address")); + + table = gtk_table_new(2, 2, FALSE); + gtk_container_set_border_width(GTK_CONTAINER(table), 0); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_table_set_row_spacings(GTK_TABLE(table), 10); + gtk_container_add(GTK_CONTAINER(vbox), table); + sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - pidgin_prefs_labeled_entry(vbox,_("ST_UN server:"), - "/purple/network/stun_server", sg); - + label = gtk_label_new_with_mnemonic(_("ST_UN server:")); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + gtk_size_group_add_widget(sg, label); + + entry = gtk_entry_new(); + gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); + gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + g_signal_connect(G_OBJECT(entry), "focus-out-event", + G_CALLBACK(network_stun_server_changed_cb), NULL); + gtk_entry_set_text(GTK_ENTRY(entry), + purple_prefs_get_string("/purple/network/stun_server")); + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); gtk_container_add(GTK_CONTAINER(vbox), hbox);