From ca0e5670ac989ff3621ba133a455756ee378faf4 Mon Sep 17 00:00:00 2001 From: Thomas Gschwantner Date: Wed, 11 Dec 2019 04:06:21 +0100 Subject: Properly send and display wg_errno and errmsg --- common.c | 9 +++++---- common.h | 2 +- wg-dynamic-client.c | 45 +++++++++++++++++++++++++++++++++++---------- wg-dynamic-server.c | 19 +++++++++++++------ 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/common.c b/common.c index de4329a..8c3baf6 100644 --- a/common.c +++ b/common.c @@ -333,16 +333,17 @@ size_t serialize_request_ip(bool send, char *buf, size_t len, print_to_buf(buf, len, &off, "ip=%s/128\n", addrbuf); } - if (rip->start && rip->leasetime) + if (rip->has_ipv4 || rip->has_ipv6) print_to_buf(buf, len, &off, "leasestart=%u\nleasetime=%u\n", rip->start, rip->leasetime); - if (rip->errmsg) - print_to_buf(buf, len, &off, "errmsg=%s\n", rip->errmsg); - if (!send) print_to_buf(buf, len, &off, "errno=%u\n", rip->wg_errno); + if (rip->wg_errno) + print_to_buf(buf, len, &off, "errmsg=%s\n", + WG_DYNAMIC_ERR[rip->wg_errno]); + print_to_buf(buf, len, &off, "\n"); return off; diff --git a/common.h b/common.h index 2608304..bdd5bc1 100644 --- a/common.h +++ b/common.h @@ -47,7 +47,7 @@ static const char *const WG_DYNAMIC_KEY[] = { ITEMS }; E(E_NO_ERROR, "Success") /* must be the first entry */ \ E(E_INVALID_REQ, "Invalid request") \ E(E_UNSUPP_PROTO, "Unsupported protocol") \ - E(E_IP_UNAVAIL, "Chosen IP unavailable") + E(E_IP_UNAVAIL, "Chosen IP(s) unavailable") #define E(x, y) x, enum wg_dynamic_err { ITEMS }; diff --git a/wg-dynamic-client.c b/wg-dynamic-client.c index 7284e3b..7839210 100644 --- a/wg-dynamic-client.c +++ b/wg-dynamic-client.c @@ -144,6 +144,7 @@ static int request_ip(struct wg_dynamic_request_ip *rip) if (close(sockfd)) debug("Failed to close socket: %s\n", strerror(errno)); + log_err("Server communication error.\n"); return -1; } @@ -151,27 +152,51 @@ static int request_ip(struct wg_dynamic_request_ip *rip) log_err("Warning: discarding %zu extra bytes sent by the server\n", remaining); - if (rip->wg_errno) + if (rip->wg_errno && !rip->has_ipv4 && !rip->has_ipv6) { + if (rip->errmsg) { + log_err("Server refused request: %s\n", rip->errmsg); + return -1; + } else if (rip->wg_errno <= ARRAY_SIZE(WG_DYNAMIC_ERR) - 1) { + log_err("Server refused request: %s\n", + WG_DYNAMIC_ERR[rip->wg_errno]); + } else { + log_err("Server refused request: unknown error code %u\n", + rip->wg_errno); + } + + free(rip->errmsg); /* TODO: this could be done cleaner */ return -1; + } + free(rip->errmsg); if (!ipv4_assigned || memcmp(&ipv4, &rip->ipv4, sizeof ipv4)) { if (ipv4_assigned && ipm_deladdr_v4(device->ifindex, &ipv4)) fatal("ipm_deladdr_v4()"); - memcpy(&ipv4, &rip->ipv4, sizeof ipv4); - if (ipm_newaddr_v4(device->ifindex, &ipv4)) - fatal("ipm_newaddr_v4()"); - ipv4_assigned = true; + if (rip->has_ipv4) { + memcpy(&ipv4, &rip->ipv4, sizeof ipv4); + if (ipm_newaddr_v4(device->ifindex, &ipv4)) + fatal("ipm_newaddr_v4()"); + ipv4_assigned = true; + } else { + memset(&ipv4, 0, sizeof ipv4); + ipv4_assigned = false; + } } if (!ipv6_assigned || memcmp(&ipv6, &rip->ipv6, sizeof ipv6)) { if (ipv6_assigned && ipm_deladdr_v6(device->ifindex, &ipv6)) fatal("ipm_deladdr_v6()"); - memcpy(&ipv6, &rip->ipv6, sizeof ipv6); - if (ipm_newaddr_v6(device->ifindex, &ipv6)) - fatal("ipm_newaddr_v6()"); - ipv6_assigned = true; + if (rip->has_ipv6) { + memcpy(&ipv6, &rip->ipv6, sizeof ipv6); + if (ipm_newaddr_v6(device->ifindex, &ipv6)) + fatal("ipm_newaddr_v6()"); + ipv6_assigned = true; + } else { + memset(&ipv6, 0, sizeof ipv6); + ipv6_assigned = false; + } } if (close(sockfd)) @@ -245,7 +270,7 @@ static void loop() if (request_ip(&rip)) { /* TODO: implement some sort of exponential backoff */ - debug("Server communication error, trying again in 30s\n"); + log_err("Trying again in 30s.\n"); xnanosleep(30); return; } diff --git a/wg-dynamic-server.c b/wg-dynamic-server.c index 3b4b1f1..7502aaa 100644 --- a/wg-dynamic-server.c +++ b/wg-dynamic-server.c @@ -262,16 +262,23 @@ static bool send_response(struct wg_dynamic_connection *con) lease = set_lease(con->pubkey, leasetime, &con->lladdr, ip4, ip6); - if (lease) { + + if (lease->ipv4.s_addr) { + ans.has_ipv4 = true; memcpy(&ans.ipv4, &lease->ipv4, sizeof ans.ipv4); + } + if (!IN6_IS_ADDR_UNSPECIFIED(&lease->ipv6)) { + ans.has_ipv6 = true; memcpy(&ans.ipv6, &lease->ipv6, sizeof ans.ipv6); - ans.has_ipv4 = ans.has_ipv6 = true; - ans.start = lease->start_real; - ans.leasetime = lease->leasetime; - } else { - ans.wg_errno = E_IP_UNAVAIL; } + if ((!ans.has_ipv4 && rip->has_ipv4) || + (!ans.has_ipv6 && rip->has_ipv6)) + ans.wg_errno = E_IP_UNAVAIL; + + ans.start = lease->start_real; + ans.leasetime = lease->leasetime; + msglen = serialize_request_ip(false, buf, sizeof buf, &ans); break; default: -- cgit v1.2.3-59-g8ed1b