# HG changeset patch # User Sadrul Habib Chowdhury # Date 1175399270 0 # Node ID 499ed587543a9f21f3688beb21129692418cf5e1 # Parent 5eb0621e0760fd54ba18ec603878a1728db6cae4# Parent a6a79b8616bfe9dc7683ff2a7a2640718db3157d merge of 'e23bc35af900cf0925d85813b5896e19f73645d2' and 'ed972b3dfab31a2b23f4b191bfe7d4dcab7cc765' diff -r 5eb0621e0760 -r 499ed587543a ChangeLog.API --- a/ChangeLog.API Sun Apr 01 03:46:58 2007 +0000 +++ b/ChangeLog.API Sun Apr 01 03:47:50 2007 +0000 @@ -416,6 +416,7 @@ * "gtkblist-hiding" * "gtkblist-unhiding" * "log-displaying" + * "network-configuration-changed" * "savedstatus-changed" * "sendto-extended-menu" * "uri-handler" diff -r 5eb0621e0760 -r 499ed587543a libpurple/Makefile.am --- a/libpurple/Makefile.am Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/Makefile.am Sun Apr 01 03:47:50 2007 +0000 @@ -49,6 +49,7 @@ imgstore.c \ log.c \ mime.c \ + nat-pmp.c \ network.c \ ntlm.c \ notify.c \ @@ -99,6 +100,7 @@ imgstore.h \ log.h \ mime.h \ + nat-pmp.h \ network.h \ notify.h \ ntlm.h \ diff -r 5eb0621e0760 -r 499ed587543a libpurple/Makefile.mingw --- a/libpurple/Makefile.mingw Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/Makefile.mingw Sun Apr 01 03:47:50 2007 +0000 @@ -48,6 +48,7 @@ imgstore.c \ log.c \ mime.c \ + nat-pmp.c \ network.c \ notify.c \ ntlm.c \ diff -r 5eb0621e0760 -r 499ed587543a libpurple/nat-pmp.c --- a/libpurple/nat-pmp.c Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/nat-pmp.c Sun Apr 01 03:47:50 2007 +0000 @@ -30,24 +30,28 @@ #include "nat-pmp.h" #include "debug.h" +#include "signals.h" +#include "network.h" +#include +#ifndef _WIN32 #include #include -#include #include #include +#include #include #include +#include +#endif + #include #include #include -#include #include -#include -#include #ifdef NET_RT_DUMP @@ -87,6 +91,20 @@ typedef struct _PurplePmpMapResponse PurplePmpMapResponse; +typedef enum { + PURPLE_PMP_STATUS_UNDISCOVERED = -1, + PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER, + PURPLE_PMP_STATUS_DISCOVERING, + PURPLE_PMP_STATUS_DISCOVERED +} PurpleUPnPStatus; + +typedef struct { + PurpleUPnPStatus status; + gchar *publicip; +} PurplePmpInfo; + +static PurplePmpInfo pmp_info = {PURPLE_PMP_STATUS_UNDISCOVERED, NULL}; + /* * Thanks to R. Matthew Emerson for the fixes on this */ @@ -240,11 +258,32 @@ char * purple_pmp_get_public_ip() { - struct sockaddr_in *gateway = default_gw(); + struct sockaddr_in addr, *gateway, *publicsockaddr = NULL; + struct timeval req_timeout; + socklen_t len; + + PurplePmpIpRequest req; + PurplePmpIpResponse resp; + int sendfd; + + if (pmp_info.status == PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER) + return NULL; + + if ((pmp_info.status == PURPLE_PMP_STATUS_DISCOVERED) && (pmp_info.publicip != NULL)) + { +#ifdef PMP_DEBUG + purple_debug_info("nat-pmp", "Returning cached publicip %s",pmp_info.publicip); +#endif + return pmp_info.publicip; + } + + gateway = default_gw(); if (!gateway) { purple_debug_info("nat-pmp", "Cannot request public IP from a NULL gateway!\n"); + /* If we get a NULL gateway, don't try again next time */ + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } @@ -252,12 +291,6 @@ if (gateway->sin_port != PMP_PORT) gateway->sin_port = htons(PMP_PORT); - int sendfd; - struct timeval req_timeout; - PurplePmpIpRequest req; - PurplePmpIpResponse resp; - struct sockaddr_in *publicsockaddr = NULL; - req_timeout.tv_sec = 0; req_timeout.tv_usec = PMP_TIMEOUT; @@ -274,20 +307,19 @@ * With the recommended timeout of 0.25 seconds, we're talking 511.5 seconds (8.5 minutes). * * This seems really silly... if this were nonblocking, a couple retries might be in order, but it's not at present. - * XXX Make this nonblocking. */ #ifdef PMP_DEBUG purple_debug_info("nat-pmp", "Attempting to retrieve the public ip address for the NAT device at: %s\n", inet_ntoa(gateway->sin_addr)); purple_debug_info("nat-pmp", "\tTimeout: %ds %dus\n", req_timeout.tv_sec, req_timeout.tv_usec); #endif - struct sockaddr_in addr; - socklen_t len = sizeof(struct sockaddr_in); /* TODO: Non-blocking! */ + if (sendto(sendfd, &req, sizeof(req), 0, (struct sockaddr *)(gateway), sizeof(struct sockaddr)) < 0) { purple_debug_info("nat-pmp", "There was an error sending the NAT-PMP public IP request! (%s)\n", strerror(errno)); g_free(gateway); + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } @@ -295,16 +327,19 @@ { purple_debug_info("nat-pmp", "There was an error setting the socket's options! (%s)\n", strerror(errno)); g_free(gateway); + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } /* TODO: Non-blocking! */ + len = sizeof(struct sockaddr_in); if (recvfrom(sendfd, &resp, sizeof(PurplePmpIpResponse), 0, (struct sockaddr *)(&addr), &len) < 0) { if (errno != EAGAIN) { purple_debug_info("nat-pmp", "There was an error receiving the response from the NAT-PMP device! (%s)\n", strerror(errno)); g_free(gateway); + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } } @@ -315,11 +350,15 @@ { purple_debug_info("nat-pmp", "Response was not received from our gateway! Instead from: %s\n", inet_ntoa(addr.sin_addr)); g_free(gateway); + + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } if (!publicsockaddr) { g_free(gateway); + + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } @@ -338,6 +377,10 @@ g_free(gateway); + g_free(pmp_info.publicip); + pmp_info.publicip = g_strdup(inet_ntoa(publicsockaddr->sin_addr)); + pmp_info.status = PURPLE_PMP_STATUS_DISCOVERED; + return inet_ntoa(publicsockaddr->sin_addr); } @@ -458,6 +501,30 @@ return success; } + +static void +purple_pmp_network_config_changed_cb(void *data) +{ + pmp_info.status = PURPLE_PMP_STATUS_UNDISCOVERED; + g_free(pmp_info.publicip); + pmp_info.publicip = NULL; +} + +static void* +purple_pmp_get_handle(void) +{ + static int handle; + + return &handle; +} + +void +purple_pmp_init() +{ + purple_signal_connect(purple_network_get_handle(), "network-configuration-changed", + purple_pmp_get_handle(), PURPLE_CALLBACK(purple_pmp_network_config_changed_cb), + GINT_TO_POINTER(0)); +} #else /* #ifdef NET_RT_DUMP */ char * purple_pmp_get_public_ip() @@ -476,4 +543,10 @@ { return FALSE; } + +void +purple_pmp_init() +{ + +} #endif /* #ifndef NET_RT_DUMP */ diff -r 5eb0621e0760 -r 499ed587543a libpurple/nat-pmp.h --- a/libpurple/nat-pmp.h Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/nat-pmp.h Sun Apr 01 03:47:50 2007 +0000 @@ -36,27 +36,20 @@ #define PURPLE_PMP_LIFETIME 3600 /* 3600 seconds */ -/* - * uint8_t: version, opcodes - * uint16_t: resultcode - * unint32_t: epoch (seconds since mappings reset) - */ - typedef enum { PURPLE_PMP_TYPE_UDP, PURPLE_PMP_TYPE_TCP } PurplePmpType; /** + * Initialize nat-pmp + */ +void purple_pmp_init(void); + +/** * */ - -/* - * TODO: This should probably cache the result of this lookup requests - * so that subsequent calls to this function do not require a - * round-trip exchange with the local router. - */ -char *purple_pmp_get_public_ip(); +char *purple_pmp_get_public_ip(void); /** * Remove the NAT-PMP mapping for a specified type on a specified port @@ -79,5 +72,6 @@ * @returns TRUE if succesful; FALSE if unsuccessful */ gboolean purple_pmp_destroy_map(PurplePmpType type, unsigned short privateport); - -#endif \ No newline at end of file + +#endif + diff -r 5eb0621e0760 -r 499ed587543a libpurple/network.c --- a/libpurple/network.c Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/network.c Sun Apr 01 03:47:50 2007 +0000 @@ -42,17 +42,12 @@ #include "debug.h" #include "account.h" +#include "nat-pmp.h" #include "network.h" #include "prefs.h" #include "stun.h" #include "upnp.h" -/* #define ENABLE_NAT_PMP 1 */ - -#ifdef ENABLE_NAT_PMP -#include "nat-pmp.h" -#endif - /* * Calling sizeof(struct ifreq) isn't always correct on * Mac OS X (and maybe others). @@ -198,12 +193,10 @@ if (ip != NULL) return ip; -#ifdef ENABLE_NAT_PMP /* Attempt to get the IP from a NAT device using NAT-PMP */ ip = purple_pmp_get_public_ip(); if (ip != NULL) return ip; -#endif /* Just fetch the IP of the local system */ return purple_network_get_local_system_ip(fd); @@ -250,7 +243,6 @@ purple_network_listen_cancel(listen_data); } -#ifdef ENABLE_NAT_PMP static gboolean purple_network_finish_pmp_map_cb(gpointer data) { @@ -265,7 +257,6 @@ return FALSE; } -#endif static PurpleNetworkListenData * purple_network_do_listen(unsigned short port, int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data) @@ -361,7 +352,6 @@ listen_data->cb = cb; listen_data->cb_data = cb_data; -#ifdef ENABLE_NAT_PMP /* Attempt a NAT-PMP Mapping, which will return immediately */ if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP), actual_port, actual_port, PURPLE_PMP_LIFETIME)) @@ -371,7 +361,6 @@ purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data); } else -#endif { /* Attempt a UPnP Mapping */ listen_data->mapping_data = purple_upnp_set_port_mapping( @@ -508,6 +497,8 @@ purple_debug_info("network", "Received Network Change Notification. Current network count is %d, previous count was %d.\n", new_count, current_network_count); + purple_signal_emit(purple_network_get_handle(), "network-configuration-changed", NULL); + if (new_count > 0 && ui_ops != NULL && ui_ops->network_connected != NULL) { ui_ops->network_connected(); } else if (new_count == 0 && current_network_count > 0 && @@ -616,6 +607,8 @@ current = libnm_glib_get_network_state(ctx); purple_debug_info("network","Entering nm_callback_func!\n"); + purple_signal_emit(purple_network_get_handle(), "network-configuration-changed", NULL); + switch(current) { case LIBNM_ACTIVE_NETWORK_CONNECTION: @@ -641,6 +634,14 @@ } #endif +void * +purple_network_get_handle(void) +{ + static int handle; + + return &handle; +} + void purple_network_init(void) { @@ -673,6 +674,12 @@ if(nm_context) nm_callback_idx = libnm_glib_register_callback(nm_context, nm_callback_func, NULL, g_main_context_default()); #endif + + purple_signal_register(purple_network_get_handle(), "network-configuration-changed", + purple_marshal_VOID, NULL, 0); + + purple_pmp_init(); + purple_upnp_init(); } void diff -r 5eb0621e0760 -r 499ed587543a libpurple/network.h --- a/libpurple/network.h Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/network.h Sun Apr 01 03:47:50 2007 +0000 @@ -197,6 +197,13 @@ gboolean purple_network_is_available(void); /** + * Get the handle for the network system + * + * @return the handle to the network system + */ +void *purple_network_get_handle(void); + +/** * Initializes the network subsystem. */ void purple_network_init(void); diff -r 5eb0621e0760 -r 499ed587543a libpurple/protocols/silc/util.c --- a/libpurple/protocols/silc/util.c Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/protocols/silc/util.c Sun Apr 01 03:47:50 2007 +0000 @@ -444,8 +444,6 @@ strcat(buf, "[private] "); if (mode & SILC_CHANNEL_MODE_SECRET) strcat(buf, "[secret] "); - if (mode & SILC_CHANNEL_MODE_SECRET) - strcat(buf, "[secret] "); if (mode & SILC_CHANNEL_MODE_PRIVKEY) strcat(buf, "[private key] "); if (mode & SILC_CHANNEL_MODE_INVITE) diff -r 5eb0621e0760 -r 499ed587543a libpurple/proxy.c --- a/libpurple/proxy.c Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/proxy.c Sun Apr 01 03:47:50 2007 +0000 @@ -87,6 +87,12 @@ static void try_connect(PurpleProxyConnectData *connect_data); +/* + * TODO: Eventually (GObjectification) this bad boy will be removed, because it is + * a gross fix for a crashy problem. + */ +#define PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data) g_slist_find(handles, connect_data) + /************************************************************************** * Proxy structure API **************************************************************************/ @@ -389,6 +395,12 @@ int error = 0; int ret; + /* If the socket-connected message had already been triggered when connect_data + * was destroyed via purple_proxy_connect_cancel(), we may get here with a freed connect_data. + */ + if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) + return; + purple_debug_info("proxy", "Connected to %s:%d.\n", connect_data->host, connect_data->port); diff -r 5eb0621e0760 -r 499ed587543a libpurple/upnp.c --- a/libpurple/upnp.c Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/upnp.c Sun Apr 01 03:47:50 2007 +0000 @@ -24,14 +24,15 @@ */ #include "internal.h" -#include "debug.h" -#include "util.h" -#include "proxy.h" -#include "xmlnode.h" -#include "network.h" -#include "eventloop.h" #include "upnp.h" +#include "debug.h" +#include "eventloop.h" +#include "network.h" +#include "proxy.h" +#include "signals.h" +#include "util.h" +#include "xmlnode.h" /*************************************************************** ** General Defines * @@ -1026,3 +1027,32 @@ do_port_mapping_cb(TRUE, ar); return ar; } + +static void +purple_upnp_network_config_changed_cb(void *data) +{ + /* Reset the control_info to default values */ + control_info.status = PURPLE_UPNP_STATUS_UNDISCOVERED; + g_free(control_info.control_url); + control_info.control_url = NULL; + control_info.service_type[0] = '\0'; + control_info.publicip[0] = '\0'; + control_info.internalip[0] = '\0'; + control_info.lookup_time = 0; +} + +static void* +purple_upnp_get_handle(void) +{ + static int handle; + + return &handle; +} + +void +purple_upnp_init() +{ + purple_signal_connect(purple_network_get_handle(), "network-configuration-changed", + purple_upnp_get_handle(), PURPLE_CALLBACK(purple_upnp_network_config_changed_cb), + GINT_TO_POINTER(0)); +} diff -r 5eb0621e0760 -r 499ed587543a libpurple/upnp.h --- a/libpurple/upnp.h Sun Apr 01 03:46:58 2007 +0000 +++ b/libpurple/upnp.h Sun Apr 01 03:47:50 2007 +0000 @@ -41,6 +41,13 @@ typedef void (*PurpleUPnPCallback) (gboolean success, gpointer data); + +/** + * Initialize UPnP + */ +void purple_upnp_init(void); + + /** * Sends a discovery request to search for a UPnP enabled IGD that * contains the WANIPConnection service that will allow us to recieve the