diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-06-30 09:57:57 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-06-30 09:57:57 +0000 |
commit | c6435cda97c1be4a38bb45a0e6bfe2daa05b824c (patch) | |
tree | 32c08d69012e7c9fb68a3d13351bd2df6b5aa45f /src/transport/plugin_transport_http.c | |
parent | a8299e6ef6bcbf8c44641383a0de86a88fffa9ee (diff) | |
download | gnunet-c6435cda97c1be4a38bb45a0e6bfe2daa05b824c.tar.gz gnunet-c6435cda97c1be4a38bb45a0e6bfe2daa05b824c.zip |
pre-lunch commit of nat implementation for http(s)
Diffstat (limited to 'src/transport/plugin_transport_http.c')
-rw-r--r-- | src/transport/plugin_transport_http.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index 9311c77fd..a7e5a338c 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "gnunet_container_lib.h" | 37 | #include "gnunet_container_lib.h" |
38 | #include "gnunet_transport_plugin.h" | 38 | #include "gnunet_transport_plugin.h" |
39 | #include "gnunet_os_lib.h" | 39 | #include "gnunet_os_lib.h" |
40 | #include "gnunet_nat_lib.h" | ||
40 | #include "microhttpd.h" | 41 | #include "microhttpd.h" |
41 | #include <curl/curl.h> | 42 | #include <curl/curl.h> |
42 | 43 | ||
@@ -413,6 +414,11 @@ struct Plugin | |||
413 | CURLM * multi_handle; | 414 | CURLM * multi_handle; |
414 | 415 | ||
415 | /** | 416 | /** |
417 | * Our handle to the NAT module. | ||
418 | */ | ||
419 | struct GNUNET_NAT_Handle *nat; | ||
420 | |||
421 | /** | ||
416 | * ipv4 DLL head | 422 | * ipv4 DLL head |
417 | */ | 423 | */ |
418 | struct IPv4HttpAddress * ipv4_addr_head; | 424 | struct IPv4HttpAddress * ipv4_addr_head; |
@@ -2877,6 +2883,135 @@ http_plugin_address_to_string (void *cls, | |||
2877 | } | 2883 | } |
2878 | 2884 | ||
2879 | /** | 2885 | /** |
2886 | * Function called by the NAT subsystem suggesting another peer wants | ||
2887 | * to connect to us via connection reversal. Try to connect back to the | ||
2888 | * given IP. | ||
2889 | * | ||
2890 | * @param cls closure | ||
2891 | * @param addr address to try | ||
2892 | * @param addrlen number of bytes in addr | ||
2893 | */ | ||
2894 | static void | ||
2895 | try_connection_reversal (void *cls, | ||
2896 | const struct sockaddr *addr, | ||
2897 | socklen_t addrlen) | ||
2898 | { | ||
2899 | |||
2900 | } | ||
2901 | |||
2902 | /** | ||
2903 | * Our external IP address/port mapping has changed. | ||
2904 | * | ||
2905 | * @param cls closure, the 'struct LocalAddrList' | ||
2906 | * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean | ||
2907 | * the previous (now invalid) one | ||
2908 | * @param addr either the previous or the new public IP address | ||
2909 | * @param addrlen actual lenght of the address | ||
2910 | */ | ||
2911 | static void | ||
2912 | tcp_nat_port_map_callback (void *cls, | ||
2913 | int add_remove, | ||
2914 | const struct sockaddr *addr, | ||
2915 | socklen_t addrlen) | ||
2916 | { | ||
2917 | struct Plugin *plugin = cls; | ||
2918 | struct IPv4HttpAddress *t4; | ||
2919 | struct IPv6HttpAddress *t6; | ||
2920 | void *arg; | ||
2921 | size_t args; | ||
2922 | int af; | ||
2923 | |||
2924 | |||
2925 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2926 | "tcp", | ||
2927 | "NPMC called with %d for address `%s'\n", | ||
2928 | add_remove, | ||
2929 | GNUNET_a2s (addr, addrlen)); | ||
2930 | /* convert 'addr' to our internal format */ | ||
2931 | |||
2932 | GNUNET_assert(cls !=NULL); | ||
2933 | af = addr->sa_family; | ||
2934 | if ((af == AF_INET) && | ||
2935 | (plugin->use_ipv4 == GNUNET_YES) && | ||
2936 | (plugin->bind6_address == NULL) ) { | ||
2937 | |||
2938 | struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr; | ||
2939 | t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress)); | ||
2940 | // Not skipping loopback addresses | ||
2941 | |||
2942 | |||
2943 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
2944 | t4->u_port = htons (plugin->port_inbound); | ||
2945 | if (plugin->bind4_address != NULL) { | ||
2946 | if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr))) | ||
2947 | { | ||
2948 | GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head, | ||
2949 | plugin->ipv4_addr_tail,t4); | ||
2950 | plugin->env->notify_address(plugin->env->cls, | ||
2951 | GNUNET_YES, | ||
2952 | t4, sizeof (struct IPv4HttpAddress)); | ||
2953 | return; | ||
2954 | } | ||
2955 | GNUNET_free (t4); | ||
2956 | return; | ||
2957 | } | ||
2958 | else | ||
2959 | { | ||
2960 | GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, | ||
2961 | plugin->ipv4_addr_tail, | ||
2962 | t4); | ||
2963 | plugin->env->notify_address(plugin->env->cls, | ||
2964 | GNUNET_YES, | ||
2965 | t4, sizeof (struct IPv4HttpAddress)); | ||
2966 | return; | ||
2967 | } | ||
2968 | } | ||
2969 | if ((af == AF_INET6) && | ||
2970 | (plugin->use_ipv6 == GNUNET_YES) && | ||
2971 | (plugin->bind4_address == NULL) ) { | ||
2972 | |||
2973 | struct in6_addr bnd_cmp6 = ((struct sockaddr_in6 *) addr)->sin6_addr; | ||
2974 | |||
2975 | t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress)); | ||
2976 | GNUNET_assert(t6 != NULL); | ||
2977 | |||
2978 | if (plugin->bind6_address != NULL) { | ||
2979 | if (0 == memcmp(&plugin->bind6_address->sin6_addr, | ||
2980 | &bnd_cmp6, | ||
2981 | sizeof (struct in6_addr))) { | ||
2982 | memcpy (&t6->ipv6_addr, | ||
2983 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
2984 | sizeof (struct in6_addr)); | ||
2985 | t6->u6_port = htons (plugin->port_inbound); | ||
2986 | plugin->env->notify_address(plugin->env->cls, | ||
2987 | GNUNET_YES, | ||
2988 | t6, sizeof (struct IPv6HttpAddress)); | ||
2989 | GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head, | ||
2990 | plugin->ipv6_addr_tail, | ||
2991 | t6); | ||
2992 | return; | ||
2993 | } | ||
2994 | GNUNET_free (t6); | ||
2995 | return; | ||
2996 | } | ||
2997 | memcpy (&t6->ipv6_addr, | ||
2998 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
2999 | sizeof (struct in6_addr)); | ||
3000 | t6->u6_port = htons (plugin->port_inbound); | ||
3001 | GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6); | ||
3002 | |||
3003 | plugin->env->notify_address(plugin->env->cls, | ||
3004 | GNUNET_YES, | ||
3005 | t6, sizeof (struct IPv6HttpAddress)); | ||
3006 | } | ||
3007 | |||
3008 | /* modify our published address list */ | ||
3009 | plugin->env->notify_address (plugin->env->cls, | ||
3010 | add_remove, | ||
3011 | arg, args); | ||
3012 | } | ||
3013 | |||
3014 | /** | ||
2880 | * Notify transport service about address | 3015 | * Notify transport service about address |
2881 | * | 3016 | * |
2882 | * @param cls the plugin | 3017 | * @param cls the plugin |
@@ -2963,6 +3098,9 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
2963 | plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; | 3098 | plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; |
2964 | } | 3099 | } |
2965 | 3100 | ||
3101 | if (plugin->nat != NULL) | ||
3102 | GNUNET_NAT_unregister (plugin->nat); | ||
3103 | |||
2966 | GNUNET_free_non_null (plugin->bind4_address); | 3104 | GNUNET_free_non_null (plugin->bind4_address); |
2967 | GNUNET_free_non_null (plugin->bind6_address); | 3105 | GNUNET_free_non_null (plugin->bind6_address); |
2968 | GNUNET_free_non_null(plugin->bind_hostname); | 3106 | GNUNET_free_non_null(plugin->bind_hostname); |
@@ -3023,6 +3161,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
3023 | struct GNUNET_TIME_Relative gn_timeout; | 3161 | struct GNUNET_TIME_Relative gn_timeout; |
3024 | long long unsigned int port; | 3162 | long long unsigned int port; |
3025 | unsigned long long tneigh; | 3163 | unsigned long long tneigh; |
3164 | int addr_count = 0; | ||
3026 | char * component_name; | 3165 | char * component_name; |
3027 | #if BUILD_HTTPS | 3166 | #if BUILD_HTTPS |
3028 | char * key_file = NULL; | 3167 | char * key_file = NULL; |
@@ -3398,6 +3537,56 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
3398 | return NULL; | 3537 | return NULL; |
3399 | } | 3538 | } |
3400 | 3539 | ||
3540 | if (plugin->bind4_address != NULL) | ||
3541 | addr_count++; | ||
3542 | if (plugin->bind6_address != NULL) | ||
3543 | addr_count++; | ||
3544 | |||
3545 | struct sockaddr **addrs; | ||
3546 | socklen_t *addrlens; | ||
3547 | int ret; | ||
3548 | |||
3549 | if (GNUNET_SYSERR != | ||
3550 | (ret = GNUNET_SERVICE_get_server_addresses ("transport-http", | ||
3551 | env->cfg, | ||
3552 | &addrs, | ||
3553 | &addrlens))) | ||
3554 | { | ||
3555 | |||
3556 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
3557 | component_name, | ||
3558 | "addresses %u\n",ret); | ||
3559 | /* | ||
3560 | plugin->nat = GNUNET_NAT_register (env->cfg, | ||
3561 | GNUNET_YES, | ||
3562 | port, | ||
3563 | (unsigned int) ret, | ||
3564 | (const struct sockaddr **) addrs, | ||
3565 | addrlens, | ||
3566 | &tcp_nat_port_map_callback, | ||
3567 | &try_connection_reversal, | ||
3568 | plugin); | ||
3569 | |||
3570 | while (ret > 0) | ||
3571 | { | ||
3572 | ret--; | ||
3573 | GNUNET_assert (addrs[ret] != NULL); | ||
3574 | GNUNET_free (addrs[ret]); | ||
3575 | } | ||
3576 | GNUNET_free_non_null (addrs); | ||
3577 | GNUNET_free_non_null (addrlens);*/ | ||
3578 | } | ||
3579 | else | ||
3580 | { | ||
3581 | plugin->nat = GNUNET_NAT_register (env->cfg, | ||
3582 | GNUNET_YES, | ||
3583 | 0, | ||
3584 | 0, NULL, NULL, | ||
3585 | NULL, | ||
3586 | &try_connection_reversal, | ||
3587 | plugin); | ||
3588 | } | ||
3589 | |||
3401 | plugin->peers = GNUNET_CONTAINER_multihashmap_create (10); | 3590 | plugin->peers = GNUNET_CONTAINER_multihashmap_create (10); |
3402 | 3591 | ||
3403 | GNUNET_free(component_name); | 3592 | GNUNET_free(component_name); |