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 }