Mercurial > pidgin
comparison libpurple/network.c @ 27590:a08e84032814
merge of '2348ff22f0ff3453774b8b25b36238465580c609'
and 'e76f11543c2a4aa05bdf584f087cbe3439029661'
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 12 Jul 2009 05:43:38 +0000 |
parents | 627d23bfdb05 |
children | 7fbf964c6c6c |
comparison
equal
deleted
inserted
replaced
27104:048bcf41deef | 27590:a08e84032814 |
---|---|
103 | 103 |
104 /* Cached IP addresses for STUN and TURN servers (set globally in prefs) */ | 104 /* Cached IP addresses for STUN and TURN servers (set globally in prefs) */ |
105 static gchar *stun_ip = NULL; | 105 static gchar *stun_ip = NULL; |
106 static gchar *turn_ip = NULL; | 106 static gchar *turn_ip = NULL; |
107 | 107 |
108 /* Keep track of port mappings done with UPnP and NAT-PMP */ | |
109 static GHashTable *upnp_port_mappings = NULL; | |
110 static GHashTable *nat_pmp_port_mappings = NULL; | |
111 | |
108 const unsigned char * | 112 const unsigned char * |
109 purple_network_ip_atoi(const char *ip) | 113 purple_network_ip_atoi(const char *ip) |
110 { | 114 { |
111 static unsigned char ret[4]; | 115 static unsigned char ret[4]; |
112 gchar *delimiter = "."; | 116 gchar *delimiter = "."; |
234 listen_data = data; | 238 listen_data = data; |
235 /* TODO: Once we're keeping track of upnp requests... */ | 239 /* TODO: Once we're keeping track of upnp requests... */ |
236 /* listen_data->pnp_data = NULL; */ | 240 /* listen_data->pnp_data = NULL; */ |
237 | 241 |
238 if (!success) { | 242 if (!success) { |
239 purple_debug_info("network", "Couldn't create UPnP mapping\n"); | 243 purple_debug_warning("network", "Couldn't create UPnP mapping\n"); |
240 if (listen_data->retry) { | 244 if (listen_data->retry) { |
241 listen_data->retry = FALSE; | 245 listen_data->retry = FALSE; |
242 listen_data->adding = FALSE; | 246 listen_data->adding = FALSE; |
243 listen_data->mapping_data = purple_upnp_remove_port_mapping( | 247 listen_data->mapping_data = purple_upnp_remove_port_mapping( |
244 purple_network_get_port_from_fd(listen_data->listenfd), | 248 purple_network_get_port_from_fd(listen_data->listenfd), |
255 (listen_data->socket_type == SOCK_STREAM) ? "TCP" : "UDP", | 259 (listen_data->socket_type == SOCK_STREAM) ? "TCP" : "UDP", |
256 purple_network_set_upnp_port_mapping_cb, listen_data); | 260 purple_network_set_upnp_port_mapping_cb, listen_data); |
257 return; | 261 return; |
258 } | 262 } |
259 | 263 |
264 if (success) { | |
265 /* add port mapping to hash table */ | |
266 gint *key = g_new(gint, 1); | |
267 gint *value = g_new(gint, 1); | |
268 *key = purple_network_get_port_from_fd(listen_data->listenfd); | |
269 *value = listen_data->socket_type; | |
270 g_hash_table_insert(upnp_port_mappings, key, value); | |
271 } | |
272 | |
260 if (listen_data->cb) | 273 if (listen_data->cb) |
261 listen_data->cb(listen_data->listenfd, listen_data->cb_data); | 274 listen_data->cb(listen_data->listenfd, listen_data->cb_data); |
262 | 275 |
263 /* Clear the UPnP mapping data, since it's complete and purple_netweork_listen_cancel() will try to cancel | 276 /* Clear the UPnP mapping data, since it's complete and purple_netweork_listen_cancel() will try to cancel |
264 * it otherwise. */ | 277 * it otherwise. */ |
268 | 281 |
269 static gboolean | 282 static gboolean |
270 purple_network_finish_pmp_map_cb(gpointer data) | 283 purple_network_finish_pmp_map_cb(gpointer data) |
271 { | 284 { |
272 PurpleNetworkListenData *listen_data; | 285 PurpleNetworkListenData *listen_data; |
286 gint *key = g_new(gint, 1); | |
287 gint *value = g_new(gint, 1); | |
273 | 288 |
274 listen_data = data; | 289 listen_data = data; |
290 | |
291 /* add port mapping to hash table */ | |
292 *key = purple_network_get_port_from_fd(listen_data->listenfd); | |
293 *value = listen_data->socket_type; | |
294 g_hash_table_insert(nat_pmp_port_mappings, key, value); | |
275 | 295 |
276 if (listen_data->cb) | 296 if (listen_data->cb) |
277 listen_data->cb(listen_data->listenfd, listen_data->cb_data); | 297 listen_data->cb(listen_data->listenfd, listen_data->cb_data); |
278 | 298 |
279 purple_network_listen_cancel(listen_data); | 299 purple_network_listen_cancel(listen_data); |
890 static int handle; | 910 static int handle; |
891 | 911 |
892 return &handle; | 912 return &handle; |
893 } | 913 } |
894 | 914 |
915 static void | |
916 purple_network_upnp_mapping_remove_cb(gboolean sucess, gpointer data) | |
917 { | |
918 purple_debug_info("network", "done removing UPnP port mapping\n"); | |
919 } | |
920 | |
921 /* the reason for these functions to have these signatures is to be able to | |
922 use them for g_hash_table_foreach to clean remaining port mappings, which is | |
923 not yet done */ | |
924 static void | |
925 purple_network_upnp_mapping_remove(gpointer key, gpointer value, | |
926 gpointer user_data) | |
927 { | |
928 gint port = (gint) *((gint *) key); | |
929 gint protocol = (gint) *((gint *) value); | |
930 purple_debug_info("network", "removing UPnP port mapping for port %d\n", | |
931 port); | |
932 purple_upnp_remove_port_mapping(port, | |
933 protocol == SOCK_STREAM ? "TCP" : "UDP", | |
934 purple_network_upnp_mapping_remove_cb, NULL); | |
935 g_hash_table_remove(upnp_port_mappings, key); | |
936 } | |
937 | |
938 static void | |
939 purple_network_nat_pmp_mapping_remove(gpointer key, gpointer value, | |
940 gpointer user_data) | |
941 { | |
942 gint port = (gint) *((gint *) key); | |
943 gint protocol = (gint) *((gint *) value); | |
944 purple_debug_info("network", "removing NAT-PMP port mapping for port %d\n", | |
945 port); | |
946 purple_pmp_destroy_map( | |
947 protocol == SOCK_STREAM ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP, | |
948 port); | |
949 g_hash_table_remove(nat_pmp_port_mappings, key); | |
950 } | |
951 | |
952 void | |
953 purple_network_remove_port_mapping(gint fd) | |
954 { | |
955 int port = purple_network_get_port_from_fd(fd); | |
956 gint *protocol = g_hash_table_lookup(upnp_port_mappings, &port); | |
957 | |
958 if (protocol) { | |
959 purple_network_upnp_mapping_remove(&port, protocol, NULL); | |
960 g_hash_table_remove(upnp_port_mappings, protocol); | |
961 } else { | |
962 protocol = g_hash_table_lookup(nat_pmp_port_mappings, &port); | |
963 if (protocol) { | |
964 purple_network_nat_pmp_mapping_remove(&port, protocol, NULL); | |
965 g_hash_table_remove(nat_pmp_port_mappings, protocol); | |
966 } | |
967 } | |
968 } | |
969 | |
895 void | 970 void |
896 purple_network_init(void) | 971 purple_network_init(void) |
897 { | 972 { |
898 #ifdef HAVE_NETWORKMANAGER | 973 #ifdef HAVE_NETWORKMANAGER |
899 GError *error = NULL; | 974 GError *error = NULL; |
962 | 1037 |
963 purple_network_set_stun_server( | 1038 purple_network_set_stun_server( |
964 purple_prefs_get_string("/purple/network/stun_server")); | 1039 purple_prefs_get_string("/purple/network/stun_server")); |
965 purple_network_set_turn_server( | 1040 purple_network_set_turn_server( |
966 purple_prefs_get_string("/purple/network/turn_server")); | 1041 purple_prefs_get_string("/purple/network/turn_server")); |
967 } | 1042 |
1043 upnp_port_mappings = | |
1044 g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); | |
1045 nat_pmp_port_mappings = | |
1046 g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); | |
1047 } | |
1048 | |
1049 | |
968 | 1050 |
969 void | 1051 void |
970 purple_network_uninit(void) | 1052 purple_network_uninit(void) |
971 { | 1053 { |
972 #ifdef HAVE_NETWORKMANAGER | 1054 #ifdef HAVE_NETWORKMANAGER |
1006 purple_signal_unregister(purple_network_get_handle(), | 1088 purple_signal_unregister(purple_network_get_handle(), |
1007 "network-configuration-changed"); | 1089 "network-configuration-changed"); |
1008 | 1090 |
1009 if (stun_ip) | 1091 if (stun_ip) |
1010 g_free(stun_ip); | 1092 g_free(stun_ip); |
1011 } | 1093 |
1094 g_hash_table_destroy(upnp_port_mappings); | |
1095 g_hash_table_destroy(nat_pmp_port_mappings); | |
1096 | |
1097 /* TODO: clean up remaining port mappings, note calling | |
1098 purple_upnp_remove_port_mapping from here doesn't quite work... */ | |
1099 } |