From db5cb4f15c053c250047cf83390c1ec0cbdcd07c Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 3 Feb 2020 16:35:01 +0100 Subject: [PATCH] embeddable-wg-library: use newer string_list This ports 1d2d6200b8ff517db0f7530645180df3cc4afa74. Signed-off-by: Jason A. Donenfeld --- contrib/embeddable-wg-library/test.c | 7 +- contrib/embeddable-wg-library/wireguard.c | 93 +++++++++-------------- 2 files changed, 42 insertions(+), 58 deletions(-) diff --git a/contrib/embeddable-wg-library/test.c b/contrib/embeddable-wg-library/test.c index 4c95373..f9a8bd4 100644 --- a/contrib/embeddable-wg-library/test.c +++ b/contrib/embeddable-wg-library/test.c @@ -27,8 +27,11 @@ void list_devices(void) perror("Unable to get device"); continue; } - wg_key_to_base64(key, device->public_key); - printf("%s has public key %s\n", device_name, key); + if (device->flags & WGDEVICE_HAS_PUBLIC_KEY) { + wg_key_to_base64(key, device->public_key); + printf("%s has public key %s\n", device_name, key); + } else + printf("%s has no public key\n", device_name); wg_for_each_peer(device, peer) { wg_key_to_base64(key, peer->public_key); printf(" - peer %s\n", key); diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c index fd68918..a9cda20 100644 --- a/contrib/embeddable-wg-library/wireguard.c +++ b/contrib/embeddable-wg-library/wireguard.c @@ -856,85 +856,73 @@ static void mnlg_socket_close(struct mnlg_socket *nlg) /* wireguard-specific parts: */ -struct inflatable_buffer { +struct string_list { char *buffer; - char *next; - bool good; size_t len; - size_t pos; + size_t cap; }; -#define max(a, b) ((a) > (b) ? (a) : (b)) - -static int add_next_to_inflatable_buffer(struct inflatable_buffer *buffer) +static int string_list_add(struct string_list *list, const char *str) { - size_t len, expand_to; - char *new_buffer; + size_t len = strlen(str) + 1; - if (!buffer->good || !buffer->next) { - free(buffer->next); - buffer->good = false; + if (len == 1) return 0; - } - len = strlen(buffer->next) + 1; + if (len >= list->cap - list->len) { + char *new_buffer; + size_t new_cap = list->cap * 2; - if (len == 1) { - free(buffer->next); - buffer->good = false; - return 0; - } - - if (buffer->len - buffer->pos <= len) { - expand_to = max(buffer->len * 2, buffer->len + len + 1); - new_buffer = realloc(buffer->buffer, expand_to); - if (!new_buffer) { - free(buffer->next); - buffer->good = false; + if (new_cap < list->len +len + 1) + new_cap = list->len + len + 1; + new_buffer = realloc(list->buffer, new_cap); + if (!new_buffer) return -errno; - } - memset(&new_buffer[buffer->len], 0, expand_to - buffer->len); - buffer->buffer = new_buffer; - buffer->len = expand_to; + list->buffer = new_buffer; + list->cap = new_cap; } - memcpy(&buffer->buffer[buffer->pos], buffer->next, len); - free(buffer->next); - buffer->good = false; - buffer->pos += len; + memcpy(list->buffer + list->len, str, len); + list->len += len; + list->buffer[list->len] = '\0'; return 0; } +struct interface { + const char *name; + bool is_wireguard; +}; + static int parse_linkinfo(const struct nlattr *attr, void *data) { - struct inflatable_buffer *buffer = data; + struct interface *interface = data; if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr))) - buffer->good = true; + interface->is_wireguard = true; return MNL_CB_OK; } static int parse_infomsg(const struct nlattr *attr, void *data) { - struct inflatable_buffer *buffer = data; + struct interface *interface = data; if (mnl_attr_get_type(attr) == IFLA_LINKINFO) return mnl_attr_parse_nested(attr, parse_linkinfo, data); else if (mnl_attr_get_type(attr) == IFLA_IFNAME) - buffer->next = strdup(mnl_attr_get_str(attr)); + interface->name = mnl_attr_get_str(attr); return MNL_CB_OK; } static int read_devices_cb(const struct nlmsghdr *nlh, void *data) { - struct inflatable_buffer *buffer = data; + struct string_list *list = data; + struct interface interface = { 0 }; int ret; - buffer->good = false; - buffer->next = NULL; - ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, data); + ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, &interface); if (ret != MNL_CB_OK) return ret; - ret = add_next_to_inflatable_buffer(buffer); + if (interface.name && interface.is_wireguard) + ret = string_list_add(list, interface.name); if (ret < 0) return ret; if (nlh->nlmsg_type != NLMSG_DONE) @@ -942,7 +930,7 @@ static int read_devices_cb(const struct nlmsghdr *nlh, void *data) return MNL_CB_OK; } -static int fetch_device_names(struct inflatable_buffer *buffer) +static int fetch_device_names(struct string_list *list) { struct mnl_socket *nl = NULL; char *rtnl_buffer = NULL; @@ -989,7 +977,7 @@ another: ret = -errno; goto cleanup; } - if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, buffer)) < 0) { + if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, list)) < 0) { /* Netlink returns NLM_F_DUMP_INTR if the set of all tunnels changed * during the dump. That's unfortunate, but is pretty common on busy * systems that are adding and removing tunnels all the time. Rather @@ -1463,22 +1451,15 @@ out: /* first\0second\0third\0forth\0last\0\0 */ char *wg_list_device_names(void) { - struct inflatable_buffer buffer = { .len = MNL_SOCKET_BUFFER_SIZE }; - int ret; + struct string_list list = { 0 }; + int ret = fetch_device_names(&list); - ret = -ENOMEM; - buffer.buffer = calloc(1, buffer.len); - if (!buffer.buffer) - goto err; - - ret = fetch_device_names(&buffer); -err: errno = -ret; if (errno) { - free(buffer.buffer); + free(list.buffer); return NULL; } - return buffer.buffer; + return list.buffer ?: strdup("\0"); } int wg_add_device(const char *device_name)