+ string port_string;
+
+ AcceptorConfig acceptor;
+ memset(&acceptor.addr, 0, sizeof(acceptor.addr));
+ acceptor.addr.sin6_family = AF_INET6;
+ if (addr_string[0] == '[') {
+ // IPv6 address: [addr]:port.
+ size_t addr_end = addr_string.find("]:");
+ if (addr_end == string::npos) {
+ log(ERROR, "IPv6 address '%s' should be on form [address]:port", addr_string.c_str());
+ return false;
+ }
+
+ string addr_only = addr_string.substr(1, addr_end - 1);
+ if (inet_pton(AF_INET6, addr_only.c_str(), &acceptor.addr.sin6_addr) != 1) {
+ log(ERROR, "Invalid IPv6 address '%s'", addr_only.c_str());
+ return false;
+ }
+
+ port_string = addr_string.substr(addr_end + 2);
+ } else {
+ // IPv4 address: addr:port.
+ size_t addr_end = addr_string.find(":");
+ if (addr_end == string::npos) {
+ log(ERROR, "IPv4 address '%s' should be on form address:port", addr_string.c_str());
+ return false;
+ }
+
+ in_addr addr4;
+ string addr_only = addr_string.substr(0, addr_end);
+ if (inet_pton(AF_INET, addr_only.c_str(), &addr4) != 1) {
+ log(ERROR, "Invalid IPv4 address '%s'", addr_only.c_str());
+ return false;
+ }
+
+ // Convert to a v4-mapped address.
+ acceptor.addr.sin6_addr.s6_addr32[2] = htonl(0xffff);
+ acceptor.addr.sin6_addr.s6_addr32[3] = addr4.s_addr;
+ port_string = addr_string.substr(addr_end + 1);
+ }
+
+ int port = atoi(port_string.c_str());
+ if (port < 1 || port >= 65536) {
+ log(ERROR, "port %d is out of range (must be [1,65536>).", port);
+ return false;
+ }
+ acceptor.addr.sin6_port = ntohs(port);
+