Maybe an attacker on the system could use the infoleak in /proc to gauge
how long a wg(8) process takes to complete and determine the number of
leading zeros. This is somewhat ridiculous, but it's possible somebody
somewhere might at somepoint care in the future, so alright.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
'bandwidth' is a measure of speed, but wg's output shows only the
number of bytes transferred. Thus 'transfer' is a better label.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
The C standard states:
A declaration of a parameter as ``array of type'' shall be adjusted to ``qualified pointer to
type'', where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.
By changing void func(int array[4]) to void func(int array[static 4]),
we automatically get the compiler checking argument sizes for us, which
is quite nice.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This is designed to work with a server that follows this:
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = "/var/run/wireguard/wguserspace0.sock"
};
int fd, ret;
ssize_t len;
socklen_t socklen;
struct wgdevice *device;
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0)
exit(1);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
exit(1);
for (;;) {
/* First we look at how big the next message is, so we know how much to
* allocate. Note on BSD you can instead use ioctl(fd, FIONREAD, &len). */
len = recv(fd, NULL, 0, MSG_PEEK | MSG_TRUNC);
if (len < 0) {
handle_error();
continue;
}
/* Next we allocate a buffer for the received data. */
device = NULL;
if (len) {
device = malloc(len);
if (!device) {
handle_error();
continue;
}
}
/* Finally we receive the data, storing too the return address. */
socklen = sizeof(addr);
len = recvfrom(fd, device, len, 0, (struct sockaddr *)&addr, (socklen_t *)&socklen);
if (len < 0) {
handle_error();
free(device);
continue;
}
if (!len) { /* If len is zero, it's a "get" request, so we send our device back. */
device = get_current_wireguard_device(&len);
sendto(fd, device, len, 0, (struct sockaddr *)&addr, socklen);
} else { /* Otherwise, we just received a wgdevice, so we should "set" and send back the return status. */
ret = set_current_wireguard_device(device);
sendto(fd, &ret, sizeof(ret), 0, (struct sockaddr *)&addr, socklen);
free(device);
}
}
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>