43 typedef int (__stdcall * getaddrinfo_ptr_t) (
const char *nodename,
48 typedef void (__stdcall * freeaddrinfo_ptr_t) (
struct addrinfo *ai);
50 typedef int (__stdcall * getnameinfo_ptr_t) (
const struct sockaddr *
sa,
52 char *node,
int nodelen,
53 char *service,
int servicelen,
57 static getaddrinfo_ptr_t getaddrinfo_ptr = NULL;
58 static freeaddrinfo_ptr_t freeaddrinfo_ptr = NULL;
59 static getnameinfo_ptr_t getnameinfo_ptr = NULL;
63 haveNativeWindowsIPv6routines(
void)
65 void *hLibrary = NULL;
66 static bool alreadyLookedForIpv6routines =
false;
68 if (alreadyLookedForIpv6routines)
69 return (getaddrinfo_ptr != NULL);
76 hLibrary = LoadLibraryA(
"ws2_32");
78 if (hLibrary == NULL || GetProcAddress(hLibrary,
"getaddrinfo") == NULL)
85 FreeLibrary(hLibrary);
92 hLibrary = LoadLibraryA(
"wship6");
100 getaddrinfo_ptr = (getaddrinfo_ptr_t) GetProcAddress(hLibrary,
102 freeaddrinfo_ptr = (freeaddrinfo_ptr_t) GetProcAddress(hLibrary,
104 getnameinfo_ptr = (getnameinfo_ptr_t) GetProcAddress(hLibrary,
111 if (getaddrinfo_ptr == NULL ||
112 freeaddrinfo_ptr == NULL ||
113 getnameinfo_ptr == NULL)
115 FreeLibrary(hLibrary);
117 getaddrinfo_ptr = NULL;
118 freeaddrinfo_ptr = NULL;
119 getnameinfo_ptr = NULL;
123 alreadyLookedForIpv6routines =
true;
124 return (getaddrinfo_ptr != NULL);
143 struct sockaddr_in sin,
153 if (haveNativeWindowsIPv6routines())
154 return (*getaddrinfo_ptr) (node, service, hintp, res);
159 memset(&hints, 0,
sizeof(hints));
164 memcpy(&hints, hintp,
sizeof(hints));
172 if (!node && !service)
175 memset(&sin, 0,
sizeof(sin));
177 sin.sin_family = AF_INET;
182 sin.sin_addr.s_addr =
pg_hton32(INADDR_ANY);
193 struct hostent hpstr;
200 hp = gethostbyname(node);
216 if (hp->h_addrtype != AF_INET)
219 memcpy(&(sin.sin_addr), hp->h_addr, hp->h_length);
225 sin.sin_addr.s_addr =
pg_hton32(INADDR_ANY);
227 sin.sin_addr.s_addr =
pg_hton32(INADDR_LOOPBACK);
231 sin.sin_port =
pg_hton16((
unsigned short) atoi(service));
233 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 234 sin.sin_len =
sizeof(sin);
241 psin =
malloc(
sizeof(*psin));
248 memcpy(psin, &sin,
sizeof(*psin));
255 ai->
ai_addr = (
struct sockaddr *) psin;
276 if (haveNativeWindowsIPv6routines())
278 (*freeaddrinfo_ptr) (res);
293 #ifdef HAVE_HSTRERROR 299 hcode = HOST_NOT_FOUND;
310 return hstrerror(hcode);
316 return "Unknown host";
318 return "Host name lookup failure";
322 return "Invalid argument";
326 return "Address family not supported";
330 return "Not enough memory";
332 #if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME 334 return "No host data of that type was found";
338 return "Class type not found";
342 return "Socket type not supported";
345 return "Unknown server error";
359 char *node,
int nodelen,
360 char *service,
int servicelen,
int flags)
368 if (haveNativeWindowsIPv6routines())
369 return (*getnameinfo_ptr) (sa, salen, node, nodelen,
370 service, servicelen, flags);
374 if (sa == NULL || (node == NULL && service == NULL))
378 if (sa->sa_family == AF_INET6)
388 if (sa->sa_family == AF_INET)
391 &((
struct sockaddr_in *) sa)->sin_addr,
392 sa->sa_family == AF_INET ? 32 : 128,
393 node, nodelen) == NULL)
404 if (sa->sa_family == AF_INET)
406 ret =
snprintf(service, servicelen,
"%d",
407 pg_ntoh16(((
struct sockaddr_in *) sa)->sin_port));
409 if (ret < 0 || ret >= servicelen)
int pqGethostbyname(const char *name, struct hostent *resultbuf, char *buffer, size_t buflen, struct hostent **result, int *herrno)
const char * gai_strerror(int errcode)
int errcode(int sqlerrcode)
void freeaddrinfo(struct addrinfo *res)
char * pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
int getnameinfo(const struct sockaddr *sa, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
int inet_aton(const char *cp, struct in_addr *addr)
struct addrinfo * ai_next
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hintp, struct addrinfo **res)
struct sockaddr * ai_addr