comparison libpurple/network.c @ 15974:1a12ce76c4f4

The network module now registers the signal 'network-configuration-changed' and emits it when a network change is detected via libnm or the win32 network monitor. The UI could also emit this signal if it knows something network.c doesn't. UPnP and NAT-PMP respond to the signal by clearing their IP address caches; changing networks without quitting/relaunching will now lead to the new IP address being (lazily) determined. This commit also enables nat-pmp and adds nat-pmp.[h|c] to the build process; please let me know if there are any problems building, as I only have OS X test machines.
author Evan Schoenberg <evan.s@dreskin.net>
date Sat, 31 Mar 2007 20:33:54 +0000
parents b4ab4812838a
children 4999bbc52881
comparison
equal deleted inserted replaced
15973:71fddbec98e4 15974:1a12ce76c4f4
40 #include <sys/sockio.h> 40 #include <sys/sockio.h>
41 #endif 41 #endif
42 42
43 #include "debug.h" 43 #include "debug.h"
44 #include "account.h" 44 #include "account.h"
45 #include "nat-pmp.h"
45 #include "network.h" 46 #include "network.h"
46 #include "prefs.h" 47 #include "prefs.h"
47 #include "stun.h" 48 #include "stun.h"
48 #include "upnp.h" 49 #include "upnp.h"
49
50 /* #define ENABLE_NAT_PMP 1 */
51
52 #ifdef ENABLE_NAT_PMP
53 #include "nat-pmp.h"
54 #endif
55 50
56 /* 51 /*
57 * Calling sizeof(struct ifreq) isn't always correct on 52 * Calling sizeof(struct ifreq) isn't always correct on
58 * Mac OS X (and maybe others). 53 * Mac OS X (and maybe others).
59 */ 54 */
196 /* Attempt to get the IP from a NAT device using UPnP */ 191 /* Attempt to get the IP from a NAT device using UPnP */
197 ip = purple_upnp_get_public_ip(); 192 ip = purple_upnp_get_public_ip();
198 if (ip != NULL) 193 if (ip != NULL)
199 return ip; 194 return ip;
200 195
201 #ifdef ENABLE_NAT_PMP
202 /* Attempt to get the IP from a NAT device using NAT-PMP */ 196 /* Attempt to get the IP from a NAT device using NAT-PMP */
203 ip = purple_pmp_get_public_ip(); 197 ip = purple_pmp_get_public_ip();
204 if (ip != NULL) 198 if (ip != NULL)
205 return ip; 199 return ip;
206 #endif
207 200
208 /* Just fetch the IP of the local system */ 201 /* Just fetch the IP of the local system */
209 return purple_network_get_local_system_ip(fd); 202 return purple_network_get_local_system_ip(fd);
210 } 203 }
211 204
248 * it otherwise. */ 241 * it otherwise. */
249 listen_data->mapping_data = NULL; 242 listen_data->mapping_data = NULL;
250 purple_network_listen_cancel(listen_data); 243 purple_network_listen_cancel(listen_data);
251 } 244 }
252 245
253 #ifdef ENABLE_NAT_PMP
254 static gboolean 246 static gboolean
255 purple_network_finish_pmp_map_cb(gpointer data) 247 purple_network_finish_pmp_map_cb(gpointer data)
256 { 248 {
257 PurpleNetworkListenData *listen_data; 249 PurpleNetworkListenData *listen_data;
258 250
263 255
264 purple_network_listen_cancel(listen_data); 256 purple_network_listen_cancel(listen_data);
265 257
266 return FALSE; 258 return FALSE;
267 } 259 }
268 #endif
269 260
270 static PurpleNetworkListenData * 261 static PurpleNetworkListenData *
271 purple_network_do_listen(unsigned short port, int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data) 262 purple_network_do_listen(unsigned short port, int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data)
272 { 263 {
273 int listenfd = -1; 264 int listenfd = -1;
359 listen_data->adding = TRUE; 350 listen_data->adding = TRUE;
360 listen_data->retry = TRUE; 351 listen_data->retry = TRUE;
361 listen_data->cb = cb; 352 listen_data->cb = cb;
362 listen_data->cb_data = cb_data; 353 listen_data->cb_data = cb_data;
363 354
364 #ifdef ENABLE_NAT_PMP
365 /* Attempt a NAT-PMP Mapping, which will return immediately */ 355 /* Attempt a NAT-PMP Mapping, which will return immediately */
366 if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP), 356 if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
367 actual_port, actual_port, PURPLE_PMP_LIFETIME)) 357 actual_port, actual_port, PURPLE_PMP_LIFETIME))
368 { 358 {
369 purple_debug_info("network", "Created NAT-PMP mapping on port %i",actual_port); 359 purple_debug_info("network", "Created NAT-PMP mapping on port %i",actual_port);
370 /* We want to return listen_data now, and on the next run loop trigger the cb and destroy listen_data */ 360 /* We want to return listen_data now, and on the next run loop trigger the cb and destroy listen_data */
371 purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data); 361 purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
372 } 362 }
373 else 363 else
374 #endif
375 { 364 {
376 /* Attempt a UPnP Mapping */ 365 /* Attempt a UPnP Mapping */
377 listen_data->mapping_data = purple_upnp_set_port_mapping( 366 listen_data->mapping_data = purple_upnp_set_port_mapping(
378 actual_port, 367 actual_port,
379 (socket_type == SOCK_STREAM) ? "TCP" : "UDP", 368 (socket_type == SOCK_STREAM) ? "TCP" : "UDP",
505 494
506 if (new_count < 0) 495 if (new_count < 0)
507 return FALSE; 496 return FALSE;
508 497
509 purple_debug_info("network", "Received Network Change Notification. Current network count is %d, previous count was %d.\n", new_count, current_network_count); 498 purple_debug_info("network", "Received Network Change Notification. Current network count is %d, previous count was %d.\n", new_count, current_network_count);
499
500 purple_signal_emit(purple_network_get_handle(), "network-configuration-changed", NULL);
510 501
511 if (new_count > 0 && ui_ops != NULL && ui_ops->network_connected != NULL) { 502 if (new_count > 0 && ui_ops != NULL && ui_ops->network_connected != NULL) {
512 ui_ops->network_connected(); 503 ui_ops->network_connected();
513 } else if (new_count == 0 && current_network_count > 0 && 504 } else if (new_count == 0 && current_network_count > 0 &&
514 ui_ops != NULL && ui_ops->network_disconnected != NULL) { 505 ui_ops != NULL && ui_ops->network_disconnected != NULL) {
613 libnm_glib_state current; 604 libnm_glib_state current;
614 PurpleConnectionUiOps *ui_ops = purple_connections_get_ui_ops(); 605 PurpleConnectionUiOps *ui_ops = purple_connections_get_ui_ops();
615 606
616 current = libnm_glib_get_network_state(ctx); 607 current = libnm_glib_get_network_state(ctx);
617 purple_debug_info("network","Entering nm_callback_func!\n"); 608 purple_debug_info("network","Entering nm_callback_func!\n");
609
610 purple_signal_emit(purple_network_get_handle(), "network-configuration-changed", NULL);
618 611
619 switch(current) 612 switch(current)
620 { 613 {
621 case LIBNM_ACTIVE_NETWORK_CONNECTION: 614 case LIBNM_ACTIVE_NETWORK_CONNECTION:
622 /* Call res_init in case DNS servers have changed */ 615 /* Call res_init in case DNS servers have changed */
639 break; 632 break;
640 } 633 }
641 } 634 }
642 #endif 635 #endif
643 636
637 void *
638 purple_network_get_handle(void)
639 {
640 static int handle;
641
642 return &handle;
643 }
644
644 void 645 void
645 purple_network_init(void) 646 purple_network_init(void)
646 { 647 {
647 #ifdef _WIN32 648 #ifdef _WIN32
648 GError *err = NULL; 649 GError *err = NULL;
671 #ifdef HAVE_LIBNM 672 #ifdef HAVE_LIBNM
672 nm_context = libnm_glib_init(); 673 nm_context = libnm_glib_init();
673 if(nm_context) 674 if(nm_context)
674 nm_callback_idx = libnm_glib_register_callback(nm_context, nm_callback_func, NULL, g_main_context_default()); 675 nm_callback_idx = libnm_glib_register_callback(nm_context, nm_callback_func, NULL, g_main_context_default());
675 #endif 676 #endif
677
678 purple_signal_register(purple_network_get_handle(), "network-configuration-changed",
679 purple_marshal_VOID, NULL, 0);
680
681 purple_pmp_init();
682 purple_upnp_init();
676 } 683 }
677 684
678 void 685 void
679 purple_network_uninit(void) 686 purple_network_uninit(void)
680 { 687 {