|
|
|
@ -44,6 +44,7 @@ |
|
|
|
|
#include "src/core/iomgr/sockaddr_utils.h" |
|
|
|
|
#include "src/core/support/string.h" |
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/host_port.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
#include <grpc/support/thd.h> |
|
|
|
|
#include <grpc/support/time.h> |
|
|
|
@ -55,63 +56,6 @@ typedef struct { |
|
|
|
|
void *arg; |
|
|
|
|
} request; |
|
|
|
|
|
|
|
|
|
static void split_host_port(const char *name, char **host, char **port) { |
|
|
|
|
const char *host_start; |
|
|
|
|
size_t host_len; |
|
|
|
|
const char *port_start; |
|
|
|
|
|
|
|
|
|
*host = NULL; |
|
|
|
|
*port = NULL; |
|
|
|
|
|
|
|
|
|
if (name[0] == '[') { |
|
|
|
|
/* Parse a bracketed host, typically an IPv6 literal. */ |
|
|
|
|
const char *rbracket = strchr(name, ']'); |
|
|
|
|
if (rbracket == NULL) { |
|
|
|
|
/* Unmatched [ */ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (rbracket[1] == '\0') { |
|
|
|
|
/* ]<end> */ |
|
|
|
|
port_start = NULL; |
|
|
|
|
} else if (rbracket[1] == ':') { |
|
|
|
|
/* ]:<port?> */ |
|
|
|
|
port_start = rbracket + 2; |
|
|
|
|
} else { |
|
|
|
|
/* ]<invalid> */ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
host_start = name + 1; |
|
|
|
|
host_len = rbracket - host_start; |
|
|
|
|
if (memchr(host_start, ':', host_len) == NULL) { |
|
|
|
|
/* Require all bracketed hosts to contain a colon, because a hostname or
|
|
|
|
|
IPv4 address should never use brackets. */ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
const char *colon = strchr(name, ':'); |
|
|
|
|
if (colon != NULL && strchr(colon + 1, ':') == NULL) { |
|
|
|
|
/* Exactly 1 colon. Split into host:port. */ |
|
|
|
|
host_start = name; |
|
|
|
|
host_len = colon - name; |
|
|
|
|
port_start = colon + 1; |
|
|
|
|
} else { |
|
|
|
|
/* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ |
|
|
|
|
host_start = name; |
|
|
|
|
host_len = strlen(name); |
|
|
|
|
port_start = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Allocate return values. */ |
|
|
|
|
*host = gpr_malloc(host_len + 1); |
|
|
|
|
memcpy(*host, host_start, host_len); |
|
|
|
|
(*host)[host_len] = '\0'; |
|
|
|
|
|
|
|
|
|
if (port_start != NULL) { |
|
|
|
|
*port = gpr_strdup(port_start); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_resolved_addresses *grpc_blocking_resolve_address( |
|
|
|
|
const char *name, const char *default_port) { |
|
|
|
|
struct addrinfo hints; |
|
|
|
@ -124,7 +68,7 @@ grpc_resolved_addresses *grpc_blocking_resolve_address( |
|
|
|
|
const gpr_timespec start_time = gpr_now(); |
|
|
|
|
|
|
|
|
|
/* parse name, splitting it into host and port parts */ |
|
|
|
|
split_host_port(name, &host, &port); |
|
|
|
|
gpr_split_host_port(name, &host, &port); |
|
|
|
|
if (host == NULL) { |
|
|
|
|
gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); |
|
|
|
|
goto done; |
|
|
|
|