Skip to content

Commit 76c7d26

Browse files
committed
Handle case of host == NULL
The fix addresses two defects. The getaddrinfo interface contract allowed for host == NULL, but Ziti_resolve assumed host != NULL. Additionally, Ziti_resolve would leak res and addr if the function wasn't successful. Signed-off-by: Tom Carroll <[email protected]>
1 parent d3a58bd commit 76c7d26

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

library/zitilib.c

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,15 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
12261226
in_port_t portnum = port ? (in_port_t) strtol(port, NULL, 10) : 0;
12271227
ZITI_LOG(DEBUG, "host[%s] port[%s]", host, port);
12281228
struct addrinfo *res = calloc(1, sizeof(struct addrinfo));
1229+
union {
1230+
struct sockaddr_in s4;
1231+
struct sockaddr_in6 s6;
1232+
} *addr = calloc(1, sizeof *addr);
1233+
int af = AF_UNSPEC;
1234+
1235+
if (!res || !addr)
1236+
goto error;
1237+
12291238
if (hints) {
12301239
res->ai_socktype = hints->ai_socktype;
12311240
switch (hints->ai_socktype) {
@@ -1239,27 +1248,34 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
12391248
res->ai_protocol = 0;
12401249
break;
12411250
default: // no other protocols are supported
1242-
return -1;
1251+
goto error;
1252+
}
1253+
1254+
switch (hints->ai_family) {
1255+
case AF_INET:
1256+
case AF_INET6:
1257+
case AF_UNSPEC:
1258+
af = hints->ai_family;
1259+
break;
1260+
default: // unsupported address family
1261+
goto error;
12431262
}
12441263
}
12451264

1246-
struct sockaddr_in *addr4 = calloc(1, sizeof(struct sockaddr_in6));
1247-
int rc = 0;
1248-
if ((rc = uv_ip4_addr(host, portnum, addr4)) == 0) {
1249-
ZITI_LOG(DEBUG, "host[%s] port[%s] rc = %d", host, port, rc);
1265+
if ((af == AF_UNSPEC || af == AF_INET) && uv_ip4_addr(host ? host : "127.0.0.1", portnum, &addr->s4) == 0) {
1266+
ZITI_LOG(DEBUG, "host[%s] port[%s]", host, port);
12501267

12511268
res->ai_family = AF_INET;
1252-
res->ai_addr = (struct sockaddr *) addr4;
1253-
res->ai_addrlen = sizeof(struct sockaddr_in);
1254-
1269+
res->ai_addr = (struct sockaddr*)&addr->s4;
1270+
res->ai_addrlen = sizeof addr->s4;
12551271
*addrlist = res;
12561272
return 0;
1257-
} else if (uv_ip6_addr(host, portnum, (struct sockaddr_in6 *) addr4) == 0) {
1258-
ZITI_LOG(INFO, "host[%s] port[%s] rc = %d", host, port, rc);
1273+
} else if ((af == AF_UNSPEC || af == AF_INET6) && uv_ip6_addr(host ? host : "::1", portnum, &addr->s6) == 0) {
1274+
ZITI_LOG(INFO, "host[%s] port[%s]", host, port);
12591275

12601276
res->ai_family = AF_INET6;
1261-
res->ai_addr = (struct sockaddr *) addr4;
1262-
res->ai_addrlen = sizeof(struct sockaddr_in6);
1277+
res->ai_addr = (struct sockaddr*)&addr->s6;
1278+
res->ai_addrlen = sizeof addr->s6;
12631279
*addrlist = res;
12641280
return 0;
12651281
}
@@ -1273,14 +1289,14 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
12731289
tlsuv_parse_url(&url, ctrl);
12741290

12751291
if (strncmp(host, url.hostname, url.hostname_len) == 0) {
1276-
return -1;
1292+
goto error;
12771293
}
12781294

12791295
if (wrap->ztx) {
12801296
MODEL_MAP_FOR(chit, wrap->ztx->channels) {
12811297
ziti_channel_t *ch = model_map_it_value(chit);
12821298
if (strcmp(ch->host, host) == 0) {
1283-
return -1;
1299+
goto error;
12841300
}
12851301
}
12861302
}
@@ -1300,21 +1316,28 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
13001316
int err = await_future(f);
13011317
set_error(err);
13021318

1303-
if (err == 0) {
1304-
addr4->sin_family = AF_INET;
1305-
addr4->sin_port = htons(portnum);
1306-
addr4->sin_addr.s_addr = (in_addr_t)(uintptr_t)f->result;
1319+
if (err != 0)
1320+
goto error;
13071321

1308-
res->ai_family = AF_INET;
1309-
res->ai_addr = (struct sockaddr *) addr4;
1310-
res->ai_socktype = hints->ai_socktype;
1322+
addr->s4.sin_family = AF_INET;
1323+
addr->s4.sin_port = htons(portnum);
1324+
addr->s4.sin_addr.s_addr = (in_addr_t)(uintptr_t)f->result;
1325+
1326+
res->ai_family = AF_INET;
1327+
res->ai_addr = (struct sockaddr*)&addr->s4;
1328+
res->ai_socktype = hints->ai_socktype;
1329+
1330+
res->ai_addrlen = sizeof addr->s4;
1331+
*addrlist = res;
13111332

1312-
res->ai_addrlen = sizeof(*addr4);
1313-
*addrlist = res;
1314-
}
13151333
destroy_future(f);
13161334

1317-
return err == 0 ? 0 : -1;
1335+
return 0;
1336+
1337+
error:
1338+
free(res);
1339+
free(addr);
1340+
return -1;
13181341
}
13191342

13201343
int Ziti_check_socket(ziti_socket_t fd) {

0 commit comments

Comments
 (0)