X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fplugin_transport_http_common.c;h=eb8320c8e698212ac731100be3bae264b067eb77;hb=5126e9d42b24a0a6cf26de79b65bcd23790dee9b;hp=f5712db58a867fe5631c6f5887fc02ce68e8702c;hpb=800c3b54ba9a67ad995d6b5c1ecbffe224f4676d;p=oweals%2Fgnunet.git diff --git a/src/transport/plugin_transport_http_common.c b/src/transport/plugin_transport_http_common.c index f5712db58..eb8320c8e 100644 --- a/src/transport/plugin_transport_http_common.c +++ b/src/transport/plugin_transport_http_common.c @@ -1,52 +1,43 @@ /* - This file is part of GNUnet - (C) 2002-2013 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ + This file is part of GNUnet + Copyright (C) 2002-2013 GNUnet e.V. + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ /** * @file transport/plugin_transport_http_common.c - * @brief functionality shared by http client and server transport service plugin + * @brief functionality shared between http(s)client plugins * @author Matthias Wachs */ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_transport_plugin.h" #include "plugin_transport_http_common.h" - - -struct SplittedHTTPAddress -{ - char *protocol; - char *host; - char *path; - int port; -}; - +#include "gnunet_resolver_service.h" static void http_clean_splitted (struct SplittedHTTPAddress *spa) { if (NULL != spa) { - GNUNET_free_non_null (spa->protocol); - GNUNET_free_non_null (spa->host); - GNUNET_free_non_null (spa->path); - GNUNET_free_non_null (spa); + GNUNET_free_non_null(spa->protocol); + GNUNET_free_non_null(spa->host); + GNUNET_free_non_null(spa->path); + GNUNET_free_non_null(spa); } } @@ -69,9 +60,9 @@ http_split_address (const char * addr) host_start = strstr (src, "://"); if (NULL == host_start) { - GNUNET_free (src); - GNUNET_free (sp); - return NULL; + GNUNET_free(src); + GNUNET_free(sp); + return NULL ; } host_start[0] = '\0'; sp->protocol = GNUNET_strdup (protocol_start); @@ -79,10 +70,10 @@ http_split_address (const char * addr) host_start += strlen ("://"); if (strlen (host_start) == 0) { - GNUNET_free (src); - GNUNET_free (sp->protocol); - GNUNET_free (sp); - return NULL; + GNUNET_free(src); + GNUNET_free(sp->protocol); + GNUNET_free(sp); + return NULL ; } /* Find path start */ @@ -95,41 +86,41 @@ http_split_address (const char * addr) else sp->path = GNUNET_strdup (""); - if (strlen(host_start) < 1) + if (strlen (host_start) < 1) { - GNUNET_free (src); - GNUNET_free (sp->protocol); - GNUNET_free (sp->path); - GNUNET_free (sp); - return NULL; + GNUNET_free(src); + GNUNET_free(sp->protocol); + GNUNET_free(sp->path); + GNUNET_free(sp); + return NULL ; } if (NULL != (port_start = strrchr (host_start, ':'))) { /* *We COULD have a port, but also an IPv6 address! */ - if (NULL != (v6_end = strchr(host_start, ']'))) + if (NULL != (v6_end = strchr (host_start, ']'))) { - if (v6_end < port_start) + if (v6_end < port_start) { /* IPv6 address + port */ port_start[0] = '\0'; - port_start ++; + port_start++; sp->port = atoi (port_start); if ((0 == sp->port) || (65535 < sp->port)) { - GNUNET_free (src); - GNUNET_free (sp->protocol); - GNUNET_free (sp->path); - GNUNET_free (sp); - return NULL; + GNUNET_free(src); + GNUNET_free(sp->protocol); + GNUNET_free(sp->path); + GNUNET_free(sp); + return NULL ; } } else { - /* IPv6 address + no port */ - if (0 == strcmp(sp->protocol, "https")) + /* IPv6 address + no port */ + if (0 == strcmp (sp->protocol, "https")) sp->port = HTTPS_DEFAULT_PORT; - else if (0 == strcmp(sp->protocol, "http")) + else if (0 == strcmp (sp->protocol, "http")) sp->port = HTTP_DEFAULT_PORT; } } @@ -137,50 +128,276 @@ http_split_address (const char * addr) { /* No IPv6 address */ port_start[0] = '\0'; - port_start ++; + port_start++; sp->port = atoi (port_start); if ((0 == sp->port) || (65535 < sp->port)) - { - GNUNET_free (src); - GNUNET_free (sp->protocol); - GNUNET_free (sp->path); - GNUNET_free (sp); - return NULL; - } + { + GNUNET_free(src); + GNUNET_free(sp->protocol); + GNUNET_free(sp->path); + GNUNET_free(sp); + return NULL ; + } } } else { /* No ':' as port separator, default port for protocol */ - if (0 == strcmp(sp->protocol, "https")) + if (0 == strcmp (sp->protocol, "https")) sp->port = HTTPS_DEFAULT_PORT; - else if (0 == strcmp(sp->protocol, "http")) + else if (0 == strcmp (sp->protocol, "http")) sp->port = HTTP_DEFAULT_PORT; else { - GNUNET_break (0); - GNUNET_free (src); - GNUNET_free (sp->protocol); - GNUNET_free (sp->path); - GNUNET_free (sp); - return NULL; + GNUNET_break(0); + GNUNET_free(src); + GNUNET_free(sp->protocol); + GNUNET_free(sp->path); + GNUNET_free(sp); + return NULL ; } } if (strlen (host_start) > 0) sp->host = GNUNET_strdup (host_start); else { - GNUNET_break (0); - GNUNET_free (src); - GNUNET_free (sp->protocol); - GNUNET_free (sp->path); - GNUNET_free (sp); - return NULL; + GNUNET_break(0); + GNUNET_free(src); + GNUNET_free(sp->protocol); + GNUNET_free(sp->path); + GNUNET_free(sp); + return NULL ; } - GNUNET_free (src); + GNUNET_free(src); return sp; } +/** + * Closure for #append_port(). + */ +struct PrettyPrinterContext +{ + /** + * DLL + */ + struct PrettyPrinterContext *next; + + /** + * DLL + */ + struct PrettyPrinterContext *prev; + + /** + * Resolver handle + */ + struct GNUNET_RESOLVER_RequestHandle *resolver_handle; + + /** + * Function to call with the result. + */ + GNUNET_TRANSPORT_AddressStringCallback asc; + + /** + * Clsoure for @e asc. + */ + void *asc_cls; + + /** + * Timeout task + */ + struct GNUNET_SCHEDULER_Task * timeout_task; + + /** + * Splitted Address + */ + struct SplittedHTTPAddress *saddr; + + /** + * Plugin String + */ + char *plugin; + + /** + * Was conversion successful + */ + int sucess; + + /** + * Address options + */ + uint32_t options; +}; + +/** + * Head of PPC list + */ +static struct PrettyPrinterContext *dll_ppc_head; + +/** + * Tail of PPC list + */ +static struct PrettyPrinterContext *dll_ppc_tail; + +/** + * Function called for a quick conversion of the binary address to + * a numeric address. Note that the caller must not free the + * address and that the next call to this function is allowed + * to override the address again. + * + * @param plugin the name of the plugin + * @param saddr the splitted http address + * @param options address options + * @param dnsresult dns name to include in address + * @return string representing the same address or NULL on error + */ +static const char * +http_common_plugin_dnsresult_to_address (const char *plugin, + const struct SplittedHTTPAddress *saddr, + uint32_t options, + const char *dnsresult) +{ + static char rbuf[1024]; + char *res; + + GNUNET_asprintf (&res, "%s.%u.%s://%s:%u%s", plugin, options, saddr->protocol, + dnsresult, saddr->port, saddr->path); + if (strlen (res) + 1 < 500) + { + GNUNET_memcpy (rbuf, res, strlen (res) + 1); + GNUNET_free(res); + return rbuf; + } + GNUNET_break(0); + GNUNET_free(res); + return NULL ; +} + + +static void +http_common_dns_reverse_lookup_cb (void *cls, const char *hostname) +{ + struct PrettyPrinterContext *ppc = cls; + + if (NULL != hostname) + { + ppc->asc (ppc->asc_cls, + http_common_plugin_dnsresult_to_address (ppc->plugin, ppc->saddr, ppc->options, + hostname), GNUNET_OK); + ppc->sucess = GNUNET_YES; + + } + else + { + ppc->asc (ppc->asc_cls, NULL, + (GNUNET_NO == ppc->sucess) ? GNUNET_SYSERR : GNUNET_OK); + + GNUNET_CONTAINER_DLL_remove(dll_ppc_head, dll_ppc_tail, ppc); + http_clean_splitted (ppc->saddr); + GNUNET_free(ppc->plugin); + GNUNET_free(ppc); + } +} + + +static int +http_common_dns_reverse_lookup (const struct sockaddr *sockaddr, + socklen_t sockaddr_len, + const char *type, + struct SplittedHTTPAddress *saddr, + uint32_t options, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_AddressStringCallback asc, + void *asc_cls) +{ + struct PrettyPrinterContext *ppc; + + ppc = GNUNET_new (struct PrettyPrinterContext); + ppc->saddr = saddr; + ppc->asc = asc; + ppc->asc_cls = asc_cls; + ppc->plugin = GNUNET_strdup (type); + ppc->options = options; + ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sockaddr, + sockaddr_len, + GNUNET_YES, + timeout, + &http_common_dns_reverse_lookup_cb, + ppc); + if (NULL == ppc->resolver_handle) + { + GNUNET_free(ppc->plugin); + GNUNET_free(ppc); + return GNUNET_SYSERR; + } + GNUNET_CONTAINER_DLL_insert (dll_ppc_head, + dll_ppc_tail, + ppc); + return GNUNET_OK; +} + + +static void +http_common_dns_ip_lookup_cb (void *cls, + const struct sockaddr *addr, + socklen_t addrlen) +{ + struct PrettyPrinterContext *ppc = cls; + + if (NULL != addr) + { + ppc->asc (ppc->asc_cls, + http_common_plugin_dnsresult_to_address (ppc->plugin, ppc->saddr, ppc->options, + GNUNET_a2s (addr, addrlen)), GNUNET_OK); + ppc->sucess = GNUNET_YES; + ppc->asc (ppc->asc_cls, GNUNET_a2s (addr, addrlen), GNUNET_OK); + } + else + { + ppc->asc (ppc->asc_cls, NULL, + (GNUNET_NO == ppc->sucess) ? GNUNET_SYSERR : GNUNET_OK); + + GNUNET_CONTAINER_DLL_remove(dll_ppc_head, dll_ppc_tail, ppc); + GNUNET_free(ppc->plugin); + http_clean_splitted (ppc->saddr); + GNUNET_free(ppc); + } +} + + +static int +http_common_dns_ip_lookup (const char *name, + const char *type, + struct SplittedHTTPAddress *saddr, + uint32_t options, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls) +{ + struct PrettyPrinterContext *ppc; + + ppc = GNUNET_new (struct PrettyPrinterContext); + ppc->sucess = GNUNET_NO; + ppc->saddr = saddr; + ppc->asc = asc; + ppc->asc_cls = asc_cls; + ppc->plugin = GNUNET_strdup (type); + ppc->options = options; + ppc->resolver_handle = GNUNET_RESOLVER_ip_get (name, + AF_UNSPEC, + timeout, + &http_common_dns_ip_lookup_cb, + ppc); + if (NULL == ppc->resolver_handle) + { + GNUNET_free(ppc->plugin); + GNUNET_free(ppc); + return GNUNET_SYSERR; + } + GNUNET_CONTAINER_DLL_insert (dll_ppc_head, + dll_ppc_tail, + ppc); + return GNUNET_OK; +} + /** * Convert the transports address to a nice, human-readable @@ -197,8 +414,7 @@ http_split_address (const char * addr) * @param asc_cls closure for @a asc */ void -http_common_plugin_address_pretty_printer (void *cls, - const char *type, +http_common_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, size_t addrlen, int numeric, @@ -207,18 +423,136 @@ http_common_plugin_address_pretty_printer (void *cls, void *asc_cls) { const struct HttpAddress *address = addr; + struct SplittedHTTPAddress *saddr; + struct sockaddr *sock_addr; + const char *ret; + char *addr_str; + int res; + int have_ip; + + saddr = NULL; + sock_addr = NULL; + if ( (addrlen < sizeof(struct HttpAddress)) || + (addrlen != http_common_address_get_size (address)) ) + { + GNUNET_break(0); + goto handle_error; + } + + addr_str = (char *) &address[1]; + if (addr_str[ntohl (address->urlen) - 1] != '\0') + { + GNUNET_break(0); + goto handle_error; + } + + saddr = http_split_address (addr_str); + if (NULL == saddr) + { + GNUNET_break(0); + goto handle_error; + } - if (NULL - == http_common_plugin_address_to_string (NULL, type, address, addrlen)) - asc (asc_cls, NULL, GNUNET_SYSERR); + sock_addr = http_common_socket_from_address (addr, addrlen, &res); + if (GNUNET_SYSERR == res) + { + /* Malformed address */ + GNUNET_break (0); + goto handle_error; + } + else if (GNUNET_NO == res) + { + /* Could not convert to IP */ + have_ip = GNUNET_NO; + } + else if (GNUNET_YES == res) + { + /* Converted to IP */ + have_ip = GNUNET_YES; + } else - asc (asc_cls, - http_common_plugin_address_to_string (NULL, type, address, addrlen), - GNUNET_OK); + { + /* Must not happen */ + GNUNET_break (0); + goto handle_error; + } + + if ( (GNUNET_YES == numeric) && + (GNUNET_YES == have_ip) ) + { + /* No lookup required */ + ret = http_common_plugin_address_to_string (type, address, addrlen); + asc (asc_cls, ret, (NULL == ret) ? GNUNET_SYSERR : GNUNET_OK); + asc (asc_cls, NULL, GNUNET_OK); + http_clean_splitted (saddr); + GNUNET_free_non_null (sock_addr); + return; + } + if ( (GNUNET_YES == numeric) && + (GNUNET_NO == have_ip) ) + { + /* Forward lookup */ + if (GNUNET_SYSERR == + http_common_dns_ip_lookup (saddr->host, type, saddr, + address->options, timeout, + asc, asc_cls)) + { + GNUNET_break(0); + goto handle_error; + } + /* Wait for resolver callback */ + GNUNET_free_non_null (sock_addr); + return; + } + if ( (GNUNET_NO == numeric) && + (GNUNET_YES == have_ip) ) + { + /* Reverse lookup */ + if (GNUNET_SYSERR == + http_common_dns_reverse_lookup (sock_addr, + (AF_INET == sock_addr->sa_family) + ? sizeof(struct sockaddr_in) + : sizeof(struct sockaddr_in6), + type, + saddr, + address->options, timeout, + asc, asc_cls)) + { + GNUNET_break(0); + goto handle_error; + } + /* Wait for resolver callback */ + GNUNET_free_non_null (sock_addr); + return; + } + if ( (GNUNET_NO == numeric) && + (GNUNET_NO == have_ip) ) + { + /* No lookup required */ + ret = http_common_plugin_address_to_string (type, address, addrlen); + asc (asc_cls, ret, (NULL == ret) ? GNUNET_SYSERR : GNUNET_OK); + asc (asc_cls, NULL, GNUNET_OK); + GNUNET_free_non_null (sock_addr); + http_clean_splitted (saddr); + return; + } + /* Error (argument supplied not GNUNET_YES or GNUNET_NO) */ + GNUNET_break (0); + goto handle_error; + + handle_error: + /* Report error */ + asc (asc_cls, NULL, GNUNET_SYSERR); asc (asc_cls, NULL, GNUNET_OK); + GNUNET_free_non_null (sock_addr); + if (NULL != saddr) + http_clean_splitted (saddr); } +/** + * FIXME. + */ const char * http_common_plugin_address_to_url (void *cls, const void *addr, @@ -230,25 +564,26 @@ http_common_plugin_address_to_url (void *cls, if (NULL == addr) { - GNUNET_break (0); + GNUNET_break(0); return NULL; } - if (0 >= addrlen) + if (0 == addrlen) { - GNUNET_break (0); + GNUNET_break(0); return NULL; } if (addrlen != http_common_address_get_size (address)) { - GNUNET_break (0); + GNUNET_break(0); return NULL; } addr_str = (char *) &address[1]; - - if (addr_str[ntohl(address->urlen) -1] != '\0') + if (addr_str[ntohl (address->urlen) - 1] != '\0') return NULL; - memcpy (rbuf, &address[1], ntohl(address->urlen)); + GNUNET_memcpy (rbuf, + &address[1], + ntohl (address->urlen)); return rbuf; } @@ -259,15 +594,13 @@ http_common_plugin_address_to_url (void *cls, * address and that the next call to this function is allowed * to override the address again. * - * @param cls closure - * @param plugin the plugin + * @param plugin the name of the plugin * @param addr binary address * @param addrlen length of the address * @return string representing the same address */ const char * -http_common_plugin_address_to_string (void *cls, - const char *plugin, +http_common_plugin_address_to_string (const char *plugin, const void *addr, size_t addrlen) { @@ -276,31 +609,29 @@ http_common_plugin_address_to_string (void *cls, const char * addr_str; char *res; - GNUNET_assert (NULL != plugin); - + GNUNET_assert(NULL != plugin); if (NULL == addr) - return NULL; + return NULL; if (0 == addrlen) - return TRANSPORT_SESSION_INBOUND_STRING; + return NULL; if (addrlen != http_common_address_get_size (address)) - return NULL; + return NULL; addr_str = (char *) &address[1]; - - if (addr_str[ntohl(address->urlen) -1] != '\0') + if (addr_str[ntohl (address->urlen) - 1] != '\0') return NULL; - GNUNET_asprintf (&res, "%s.%u.%s", plugin, ntohl(address->options), &address[1]); - if (strlen(res) + 1 < 500) + GNUNET_asprintf (&res, "%s.%u.%s", plugin, ntohl (address->options), + &address[1]); + if (strlen (res) + 1 < 500) { - memcpy (rbuf, res, strlen(res) + 1); - GNUNET_free (res); + GNUNET_memcpy (rbuf, res, strlen (res) + 1); + GNUNET_free(res); return rbuf; } - GNUNET_break (0); - GNUNET_free (res); + GNUNET_break(0); + GNUNET_free(res); return NULL; } - /** * Function called to convert a string address to * a binary address. @@ -333,49 +664,49 @@ http_common_plugin_string_to_address (void *cls, optionstr = NULL; if ((NULL == addr) || (addrlen == 0)) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } if ('\0' != addr[addrlen - 1]) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } if (strlen (addr) != addrlen - 1) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } plugin = GNUNET_strdup (addr); optionstr = strchr (plugin, '.'); if (NULL == optionstr) { - GNUNET_break (0); - GNUNET_free (plugin); + GNUNET_break(0); + GNUNET_free(plugin); return GNUNET_SYSERR; } optionstr[0] = '\0'; - optionstr ++; + optionstr++; options = atol (optionstr); /* 0 on conversion error, that's ok */ address = strchr (optionstr, '.'); if (NULL == address) { - GNUNET_break (0); - GNUNET_free (plugin); + GNUNET_break(0); + GNUNET_free(plugin); return GNUNET_SYSERR; } address[0] = '\0'; - address ++; + address++; urlen = strlen (address) + 1; a = GNUNET_malloc (sizeof (struct HttpAddress) + urlen); - a->options = htonl(options); - a->urlen = htonl(urlen); - memcpy (&a[1], address, urlen); + a->options = htonl (options); + a->urlen = htonl (urlen); + GNUNET_memcpy (&a[1], address, urlen); (*buf) = a; - (*added) = sizeof (struct HttpAddress) + urlen; - GNUNET_free (plugin); + (*added) = sizeof(struct HttpAddress) + urlen; + GNUNET_free(plugin); return GNUNET_OK; } @@ -397,16 +728,17 @@ http_common_address_from_socket (const char *protocol, char *res; size_t len; - GNUNET_asprintf(&res, - "%s://%s", - protocol, - GNUNET_a2s (addr, addrlen)); - len = strlen (res)+1; + GNUNET_asprintf (&res, + "%s://%s", + protocol, + GNUNET_a2s (addr, + addrlen)); + len = strlen (res) + 1; address = GNUNET_malloc (sizeof (struct HttpAddress) + len); address->options = htonl (HTTP_OPTIONS_NONE); address->urlen = htonl (len); - memcpy (&address[1], res, len); - GNUNET_free (res); + GNUNET_memcpy (&address[1], res, len); + GNUNET_free(res); return address; } @@ -437,63 +769,63 @@ http_common_socket_from_address (const void *addr, ha = (const struct HttpAddress *) addr; if (NULL == addr) { - GNUNET_break(0); - return NULL ; + GNUNET_break (0); + return NULL; } - if (0 >= addrlen) + if (0 == addrlen) { - GNUNET_break(0); - return NULL ; + GNUNET_break (0); + return NULL; } if (addrlen < sizeof(struct HttpAddress)) { - GNUNET_break(0); - return NULL ; + GNUNET_break (0); + return NULL; } urlen = ntohl (ha->urlen); if (sizeof(struct HttpAddress) + urlen != addrlen) { /* This is a legacy addresses */ - return NULL ; + return NULL; } if (addrlen < sizeof(struct HttpAddress) + urlen) { /* This is a legacy addresses */ - return NULL ; + return NULL; } if (((char *) addr)[addrlen - 1] != '\0') { - GNUNET_break(0); - return NULL ; + GNUNET_break (0); + return NULL; } spa = http_split_address ((const char *) &ha[1]); if (NULL == spa) { - (*res) = GNUNET_SYSERR; - return NULL; + (*res) = GNUNET_SYSERR; + return NULL; } s = GNUNET_new (struct sockaddr_storage); GNUNET_asprintf (&to_conv, "%s:%u", spa->host, spa->port); - if (GNUNET_SYSERR == GNUNET_STRINGS_to_address_ip (to_conv, strlen(to_conv), s)) + if (GNUNET_SYSERR + == GNUNET_STRINGS_to_address_ip (to_conv, strlen (to_conv), s)) { /* could be a hostname */ - GNUNET_free (s); + GNUNET_free(s); (*res) = GNUNET_NO; s = NULL; } else if ((AF_INET != s->ss_family) && (AF_INET6 != s->ss_family)) { - - GNUNET_free (s); - (*res) = GNUNET_SYSERR; - s = NULL; + GNUNET_free (s); + (*res) = GNUNET_SYSERR; + s = NULL; } else { - (*res) = GNUNET_YES; + (*res) = GNUNET_YES; } - http_clean_splitted (spa); + http_clean_splitted (spa); GNUNET_free (to_conv); return (struct sockaddr *) s; } @@ -508,7 +840,7 @@ http_common_socket_from_address (const void *addr, size_t http_common_address_get_size (const struct HttpAddress * addr) { - return sizeof (struct HttpAddress) + ntohl(addr->urlen); + return sizeof(struct HttpAddress) + ntohl (addr->urlen); } @@ -535,17 +867,17 @@ http_common_cmp_addresses (const void *addr1, ha2 = (const struct HttpAddress *) a2; if (NULL == a1) - return GNUNET_SYSERR; - if (0 >= addrlen1) return GNUNET_SYSERR; - if (a1[addrlen1-1] != '\0') + if (0 == addrlen1) + return GNUNET_SYSERR; + if (a1[addrlen1 - 1] != '\0') return GNUNET_SYSERR; if (NULL == a2) - return GNUNET_SYSERR; - if (0 >= addrlen2) return GNUNET_SYSERR; - if (a2[addrlen2-1] != '\0') + if (0 == addrlen2) + return GNUNET_SYSERR; + if (a2[addrlen2 - 1] != '\0') return GNUNET_SYSERR; if (addrlen1 != addrlen2) @@ -553,11 +885,54 @@ http_common_cmp_addresses (const void *addr1, if (ha1->urlen != ha2->urlen) return GNUNET_NO; - if (0 == strcmp ((const char *) &ha1[1],(const char *) &ha2[1])) + if (0 == strcmp ((const char *) &ha1[1], (const char *) &ha2[1])) return GNUNET_YES; return GNUNET_NO; } +/** + * Function obtain the network type for an address. + * + * @param env the environment + * @param address the address + * @return the network type + */ +enum GNUNET_ATS_Network_Type +http_common_get_network_for_address (struct GNUNET_TRANSPORT_PluginEnvironment *env, + const struct GNUNET_HELLO_Address *address) +{ + + struct sockaddr *sa; + enum GNUNET_ATS_Network_Type net_type; + size_t salen = 0; + int res; + + net_type = GNUNET_ATS_NET_UNSPECIFIED; + sa = http_common_socket_from_address (address->address, + address->address_length, + &res); + if (GNUNET_SYSERR == res) + return net_type; + if (GNUNET_YES == res) + { + GNUNET_assert (NULL != sa); + if (AF_INET == sa->sa_family) + { + salen = sizeof (struct sockaddr_in); + } + else if (AF_INET6 == sa->sa_family) + { + salen = sizeof (struct sockaddr_in6); + } + net_type = env->get_address_type (env->cls, + sa, + salen); + GNUNET_free (sa); + } + return net_type; +} + + /* end of plugin_transport_http_common.c */