]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/addr_parsing.c
import new upstream nautilus stable release 14.2.8
[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
25
26int safe_cat(char **pstr, int *plen, int pos, const char *str2)
27{
28 int len2 = strlen(str2);
29
30 //printf("safe_cat '%s' max %d pos %d '%s' len %d\n", *pstr, *plen, pos, str2, len2);
31 while (*plen < pos + len2 + 1) {
32 *plen += BUF_SIZE;
33
11fdf7f2
TL
34 void *_realloc = realloc(*pstr, (size_t)*plen);
35
36 if (!_realloc) {
7c673cae
FG
37 printf("Out of memory\n");
38 exit(1);
39 } else {
11fdf7f2 40 *pstr = _realloc;
7c673cae
FG
41 }
42 //printf("safe_cat '%s' max %d pos %d '%s' len %d\n", *pstr, *plen, pos, str2, len2);
43 }
44
45 strncpy((*pstr)+pos, str2, len2);
46 (*pstr)[pos+len2] = '\0';
47
48 return pos + len2;
49}
50
51char *resolve_addrs(const char *orig_str)
52{
11fdf7f2
TL
53 int len = BUF_SIZE;
54 char *new_str = (char *)malloc(len);
7c673cae 55
7c673cae 56 if (!new_str) {
7c673cae
FG
57 return NULL;
58 }
59
11fdf7f2
TL
60 char *saveptr = NULL;
61 char *buf = strdup(orig_str);
62 const char *delim = ",; ";
63
64 char *tok = strtok_r(buf, delim, &saveptr);
7c673cae 65
11fdf7f2 66 int pos = 0;
7c673cae
FG
67
68 while (tok) {
69 struct addrinfo hint;
70 struct addrinfo *res, *ores;
71 char *firstcolon, *lastcolon, *bracecolon;
72 int r;
73 int brackets = 0;
74
75 firstcolon = strchr(tok, ':');
76 lastcolon = strrchr(tok, ':');
77 bracecolon = strstr(tok, "]:");
78
79 char *port_str = 0;
80 if (firstcolon && firstcolon == lastcolon) {
81 /* host:port or a.b.c.d:port */
82 *firstcolon = 0;
83 port_str = firstcolon + 1;
84 } else if (bracecolon) {
85 /* [ipv6addr]:port */
86 port_str = bracecolon + 1;
87 *port_str = 0;
88 port_str++;
89 }
90 if (port_str && !*port_str)
91 port_str = NULL;
92
93 if (*tok == '[' &&
94 tok[strlen(tok)-1] == ']') {
95 tok[strlen(tok)-1] = 0;
96 tok++;
97 brackets = 1;
98 }
99
100 //printf("name '%s' port '%s'\n", tok, port_str);
101
92f5a8d4 102 // FIPS zeroization audit 20191115: this memset is fine.
7c673cae
FG
103 memset(&hint, 0, sizeof(hint));
104 hint.ai_family = AF_UNSPEC;
105 hint.ai_socktype = SOCK_STREAM;
106 hint.ai_protocol = IPPROTO_TCP;
107
108 r = getaddrinfo(tok, port_str, &hint, &res);
109 if (r < 0) {
110 printf("server name not found: %s (%s)\n", tok,
111 gai_strerror(r));
112 free(new_str);
113 free(buf);
114 return 0;
115 }
116
117 /* build resolved addr list */
118 ores = res;
119 while (res) {
120 char host[40], port[40];
121 getnameinfo(res->ai_addr, res->ai_addrlen,
122 host, sizeof(host),
123 port, sizeof(port),
124 NI_NUMERICSERV | NI_NUMERICHOST);
125 /*printf(" host %s port %s flags %d family %d socktype %d proto %d sanonname %s\n",
126 host, port,
127 res->ai_flags, res->ai_family, res->ai_socktype, res->ai_protocol,
128 res->ai_canonname);*/
129 if (res->ai_family == AF_INET6)
130 brackets = 1; /* always surround ipv6 addrs with brackets */
131 if (brackets)
132 pos = safe_cat(&new_str, &len, pos, "[");
133 pos = safe_cat(&new_str, &len, pos, host);
134 if (brackets)
135 pos = safe_cat(&new_str, &len, pos, "]");
136 if (port_str) {
137 pos = safe_cat(&new_str, &len, pos, ":");
138 pos = safe_cat(&new_str, &len, pos, port);
139 }
140 res = res->ai_next;
141 if (res)
142 pos = safe_cat(&new_str, &len, pos, ",");
143 }
144 freeaddrinfo(ores);
145
146 tok = strtok_r(NULL, delim, &saveptr);
147 if (tok)
148 pos = safe_cat(&new_str, &len, pos, ",");
149
150 }
151
152 //printf("new_str is '%s'\n", new_str);
153 free(buf);
154 return new_str;
155}