int getaddrinfo(GETADDRINFO_SIGNATURE) { if(pool) { return our_getaddrinfo(pool, node, service, hints, res); } else { return realgetaddrinfo(node, service, hints, res); } }
int our_getaddrinfo(dead_pool *pool, const char *node, const char *service, void *hints, void *res) { int pos; struct in_addr addr; char *ipstr; int ret; /* If "node" looks like a dotted-decimal ip address, then just call the real getaddrinfo; otherwise we'll need to get an address from our pool. */ /* TODO: work out what to do with AF_INET6 requests */ #ifdef HAVE_INET_ATON if(node && inet_aton(node, &addr) == 0 && memcmp(node,"*",1)) { #elif defined(HAVE_INET_ADDR) /* If we're stuck with inet_addr, then getaddrinfo() won't work properly with 255.255.255.255 (= -1). There's not much we can do about this */ in_addr_t is_valid; is_valid = inet_addr(node); if(is_valid == -1) { #endif pos = store_pool_entry(pool, (char *) node, &addr); if(pos == -1) { return EAI_NONAME; } else { ipstr = strdup(inet_ntoa(addr)); ret = realgetaddrinfo(ipstr, service, hints, res); free(ipstr); } } else { ret = realgetaddrinfo(node, service, hints, res); } return ret; } struct hostent * our_getipnodebyname(dead_pool *pool, const char *name, int af, int flags, int *error_num) { int pos; struct hostent *he = NULL; int want_4in6 = 0; char addr_convert_buf[80]; struct in_addr pool_addr; if(af == AF_INET6) { /* Caller has requested an AF_INET6 address, and is not prepared to accept IPv4-mapped IPV6 addresses. There's nothing we can do to service their request. */ if((flags & AI_V4MAPPED) == 0) { show_msg(MSGWARN, "getipnodebyname: asked for V6 addresses only, " "but tsocks can't handle that\n"); *error_num = NO_RECOVERY; return NULL; } else { want_4in6 = 1; } } pos = store_pool_entry(pool, (char *)name, &pool_addr); if(pos == -1) { *error_num = HOST_NOT_FOUND; return NULL; } he = alloc_hostent(af); if(he == NULL) { show_msg(MSGERR, "getipnodebyname: failed to allocate hostent\n"); *error_num = NO_RECOVERY; return NULL; } if(want_4in6) { /* Convert the ipv4 address in *addr to an IPv4 in IPv6 mapped address. TODO: inet_ntoa() is thread-safe on Solaris but might not be on other platforms. */ strcpy(addr_convert_buf, "::FFFF:"); strcpy(addr_convert_buf+7, inet_ntoa(pool_addr)); if(inet_pton(AF_INET6, addr_convert_buf, he->h_addr_list[0]) != 1) { show_msg(MSGERR, "getipnodebyname: inet_pton() failed!\n"); free_hostent(he); *error_num = NO_RECOVERY; return NULL; } } else { ((struct in_addr *) he->h_addr_list[0])->s_addr = pool_addr.s_addr; } he->h_name = strdup(name); return he; }