# HG changeset patch # User Richard Laager # Date 1136247804 0 # Node ID 5f65a0cca87c211e5f3cdb4209749049a1910ff5 # Parent e9f279f0ef02bf4cac08df5c14fd521434cadc7d [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 diff -r e9f279f0ef02 -r 5f65a0cca87c src/dnssrv.c --- 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 diff -r e9f279f0ef02 -r 5f65a0cca87c src/dnssrv.h --- 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 */ diff -r e9f279f0ef02 -r 5f65a0cca87c src/network.c --- 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); diff -r e9f279f0ef02 -r 5f65a0cca87c src/protocols/jabber/jabber.c --- 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); diff -r e9f279f0ef02 -r 5f65a0cca87c src/protocols/simple/simple.c --- 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; diff -r e9f279f0ef02 -r 5f65a0cca87c src/stun.c --- 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; } diff -r e9f279f0ef02 -r 5f65a0cca87c src/stun.h --- 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_ */ -