]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/addr_parsing.c
import ceph quincy 17.2.4
[ceph.git] / ceph / src / common / addr_parsing.c
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
7c673cae
FG
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#if defined(__FreeBSD__) || defined(_AIX)
19#include <sys/socket.h>
20#include <netinet/in.h>
21#endif
22#include <netdb.h>
23
24#define BUF_SIZE 128
f67539c2 25#define ROUND_UP_128(x) (-(-(x) & -128))
7c673cae 26
f67539c2 27int safe_cat(char **pstr, int *plen, int pos, const char *src)
7c673cae 28{
f67539c2
TL
29 size_t len2 = strlen(src);
30 size_t new_size = pos + len2 + 1;
31 if (*plen < new_size) {
32 size_t round_up = ROUND_UP_128(new_size);
33 void* p = realloc(*pstr, round_up);
34 if (!p) {
7c673cae
FG
35 printf("Out of memory\n");
36 exit(1);
37 } else {
f67539c2 38 *pstr = p;
7c673cae 39 }
7c673cae 40 }
f67539c2 41 memcpy(*pstr + pos, src, len2 + 1);
7c673cae
FG
42 return pos + len2;
43}
44
45char *resolve_addrs(const char *orig_str)
46{
11fdf7f2
TL
47 int len = BUF_SIZE;
48 char *new_str = (char *)malloc(len);
7c673cae 49
7c673cae 50 if (!new_str) {
7c673cae
FG
51 return NULL;
52 }
53
11fdf7f2
TL
54 char *saveptr = NULL;
55 char *buf = strdup(orig_str);
56 const char *delim = ",; ";
57
58 char *tok = strtok_r(buf, delim, &saveptr);
7c673cae 59
11fdf7f2 60 int pos = 0;
7c673cae
FG
61
62 while (tok) {
63 struct addrinfo hint;
64 struct addrinfo *res, *ores;
65 char *firstcolon, *lastcolon, *bracecolon;
66 int r;
67 int brackets = 0;
68
69 firstcolon = strchr(tok, ':');
70 lastcolon = strrchr(tok, ':');
71 bracecolon = strstr(tok, "]:");
72
73 char *port_str = 0;
74 if (firstcolon && firstcolon == lastcolon) {
75 /* host:port or a.b.c.d:port */
76 *firstcolon = 0;
77 port_str = firstcolon + 1;
78 } else if (bracecolon) {
79 /* [ipv6addr]:port */
80 port_str = bracecolon + 1;
81 *port_str = 0;
82 port_str++;
83 }
84 if (port_str && !*port_str)
85 port_str = NULL;
86
87 if (*tok == '[' &&
88 tok[strlen(tok)-1] == ']') {
89 tok[strlen(tok)-1] = 0;
90 tok++;
91 brackets = 1;
92 }
93
94 //printf("name '%s' port '%s'\n", tok, port_str);
95
92f5a8d4 96 // FIPS zeroization audit 20191115: this memset is fine.
7c673cae
FG
97 memset(&hint, 0, sizeof(hint));
98 hint.ai_family = AF_UNSPEC;
99 hint.ai_socktype = SOCK_STREAM;
100 hint.ai_protocol = IPPROTO_TCP;
101
102 r = getaddrinfo(tok, port_str, &hint, &res);
103 if (r < 0) {
104 printf("server name not found: %s (%s)\n", tok,
105 gai_strerror(r));
106 free(new_str);
107 free(buf);
108 return 0;
109 }
110
111 /* build resolved addr list */
112 ores = res;
113 while (res) {
114 char host[40], port[40];
115 getnameinfo(res->ai_addr, res->ai_addrlen,
116 host, sizeof(host),
117 port, sizeof(port),
118 NI_NUMERICSERV | NI_NUMERICHOST);
119 /*printf(" host %s port %s flags %d family %d socktype %d proto %d sanonname %s\n",
120 host, port,
121 res->ai_flags, res->ai_family, res->ai_socktype, res->ai_protocol,
122 res->ai_canonname);*/
123 if (res->ai_family == AF_INET6)
124 brackets = 1; /* always surround ipv6 addrs with brackets */
125 if (brackets)
126 pos = safe_cat(&new_str, &len, pos, "[");
127 pos = safe_cat(&new_str, &len, pos, host);
128 if (brackets)
129 pos = safe_cat(&new_str, &len, pos, "]");
130 if (port_str) {
131 pos = safe_cat(&new_str, &len, pos, ":");
132 pos = safe_cat(&new_str, &len, pos, port);
133 }
134 res = res->ai_next;
135 if (res)
136 pos = safe_cat(&new_str, &len, pos, ",");
137 }
138 freeaddrinfo(ores);
139
140 tok = strtok_r(NULL, delim, &saveptr);
141 if (tok)
142 pos = safe_cat(&new_str, &len, pos, ",");
143
144 }
145
146 //printf("new_str is '%s'\n", new_str);
147 free(buf);
148 return new_str;
149}