diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-12 14:21:51 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-12 14:21:51 +0000 |
commit | f602721d81e34679a6ef4738b9a2242ed1657beb (patch) | |
tree | b2719c4b2332f68825f16ba83d334bf201b70fc9 /src/transport | |
parent | 440151484373b16aca0414771b7f120114a9e460 (diff) | |
download | gnunet-f602721d81e34679a6ef4738b9a2242ed1657beb.tar.gz gnunet-f602721d81e34679a6ef4738b9a2242ed1657beb.zip |
fixing mantis #1825
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http.c | 171 |
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 | */ | ||
39 | struct 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 | */ | ||
55 | struct 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 | */ |
39 | struct IPv4HttpAddressWrapper | 71 | struct 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 * | |||
283 | http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) | 317 | http_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); |