-static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
-{
- uint32_t res = 0;
- int local = GNUNET_NO;
- int af = addr->sa_family;
- switch (af)
- {
- case AF_INET:
- {
- uint32_t netmask = 0x7F000000;
- uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
- res = (address >> 24) ^ (netmask >> 24);
- if (res != 0)
- local = GNUNET_NO;
- else
- local = GNUNET_YES;
-#if DEBUG_TCP
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
-#endif
- break;
- }
- case AF_INET6:
- {
- if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr) ||
- IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
- local = GNUNET_YES;
- else
- local = GNUNET_NO;
-#if DEBUG_TCP
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
-#endif
- break;
- }
- }
- return local;
-}
-
-/**
- * Add the IP of our network interface to the list of
- * our internal IP addresses.
- *
- * @param cls the 'struct Plugin*'
- * @param name name of the interface
- * @param isDefault do we think this may be our default interface
- * @param addr address of the interface
- * @param addrlen number of bytes in addr
- * @return GNUNET_OK to continue iterating
- */
-static int
-process_interfaces (void *cls,
- const char *name,
- int isDefault,
- const struct sockaddr *addr, socklen_t addrlen)
-{
- struct Plugin *plugin = cls;
- int af;
- struct IPv4TcpAddress t4;
- struct IPv6TcpAddress t6;
- struct IPv4TcpAddress t4_nat;
- struct IPv6TcpAddress t6_nat;
- void *arg;
- uint16_t args;
- void *arg_nat;
- char buf[INET6_ADDRSTRLEN];
-
- af = addr->sa_family;
- arg_nat = NULL;
-
- if (plugin->use_localaddresses == GNUNET_NO)
- {
- if (GNUNET_YES == check_localaddress (addr, addrlen))
- {
-#if DEBUG_TCP
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
- "tcp",
- "Not notifying transport of address `%s' (local address)\n",
- GNUNET_a2s (addr, addrlen));
-#endif
- return GNUNET_OK;
- }
- }
-
- switch (af)
- {
- case AF_INET:
- t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
- GNUNET_assert (NULL != inet_ntop(AF_INET,
- &t4.ipv4_addr,
- buf,
- sizeof (buf)));
- if ( (plugin->bind_address != NULL) &&
- (0 != strcmp(buf, plugin->bind_address)) )
- {
-#if DEBUG_TCP
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
- "tcp",
- "Not notifying transport of address `%s' (does not match bind address)\n",
- GNUNET_a2s (addr, addrlen));
-#endif
- return GNUNET_OK;
- }
- if ( (plugin->internal_address == NULL) &&
- (isDefault) )
- plugin->internal_address = GNUNET_strdup (buf);
- add_to_address_list (plugin, &t4.ipv4_addr, sizeof (struct in_addr));
- if (plugin->behind_nat == GNUNET_YES)
- {
- /* Also advertise as NAT (with port 0) */
- t4_nat.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
- t4_nat.t_port = htons(0);
- arg_nat = &t4_nat;
- }
- t4.t_port = htons (plugin->adv_port);
- arg = &t4;
- args = sizeof (t4);
- break;
- case AF_INET6:
- if ( (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) ||
- (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(plugin->env->cfg,
- "transport-tcp",
- "DISABLEV6")) )
- {
- /* skip link local addresses */
- return GNUNET_OK;
- }
- memcpy (&t6.ipv6_addr,
- &((struct sockaddr_in6 *) addr)->sin6_addr,
- sizeof (struct in6_addr));
-
- /* check bind address */
- GNUNET_assert (NULL != inet_ntop(AF_INET6,
- &t6.ipv6_addr,
- buf,
- sizeof (buf)));
-
- if ( (plugin->bind_address != NULL) &&
- (0 != strcmp(buf, plugin->bind_address)) )
- {
-#if DEBUG_TCP
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
- "tcp",
- "Not notifying transport of address `%s' (does not match bind address)\n",
- GNUNET_a2s (addr, addrlen));
-#endif
- return GNUNET_OK;
- }
-
- add_to_address_list (plugin,
- &t6.ipv6_addr,
- sizeof (struct in6_addr));
- if (plugin->behind_nat == GNUNET_YES)
- {
- /* Also advertise as NAT (with port 0) */
- memcpy (&t6_nat.ipv6_addr,
- &((struct sockaddr_in6 *) addr)->sin6_addr,
- sizeof (struct in6_addr));
- t6_nat.t6_port = htons(0);
- arg_nat = &t6;
- }
- t6.t6_port = htons (plugin->adv_port);
- arg = &t6;
- args = sizeof (t6);
- break;
- default:
- GNUNET_break (0);
- return GNUNET_OK;
- }
- if (plugin->adv_port != 0)
- {
-#if DEBUG_TCP
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
- "tcp",
- "Found address `%s' (%s) len %d\n",
- GNUNET_a2s (addr, addrlen), name, args);
-#endif
- plugin->env->notify_address (plugin->env->cls,
- "tcp",
- arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
- }
-
- if (arg_nat != NULL)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
- "tcp",
- _("Found address `%s' (%s) len %d\n"),
- GNUNET_a2s (addr, addrlen), name, args);
- plugin->env->notify_address (plugin->env->cls,
- "tcp",
- arg_nat, args, GNUNET_TIME_UNIT_FOREVER_REL);
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Function called by the resolver for each address obtained from DNS
- * for our own hostname. Add the addresses to the list of our
- * external IP addresses.
- *
- * @param cls closure
- * @param addr one of the addresses of the host, NULL for the last address
- * @param addrlen length of the address
- */
-static void
-process_hostname_ips (void *cls,
- const struct sockaddr *addr, socklen_t addrlen)
-{
- struct Plugin *plugin = cls;
-
- if (addr == NULL)
- {
- plugin->hostname_dns = NULL;
- return;
- }
- /* FIXME: Can we figure out our external address here so it doesn't need to be user specified? */
- process_interfaces (plugin, "<hostname>", GNUNET_YES, addr, addrlen);
-}
-
-