From 2038538b005396681eb97c3aaa26681695696d8b Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Tue, 7 Sep 2010 19:49:58 +0200 Subject: [PATCH] work around more OS X breakage Steve Jobs must have caused --- misc/builddeps/dp.win32/include/wspiapi.h | 2122 ++++++++--------- .../Contents/MacOS/libd0_blind_id.0.dylib | Bin 165096 -> 165000 bytes .../Contents/MacOS/libd0_rijndael.0.dylib | Bin 103648 -> 103648 bytes .../Contents/MacOS/libd0_blind_id.0.dylib | Bin 165096 -> 165000 bytes .../Contents/MacOS/libd0_rijndael.0.dylib | Bin 103648 -> 103648 bytes 5 files changed, 1061 insertions(+), 1061 deletions(-) diff --git a/misc/builddeps/dp.win32/include/wspiapi.h b/misc/builddeps/dp.win32/include/wspiapi.h index ba5e7c2b..a14be51c 100644 --- a/misc/builddeps/dp.win32/include/wspiapi.h +++ b/misc/builddeps/dp.win32/include/wspiapi.h @@ -1,1061 +1,1061 @@ -/*++ - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - wspiapi.h - -Abstract: - The file contains protocol independent API functions. - -Revision History: - Wed Jul 12 10:50:31 2000, Created - ---*/ - -#ifndef _WSPIAPI_H_ -#define _WSPIAPI_H_ - -#pragma once - -#if (NTDDI_VERSION >= NTDDI_WIN2K) - -#include // sprintf() -#include // calloc(), strtoul() -#include // calloc() -#include // strlen(), strcmp(), strstr() - -#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L - -#define _WSPIAPI_STRCPY_S strcpy_s -#define _WSPIAPI_STRCAT_S strcat_s -#define _WSPIAPI_STRNCPY_S strncpy_s -#define _WSPIAPI_SPRINTF_S_1 sprintf_s - -#else - -#define _WSPIAPI_STRCPY_S(_Dst, _Size, _Src) strcpy((_Dst), (_Src)) -#define _WSPIAPI_STRCAT_S(_Dst, _Size, _Src) strcat((_Dst), (_Src)) -#define _WSPIAPI_STRNCPY_S(_Dst, _Size, _Src, _Count) strncpy((_Dst), (_Src), (_Count)); (_Dst)[(_Size) - 1] = 0 -#define _WSPIAPI_SPRINTF_S_1(_Dst, _Size, _Format, _Arg1) sprintf((_Dst), (_Format), (_Arg1)) - -#endif // defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L - -#if !defined(_WSPIAPI_COUNTOF) -#if !defined(__cplusplus) -#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0])) -#else -template -char (&__wspiapi_countof_helper(__CountofType (&_Array)[_N]))[_N]; -#define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array)) -#endif -#endif - -#define WspiapiMalloc(tSize) calloc(1, (tSize)) -#define WspiapiFree(p) free(p) -#define WspiapiSwap(a, b, c) { (c) = (a); (a) = (b); (b) = (c); } -#define getaddrinfo WspiapiGetAddrInfo -#define getnameinfo WspiapiGetNameInfo -#define freeaddrinfo WspiapiFreeAddrInfo - -// -// These function pointers are also within the #if (NTDDI_VERSION >= WIN2K) -// because they are used by the other functions defined in this file available -// only on win2k and above. -// -typedef int (WINAPI *WSPIAPI_PGETADDRINFO) ( - IN const char *nodename, - IN const char *servname, - IN const struct addrinfo *hints, - OUT struct addrinfo **res); - -typedef int (WINAPI *WSPIAPI_PGETNAMEINFO) ( - IN const struct sockaddr *sa, - IN socklen_t salen, - OUT char *host, - IN size_t hostlen, - OUT char *serv, - IN size_t servlen, - IN int flags); - -typedef void (WINAPI *WSPIAPI_PFREEADDRINFO) ( - IN struct addrinfo *ai); - - - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////// -// v4 only versions of getaddrinfo and friends. -// NOTE: gai_strerror is inlined in ws2tcpip.h -//////////////////////////////////////////////////////////// - -__inline -char * -WINAPI -WspiapiStrdup ( - IN const char * pszString) -/*++ - -Routine Description - allocates enough storage via calloc() for a copy of the string, - copies the string into the new memory, and returns a pointer to it. - -Arguments - pszString string to copy into new memory - -Return Value - a pointer to the newly allocated storage with the string in it. - NULL if enough memory could not be allocated, or string was NULL. - ---*/ -{ - char *pszMemory; - size_t cchMemory; - - if (!pszString) - return(NULL); - - cchMemory = strlen(pszString) + 1; - pszMemory = (char *) WspiapiMalloc(cchMemory); - if (!pszMemory) - return(NULL); - - _WSPIAPI_STRCPY_S(pszMemory, cchMemory, pszString); - return pszMemory; -} - - - -__inline -BOOL -WINAPI -WspiapiParseV4Address ( - IN const char * pszAddress, - OUT PDWORD pdwAddress) -/*++ - -Routine Description - get the IPv4 address (in network byte order) from its string - representation. the syntax should be a.b.c.d. - -Arguments - pszArgument string representation of the IPv4 address - ptAddress pointer to the resulting IPv4 address - -Return Value - Returns FALSE if there is an error, TRUE for success. - ---*/ -{ - DWORD dwAddress = 0; - const char *pcNext = NULL; - int iCount = 0; - - // ensure there are 3 '.' (periods) - for (pcNext = pszAddress; *pcNext != '\0'; pcNext++) - if (*pcNext == '.') - iCount++; - if (iCount != 3) - return FALSE; - - // return an error if dwAddress is INADDR_NONE (255.255.255.255) - // since this is never a valid argument to getaddrinfo. - dwAddress = inet_addr(pszAddress); - if (dwAddress == INADDR_NONE) - return FALSE; - - *pdwAddress = dwAddress; - return TRUE; -} - - - -__inline -struct addrinfo * -WINAPI -WspiapiNewAddrInfo ( - IN int iSocketType, - IN int iProtocol, - IN WORD wPort, - IN DWORD dwAddress) -/*++ - -Routine Description - allocate an addrinfo structure and populate fields. - IPv4 specific internal function, not exported. - -Arguments - iSocketType SOCK_*. can be wildcarded (zero). - iProtocol IPPROTO_*. can be wildcarded (zero). - wPort port number of service (in network order). - dwAddress IPv4 address (in network order). - -Return Value - returns an addrinfo struct, or NULL if out of memory. - ---*/ -{ - struct addrinfo *ptNew; - struct sockaddr_in *ptAddress; - - // allocate a new addrinfo structure. - ptNew = - (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo)); - if (!ptNew) - return NULL; - - ptAddress = - (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in)); - if (!ptAddress) - { - WspiapiFree(ptNew); - return NULL; - } - ptAddress->sin_family = AF_INET; - ptAddress->sin_port = wPort; - ptAddress->sin_addr.s_addr = dwAddress; - - // fill in the fields... - ptNew->ai_family = PF_INET; - ptNew->ai_socktype = iSocketType; - ptNew->ai_protocol = iProtocol; - ptNew->ai_addrlen = sizeof(struct sockaddr_in); - ptNew->ai_addr = (struct sockaddr *) ptAddress; - - return ptNew; -} - - - -__inline -int -WINAPI -WspiapiQueryDNS( - IN const char *pszNodeName, - IN int iSocketType, - IN int iProtocol, - IN WORD wPort, - OUT char pszAlias[NI_MAXHOST], - OUT struct addrinfo **pptResult) -/*++ - -Routine Description - helper routine for WspiapiLookupNode. - performs name resolution by querying the DNS for A records. - *pptResult would need to be freed if an error is returned. - -Arguments - pszNodeName name of node to resolve. - iSocketType SOCK_*. can be wildcarded (zero). - iProtocol IPPROTO_*. can be wildcarded (zero). - wPort port number of service (in network order). - pszAlias where to return the alias. must be of size NI_MAXHOST. - pptResult where to return the result. - -Return Value - Returns 0 on success, an EAI_* style error value otherwise. - ---*/ -{ - struct addrinfo **pptNext = pptResult; - struct hostent *ptHost = NULL; - char **ppAddresses; - - *pptNext = NULL; - pszAlias[0] = '\0'; - - ptHost = gethostbyname(pszNodeName); - if (ptHost) - { - if ((ptHost->h_addrtype == AF_INET) && - (ptHost->h_length == sizeof(struct in_addr))) - { - for (ppAddresses = ptHost->h_addr_list; - *ppAddresses != NULL; - ppAddresses++) - { - // create an addrinfo structure... - *pptNext = WspiapiNewAddrInfo( - iSocketType, - iProtocol, - wPort, - ((struct in_addr *) *ppAddresses)->s_addr); - if (!*pptNext) - return EAI_MEMORY; - - pptNext = &((*pptNext)->ai_next); - } - } - - // pick up the canonical name. - _WSPIAPI_STRNCPY_S(pszAlias, NI_MAXHOST, ptHost->h_name, NI_MAXHOST - 1); - - return 0; - } - - switch (WSAGetLastError()) - { - case WSAHOST_NOT_FOUND: return EAI_NONAME; - case WSATRY_AGAIN: return EAI_AGAIN; - case WSANO_RECOVERY: return EAI_FAIL; - case WSANO_DATA: return EAI_NODATA; - default: return EAI_NONAME; - } -} - - - -__inline -int -WINAPI -WspiapiLookupNode( - IN const char *pszNodeName, - IN int iSocketType, - IN int iProtocol, - IN WORD wPort, - IN BOOL bAI_CANONNAME, - OUT struct addrinfo **pptResult) -/*++ - -Routine Description - resolve a nodename and return a list of addrinfo structures. - IPv4 specific internal function, not exported. - *pptResult would need to be freed if an error is returned. - - NOTE: if bAI_CANONNAME is true, the canonical name should be - returned in the first addrinfo structure. - -Arguments - pszNodeName name of node to resolve. - iSocketType SOCK_*. can be wildcarded (zero). - iProtocol IPPROTO_*. can be wildcarded (zero). - wPort port number of service (in network order). - bAI_CANONNAME whether the AI_CANONNAME flag is set. - pptResult where to return result. - -Return Value - Returns 0 on success, an EAI_* style error value otherwise. - ---*/ -{ - int iError = 0; - int iAliasCount = 0; - - char szFQDN1[NI_MAXHOST] = ""; - char szFQDN2[NI_MAXHOST] = ""; - char *pszName = szFQDN1; - char *pszAlias = szFQDN2; - char *pszScratch = NULL; - _WSPIAPI_STRNCPY_S(pszName, NI_MAXHOST, pszNodeName, NI_MAXHOST - 1); - - for (;;) - { - iError = WspiapiQueryDNS(pszNodeName, - iSocketType, - iProtocol, - wPort, - pszAlias, - pptResult); - if (iError) - break; - - // if we found addresses, then we are done. - if (*pptResult) - break; - - // stop infinite loops due to DNS misconfiguration. there appears - // to be no particular recommended limit in RFCs 1034 and 1035. - if ((!strlen(pszAlias)) || - (!strcmp(pszName, pszAlias)) || - (++iAliasCount == 16)) - { - iError = EAI_FAIL; - break; - } - - // there was a new CNAME, look again. - WspiapiSwap(pszName, pszAlias, pszScratch); - } - - if (!iError && bAI_CANONNAME) - { - (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias); - if (!(*pptResult)->ai_canonname) - iError = EAI_MEMORY; - } - - return iError; -} - - - -__inline -int -WINAPI -WspiapiClone ( - IN WORD wPort, - IN struct addrinfo *ptResult) -/*++ - -Routine Description - clone every addrinfo structure in ptResult for the UDP service. - ptResult would need to be freed if an error is returned. - -Arguments - wPort port number of UDP service. - ptResult list of addrinfo structures, each - of whose node needs to be cloned. - -Return Value - Returns 0 on success, an EAI_MEMORY on allocation failure. - ---*/ -{ - struct addrinfo *ptNext = NULL; - struct addrinfo *ptNew = NULL; - - for (ptNext = ptResult; ptNext != NULL; ) - { - // create an addrinfo structure... - ptNew = WspiapiNewAddrInfo( - SOCK_DGRAM, - ptNext->ai_protocol, - wPort, - ((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr); - if (!ptNew) - break; - - // link the cloned addrinfo - ptNew->ai_next = ptNext->ai_next; - ptNext->ai_next = ptNew; - ptNext = ptNew->ai_next; - } - - if (ptNext != NULL) - return EAI_MEMORY; - - return 0; -} - - - -__inline -void -WINAPI -WspiapiLegacyFreeAddrInfo ( - IN struct addrinfo *ptHead) -/*++ - -Routine Description - Free an addrinfo structure (or chain of structures). - As specified in RFC 2553, Section 6.4. - -Arguments - ptHead structure (chain) to free - ---*/ -{ - struct addrinfo *ptNext; // next strcture to free - - for (ptNext = ptHead; ptNext != NULL; ptNext = ptHead) - { - if (ptNext->ai_canonname) - WspiapiFree(ptNext->ai_canonname); - - if (ptNext->ai_addr) - WspiapiFree(ptNext->ai_addr); - - ptHead = ptNext->ai_next; - WspiapiFree(ptNext); - } -} - - - -__inline -int -WINAPI -WspiapiLegacyGetAddrInfo( - IN const char *pszNodeName, - IN const char *pszServiceName, - IN const struct addrinfo *ptHints, - OUT struct addrinfo **pptResult) -/*++ - -Routine Description - Protocol-independent name-to-address translation. - As specified in RFC 2553, Section 6.4. - This is the hacked version that only supports IPv4. - -Arguments - pszNodeName node name to lookup. - pszServiceName service name to lookup. - ptHints hints about how to process request. - pptResult where to return result. - -Return Value - returns zero if successful, an EAI_* error code if not. - ---*/ -{ - int iError = 0; - int iFlags = 0; - int iFamily = PF_UNSPEC; - int iSocketType = 0; - int iProtocol = 0; - WORD wPort = 0; - DWORD dwAddress = 0; - - struct servent *ptService = NULL; - char *pc = NULL; - BOOL bClone = FALSE; - WORD wTcpPort = 0; - WORD wUdpPort = 0; - - - // initialize pptResult with default return value. - *pptResult = NULL; - - - //////////////////////////////////////// - // validate arguments... - // - - // both the node name and the service name can't be NULL. - if ((!pszNodeName) && (!pszServiceName)) - return EAI_NONAME; - - // validate hints. - if (ptHints) - { - // all members other than ai_flags, ai_family, ai_socktype - // and ai_protocol must be zero or a null pointer. - if ((ptHints->ai_addrlen != 0) || - (ptHints->ai_canonname != NULL) || - (ptHints->ai_addr != NULL) || - (ptHints->ai_next != NULL)) - { - return EAI_FAIL; - } - - // the spec has the "bad flags" error code, so presumably we - // should check something here. insisting that there aren't - // any unspecified flags set would break forward compatibility, - // however. so we just check for non-sensical combinations. - // - // we cannot come up with a canonical name given a null node name. - iFlags = ptHints->ai_flags; - if ((iFlags & AI_CANONNAME) && !pszNodeName) - return EAI_BADFLAGS; - - // we only support a limited number of protocol families. - iFamily = ptHints->ai_family; - if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET)) - return EAI_FAMILY; - - // we only support only these socket types. - iSocketType = ptHints->ai_socktype; - if ((iSocketType != 0) && - (iSocketType != SOCK_STREAM) && - (iSocketType != SOCK_DGRAM) && - (iSocketType != SOCK_RAW)) - return EAI_SOCKTYPE; - - // REVIEW: What if ai_socktype and ai_protocol are at odds? - iProtocol = ptHints->ai_protocol; - } - - - //////////////////////////////////////// - // do service lookup... - - if (pszServiceName) - { - wPort = (WORD) strtoul(pszServiceName, &pc, 10); - if (*pc == '\0') // numeric port string - { - wPort = wTcpPort = wUdpPort = htons(wPort); - if (iSocketType == 0) - { - bClone = TRUE; - iSocketType = SOCK_STREAM; - } - } - else // non numeric port string - { - if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM)) - { - ptService = getservbyname(pszServiceName, "udp"); - if (ptService) - wPort = wUdpPort = ptService->s_port; - } - - if ((iSocketType == 0) || (iSocketType == SOCK_STREAM)) - { - ptService = getservbyname(pszServiceName, "tcp"); - if (ptService) - wPort = wTcpPort = ptService->s_port; - } - - // assumes 0 is an invalid service port... - if (wPort == 0) // no service exists - return (iSocketType ? EAI_SERVICE : EAI_NONAME); - - if (iSocketType == 0) - { - // if both tcp and udp, process tcp now & clone udp later. - iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM; - bClone = (wTcpPort && wUdpPort); - } - } - } - - - - //////////////////////////////////////// - // do node name lookup... - - // if we weren't given a node name, - // return the wildcard or loopback address (depending on AI_PASSIVE). - // - // if we have a numeric host address string, - // return the binary address. - // - if ((!pszNodeName) || (WspiapiParseV4Address(pszNodeName, &dwAddress))) - { - if (!pszNodeName) - { - dwAddress = htonl((iFlags & AI_PASSIVE) - ? INADDR_ANY - : INADDR_LOOPBACK); - } - - // create an addrinfo structure... - *pptResult = - WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); - if (!(*pptResult)) - iError = EAI_MEMORY; - - if (!iError && pszNodeName) - { - // implementation specific behavior: set AI_NUMERICHOST - // to indicate that we got a numeric host address string. - (*pptResult)->ai_flags |= AI_NUMERICHOST; - - // return the numeric address string as the canonical name - if (iFlags & AI_CANONNAME) - { - (*pptResult)->ai_canonname = - WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress))); - if (!(*pptResult)->ai_canonname) - iError = EAI_MEMORY; - } - } - } - - - // if we do not have a numeric host address string and - // AI_NUMERICHOST flag is set, return an error! - else if (iFlags & AI_NUMERICHOST) - { - iError = EAI_NONAME; - } - - - // since we have a non-numeric node name, - // we have to do a regular node name lookup. - else - { - iError = WspiapiLookupNode(pszNodeName, - iSocketType, - iProtocol, - wPort, - (iFlags & AI_CANONNAME), - pptResult); - } - - if (!iError && bClone) - { - iError = WspiapiClone(wUdpPort, *pptResult); - } - - if (iError) - { - WspiapiLegacyFreeAddrInfo(*pptResult); - *pptResult = NULL; - } - - return (iError); -} - - - -__inline -int -WINAPI -WspiapiLegacyGetNameInfo( - IN const struct sockaddr *ptSocketAddress, - IN socklen_t tSocketLength, - OUT char *pszNodeName, - IN size_t tNodeLength, - OUT char *pszServiceName, - IN size_t tServiceLength, - IN int iFlags) -/*++ - -Routine Description - protocol-independent address-to-name translation. - as specified in RFC 2553, Section 6.5. - this is the hacked version that only supports IPv4. - -Arguments - ptSocketAddress socket address to translate. - tSocketLength length of above socket address. - pszNodeName where to return the node name. - tNodeLength size of above buffer. - pszServiceName where to return the service name. - tServiceLength size of above buffer. - iFlags flags of type NI_*. - -Return Value - returns zero if successful, an EAI_* error code if not. - ---*/ -{ - struct servent *ptService; - WORD wPort; - char szBuffer[] = "65535"; - char *pszService = szBuffer; - - struct hostent *ptHost; - struct in_addr tAddress; - char *pszNode = NULL; - char *pc = NULL; - - - // sanity check ptSocketAddress and tSocketLength. - if ((!ptSocketAddress) || (tSocketLength < sizeof(struct sockaddr))) - return EAI_FAIL; - - if (ptSocketAddress->sa_family != AF_INET) - return EAI_FAMILY; - - if (tSocketLength < sizeof(struct sockaddr_in)) - return EAI_FAIL; - - if (!(pszNodeName && tNodeLength) && - !(pszServiceName && tServiceLength)) - { - return EAI_NONAME; - } - - // the draft has the "bad flags" error code, so presumably we - // should check something here. insisting that there aren't - // any unspecified flags set would break forward compatibility, - // however. so we just check for non-sensical combinations. - if ((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD)) - { - return EAI_BADFLAGS; - } - - // translate the port to a service name (if requested). - if (pszServiceName && tServiceLength) - { - wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port; - - if (iFlags & NI_NUMERICSERV) - { - // return numeric form of the address. - _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); - } - else - { - // return service name corresponding to port. - ptService = getservbyport(wPort, - (iFlags & NI_DGRAM) ? "udp" : NULL); - if (ptService && ptService->s_name) - { - // lookup successful. - pszService = ptService->s_name; - } - else - { - // DRAFT: return numeric form of the port! - _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); - } - } - - - if (tServiceLength > strlen(pszService)) - _WSPIAPI_STRCPY_S(pszServiceName, tServiceLength, pszService); - else - return EAI_FAIL; - } - - - // translate the address to a node name (if requested). - if (pszNodeName && tNodeLength) - { - // this is the IPv4-only version, so we have an IPv4 address. - tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr; - - if (iFlags & NI_NUMERICHOST) - { - // return numeric form of the address. - pszNode = inet_ntoa(tAddress); - } - else - { - // return node name corresponding to address. - ptHost = gethostbyaddr((char *) &tAddress, - sizeof(struct in_addr), - AF_INET); - if (ptHost && ptHost->h_name) - { - // DNS lookup successful. - // stop copying at a "." if NI_NOFQDN is specified. - pszNode = ptHost->h_name; - if ((iFlags & NI_NOFQDN) && - ((pc = strchr(pszNode, '.')) != NULL)) - *pc = '\0'; - } - else - { - // DNS lookup failed. return numeric form of the address. - if (iFlags & NI_NAMEREQD) - { - switch (WSAGetLastError()) - { - case WSAHOST_NOT_FOUND: return EAI_NONAME; - case WSATRY_AGAIN: return EAI_AGAIN; - case WSANO_RECOVERY: return EAI_FAIL; - default: return EAI_NONAME; - } - } - else - pszNode = inet_ntoa(tAddress); - } - } - - if (tNodeLength > strlen(pszNode)) - _WSPIAPI_STRCPY_S(pszNodeName, tNodeLength, pszNode); - else - return EAI_FAIL; - } - - return 0; -} - - - -typedef struct -{ - char const *pszName; - FARPROC pfAddress; -} WSPIAPI_FUNCTION; - -#define WSPIAPI_FUNCTION_ARRAY \ -{ \ - "getaddrinfo", (FARPROC) WspiapiLegacyGetAddrInfo, \ - "getnameinfo", (FARPROC) WspiapiLegacyGetNameInfo, \ - "freeaddrinfo", (FARPROC) WspiapiLegacyFreeAddrInfo, \ -} - - - -__inline -FARPROC -WINAPI -WspiapiLoad( - IN WORD wFunction) -/*++ - -Routine Description - try to locate the address family independent name resolution routines - (i.e. getaddrinfo, getnameinfo, freeaddrinfo, gai_strerror). - -Locks - this function call is not synchronized. hence the library containing - the routines might be loaded multiple times. another option is to - synchronize through a spin lock using a static local variable and the - InterlockedExchange operation. - - -Arguments - wFunction ordinal # of the function to get the pointer to - 0 getaddrinfo - 1 getnameinfo - 2 freeaddrinfo - -Return Value - address of the library/legacy routine - ---*/ -{ - HMODULE hLibrary = NULL; - - // these static variables store state across calls, across threads. - static BOOL bInitialized = FALSE; - static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY; - static const int iNumGlobal = (sizeof(rgtGlobal) / - sizeof(WSPIAPI_FUNCTION)); - - // we overwrite rgtGlobal only if all routines exist in library. - WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY; - FARPROC fScratch = NULL; - int i = 0; - - - if (bInitialized) // WspiapiLoad has already been called once - return (rgtGlobal[wFunction].pfAddress); - - for (;;) // breakout loop - { - CHAR SystemDir[MAX_PATH + 1]; - CHAR Path[MAX_PATH + 8]; - - if (GetSystemDirectoryA(SystemDir, MAX_PATH) == 0) - { - break; - } - - // in Whistler and beyond... - // the routines are present in the WinSock 2 library (ws2_32.dll). - // printf("Looking in ws2_32 for getaddrinfo...\n"); - _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); - _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\ws2_32"); - hLibrary = LoadLibraryA(Path); - if (hLibrary != NULL) - { - fScratch = GetProcAddress(hLibrary, "getaddrinfo"); - if (fScratch == NULL) - { - FreeLibrary(hLibrary); - hLibrary = NULL; - } - } - if (hLibrary != NULL) - break; - - - // in the IPv6 Technology Preview... - // the routines are present in the IPv6 WinSock library (wship6.dll). - // printf("Looking in wship6 for getaddrinfo...\n"); - _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); - _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\wship6"); - hLibrary = LoadLibraryA(Path); - if (hLibrary != NULL) - { - fScratch = GetProcAddress(hLibrary, "getaddrinfo"); - if (fScratch == NULL) - { - FreeLibrary(hLibrary); - hLibrary = NULL; - } - } - - break; - } - - - if (hLibrary != NULL) - { - // use routines from this library... - // since getaddrinfo is here, we expect all routines to be here, - // but will fall back to IPv4-only if any of them is missing. - for (i = 0; i < iNumGlobal; i++) - { - rgtLocal[i].pfAddress - = GetProcAddress(hLibrary, rgtLocal[i].pszName); - if (rgtLocal[i].pfAddress == NULL) - { - FreeLibrary(hLibrary); - hLibrary = NULL; - break; - } - } - - if (hLibrary != NULL) - { - // printf("found!\n"); - for (i = 0; i < iNumGlobal; i++) - rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress; - } - } - - bInitialized = TRUE; - return (rgtGlobal[wFunction].pfAddress); -} - - - -__inline -int -WINAPI -WspiapiGetAddrInfo( - IN const char *nodename, - IN const char *servname, - IN const struct addrinfo *hints, - OUT struct addrinfo **res) -{ - int iError; - static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL; - - if (!pfGetAddrInfo) - pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0); - - iError = (*pfGetAddrInfo)(nodename, servname, hints, res); - WSASetLastError(iError); - return iError; -} - - - -__inline -int -WINAPI -WspiapiGetNameInfo ( - IN const struct sockaddr *sa, - IN socklen_t salen, - OUT char *host, - IN size_t hostlen, - OUT char *serv, - IN size_t servlen, - IN int flags) -{ - int iError; - static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL; - - if (!pfGetNameInfo) - pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1); - - iError = (*pfGetNameInfo)(sa, salen, host, hostlen, serv, servlen, flags); - WSASetLastError(iError); - return iError; -} - - - -__inline -void -WINAPI -WspiapiFreeAddrInfo ( - IN struct addrinfo *ai) -{ - static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL; - - if (!pfFreeAddrInfo) - pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2); - (*pfFreeAddrInfo)(ai); -} - -#ifdef __cplusplus -} -#endif - -#endif // if (NTDDI_VERSION >= WIN2K) -#endif // _WSPIAPI_H_ - +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + wspiapi.h + +Abstract: + The file contains protocol independent API functions. + +Revision History: + Wed Jul 12 10:50:31 2000, Created + +--*/ + +#ifndef _WSPIAPI_H_ +#define _WSPIAPI_H_ + +#pragma once + +#if (NTDDI_VERSION >= NTDDI_WIN2K) + +#include // sprintf() +#include // calloc(), strtoul() +#include // calloc() +#include // strlen(), strcmp(), strstr() + +#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L + +#define _WSPIAPI_STRCPY_S strcpy_s +#define _WSPIAPI_STRCAT_S strcat_s +#define _WSPIAPI_STRNCPY_S strncpy_s +#define _WSPIAPI_SPRINTF_S_1 sprintf_s + +#else + +#define _WSPIAPI_STRCPY_S(_Dst, _Size, _Src) strcpy((_Dst), (_Src)) +#define _WSPIAPI_STRCAT_S(_Dst, _Size, _Src) strcat((_Dst), (_Src)) +#define _WSPIAPI_STRNCPY_S(_Dst, _Size, _Src, _Count) strncpy((_Dst), (_Src), (_Count)); (_Dst)[(_Size) - 1] = 0 +#define _WSPIAPI_SPRINTF_S_1(_Dst, _Size, _Format, _Arg1) sprintf((_Dst), (_Format), (_Arg1)) + +#endif // defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L + +#if !defined(_WSPIAPI_COUNTOF) +#if !defined(__cplusplus) +#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0])) +#else +template +char (&__wspiapi_countof_helper(__CountofType (&_Array)[_N]))[_N]; +#define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array)) +#endif +#endif + +#define WspiapiMalloc(tSize) calloc(1, (tSize)) +#define WspiapiFree(p) free(p) +#define WspiapiSwap(a, b, c) { (c) = (a); (a) = (b); (b) = (c); } +#define getaddrinfo WspiapiGetAddrInfo +#define getnameinfo WspiapiGetNameInfo +#define freeaddrinfo WspiapiFreeAddrInfo + +// +// These function pointers are also within the #if (NTDDI_VERSION >= WIN2K) +// because they are used by the other functions defined in this file available +// only on win2k and above. +// +typedef int (WINAPI *WSPIAPI_PGETADDRINFO) ( + IN const char *nodename, + IN const char *servname, + IN const struct addrinfo *hints, + OUT struct addrinfo **res); + +typedef int (WINAPI *WSPIAPI_PGETNAMEINFO) ( + IN const struct sockaddr *sa, + IN socklen_t salen, + OUT char *host, + IN size_t hostlen, + OUT char *serv, + IN size_t servlen, + IN int flags); + +typedef void (WINAPI *WSPIAPI_PFREEADDRINFO) ( + IN struct addrinfo *ai); + + + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////// +// v4 only versions of getaddrinfo and friends. +// NOTE: gai_strerror is inlined in ws2tcpip.h +//////////////////////////////////////////////////////////// + +__inline +char * +WINAPI +WspiapiStrdup ( + IN const char * pszString) +/*++ + +Routine Description + allocates enough storage via calloc() for a copy of the string, + copies the string into the new memory, and returns a pointer to it. + +Arguments + pszString string to copy into new memory + +Return Value + a pointer to the newly allocated storage with the string in it. + NULL if enough memory could not be allocated, or string was NULL. + +--*/ +{ + char *pszMemory; + size_t cchMemory; + + if (!pszString) + return(NULL); + + cchMemory = strlen(pszString) + 1; + pszMemory = (char *) WspiapiMalloc(cchMemory); + if (!pszMemory) + return(NULL); + + _WSPIAPI_STRCPY_S(pszMemory, cchMemory, pszString); + return pszMemory; +} + + + +__inline +BOOL +WINAPI +WspiapiParseV4Address ( + IN const char * pszAddress, + OUT PDWORD pdwAddress) +/*++ + +Routine Description + get the IPv4 address (in network byte order) from its string + representation. the syntax should be a.b.c.d. + +Arguments + pszArgument string representation of the IPv4 address + ptAddress pointer to the resulting IPv4 address + +Return Value + Returns FALSE if there is an error, TRUE for success. + +--*/ +{ + DWORD dwAddress = 0; + const char *pcNext = NULL; + int iCount = 0; + + // ensure there are 3 '.' (periods) + for (pcNext = pszAddress; *pcNext != '\0'; pcNext++) + if (*pcNext == '.') + iCount++; + if (iCount != 3) + return FALSE; + + // return an error if dwAddress is INADDR_NONE (255.255.255.255) + // since this is never a valid argument to getaddrinfo. + dwAddress = inet_addr(pszAddress); + if (dwAddress == INADDR_NONE) + return FALSE; + + *pdwAddress = dwAddress; + return TRUE; +} + + + +__inline +struct addrinfo * +WINAPI +WspiapiNewAddrInfo ( + IN int iSocketType, + IN int iProtocol, + IN WORD wPort, + IN DWORD dwAddress) +/*++ + +Routine Description + allocate an addrinfo structure and populate fields. + IPv4 specific internal function, not exported. + +Arguments + iSocketType SOCK_*. can be wildcarded (zero). + iProtocol IPPROTO_*. can be wildcarded (zero). + wPort port number of service (in network order). + dwAddress IPv4 address (in network order). + +Return Value + returns an addrinfo struct, or NULL if out of memory. + +--*/ +{ + struct addrinfo *ptNew; + struct sockaddr_in *ptAddress; + + // allocate a new addrinfo structure. + ptNew = + (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo)); + if (!ptNew) + return NULL; + + ptAddress = + (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in)); + if (!ptAddress) + { + WspiapiFree(ptNew); + return NULL; + } + ptAddress->sin_family = AF_INET; + ptAddress->sin_port = wPort; + ptAddress->sin_addr.s_addr = dwAddress; + + // fill in the fields... + ptNew->ai_family = PF_INET; + ptNew->ai_socktype = iSocketType; + ptNew->ai_protocol = iProtocol; + ptNew->ai_addrlen = sizeof(struct sockaddr_in); + ptNew->ai_addr = (struct sockaddr *) ptAddress; + + return ptNew; +} + + + +__inline +int +WINAPI +WspiapiQueryDNS( + IN const char *pszNodeName, + IN int iSocketType, + IN int iProtocol, + IN WORD wPort, + OUT char pszAlias[NI_MAXHOST], + OUT struct addrinfo **pptResult) +/*++ + +Routine Description + helper routine for WspiapiLookupNode. + performs name resolution by querying the DNS for A records. + *pptResult would need to be freed if an error is returned. + +Arguments + pszNodeName name of node to resolve. + iSocketType SOCK_*. can be wildcarded (zero). + iProtocol IPPROTO_*. can be wildcarded (zero). + wPort port number of service (in network order). + pszAlias where to return the alias. must be of size NI_MAXHOST. + pptResult where to return the result. + +Return Value + Returns 0 on success, an EAI_* style error value otherwise. + +--*/ +{ + struct addrinfo **pptNext = pptResult; + struct hostent *ptHost = NULL; + char **ppAddresses; + + *pptNext = NULL; + pszAlias[0] = '\0'; + + ptHost = gethostbyname(pszNodeName); + if (ptHost) + { + if ((ptHost->h_addrtype == AF_INET) && + (ptHost->h_length == sizeof(struct in_addr))) + { + for (ppAddresses = ptHost->h_addr_list; + *ppAddresses != NULL; + ppAddresses++) + { + // create an addrinfo structure... + *pptNext = WspiapiNewAddrInfo( + iSocketType, + iProtocol, + wPort, + ((struct in_addr *) *ppAddresses)->s_addr); + if (!*pptNext) + return EAI_MEMORY; + + pptNext = &((*pptNext)->ai_next); + } + } + + // pick up the canonical name. + _WSPIAPI_STRNCPY_S(pszAlias, NI_MAXHOST, ptHost->h_name, NI_MAXHOST - 1); + + return 0; + } + + switch (WSAGetLastError()) + { + case WSAHOST_NOT_FOUND: return EAI_NONAME; + case WSATRY_AGAIN: return EAI_AGAIN; + case WSANO_RECOVERY: return EAI_FAIL; + case WSANO_DATA: return EAI_NODATA; + default: return EAI_NONAME; + } +} + + + +__inline +int +WINAPI +WspiapiLookupNode( + IN const char *pszNodeName, + IN int iSocketType, + IN int iProtocol, + IN WORD wPort, + IN BOOL bAI_CANONNAME, + OUT struct addrinfo **pptResult) +/*++ + +Routine Description + resolve a nodename and return a list of addrinfo structures. + IPv4 specific internal function, not exported. + *pptResult would need to be freed if an error is returned. + + NOTE: if bAI_CANONNAME is true, the canonical name should be + returned in the first addrinfo structure. + +Arguments + pszNodeName name of node to resolve. + iSocketType SOCK_*. can be wildcarded (zero). + iProtocol IPPROTO_*. can be wildcarded (zero). + wPort port number of service (in network order). + bAI_CANONNAME whether the AI_CANONNAME flag is set. + pptResult where to return result. + +Return Value + Returns 0 on success, an EAI_* style error value otherwise. + +--*/ +{ + int iError = 0; + int iAliasCount = 0; + + char szFQDN1[NI_MAXHOST] = ""; + char szFQDN2[NI_MAXHOST] = ""; + char *pszName = szFQDN1; + char *pszAlias = szFQDN2; + char *pszScratch = NULL; + _WSPIAPI_STRNCPY_S(pszName, NI_MAXHOST, pszNodeName, NI_MAXHOST - 1); + + for (;;) + { + iError = WspiapiQueryDNS(pszNodeName, + iSocketType, + iProtocol, + wPort, + pszAlias, + pptResult); + if (iError) + break; + + // if we found addresses, then we are done. + if (*pptResult) + break; + + // stop infinite loops due to DNS misconfiguration. there appears + // to be no particular recommended limit in RFCs 1034 and 1035. + if ((!strlen(pszAlias)) || + (!strcmp(pszName, pszAlias)) || + (++iAliasCount == 16)) + { + iError = EAI_FAIL; + break; + } + + // there was a new CNAME, look again. + WspiapiSwap(pszName, pszAlias, pszScratch); + } + + if (!iError && bAI_CANONNAME) + { + (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias); + if (!(*pptResult)->ai_canonname) + iError = EAI_MEMORY; + } + + return iError; +} + + + +__inline +int +WINAPI +WspiapiClone ( + IN WORD wPort, + IN struct addrinfo *ptResult) +/*++ + +Routine Description + clone every addrinfo structure in ptResult for the UDP service. + ptResult would need to be freed if an error is returned. + +Arguments + wPort port number of UDP service. + ptResult list of addrinfo structures, each + of whose node needs to be cloned. + +Return Value + Returns 0 on success, an EAI_MEMORY on allocation failure. + +--*/ +{ + struct addrinfo *ptNext = NULL; + struct addrinfo *ptNew = NULL; + + for (ptNext = ptResult; ptNext != NULL; ) + { + // create an addrinfo structure... + ptNew = WspiapiNewAddrInfo( + SOCK_DGRAM, + ptNext->ai_protocol, + wPort, + ((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr); + if (!ptNew) + break; + + // link the cloned addrinfo + ptNew->ai_next = ptNext->ai_next; + ptNext->ai_next = ptNew; + ptNext = ptNew->ai_next; + } + + if (ptNext != NULL) + return EAI_MEMORY; + + return 0; +} + + + +__inline +void +WINAPI +WspiapiLegacyFreeAddrInfo ( + IN struct addrinfo *ptHead) +/*++ + +Routine Description + Free an addrinfo structure (or chain of structures). + As specified in RFC 2553, Section 6.4. + +Arguments + ptHead structure (chain) to free + +--*/ +{ + struct addrinfo *ptNext; // next strcture to free + + for (ptNext = ptHead; ptNext != NULL; ptNext = ptHead) + { + if (ptNext->ai_canonname) + WspiapiFree(ptNext->ai_canonname); + + if (ptNext->ai_addr) + WspiapiFree(ptNext->ai_addr); + + ptHead = ptNext->ai_next; + WspiapiFree(ptNext); + } +} + + + +__inline +int +WINAPI +WspiapiLegacyGetAddrInfo( + IN const char *pszNodeName, + IN const char *pszServiceName, + IN const struct addrinfo *ptHints, + OUT struct addrinfo **pptResult) +/*++ + +Routine Description + Protocol-independent name-to-address translation. + As specified in RFC 2553, Section 6.4. + This is the hacked version that only supports IPv4. + +Arguments + pszNodeName node name to lookup. + pszServiceName service name to lookup. + ptHints hints about how to process request. + pptResult where to return result. + +Return Value + returns zero if successful, an EAI_* error code if not. + +--*/ +{ + int iError = 0; + int iFlags = 0; + int iFamily = PF_UNSPEC; + int iSocketType = 0; + int iProtocol = 0; + WORD wPort = 0; + DWORD dwAddress = 0; + + struct servent *ptService = NULL; + char *pc = NULL; + BOOL bClone = FALSE; + WORD wTcpPort = 0; + WORD wUdpPort = 0; + + + // initialize pptResult with default return value. + *pptResult = NULL; + + + //////////////////////////////////////// + // validate arguments... + // + + // both the node name and the service name can't be NULL. + if ((!pszNodeName) && (!pszServiceName)) + return EAI_NONAME; + + // validate hints. + if (ptHints) + { + // all members other than ai_flags, ai_family, ai_socktype + // and ai_protocol must be zero or a null pointer. + if ((ptHints->ai_addrlen != 0) || + (ptHints->ai_canonname != NULL) || + (ptHints->ai_addr != NULL) || + (ptHints->ai_next != NULL)) + { + return EAI_FAIL; + } + + // the spec has the "bad flags" error code, so presumably we + // should check something here. insisting that there aren't + // any unspecified flags set would break forward compatibility, + // however. so we just check for non-sensical combinations. + // + // we cannot come up with a canonical name given a null node name. + iFlags = ptHints->ai_flags; + if ((iFlags & AI_CANONNAME) && !pszNodeName) + return EAI_BADFLAGS; + + // we only support a limited number of protocol families. + iFamily = ptHints->ai_family; + if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET)) + return EAI_FAMILY; + + // we only support only these socket types. + iSocketType = ptHints->ai_socktype; + if ((iSocketType != 0) && + (iSocketType != SOCK_STREAM) && + (iSocketType != SOCK_DGRAM) && + (iSocketType != SOCK_RAW)) + return EAI_SOCKTYPE; + + // REVIEW: What if ai_socktype and ai_protocol are at odds? + iProtocol = ptHints->ai_protocol; + } + + + //////////////////////////////////////// + // do service lookup... + + if (pszServiceName) + { + wPort = (WORD) strtoul(pszServiceName, &pc, 10); + if (*pc == '\0') // numeric port string + { + wPort = wTcpPort = wUdpPort = htons(wPort); + if (iSocketType == 0) + { + bClone = TRUE; + iSocketType = SOCK_STREAM; + } + } + else // non numeric port string + { + if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM)) + { + ptService = getservbyname(pszServiceName, "udp"); + if (ptService) + wPort = wUdpPort = ptService->s_port; + } + + if ((iSocketType == 0) || (iSocketType == SOCK_STREAM)) + { + ptService = getservbyname(pszServiceName, "tcp"); + if (ptService) + wPort = wTcpPort = ptService->s_port; + } + + // assumes 0 is an invalid service port... + if (wPort == 0) // no service exists + return (iSocketType ? EAI_SERVICE : EAI_NONAME); + + if (iSocketType == 0) + { + // if both tcp and udp, process tcp now & clone udp later. + iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM; + bClone = (wTcpPort && wUdpPort); + } + } + } + + + + //////////////////////////////////////// + // do node name lookup... + + // if we weren't given a node name, + // return the wildcard or loopback address (depending on AI_PASSIVE). + // + // if we have a numeric host address string, + // return the binary address. + // + if ((!pszNodeName) || (WspiapiParseV4Address(pszNodeName, &dwAddress))) + { + if (!pszNodeName) + { + dwAddress = htonl((iFlags & AI_PASSIVE) + ? INADDR_ANY + : INADDR_LOOPBACK); + } + + // create an addrinfo structure... + *pptResult = + WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); + if (!(*pptResult)) + iError = EAI_MEMORY; + + if (!iError && pszNodeName) + { + // implementation specific behavior: set AI_NUMERICHOST + // to indicate that we got a numeric host address string. + (*pptResult)->ai_flags |= AI_NUMERICHOST; + + // return the numeric address string as the canonical name + if (iFlags & AI_CANONNAME) + { + (*pptResult)->ai_canonname = + WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress))); + if (!(*pptResult)->ai_canonname) + iError = EAI_MEMORY; + } + } + } + + + // if we do not have a numeric host address string and + // AI_NUMERICHOST flag is set, return an error! + else if (iFlags & AI_NUMERICHOST) + { + iError = EAI_NONAME; + } + + + // since we have a non-numeric node name, + // we have to do a regular node name lookup. + else + { + iError = WspiapiLookupNode(pszNodeName, + iSocketType, + iProtocol, + wPort, + (iFlags & AI_CANONNAME), + pptResult); + } + + if (!iError && bClone) + { + iError = WspiapiClone(wUdpPort, *pptResult); + } + + if (iError) + { + WspiapiLegacyFreeAddrInfo(*pptResult); + *pptResult = NULL; + } + + return (iError); +} + + + +__inline +int +WINAPI +WspiapiLegacyGetNameInfo( + IN const struct sockaddr *ptSocketAddress, + IN socklen_t tSocketLength, + OUT char *pszNodeName, + IN size_t tNodeLength, + OUT char *pszServiceName, + IN size_t tServiceLength, + IN int iFlags) +/*++ + +Routine Description + protocol-independent address-to-name translation. + as specified in RFC 2553, Section 6.5. + this is the hacked version that only supports IPv4. + +Arguments + ptSocketAddress socket address to translate. + tSocketLength length of above socket address. + pszNodeName where to return the node name. + tNodeLength size of above buffer. + pszServiceName where to return the service name. + tServiceLength size of above buffer. + iFlags flags of type NI_*. + +Return Value + returns zero if successful, an EAI_* error code if not. + +--*/ +{ + struct servent *ptService; + WORD wPort; + char szBuffer[] = "65535"; + char *pszService = szBuffer; + + struct hostent *ptHost; + struct in_addr tAddress; + char *pszNode = NULL; + char *pc = NULL; + + + // sanity check ptSocketAddress and tSocketLength. + if ((!ptSocketAddress) || (tSocketLength < sizeof(struct sockaddr))) + return EAI_FAIL; + + if (ptSocketAddress->sa_family != AF_INET) + return EAI_FAMILY; + + if (tSocketLength < sizeof(struct sockaddr_in)) + return EAI_FAIL; + + if (!(pszNodeName && tNodeLength) && + !(pszServiceName && tServiceLength)) + { + return EAI_NONAME; + } + + // the draft has the "bad flags" error code, so presumably we + // should check something here. insisting that there aren't + // any unspecified flags set would break forward compatibility, + // however. so we just check for non-sensical combinations. + if ((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD)) + { + return EAI_BADFLAGS; + } + + // translate the port to a service name (if requested). + if (pszServiceName && tServiceLength) + { + wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port; + + if (iFlags & NI_NUMERICSERV) + { + // return numeric form of the address. + _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); + } + else + { + // return service name corresponding to port. + ptService = getservbyport(wPort, + (iFlags & NI_DGRAM) ? "udp" : NULL); + if (ptService && ptService->s_name) + { + // lookup successful. + pszService = ptService->s_name; + } + else + { + // DRAFT: return numeric form of the port! + _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); + } + } + + + if (tServiceLength > strlen(pszService)) + _WSPIAPI_STRCPY_S(pszServiceName, tServiceLength, pszService); + else + return EAI_FAIL; + } + + + // translate the address to a node name (if requested). + if (pszNodeName && tNodeLength) + { + // this is the IPv4-only version, so we have an IPv4 address. + tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr; + + if (iFlags & NI_NUMERICHOST) + { + // return numeric form of the address. + pszNode = inet_ntoa(tAddress); + } + else + { + // return node name corresponding to address. + ptHost = gethostbyaddr((char *) &tAddress, + sizeof(struct in_addr), + AF_INET); + if (ptHost && ptHost->h_name) + { + // DNS lookup successful. + // stop copying at a "." if NI_NOFQDN is specified. + pszNode = ptHost->h_name; + if ((iFlags & NI_NOFQDN) && + ((pc = strchr(pszNode, '.')) != NULL)) + *pc = '\0'; + } + else + { + // DNS lookup failed. return numeric form of the address. + if (iFlags & NI_NAMEREQD) + { + switch (WSAGetLastError()) + { + case WSAHOST_NOT_FOUND: return EAI_NONAME; + case WSATRY_AGAIN: return EAI_AGAIN; + case WSANO_RECOVERY: return EAI_FAIL; + default: return EAI_NONAME; + } + } + else + pszNode = inet_ntoa(tAddress); + } + } + + if (tNodeLength > strlen(pszNode)) + _WSPIAPI_STRCPY_S(pszNodeName, tNodeLength, pszNode); + else + return EAI_FAIL; + } + + return 0; +} + + + +typedef struct +{ + char const *pszName; + FARPROC pfAddress; +} WSPIAPI_FUNCTION; + +#define WSPIAPI_FUNCTION_ARRAY \ +{ \ + "getaddrinfo", (FARPROC) WspiapiLegacyGetAddrInfo, \ + "getnameinfo", (FARPROC) WspiapiLegacyGetNameInfo, \ + "freeaddrinfo", (FARPROC) WspiapiLegacyFreeAddrInfo, \ +} + + + +__inline +FARPROC +WINAPI +WspiapiLoad( + IN WORD wFunction) +/*++ + +Routine Description + try to locate the address family independent name resolution routines + (i.e. getaddrinfo, getnameinfo, freeaddrinfo, gai_strerror). + +Locks + this function call is not synchronized. hence the library containing + the routines might be loaded multiple times. another option is to + synchronize through a spin lock using a static local variable and the + InterlockedExchange operation. + + +Arguments + wFunction ordinal # of the function to get the pointer to + 0 getaddrinfo + 1 getnameinfo + 2 freeaddrinfo + +Return Value + address of the library/legacy routine + +--*/ +{ + HMODULE hLibrary = NULL; + + // these static variables store state across calls, across threads. + static BOOL bInitialized = FALSE; + static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY; + static const int iNumGlobal = (sizeof(rgtGlobal) / + sizeof(WSPIAPI_FUNCTION)); + + // we overwrite rgtGlobal only if all routines exist in library. + WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY; + FARPROC fScratch = NULL; + int i = 0; + + + if (bInitialized) // WspiapiLoad has already been called once + return (rgtGlobal[wFunction].pfAddress); + + for (;;) // breakout loop + { + CHAR SystemDir[MAX_PATH + 1]; + CHAR Path[MAX_PATH + 8]; + + if (GetSystemDirectoryA(SystemDir, MAX_PATH) == 0) + { + break; + } + + // in Whistler and beyond... + // the routines are present in the WinSock 2 library (ws2_32.dll). + // printf("Looking in ws2_32 for getaddrinfo...\n"); + _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); + _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\ws2_32"); + hLibrary = LoadLibraryA(Path); + if (hLibrary != NULL) + { + fScratch = GetProcAddress(hLibrary, "getaddrinfo"); + if (fScratch == NULL) + { + FreeLibrary(hLibrary); + hLibrary = NULL; + } + } + if (hLibrary != NULL) + break; + + + // in the IPv6 Technology Preview... + // the routines are present in the IPv6 WinSock library (wship6.dll). + // printf("Looking in wship6 for getaddrinfo...\n"); + _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); + _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\wship6"); + hLibrary = LoadLibraryA(Path); + if (hLibrary != NULL) + { + fScratch = GetProcAddress(hLibrary, "getaddrinfo"); + if (fScratch == NULL) + { + FreeLibrary(hLibrary); + hLibrary = NULL; + } + } + + break; + } + + + if (hLibrary != NULL) + { + // use routines from this library... + // since getaddrinfo is here, we expect all routines to be here, + // but will fall back to IPv4-only if any of them is missing. + for (i = 0; i < iNumGlobal; i++) + { + rgtLocal[i].pfAddress + = GetProcAddress(hLibrary, rgtLocal[i].pszName); + if (rgtLocal[i].pfAddress == NULL) + { + FreeLibrary(hLibrary); + hLibrary = NULL; + break; + } + } + + if (hLibrary != NULL) + { + // printf("found!\n"); + for (i = 0; i < iNumGlobal; i++) + rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress; + } + } + + bInitialized = TRUE; + return (rgtGlobal[wFunction].pfAddress); +} + + + +__inline +int +WINAPI +WspiapiGetAddrInfo( + IN const char *nodename, + IN const char *servname, + IN const struct addrinfo *hints, + OUT struct addrinfo **res) +{ + int iError; + static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL; + + if (!pfGetAddrInfo) + pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0); + + iError = (*pfGetAddrInfo)(nodename, servname, hints, res); + WSASetLastError(iError); + return iError; +} + + + +__inline +int +WINAPI +WspiapiGetNameInfo ( + IN const struct sockaddr *sa, + IN socklen_t salen, + OUT char *host, + IN size_t hostlen, + OUT char *serv, + IN size_t servlen, + IN int flags) +{ + int iError; + static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL; + + if (!pfGetNameInfo) + pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1); + + iError = (*pfGetNameInfo)(sa, salen, host, hostlen, serv, servlen, flags); + WSASetLastError(iError); + return iError; +} + + + +__inline +void +WINAPI +WspiapiFreeAddrInfo ( + IN struct addrinfo *ai) +{ + static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL; + + if (!pfFreeAddrInfo) + pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2); + (*pfFreeAddrInfo)(ai); +} + +#ifdef __cplusplus +} +#endif + +#endif // if (NTDDI_VERSION >= WIN2K) +#endif // _WSPIAPI_H_ + diff --git a/misc/buildfiles/osx/Xonotic-SDL.app/Contents/MacOS/libd0_blind_id.0.dylib b/misc/buildfiles/osx/Xonotic-SDL.app/Contents/MacOS/libd0_blind_id.0.dylib index 613e8b6f7364b53bd2653c86913f5dea0f1854c9..f7c1abbf57b8e3f8fa316f706c66359a08d4b1cf 100755 GIT binary patch delta 33424 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 Zzuagu?k&A%R_VO%J$q*gANb3({|AE&vW)-$ delta 33598 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 Kf43`;0ks4-TQTSW diff --git a/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.0.dylib b/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id.0.dylib index 613e8b6f7364b53bd2653c86913f5dea0f1854c9..f7c1abbf57b8e3f8fa316f706c66359a08d4b1cf 100755 GIT binary patch delta 33424 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 Zzuagu?k&A%R_VO%J$q*gANb3({|AE&vW)-$ delta 33598 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 Kf43`;0ks4-TQTSW -- 2.39.2