Resolve the hostname "host" and set the string representation of the * IP address into the buffer pointed by "ipbuf". * * If flags is set to ANET_IP_ONLY the function only resolves hostnames * that are actually already IPv4 or IPv6 addresses. This turns the function * into a validating / normalizing function. */
| 231 | * that are actually already IPv4 or IPv6 addresses. This turns the function |
| 232 | * into a validating / normalizing function. */ |
| 233 | int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len, |
| 234 | int flags) |
| 235 | { |
| 236 | struct addrinfo hints, *info; |
| 237 | int rv; |
| 238 | |
| 239 | memset(&hints,0,sizeof(hints)); |
| 240 | if (flags & ANET_IP_ONLY) hints.ai_flags = AI_NUMERICHOST; |
| 241 | hints.ai_family = AF_UNSPEC; |
| 242 | hints.ai_socktype = SOCK_STREAM; /* specify socktype to avoid dups */ |
| 243 | |
| 244 | if ((rv = getaddrinfo(host, NULL, &hints, &info)) != 0) { |
| 245 | anetSetError(err, "%s", gai_strerror(rv)); |
| 246 | return ANET_ERR; |
| 247 | } |
| 248 | if (info->ai_family == AF_INET) { |
| 249 | struct sockaddr_in *sa = (struct sockaddr_in *)info->ai_addr; |
| 250 | inet_ntop(AF_INET, &(sa->sin_addr), ipbuf, ipbuf_len); |
| 251 | } else { |
| 252 | struct sockaddr_in6 *sa = (struct sockaddr_in6 *)info->ai_addr; |
| 253 | inet_ntop(AF_INET6, &(sa->sin6_addr), ipbuf, ipbuf_len); |
| 254 | } |
| 255 | |
| 256 | freeaddrinfo(info); |
| 257 | return ANET_OK; |
| 258 | } |
| 259 | |
| 260 | static int anetSetReuseAddr(char *err, int fd) { |
| 261 | int yes = 1; |
no test coverage detected