aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.c9
-rw-r--r--common.h2
-rw-r--r--wg-dynamic-client.c45
-rw-r--r--wg-dynamic-server.c19
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: