This file is part of GNUnet.
Copyright (C) 2016, 2017 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 free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ 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.
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
- 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.
+ SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
network,
&net));
memset (&mask, 0, sizeof (mask));
- if (0 == memcmp (&mask,
- ip,
- sizeof (mask)))
+ if (0 == GNUNET_memcmp (&mask,
+ ip))
return GNUNET_YES;
off = 0;
while (bits > 8)
struct GNUNET_MQ_Envelope *env;
struct GNUNET_NAT_AddressChangeNotificationMessage *msg;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Notifying client about %s of IP %s\n",
+ add ? "addition" : "removal",
+ GNUNET_a2s (addr,
+ addr_len));
env = GNUNET_MQ_msg_extra (msg,
addr_len,
GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE);
struct sockaddr_in6 v6;
if (0 == (ch->flags & GNUNET_NAT_RF_ADDRESSES))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Not notifying client as it does not care about addresses\n");
return;
+ }
switch (delta->af)
{
case AF_INET:
(! match_ipv4 ("127.0.0.1", &v4.sin_addr, 8)) )
continue; /* bound to loopback, but this is not loopback */
if ( (! match_ipv4 ("127.0.0.1", &c4->sin_addr, 8) ) &&
- (0 != c4->sin_addr.s_addr) &&
match_ipv4 ("127.0.0.1", &v4.sin_addr, 8) )
continue; /* bound to non-loopback, but this is loopback */
- if ( (0 != (ch->flags & GNUNET_NAT_AC_EXTERN)) &&
- (0 != c4->sin_addr.s_addr) &&
- (! is_nat_v4 (&v4.sin_addr)) )
- continue; /* based on external-IP, but this IP is not
- from private address range. */
- if ( (0 != memcmp (&v4.sin_addr,
- &c4->sin_addr,
- sizeof (struct in_addr))) &&
- (0 != c4->sin_addr.s_addr) &&
- ( (! is_nat_v4 (&c4->sin_addr)) ||
- (0 == (ch->flags & GNUNET_NAT_AC_EXTERN))) )
+ if ( (0 != (delta->ac & GNUNET_NAT_AC_EXTERN)) &&
+ (0 != c4->sin_addr.s_addr) &&
+ (! is_nat_v4 (&v4.sin_addr)) )
+ continue; /* based on external-IP, but this IP is not
+ from private address range. */
+ if ( (0 != GNUNET_memcmp (&v4.sin_addr,
+ &c4->sin_addr)) &&
+ (0 != c4->sin_addr.s_addr) &&
+ (! is_nat_v4 (&c4->sin_addr)) )
continue; /* this IP is not from private address range,
and IP does not match. */
/* OK, IP seems relevant, notify client */
- v4.sin_port = c4->sin_port;
+ if (0 == htons (v4.sin_port))
+ v4.sin_port = c4->sin_port;
notify_client (delta->ac,
ch,
add,
continue; /* IPv4 not relevant */
c6 = (const struct sockaddr_in6 *) &ch->caddrs[i].ss;
if ( match_ipv6 ("::1", &c6->sin6_addr, 128) &&
- (0 != memcmp (&c6->sin6_addr,
- &in6addr_any,
- sizeof (struct in6_addr))) &&
+ (0 != GNUNET_memcmp (&c6->sin6_addr,
+ &in6addr_any)) &&
(! match_ipv6 ("::1", &v6.sin6_addr, 128)) )
continue; /* bound to loopback, but this is not loopback */
if ( (! match_ipv6 ("::1", &c6->sin6_addr, 128) ) &&
- (0 != memcmp (&c6->sin6_addr,
- &in6addr_any,
- sizeof (struct in6_addr))) &&
match_ipv6 ("::1", &v6.sin6_addr, 128) )
continue; /* bound to non-loopback, but this is loopback */
- if ( (0 != (ch->flags & GNUNET_NAT_AC_EXTERN)) &&
- (0 != memcmp (&c6->sin6_addr,
- &in6addr_any,
- sizeof (struct in6_addr))) &&
+ if ( (0 != (delta->ac & GNUNET_NAT_AC_EXTERN)) &&
+ (0 != GNUNET_memcmp (&c6->sin6_addr,
+ &in6addr_any)) &&
(! is_nat_v6 (&v6.sin6_addr)) )
continue; /* based on external-IP, but this IP is not
from private address range. */
- if ( (0 != memcmp (&v6.sin6_addr,
- &c6->sin6_addr,
- sizeof (struct in6_addr))) &&
- (0 != memcmp (&c6->sin6_addr,
- &in6addr_any,
- sizeof (struct in6_addr))) &&
+ if ( (0 != GNUNET_memcmp (&v6.sin6_addr,
+ &c6->sin6_addr)) &&
+ (0 != GNUNET_memcmp (&c6->sin6_addr,
+ &in6addr_any)) &&
(! is_nat_v6 (&c6->sin6_addr)) )
continue; /* this IP is not from private address range,
and IP does not match. */
if ( (match_ipv6 ("fe80::", &c6->sin6_addr, 10)) &&
- (0 != memcmp (&c6->sin6_addr,
- &in6addr_any,
- sizeof (struct in6_addr))) &&
- (0 != memcmp (&v6.sin6_addr,
- &c6->sin6_addr,
- sizeof (struct in6_addr))) &&
+ (0 != GNUNET_memcmp (&c6->sin6_addr,
+ &in6addr_any)) &&
+ (0 != GNUNET_memcmp (&v6.sin6_addr,
+ &c6->sin6_addr)) &&
(0 == (delta->ac & GNUNET_NAT_AC_EXTERN)) )
continue; /* client bound to link-local, and the other address
does not match and is not an external IP */
/* OK, IP seems relevant, notify client */
- v6.sin6_port = c6->sin6_port;
+ if (0 == htons (v6.sin6_port))
+ v6.sin6_port = c6->sin6_port;
notify_client (delta->ac,
ch,
add,
struct LocalAddressList lal;
struct sockaddr_in *s4;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Detected eternal IP, can now back-fill AUTO:%u in hole punching specification of `%s'\n",
+ (unsigned int) ch->ext_dns_port,
+ ch->section_name);
memset (&lal, 0, sizeof (lal));
s4 = (struct sockaddr_in *) &lal.addr;
s4->sin_family = AF_INET;
/* (1) check if client cares. */
if (! ch->natted_address)
return;
- if (0 == (GNUNET_NAT_RF_ADDRESSES & ch->flags))
- return;
have_v4 = GNUNET_NO;
for (unsigned int i=0;i<ch->num_caddrs;i++)
{
sa.sin_addr = *v4;
sa.sin_port = htons (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Detected eternal IP %s, notifying client of external IP (without port)\n",
+ GNUNET_a2s ((const struct sockaddr *) &sa,
+ sizeof (sa)));
/* (3) notify client of change */
notify_client (is_nat_v4 (v4)
? GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_LAN
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Found NATed local address %s, starting NAT server\n",
- GNUNET_a2s ((void *) &pos->addr, sizeof (*s4)));
+ GNUNET_a2s ((const struct sockaddr *) &pos->addr,
+ sizeof (*s4)));
pos->hc = GN_start_gnunet_nat_server_ (&s4->sin_addr,
&reversal_callback,
pos);
ch->hole_external);
/* build sockaddr storage with port number */
- memset (&ss, 0, sizeof (ss));
- memcpy (&ss, addr, addrlen);
+ memset (&ss,
+ 0,
+ sizeof (ss));
+ GNUNET_memcpy (&ss,
+ addr,
+ addrlen);
switch (addr->sa_family)
{
case AF_INET:
struct ClientHandle *ch = cls;
struct LocalAddressList *lal;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Performing DNS lookup for punched hole given for `%s' as `%s:%u'\n",
+ ch->section_name,
+ ch->hole_external,
+ (unsigned int) ch->ext_dns_port);
for (lal = ch->ext_addr_head; NULL != lal; lal = lal->next)
lal->old = GNUNET_YES;
ch->ext_dns_task = NULL;
ch->hole_external,
&s4->sin_addr))
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "IPv4 punched hole given for `%s' via `%s:%u'\n",
+ ch->section_name,
+ ch->hole_external,
+ (unsigned int) ch->ext_dns_port);
s4->sin_port = htons (ch->ext_dns_port);
lal->af = AF_INET;
lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
GNUNET_SERVICE_client_drop (ch->client);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received REGISTER message from client\n");
ch->flags = message->flags;
ch->proto = message->proto;
ch->num_caddrs = ntohs (message->num_addrs);
off = (const char *) &message[1];
for (unsigned int i=0;i<ch->num_caddrs;i++)
{
- size_t alen;
const struct sockaddr *sa = (const struct sockaddr *) off;
+ size_t alen;
uint16_t port;
int is_nat;
{
case AF_INET:
{
- const struct sockaddr_in *s4 = (const struct sockaddr_in *) sa;
+ struct sockaddr_in s4;
+ GNUNET_memcpy (&s4,
+ off,
+ sizeof (struct sockaddr_in));
alen = sizeof (struct sockaddr_in);
- if (is_nat_v4 (&s4->sin_addr))
+ if (is_nat_v4 (&s4.sin_addr))
is_nat = GNUNET_YES;
- port = ntohs (s4->sin_port);
+ port = ntohs (s4.sin_port);
}
break;
case AF_INET6:
{
- const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) sa;
+ struct sockaddr_in6 s6;
+ GNUNET_memcpy (&s6,
+ off,
+ sizeof (struct sockaddr_in6));
alen = sizeof (struct sockaddr_in6);
- if (is_nat_v6 (&s6->sin6_addr))
+ if (is_nat_v6 (&s6.sin6_addr))
is_nat = GNUNET_YES;
- port = ntohs (s6->sin6_port);
+ port = ntohs (s6.sin6_port);
}
break;
#if AF_UNIX
GNUNET_assert (alen <= left);
GNUNET_assert (alen <= sizeof (struct sockaddr_storage));
GNUNET_memcpy (&ch->caddrs[i].ss,
- sa,
+ off,
alen);
/* If applicable, try UPNPC NAT punching */
ch->section_name
= GNUNET_strndup (off,
ntohs (message->str_len));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received REGISTER message from client for subsystem `%s'\n",
+ ch->section_name);
if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_string (cfg,
ch->section_name,
&se->stun_server_addr,
sa_len)) )
continue; /* different STUN server */
- if (0 != memcmp (&external_addr,
- &se->external_addr,
- sizeof (struct sockaddr_in)))
+ if (0 != GNUNET_memcmp (&external_addr,
+ &se->external_addr))
{
/* external IP changed, update! */
notify_clients_stun_change (&se->external_addr,