aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_http.c')
-rw-r--r--src/transport/plugin_transport_http.c496
1 files changed, 86 insertions, 410 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c
index af0d9fcf8..7f78f0e4f 100644
--- a/src/transport/plugin_transport_http.c
+++ b/src/transport/plugin_transport_http.c
@@ -53,43 +53,6 @@ struct HttpAddressWrapper
53}; 53};
54 54
55/** 55/**
56 * Wrapper to manage IPv4 addresses
57 */
58struct IPv4HttpAddressWrapper
59{
60 /**
61 * Linked list next
62 */
63 struct IPv4HttpAddressWrapper *next;
64
65 /**
66 * Linked list previous
67 */
68 struct IPv4HttpAddressWrapper *prev;
69
70 struct IPv4HttpAddress addr;
71};
72
73/**
74 * Wrapper for IPv4 addresses.
75 */
76struct IPv6HttpAddressWrapper
77{
78 /**
79 * Linked list next
80 */
81 struct IPv6HttpAddressWrapper *next;
82
83 /**
84 * Linked list previous
85 */
86 struct IPv6HttpAddressWrapper *prev;
87
88 struct IPv6HttpAddress addr6;
89};
90
91
92/**
93 * Context for address to string conversion. 56 * Context for address to string conversion.
94 */ 57 */
95struct PrettyPrinterContext 58struct PrettyPrinterContext
@@ -144,52 +107,6 @@ static void
144stop_session_timeout (struct Session *s); 107stop_session_timeout (struct Session *s);
145 108
146/** 109/**
147 * Append our port and forward the result.
148 *
149 * @param cls the 'struct PrettyPrinterContext*'
150 * @param hostname hostname part of the address
151 */
152static void
153append_port (void *cls, const char *hostname)
154{
155 struct PrettyPrinterContext *ppc = cls;
156 static char rbuf[INET6_ADDRSTRLEN + 13];
157
158 if (hostname == NULL)
159 {
160 ppc->asc (ppc->asc_cls, NULL);
161 GNUNET_free (ppc);
162 return;
163 }
164
165#if !BUILD_HTTPS
166 const char *protocol = "http";
167#else
168 const char *protocol = "https";
169#endif
170 GNUNET_assert ((strlen (hostname) + 7) < (INET6_ADDRSTRLEN + 13));
171 if (ppc->addrlen == sizeof (struct IPv6HttpAddress))
172 {
173 if (ppc->numeric == GNUNET_YES)
174 GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, hostname, ppc->port);
175 else
176 {
177 if (strchr(hostname, ':') != NULL)
178 GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, hostname, ppc->port);
179 else
180 GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, hostname, ppc->port);
181 }
182 }
183 else if (ppc->addrlen == sizeof (struct IPv4HttpAddress))
184 GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, hostname, ppc->port);
185 ppc->asc (ppc->asc_cls, rbuf);
186}
187
188
189
190
191
192/**
193 * Convert the transports address to a nice, human-readable 110 * Convert the transports address to a nice, human-readable
194 * format. 111 * format.
195 * 112 *
@@ -212,62 +129,16 @@ http_plugin_address_pretty_printer (void *cls, const char *type,
212 void *asc_cls) 129 void *asc_cls)
213{ 130{
214 GNUNET_assert (cls != NULL); 131 GNUNET_assert (cls != NULL);
215 struct PrettyPrinterContext *ppc; 132 struct HttpAddress *haddr = (struct HttpAddress *) addr;
216 const void *sb;
217 struct sockaddr_in s4;
218 struct sockaddr_in6 s6;
219 size_t sbs;
220 uint16_t port = 0;
221
222 if ((addrlen == sizeof (struct IPv6HttpAddress)) && (addr != NULL))
223 {
224 struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) addr;
225 s6.sin6_family = AF_INET6;
226 s6.sin6_addr = a6->ipv6_addr;
227 s6.sin6_port = a6->u6_port;
228#if HAVE_SOCKADDR_IN_SIN_LEN
229 s6.sin6_len = sizeof (struct sockaddr_in6);
230#endif
231 sb = &s6;
232 sbs = sizeof (struct sockaddr_in6);
233 port = ntohs (a6->u6_port);
234
235 }
236 else if ((addrlen == sizeof (struct IPv4HttpAddress)) && (addr != NULL))
237 {
238 struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) addr;
239 133
240 s4.sin_family = AF_INET; 134 if (addrlen < (sizeof (struct HttpAddress)))
241 s4.sin_addr.s_addr = a4->ipv4_addr;
242 s4.sin_port = a4->u4_port;
243#if HAVE_SOCKADDR_IN_SIN_LEN
244 s4.sin_len = sizeof (struct sockaddr_in);
245#endif
246 sb = &s4;
247 sbs = sizeof (struct sockaddr_in);
248 port = ntohs (a4->u4_port);
249 }
250 else if (0 == addrlen)
251 {
252 asc (asc_cls, "<inbound connection>");
253 asc (asc_cls, NULL);
254 return;
255 }
256 else
257 { 135 {
258 /* invalid address */ 136 /* invalid address */
259 GNUNET_break_op (0); 137 GNUNET_break_op (0);
260 asc (asc_cls, NULL); 138 asc (asc_cls, NULL);
261 return; 139 return;
262 } 140 }
263 ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); 141 asc (asc_cls, haddr->addr);
264 ppc->asc = asc;
265 ppc->asc_cls = asc_cls;
266 ppc->port = port;
267 ppc->plugin = cls;
268 ppc->addrlen = addrlen;
269 ppc->numeric = numeric;
270 GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
271} 142}
272 143
273 144
@@ -288,51 +159,24 @@ static int
288http_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) 159http_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
289{ 160{
290 struct Plugin *plugin = cls; 161 struct Plugin *plugin = cls;
291 struct IPv4HttpAddressWrapper *w_tv4 = plugin->ipv4_addr_head; 162 struct HttpAddressWrapper *w = plugin->addr_head;
292 struct IPv6HttpAddressWrapper *w_tv6 = plugin->ipv6_addr_head; 163 struct HttpAddress *haddr = (struct HttpAddress *) addr;
293 164
294 GNUNET_assert (cls != NULL); 165 GNUNET_assert (cls != NULL);
295 if ((addrlen != sizeof (struct sockaddr_in)) ||
296 (addrlen != sizeof (struct sockaddr_in6)))
297 return GNUNET_SYSERR;
298 166
299 if (addrlen == sizeof (struct IPv4HttpAddress)) 167 if (addrlen <= sizeof (struct HttpAddress))
300 { 168 return GNUNET_SYSERR;
301 struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) addr;
302 169
303 while (w_tv4 != NULL) 170 if (0 == (strcmp (plugin->ext_addr->addr, haddr->addr)))
304 {
305 if ((0 ==
306 memcmp (&w_tv4->addr.ipv4_addr, &a4->ipv4_addr,
307 sizeof (struct in_addr))) &&
308 (w_tv4->addr.u4_port == a4->u4_port))
309 break;
310 w_tv4 = w_tv4->next;
311 }
312 if (w_tv4 != NULL)
313 return GNUNET_OK; 171 return GNUNET_OK;
314 else
315 return GNUNET_SYSERR;
316 }
317 if (addrlen == sizeof (struct sockaddr_in6))
318 {
319 struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) addr;
320 172
321 while (w_tv6 != NULL) 173 while (NULL != w)
322 { 174 {
323 if ((0 == 175 if (0 == (strcmp (w->addr->addr, haddr->addr)))
324 memcmp (&w_tv6->addr6.ipv6_addr, &a6->ipv6_addr, 176 return GNUNET_OK;
325 sizeof (struct in6_addr))) && 177 w = w->next;
326 (w_tv6->addr6.u6_port == a6->u6_port))
327 break;
328 w_tv6 = w_tv6->next;
329 }
330 if (w_tv6 != NULL)
331 return GNUNET_OK;
332 else
333 return GNUNET_SYSERR;
334 } 178 }
335 return GNUNET_OK; 179 return GNUNET_SYSERR;
336} 180}
337 181
338struct GNUNET_TIME_Relative 182struct GNUNET_TIME_Relative
@@ -381,6 +225,7 @@ http_string_to_address (void *cls,
381 void **buf, 225 void **buf,
382 size_t *added) 226 size_t *added)
383{ 227{
228#if 0
384#if !BUILD_HTTPS 229#if !BUILD_HTTPS
385 char *protocol = "http"; 230 char *protocol = "http";
386#else 231#else
@@ -455,7 +300,8 @@ http_string_to_address (void *cls,
455 "Invalid address string `%s' to convert to address\n", 300 "Invalid address string `%s' to convert to address\n",
456 addr_str); 301 addr_str);
457 GNUNET_break (0); 302 GNUNET_break (0);
458 return GNUNET_SYSERR; 303 return GNUNET_SYSERR;
304#endif
459} 305}
460 306
461 307
@@ -473,57 +319,19 @@ http_string_to_address (void *cls,
473const char * 319const char *
474http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) 320http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
475{ 321{
476 322 struct HttpAddress *haddr;
477 struct IPv4HttpAddress *a4; 323 if (addrlen < sizeof (struct HttpAddress))
478 struct IPv6HttpAddress *a6;
479 char *address;
480 static char rbuf[INET6_ADDRSTRLEN + 13];
481 uint16_t port;
482 int res = 0;
483
484 if (addrlen == sizeof (struct IPv6HttpAddress))
485 {
486 a6 = (struct IPv6HttpAddress *) addr;
487 address = GNUNET_malloc (INET6_ADDRSTRLEN);
488 GNUNET_assert (NULL !=
489 inet_ntop (AF_INET6, &a6->ipv6_addr, address,
490 INET6_ADDRSTRLEN));
491 port = ntohs (a6->u6_port);
492 }
493 else if (addrlen == sizeof (struct IPv4HttpAddress))
494 { 324 {
495 a4 = (struct IPv4HttpAddress *) addr; 325 /* invalid address */
496 address = GNUNET_malloc (INET_ADDRSTRLEN); 326 GNUNET_break (0);
497 GNUNET_assert (NULL != 327 return NULL;
498 inet_ntop (AF_INET, &(a4->ipv4_addr), address,
499 INET_ADDRSTRLEN));
500 port = ntohs (a4->u4_port);
501 } 328 }
502 else 329 else
503 { 330 {
504 /* invalid address */ 331 haddr = (struct HttpAddress *) addr;
505 GNUNET_break (0); 332 GNUNET_assert (NULL != haddr->addr);
506 return NULL; 333 return (const char *) haddr->addr;
507 } 334 }
508#if !BUILD_HTTPS
509 char *protocol = "http";
510#else
511 char *protocol = "https";
512#endif
513
514 GNUNET_assert (strlen (address) + 7 < (INET6_ADDRSTRLEN + 13));
515 if (addrlen == sizeof (struct IPv6HttpAddress))
516 res =
517 GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol,
518 address, port);
519 else if (addrlen == sizeof (struct IPv4HttpAddress))
520 res =
521 GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, address,
522 port);
523
524 GNUNET_free (address);
525 GNUNET_assert (res != 0);
526 return rbuf;
527} 335}
528 336
529 337
@@ -651,44 +459,16 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
651 struct Session *s = NULL; 459 struct Session *s = NULL;
652 struct GNUNET_ATS_Information ats; 460 struct GNUNET_ATS_Information ats;
653 461
654 GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || 462 /*
655 (addrlen == sizeof (struct IPv4HttpAddress))); 463 * ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s6, sizeof (struct sockaddr_in6));
656 464 */
657 465 if (addrlen < sizeof (struct HttpAddress))
658
659
660 if (addrlen == sizeof (struct IPv4HttpAddress))
661 { 466 {
662 struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) addr; 467 GNUNET_break (0);
663 struct sockaddr_in s4;
664
665 if (0 == ntohs(a4->u4_port))
666 return NULL; 468 return NULL;
667
668 s4.sin_family = AF_INET;
669 s4.sin_addr.s_addr = a4->ipv4_addr;
670 s4.sin_port = a4->u4_port;
671#if HAVE_SOCKADDR_IN_SIN_LEN
672 s4.sin_len = sizeof (struct sockaddr_in);
673#endif
674 ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s4, sizeof (struct sockaddr_in));
675 } 469 }
676 if (addrlen == sizeof (struct IPv6HttpAddress))
677 {
678 struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) addr;
679 struct sockaddr_in6 s6;
680 470
681 if (0 == ntohs(a6->u6_port))
682 return NULL;
683 471
684 s6.sin6_family = AF_INET6;
685 s6.sin6_addr = a6->ipv6_addr;
686 s6.sin6_port = a6->u6_port;
687#if HAVE_SOCKADDR_IN_SIN_LEN
688 s6.sin6_len = sizeof (struct sockaddr_in6);
689#endif
690 ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s6, sizeof (struct sockaddr_in6));
691 }
692 472
693 s = GNUNET_malloc (sizeof (struct Session)); 473 s = GNUNET_malloc (sizeof (struct Session));
694 memcpy (&s->target, target, sizeof (struct GNUNET_PeerIdentity)); 474 memcpy (&s->target, target, sizeof (struct GNUNET_PeerIdentity));
@@ -756,8 +536,7 @@ http_get_session (void *cls,
756 /* create new session */ 536 /* create new session */
757 addrlen = address->address_length; 537 addrlen = address->address_length;
758 538
759 GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || 539 GNUNET_assert (addrlen > sizeof (struct HttpAddress));
760 (addrlen == sizeof (struct IPv4HttpAddress)));
761 540
762 s = create_session (plugin, &address->peer, address->address, address->address_length); 541 s = create_session (plugin, &address->peer, address->address, address->address_length);
763 542
@@ -913,120 +692,49 @@ http_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
913static void * 692static void *
914find_address (struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen) 693find_address (struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen)
915{ 694{
916 int af; 695 struct HttpAddressWrapper *w = NULL;
917 struct IPv4HttpAddressWrapper *w_t4 = NULL; 696 char *saddr;
918 struct IPv6HttpAddressWrapper *w_t6 = NULL;
919 697
920 af = addr->sa_family; 698 GNUNET_asprintf(&saddr, "%s://%s", plugin->protocol, GNUNET_a2s (addr, addrlen));
921 switch (af) 699 w = plugin->addr_head;
700 while (NULL != w)
922 { 701 {
923 case AF_INET: 702 if (0 == strcmp (saddr, w->addr->addr))
924 w_t4 = plugin->ipv4_addr_head;
925 struct sockaddr_in *a4 = (struct sockaddr_in *) addr;
926
927 while (w_t4 != NULL)
928 {
929 int res = memcmp (&w_t4->addr.ipv4_addr,
930 &a4->sin_addr,
931 sizeof (struct in_addr));
932
933 if (res == 0)
934 {
935 if (a4->sin_port != w_t4->addr.u4_port)
936 res = -1;
937 }
938
939 if (0 == res)
940 break; 703 break;
941 w_t4 = w_t4->next; 704 w = w->next;
942 }
943 return w_t4;
944 break;
945 case AF_INET6:
946 w_t6 = plugin->ipv6_addr_head;
947 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr;
948
949 while (w_t6)
950 {
951 int res = memcmp (&w_t6->addr6.ipv6_addr, &a6->sin6_addr,
952 sizeof (struct in6_addr));
953
954 if (res == 0)
955 {
956 if (a6->sin6_port != w_t6->addr6.u6_port)
957 res = -1;
958 }
959 if (0 == res)
960 break;
961 w_t6 = w_t6->next;
962 }
963 return w_t6;
964 break;
965 default:
966 return NULL;
967 } 705 }
968 return NULL; 706
707 GNUNET_free (saddr);
708 return w;
969} 709}
970 710
971 711
712
713
972static void 714static void
973nat_add_address (void *cls, int add_remove, const struct sockaddr *addr, 715nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
974 socklen_t addrlen) 716 socklen_t addrlen)
975{ 717{
976 struct Plugin *plugin = cls; 718 struct Plugin *plugin = cls;
977 struct IPv4HttpAddressWrapper *w_t4 = NULL; 719 struct HttpAddressWrapper *w = NULL;
978 struct IPv6HttpAddressWrapper *w_t6 = NULL; 720 char *saddr;
979 int af; 721 size_t haddrlen;
980
981 af = addr->sa_family;
982 switch (af)
983 {
984 case AF_INET:
985 w_t4 = find_address (plugin, addr, addrlen);
986 if (w_t4 == NULL)
987 {
988 struct sockaddr_in *a4 = (struct sockaddr_in *) addr;
989 w_t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddressWrapper));
990 memcpy (&w_t4->addr.ipv4_addr, &a4->sin_addr, sizeof (struct in_addr));
991 w_t4->addr.u4_port = a4->sin_port;
992 722
993 GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, 723 GNUNET_asprintf(&saddr, "%s://%s", plugin->protocol, GNUNET_a2s (addr, addrlen));
994 plugin->ipv4_addr_tail, w_t4);
995
996 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
997 "Notifying transport to add IPv4 address `%s'\n",
998 http_plugin_address_to_string (NULL, &w_t4->addr,
999 sizeof (struct
1000 IPv4HttpAddress)));
1001 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr,
1002 sizeof (struct IPv4HttpAddress));
1003 }
1004 break;
1005 case AF_INET6:
1006 w_t6 = find_address (plugin, addr, addrlen);
1007 if (w_t6 == NULL)
1008 {
1009 w_t6 = GNUNET_malloc (sizeof (struct IPv6HttpAddressWrapper));
1010 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr;
1011 memcpy (&w_t6->addr6.ipv6_addr, &a6->sin6_addr, sizeof (struct in6_addr));
1012 w_t6->addr6.u6_port = a6->sin6_port;
1013 724
1014 GNUNET_CONTAINER_DLL_insert (plugin->ipv6_addr_head, 725 haddrlen = sizeof (struct HttpAddress) + strlen(saddr) + 1;
1015 plugin->ipv6_addr_tail, w_t6); 726 w = GNUNET_malloc (sizeof (struct HttpAddressWrapper));
727 w->addr = GNUNET_malloc (haddrlen);
728 w->addr->addr = &w->addr[1];
729 w->addr->addr_len = htonl (strlen(saddr) + 1);
730 memcpy (w->addr->addr, saddr, strlen(saddr) + 1);
731 GNUNET_free (saddr);
1016 732
1017 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 733 GNUNET_CONTAINER_DLL_insert(plugin->addr_head, plugin->addr_tail, w);
1018 "Notifying transport to add IPv6 address `%s'\n", 734 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
1019 http_plugin_address_to_string (NULL, &w_t6->addr6, 735 "Notifying transport to add address `%s'\n", w->addr->addr);
1020 sizeof (struct
1021 IPv6HttpAddress)));
1022 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6,
1023 sizeof (struct IPv6HttpAddress));
1024 }
1025 break;
1026 default:
1027 return;
1028 }
1029 736
737 plugin->env->notify_address (plugin->env->cls, add_remove, w->addr, haddrlen);
1030} 738}
1031 739
1032 740
@@ -1035,52 +743,23 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
1035 socklen_t addrlen) 743 socklen_t addrlen)
1036{ 744{
1037 struct Plugin *plugin = cls; 745 struct Plugin *plugin = cls;
1038 struct IPv4HttpAddressWrapper *w_t4 = NULL; 746 struct HttpAddressWrapper *w = NULL;
1039 struct IPv6HttpAddressWrapper *w_t6 = NULL; 747 size_t haddrlen;
1040 int af;
1041 748
1042 af = addr->sa_family; 749 w = find_address (plugin, addr, addrlen);
1043 switch (af) 750 if (NULL == w)
1044 { 751 return;
1045 case AF_INET:
1046 w_t4 = find_address (plugin, addr, addrlen);
1047 if (w_t4 == NULL)
1048 return;
1049
1050
1051 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1052 "Notifying transport to remove IPv4 address `%s'\n",
1053 http_plugin_address_to_string (NULL, &w_t4->addr,
1054 sizeof (struct
1055 IPv4HttpAddress)));
1056 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr,
1057 sizeof (struct IPv4HttpAddress));
1058
1059 GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail,
1060 w_t4);
1061 GNUNET_free (w_t4);
1062 break;
1063 case AF_INET6:
1064 w_t6 = find_address (plugin, addr, addrlen);
1065 if (w_t6 == NULL)
1066 return;
1067 752
1068 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 753 haddrlen = sizeof (struct HttpAddress) + ntohl (w->addr->addr_len);
1069 "Notifying transport to remove IPv6 address `%s'\n", 754 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1070 http_plugin_address_to_string (NULL, &w_t6->addr6, 755 "Notifying transport to remove address `%s'\n", http_plugin_address_to_string(NULL, w->addr, haddrlen));
1071 sizeof (struct
1072 IPv6HttpAddress)));
1073 756
1074 plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6,
1075 sizeof (struct IPv6HttpAddress));
1076 757
1077 GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail, 758 GNUNET_CONTAINER_DLL_remove (plugin->addr_head, plugin->addr_tail, w);
1078 w_t6); 759 plugin->env->notify_address (plugin->env->cls, add_remove, w->addr,
1079 GNUNET_free (w_t6); 760 sizeof (struct HttpAddress) + ntohl (w->addr->addr_len));
1080 break; 761 GNUNET_free (w->addr);
1081 default: 762 GNUNET_free (w);
1082 return;
1083 }
1084} 763}
1085 764
1086 765
@@ -1371,23 +1050,14 @@ stop_report_addresses (struct Plugin *plugin)
1371 GNUNET_NAT_unregister (plugin->nat); 1050 GNUNET_NAT_unregister (plugin->nat);
1372 1051
1373 /* Clean up addresses */ 1052 /* Clean up addresses */
1374 struct IPv4HttpAddressWrapper *w_t4; 1053 struct HttpAddressWrapper *w;
1375 struct IPv6HttpAddressWrapper *w_t6;
1376 1054
1377 while (plugin->ipv4_addr_head != NULL) 1055 while (plugin->addr_head != NULL)
1378 { 1056 {
1379 w_t4 = plugin->ipv4_addr_head; 1057 w = plugin->addr_head;
1380 GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail, 1058 GNUNET_CONTAINER_DLL_remove (plugin->addr_head, plugin->addr_tail, w);
1381 w_t4); 1059 GNUNET_free (w->addr);
1382 GNUNET_free (w_t4); 1060 GNUNET_free (w);
1383 }
1384
1385 while (plugin->ipv6_addr_head != NULL)
1386 {
1387 w_t6 = plugin->ipv6_addr_head;
1388 GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail,
1389 w_t6);
1390 GNUNET_free (w_t6);
1391 } 1061 }
1392} 1062}
1393 1063
@@ -1403,6 +1073,7 @@ notify_external_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *
1403{ 1073{
1404 struct Plugin *plugin = cls; 1074 struct Plugin *plugin = cls;
1405 struct HttpAddress *eaddr; 1075 struct HttpAddress *eaddr;
1076 char *addr;
1406 size_t eaddr_len; 1077 size_t eaddr_len;
1407 size_t uri_len; 1078 size_t uri_len;
1408 1079
@@ -1411,12 +1082,17 @@ notify_external_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *
1411 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 1082 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1412 return; 1083 return;
1413 1084
1414 uri_len = strlen (plugin->external_hostname) + 1; 1085 GNUNET_asprintf(&addr, "%s://%s", plugin->protocol, plugin->external_hostname);
1086 uri_len = strlen (addr) + 1;
1415 eaddr_len = sizeof (struct HttpAddress) + uri_len; 1087 eaddr_len = sizeof (struct HttpAddress) + uri_len;
1416 eaddr = GNUNET_malloc (eaddr_len); 1088 eaddr = GNUNET_malloc (eaddr_len);
1417 eaddr->addr_len = htonl (strlen (plugin->external_hostname) + 1); 1089 eaddr->addr_len = htonl (uri_len);
1418 eaddr->addr = (void *) &eaddr[1]; 1090 eaddr->addr = (void *) &eaddr[1];
1419 memcpy (&eaddr->addr, plugin->external_hostname, uri_len); 1091 memcpy (&eaddr->addr, addr, uri_len);
1092 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
1093 "Notifying transport about external hostname address `%s'\n", addr);
1094
1095 GNUNET_free (addr);
1420 plugin->env->notify_address (plugin->env->cls, GNUNET_YES, eaddr, eaddr_len); 1096 plugin->env->notify_address (plugin->env->cls, GNUNET_YES, eaddr, eaddr_len);
1421 plugin->ext_addr = eaddr; 1097 plugin->ext_addr = eaddr;
1422 plugin->ext_addr_len = eaddr_len; 1098 plugin->ext_addr_len = eaddr_len;