summaryrefslogtreecommitdiff
path: root/proto/wireguard/wireguard.c
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2019-09-27 21:56:07 +0200
committerMikael Magnusson <mikma@users.sourceforge.net>2020-05-08 18:52:55 +0200
commit93f93af1c15e1a82d0f58f10c81bb814eb56e28f (patch)
tree59d2ddbd197a32e980211b7a0e9ca3866fd170c9 /proto/wireguard/wireguard.c
parent83a043f7db16b0143ae01eee043bdaca86308383 (diff)
Wireguard: Refactor unix socket implementation
Move unix socket implementation for wireguard-go to sysdep/unix/.
Diffstat (limited to 'proto/wireguard/wireguard.c')
-rw-r--r--proto/wireguard/wireguard.c249
1 files changed, 6 insertions, 243 deletions
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c
index 76333fb5..dd66ab32 100644
--- a/proto/wireguard/wireguard.c
+++ b/proto/wireguard/wireguard.c
@@ -7,256 +7,17 @@
#include <sys/un.h>
#include <unistd.h>
#include "lib/lists.h"
-#include "lib/socket.h"
+#include "lib/ip.h"
#include "nest/protocol.h"
#include "nest/iface.h"
#include "sysdep/linux/wireguard.h"
#include "sysdep/unix/unix.h"
+#include "sysdep/unix/wg_user.h"
#include "wireguard.h"
-#define SOCKET_PATH PATH_RUNSTATEDIR "/wireguard/"
-
#define BA_TUNNEL_ENCAP 0x17
static
-char *get_socket_path(struct wg_proto *p, char *buf, uint size)
-{
- struct wg_config *c = (struct wg_config *) p->p.cf;
- bsnprintf(buf, size, SOCKET_PATH "%s.sock", c->ifname);
- return buf;
-}
-
-static
-bool has_userspace(struct wg_proto *p)
-{
- struct wg_config *c = (struct wg_config *) p->p.cf;
- struct stat sb;
- char tmp[sizeof(struct sockaddr_un)];
-
- if (stat(get_socket_path(p, tmp, sizeof(tmp)), &sb) == 0)
- return (sb.st_mode & S_IFMT) == S_IFSOCK;
- else
- {
- log(L_TRACE "WG: no socket %s", tmp);
- return false;
- }
-}
-
-/* NULL=receiving turned off, returns 1 to clear rx buffer */
-static
-int user_rx_hook(struct birdsock *sk, uint size)
-{
- log(L_TRACE "WG: RX %d", size);
- return 1;
-}
-
-static
-void user_tx_hook(struct birdsock *bs)
-{
- log(L_TRACE "WG: TX");
-}
-
-/* errno or zero if EOF */
-static
-void user_err_hook(struct birdsock *bs, int err)
-{
- /* if (err == 0) */
- /* return; */
-
- log(L_TRACE "WG: ERR %d %s", err, bs->err);
- if (bs->fd >= 0)
- close(bs->fd);
- bs->fd = -1;
-}
-
-static void
-wg_puts(const char *str, byte **buf, uint *size)
-{
- int len = strlen(str);
- if (0 < len && len < (int)*size)
- {
- strcpy(*buf, str);
- *size -= len;
- *buf += len;
- }
- else
- *size = 0;
-}
-
-static void
-wg_put_str(const char *key, const char *value, byte **buf, uint *size)
-{
- char tmp[128];
-
- int len = snprintf(tmp, sizeof(tmp), "%s=%s\n", key, value);
- if (0 < len && len < (int)*size)
- {
- strcpy(*buf, tmp);
- *size -= len;
- *buf += len;
- }
- else
- *size = 0;
-}
-
-static void
-wg_put_u16(const char *key, u16 value, byte **buf, uint *size)
-{
- char tmp[64];
-
- int len = snprintf(tmp, sizeof(tmp), "%u", value);
- if (len > 0)
- wg_put_str(key, tmp, buf, size);
- else
- *size = 0;
-}
-
-static void
-wg_put_bool(const char *key, bool value, byte **buf, uint *size)
-{
- char tmp[64];
-
- if (value)
- wg_put_str(key, "true", buf, size);
-}
-
-static void
-wg_put_key(const char *key, wg_key value, byte **buf, uint *size)
-{
- char tmp[128];
-
- for (uint i=0; i < sizeof(wg_key); i++)
- bsnprintf(tmp+2*i, sizeof(tmp)-2*i, "%02x", value[i]);
-
- wg_put_str(key, tmp, buf, size);
-}
-
-static void
-wg_put_endpoint(const char *key, const wg_endpoint *endpoint, byte **buf, uint *size)
-{
- char tmp[INET6_ADDRSTRLEN + 16];
- ip_addr ip;
- struct iface *ifa = NULL;
- uint port = 0;
-
- if (sockaddr_read((sockaddr*)&endpoint->addr, endpoint->addr.sa_family,
- &ip, &ifa, &port) == 0)
- {
- char *pos = NULL;
-
- if (ipa_is_ip4(ip))
- pos = ip4_ntop(ipa_to_ip4(ip), tmp);
- else
- {
- tmp[0] = '[';
- pos = ip6_ntop(ipa_to_ip6(ip), tmp + 1);
- if (ifa)
- pos += bsprintf(pos, "%%%u", ifa->index);
- *pos++ = ']';
- }
- bsprintf(pos, ":%u", port);
- wg_put_str("endpoint", tmp, buf, size);
- }
-}
-
-static void
-wg_put_allowedip(wg_allowedip *allowedip, byte **buf, uint *size)
-{
- char tmp[INET6_ADDRSTRLEN + 10];
- ip_addr ip = IP6_NONE;
-
- switch (allowedip->family)
- {
- case AF_INET:
- ip = ipa_from_in4(allowedip->ip4);
- break;
- case AF_INET6:
- ip = ipa_from_in6(allowedip->ip6);
- break;
- default:
- return;
- }
-
- int res = bsnprintf(tmp, sizeof(tmp), "%I/%u", ip, allowedip->cidr);
-
- if (res < 0)
- {
- *size = 0;
- return;
- }
-
- wg_put_str("allowed_ip", tmp, buf, size);
-}
-
-static int
-user_put_device(wg_device *dev, byte **buf, uint *size)
-{
- wg_put_u16("set", 1, buf, size);
- wg_put_key("private_key", dev->private_key, buf, size);
- wg_put_u16("listen_port", dev->listen_port, buf, size);
- wg_put_bool("replace_peers", dev->flags & WGDEVICE_REPLACE_PEERS, buf, size);
-
- wg_peer *peer = NULL;
- wg_for_each_peer(dev, peer)
- {
- wg_put_key("public_key", peer->public_key, buf, size);
- wg_put_endpoint("endpoint", &peer->endpoint, buf, size);
- wg_put_bool("replace_allowed_ips", peer->flags & WGPEER_REPLACE_ALLOWEDIPS, buf, size);
-
- wg_allowedip *allowedip = NULL;
- wg_for_each_allowedip(peer, allowedip)
- {
- wg_put_allowedip(allowedip, buf, size);
- }
- }
- wg_puts("\n", buf, size);
-
- if (*size > 0)
- return 0;
- else
- return -1;
-}
-
-static int
-user_set_device(struct wg_proto *p)
-{
- struct wg_config *c = (struct wg_config *) p->p.cf;
- char path[sizeof(struct sockaddr_un)];
-
- bsnprintf(path, sizeof(path), SOCKET_PATH "%s.sock", c->ifname);
-
- struct birdsock *sock = sk_new(p->p.pool);
- sock->rx_hook = user_rx_hook;
- sock->tx_hook = user_tx_hook;
- sock->err_hook = user_err_hook;
- int res = sk_connect_unix(sock, path);
- log(L_TRACE "WG: socket %d %d %s", res, sock->fd, path);
- if (res < 0)
- return -1;
-
- uint tbsize = 8192;
- sk_set_tbsize(sock, tbsize);
- sk_set_rbsize(sock, 16);
- byte *pos = sock->tbuf;
- uint size = tbsize;
- int len = user_put_device(p->dev, &pos, &size);
-
- log(L_TRACE "WG: put %d %s", size, sock->tbuf);
-
- if (len < 0)
- {
- /* FIXME close */
- return -1;
- }
- res = sk_send(sock, tbsize - size);
- /* Send data, <0=err, >0=ok, 0=sleep */
- log(L_TRACE "WG: send %d", res);
-
- /* abort(); */
- return -1;
-}
-
-static
int get_device(struct wg_proto *p, wg_device **pdev, const char *device_name)
{
struct wg_config *c = (struct wg_config *) p->p.cf;
@@ -339,8 +100,10 @@ int get_device(struct wg_proto *p, wg_device **pdev, const char *device_name)
static int
set_device(struct wg_proto *p)
{
- if (has_userspace(p))
- return user_set_device(p);
+ struct wg_config *c = (struct wg_config *) p->p.cf;
+
+ if (wg_has_userspace(c->ifname))
+ return wg_user_set_device(p->p.pool, c->ifname, p->dev);
else
{
log(L_TRACE "WG: wg_set_device");