/*
+--------------------------------------------------------------------+
- | libmemcached - C/C++ Client Library for memcached |
+ | libmemcached-awesome - C/C++ Client Library for memcached |
+--------------------------------------------------------------------+
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted under the terms of the BSD license. |
| the terms online at: https://opensource.org/licenses/BSD-3-Clause |
+--------------------------------------------------------------------+
| Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
- | Copyright (c) 2020 Michael Wallner <mike@php.net> |
+ | Copyright (c) 2020-2021 Michael Wallner https://awesome.co/ |
+--------------------------------------------------------------------+
*/
#include <cassert>
-
static memcached_return_t set_hostinfo(memcached_instance_st *server) {
assert(server->type != MEMCACHED_CONNECTION_UNIX_SOCKET);
+ assert(server->hostname());
+
server->clear_addrinfo();
- char str_port[MEMCACHED_NI_MAXSERV] = {0};
+ char str_host[MEMCACHED_NI_MAXHOST] = {0}, str_port[MEMCACHED_NI_MAXSERV] = {0};
errno = 0;
- int length = snprintf(str_port, MEMCACHED_NI_MAXSERV, "%u", uint32_t(server->port()));
- if (length >= MEMCACHED_NI_MAXSERV or length <= 0 or errno) {
+
+ auto length = snprintf(str_port, MEMCACHED_NI_MAXSERV, "%u", uint32_t(server->port()));
+ if (length <= 0 or errno) {
return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
memcached_literal_param("snprintf(NI_MAXSERV)"));
}
- struct addrinfo hints;
- memset(&hints, 0, sizeof(struct addrinfo));
-
+ struct addrinfo hints{};
hints.ai_family = AF_UNSPEC;
if (memcached_is_udp(server->root)) {
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
} else {
- hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_socktype = SOCK_STREAM;
}
- assert(server->address_info == NULL);
- assert(server->address_info_next == NULL);
- int errcode;
- assert(server->hostname());
- switch (errcode = getaddrinfo(server->hostname(), str_port, &hints, &server->address_info)) {
+ auto hostname = server->hostname();
+ if (*hostname == '[') {
+ auto closing_bracket = &hostname[strlen(hostname) - 1];
+ if (*closing_bracket == ']') {
+ auto host_len = closing_bracket - hostname - 1;
+ if (host_len < MEMCACHED_NI_MAXHOST) {
+ hostname = strncpy(str_host, hostname + 1, host_len);
+ }
+ }
+ }
+
+ auto errcode = getaddrinfo(hostname, str_port, &hints, &server->address_info);
+ switch (errcode) {
case 0:
server->address_info_next = server->address_info;
server->state = MEMCACHED_SERVER_STATE_ADDRINFO;