static grpc_error *try_split_host_port(const char *name, const char *default_port, char **host, char **port) { /* parse name, splitting it into host and port parts */ grpc_error *error; gpr_split_host_port(name, host, port); if (*host == NULL) { char *msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; } if (*port == NULL) { // TODO(murgatroid99): add tests for this case if (default_port == NULL) { char *msg; gpr_asprintf(&msg, "no port in name '%s'", name); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; } *port = gpr_strdup(default_port); } return GRPC_ERROR_NONE; }
static grpc_error *try_split_host_port(const char *name, const char *default_port, char **host, char **port) { /* parse name, splitting it into host and port parts */ grpc_error *error; gpr_split_host_port(name, host, port); if (host == NULL) { char *msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); error = GRPC_ERROR_CREATE(msg); gpr_free(msg); return error; } if (port == NULL) { if (default_port == NULL) { char *msg; gpr_asprintf(&msg, "no port in name '%s'", name); error = GRPC_ERROR_CREATE(msg); gpr_free(msg); return error; } *port = gpr_strdup(default_port); } return GRPC_ERROR_NONE; }
static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) { char *allocated_name = NULL; int r; if (strchr(peer_name, ':') != NULL) { char *ignored_port; gpr_split_host_port(peer_name, &allocated_name, &ignored_port); gpr_free(ignored_port); peer_name = allocated_name; if (!peer_name) return 0; } r = tsi_ssl_peer_matches_name(peer, peer_name); gpr_free(allocated_name); return r; }
static int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { const char *host_port = uri->path; char *host; char *port; int port_num; int result = 0; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; if (*host_port == '/') ++host_port; if (!gpr_split_host_port(host_port, &host, &port)) { return 0; } memset(in6, 0, sizeof(*in6)); *len = sizeof(*in6); in6->sin6_family = AF_INET6; if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) { gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); goto done; } if (port != NULL) { if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port); goto done; } in6->sin6_port = htons((uint16_t)port_num); } else { gpr_log(GPR_ERROR, "no port given for ipv6 scheme"); goto done; } result = 1; done: gpr_free(host); gpr_free(port); return result; }
static grpc_error *blocking_resolve_address_impl( const char *name, const char *default_port, grpc_resolved_addresses **addresses) { struct addrinfo hints; struct addrinfo *result = NULL, *resp; char *host; char *port; int s; size_t i; grpc_error *error = GRPC_ERROR_NONE; /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); if (host == NULL) { char *msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); error = GRPC_ERROR_CREATE(msg); gpr_free(msg); goto done; } if (port == NULL) { if (default_port == NULL) { char *msg; gpr_asprintf(&msg, "no port in name '%s'", name); error = GRPC_ERROR_CREATE(msg); gpr_free(msg); goto done; } port = gpr_strdup(default_port); } /* Call getaddrinfo */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ hints.ai_socktype = SOCK_STREAM; /* stream socket */ hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; s = getaddrinfo(host, port, &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { error = GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo"); goto done; } /* Success path: set addrs non-NULL, fill it in */ (*addresses) = gpr_malloc(sizeof(grpc_resolved_addresses)); (*addresses)->naddrs = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { (*addresses)->naddrs++; } (*addresses)->addrs = gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs); i = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { memcpy(&(*addresses)->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); (*addresses)->addrs[i].len = resp->ai_addrlen; i++; } { for (i = 0; i < (*addresses)->naddrs; i++) { char *buf; grpc_sockaddr_to_string( &buf, (struct sockaddr *)&(*addresses)->addrs[i].addr, 0); gpr_free(buf); } } done: gpr_free(host); gpr_free(port); if (result) { freeaddrinfo(result); } return error; }
grpc_security_status grpc_ssl_channel_security_connector_create( grpc_credentials *request_metadata_creds, const grpc_ssl_config *config, const char *target_name, const char *overridden_target_name, grpc_channel_security_connector **sc) { size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); const unsigned char **alpn_protocol_strings = gpr_malloc(sizeof(const char *) * num_alpn_protocols); unsigned char *alpn_protocol_string_lengths = gpr_malloc(sizeof(unsigned char) * num_alpn_protocols); tsi_result result = TSI_OK; grpc_ssl_channel_security_connector *c; size_t i; const unsigned char *pem_root_certs; size_t pem_root_certs_size; char *port; for (i = 0; i < num_alpn_protocols; i++) { alpn_protocol_strings[i] = (const unsigned char *)grpc_chttp2_get_alpn_version_index(i); alpn_protocol_string_lengths[i] = (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i)); } if (config == NULL || target_name == NULL) { gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); goto error; } if (!check_request_metadata_creds(request_metadata_creds)) { goto error; } c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector)); memset(c, 0, sizeof(grpc_ssl_channel_security_connector)); gpr_ref_init(&c->base.base.refcount, 1); c->base.base.vtable = &ssl_channel_vtable; c->base.base.is_client_side = 1; c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds); c->base.check_call_host = ssl_channel_check_call_host; gpr_split_host_port(target_name, &c->target_name, &port); gpr_free(port); if (overridden_target_name != NULL) { c->overridden_target_name = gpr_strdup(overridden_target_name); } if (config->pem_root_certs == NULL) { pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); if (pem_root_certs == NULL || pem_root_certs_size == 0) { gpr_log(GPR_ERROR, "Could not get default pem root certs."); goto error; } } else { pem_root_certs = config->pem_root_certs; pem_root_certs_size = config->pem_root_certs_size; } result = tsi_create_ssl_client_handshaker_factory( config->pem_private_key, config->pem_private_key_size, config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs, pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); ssl_channel_destroy(&c->base.base); *sc = NULL; goto error; } *sc = &c->base; gpr_free(alpn_protocol_strings); gpr_free(alpn_protocol_string_lengths); return GRPC_SECURITY_OK; error: gpr_free(alpn_protocol_strings); gpr_free(alpn_protocol_string_lengths); return GRPC_SECURITY_ERROR; }
grpc_resolved_addresses *grpc_blocking_resolve_address( const char *name, const char *default_port) { struct addrinfo hints; struct addrinfo *result = NULL, *resp; char *host; char *port; int s; size_t i; grpc_resolved_addresses *addrs = NULL; /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); if (host == NULL) { gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); goto done; } if (port == NULL) { if (default_port == NULL) { gpr_log(GPR_ERROR, "no port in name '%s'", name); goto done; } port = gpr_strdup(default_port); } /* Call getaddrinfo */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ hints.ai_socktype = SOCK_STREAM; /* stream socket */ hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; s = getaddrinfo(host, port, &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s)); goto done; } /* Success path: set addrs non-NULL, fill it in */ addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); addrs->naddrs = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { addrs->naddrs++; } addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); i = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); addrs->addrs[i].len = resp->ai_addrlen; i++; } { for (i = 0; i < addrs->naddrs; i++) { char *buf; grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr, 0); gpr_free(buf); } } done: gpr_free(host); gpr_free(port); if (result) { freeaddrinfo(result); } return addrs; }
static grpc_error *blocking_resolve_address_impl( const char *name, const char *default_port, grpc_resolved_addresses **addresses) { struct addrinfo hints; struct addrinfo *result = NULL, *resp; char *host; char *port; int s; size_t i; grpc_error *err; if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && name[4] == ':' && name[5] != 0) { return grpc_resolve_unix_domain_address(name + 5, addresses); } /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); if (host == NULL) { err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"), GRPC_ERROR_STR_TARGET_ADDRESS, name); goto done; } if (port == NULL) { if (default_port == NULL) { err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"), GRPC_ERROR_STR_TARGET_ADDRESS, name); goto done; } port = gpr_strdup(default_port); } /* Call getaddrinfo */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ hints.ai_socktype = SOCK_STREAM; /* stream socket */ hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; s = getaddrinfo(host, port, &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { /* Retry if well-known service name is recognized */ char *svc[][2] = {{"http", "80"}, {"https", "443"}}; for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) { if (strcmp(port, svc[i][0]) == 0) { GRPC_SCHEDULING_START_BLOCKING_REGION; s = getaddrinfo(host, svc[i][1], &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; break; } } } if (s != 0) { err = grpc_error_set_str( grpc_error_set_str( grpc_error_set_str(grpc_error_set_int(GRPC_ERROR_CREATE("OS Error"), GRPC_ERROR_INT_ERRNO, s), GRPC_ERROR_STR_OS_ERROR, gai_strerror(s)), GRPC_ERROR_STR_SYSCALL, "getaddrinfo"), GRPC_ERROR_STR_TARGET_ADDRESS, name); goto done; } /* Success path: set addrs non-NULL, fill it in */ *addresses = gpr_malloc(sizeof(grpc_resolved_addresses)); (*addresses)->naddrs = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { (*addresses)->naddrs++; } (*addresses)->addrs = gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs); i = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { memcpy(&(*addresses)->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); (*addresses)->addrs[i].len = resp->ai_addrlen; i++; } err = GRPC_ERROR_NONE; done: gpr_free(host); gpr_free(port); if (result) { freeaddrinfo(result); } return err; }
grpc_resolved_addresses *grpc_blocking_resolve_address( const char *name, const char *default_port) { struct addrinfo hints; struct addrinfo *result = NULL, *resp; char *host; char *port; int s; size_t i; grpc_resolved_addresses *addrs = NULL; struct sockaddr_un *un; if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && name[4] == ':' && name[5] != 0) { addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); addrs->naddrs = 1; addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address)); un = (struct sockaddr_un *)addrs->addrs->addr; un->sun_family = AF_UNIX; strcpy(un->sun_path, name + 5); addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; return addrs; } /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); if (host == NULL) { gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); goto done; } if (port == NULL) { if (default_port == NULL) { gpr_log(GPR_ERROR, "no port in name '%s'", name); goto done; } port = gpr_strdup(default_port); } /* Call getaddrinfo */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ hints.ai_socktype = SOCK_STREAM; /* stream socket */ hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ s = getaddrinfo(host, port, &hints, &result); if (s != 0) { /* Retry if well-known service name is recognized */ char *svc[][2] = {{"http", "80"}, {"https", "443"}}; int i; for (i = 0; i < (int)(sizeof(svc) / sizeof(svc[0])); i++) { if (strcmp(port, svc[i][0]) == 0) { s = getaddrinfo(host, svc[i][1], &hints, &result); break; } } } if (s != 0) { gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s)); goto done; } /* Success path: set addrs non-NULL, fill it in */ addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); addrs->naddrs = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { addrs->naddrs++; } addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); i = 0; for (resp = result; resp != NULL; resp = resp->ai_next) { memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); addrs->addrs[i].len = resp->ai_addrlen; i++; } done: gpr_free(host); gpr_free(port); if (result) { freeaddrinfo(result); } return addrs; }