From bf53fcda68b1389432b8bfb749972a4ee744ead1 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 8 Jul 2016 20:34:32 +0200 Subject: persistent keepalive: use authenticated keepalives --- src/config.c | 2 +- src/device.c | 2 +- src/receive.c | 2 ++ src/send.c | 3 +++ src/socket.c | 8 ++------ src/timers.c | 5 +++-- src/timers.h | 2 +- src/tools/wg.8 | 10 +++++----- 8 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/config.c b/src/config.c index 910c31b..9cf75b1 100644 --- a/src/config.c +++ b/src/config.c @@ -108,7 +108,7 @@ static int set_peer(struct wireguard_device *wg, void __user *user_peer, size_t ret = -EINVAL; else { if (!peer->persistent_keepalive_interval && in_peer.persistent_keepalive_interval && netdev_pub(wg)->flags & IFF_UP) - socket_send_buffer_to_peer(peer, NULL, 0, 0); + packet_send_keepalive(peer); peer->persistent_keepalive_interval = in_peer.persistent_keepalive_interval; } } diff --git a/src/device.c b/src/device.c index 198368f..0f922c7 100644 --- a/src/device.c +++ b/src/device.c @@ -41,7 +41,7 @@ static int open_peer(struct wireguard_peer *peer, void *data) timers_init_peer(peer); packet_send_queue(peer); if (peer->persistent_keepalive_interval) - socket_send_buffer_to_peer(peer, NULL, 0, 0); + packet_send_keepalive(peer); return 0; } diff --git a/src/receive.c b/src/receive.c index 2323b97..2994c02 100644 --- a/src/receive.c +++ b/src/receive.c @@ -152,6 +152,7 @@ static void receive_handshake_packet(struct wireguard_device *wg, void *data, si rx_stats(peer, len); timers_any_authenticated_packet_received(peer); + timers_any_authenticated_packet_traversal(peer); update_latest_addr(peer, skb); peer_put(peer); } @@ -259,6 +260,7 @@ packet_processed: dev_kfree_skb(skb); continue_processing: timers_any_authenticated_packet_received(peer); + timers_any_authenticated_packet_traversal(peer); socket_set_peer_addr(peer, addr); peer_put(peer); } diff --git a/src/send.c b/src/send.c index e1d8010..6992fd4 100644 --- a/src/send.c +++ b/src/send.c @@ -23,6 +23,7 @@ void packet_send_handshake_initiation(struct wireguard_peer *peer) if (noise_handshake_create_initiation(&packet, &peer->handshake)) { cookie_add_mac_to_packet(&packet, sizeof(packet), peer); + timers_any_authenticated_packet_traversal(peer); socket_send_buffer_to_peer(peer, &packet, sizeof(struct message_handshake_initiation), HANDSHAKE_DSCP); timers_handshake_initiated(peer); } @@ -39,6 +40,7 @@ void packet_send_handshake_response(struct wireguard_peer *peer) cookie_add_mac_to_packet(&packet, sizeof(packet), peer); if (noise_handshake_begin_session(&peer->handshake, &peer->keypairs, false)) { timers_ephemeral_key_created(peer); + timers_any_authenticated_packet_traversal(peer); socket_send_buffer_to_peer(peer, &packet, sizeof(struct message_handshake_response), HANDSHAKE_DSCP); } } @@ -136,6 +138,7 @@ static inline void send_off_bundle(struct packet_bundle *bundle, struct wireguar * consumes the packet before the top of the loop comes again. */ next = skb->next; is_keepalive = skb->len == message_data_len(0); + timers_any_authenticated_packet_traversal(peer); if (likely(!socket_send_skb_to_peer(peer, skb, 0 /* TODO: Should we copy the DSCP value from the enclosed packet? */) && !is_keepalive)) timers_data_sent(peer); } diff --git a/src/socket.c b/src/socket.c index 5b7bbf8..ac19a47 100644 --- a/src/socket.c +++ b/src/socket.c @@ -4,7 +4,6 @@ #include "socket.h" #include "packets.h" #include "messages.h" -#include "timers.h" #include #include @@ -251,10 +250,8 @@ int socket_send_skb_to_peer(struct wireguard_peer *peer, struct sk_buff *skb, u8 read_lock_bh(&peer->endpoint_lock); ret = send(dev, skb, dst, &peer->endpoint_flow.fl4, &peer->endpoint_flow.fl6, &peer->endpoint_addr, rcu_dereference(peer->device->sock4), rcu_dereference(peer->device->sock6), dscp); - if (!ret) { - timers_any_packet_sent(peer); + if (!ret) peer->tx_bytes += skb_len; - } read_unlock_bh(&peer->endpoint_lock); rcu_read_unlock(); @@ -268,8 +265,7 @@ int socket_send_buffer_to_peer(struct wireguard_peer *peer, void *buffer, size_t if (!skb) return -ENOMEM; skb_reserve(skb, SKB_HEADER_LEN); - if (likely(buffer)) - memcpy(skb_put(skb, len), buffer, len); + memcpy(skb_put(skb, len), buffer, len); return socket_send_skb_to_peer(peer, skb, dscp); } diff --git a/src/timers.c b/src/timers.c index edc6da3..8ef1469 100644 --- a/src/timers.c +++ b/src/timers.c @@ -82,7 +82,8 @@ static void expired_send_persistent_keepalive(unsigned long ptr) if (unlikely(!peer->persistent_keepalive_interval)) return; - socket_send_buffer_to_peer(peer, NULL, 0, 0); + pr_debug("Sending keep alive packet to peer %Lu (%pISpfsc), since we haven't sent or received authenticated data for %u seconds\n", peer->internal_id, &peer->endpoint_addr, peer->persistent_keepalive_interval); + packet_send_keepalive(peer); } void timers_data_sent(struct wireguard_peer *peer) @@ -130,7 +131,7 @@ void timers_ephemeral_key_created(struct wireguard_peer *peer) do_gettimeofday(&peer->walltime_last_handshake); } -void timers_any_packet_sent(struct wireguard_peer *peer) +void timers_any_authenticated_packet_traversal(struct wireguard_peer *peer) { if (peer->persistent_keepalive_interval && likely(peer->timer_persistent_keepalive.data)) mod_timer(&peer->timer_persistent_keepalive, jiffies + HZ * peer->persistent_keepalive_interval); diff --git a/src/timers.h b/src/timers.h index 69bd10f..b6f80fd 100644 --- a/src/timers.h +++ b/src/timers.h @@ -15,6 +15,6 @@ void timers_any_authenticated_packet_received(struct wireguard_peer *peer); void timers_handshake_initiated(struct wireguard_peer *peer); void timers_handshake_complete(struct wireguard_peer *peer); void timers_ephemeral_key_created(struct wireguard_peer *peer); -void timers_any_packet_sent(struct wireguard_peer *peer); +void timers_any_authenticated_packet_traversal(struct wireguard_peer *peer); #endif diff --git a/src/tools/wg.8 b/src/tools/wg.8 index 347fb27..4f5d8f5 100644 --- a/src/tools/wg.8 +++ b/src/tools/wg.8 @@ -68,12 +68,12 @@ public-key cryptography, for post-quantum resistance. If \fIallowed-ips\fP is specified, but the value is the empty string, all allowed ips are removed from the peer. The use of \fIpersistent-keepalive\fP is optional and is by default off; setting it to 0 or "off", disables it. Otherwise it represents, -in seconds, between 10 and 3600 inclusive, how often to send an empty UDP -packet to the peer, for the purpose of keeping a stateful firewall or NAT +in seconds, between 10 and 3600 inclusive, how often to send an authenticated +empty packet to the peer, for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from a peer, and it is behind NAT, the interface might benefit from having a persistent keepalive interval -of 25 seconds. +of 25 seconds; however, most users will not need this. .TP \fBsetconf\fP \fI\fP \fI\fP Sets the current configuration of \fI\fP to the contents of @@ -143,12 +143,12 @@ source IP address and port of correctly authenticated packets from the peer. Optional. .IP \(bu PersistentKeepalive \(em a seconds interval, between 10 and 3600 inclusive, of -how often to send an empty UDP packet to the peer for the purpose of keeping a +how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from a peer, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If set to 0 or "off", this option is disabled. By default or -when unspecified, this option is off. Optional. +when unspecified, this option is off. Most users will not need this. Optional. .SH CONFIGURATION FILE FORMAT EXAMPLE This example may be used as a model for writing configuration files. -- cgit v1.2.3-59-g8ed1b