aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-10-12 14:21:51 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-10-12 14:21:51 +0000
commitf602721d81e34679a6ef4738b9a2242ed1657beb (patch)
treeb2719c4b2332f68825f16ba83d334bf201b70fc9 /src/transport
parent440151484373b16aca0414771b7f120114a9e460 (diff)
downloadgnunet-f602721d81e34679a6ef4738b9a2242ed1657beb.tar.gz
gnunet-f602721d81e34679a6ef4738b9a2242ed1657beb.zip
fixing mantis #1825
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_http.c171
1 files changed, 114 insertions, 57 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c
index aeef547a5..11ce54331 100644
--- a/src/transport/plugin_transport_http.c
+++ b/src/transport/plugin_transport_http.c
@@ -34,6 +34,38 @@
34#define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6) 34#define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
35 35
36/** 36/**
37 * IPv4 addresses
38 */
39struct IPv4HttpAddress
40{
41 /**
42 * IPv4 address, in network byte order.
43 */
44 uint32_t ipv4_addr GNUNET_PACKED;
45
46 /**
47 * Port number, in network byte order.
48 */
49 uint16_t u4_port GNUNET_PACKED;
50};
51
52/**
53 * IPv4 addresses
54 */
55struct IPv6HttpAddress
56{
57 /**
58 * IPv6 address.
59 */
60 struct in6_addr ipv6_addr GNUNET_PACKED;
61
62 /**
63 * Port number, in network byte order.
64 */
65 uint16_t u6_port GNUNET_PACKED;
66};
67
68/**
37 * Wrapper to manage IPv4 addresses 69 * Wrapper to manage IPv4 addresses
38 */ 70 */
39struct IPv4HttpAddressWrapper 71struct IPv4HttpAddressWrapper
@@ -48,7 +80,7 @@ struct IPv4HttpAddressWrapper
48 */ 80 */
49 struct IPv4HttpAddressWrapper *prev; 81 struct IPv4HttpAddressWrapper *prev;
50 82
51 struct sockaddr_in addr; 83 struct IPv4HttpAddress addr;
52}; 84};
53 85
54/** 86/**
@@ -66,10 +98,7 @@ struct IPv6HttpAddressWrapper
66 */ 98 */
67 struct IPv6HttpAddressWrapper *prev; 99 struct IPv6HttpAddressWrapper *prev;
68 100
69 /** 101 struct IPv6HttpAddress addr6;
70 * IPv6 address.
71 */
72 struct sockaddr_in6 addr GNUNET_PACKED;
73}; 102};
74 103
75 104
@@ -161,18 +190,19 @@ http_plugin_address_pretty_printer (void *cls, const char *type,
161 uint16_t port = 0 ; 190 uint16_t port = 0 ;
162 191
163 // BUG! Transport addrs over the network must NOT be 'struct sockaddr*'s! 192 // BUG! Transport addrs over the network must NOT be 'struct sockaddr*'s!
164 if (addrlen == sizeof (struct sockaddr_in6)) 193 if (addrlen == sizeof (struct IPv6HttpAddress))
165 { 194 {
166 sb = addr; 195 struct IPv6HttpAddress * a6 = (struct IPv6HttpAddress *) addr;
167 sbs = sizeof (struct sockaddr_in6); 196 sb = &a6->ipv6_addr;
168 197 sbs = sizeof (struct in6_addr);
169 port = ntohs (((struct sockaddr_in6 *)addr)->sin6_port); 198 port = ntohs (a6->u6_port);
170 } 199 }
171 else if (addrlen == sizeof (struct sockaddr_in)) 200 else if (addrlen == sizeof (struct IPv4HttpAddress))
172 { 201 {
173 sb = &addr; 202 struct IPv4HttpAddress * a4 = (struct IPv4HttpAddress *) addr;
174 sbs = sizeof (struct sockaddr_in); 203 sb = &a4->ipv4_addr;
175 port = ntohs (((struct sockaddr_in *)addr)->sin_port); 204 sbs = sizeof (struct in_addr);
205 port = ntohs (a4->u4_port);
176 } 206 }
177 else 207 else
178 { 208 {
@@ -211,16 +241,20 @@ http_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
211 struct IPv4HttpAddressWrapper *w_tv4 = plugin->ipv4_addr_head; 241 struct IPv4HttpAddressWrapper *w_tv4 = plugin->ipv4_addr_head;
212 struct IPv6HttpAddressWrapper *w_tv6 = plugin->ipv6_addr_head; 242 struct IPv6HttpAddressWrapper *w_tv6 = plugin->ipv6_addr_head;
213 243
244
245
214 GNUNET_assert (cls != NULL); 246 GNUNET_assert (cls != NULL);
215 if ((addrlen != sizeof (struct sockaddr_in)) || 247 if ((addrlen != sizeof (struct sockaddr_in)) ||
216 (addrlen != sizeof (struct sockaddr_in6))) 248 (addrlen != sizeof (struct sockaddr_in6)))
217 return GNUNET_SYSERR; 249 return GNUNET_SYSERR;
218 250
219 if (addrlen == sizeof (struct sockaddr_in)) 251 if (addrlen == sizeof (struct IPv4HttpAddress))
220 { 252 {
253 struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) addr;
221 while (w_tv4 != NULL) 254 while (w_tv4 != NULL)
222 { 255 {
223 if (0 == memcmp (&w_tv4->addr, addr, sizeof (struct sockaddr_in))) 256 if ((0 == memcmp (&w_tv4->addr.ipv4_addr, &a4->ipv4_addr, sizeof (struct in_addr))) &&
257 (w_tv4->addr.u4_port == a4->u4_port))
224 break; 258 break;
225 w_tv4 = w_tv4->next; 259 w_tv4 = w_tv4->next;
226 } 260 }
@@ -231,11 +265,11 @@ http_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
231 } 265 }
232 if (addrlen == sizeof (struct sockaddr_in6)) 266 if (addrlen == sizeof (struct sockaddr_in6))
233 { 267 {
268 struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) addr;
234 while (w_tv6 != NULL) 269 while (w_tv6 != NULL)
235 { 270 {
236 if (0 == 271 if ((0 == memcmp (&w_tv6->addr6.ipv6_addr, &a6->ipv6_addr, sizeof (struct in6_addr))) &&
237 memcmp (&w_tv6->addr, addr, 272 (w_tv6->addr6.u6_port == a6->u6_port))
238 sizeof (struct sockaddr_in6)))
239 break; 273 break;
240 w_tv6 = w_tv6->next; 274 w_tv6 = w_tv6->next;
241 } 275 }
@@ -283,26 +317,26 @@ const char *
283http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) 317http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
284{ 318{
285 319
286 struct sockaddr_in *a4; 320 struct IPv4HttpAddress *a4;
287 struct sockaddr_in6 *a6; 321 struct IPv6HttpAddress *a6;
288 char *address; 322 char *address;
289 static char rbuf[INET6_ADDRSTRLEN + 13]; 323 static char rbuf[INET6_ADDRSTRLEN + 13];
290 uint16_t port; 324 uint16_t port;
291 int res = 0; 325 int res = 0;
292 326
293 if (addrlen == sizeof (struct sockaddr_in6)) 327 if (addrlen == sizeof (struct IPv6HttpAddress))
294 { 328 {
295 a6 = (struct sockaddr_in6 *) addr; 329 a6 = (struct IPv6HttpAddress *) addr;
296 address = GNUNET_malloc (INET6_ADDRSTRLEN); 330 address = GNUNET_malloc (INET6_ADDRSTRLEN);
297 inet_ntop (AF_INET6, &(a6->sin6_addr), address, INET6_ADDRSTRLEN); 331 GNUNET_assert(NULL != inet_ntop (AF_INET6, &a6->ipv6_addr, address, INET6_ADDRSTRLEN));
298 port = ntohs (a6->sin6_port); 332 port = ntohs (a6->u6_port);
299 } 333 }
300 else if (addrlen == sizeof (struct sockaddr_in)) 334 else if (addrlen == sizeof (struct IPv4HttpAddress))
301 { 335 {
302 a4 = (struct sockaddr_in *) addr; 336 a4 = (struct IPv4HttpAddress *) addr;
303 address = GNUNET_malloc (INET_ADDRSTRLEN); 337 address = GNUNET_malloc (INET_ADDRSTRLEN);
304 inet_ntop (AF_INET, &(a4->sin_addr), address, INET_ADDRSTRLEN); 338 GNUNET_assert(NULL != inet_ntop (AF_INET, &(a4->ipv4_addr), address, INET_ADDRSTRLEN));
305 port = ntohs (a4->sin_port); 339 port = ntohs (a4->u4_port);
306 } 340 }
307 else 341 else
308 { 342 {
@@ -316,9 +350,9 @@ http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
316#endif 350#endif
317 351
318 GNUNET_assert (strlen (address) + 7 < (INET6_ADDRSTRLEN + 13)); 352 GNUNET_assert (strlen (address) + 7 < (INET6_ADDRSTRLEN + 13));
319 if (addrlen == sizeof (struct sockaddr_in6)) 353 if (addrlen == sizeof (struct IPv6HttpAddress))
320 res = GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, address, port); 354 res = GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, address, port);
321 else if (addrlen == sizeof (struct sockaddr_in)) 355 else if (addrlen == sizeof (struct IPv4HttpAddress))
322 res = GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, address, port); 356 res = GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, address, port);
323 357
324 GNUNET_free (address); 358 GNUNET_free (address);
@@ -615,11 +649,17 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
615 { 649 {
616 case AF_INET: 650 case AF_INET:
617 w_t4 = plugin->ipv4_addr_head; 651 w_t4 = plugin->ipv4_addr_head;
652 struct sockaddr_in *a4 = (struct sockaddr_in *) addr;
618 while (w_t4 != NULL) 653 while (w_t4 != NULL)
619 { 654 {
620 int res = memcmp (&w_t4->addr, 655 int res = memcmp (&w_t4->addr.ipv4_addr,
621 (struct sockaddr_in *) addr, 656 &a4->sin_addr,
622 sizeof (struct sockaddr_in)); 657 sizeof (struct in_addr));
658 if (res == 0)
659 {
660 if (a4->sin_port!= w_t4->addr.u4_port)
661 res = -1;
662 }
623 663
624 if (0 == res) 664 if (0 == res)
625 break; 665 break;
@@ -628,8 +668,9 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
628 if (w_t4 == NULL) 668 if (w_t4 == NULL)
629 { 669 {
630 w_t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddressWrapper)); 670 w_t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddressWrapper));
631 memcpy (&w_t4->addr, (struct sockaddr_in *) addr, 671 memcpy (&w_t4->addr.ipv4_addr, &a4->sin_addr,
632 sizeof (struct sockaddr_in)); 672 sizeof (struct in_addr));
673 w_t4->addr.u4_port = a4->sin_port;
633 674
634 GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, 675 GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head,
635 plugin->ipv4_addr_tail, w_t4); 676 plugin->ipv4_addr_tail, w_t4);
@@ -637,19 +678,23 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
637#if DEBUG_HTTP 678#if DEBUG_HTTP
638 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 679 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
639 "Notifying transport to add IPv4 address `%s'\n", 680 "Notifying transport to add IPv4 address `%s'\n",
640 http_plugin_address_to_string(NULL, &w_t4->addr, sizeof (struct sockaddr_in))); 681 http_plugin_address_to_string(NULL, &w_t4->addr, sizeof (struct IPv4HttpAddress)));
641#endif 682#endif
642 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, sizeof (struct sockaddr_in)); 683 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, sizeof (struct IPv4HttpAddress));
643 684
644 break; 685 break;
645 case AF_INET6: 686 case AF_INET6:
646 w_t6 = plugin->ipv6_addr_head; 687 w_t6 = plugin->ipv6_addr_head;
688 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr;
647 while (w_t6) 689 while (w_t6)
648 { 690 {
649 int res = memcmp (&w_t6->addr, 691 int res = memcmp (&w_t6->addr6.ipv6_addr, &a6->sin6_addr,
650 (struct sockaddr_in6 *) addr, 692 sizeof (struct in6_addr));
651 sizeof (struct sockaddr_in6)); 693 if (res == 0)
652 694 {
695 if (a6->sin6_port != w_t6->addr6.u6_port)
696 res = -1;
697 }
653 if (0 == res) 698 if (0 == res)
654 break; 699 break;
655 w_t6 = w_t6->next; 700 w_t6 = w_t6->next;
@@ -657,8 +702,10 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
657 if (w_t6 == NULL) 702 if (w_t6 == NULL)
658 { 703 {
659 w_t6 = GNUNET_malloc (sizeof (struct IPv6HttpAddressWrapper)); 704 w_t6 = GNUNET_malloc (sizeof (struct IPv6HttpAddressWrapper));
660 memcpy (&w_t6->addr, (struct sockaddr_in6 *) addr, 705
661 sizeof (struct sockaddr_in6)); 706 memcpy (&w_t6->addr6.ipv6_addr, &a6->sin6_addr,
707 sizeof (struct in6_addr));
708 w_t6->addr6.u6_port = a6->sin6_port;
662 709
663 GNUNET_CONTAINER_DLL_insert (plugin->ipv6_addr_head, 710 GNUNET_CONTAINER_DLL_insert (plugin->ipv6_addr_head,
664 plugin->ipv6_addr_tail, w_t6); 711 plugin->ipv6_addr_tail, w_t6);
@@ -666,9 +713,9 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
666#if DEBUG_HTTP 713#if DEBUG_HTTP
667 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 714 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
668 "Notifying transport to add IPv6 address `%s'\n", 715 "Notifying transport to add IPv6 address `%s'\n",
669 http_plugin_address_to_string(NULL, &w_t6->addr, sizeof (struct sockaddr_in6))); 716 http_plugin_address_to_string(NULL, &w_t6->addr6, sizeof (struct IPv6HttpAddress)));
670#endif 717#endif
671 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr, sizeof (struct sockaddr_in6)); 718 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6, sizeof (struct IPv6HttpAddress));
672 break; 719 break;
673 default: 720 default:
674 return; 721 return;
@@ -690,11 +737,17 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
690 { 737 {
691 case AF_INET: 738 case AF_INET:
692 w_t4 = plugin->ipv4_addr_head; 739 w_t4 = plugin->ipv4_addr_head;
740 struct sockaddr_in *a4 = (struct sockaddr_in *) addr;
693 while (w_t4 != NULL) 741 while (w_t4 != NULL)
694 { 742 {
695 int res = memcmp (&(w_t4->addr.sin_addr), 743 int res = memcmp (&w_t4->addr.ipv4_addr,
696 &((struct sockaddr_in *) addr)->sin_addr, 744 &a4->sin_addr,
697 sizeof (struct in_addr)); 745 sizeof (struct in_addr));
746 if (res == 0)
747 {
748 if (a4->sin_port!= w_t4->addr.u4_port)
749 res = -1;
750 }
698 751
699 if (0 == res) 752 if (0 == res)
700 break; 753 break;
@@ -706,10 +759,10 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
706#if DEBUG_HTTP 759#if DEBUG_HTTP
707 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 760 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
708 "Notifying transport to remove IPv4 address `%s'\n", 761 "Notifying transport to remove IPv4 address `%s'\n",
709 http_plugin_address_to_string(NULL, &w_t4->addr, sizeof (struct sockaddr_in))); 762 http_plugin_address_to_string(NULL, &w_t4->addr, sizeof (struct IPv4HttpAddress)));
710#endif 763#endif
711 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, 764 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr,
712 sizeof (struct sockaddr_in)); 765 sizeof (struct IPv4HttpAddress));
713 766
714 GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail, 767 GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail,
715 w_t4); 768 w_t4);
@@ -717,12 +770,16 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
717 break; 770 break;
718 case AF_INET6: 771 case AF_INET6:
719 w_t6 = plugin->ipv6_addr_head; 772 w_t6 = plugin->ipv6_addr_head;
720 while (w_t6 != NULL) 773 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr;
774 while (w_t6)
721 { 775 {
722 int res = memcmp (&(w_t6->addr.sin6_addr), 776 int res = memcmp (&w_t6->addr6.ipv6_addr, &a6->sin6_addr,
723 &((struct sockaddr_in6 *) addr)->sin6_addr,
724 sizeof (struct in6_addr)); 777 sizeof (struct in6_addr));
725 778 if (res == 0)
779 {
780 if (a6->sin6_port != w_t6->addr6.u6_port)
781 res = -1;
782 }
726 if (0 == res) 783 if (0 == res)
727 break; 784 break;
728 w_t6 = w_t6->next; 785 w_t6 = w_t6->next;
@@ -732,10 +789,10 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
732#if DEBUG_HTTP 789#if DEBUG_HTTP
733 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 790 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
734 "Notifying transport to remove IPv6 address `%s'\n", 791 "Notifying transport to remove IPv6 address `%s'\n",
735 http_plugin_address_to_string(NULL, &w_t6->addr, sizeof (struct sockaddr_in6))); 792 http_plugin_address_to_string(NULL, &w_t6->addr6, sizeof (struct IPv6HttpAddress)));
736#endif 793#endif
737 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr, 794 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6,
738 sizeof (struct sockaddr_in6 )); 795 sizeof (struct IPv6HttpAddress));
739 796
740 GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail, 797 GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail,
741 w_t6); 798 w_t6);