pidgin.vv.yahoo.voice: a7c422ff: Fallback on the Yahoo STUN server if the...

maiku at pidgin.im maiku at pidgin.im
Sun Aug 30 04:45:46 EDT 2009


-----------------------------------------------------------------
Revision: a7c422fff3edb538ec323b48b0081e0edd1308be
Ancestor: f36dc8d215440b99d56b2cefc15be07231dcc80c
Author: maiku at pidgin.im
Date: 2009-08-30T08:43:28
Branch: im.pidgin.pidgin.vv.yahoo.voice
URL: http://d.pidgin.im/viewmtn/revision/info/a7c422fff3edb538ec323b48b0081e0edd1308be

Modified files:
        libpurple/protocols/yahoo/libymsg.h
        libpurple/protocols/yahoo/yahoo_sip.c

ChangeLog: 

Fallback on the Yahoo STUN server if the STUN server preference is empty.

-------------- next part --------------
============================================================
--- libpurple/protocols/yahoo/libymsg.h	d4d6a3803b1e90bda4d2c91e8893a8778bfa14b7
+++ libpurple/protocols/yahoo/libymsg.h	3984d233277f011c6c54dce56483d75370e7b3b7
@@ -44,6 +44,7 @@
 #define YAHOO_XFER_RELAY_HOST "relay.msg.yahoo.com"
 #define YAHOO_XFER_RELAY_PORT 80
 #define YAHOO_SIP_HOST "voipa.sip.yahoo.com"
+#define YAHOO_STUN_HOST "beta.stun.voice.yahoo.com"
 #define YAHOO_ROOMLIST_URL "http://insider.msg.yahoo.com/ycontent/"
 #define YAHOO_ROOMLIST_LOCALE "us"
 /* really we should get the list of servers from
============================================================
--- libpurple/protocols/yahoo/yahoo_sip.c	c6bbf53c21e4749517470ff4dc5b7559a65c4975
+++ libpurple/protocols/yahoo/yahoo_sip.c	c9bf271678093eb3bef6c0899314f9c89d87f038
@@ -27,6 +27,7 @@
 #include "cipher.h"
 #include "debug.h"
 #include "dnsquery.h"
+#include "network.h"
 #include "mediamanager.h"
 
 #include "yahoo_sip.h"
@@ -49,6 +50,9 @@ struct _YahooSip {
 	guint yahooref_timeout_handle;
 	gchar *to_str;
 	gboolean shutdown;
+	gchar *stun_ip;
+	PurpleDnsQueryData *sip_host_query;
+	PurpleDnsQueryData *stun_host_query;
 #endif /* defined(USE_VV) && defined(USE_SOFIASIP) */
 };
 
@@ -298,7 +302,11 @@ event_callback(nua_event_t event, int st
 				nua_handle_remote(nh)->a_display);
 		PurpleMedia *media;
 		PurpleAccount *account = magic;
-		GParameter param;
+		PurpleConnection *pc = purple_account_get_connection(account);
+		YahooData *yd = pc->proto_data;
+		YahooSip *ysip = yd->ysip;
+		GParameter params[2];
+		guint num_params = 1;
 		sip_unknown_t *iter = sip_unknown(sip);
 
 		purple_debug_info("yahoo", "INVITE status %d display: %s\n",
@@ -348,12 +356,23 @@ event_callback(nua_event_t event, int st
 		g_signal_connect(G_OBJECT(media), "stream-info",
 				G_CALLBACK(yahoo_sip_stream_info_cb), nh);
 
-		param.name = "compatibility-mode";
-		param.value.g_type = 0;
-		g_value_init(&param.value, G_TYPE_UINT);
-		g_value_set_uint(&param.value, 4); /* NICE_COMPATIBILITY_YAHOO */
+		/* NICE_COMPATIBILITY_YAHOO */
+		params[0].name = "compatibility-mode";
+		params[0].value.g_type = 0;
+		g_value_init(&params[0].value, G_TYPE_UINT);
+		g_value_set_uint(&params[0].value, 4);
+
+		if (ysip->stun_ip && !purple_network_get_stun_ip()) {
+			num_params = 2;
+			params[1].name = "stun-ip";
+			params[1].value.g_type = 0;
+			g_value_init(&params[1].value, G_TYPE_STRING);
+			g_value_set_string(&params[1].value, ysip->stun_ip);
+		}
+
 		purple_media_add_stream(media, "yahoo-voice", name,
-				PURPLE_MEDIA_AUDIO, FALSE, "nice", 1, &param);
+				PURPLE_MEDIA_AUDIO, FALSE, "nice",
+				num_params, params);
 	} else if (event == nua_i_state && status == 100) {
 		/*
 		 * This has a phrase of "Trying" if not,
@@ -446,18 +465,19 @@ yahoo_start_sip(GSList *hosts, gpointer 
 static void
 yahoo_start_sip(GSList *hosts, gpointer data, const char *error_message)
 {
-	PurpleAccount *account;
-	PurpleConnection *pc;
-	YahooData *yd;
-	YahooSip *ysip;
+	PurpleAccount *account = data;
+	PurpleConnection *pc = purple_account_get_connection(account);
+	YahooData *yd = purple_connection_get_protocol_data(pc);
+	YahooSip *ysip = yd->ysip;
 	GSource *gsource;
 	gchar sip_host[INET6_ADDRSTRLEN];
 	struct sockaddr *addr;
 
+	ysip->sip_host_query = NULL;
+
 	if (error_message) {
 		purple_debug_warning("yahoo", "Error resolving SIP server "
 				"address: %s\n", error_message);
-		g_slist_free(hosts);
 		return;
 	} else if (hosts == NULL || g_slist_next(hosts) == NULL) {
 		purple_debug_warning("yahoo", "No hosts retrieved from "
@@ -473,15 +493,9 @@ yahoo_start_sip(GSList *hosts, gpointer 
 		inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr,
 			sip_host, sizeof(sip_host));
 	}
-	g_slist_free(hosts);
 
 	purple_debug_info("yahoo", "Starting Sofia-SIP\n");
 
-	account = data;
-	pc = purple_account_get_connection(account);
-	yd = purple_connection_get_protocol_data(pc);
-	ysip = yd->ysip = g_new0(YahooSip, 1);
-
 	ysip->root = su_glib_root_create(NULL);
 
 	gsource = su_glib_root_gsource(ysip->root);
@@ -518,14 +532,61 @@ yahoo_start_sip(GSList *hosts, gpointer 
 }
 #endif /* defined(USE_VV) && defined(USE_SOFIASIP) */
 
+static void
+yahoo_query_stun_server_cb(GSList *hosts, gpointer data,
+		const char *error_message) {
+	YahooSip *ysip = data;
+	gchar dst[INET6_ADDRSTRLEN];
+	struct sockaddr *addr;
+
+	ysip->stun_host_query = NULL;
+
+	if (error_message) {
+		purple_debug_warning("yahoo", "Error resolving STUN server "
+				"address: %s\n", error_message);
+		return;
+	} else if (hosts == NULL || g_slist_next(hosts) == NULL) {
+		purple_debug_warning("yahoo", "No hosts retrieved from "
+				"STUN dns query\n");
+		return;
+	}
+
+	addr = g_slist_next(hosts)->data;
+	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));
+	}
+
+	ysip->stun_ip = g_strdup(dst);
+}
+
 void
 yahoo_sip_init(PurpleAccount *account)
 {
 #if defined(USE_VV) && defined(USE_SOFIASIP)
-	if (purple_dnsquery_a(YAHOO_SIP_HOST, 443,
-			yahoo_start_sip, account) == NULL)
-		purple_debug_warning("yahoo", "Error starting SIP "
+	PurpleConnection *pc = purple_account_get_connection(account);
+	YahooData *yd = purple_connection_get_protocol_data(pc);
+	YahooSip *ysip = yd->ysip = g_new0(YahooSip, 1);
+
+	ysip->sip_host_query = purple_dnsquery_a(YAHOO_SIP_HOST, 443,
+			yahoo_start_sip, account);
+	if (ysip->sip_host_query == NULL) {
+		purple_debug_error("yahoo", "Error starting SIP "
 				"server dns query\n");
+		g_free(ysip);
+		yd->ysip = NULL;
+		return;
+	}
+
+	ysip->stun_host_query = purple_dnsquery_a(YAHOO_STUN_HOST, 3478,
+			yahoo_query_stun_server_cb, ysip);
+	if (ysip->stun_host_query == NULL) {
+		purple_debug_warning("yahoo", "Unable to starting stun "
+				"server dns query\n");
+	}
 #endif /* defined(USE_VV) && defined(USE_SOFIASIP) */
 }
 
@@ -537,6 +598,12 @@ yahoo_sip_uninit(PurpleAccount *account)
 	YahooData *yd = purple_connection_get_protocol_data(pc);
 	YahooSip *ysip = yd->ysip;
 
+	if (ysip->sip_host_query)
+		purple_dnsquery_destroy(ysip->sip_host_query);
+
+	if (ysip->stun_host_query)
+		purple_dnsquery_destroy(ysip->stun_host_query);
+
 	if (ysip->yahooref_timeout_handle)
 		purple_timeout_remove(ysip->yahooref_timeout_handle);
 
@@ -559,6 +626,8 @@ yahoo_sip_uninit(PurpleAccount *account)
 
 	nua_destroy(ysip->nua);
 	g_free(ysip->to_str);
+	g_free(ysip->stun_ip);
 	g_free(ysip);
+	yd->ysip = NULL;
 #endif /* defined(USE_VV) && defined(USE_SOFIASIP) */
 }


More information about the Commits mailing list