aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2016-07-08 20:34:32 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2016-07-10 03:46:56 +0200
commitbf53fcda68b1389432b8bfb749972a4ee744ead1 (patch)
tree4b57c304bfcecf0c21f24b2c1102d3fe48419e29 /src
parentkeepalives: only queue keepalive when queue is empty (diff)
downloadwireguard-monolithic-historical-bf53fcda68b1389432b8bfb749972a4ee744ead1.tar.xz
wireguard-monolithic-historical-bf53fcda68b1389432b8bfb749972a4ee744ead1.zip
persistent keepalive: use authenticated keepalives
Diffstat (limited to 'src')
-rw-r--r--src/config.c2
-rw-r--r--src/device.c2
-rw-r--r--src/receive.c2
-rw-r--r--src/send.c3
-rw-r--r--src/socket.c8
-rw-r--r--src/timers.c5
-rw-r--r--src/timers.h2
-rw-r--r--src/tools/wg.810
8 files changed, 18 insertions, 16 deletions
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 <linux/net.h>
#include <linux/if_vlan.h>
@@ -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<interface>\fP \fI<configuration-filename>\fP
Sets the current configuration of \fI<interface>\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.