changeset 12686:5f65a0cca87c

[gaim-migrate @ 15029] Clean up the STUN / SRV API a bit. I don't use this stuff, so there was no testing beyond compiling it. I think it's right, though I couldn't find where the STUN discovery status was ever set to 1 (discovering). Anyone know something about that? committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Tue, 03 Jan 2006 00:23:24 +0000
parents e9f279f0ef02
children 88ccc3603163
files src/dnssrv.c src/dnssrv.h src/network.c src/protocols/jabber/jabber.c src/protocols/simple/simple.c src/stun.c src/stun.h
diffstat 7 files changed, 113 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/src/dnssrv.c	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/dnssrv.c	Tue Jan 03 00:23:24 2006 +0000
@@ -58,7 +58,7 @@
 #endif
 
 struct resdata {
-	SRVCallback cb;
+	GaimSRVCallback cb;
 	gpointer extradata;
 #ifndef _WIN32
 	guint handle;
@@ -70,8 +70,8 @@
 };
 
 static gint responsecompare(gconstpointer ar, gconstpointer br) {
-	struct srv_response *a = (struct srv_response*)ar;
-	struct srv_response *b = (struct srv_response*)br;
+	GaimSrvResponse *a = (GaimSrvResponse*)ar;
+	GaimSrvResponse *b = (GaimSrvResponse*)br;
 
 	if(a->pref == b->pref) {
 		if(a->weight == b->weight)
@@ -87,7 +87,7 @@
 #ifndef _WIN32
 static void resolve(int in, int out) {
 	GList *ret = NULL;
-	struct srv_response *srvres;
+	GaimSrvResponse *srvres;
 	queryans answer;
 	int size;
 	int qdcount;
@@ -142,7 +142,7 @@
 
 			cp += size;
 
-			srvres = g_new0(struct srv_response,1);
+			srvres = g_new0(GaimSrvResponse, 1);
 			strcpy(srvres->hostname, name);
 			srvres->pref = pref;
 			srvres->port = port;
@@ -156,7 +156,7 @@
 end:	size = g_list_length(ret);
 	write(out, &size, sizeof(int));
 	while(g_list_first(ret)) {
-		write(out, g_list_first(ret)->data, sizeof(struct srv_response));
+		write(out, g_list_first(ret)->data, sizeof(GaimSrvResponse));
 		g_free(g_list_first(ret)->data);
 		ret = g_list_remove(ret, g_list_first(ret)->data);
 	}
@@ -170,17 +170,17 @@
 static void resolved(gpointer data, gint source, GaimInputCondition cond) {
 	int size;
 	struct resdata *rdata = (struct resdata*)data;
-	struct srv_response *res;
-	struct srv_response *tmp;
+	GaimSrvResponse *res;
+	GaimSrvResponse *tmp;
 	int i;
-	SRVCallback cb = rdata->cb;
+	GaimSRVCallback cb = rdata->cb;
 
 	read(source, &size, sizeof(int));
 	gaim_debug_info("srv","found %d SRV entries\n", size);
-	tmp = res = g_malloc0(sizeof(struct srv_response)*size);
+	tmp = res = g_new0(GaimSrvResponse, size);
 	i = size;
 	while(i) {
-		read(source, tmp++, sizeof(struct srv_response));
+		read(source, tmp++, sizeof(GaimSrvResponse));
 		i--;
 	}
 	cb(res, size, rdata->extradata);
@@ -193,7 +193,7 @@
 /** The Jabber Server code was inspiration for parts of this. */
 
 static gboolean res_main_thread_cb(gpointer data) {
-	struct srv_response *srvres = NULL;
+	GaimSrvResponse *srvres = NULL;
 	int size = 0;
 	struct resdata *rdata = data;
 
@@ -201,14 +201,14 @@
 		gaim_debug_error("srv", rdata->errmsg);
 		g_free(rdata->errmsg);
 	} else {
-		struct srv_response *srvres_tmp;
+		GaimSrvResponse *srvres_tmp;
 		GSList *lst = rdata->results;
 
 		size = g_slist_length(rdata->results);
 
-		srvres_tmp = srvres = g_malloc0(sizeof(struct srv_response) * size);
+		srvres_tmp = srvres = g_new0(GaimSrvResponse, size);
 		while (lst) {
-			memcpy(srvres_tmp++, lst->data, sizeof(struct srv_response));
+			memcpy(srvres_tmp++, lst->data, sizeof(GaimSrvResponse));
 			g_free(lst->data);
 			lst = g_slist_remove(lst, lst->data);
 		}
@@ -239,7 +239,7 @@
 		PDNS_RECORD dr_tmp;
 		GSList *lst = NULL;
 		DNS_SRV_DATA *srv_data;
-		struct srv_response *srvres;
+		GaimSrvResponse *srvres;
 
 		for (dr_tmp = dr; dr_tmp != NULL; dr_tmp = dr_tmp->pNext) {
 			/* Discard any incorrect entries. I'm not sure if this is necessary */
@@ -248,7 +248,7 @@
 			}
 
 			srv_data = &dr_tmp->Data.SRV;
-			srvres = g_new0(struct srv_response, 1);
+			srvres = g_new0(GaimSrvResponse, 1);
 			strncpy(srvres->hostname, srv_data->pNameTarget, 255);
 			srvres->hostname[255] = '\0';
 			srvres->pref = srv_data->wPriority;
@@ -270,7 +270,7 @@
 
 #endif
 
-void gaim_srv_resolve(const char *protocol, const char *transport, const char *domain, SRVCallback cb, gpointer extradata) {
+void gaim_srv_resolve(const char *protocol, const char *transport, const char *domain, GaimSRVCallback cb, gpointer extradata) {
 	char *query = g_strdup_printf("_%s._%s.%s",protocol, transport, domain);
 	struct resdata *rdata;
 #ifndef _WIN32
--- a/src/dnssrv.h	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/dnssrv.h	Tue Jan 03 00:23:24 2006 +0000
@@ -23,14 +23,16 @@
 #ifndef _GAIM_DNSSRV_H
 #define _GAIM_DNSSRV_H
 
-struct srv_response {
+typedef struct _GaimSrvResponse GaimSrvResponse;
+
+struct _GaimSrvResponse {
 	char hostname[256];
 	int port;
 	int weight;
 	int pref;
 };
 
-typedef void (*SRVCallback)(struct srv_response *resp, int results, gpointer data);
+typedef void (*GaimSRVCallback)(GaimSrvResponse *resp, int results, gpointer data);
 
 /**
  * Queries an SRV record.
@@ -41,6 +43,6 @@
  * @param cb A callback which will be called with the results
  * @param extradata Extra data to be passed to the callback
  */
-void gaim_srv_resolve(const char *protocol, const char *transport, const char *domain, SRVCallback cb, gpointer extradata);
+void gaim_srv_resolve(const char *protocol, const char *transport, const char *domain, GaimSRVCallback cb, gpointer extradata);
 
 #endif /* _GAIM_DNSSRV_H */
--- a/src/network.c	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/network.c	Tue Jan 03 00:23:24 2006 +0000
@@ -69,14 +69,14 @@
 gaim_network_get_public_ip(void)
 {
 	const char *ip;
-	struct stun_nattype *stun;
+	GaimStunNatDiscovery *stun;
 
 	ip = gaim_prefs_get_string("/core/network/public_ip");
 
 	if (ip == NULL || *ip == '\0') {
 		/* Check if STUN discovery was already done */
 		stun = gaim_stun_discover(NULL);
-		if(stun && stun->status>1)
+		if (stun != NULL && stun->status == GAIM_STUN_STATUS_DISCOVERED)
 			return stun->publicip;
 		return NULL;
 	}	
@@ -142,9 +142,9 @@
 const char *
 gaim_network_get_my_ip(int fd)
 {
-  const char *ip = NULL;
-  GaimUPnPControlInfo* controlInfo = NULL;
-	struct stun_nattype *stun;
+	const char *ip = NULL;
+	GaimUPnPControlInfo* controlInfo = NULL;
+	GaimStunNatDiscovery *stun;
 
 	/* Check if the user specified an IP manually */
 	if (!gaim_prefs_get_bool("/core/network/auto_ip")) {
@@ -156,21 +156,22 @@
 	if (ip == NULL || *ip == '\0') {
 		/* Check if STUN discovery was already done */
 		stun = gaim_stun_discover(NULL);
-		if(stun && stun->status>1)
+		if (stun != NULL && stun->status == GAIM_STUN_STATUS_DISCOVERED)
 			return stun->publicip;
 	}	
 
 
-  /* attempt to get the ip from a NAT device */
-  if ((controlInfo = gaim_upnp_discover()) != NULL) {
-    ip = gaim_upnp_get_public_ip(controlInfo);
-    g_free(controlInfo->controlURL);
-    g_free(controlInfo->serviceType);
-    g_free(controlInfo);
-    if (ip != NULL) {
-      return ip;
-    }
-  }
+	/* attempt to get the ip from a NAT device */
+	if ((controlInfo = gaim_upnp_discover()) != NULL) {
+		ip = gaim_upnp_get_public_ip(controlInfo);
+
+		g_free(controlInfo->controlURL);
+		g_free(controlInfo->serviceType);
+		g_free(controlInfo);
+
+		if (ip != NULL)
+		  return ip;
+	}
 
 	/* Just fetch the IP of the local system */
 	return gaim_network_get_local_system_ip(fd);
--- a/src/protocols/jabber/jabber.c	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/protocols/jabber/jabber.c	Tue Jan 03 00:23:24 2006 +0000
@@ -407,7 +407,7 @@
 		gaim_connection_error(js->gc, _("Unable to create socket"));
 }
 
-static void srv_resolved_cb(struct srv_response *resp, int results, gpointer data)
+static void srv_resolved_cb(GaimSrvResponse *resp, int results, gpointer data)
 {
 	JabberStream *js = (JabberStream*)data;
 	int config_port = gaim_account_get_int(js->gc->account, "port", 0);
--- a/src/protocols/simple/simple.c	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/protocols/simple/simple.c	Tue Jan 03 00:23:24 2006 +0000
@@ -1194,7 +1194,7 @@
 	return (gaim_utf8_strcasecmp(nick1, nick2) == 0);
 }
 
-static void srvresolved(struct srv_response *resp, int results, gpointer data) {
+static void srvresolved(GaimSrvResponse *resp, int results, gpointer data) {
 	struct simple_account_data *sip = (struct simple_account_data*) data;
 
 	gchar *hostname;
--- a/src/stun.c	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/stun.c	Tue Jan 03 00:23:24 2006 +0000
@@ -40,7 +40,24 @@
 #include "stun.h"
 #include "prefs.h"
 
-static struct stun_nattype nattype = {-1, 0, "\0"};
+struct stun_header {
+	short	type;
+	short	len;
+	int	transid[4];
+};
+
+struct stun_attrib {
+	short type;
+	short len;
+};
+
+struct stun_change {
+	struct stun_header hdr;
+	struct stun_attrib attrib;
+	char value[4];
+};
+
+static GaimStunNatDiscovery nattype = {-1, 0, "\0"};
 
 static GSList *callbacks = 0;
 static int fd = -1;
@@ -63,12 +80,14 @@
 
 static gboolean timeoutfunc(void *blah) {
 	if(retry > 2) {
-		if(test == 2) nattype.type = 5;
+		if(test == 2)
+			nattype.type = GAIM_STUN_NAT_TYPE_SYMMETRIC;
+
 		/* remove input */
 		gaim_input_remove(incb);
 
 		/* set unknown */
-		nattype.status = 0;
+		nattype.status = GAIM_STUN_STATUS_UNKNOWN;
 
 		/* callbacks */
 		do_callbacks();
@@ -131,8 +150,8 @@
 			tmp += sizeof(struct stun_attrib) + attrib->len;
 		}
 		gaim_debug_info("stun", "got public ip %s\n", nattype.publicip);
-		nattype.status = 2;
-		nattype.type = 1;
+		nattype.status = GAIM_STUN_STATUS_DISCOVERED;
+		nattype.type = GAIM_STUN_NAT_TYPE_UNKNOWN_NAT;
 
 		/* is it a NAT? */
 
@@ -152,7 +171,7 @@
 				if(sinptr->sin_addr.s_addr == in.s_addr) {
 					/* no NAT */
 					gaim_debug_info("stun", "no nat");
-					nattype.type = 0;
+					nattype.type = GAIM_STUN_NAT_TYPE_PUBLIC_IP;
 				}
 			}
 		}
@@ -166,7 +185,7 @@
 		do_callbacks();
 		gaim_input_remove(incb);
 		gaim_timeout_remove(timeout);
-		nattype.type = 2;
+		nattype.type = GAIM_STUN_NAT_TYPE_FULL_CONE;
 	}
 }
 
@@ -178,7 +197,7 @@
 	if(!hosts->data) return;
 
 	if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-		nattype.status = 0;
+		nattype.status = GAIM_STUN_STATUS_UNKNOWN;
 		do_callbacks();
 		return;
 	}
@@ -190,7 +209,7 @@
 		addr.sin_port = htons(ntohs(addr.sin_port)+1);
 	}
 	if( ret < 0 ) {
-		nattype.status = 0;
+		nattype.status = GAIM_STUN_STATUS_UNKNOWN;
 		do_callbacks();
 		return;
 	}
@@ -214,8 +233,8 @@
 	data.transid[2] = rand();
 	data.transid[3] = rand();
 
-	if( sendto(fd, &data, sizeof(struct stun_header), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < sizeof(struct stun_header)) {
-		nattype.status = 0;
+	if(sendto(fd, &data, sizeof(struct stun_header), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < sizeof(struct stun_header)) {
+		nattype.status = GAIM_STUN_STATUS_UNKNOWN;
 		do_callbacks();
 		return;
 	}
@@ -225,7 +244,7 @@
 	timeout = gaim_timeout_add(500, (GSourceFunc)timeoutfunc, NULL);
 }
 
-static void do_test1(struct srv_response *resp, int results, gpointer sdata) {
+static void do_test1(GaimSrvResponse *resp, int results, gpointer sdata) {
 	const char *servername = sdata;
 	int port = 3478;
 
@@ -239,26 +258,31 @@
 	g_free(resp);
 }
 
-struct stun_nattype *gaim_stun_discover(StunCallback cb) {
+GaimStunNatDiscovery *gaim_stun_discover(StunCallback cb) {
 	const char *servername = gaim_prefs_get_string("/core/network/stun_server");
 
 	gaim_debug_info("stun", "using server %s\n", servername);
-	if(nattype.status == 1) { /* currently discovering */
-		if(cb) callbacks = g_slist_append(callbacks, cb);
+
+	if(nattype.status == GAIM_STUN_STATUS_DISCOVERING) {
+		if(cb)
+			callbacks = g_slist_append(callbacks, cb);
 		return NULL;
 	}
-	if(nattype.status != -1) { /* already discovered */
-		if(cb) cb(&nattype);
+
+	if(nattype.status != GAIM_STUN_STATUS_UNDISCOVERED) {
+		if(cb)
+			cb(&nattype);
 		return &nattype;
 	}
 
-	if(!servername || (strlen(servername)<2)) {
-		nattype.status = 0;
-		if(cb) cb(&nattype);
+	if(!servername || (strlen(servername) < 2)) {
+		nattype.status = GAIM_STUN_STATUS_UNKNOWN;
+		if(cb)
+			cb(&nattype);
 		return &nattype;
 	}
 	callbacks = g_slist_append(callbacks, cb);
-	gaim_srv_resolve("stun","udp",servername, do_test1,
+	gaim_srv_resolve("stun", "udp", servername, do_test1,
 		(gpointer) servername);
 	return &nattype;
 }
--- a/src/stun.h	Mon Jan 02 23:07:46 2006 +0000
+++ b/src/stun.h	Tue Jan 03 00:23:24 2006 +0000
@@ -30,55 +30,48 @@
 /**************************************************************************/
 /*@{*/
 
-struct stun_nattype {
-	gint status;	/* 0 - unknown (no STUN server reachable) */
-			/* 1 - discovering                        */
-			/* 2 - discovered                         */
+typedef struct _GaimStunNatDiscovery GaimStunNatDiscovery;
+
+typedef enum {
+	GAIM_STUN_STATUS_UNDISCOVERED = -1,
+	GAIM_STUN_STATUS_UNKNOWN, /* no STUN server reachable */
+	GAIM_STUN_STATUS_DISCOVERING,
+	GAIM_STUN_STATUS_DISCOVERED
+} GaimStunStatus;
 
-	gint type;	/* 0 - public ip                          */
-			/* 1 - NAT (unknown type)                 */
-			/* 2 - full cone                          */
-			/* 3 - restricted cone                    */
-			/* 4 - port restricted cone               */
-			/* 5 - symmetric                          */
+typedef enum {
+	GAIM_STUN_NAT_TYPE_PUBLIC_IP,
+	GAIM_STUN_NAT_TYPE_UNKNOWN_NAT,
+	GAIM_STUN_NAT_TYPE_FULL_CONE,
+	GAIM_STUN_NAT_TYPE_RESTRICTED_CONE,
+	GAIM_STUN_NAT_TYPE_PORT_RESTRICTED_CONE,
+	GAIM_STUN_NAT_TYPE_SYMMETRIC
+} GaimStunNatType;
 
+struct _GaimStunNatDiscovery {
+	GaimStunStatus status;
+	GaimStunNatType type;
 	char publicip[16];
 };
 
-struct stun_header {
-	short	type;
-	short	len;
-	int	transid[4];
-};
-
-struct stun_attrib {
-	short type;
-	short len;
-};
-
-struct stun_change {
-	struct stun_header hdr;
-	struct stun_attrib attrib;
-	char value[4];
-};
-
-typedef void (*StunCallback) (struct stun_nattype *);
+typedef void (*StunCallback) (GaimStunNatDiscovery *);
 
 /**
- * Starts a NAT discovery. It returns a struct stun_nattype if the discovery
+ * Starts a NAT discovery. It returns a GaimStunNatDiscovery if the discovery
  * is already done. Otherwise the callback is called when the discovery is over
  * and NULL is returned.
  *
- * @param cb A callback
+ * @param cb The callback to call when the STUN discovery is finished if the
+ *           discovery would block.  If the discovery is done, this is NOT
+ *           called.
  *
- * @return a struct stun_nattype which includes the public IP and the type
+ * @return a GaimStunNatDiscovery which includes the public IP and the type
  *         of NAT or NULL is discovery would block
  */
-struct stun_nattype *gaim_stun_discover(StunCallback cb);
+GaimStunNatDiscovery *gaim_stun_discover(StunCallback cb);
 
 void gaim_stun_init(void);
 
 /*@}*/
 
 #endif /* _GAIM_STUN_H_ */
-