# HG changeset patch # User Marcus Lundblad # Date 1257274292 0 # Node ID fc8c85e8b6e132caab9704b3b3e63e5147f4938f # Parent 28d73d34d792ddc27b14765481d0e2b327938766 jabber: Automatically find a STUN server by SRV lookup on the account's domain (for vv) diff -r 28d73d34d792 -r fc8c85e8b6e1 ChangeLog --- a/ChangeLog Tue Nov 03 07:46:01 2009 +0000 +++ b/ChangeLog Tue Nov 03 18:51:32 2009 +0000 @@ -29,6 +29,9 @@ * Resolve an issue when connecting to iChat Server when no resource is specified. * Fix a crash when adding a buddy without an '@'. + * Try to automatically find a STUN server by using an SRV lookup on the + account's domain, and use that for voice and video if found and the user + didn't set one manually in prefs. Yahoo: * Fix sending /buzz. diff -r 28d73d34d792 -r fc8c85e8b6e1 libpurple/protocols/jabber/disco.c --- a/libpurple/protocols/jabber/disco.c Tue Nov 03 07:46:01 2009 +0000 +++ b/libpurple/protocols/jabber/disco.c Tue Nov 03 18:51:32 2009 +0000 @@ -421,6 +421,76 @@ } +/* should probably share this code with google.c, or maybe from 2.7.0 + introduce an abstracted hostname -> IP function in dns.c */ +static void +jabber_disco_stun_lookup_cb(GSList *hosts, gpointer data, + const char *error_message) +{ + JabberStream *js = (JabberStream *) data; + + if (error_message) { + purple_debug_error("jabber", "STUN lookup failed: %s\n", + error_message); + g_slist_free(hosts); + js->stun_query = NULL; + return; + } + + if (hosts && g_slist_next(hosts)) { + struct sockaddr *addr = g_slist_next(hosts)->data; + char dst[INET6_ADDRSTRLEN]; + int port; + + if (addr->sa_family == AF_INET6) { + inet_ntop(addr->sa_family, &((struct sockaddr_in6 *) addr)->sin6_addr, + dst, sizeof(dst)); + port = ntohs(((struct sockaddr_in6 *) addr)->sin6_port); + } else { + inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr, + dst, sizeof(dst)); + port = ntohs(((struct sockaddr_in *) addr)->sin_port); + } + + if (js->stun_ip) + g_free(js->stun_ip); + js->stun_ip = g_strdup(dst); + js->stun_port = port; + + purple_debug_info("jabber", "set STUN IP/port address: " + "%s:%d\n", dst, port); + + /* unmark ongoing query */ + js->stun_query = NULL; + } + + while (hosts != NULL) { + hosts = g_slist_delete_link(hosts, hosts); + /* Free the address */ + g_free(hosts->data); + hosts = g_slist_delete_link(hosts, hosts); + } +} + + +static void +jabber_disco_stun_srv_resolve_cb(PurpleSrvResponse *resp, int results, gpointer data) +{ + JabberStream *js = (JabberStream *) data; + + purple_debug_info("jabber", "got %d SRV responses for STUN.\n", results); + js->srv_query_data = NULL; + + if (results > 0) { + purple_debug_info("jabber", "looking up IP for %s:%d\n", + resp[0].hostname, resp[0].port); + js->stun_query = + purple_dnsquery_a(resp[0].hostname, resp[0].port, + jabber_disco_stun_lookup_cb, js); + } +} + + static void jabber_disco_server_info_result_cb(JabberStream *js, const char *from, JabberIqType type, const char *id, @@ -471,7 +541,10 @@ /* autodiscover stun and relays */ jabber_google_send_jingle_info(js); } else { - /* TODO: add external service discovery here... */ + js->srv_query_data = + purple_srv_resolve("stun", "udp", js->user->domain, + jabber_disco_stun_srv_resolve_cb, js); + /* TODO: add TURN support later... */ } } diff -r 28d73d34d792 -r fc8c85e8b6e1 libpurple/protocols/jabber/jingle/jingle.c --- a/libpurple/protocols/jabber/jingle/jingle.c Tue Nov 03 07:46:01 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/jingle.c Tue Nov 03 18:51:32 2009 +0000 @@ -442,15 +442,15 @@ if (num_params > 0) { params = g_new0(GParameter, num_params); - purple_debug_info("jabber", - "setting param stun-ip for stream using Google auto-config: %s\n", - js->stun_ip); + purple_debug_info("jabber", + "setting param stun-ip for stream using auto-discovered IP: %s\n", + js->stun_ip); params[0].name = "stun-ip"; g_value_init(¶ms[0].value, G_TYPE_STRING); g_value_set_string(¶ms[0].value, js->stun_ip); purple_debug_info("jabber", - "setting param stun-port for stream using Google auto-config: %d\n", - js->stun_port); + "setting param stun-port for stream using auto-discovered port: %d\n", + js->stun_port); params[1].name = "stun-port"; g_value_init(¶ms[1].value, G_TYPE_UINT); g_value_set_uint(¶ms[1].value, js->stun_port);