+static bool sockaddr_cmp_addr(struct sockaddr *a, struct sockaddr *b)
+{
+ if (a->sa_family != b->sa_family)
+ return false;
+
+ if (a->sa_family == AF_INET) {
+ struct sockaddr_in *a4 = (struct sockaddr_in *)a;
+ struct sockaddr_in *b4 = (struct sockaddr_in *)b;
+
+ return !memcmp(a4, b4, sizeof(struct sockaddr_in));
+ } else if (a->sa_family == AF_INET6) {
+ struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)a;
+ struct sockaddr_in6 *b6 = (struct sockaddr_in6 *)b;
+
+ return !memcmp(a6->sin6_addr.s6_addr,
+ b6->sin6_addr.s6_addr,
+ sizeof(a6->sin6_addr.s6_addr));
+ }
+
+ return false;
+}
+
+static gboolean wg_dns_reresolve_cb(gpointer user_data)
+{
+ struct wireguard_info *info = user_data;
+ int err;
+ struct sockaddr addr;
+
+ DBG("");
+
+ err = parse_endpoint(info->endpoint_fqdn,
+ info->port, &addr);
+ if (err)
+ return TRUE;
+
+ if (sockaddr_cmp_addr(&addr, &info->peer.endpoint.addr))
+ return TRUE;
+
+ if (addr.sa_family == AF_INET)
+ memcpy(&info->peer.endpoint.addr, &addr,
+ sizeof(info->peer.endpoint.addr4));
+ else
+ memcpy(&info->peer.endpoint.addr, &addr,
+ sizeof(info->peer.endpoint.addr6));
+
+ DBG("Endpoint address has changed, udpate WireGuard device");
+ err = wg_set_device(&info->device);
+ if (err)
+ DBG("Failed to update Endpoint address for WireGuard device %s",
+ info->device.name);
+
+ return TRUE;
+}