platform: track wireguard endpoint as sockaddr struct

We need to track the IPv6 endpoint as struct sockaddr_in6, so that
we have access to the scope-id.
This commit is contained in:
Thomas Haller
2018-12-24 00:41:01 +01:00
parent 2e48f6419f
commit 0713a6996c
4 changed files with 59 additions and 44 deletions

View File

@@ -475,6 +475,30 @@ static struct nl_sock *_genl_sock (NMLinuxPlatform *platform);
/*****************************************************************************/ /*****************************************************************************/
static int
_sock_addr_set_unaligned (NMSockAddrUnion *dst,
gconstpointer src,
gsize src_len)
{
int f_expected;
struct sockaddr sa;
if (src_len == sizeof (struct sockaddr_in))
f_expected = AF_INET;
else if (src_len == sizeof (struct sockaddr_in6))
f_expected = AF_INET6;
else
return AF_UNSPEC;
memcpy (&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof (sa.sa_family));
if (sa.sa_family != f_expected)
return AF_UNSPEC;
memcpy (dst, src, src_len);
return f_expected;
}
/*****************************************************************************/
static int static int
wait_for_nl_response_to_nmerr (WaitForNlResponseResult seq_result) wait_for_nl_response_to_nmerr (WaitForNlResponseResult seq_result)
{ {
@@ -2009,28 +2033,9 @@ _wireguard_update_from_peers_nla (CList *peers,
nla_len (tb[WGPEER_A_PRESHARED_KEY])); nla_len (tb[WGPEER_A_PRESHARED_KEY]));
} }
if (tb[WGPEER_A_ENDPOINT]) { if (tb[WGPEER_A_ENDPOINT]) {
const struct sockaddr *addr = nla_data (tb[WGPEER_A_ENDPOINT]); _sock_addr_set_unaligned (&peer_c->data.endpoint,
unsigned short family; nla_data (tb[WGPEER_A_ENDPOINT]),
nla_len (tb[WGPEER_A_ENDPOINT]));
G_STATIC_ASSERT (sizeof (addr->sa_family) == sizeof (family));
memcpy (&family, &addr->sa_family, sizeof (addr->sa_family));
if ( family == AF_INET
&& nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in)) {
const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
peer_c->data.endpoint_family = AF_INET;
peer_c->data.endpoint_port = unaligned_read_be16 (&addr4->sin_port);
peer_c->data.endpoint_addr.addr4 = unaligned_read_ne32 (&addr4->sin_addr.s_addr);
memcpy (&peer_c->data.endpoint_addr.addr4, &addr4->sin_addr.s_addr, 4);
} else if ( family == AF_INET6
&& nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in6)) {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
peer_c->data.endpoint_family = AF_INET6;
peer_c->data.endpoint_port = unaligned_read_be16 (&addr6->sin6_port);
memcpy (&peer_c->data.endpoint_addr.addr6, &addr6->sin6_addr, 16);
}
} }
if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]) if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL])
peer_c->data.persistent_keepalive_interval = nla_get_u64 (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); peer_c->data.persistent_keepalive_interval = nla_get_u64 (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]);

View File

@@ -5550,20 +5550,26 @@ nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, g
gs_free char *public_key_b64 = NULL; gs_free char *public_key_b64 = NULL;
char s_endpoint[NM_UTILS_INET_ADDRSTRLEN + 100]; char s_endpoint[NM_UTILS_INET_ADDRSTRLEN + 100];
char s_addr[NM_UTILS_INET_ADDRSTRLEN]; char s_addr[NM_UTILS_INET_ADDRSTRLEN];
char s_scope_id[40];
guint i; guint i;
nm_utils_to_string_buffer_init (&buf, &len); nm_utils_to_string_buffer_init (&buf, &len);
if (peer->endpoint_family == AF_INET) { if (peer->endpoint.sa.sa_family == AF_INET) {
nm_sprintf_buf (s_endpoint, nm_sprintf_buf (s_endpoint,
" endpoint %s:%u", " endpoint %s:%u",
nm_utils_inet4_ntop (peer->endpoint_addr.addr4, s_addr), nm_utils_inet4_ntop (peer->endpoint.in.sin_addr.s_addr, s_addr),
(guint) peer->endpoint_port); (guint) htons (peer->endpoint.in.sin_port));
} else if (peer->endpoint_family == AF_INET6) { } else if (peer->endpoint.sa.sa_family == AF_INET6) {
if (peer->endpoint.in6.sin6_scope_id != 0)
nm_sprintf_buf (s_scope_id, "@%u", peer->endpoint.in6.sin6_scope_id);
else
s_scope_id[0] = '\0';
nm_sprintf_buf (s_endpoint, nm_sprintf_buf (s_endpoint,
" endpoint [%s]:%u", " endpoint [%s]%s:%u",
nm_utils_inet6_ntop (&peer->endpoint_addr.addr6, s_addr), nm_utils_inet6_ntop (&peer->endpoint.in6.sin6_addr, s_addr),
(guint) peer->endpoint_port); s_scope_id,
(guint) htons (peer->endpoint.in6.sin6_port));
} else } else
s_endpoint[0] = '\0'; s_endpoint[0] = '\0';

View File

@@ -393,13 +393,12 @@ _wireguard_peer_hash_update (const NMPWireGuardPeer *peer,
peer->tx_bytes, peer->tx_bytes,
peer->last_handshake_time.tv_sec, peer->last_handshake_time.tv_sec,
peer->last_handshake_time.tv_nsec, peer->last_handshake_time.tv_nsec,
peer->endpoint_port, peer->endpoint.sa.sa_family);
peer->endpoint_family);
if (peer->endpoint_family == AF_INET) if (peer->endpoint.sa.sa_family == AF_INET)
nm_hash_update_val (h, peer->endpoint_addr.addr4); nm_hash_update_val (h, peer->endpoint.in);
else if (peer->endpoint_family == AF_INET6) else if (peer->endpoint.sa.sa_family == AF_INET6)
nm_hash_update_val (h, peer->endpoint_addr.addr6); nm_hash_update_val (h, peer->endpoint.in6);
for (i = 0; i < peer->allowed_ips_len; i++) for (i = 0; i < peer->allowed_ips_len; i++)
_wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h); _wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h);
@@ -419,15 +418,14 @@ _wireguard_peer_cmp (const NMPWireGuardPeer *a,
NM_CMP_FIELD (a, b, tx_bytes); NM_CMP_FIELD (a, b, tx_bytes);
NM_CMP_FIELD (a, b, allowed_ips_len); NM_CMP_FIELD (a, b, allowed_ips_len);
NM_CMP_FIELD (a, b, persistent_keepalive_interval); NM_CMP_FIELD (a, b, persistent_keepalive_interval);
NM_CMP_FIELD (a, b, endpoint_port); NM_CMP_FIELD (a, b, endpoint.sa.sa_family);
NM_CMP_FIELD (a, b, endpoint_family);
NM_CMP_FIELD_MEMCMP (a, b, public_key); NM_CMP_FIELD_MEMCMP (a, b, public_key);
NM_CMP_FIELD_MEMCMP (a, b, preshared_key); NM_CMP_FIELD_MEMCMP (a, b, preshared_key);
if (a->endpoint_family == AF_INET) if (a->endpoint.sa.sa_family == AF_INET)
NM_CMP_FIELD (a, b, endpoint_addr.addr4); NM_CMP_FIELD_MEMCMP (a, b, endpoint.in);
else if (a->endpoint_family == AF_INET6) else if (a->endpoint.sa.sa_family == AF_INET6)
NM_CMP_FIELD_IN6ADDR (a, b, endpoint_addr.addr6); NM_CMP_FIELD_MEMCMP (a, b, endpoint.in6);
for (i = 0; i < a->allowed_ips_len; i++) { for (i = 0; i < a->allowed_ips_len; i++) {
NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i], NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i],

View File

@@ -21,6 +21,8 @@
#ifndef __NMP_OBJECT_H__ #ifndef __NMP_OBJECT_H__
#define __NMP_OBJECT_H__ #define __NMP_OBJECT_H__
#include <netinet/in.h>
#include "nm-utils/nm-obj.h" #include "nm-utils/nm-obj.h"
#include "nm-utils/nm-dedup-multi.h" #include "nm-utils/nm-dedup-multi.h"
#include "nm-platform.h" #include "nm-platform.h"
@@ -29,6 +31,12 @@ struct udev_device;
/*****************************************************************************/ /*****************************************************************************/
typedef union {
struct sockaddr sa;
struct sockaddr_in in;
struct sockaddr_in6 in6;
} NMSockAddrUnion;
typedef struct { typedef struct {
NMIPAddr addr; NMIPAddr addr;
guint8 family; guint8 family;
@@ -36,7 +44,7 @@ typedef struct {
} NMPWireGuardAllowedIP; } NMPWireGuardAllowedIP;
typedef struct _NMPWireGuardPeer { typedef struct _NMPWireGuardPeer {
NMIPAddr endpoint_addr; NMSockAddrUnion endpoint;
struct timespec last_handshake_time; struct timespec last_handshake_time;
guint64 rx_bytes; guint64 rx_bytes;
guint64 tx_bytes; guint64 tx_bytes;
@@ -49,10 +57,8 @@ typedef struct _NMPWireGuardPeer {
guint _construct_idx_end; guint _construct_idx_end;
}; };
guint16 persistent_keepalive_interval; guint16 persistent_keepalive_interval;
guint16 endpoint_port;
guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN];
guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN];
guint8 endpoint_family;
} NMPWireGuardPeer; } NMPWireGuardPeer;
/*****************************************************************************/ /*****************************************************************************/