aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-06-28 11:37:52 +0000
committerChristian Grothoff <christian@grothoff.org>2010-06-28 11:37:52 +0000
commit59ca0059f61b1e2538f2890625601a88b2119f66 (patch)
treeecc298a424c8e28d3048bc74dd47bc8d3deff538
parent62f22f399bd326fc6521204aff3b02bb32e8a401 (diff)
downloadgnunet-59ca0059f61b1e2538f2890625601a88b2119f66.tar.gz
gnunet-59ca0059f61b1e2538f2890625601a88b2119f66.zip
implementing local address check for tcp/udp
-rw-r--r--src/transport/plugin_transport_tcp.c106
-rw-r--r--src/transport/plugin_transport_udp.c154
2 files changed, 229 insertions, 31 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index edf403ac6..2737003ab 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -150,6 +150,31 @@ struct Plugin;
150 150
151 151
152/** 152/**
153 * Local network addresses (actual IP address follows this struct).
154 * PORT is NOT included!
155 */
156struct LocalAddrList
157{
158
159 /**
160 * This is a doubly linked list.
161 */
162 struct LocalAddrList *next;
163
164 /**
165 * This is a doubly linked list.
166 */
167 struct LocalAddrList *prev;
168
169 /**
170 * Number of bytes of the address that follow
171 */
172 size_t size;
173
174};
175
176
177/**
153 * Information kept for each message that is yet to 178 * Information kept for each message that is yet to
154 * be transmitted. 179 * be transmitted.
155 */ 180 */
@@ -360,6 +385,16 @@ struct Plugin
360 char *internal_address; 385 char *internal_address;
361 386
362 /** 387 /**
388 * List of our IP addresses.
389 */
390 struct LocalAddrList *lal_head;
391
392 /**
393 * Tail of our IP address list.
394 */
395 struct LocalAddrList *lal_tail;
396
397 /**
363 * ID of task used to update our addresses when one expires. 398 * ID of task used to update our addresses when one expires.
364 */ 399 */
365 GNUNET_SCHEDULER_TaskIdentifier address_update_task; 400 GNUNET_SCHEDULER_TaskIdentifier address_update_task;
@@ -395,6 +430,47 @@ struct Plugin
395}; 430};
396 431
397 432
433static void
434add_to_address_list (struct Plugin *plugin,
435 const void *arg,
436 size_t arg_size)
437{
438 struct LocalAddrList *lal;
439
440 lal = plugin->lal_head;
441 while (NULL != lal)
442 {
443 if ( (lal->size == arg_size) &&
444 (0 == memcmp (&lal[1], arg, arg_size)) )
445 return;
446 lal = lal->next;
447 }
448 lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size);
449 lal->size = arg_size;
450 memcpy (&lal[1], arg, arg_size);
451 GNUNET_CONTAINER_DLL_insert (plugin->lal_head,
452 plugin->lal_tail,
453 lal);
454}
455
456
457static int
458check_local_addr (struct Plugin *plugin,
459 const void *arg,
460 size_t arg_size)
461{
462 struct LocalAddrList *lal;
463
464 lal = plugin->lal_head;
465 while (NULL != lal)
466 {
467 if ( (lal->size == arg_size) &&
468 (0 == memcmp (&lal[1], arg, arg_size)) )
469 return GNUNET_OK;
470 lal = lal->next;
471 }
472 return GNUNET_SYSERR;
473}
398 474
399 475
400/** 476/**
@@ -1375,6 +1451,14 @@ tcp_plugin_address_pretty_printer (void *cls,
1375static int 1451static int
1376check_port (struct Plugin *plugin, uint16_t in_port) 1452check_port (struct Plugin *plugin, uint16_t in_port)
1377{ 1453{
1454 if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) )
1455 return GNUNET_OK;
1456 if ( (plugin->only_nat_addresses == GNUNET_YES) &&
1457 (plugin->behind_nat == GNUNET_YES) &&
1458 (in_port != 0) )
1459 {
1460 return GNUNET_SYSERR; /* odd case... */
1461 }
1378 if ((in_port == plugin->adv_port) || (in_port == plugin->open_port)) 1462 if ((in_port == plugin->adv_port) || (in_port == plugin->open_port))
1379 return GNUNET_OK; 1463 return GNUNET_OK;
1380 return GNUNET_SYSERR; 1464 return GNUNET_SYSERR;
@@ -1417,7 +1501,11 @@ tcp_plugin_check_address (void *cls,
1417 if (GNUNET_OK != 1501 if (GNUNET_OK !=
1418 check_port (plugin, ntohs (v4->t_port))) 1502 check_port (plugin, ntohs (v4->t_port)))
1419 return GNUNET_SYSERR; 1503 return GNUNET_SYSERR;
1420 /* FIXME: check IP! */ 1504 if (GNUNET_OK !=
1505 check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t)))
1506 {
1507 return GNUNET_SYSERR;
1508 }
1421 } 1509 }
1422 else 1510 else
1423 { 1511 {
@@ -1430,7 +1518,11 @@ tcp_plugin_check_address (void *cls,
1430 if (GNUNET_OK != 1518 if (GNUNET_OK !=
1431 check_port (plugin, ntohs (v6->t6_port))) 1519 check_port (plugin, ntohs (v6->t6_port)))
1432 return GNUNET_SYSERR; 1520 return GNUNET_SYSERR;
1433 /* FIXME: check IP! */ 1521 if (GNUNET_OK !=
1522 check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr)))
1523 {
1524 return GNUNET_SYSERR;
1525 }
1434 } 1526 }
1435 return GNUNET_OK; 1527 return GNUNET_OK;
1436} 1528}
@@ -1796,6 +1888,7 @@ process_interfaces (void *cls,
1796 if (af == AF_INET) 1888 if (af == AF_INET)
1797 { 1889 {
1798 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; 1890 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
1891 add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t));
1799 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) 1892 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
1800 t4.t_port = htons(0); 1893 t4.t_port = htons(0);
1801 else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ 1894 else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */
@@ -1819,6 +1912,7 @@ process_interfaces (void *cls,
1819 memcpy (&t6.ipv6_addr, 1912 memcpy (&t6.ipv6_addr,
1820 &((struct sockaddr_in6 *) addr)->sin6_addr, 1913 &((struct sockaddr_in6 *) addr)->sin6_addr,
1821 sizeof (struct in6_addr)); 1914 sizeof (struct in6_addr));
1915 add_to_address_list (plugin, &t6.ipv6_addr, sizeof (struct in6_addr));
1822 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) 1916 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
1823 t6.t6_port = htons(0); 1917 t6.t6_port = htons(0);
1824 else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ 1918 else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */
@@ -2401,6 +2495,7 @@ libgnunet_plugin_transport_tcp_done (void *cls)
2401 struct GNUNET_TRANSPORT_PluginFunctions *api = cls; 2495 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2402 struct Plugin *plugin = api->cls; 2496 struct Plugin *plugin = api->cls;
2403 struct Session *session; 2497 struct Session *session;
2498 struct LocalAddrList *lal;
2404 2499
2405 while (NULL != (session = plugin->sessions)) 2500 while (NULL != (session = plugin->sessions))
2406 disconnect_session (session); 2501 disconnect_session (session);
@@ -2411,6 +2506,13 @@ libgnunet_plugin_transport_tcp_done (void *cls)
2411 } 2506 }
2412 GNUNET_SERVICE_stop (plugin->service); 2507 GNUNET_SERVICE_stop (plugin->service);
2413 GNUNET_free (plugin->handlers); 2508 GNUNET_free (plugin->handlers);
2509 while (NULL != (lal = plugin->lal_head))
2510 {
2511 GNUNET_CONTAINER_DLL_remove (plugin->lal_head,
2512 plugin->lal_tail,
2513 lal);
2514 GNUNET_free (lal);
2515 }
2414 GNUNET_free (plugin); 2516 GNUNET_free (plugin);
2415 GNUNET_free (api); 2517 GNUNET_free (api);
2416 return NULL; 2518 return NULL;
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 724dfe6b3..7067dc196 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -40,6 +40,7 @@
40#include "platform.h" 40#include "platform.h"
41#include "gnunet_hello_lib.h" 41#include "gnunet_hello_lib.h"
42#include "gnunet_connection_lib.h" 42#include "gnunet_connection_lib.h"
43#include "gnunet_container_lib.h"
43#include "gnunet_os_lib.h" 44#include "gnunet_os_lib.h"
44#include "gnunet_peerinfo_service.h" 45#include "gnunet_peerinfo_service.h"
45#include "gnunet_protocols.h" 46#include "gnunet_protocols.h"
@@ -115,7 +116,7 @@ struct IPv6UdpAddress
115 /** 116 /**
116 * IPv6 address. 117 * IPv6 address.
117 */ 118 */
118 unsigned char ipv6_addr[16]; 119 struct in6_addr ipv6_addr;
119 120
120 /** 121 /**
121 * Port number, in network byte order. 122 * Port number, in network byte order.
@@ -210,6 +211,30 @@ struct UDP_NAT_ProbeMessageConfirmation
210}; 211};
211 212
212 213
214/**
215 * Local network addresses (actual IP address follows this struct).
216 * PORT is NOT included!
217 */
218struct LocalAddrList
219{
220
221 /**
222 * This is a doubly linked list.
223 */
224 struct LocalAddrList *next;
225
226 /**
227 * This is a doubly linked list.
228 */
229 struct LocalAddrList *prev;
230
231 /**
232 * Number of bytes of the address that follow
233 */
234 size_t size;
235
236};
237
213 238
214/** 239/**
215 * UDP NAT "Session" 240 * UDP NAT "Session"
@@ -354,17 +379,27 @@ struct Plugin
354 */ 379 */
355 char *internal_address; 380 char *internal_address;
356 381
357 /* 382 /**
383 * List of our IP addresses.
384 */
385 struct LocalAddrList *lal_head;
386
387 /**
388 * Tail of our IP address list.
389 */
390 struct LocalAddrList *lal_tail;
391
392 /**
358 * FD Read set 393 * FD Read set
359 */ 394 */
360 struct GNUNET_NETWORK_FDSet *rs; 395 struct GNUNET_NETWORK_FDSet *rs;
361 396
362 /* 397 /**
363 * stdout pipe handle for the gnunet-nat-server process 398 * stdout pipe handle for the gnunet-nat-server process
364 */ 399 */
365 struct GNUNET_DISK_PipeHandle *server_stdout; 400 struct GNUNET_DISK_PipeHandle *server_stdout;
366 401
367 /* 402 /**
368 * stdout file handle (for reading) for the gnunet-nat-server process 403 * stdout file handle (for reading) for the gnunet-nat-server process
369 */ 404 */
370 const struct GNUNET_DISK_FileHandle *server_stdout_handle; 405 const struct GNUNET_DISK_FileHandle *server_stdout_handle;
@@ -796,6 +831,49 @@ udp_plugin_send (void *cls,
796} 831}
797 832
798 833
834static void
835add_to_address_list (struct Plugin *plugin,
836 const void *arg,
837 size_t arg_size)
838{
839 struct LocalAddrList *lal;
840
841 lal = plugin->lal_head;
842 while (NULL != lal)
843 {
844 if ( (lal->size == arg_size) &&
845 (0 == memcmp (&lal[1], arg, arg_size)) )
846 return;
847 lal = lal->next;
848 }
849 lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size);
850 lal->size = arg_size;
851 memcpy (&lal[1], arg, arg_size);
852 GNUNET_CONTAINER_DLL_insert (plugin->lal_head,
853 plugin->lal_tail,
854 lal);
855}
856
857
858static int
859check_local_addr (struct Plugin *plugin,
860 const void *arg,
861 size_t arg_size)
862{
863 struct LocalAddrList *lal;
864
865 lal = plugin->lal_head;
866 while (NULL != lal)
867 {
868 if ( (lal->size == arg_size) &&
869 (0 == memcmp (&lal[1], arg, arg_size)) )
870 return GNUNET_OK;
871 lal = lal->next;
872 }
873 return GNUNET_SYSERR;
874}
875
876
799/** 877/**
800 * Add the IP of our network interface to the list of 878 * Add the IP of our network interface to the list of
801 * our external IP addresses. 879 * our external IP addresses.
@@ -819,6 +897,7 @@ process_interfaces (void *cls,
819 if (af == AF_INET) 897 if (af == AF_INET)
820 { 898 {
821 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; 899 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
900 add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t));
822 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) 901 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
823 { 902 {
824 t4.u_port = htons (DEFAULT_NAT_PORT); 903 t4.u_port = htons (DEFAULT_NAT_PORT);
@@ -839,7 +918,6 @@ process_interfaces (void *cls,
839 } 918 }
840 else if (af == AF_INET6) 919 else if (af == AF_INET6)
841 { 920 {
842
843 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) 921 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
844 { 922 {
845 /* skip link local addresses */ 923 /* skip link local addresses */
@@ -848,6 +926,7 @@ process_interfaces (void *cls,
848 memcpy (&t6.ipv6_addr, 926 memcpy (&t6.ipv6_addr,
849 &((struct sockaddr_in6 *) addr)->sin6_addr, 927 &((struct sockaddr_in6 *) addr)->sin6_addr,
850 sizeof (struct in6_addr)); 928 sizeof (struct in6_addr));
929 add_to_address_list (plugin, &t6.ipv6_addr, sizeof (struct in6_addr));
851 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) 930 if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES))
852 { 931 {
853 t6.u6_port = htons (0); 932 t6.u6_port = htons (0);
@@ -872,28 +951,27 @@ process_interfaces (void *cls,
872 GNUNET_break (0); 951 GNUNET_break (0);
873 return GNUNET_OK; 952 return GNUNET_OK;
874 } 953 }
875 954
876 GNUNET_log (GNUNET_ERROR_TYPE_INFO | 955 GNUNET_log (GNUNET_ERROR_TYPE_INFO |
877 GNUNET_ERROR_TYPE_BULK, 956 GNUNET_ERROR_TYPE_BULK,
878 _("Found address `%s' (%s)\n"), 957 _("Found address `%s' (%s)\n"),
879 GNUNET_a2s (addr, addrlen), name); 958 GNUNET_a2s (addr, addrlen), name);
880 959
881 if (addr_nat != NULL) 960 if (addr_nat != NULL)
882 { 961 {
883 plugin->env->notify_address (plugin->env->cls, 962 plugin->env->notify_address (plugin->env->cls,
884 "udp", 963 "udp",
885 addr_nat, args, GNUNET_TIME_UNIT_FOREVER_REL); 964 addr_nat, args, GNUNET_TIME_UNIT_FOREVER_REL);
886 GNUNET_log (GNUNET_ERROR_TYPE_INFO | 965 GNUNET_log (GNUNET_ERROR_TYPE_INFO |
887 GNUNET_ERROR_TYPE_BULK, 966 GNUNET_ERROR_TYPE_BULK,
888 _("Found NAT address `%s' (%s)\n"), 967 _("Found NAT address `%s' (%s)\n"),
889 GNUNET_a2s (addr_nat, args), name); 968 GNUNET_a2s (addr_nat, args), name);
890 GNUNET_free(addr_nat); 969 GNUNET_free(addr_nat);
891 } 970 }
892 971
893 plugin->env->notify_address (plugin->env->cls, 972 plugin->env->notify_address (plugin->env->cls,
894 "udp", 973 "udp",
895 arg, args, GNUNET_TIME_UNIT_FOREVER_REL); 974 arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
896
897 return GNUNET_OK; 975 return GNUNET_OK;
898} 976}
899 977
@@ -1599,6 +1677,12 @@ udp_transport_server_start (void *cls)
1599static int 1677static int
1600check_port (struct Plugin *plugin, uint16_t in_port) 1678check_port (struct Plugin *plugin, uint16_t in_port)
1601{ 1679{
1680 if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) )
1681 return GNUNET_OK;
1682 if ( (plugin->only_nat_addresses == GNUNET_YES) &&
1683 (plugin->behind_nat == GNUNET_YES) &&
1684 (in_port != 0) )
1685 return GNUNET_SYSERR; /* odd case... */
1602 if (in_port == plugin->port) 1686 if (in_port == plugin->port)
1603 return GNUNET_OK; 1687 return GNUNET_OK;
1604 return GNUNET_SYSERR; 1688 return GNUNET_SYSERR;
@@ -1642,7 +1726,9 @@ udp_check_address (void *cls,
1642 if (GNUNET_OK != 1726 if (GNUNET_OK !=
1643 check_port (plugin, ntohs (v4->u_port))) 1727 check_port (plugin, ntohs (v4->u_port)))
1644 return GNUNET_SYSERR; 1728 return GNUNET_SYSERR;
1645 /* FIXME: check IP! */ 1729 if (GNUNET_OK !=
1730 check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t)))
1731 return GNUNET_SYSERR;
1646 } 1732 }
1647 else 1733 else
1648 { 1734 {
@@ -1655,7 +1741,9 @@ udp_check_address (void *cls,
1655 if (GNUNET_OK != 1741 if (GNUNET_OK !=
1656 check_port (plugin, ntohs (v6->u6_port))) 1742 check_port (plugin, ntohs (v6->u6_port)))
1657 return GNUNET_SYSERR; 1743 return GNUNET_SYSERR;
1658 /* FIXME: check IP! */ 1744 if (GNUNET_OK !=
1745 check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr)))
1746 return GNUNET_SYSERR;
1659 } 1747 }
1660#if DEBUG_UDP 1748#if DEBUG_UDP
1661 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1749 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
@@ -2069,6 +2157,7 @@ libgnunet_plugin_transport_udp_done (void *cls)
2069{ 2157{
2070 struct GNUNET_TRANSPORT_PluginFunctions *api = cls; 2158 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2071 struct Plugin *plugin = api->cls; 2159 struct Plugin *plugin = api->cls;
2160 struct LocalAddrList *lal;
2072 2161
2073 udp_transport_server_stop (plugin); 2162 udp_transport_server_stop (plugin);
2074 if (NULL != plugin->hostname_dns) 2163 if (NULL != plugin->hostname_dns)
@@ -2080,6 +2169,13 @@ libgnunet_plugin_transport_udp_done (void *cls)
2080 GNUNET_SERVICE_stop (plugin->service); 2169 GNUNET_SERVICE_stop (plugin->service);
2081 2170
2082 GNUNET_NETWORK_fdset_destroy (plugin->rs); 2171 GNUNET_NETWORK_fdset_destroy (plugin->rs);
2172 while (NULL != (lal = plugin->lal_head))
2173 {
2174 GNUNET_CONTAINER_DLL_remove (plugin->lal_head,
2175 plugin->lal_tail,
2176 lal);
2177 GNUNET_free (lal);
2178 }
2083 GNUNET_free (plugin); 2179 GNUNET_free (plugin);
2084 GNUNET_free (api); 2180 GNUNET_free (api);
2085 return NULL; 2181 return NULL;