diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-22 10:06:18 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-22 10:06:18 +0000 |
commit | 6b2284a0d6ff73258622687c6ecd75d054f156f1 (patch) | |
tree | ab682fb56eb417673735be78939d95e2f325f59a /src | |
parent | 9c57c788237e66e4f40cf9919b583bb8ecf30523 (diff) | |
download | gnunet-6b2284a0d6ff73258622687c6ecd75d054f156f1.tar.gz gnunet-6b2284a0d6ff73258622687c6ecd75d054f156f1.zip |
changes
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 14 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 682 | ||||
-rw-r--r-- | src/transport/test_transport_api_http_reverse_proxy.conf | 7 |
3 files changed, 678 insertions, 25 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index f4790b0f6..c2dda5efc 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -55,7 +55,7 @@ | |||
55 | /** | 55 | /** |
56 | * Encapsulation of all of the state of the plugin. | 56 | * Encapsulation of all of the state of the plugin. |
57 | */ | 57 | */ |
58 | struct Plugin; | 58 | struct HTTP_Client_Plugin; |
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
@@ -77,7 +77,7 @@ struct Session | |||
77 | /** | 77 | /** |
78 | * Pointer to the global plugin struct. | 78 | * Pointer to the global plugin struct. |
79 | */ | 79 | */ |
80 | struct Plugin *plugin; | 80 | struct HTTP_Client_Plugin *plugin; |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * The client (used to identify this connection) | 83 | * The client (used to identify this connection) |
@@ -118,7 +118,7 @@ struct Session | |||
118 | /** | 118 | /** |
119 | * Encapsulation of all of the state of the plugin. | 119 | * Encapsulation of all of the state of the plugin. |
120 | */ | 120 | */ |
121 | struct Plugin | 121 | struct HTTP_Client_Plugin |
122 | { | 122 | { |
123 | /** | 123 | /** |
124 | * Our environment. | 124 | * Our environment. |
@@ -168,7 +168,7 @@ http_client_plugin_send (void *cls, | |||
168 | struct GNUNET_TIME_Relative to, | 168 | struct GNUNET_TIME_Relative to, |
169 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | 169 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) |
170 | { | 170 | { |
171 | struct Plugin *plugin = cls; | 171 | struct HTTP_Client_Plugin *plugin = cls; |
172 | int bytes_sent = 0; | 172 | int bytes_sent = 0; |
173 | 173 | ||
174 | GNUNET_assert (plugin != NULL); | 174 | GNUNET_assert (plugin != NULL); |
@@ -275,9 +275,9 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
275 | { | 275 | { |
276 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | 276 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; |
277 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 277 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
278 | struct Plugin *plugin; | 278 | struct HTTP_Client_Plugin *plugin; |
279 | 279 | ||
280 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 280 | plugin = GNUNET_malloc (sizeof (struct HTTP_Client_Plugin)); |
281 | plugin->env = env; | 281 | plugin->env = env; |
282 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 282 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
283 | api->cls = plugin; | 283 | api->cls = plugin; |
@@ -297,7 +297,7 @@ void * | |||
297 | LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | 297 | LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) |
298 | { | 298 | { |
299 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 299 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
300 | struct Plugin *plugin = api->cls; | 300 | struct HTTP_Client_Plugin *plugin = api->cls; |
301 | 301 | ||
302 | GNUNET_free (plugin); | 302 | GNUNET_free (plugin); |
303 | GNUNET_free (api); | 303 | GNUNET_free (api); |
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index da0c11e24..5eb0938d2 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -33,6 +33,10 @@ | |||
33 | #include "gnunet_transport_service.h" | 33 | #include "gnunet_transport_service.h" |
34 | #include "gnunet_transport_plugin.h" | 34 | #include "gnunet_transport_plugin.h" |
35 | 35 | ||
36 | #include "gnunet_container_lib.h" | ||
37 | #include "gnunet_nat_lib.h" | ||
38 | #include "microhttpd.h" | ||
39 | |||
36 | #if BUILD_HTTPS | 40 | #if BUILD_HTTPS |
37 | #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_server_init | 41 | #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_server_init |
38 | #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_server_done | 42 | #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_server_done |
@@ -77,7 +81,7 @@ struct Session | |||
77 | /** | 81 | /** |
78 | * Pointer to the global plugin struct. | 82 | * Pointer to the global plugin struct. |
79 | */ | 83 | */ |
80 | struct Plugin *plugin; | 84 | struct HTTP_Server_Plugin *plugin; |
81 | 85 | ||
82 | /** | 86 | /** |
83 | * The client (used to identify this connection) | 87 | * The client (used to identify this connection) |
@@ -118,7 +122,7 @@ struct Session | |||
118 | /** | 122 | /** |
119 | * Encapsulation of all of the state of the plugin. | 123 | * Encapsulation of all of the state of the plugin. |
120 | */ | 124 | */ |
121 | struct Plugin | 125 | struct HTTP_Server_Plugin |
122 | { | 126 | { |
123 | /** | 127 | /** |
124 | * Our environment. | 128 | * Our environment. |
@@ -130,6 +134,123 @@ struct Plugin | |||
130 | */ | 134 | */ |
131 | struct Session *sessions; | 135 | struct Session *sessions; |
132 | 136 | ||
137 | char *name; | ||
138 | char *protocol; | ||
139 | char *external_hostname; | ||
140 | |||
141 | /** | ||
142 | * Maximum number of sockets the plugin can use | ||
143 | * Each http inbound /outbound connections are two connections | ||
144 | */ | ||
145 | unsigned int max_connections; | ||
146 | |||
147 | /** | ||
148 | * External hostname the plugin can be connected to, can be different to | ||
149 | * the host's FQDN, used e.g. for reverse proxying | ||
150 | */ | ||
151 | struct HttpAddress *ext_addr; | ||
152 | |||
153 | /** | ||
154 | * External address length | ||
155 | */ | ||
156 | size_t ext_addr_len; | ||
157 | |||
158 | /** | ||
159 | * use IPv6 | ||
160 | */ | ||
161 | uint16_t use_ipv6; | ||
162 | |||
163 | /** | ||
164 | * use IPv4 | ||
165 | */ | ||
166 | uint16_t use_ipv4; | ||
167 | |||
168 | /** | ||
169 | * Port used | ||
170 | */ | ||
171 | uint16_t port; | ||
172 | |||
173 | /** | ||
174 | * Task calling transport service about external address | ||
175 | */ | ||
176 | GNUNET_SCHEDULER_TaskIdentifier notify_ext_task; | ||
177 | |||
178 | /** | ||
179 | * NAT handle & address management | ||
180 | */ | ||
181 | struct GNUNET_NAT_Handle *nat; | ||
182 | |||
183 | /** | ||
184 | * List of own addresses | ||
185 | */ | ||
186 | |||
187 | /** | ||
188 | * IPv4 addresses DLL head | ||
189 | */ | ||
190 | struct HttpAddressWrapper *addr_head; | ||
191 | |||
192 | /** | ||
193 | * IPv4 addresses DLL tail | ||
194 | */ | ||
195 | struct HttpAddressWrapper *addr_tail; | ||
196 | |||
197 | /** | ||
198 | * IPv4 server socket to bind to | ||
199 | */ | ||
200 | struct sockaddr_in *server_addr_v4; | ||
201 | |||
202 | /** | ||
203 | * IPv6 server socket to bind to | ||
204 | */ | ||
205 | struct sockaddr_in6 *server_addr_v6; | ||
206 | |||
207 | |||
208 | /** | ||
209 | * MHD IPv4 daemon | ||
210 | */ | ||
211 | struct MHD_Daemon *server_v4; | ||
212 | |||
213 | /** | ||
214 | * MHD IPv4 daemon | ||
215 | */ | ||
216 | struct MHD_Daemon *server_v6; | ||
217 | }; | ||
218 | |||
219 | GNUNET_NETWORK_STRUCT_BEGIN | ||
220 | |||
221 | /** | ||
222 | * HTTP addresses including a full URI | ||
223 | */ | ||
224 | struct HttpAddress | ||
225 | { | ||
226 | /** | ||
227 | * Length of the address following in NBO | ||
228 | */ | ||
229 | uint32_t addr_len GNUNET_PACKED; | ||
230 | |||
231 | /** | ||
232 | * Address following | ||
233 | */ | ||
234 | void *addr GNUNET_PACKED; | ||
235 | }; | ||
236 | GNUNET_NETWORK_STRUCT_END | ||
237 | |||
238 | /** | ||
239 | * Wrapper to manage addresses | ||
240 | */ | ||
241 | struct HttpAddressWrapper | ||
242 | { | ||
243 | /** | ||
244 | * Linked list next | ||
245 | */ | ||
246 | struct HttpAddressWrapper *next; | ||
247 | |||
248 | /** | ||
249 | * Linked list previous | ||
250 | */ | ||
251 | struct HttpAddressWrapper *prev; | ||
252 | |||
253 | struct HttpAddress *addr; | ||
133 | }; | 254 | }; |
134 | 255 | ||
135 | 256 | ||
@@ -168,7 +289,7 @@ http_server_plugin_send (void *cls, | |||
168 | struct GNUNET_TIME_Relative to, | 289 | struct GNUNET_TIME_Relative to, |
169 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | 290 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) |
170 | { | 291 | { |
171 | struct Plugin *plugin = cls; | 292 | struct HTTP_Server_Plugin *plugin = cls; |
172 | int bytes_sent = 0; | 293 | int bytes_sent = 0; |
173 | 294 | ||
174 | GNUNET_assert (plugin != NULL); | 295 | GNUNET_assert (plugin != NULL); |
@@ -264,8 +385,522 @@ http_server_plugin_address_to_string (void *cls, const void *addr, size_t addrle | |||
264 | return NULL; | 385 | return NULL; |
265 | } | 386 | } |
266 | 387 | ||
388 | /** | ||
389 | * Our external IP address/port mapping has changed. | ||
390 | * | ||
391 | * @param cls closure, the 'struct LocalAddrList' | ||
392 | * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean | ||
393 | * the previous (now invalid) one | ||
394 | * @param addr either the previous or the new public IP address | ||
395 | * @param addrlen actual lenght of the address | ||
396 | */ | ||
397 | static void | ||
398 | server_nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr, | ||
399 | socklen_t addrlen) | ||
400 | { | ||
401 | GNUNET_assert (cls != NULL); | ||
402 | struct HTTP_Server_Plugin *plugin = cls; | ||
403 | |||
404 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
405 | "NPMC called %s to address `%s'\n", | ||
406 | (add_remove == GNUNET_NO) ? "remove" : "add", | ||
407 | GNUNET_a2s (addr, addrlen)); | ||
408 | |||
409 | switch (add_remove) | ||
410 | { | ||
411 | case GNUNET_YES: | ||
412 | //nat_add_address (cls, add_remove, addr, addrlen); | ||
413 | break; | ||
414 | case GNUNET_NO: | ||
415 | //nat_remove_address (cls, add_remove, addr, addrlen); | ||
416 | break; | ||
417 | } | ||
418 | } | ||
267 | 419 | ||
268 | 420 | ||
421 | static int | ||
422 | server_get_addresses (struct HTTP_Server_Plugin *plugin, | ||
423 | const char *serviceName, | ||
424 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
425 | struct sockaddr ***addrs, socklen_t ** addr_lens) | ||
426 | { | ||
427 | int disablev6; | ||
428 | unsigned long long port; | ||
429 | struct addrinfo hints; | ||
430 | struct addrinfo *res; | ||
431 | struct addrinfo *pos; | ||
432 | struct addrinfo *next; | ||
433 | unsigned int i; | ||
434 | int resi; | ||
435 | int ret; | ||
436 | struct sockaddr **saddrs; | ||
437 | socklen_t *saddrlens; | ||
438 | char *hostname; | ||
439 | |||
440 | *addrs = NULL; | ||
441 | *addr_lens = NULL; | ||
442 | |||
443 | disablev6 = !plugin->use_ipv6; | ||
444 | |||
445 | port = 0; | ||
446 | if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT")) | ||
447 | { | ||
448 | GNUNET_break (GNUNET_OK == | ||
449 | GNUNET_CONFIGURATION_get_value_number (cfg, serviceName, | ||
450 | "PORT", &port)); | ||
451 | if (port > 65535) | ||
452 | { | ||
453 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
454 | _ | ||
455 | ("Require valid port number for service in configuration!\n")); | ||
456 | return GNUNET_SYSERR; | ||
457 | } | ||
458 | } | ||
459 | if (0 == port) | ||
460 | { | ||
461 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, plugin->name, | ||
462 | "Starting in listen only mode\n"); | ||
463 | return -1; /* listen only */ | ||
464 | } | ||
465 | |||
466 | |||
467 | if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO")) | ||
468 | { | ||
469 | GNUNET_break (GNUNET_OK == | ||
470 | GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, | ||
471 | "BINDTO", &hostname)); | ||
472 | } | ||
473 | else | ||
474 | hostname = NULL; | ||
475 | |||
476 | if (hostname != NULL) | ||
477 | { | ||
478 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
479 | "Resolving `%s' since that is where `%s' will bind to.\n", | ||
480 | hostname, serviceName); | ||
481 | memset (&hints, 0, sizeof (struct addrinfo)); | ||
482 | if (disablev6) | ||
483 | hints.ai_family = AF_INET; | ||
484 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || | ||
485 | (res == NULL)) | ||
486 | { | ||
487 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"), | ||
488 | hostname, gai_strerror (ret)); | ||
489 | GNUNET_free (hostname); | ||
490 | return GNUNET_SYSERR; | ||
491 | } | ||
492 | next = res; | ||
493 | i = 0; | ||
494 | while (NULL != (pos = next)) | ||
495 | { | ||
496 | next = pos->ai_next; | ||
497 | if ((disablev6) && (pos->ai_family == AF_INET6)) | ||
498 | continue; | ||
499 | i++; | ||
500 | } | ||
501 | if (0 == i) | ||
502 | { | ||
503 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
504 | _("Failed to find %saddress for `%s'.\n"), | ||
505 | disablev6 ? "IPv4 " : "", hostname); | ||
506 | freeaddrinfo (res); | ||
507 | GNUNET_free (hostname); | ||
508 | return GNUNET_SYSERR; | ||
509 | } | ||
510 | resi = i; | ||
511 | saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); | ||
512 | saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); | ||
513 | i = 0; | ||
514 | next = res; | ||
515 | while (NULL != (pos = next)) | ||
516 | { | ||
517 | next = pos->ai_next; | ||
518 | if ((disablev6) && (pos->ai_family == AF_INET6)) | ||
519 | continue; | ||
520 | if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0)) | ||
521 | continue; /* not TCP */ | ||
522 | if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0)) | ||
523 | continue; /* huh? */ | ||
524 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
525 | "Service will bind to `%s'\n", GNUNET_a2s (pos->ai_addr, | ||
526 | pos->ai_addrlen)); | ||
527 | if (pos->ai_family == AF_INET) | ||
528 | { | ||
529 | GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in)); | ||
530 | saddrlens[i] = pos->ai_addrlen; | ||
531 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
532 | memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); | ||
533 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
534 | } | ||
535 | else | ||
536 | { | ||
537 | GNUNET_assert (pos->ai_family == AF_INET6); | ||
538 | GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6)); | ||
539 | saddrlens[i] = pos->ai_addrlen; | ||
540 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
541 | memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); | ||
542 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); | ||
543 | } | ||
544 | i++; | ||
545 | } | ||
546 | GNUNET_free (hostname); | ||
547 | freeaddrinfo (res); | ||
548 | resi = i; | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | /* will bind against everything, just set port */ | ||
553 | if (disablev6) | ||
554 | { | ||
555 | /* V4-only */ | ||
556 | resi = 1; | ||
557 | i = 0; | ||
558 | saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); | ||
559 | saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); | ||
560 | |||
561 | saddrlens[i] = sizeof (struct sockaddr_in); | ||
562 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
563 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
564 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; | ||
565 | #endif | ||
566 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; | ||
567 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
568 | } | ||
569 | else | ||
570 | { | ||
571 | /* dual stack */ | ||
572 | resi = 2; | ||
573 | saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); | ||
574 | saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); | ||
575 | i = 0; | ||
576 | saddrlens[i] = sizeof (struct sockaddr_in6); | ||
577 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
578 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
579 | ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; | ||
580 | #endif | ||
581 | ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; | ||
582 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); | ||
583 | i++; | ||
584 | saddrlens[i] = sizeof (struct sockaddr_in); | ||
585 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
586 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
587 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; | ||
588 | #endif | ||
589 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; | ||
590 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
591 | } | ||
592 | } | ||
593 | *addrs = saddrs; | ||
594 | *addr_lens = saddrlens; | ||
595 | return resi; | ||
596 | } | ||
597 | |||
598 | static void | ||
599 | server_start_report_addresses (struct HTTP_Server_Plugin *plugin) | ||
600 | { | ||
601 | int res = GNUNET_OK; | ||
602 | struct sockaddr **addrs; | ||
603 | socklen_t *addrlens; | ||
604 | |||
605 | res = server_get_addresses (plugin, | ||
606 | plugin->name, plugin->env->cfg, | ||
607 | &addrs, &addrlens); | ||
608 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
609 | _("Found %u addresses to report to NAT service\n"), res); | ||
610 | |||
611 | if (GNUNET_SYSERR == res) | ||
612 | { | ||
613 | plugin->nat = NULL; | ||
614 | return; | ||
615 | } | ||
616 | |||
617 | plugin->nat = | ||
618 | GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, plugin->port, | ||
619 | (unsigned int) res, | ||
620 | (const struct sockaddr **) addrs, addrlens, | ||
621 | &server_nat_port_map_callback, NULL, plugin); | ||
622 | while (res > 0) | ||
623 | { | ||
624 | res--; | ||
625 | GNUNET_assert (addrs[res] != NULL); | ||
626 | GNUNET_free (addrs[res]); | ||
627 | } | ||
628 | GNUNET_free_non_null (addrs); | ||
629 | GNUNET_free_non_null (addrlens); | ||
630 | } | ||
631 | |||
632 | |||
633 | static void | ||
634 | server_stop_report_addresses (struct HTTP_Server_Plugin *plugin) | ||
635 | { | ||
636 | /* Stop NAT handle */ | ||
637 | if (NULL != plugin->nat) | ||
638 | GNUNET_NAT_unregister (plugin->nat); | ||
639 | |||
640 | /* Clean up addresses */ | ||
641 | struct HttpAddressWrapper *w; | ||
642 | |||
643 | while (plugin->addr_head != NULL) | ||
644 | { | ||
645 | w = plugin->addr_head; | ||
646 | GNUNET_CONTAINER_DLL_remove (plugin->addr_head, plugin->addr_tail, w); | ||
647 | GNUNET_free (w->addr); | ||
648 | GNUNET_free (w); | ||
649 | } | ||
650 | } | ||
651 | |||
652 | |||
653 | /** | ||
654 | * Check if IPv6 supported on this system | ||
655 | */ | ||
656 | static int | ||
657 | server_check_ipv6_support (struct HTTP_Server_Plugin *plugin) | ||
658 | { | ||
659 | struct GNUNET_NETWORK_Handle *desc = NULL; | ||
660 | int res = GNUNET_NO; | ||
661 | |||
662 | /* Probe IPv6 support */ | ||
663 | desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); | ||
664 | if (NULL == desc) | ||
665 | { | ||
666 | if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || | ||
667 | (errno == EACCES)) | ||
668 | { | ||
669 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); | ||
670 | } | ||
671 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, | ||
672 | _ | ||
673 | ("Disabling IPv6 since it is not supported on this system!\n")); | ||
674 | res = GNUNET_NO; | ||
675 | } | ||
676 | else | ||
677 | { | ||
678 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); | ||
679 | desc = NULL; | ||
680 | res = GNUNET_YES; | ||
681 | } | ||
682 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
683 | "Testing IPv6 on this system: %s\n", | ||
684 | (res == GNUNET_YES) ? "successful" : "failed"); | ||
685 | return res; | ||
686 | } | ||
687 | |||
688 | |||
689 | /** | ||
690 | * Function called when the service shuts down. Unloads our plugins | ||
691 | * and cancels pending validations. | ||
692 | * | ||
693 | * @param cls closure, unused | ||
694 | * @param tc task context (unused) | ||
695 | */ | ||
696 | static void | ||
697 | server_notify_external_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
698 | { | ||
699 | struct HTTP_Server_Plugin *plugin = cls; | ||
700 | struct HttpAddress *eaddr; | ||
701 | char *addr; | ||
702 | size_t eaddr_len; | ||
703 | size_t uri_len; | ||
704 | |||
705 | plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK; | ||
706 | |||
707 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
708 | return; | ||
709 | |||
710 | GNUNET_asprintf(&addr, "%s://%s", plugin->protocol, plugin->external_hostname); | ||
711 | uri_len = strlen (addr) + 1; | ||
712 | eaddr_len = sizeof (struct HttpAddress) + uri_len; | ||
713 | eaddr = GNUNET_malloc (eaddr_len); | ||
714 | eaddr->addr_len = htonl (uri_len); | ||
715 | eaddr->addr = (void *) &eaddr[1]; | ||
716 | memcpy (&eaddr->addr, addr, uri_len); | ||
717 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
718 | "Notifying transport about external hostname address `%s'\n", addr); | ||
719 | |||
720 | GNUNET_free (addr); | ||
721 | plugin->env->notify_address (plugin->env->cls, GNUNET_YES, eaddr, eaddr_len); | ||
722 | plugin->ext_addr = eaddr; | ||
723 | plugin->ext_addr_len = eaddr_len; | ||
724 | } | ||
725 | |||
726 | |||
727 | static int | ||
728 | server_configure_plugin (struct HTTP_Server_Plugin *plugin) | ||
729 | { | ||
730 | unsigned long long port; | ||
731 | unsigned long long max_connections; | ||
732 | char *bind4_address = NULL; | ||
733 | char *bind6_address = NULL; | ||
734 | |||
735 | /* Use IPv4? */ | ||
736 | if (GNUNET_CONFIGURATION_have_value | ||
737 | (plugin->env->cfg, plugin->name, "USE_IPv4")) | ||
738 | { | ||
739 | plugin->use_ipv4 = | ||
740 | GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, | ||
741 | "USE_IPv4"); | ||
742 | } | ||
743 | else | ||
744 | plugin->use_ipv4 = GNUNET_YES; | ||
745 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
746 | _("IPv4 support is %s\n"), | ||
747 | (plugin->use_ipv4 == GNUNET_YES) ? "enabled" : "disabled"); | ||
748 | |||
749 | /* Use IPv6? */ | ||
750 | if (GNUNET_CONFIGURATION_have_value | ||
751 | (plugin->env->cfg, plugin->name, "USE_IPv6")) | ||
752 | { | ||
753 | plugin->use_ipv6 = | ||
754 | GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, | ||
755 | "USE_IPv6"); | ||
756 | } | ||
757 | else | ||
758 | plugin->use_ipv6 = GNUNET_YES; | ||
759 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
760 | _("IPv6 support is %s\n"), | ||
761 | (plugin->use_ipv6 == GNUNET_YES) ? "enabled" : "disabled"); | ||
762 | |||
763 | if ((plugin->use_ipv4 == GNUNET_NO) && (plugin->use_ipv6 == GNUNET_NO)) | ||
764 | { | ||
765 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
766 | _ | ||
767 | ("Neither IPv4 nor IPv6 are enabled! Fix in configuration\n"), | ||
768 | plugin->name); | ||
769 | return GNUNET_SYSERR; | ||
770 | } | ||
771 | |||
772 | /* Reading port number from config file */ | ||
773 | if ((GNUNET_OK != | ||
774 | GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, | ||
775 | "PORT", &port)) || (port > 65535)) | ||
776 | { | ||
777 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
778 | _("Port is required! Fix in configuration\n"), | ||
779 | plugin->name); | ||
780 | return GNUNET_SYSERR; | ||
781 | } | ||
782 | plugin->port = port; | ||
783 | |||
784 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
785 | _("Using port %u\n"), plugin->port); | ||
786 | |||
787 | if ((plugin->use_ipv4 == GNUNET_YES) && | ||
788 | (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, | ||
789 | plugin->name, "BINDTO", &bind4_address))) | ||
790 | { | ||
791 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
792 | "Binding %s plugin to specific IPv4 address: `%s'\n", | ||
793 | plugin->protocol, bind4_address); | ||
794 | plugin->server_addr_v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); | ||
795 | if (1 != inet_pton (AF_INET, bind4_address, | ||
796 | &plugin->server_addr_v4->sin_addr)) | ||
797 | { | ||
798 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
799 | _ | ||
800 | ("Specific IPv4 address `%s' in configuration file is invalid!\n"), | ||
801 | bind4_address); | ||
802 | GNUNET_free (bind4_address); | ||
803 | GNUNET_free (plugin->server_addr_v4); | ||
804 | plugin->server_addr_v4 = NULL; | ||
805 | return GNUNET_SYSERR; | ||
806 | } | ||
807 | else | ||
808 | { | ||
809 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
810 | _("Binding to IPv4 address %s\n"), bind4_address); | ||
811 | plugin->server_addr_v4->sin_family = AF_INET; | ||
812 | plugin->server_addr_v4->sin_port = htons (plugin->port); | ||
813 | } | ||
814 | GNUNET_free (bind4_address); | ||
815 | } | ||
816 | |||
817 | if ((plugin->use_ipv6 == GNUNET_YES) && | ||
818 | (GNUNET_YES == | ||
819 | GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, | ||
820 | "BINDTO6", &bind6_address))) | ||
821 | { | ||
822 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
823 | "Binding %s plugin to specific IPv6 address: `%s'\n", | ||
824 | plugin->protocol, bind6_address); | ||
825 | plugin->server_addr_v6 = GNUNET_malloc (sizeof (struct sockaddr_in6)); | ||
826 | if (1 != | ||
827 | inet_pton (AF_INET6, bind6_address, &plugin->server_addr_v6->sin6_addr)) | ||
828 | { | ||
829 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
830 | _ | ||
831 | ("Specific IPv6 address `%s' in configuration file is invalid!\n"), | ||
832 | bind6_address); | ||
833 | GNUNET_free (bind6_address); | ||
834 | GNUNET_free (plugin->server_addr_v6); | ||
835 | plugin->server_addr_v6 = NULL; | ||
836 | return GNUNET_SYSERR; | ||
837 | } | ||
838 | else | ||
839 | { | ||
840 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
841 | _("Binding to IPv6 address %s\n"), bind6_address); | ||
842 | plugin->server_addr_v6->sin6_family = AF_INET6; | ||
843 | plugin->server_addr_v6->sin6_port = htons (plugin->port); | ||
844 | } | ||
845 | GNUNET_free (bind6_address); | ||
846 | } | ||
847 | |||
848 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, | ||
849 | "EXTERNAL_HOSTNAME", &plugin->external_hostname)) | ||
850 | { | ||
851 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
852 | _("Using external hostname `%s'\n"), plugin->external_hostname); | ||
853 | plugin->notify_ext_task = GNUNET_SCHEDULER_add_now (&server_notify_external_hostname, plugin); | ||
854 | } | ||
855 | else | ||
856 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
857 | "No external hostname configured\n"); | ||
858 | |||
859 | |||
860 | /* Optional parameters */ | ||
861 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, | ||
862 | plugin->name, | ||
863 | "MAX_CONNECTIONS", &max_connections)) | ||
864 | max_connections = 128; | ||
865 | plugin->max_connections = max_connections; | ||
866 | |||
867 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
868 | _("Maximum number of connections is %u\n"), | ||
869 | plugin->max_connections); | ||
870 | |||
871 | return GNUNET_OK; | ||
872 | } | ||
873 | |||
874 | |||
875 | /** | ||
876 | * Exit point from the plugin. | ||
877 | */ | ||
878 | void * | ||
879 | LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | ||
880 | { | ||
881 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | ||
882 | struct HTTP_Server_Plugin *plugin = api->cls; | ||
883 | |||
884 | if (GNUNET_SCHEDULER_NO_TASK != plugin->notify_ext_task) | ||
885 | { | ||
886 | GNUNET_SCHEDULER_cancel (plugin->notify_ext_task); | ||
887 | plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK; | ||
888 | } | ||
889 | |||
890 | /* Stop to report addresses to transport service */ | ||
891 | server_stop_report_addresses (plugin); | ||
892 | |||
893 | /* Clean up */ | ||
894 | GNUNET_free_non_null (plugin->external_hostname); | ||
895 | GNUNET_free_non_null (plugin->server_addr_v4); | ||
896 | GNUNET_free_non_null (plugin->server_addr_v6); | ||
897 | |||
898 | |||
899 | GNUNET_free (plugin); | ||
900 | GNUNET_free (api); | ||
901 | return NULL; | ||
902 | } | ||
903 | |||
269 | 904 | ||
270 | /** | 905 | /** |
271 | * Entry point for the plugin. | 906 | * Entry point for the plugin. |
@@ -275,9 +910,9 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
275 | { | 910 | { |
276 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | 911 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; |
277 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 912 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
278 | struct Plugin *plugin; | 913 | struct HTTP_Server_Plugin *plugin; |
279 | 914 | ||
280 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 915 | plugin = GNUNET_malloc (sizeof (struct HTTP_Server_Plugin)); |
281 | plugin->env = env; | 916 | plugin->env = env; |
282 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 917 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
283 | api->cls = plugin; | 918 | api->cls = plugin; |
@@ -286,22 +921,35 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
286 | api->address_pretty_printer = &http_server_plugin_address_pretty_printer; | 921 | api->address_pretty_printer = &http_server_plugin_address_pretty_printer; |
287 | api->check_address = &http_server_plugin_address_suggested; | 922 | api->check_address = &http_server_plugin_address_suggested; |
288 | api->address_to_string = &http_server_plugin_address_to_string; | 923 | api->address_to_string = &http_server_plugin_address_to_string; |
924 | |||
925 | #if BUILD_HTTPS | ||
926 | plugin->name = "transport-https_server"; | ||
927 | plugin->protocol = "https"; | ||
928 | #else | ||
929 | plugin->name = "transport-http_server"; | ||
930 | plugin->protocol = "http"; | ||
931 | #endif | ||
932 | |||
933 | /* Configure plugin */ | ||
934 | if (GNUNET_SYSERR == server_configure_plugin (plugin)); | ||
935 | { | ||
936 | GNUNET_break (0); | ||
937 | LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); | ||
938 | return NULL; | ||
939 | } | ||
940 | GNUNET_break (0); | ||
941 | |||
942 | /* Check IPv6 support */ | ||
943 | if (GNUNET_YES == plugin->use_ipv6) | ||
944 | plugin->use_ipv6 = server_check_ipv6_support (plugin); | ||
945 | |||
946 | /* Report addresses to transport service */ | ||
947 | server_start_report_addresses (plugin); | ||
948 | |||
289 | return api; | 949 | return api; |
290 | } | 950 | } |
291 | 951 | ||
292 | 952 | ||
293 | /** | ||
294 | * Exit point from the plugin. | ||
295 | */ | ||
296 | void * | ||
297 | LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | ||
298 | { | ||
299 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | ||
300 | struct Plugin *plugin = api->cls; | ||
301 | 953 | ||
302 | GNUNET_free (plugin); | ||
303 | GNUNET_free (api); | ||
304 | return NULL; | ||
305 | } | ||
306 | 954 | ||
307 | /* end of plugin_transport_http_server.c */ | 955 | /* end of plugin_transport_http_server.c */ |
diff --git a/src/transport/test_transport_api_http_reverse_proxy.conf b/src/transport/test_transport_api_http_reverse_proxy.conf index 35fdff2bb..60537a4a2 100644 --- a/src/transport/test_transport_api_http_reverse_proxy.conf +++ b/src/transport/test_transport_api_http_reverse_proxy.conf | |||
@@ -9,6 +9,10 @@ DEFAULTCONFIG = test_transport_api_http_reverse_proxy.conf | |||
9 | [transport-http_server] | 9 | [transport-http_server] |
10 | PORT = 12080 | 10 | PORT = 12080 |
11 | EXTERNAL_HOSTNAME = fulcrum.net.in.tum.de:12080/peer | 11 | EXTERNAL_HOSTNAME = fulcrum.net.in.tum.de:12080/peer |
12 | USE_IPV4 = YES | ||
13 | USE_IPV6 = YES | ||
14 | BINDTO = 127.0.0.1 | ||
15 | BINDTO6 = ::1 | ||
12 | 16 | ||
13 | [arm] | 17 | [arm] |
14 | PORT = 12085 | 18 | PORT = 12085 |
@@ -30,7 +34,8 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock | |||
30 | [transport] | 34 | [transport] |
31 | #DEBUG = YES | 35 | #DEBUG = YES |
32 | PORT = 12081 | 36 | PORT = 12081 |
33 | PLUGINS = http_client http_server | 37 | PLUGINS = http_server |
38 | # http_client | ||
34 | #BINARY = .libs/gnunet-service-transport | 39 | #BINARY = .libs/gnunet-service-transport |
35 | UNIXPATH = /tmp/gnunet-p1-service-transport.sock | 40 | UNIXPATH = /tmp/gnunet-p1-service-transport.sock |
36 | PREFIX = valgrind --leak-check=full | 41 | PREFIX = valgrind --leak-check=full |