From ee473a4bd69a36f8bdcc7a84b92e3c4b741eea35 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Wed, 10 Jan 2018 15:10:58 +0100 Subject: [PATCH] Try to get endpoint from "dhcp-server-identifier" --- agent/azure.c | 53 +-------------------------------------- agent/cloudinit.c | 11 ++++----- agent/main.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- agent/main.h | 2 ++ agent/openstack.c | 9 +++---- 5 files changed, 74 insertions(+), 64 deletions(-) diff --git a/agent/azure.c b/agent/azure.c index 9067b8f..aa258cf 100644 --- a/agent/azure.c +++ b/agent/azure.c @@ -51,7 +51,6 @@ static struct httpget static int azure_keys(struct system_config *); static int azure_getpubkeys(struct system_config *); -static int azure_getendpoint(struct system_config *); static int azure_getovfenv(struct system_config *); static int azure_versions(struct system_config *); static int azure_goalstate(struct system_config *); @@ -78,7 +77,7 @@ azure(struct system_config *sc) goto done; } - if (azure_getendpoint(sc) != 0) { + if (dhcp_getendpoint(sc) != 0) { log_warnx("failed to get endpoint"); goto done; } @@ -794,53 +793,3 @@ azure_getovfenv(struct system_config *sc) xml_free(&xml); return (ret); } - -static int -azure_getendpoint(struct system_config *sc) -{ - char path[PATH_MAX], buf[BUFSIZ], *ep = NULL; - int a[4]; - FILE *fp; - - if ((size_t)snprintf(path, sizeof(path), "/var/db/dhclient.leases.%s", - sc->sc_interface) >= sizeof(path)) { - log_debug("%s: invalid path", __func__); - return (-1); - } - - if ((fp = fopen(path, "r")) == NULL) { - log_debug("%s: failed to open %s", __func__, path); - return (-1); - } - - while (fgets(buf, sizeof(buf), fp) != NULL) { - buf[strcspn(buf, ";\n")] = '\0'; - - /* Find last occurence of option-245 */ - if (sscanf(buf, " option option-245 %x:%x:%x:%x", - &a[0], &a[1], &a[2], &a[3]) == 4) { - free(ep); - if (asprintf(&ep, "%d.%d.%d.%d", - a[0], a[1], a[2], a[3]) == -1) { - log_debug("%s: asprintf", __func__); - fclose(fp); - return (-1); - } - } - } - - fclose(fp); - - if (ep == NULL) { - log_debug("%s: endpoint not found", __func__); - return (-1); - } - - sc->sc_endpoint = ep; - sc->sc_addr.ip = sc->sc_endpoint; - sc->sc_addr.family = 4; - - log_debug("%s: %s", __func__, ep); - - return (0); -} diff --git a/agent/cloudinit.c b/agent/cloudinit.c index 54b277b..5247a35 100644 --- a/agent/cloudinit.c +++ b/agent/cloudinit.c @@ -36,7 +36,7 @@ ec2(struct system_config *sc) { free(sc->sc_username); if ((sc->sc_username = strdup("ec2-user")) == NULL || - (sc->sc_endpoint = strdup("169.254.169.254")) == NULL) { + (sc->sc_endpoint = strdup(DEFAULT_ENDPOINT)) == NULL) { log_warnx("failed to set defaults"); return (-1); } @@ -47,8 +47,8 @@ ec2(struct system_config *sc) int cloudinit(struct system_config *sc) { - /* XXX get endpoint from DHCP lease file */ - if ((sc->sc_endpoint = strdup("169.254.169.254")) == NULL) { + if ((dhcp_getendpoint(sc) == -1) && + (sc->sc_endpoint = strdup(DEFAULT_ENDPOINT)) == NULL) { log_warnx("failed to set defaults"); return (-1); } @@ -89,9 +89,8 @@ cloudinit_fetch(struct system_config *sc) str = NULL; } - /* userdata */ - if ((sc->sc_userdata = metadata(sc, "/latest/user-data", TEXT)) == NULL) - goto fail; + /* userdata (optional) */ + sc->sc_userdata = metadata(sc, "/latest/user-data", TEXT); ret = 0; fail: diff --git a/agent/main.c b/agent/main.c index b0e177a..26edb86 100644 --- a/agent/main.c +++ b/agent/main.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -717,7 +718,67 @@ connect_wait(int s, const struct sockaddr *name, socklen_t namelen) return (-1); } - log_debug("%s:%d error %d", __func__, __LINE__, error); + return (0); +} + +int +dhcp_getendpoint(struct system_config *sc) +{ + char path[PATH_MAX], buf[BUFSIZ], *ep = NULL; + int a[4], has245 = 0; + size_t sz; + FILE *fp; + + if ((size_t)snprintf(path, sizeof(path), "/var/db/dhclient.leases.%s", + sc->sc_interface) >= sizeof(path)) { + log_debug("%s: invalid path", __func__); + return (-1); + } + + if ((fp = fopen(path, "r")) == NULL) { + log_debug("%s: failed to open %s", __func__, path); + return (-1); + } + + while (fgets(buf, sizeof(buf), fp) != NULL) { + buf[strcspn(buf, ";\n")] = '\0'; + + /* Find last occurence of dhcp-server-identifier */ + sz = strlen(" option dhcp-server-identifier "); + if (!has245 && + strncmp(buf, " option dhcp-server-identifier ", sz) == 0) { + free(ep); + if ((ep = strdup(buf + sz)) == NULL) { + log_debug("%s: strdup", __func__); + fclose(fp); + return (-1); + } + } + + /* Find last occurence of option-245 (only on Azure) */ + if (sscanf(buf, " option option-245 %x:%x:%x:%x", + &a[0], &a[1], &a[2], &a[3]) == 4) { + has245 = 1; + free(ep); + if (asprintf(&ep, "%d.%d.%d.%d", + a[0], a[1], a[2], a[3]) == -1) { + log_debug("%s: asprintf", __func__); + fclose(fp); + return (-1); + } + } + } + + fclose(fp); + + if (ep == NULL) + return (-1); + + sc->sc_endpoint = ep; + sc->sc_addr.ip = sc->sc_endpoint; + sc->sc_addr.family = 4; + + log_debug("%s: %s", __func__, ep); return (0); } diff --git a/agent/main.h b/agent/main.h index 8a1b53c..7167d6e 100644 --- a/agent/main.h +++ b/agent/main.h @@ -26,6 +26,7 @@ #include "http.h" #include "jsmn.h" +#define DEFAULT_ENDPOINT "169.254.169.254" #define CONNECT_TIMEOUT 10 /* in seconds */ enum strtype { @@ -107,6 +108,7 @@ int agent_setpubkey(struct system_config *, const char *, const char *); char *metadata(struct system_config *, const char *, enum strtype); char *metadata_file(struct system_config *, const char *, enum strtype); int connect_wait(int, const struct sockaddr *, socklen_t); +int dhcp_getendpoint(struct system_config *); /* log.c */ void log_init(int, int); diff --git a/agent/openstack.c b/agent/openstack.c index 19e329d..a060c3d 100644 --- a/agent/openstack.c +++ b/agent/openstack.c @@ -34,7 +34,8 @@ static int openstack_fetch(struct system_config *); int openstack(struct system_config *sc) { - if ((sc->sc_endpoint = strdup("169.254.169.254")) == NULL) { + if ((dhcp_getendpoint(sc) == -1) && + (sc->sc_endpoint = strdup(DEFAULT_ENDPOINT)) == NULL) { log_warnx("failed to set defaults"); return (-1); } @@ -88,10 +89,8 @@ openstack_fetch(struct system_config *sc) free(str); } - /* userdata */ - if ((sc->sc_userdata = - metadata(sc, "/openstack/latest/user-data", TEXT)) == NULL) - goto fail; + /* userdata (optional) */ + sc->sc_userdata = metadata(sc, "/openstack/latest/user_data", TEXT); ret = 0; fail: