summaryrefslogtreecommitdiffstats
path: root/src/common/addr_parsing.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/common/addr_parsing.c
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/common/addr_parsing.c')
-rw-r--r--src/common/addr_parsing.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/common/addr_parsing.c b/src/common/addr_parsing.c
new file mode 100644
index 00000000..4159dff6
--- /dev/null
+++ b/src/common/addr_parsing.c
@@ -0,0 +1,155 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(__FreeBSD__) || defined(_AIX)
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+#include <netdb.h>
+
+#define BUF_SIZE 128
+
+int safe_cat(char **pstr, int *plen, int pos, const char *str2)
+{
+ int len2 = strlen(str2);
+
+ //printf("safe_cat '%s' max %d pos %d '%s' len %d\n", *pstr, *plen, pos, str2, len2);
+ while (*plen < pos + len2 + 1) {
+ *plen += BUF_SIZE;
+
+ void *_realloc = realloc(*pstr, (size_t)*plen);
+
+ if (!_realloc) {
+ printf("Out of memory\n");
+ exit(1);
+ } else {
+ *pstr = _realloc;
+ }
+ //printf("safe_cat '%s' max %d pos %d '%s' len %d\n", *pstr, *plen, pos, str2, len2);
+ }
+
+ strncpy((*pstr)+pos, str2, len2);
+ (*pstr)[pos+len2] = '\0';
+
+ return pos + len2;
+}
+
+char *resolve_addrs(const char *orig_str)
+{
+ int len = BUF_SIZE;
+ char *new_str = (char *)malloc(len);
+
+ if (!new_str) {
+ return NULL;
+ }
+
+ char *saveptr = NULL;
+ char *buf = strdup(orig_str);
+ const char *delim = ",; ";
+
+ char *tok = strtok_r(buf, delim, &saveptr);
+
+ int pos = 0;
+
+ while (tok) {
+ struct addrinfo hint;
+ struct addrinfo *res, *ores;
+ char *firstcolon, *lastcolon, *bracecolon;
+ int r;
+ int brackets = 0;
+
+ firstcolon = strchr(tok, ':');
+ lastcolon = strrchr(tok, ':');
+ bracecolon = strstr(tok, "]:");
+
+ char *port_str = 0;
+ if (firstcolon && firstcolon == lastcolon) {
+ /* host:port or a.b.c.d:port */
+ *firstcolon = 0;
+ port_str = firstcolon + 1;
+ } else if (bracecolon) {
+ /* [ipv6addr]:port */
+ port_str = bracecolon + 1;
+ *port_str = 0;
+ port_str++;
+ }
+ if (port_str && !*port_str)
+ port_str = NULL;
+
+ if (*tok == '[' &&
+ tok[strlen(tok)-1] == ']') {
+ tok[strlen(tok)-1] = 0;
+ tok++;
+ brackets = 1;
+ }
+
+ //printf("name '%s' port '%s'\n", tok, port_str);
+
+ // FIPS zeroization audit 20191115: this memset is fine.
+ memset(&hint, 0, sizeof(hint));
+ hint.ai_family = AF_UNSPEC;
+ hint.ai_socktype = SOCK_STREAM;
+ hint.ai_protocol = IPPROTO_TCP;
+
+ r = getaddrinfo(tok, port_str, &hint, &res);
+ if (r < 0) {
+ printf("server name not found: %s (%s)\n", tok,
+ gai_strerror(r));
+ free(new_str);
+ free(buf);
+ return 0;
+ }
+
+ /* build resolved addr list */
+ ores = res;
+ while (res) {
+ char host[40], port[40];
+ getnameinfo(res->ai_addr, res->ai_addrlen,
+ host, sizeof(host),
+ port, sizeof(port),
+ NI_NUMERICSERV | NI_NUMERICHOST);
+ /*printf(" host %s port %s flags %d family %d socktype %d proto %d sanonname %s\n",
+ host, port,
+ res->ai_flags, res->ai_family, res->ai_socktype, res->ai_protocol,
+ res->ai_canonname);*/
+ if (res->ai_family == AF_INET6)
+ brackets = 1; /* always surround ipv6 addrs with brackets */
+ if (brackets)
+ pos = safe_cat(&new_str, &len, pos, "[");
+ pos = safe_cat(&new_str, &len, pos, host);
+ if (brackets)
+ pos = safe_cat(&new_str, &len, pos, "]");
+ if (port_str) {
+ pos = safe_cat(&new_str, &len, pos, ":");
+ pos = safe_cat(&new_str, &len, pos, port);
+ }
+ res = res->ai_next;
+ if (res)
+ pos = safe_cat(&new_str, &len, pos, ",");
+ }
+ freeaddrinfo(ores);
+
+ tok = strtok_r(NULL, delim, &saveptr);
+ if (tok)
+ pos = safe_cat(&new_str, &len, pos, ",");
+
+ }
+
+ //printf("new_str is '%s'\n", new_str);
+ free(buf);
+ return new_str;
+}