DWORD VmDnsDuplicatePtrRecord( PVMDNS_RECORD pSrc, PVMDNS_RECORD *ppDest ) { DWORD dwError = 0; PVMDNS_RECORD pRecord = NULL; BAIL_ON_VMDNS_INVALID_POINTER(pSrc, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppDest, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_RECORD), (void**)&pRecord); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyPtrRecord(pSrc, pRecord); BAIL_ON_VMDNS_ERROR(dwError); *ppDest = pRecord; pRecord = NULL; cleanup: return dwError; error: VMDNS_FREE_RECORD(pRecord); if (ppDest) { *ppDest = NULL; } goto cleanup; }
DWORD VmDnsForwarderInit( PVMDNS_FORWARDER_CONTEXT* ppForwarder ) { DWORD dwError = ERROR_SUCCESS; PVMDNS_FORWARDER_CONTEXT pForwarderContext = NULL; BAIL_ON_VMDNS_INVALID_POINTER(ppForwarder, dwError); dwError = VmDnsAllocateMemory( sizeof(VMDNS_FORWARDER_CONTEXT), (PVOID*)&pForwarderContext); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateRWLock(&pForwarderContext->pLock); BAIL_ON_VMDNS_ERROR(dwError); *ppForwarder = pForwarderContext; cleanup: return dwError; error: if (pForwarderContext) { VmDnsForwarderCleanup(pForwarderContext); } goto cleanup; }
static int* VmDnsGetLockKey( pthread_key_t* pLockKey ) { DWORD dwError = ERROR_SUCCESS; int* pCounter = NULL; int* pCount = (int*)pthread_getspecific(*pLockKey); if (!pCount) { dwError = VmDnsAllocateMemory(sizeof(int), (void**)&(pCounter)); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_setspecific(*pLockKey, pCounter); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); pCounter = NULL; pCount = (int*)pthread_getspecific(*pLockKey); } cleanup: return pCount; error: VMDNS_SAFE_FREE_MEMORY(pCounter); goto cleanup; }
DWORD VmDnsAllocateRWLock( PVMDNS_RWLOCK* ppLock ) { DWORD dwError = 0; PVMDNS_RWLOCK pLock = NULL; BAIL_ON_VMDNS_INVALID_POINTER(ppLock, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_RWLOCK), (void**)&pLock); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_rwlock_init(&pLock->rwLock, NULL); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_key_create(&pLock->readKey, VmDnsFreeLockCount); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_key_create(&pLock->writeKey, VmDnsFreeLockCount); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); *ppLock = pLock; cleanup: return dwError; error: VMDNS_SAFE_FREE_MEMORY(pLock); goto cleanup; }
DWORD VmDnsAllocateMutex( PVMDNS_MUTEX* ppMutex ) { DWORD dwError = ERROR_SUCCESS; PVMDNS_MUTEX pVmDnsMutex = NULL; if ( ppMutex == NULL ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(VMDNS_MUTEX), ((PVOID*)&pVmDnsMutex)); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsInitializeMutexContent( pVmDnsMutex ); BAIL_ON_VMDNS_ERROR(dwError); *ppMutex = pVmDnsMutex; pVmDnsMutex = NULL; error: VMDNS_SAFE_FREE_MUTEX( pVmDnsMutex ); return dwError; }
DWORD VmDnsAllocateCondition( PVMDNS_COND* ppCondition ) { DWORD dwError = ERROR_SUCCESS; PVMDNS_COND pVmDnsCond = NULL; if ( ppCondition == NULL ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(VMDNS_COND), ((PVOID*)&pVmDnsCond)); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsInitializeConditionContent( pVmDnsCond ); BAIL_ON_VMDNS_ERROR(dwError); *ppCondition = pVmDnsCond; pVmDnsCond = NULL; error: VMDNS_SAFE_FREE_CONDITION( pVmDnsCond ); return dwError; }
/** * @brief Creates a Event queue to be used for detecting events on sockets * * @param[in,optional] iEventQueueSize * specifies the event queue size. * This value can be (-1) to use the default value * @param[out] ppQueue Pointer to accept created event queue * * @return 0 on success */ DWORD VmDnsSockWinCreateEventQueue( int iEventQueueSize, PVM_SOCK_EVENT_QUEUE* ppQueue ) { DWORD dwError = 0; int sockError = 0; PVM_SOCK_EVENT_QUEUE pQueue = NULL; if (!ppQueue) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (iEventQueueSize <= 0) { iEventQueueSize = VM_SOCK_WINDOWS_DEFAULT_QUEUE_SIZE; } dwError = VmDnsAllocateMemory(sizeof(*pQueue), (PVOID*)&pQueue); BAIL_ON_VMDNS_ERROR(dwError); pQueue->hIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0); if (!pQueue->hIOCP) { dwError = GetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } pQueue->hEventListen = WSACreateEvent(); if (pQueue->hEventListen == WSA_INVALID_EVENT) { dwError = WSAGetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } *ppQueue = pQueue; cleanup: return dwError; error: if (ppQueue) { *ppQueue = NULL; } VmDnsSockWinCloseEventQueue(pQueue); goto cleanup; }
DWORD VmDnsCreateThread( PVMDNS_THREAD pThread, BOOLEAN bDetached, VmDnsStartRoutine* pStartRoutine, PVOID pArgs ) { DWORD dwError = ERROR_SUCCESS; PVMDNS_THREAD_START_INFO pThreadStartInfo = NULL; pthread_attr_t thrAttr; BOOLEAN bThreadAttrInited = FALSE; if ( ( pThread == NULL ) || ( pStartRoutine == NULL ) ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if( bDetached != FALSE ) { pthread_attr_init(&thrAttr); bThreadAttrInited = TRUE; pthread_attr_setdetachstate(&thrAttr, PTHREAD_CREATE_DETACHED); } dwError = VmDnsAllocateMemory( sizeof(VMDNS_THREAD_START_INFO), ((PVOID*)&pThreadStartInfo) ); BAIL_ON_VMDNS_ERROR(dwError); pThreadStartInfo->pStartRoutine = pStartRoutine; pThreadStartInfo->pArgs = pArgs; dwError = pthread_create( pThread, ((bDetached == FALSE) ? NULL : &thrAttr), ThreadFunction, pThreadStartInfo ); BAIL_ON_VMDNS_ERROR(dwError); // we started successfully -> pThreadStartInfo is now owned by // ThreadFunction pThreadStartInfo = NULL; error: if(bThreadAttrInited != FALSE) { pthread_attr_destroy(&thrAttr); } VMDNS_SAFE_FREE_MEMORY( pThreadStartInfo ); return dwError; }
static DWORD VmDnsSockPosixAcceptConnection( PVM_SOCKET pListener, PVM_SOCKET* ppSocket ) { DWORD dwError = 0; PVM_SOCKET pSocket = NULL; int fd = -1; dwError = VmDnsAllocateMemory(sizeof(*pSocket), (PVOID*)&pSocket); BAIL_ON_POSIX_SOCK_ERROR(dwError); pSocket->refCount = 1; dwError = VmDnsAllocateMutex(&pSocket->pMutex); BAIL_ON_POSIX_SOCK_ERROR(dwError); pSocket->protocol = pListener->protocol; pSocket->type = VM_SOCK_TYPE_SERVER; fd = accept(pListener->fd, &pSocket->addr, &pSocket->addrLen); if (fd < 0) { dwError = LwErrnoToWin32Error(errno); BAIL_ON_POSIX_SOCK_ERROR(dwError); } pSocket->fd = fd; pSocket->pAddr = &pSocket->addr; *ppSocket = pSocket; cleanup: return dwError; error: *ppSocket = NULL; if (pSocket) { VmDnsSockPosixFreeSocket(pSocket); } if (fd >= 0) { close(fd); } goto cleanup; }
DWORD VmDnsCreateSoaRecord( PVMDNS_ZONE_INFO pZoneInfo, PVMDNS_RECORD* ppRecord ) { DWORD dwError = 0; PVMDNS_RECORD pRecord = NULL; PSTR pszName = NULL; PSTR pszPrimaryDnsName = NULL; PSTR pszRName = NULL; BAIL_ON_VMDNS_INVALID_POINTER(pZoneInfo, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppRecord, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_RECORD), (void**)&pRecord); BAIL_ON_VMDNS_ERROR(dwError); pRecord->dwType = VMDNS_RR_TYPE_SOA; dwError = VmDnsAllocateStringA(VMDNS_SOA_RECORD_NAME, &pszName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringA(pZoneInfo->pszPrimaryDnsSrvName, &pszPrimaryDnsName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringA(pZoneInfo->pszRName, &pszRName); BAIL_ON_VMDNS_ERROR(dwError); pRecord->pszName = pszName; pRecord->iClass = VMDNS_CLASS_IN; pRecord->Data.SOA.pNameAdministrator = pszRName; pRecord->Data.SOA.pNamePrimaryServer = pszPrimaryDnsName; pRecord->Data.SOA.dwDefaultTtl = pZoneInfo->minimum; pRecord->Data.SOA.dwExpire = pZoneInfo->expire; pRecord->Data.SOA.dwRefresh = pZoneInfo->refreshInterval; pRecord->Data.SOA.dwRetry = pZoneInfo->retryInterval; pRecord->Data.SOA.dwSerialNo = pZoneInfo->serial; pszName = NULL; pszRName = NULL; *ppRecord = pRecord; cleanup: return dwError; error: VmDnsFreeMemory(pszName); VmDnsFreeMemory(pszRName); VMDNS_FREE_RECORD(pRecord); goto cleanup; }
DWORD VmDnsSockWinAllocateIoBuffer( VM_SOCK_EVENT_TYPE eventType, PVM_SOCK_EVENT_CONTEXT pEventContext, PFN_SOCK_EVENT_CONTEXT_FREE pfnEventContextFree, DWORD dwSize, PVM_SOCK_IO_BUFFER* ppIoBuffer ) { DWORD dwError = 0; PVM_SOCK_IO_CONTEXT pIoContext = NULL; if (!ppIoBuffer) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory(sizeof(VM_SOCK_IO_CONTEXT) + dwSize, (PVOID*)&pIoContext); BAIL_ON_VMDNS_ERROR(dwError); pIoContext->eventType = eventType; pIoContext->IoBuffer.dwExpectedSize = dwSize; pIoContext->IoBuffer.pData = pIoContext->DataBuffer; VMDNS_LOG_INFO("Buffer Allocated - Address: %p, Event: %d, Size: %d", (DWORD)&pIoContext->IoBuffer, pIoContext->eventType, pIoContext->IoBuffer.dwExpectedSize); *ppIoBuffer = &(pIoContext->IoBuffer); cleanup: return dwError; error: if (ppIoBuffer) { *ppIoBuffer = NULL; } if (pIoContext) { VmDnsSockWinFreeIoBuffer(&pIoContext->IoBuffer); } goto cleanup; }
VMDNS_API DWORD VmDnsOpenServerWithTimeOutA( PCSTR pszNetworkAddress, PCSTR pszUserName, PCSTR pszDomain, PCSTR pszPassword, DWORD dwFlags, PVOID pReserved, DWORD dwTimeOut, PVMDNS_SERVER_CONTEXT *ppServerContext ) { DWORD dwError = 0; handle_t hBinding = NULL; PVMDNS_SERVER_CONTEXT pServerContext = NULL; CHAR szRpcPort[] = VMDNS_RPC_TCP_END_POINT; dwError = VmDnsAllocateMemory( sizeof(*pServerContext), (PVOID)&pServerContext); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCreateBindingHandleA( pszNetworkAddress, szRpcPort, pszUserName, pszDomain, pszPassword, &hBinding); BAIL_ON_VMDNS_ERROR(dwError); pServerContext->hBinding = hBinding; hBinding = NULL; rpc_mgmt_set_com_timeout(pServerContext->hBinding, dwTimeOut, &dwError); BAIL_ON_VMDNS_ERROR(dwError); *ppServerContext = pServerContext; pServerContext = NULL; cleanup: return dwError; error: VmDnsCloseServer(pServerContext); goto cleanup; }
DWORD VmDnsPropertyListCreate( PVMDNS_PROPERTY_LIST *ppList ) { DWORD dwError = 0; PVMDNS_PROPERTY_LIST pList = NULL; BAIL_ON_VMDNS_INVALID_POINTER(ppList, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_PROPERTY_LIST), (PVOID*)&pList); BAIL_ON_VMDNS_ERROR(dwError); pList->dwCurrentSize = 0; pList->dwMaxSize = 10; dwError = VmDnsAllocateMemory( sizeof(PVMDNS_PROPERTY_OBJECT)* pList->dwMaxSize, (PVOID*)&pList->ppProperties); BAIL_ON_VMDNS_ERROR(dwError); pList->nRefCount = 1; *ppList = pList; cleanup: return dwError; error: if (ppList) { *ppList = NULL; } VmDnsPropertyListRelease(pList); goto cleanup; }
DWORD VmDnsPropertyListAdd( PVMDNS_PROPERTY_LIST pList, PVMDNS_PROPERTY_OBJECT pProperty ) { PVMDNS_PROPERTY_OBJECT *pNewList = NULL; DWORD dwError = 0; BAIL_ON_VMDNS_INVALID_POINTER(pList, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pProperty, dwError); if (pList->dwCurrentSize >= pList->dwMaxSize) { pList->dwMaxSize = 2 * pList->dwMaxSize; dwError = VmDnsAllocateMemory( sizeof(PVMDNS_PROPERTY_OBJECT) * pList->dwMaxSize, (PVOID*)&pNewList); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyMemory( pNewList, sizeof(PVMDNS_PROPERTY_OBJECT) * pList->dwMaxSize, pList->ppProperties, sizeof(PVMDNS_PROPERTY_OBJECT) * pList->dwCurrentSize); BAIL_ON_VMDNS_ERROR(dwError); VMDNS_SAFE_FREE_MEMORY(pList->ppProperties); pList->ppProperties = pNewList; pNewList = NULL; } VmDnsPropertyObjectAddRef(pProperty); pList->ppProperties[pList->dwCurrentSize] = pProperty; ++pList->dwCurrentSize; cleanup: return dwError; error: VMDNS_SAFE_FREE_MEMORY(pNewList); goto cleanup; }
DWORD VmDnsForwarderAppend( PVMDNS_FORWARDER_CONTEXT pForwarder, PCSTR pszForwarder ) { DWORD dwError = ERROR_SUCCESS; PSTR szForwarderCopy = NULL; DWORD dwCount = pForwarder->dwCount; if (dwCount >= VMDNS_MAX_NUM_FORWARDS) { dwError = ERROR_OUT_OF_RANGE; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateStringA(pszForwarder, &szForwarderCopy); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateMemory( sizeof(VMDNS_FORWARDER_ENTRY), (void**)&pForwarder->pForwarderEntries[dwCount]); BAIL_ON_VMDNS_ERROR(dwError); pForwarder->pForwarderEntries[dwCount]->pszForwarder = szForwarderCopy; szForwarderCopy = NULL; dwError = VmDnsForwarderMetricsInit(pForwarder->pForwarderEntries[dwCount]); BAIL_ON_VMDNS_ERROR(dwError); pForwarder->dwCount++; cleanup: return dwError; error: if (dwCount < VMDNS_MAX_NUM_FORWARDS && pForwarder->pForwarderEntries[dwCount]) { VmDnsFreeForwarderEntry(pForwarder->pForwarderEntries[dwCount]); } VMDNS_SAFE_FREE_STRINGA(szForwarderCopy); goto cleanup; }
DWORD VmDnsSockPosixAllocateIoBuffer( VM_SOCK_EVENT_TYPE eventType, PVM_SOCK_EVENT_CONTEXT pEventContext, DWORD dwSize, PVM_SOCK_IO_BUFFER* ppIoBuffer ) { DWORD dwError = 0; PVM_SOCK_IO_CONTEXT pIoContext = NULL; if (!ppIoBuffer) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(VM_SOCK_IO_CONTEXT) + dwSize, (PVOID*)&pIoContext); BAIL_ON_VMDNS_ERROR(dwError); pIoContext->eventType = eventType; pIoContext->pEventContext = pEventContext; pIoContext->IoBuffer.dwExpectedSize = dwSize; pIoContext->IoBuffer.pData = (PBYTE)pIoContext->DataBuffer; *ppIoBuffer = &pIoContext->IoBuffer; cleanup: return dwError; error: if (pIoContext) { VmDnsSockPosixFreeIoBuffer(&pIoContext->IoBuffer); } goto cleanup; }
DWORD VmDnsGetForwarders_inlock( PVMDNS_FORWARDER_CONTEXT pForwarder, PSTR** pppszForwarders, PDWORD pdwCount ) { DWORD dwError = 0; PSTR* pszForwarders = NULL; DWORD dwCount = 0, i = 0; BAIL_ON_VMDNS_INVALID_POINTER(pForwarder, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pppszForwarders, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pdwCount, dwError); dwCount = pForwarder->dwCount; dwError = VmDnsAllocateMemory( (dwCount + 1) * sizeof(PSTR), (PVOID*)&pszForwarders); BAIL_ON_VMDNS_ERROR(dwError); for (; i < dwCount; ++i) { dwError = VmDnsAllocateStringA( pForwarder->pForwarderEntries[i]->pszForwarder, &pszForwarders[i]); BAIL_ON_VMDNS_ERROR(dwError); } *pdwCount = dwCount; *pppszForwarders = pszForwarders; cleanup: return dwError; error: VmDnsFreeStringArrayA(pszForwarders); goto cleanup; }
DWORD VmDnsAllocateForwarderPacketContext( PVMDNS_FORWARDER_PACKET_CONTEXT* ppForwarderContext ) { DWORD dwError = 0; PVMDNS_FORWARDER_PACKET_CONTEXT pForwarderContext = NULL; if (!ppForwarderContext) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(VMDNS_FORWARDER_PACKET_CONTEXT), (PVOID*)&pForwarderContext ); BAIL_ON_VMDNS_ERROR(dwError); pForwarderContext->dwRefCount = 1; *ppForwarderContext = pForwarderContext; cleanup: return dwError; error: if (ppForwarderContext) { *ppForwarderContext = NULL; } if (pForwarderContext) { VmDnsFreeForwarderPacketContext(pForwarderContext); } goto cleanup; }
DWORD VmDnsRecordObjectCreate( PVMDNS_RECORD pRecord, PVMDNS_RECORD_OBJECT *ppRecordObj ) { DWORD dwError = 0; PVMDNS_RECORD_OBJECT pRecordObj = NULL; if (!ppRecordObj) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(VMDNS_RECORD_OBJECT), (PVOID*)&pRecordObj); BAIL_ON_VMDNS_ERROR(dwError); pRecordObj->lRefCount = 1; pRecordObj->pRecord = pRecord; *ppRecordObj = pRecordObj; cleanup: return dwError; error: if (ppRecordObj) { *ppRecordObj = NULL; } VmDnsRecordObjectRelease(pRecordObj); goto cleanup; }
DWORD VmDnsCacheInitialize( PVMDNS_CACHE_CONTEXT *ppContext ) { DWORD dwError = 0; PVMDNS_CACHE_CONTEXT pContext = NULL; dwError = VmDnsAllocateMemory( sizeof(VMDNS_CACHE_CONTEXT), (PVOID*)&pContext); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsZoneListInit(&pContext->pZoneList); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCacheInitRefreshThread(pContext); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateRWLock(&pContext->pLock); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCreateThread( pContext->pRefreshThread, FALSE, VmDnsCacheRefreshThread, pContext); BAIL_ON_VMDNS_ERROR(dwError); *ppContext = pContext; cleanup: return dwError; error: VmDnsCacheCleanup(pContext); goto cleanup; }
static DWORD VmDnsCacheInitRefreshThread( PVMDNS_CACHE_CONTEXT pContext ) { DWORD dwError = 0; PVMDNS_THREAD pRefreshThread = NULL; PVMDNS_COND pRefreshEvent = NULL; PVMDNS_MUTEX pThreadMutex = NULL; dwError = VmDnsAllocateCondition(&pRefreshEvent); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateMutex(&pThreadMutex); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateMemory(sizeof(*pRefreshThread), (PVOID *)&pRefreshThread); BAIL_ON_VMDNS_ERROR(dwError); pContext->pRefreshEvent = pRefreshEvent; pContext->pThreadLock = pThreadMutex; pContext->pRefreshThread = pRefreshThread; cleanup: return dwError; error: VmDnsFreeMutex(pThreadMutex); VmDnsFreeCondition(pRefreshEvent); VmDnsFreeMemory(pRefreshThread); goto cleanup; }
DWORD VmDnsReadDomainNameFromBuffer( PVMDNS_MESSAGE_BUFFER pVmDnsBuffer, PSTR *ppszDomainName ) { DWORD dwError = 0; DWORD dwTotalStringLength = 0; DWORD dwLabelLength = 0; PSTR pszTempString = NULL; PSTR pszTempStringCursor = NULL; PSTR pszLabels = NULL; PSTR pszDomainName = NULL; if (!pVmDnsBuffer|| !ppszDomainName ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( 256, (PVOID *)&pszTempString ); BAIL_ON_VMDNS_ERROR(dwError); pszTempStringCursor = pszTempString; do { dwError = VmDnsReadStringFromBuffer( pVmDnsBuffer, &pszLabels, &dwLabelLength ); BAIL_ON_VMDNS_ERROR(dwError); if (dwLabelLength) { dwError = VmDnsCopyMemory( pszTempStringCursor, 255 - dwTotalStringLength, pszLabels, dwLabelLength ); BAIL_ON_VMDNS_ERROR(dwError); pszTempStringCursor[dwLabelLength]='.'; dwLabelLength++; } pszTempStringCursor = &pszTempStringCursor[dwLabelLength]; VMDNS_SAFE_FREE_STRINGA(pszLabels); dwTotalStringLength += dwLabelLength; if (dwTotalStringLength > 255) { dwError = ERROR_LABEL_TOO_LONG; BAIL_ON_VMDNS_ERROR(dwError); } }while(dwLabelLength); if (dwTotalStringLength > 0) { pszTempString[dwTotalStringLength - 1] = 0; } dwError = VmDnsAllocateStringA( pszTempString, &pszDomainName ); BAIL_ON_VMDNS_ERROR(dwError); *ppszDomainName = pszDomainName; cleanup: VMDNS_SAFE_FREE_STRINGA(pszTempString); VMDNS_SAFE_FREE_STRINGA(pszLabels); return dwError; error: if (ppszDomainName) { *ppszDomainName = NULL; } goto cleanup; }
DWORD VmDnsReadRecordFromBuffer( PVMDNS_MESSAGE_BUFFER pVmDnsBuffer, PVMDNS_RECORD *ppDnsRecord ) { DWORD dwError = 0; PVMDNS_RECORD pDnsRecord = NULL; DWORD dwIndex = 0; if (!pVmDnsBuffer || !ppDnsRecord) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(VMDNS_RECORD), (PVOID *)&pDnsRecord ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsReadDomainNameFromBuffer( pVmDnsBuffer, &pDnsRecord->pszName ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsReadUINT16FromBuffer( pVmDnsBuffer, &pDnsRecord->dwType ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsReadUINT16FromBuffer( pVmDnsBuffer, &pDnsRecord->iClass ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsReadUINT32FromBuffer( pVmDnsBuffer, &pDnsRecord->dwTtl ); BAIL_ON_VMDNS_ERROR(dwError); for (; dwIndex < gRecordMethodMapSize; ++dwIndex) { if (pDnsRecord->dwType == gRecordMethods[dwIndex].type) { dwError = gRecordMethods[dwIndex].pfnDeSerialize( pVmDnsBuffer, &pDnsRecord->Data ); BAIL_ON_VMDNS_ERROR(dwError); } } *ppDnsRecord = pDnsRecord; cleanup: return dwError; error: if (ppDnsRecord) { *ppDnsRecord = NULL; } VMDNS_FREE_RECORD(pDnsRecord); goto cleanup; }
DWORD VmDnsSerializeDnsRecord( PVMDNS_RECORD pDnsRecord, PBYTE* ppBytes, DWORD* pdwSize, BOOL bTokenizeDomainName ) { DWORD dwError = 0; PVMDNS_MESSAGE_BUFFER pVmDnsBuffer = NULL; PBYTE pBytes = NULL; DWORD dwSize = 0; if (!pDnsRecord || !ppBytes || !pdwSize ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR (dwError); } dwError = VmDnsAllocateBufferStream( 0, &pVmDnsBuffer ); BAIL_ON_VMDNS_ERROR(dwError); pVmDnsBuffer->bTokenizeDomainName = bTokenizeDomainName; dwError = VmDnsWriteRecordToBuffer( pDnsRecord, pVmDnsBuffer ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyBufferFromBufferStream( pVmDnsBuffer, NULL, &dwSize ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateMemory( dwSize, (PVOID *)&pBytes ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyBufferFromBufferStream( pVmDnsBuffer, pBytes, &dwSize ); BAIL_ON_VMDNS_ERROR(dwError); *ppBytes = pBytes; *pdwSize = dwSize; cleanup: if (pVmDnsBuffer) { VmDnsFreeBufferStream(pVmDnsBuffer); } return dwError; error: if (ppBytes) { *ppBytes = NULL; } if (pdwSize) { *pdwSize = 0; } VMDNS_SAFE_FREE_MEMORY(pBytes); goto cleanup; }
DWORD VmDnsForwardResponse( BOOL bUseUDP, PVM_SOCKET pSocket, PBYTE* ppResponse, PDWORD pdwResponseSize, PDWORD pdwRCode ) { DWORD dwError = 0; PBYTE pResponse = NULL; DWORD dwResponseCode = 0; UINT16 usExpectedSize = 0; PVM_SOCK_IO_BUFFER pIoSizeResponse = NULL; PVM_SOCK_IO_BUFFER pIoDataResponse = NULL; if (!pSocket || !ppResponse || !pdwResponseSize || !pdwRCode ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (bUseUDP) { dwError = VmDnsSockAllocateIoBuffer( VM_SOCK_EVENT_TYPE_UNKNOWN, NULL, VMDNS_UDP_PACKET_SIZE, &pIoDataResponse); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsSockRead( pSocket, pIoDataResponse); BAIL_ON_VMDNS_ERROR(dwError); } else { dwError = VmDnsSockAllocateIoBuffer( VM_SOCK_EVENT_TYPE_UNKNOWN, NULL, sizeof(UINT16), &pIoSizeResponse); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsSockRead( pSocket, pIoSizeResponse); BAIL_ON_VMDNS_ERROR(dwError); usExpectedSize = htons(*((UINT*)pIoSizeResponse->pData)); dwError = VmDnsSockAllocateIoBuffer( VM_SOCK_EVENT_TYPE_UNKNOWN, NULL, usExpectedSize, &pIoDataResponse); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsSockRead( pSocket, pIoDataResponse); BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( pIoDataResponse->dwCurrentSize, (PVOID*)&pResponse); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyMemory( pResponse, pIoDataResponse->dwCurrentSize, pIoDataResponse->pData, pIoDataResponse->dwCurrentSize); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsPeekResponseCode( pIoDataResponse->dwCurrentSize, pResponse, &dwResponseCode ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsSockEventQueueRemove( gpSrvContext->pSockContext->pEventQueue, pSocket ); dwError = 0; *ppResponse = pResponse; *pdwResponseSize = pIoDataResponse->dwCurrentSize; *pdwRCode = dwResponseCode; //VmDnsOPStatisticUpdate(FORWARDER_QUERY_COUNT); cleanup: if (pIoSizeResponse) { VMDNS_LOG_IO_RELEASE(pIoSizeResponse); VmDnsSockReleaseIoBuffer(pIoSizeResponse); } if (pIoDataResponse) { VMDNS_LOG_IO_RELEASE(pIoDataResponse); VmDnsSockReleaseIoBuffer(pIoDataResponse); } return dwError; error: if (pdwResponseSize) { *pdwResponseSize = 0; } if (ppResponse) { *ppResponse = NULL; } if (pdwRCode) { *pdwRCode = 0; } if (pResponse) { VmDnsFreeMemory(pResponse); } goto cleanup; }
DWORD VmDnsSockPosixOpenClient( PCSTR pszHost, USHORT usPort, VM_SOCK_CREATE_FLAGS dwFlags, DWORD dwTimeoutMS, PVM_SOCKET* ppSocket ) { DWORD dwError = 0; struct addrinfo hints = {0}; struct addrinfo* pAddrInfo = NULL; struct addrinfo* pInfo = NULL; int fd = -1; PVM_SOCKET pSocket = NULL; CHAR szPort[32]; struct timeval sTimeout = {0}; if (!pszHost || !usPort || !ppSocket) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_POSIX_SOCK_ERROR(dwError); } sprintf(szPort, "%d", usPort); if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6) { hints.ai_family = AF_INET6; } else if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV4) { hints.ai_family = AF_INET; } else { hints.ai_family = AF_UNSPEC; } if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP) { hints.ai_socktype = SOCK_DGRAM; } else { hints.ai_socktype = SOCK_STREAM; } hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV; /* This will use DNS */ if (getaddrinfo(pszHost, szPort, &hints, &pAddrInfo) != 0) { dwError = LwErrnoToWin32Error(errno); BAIL_ON_POSIX_SOCK_ERROR(dwError); } for (pInfo = pAddrInfo; (fd < 0) && (pInfo != NULL); pInfo = pInfo->ai_next) { fd = socket(pInfo->ai_family, pInfo->ai_socktype, pInfo->ai_protocol); if (fd < 0) { continue; } if (dwTimeoutMS) { sTimeout.tv_sec = dwTimeoutMS / 1000; sTimeout.tv_usec = (dwTimeoutMS % 1000) * 1000; if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&sTimeout, sizeof(sTimeout)) == -1) { close(fd); fd = -1; continue; } } if (connect(fd, pInfo->ai_addr, pInfo->ai_addrlen) < 0) { close(fd); fd = -1; continue; } break; } if (fd < 0) { dwError = ERROR_CONNECTION_UNAVAIL; BAIL_ON_POSIX_SOCK_ERROR(dwError); } if (dwFlags & VM_SOCK_CREATE_FLAGS_NON_BLOCK) { dwError = VmDnsSockPosixSetDescriptorNonBlocking(fd); BAIL_ON_POSIX_SOCK_ERROR(dwError); } dwError = VmDnsAllocateMemory(sizeof(*pSocket), (PVOID*)&pSocket); BAIL_ON_POSIX_SOCK_ERROR(dwError); pSocket->refCount = 1; pSocket->type = VM_SOCK_TYPE_CLIENT; if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP) { pSocket->protocol = VM_SOCK_PROTOCOL_UDP; } else { pSocket->protocol = VM_SOCK_PROTOCOL_TCP; } dwError = VmDnsAllocateMutex(&pSocket->pMutex); BAIL_ON_POSIX_SOCK_ERROR(dwError); memcpy(&pSocket->addr, pInfo->ai_addr, pInfo->ai_addrlen); pSocket->addrLen = pInfo->ai_addrlen; pSocket->fd = fd; *ppSocket = pSocket; cleanup: if (pAddrInfo) { freeaddrinfo(pAddrInfo); } return dwError; error: if (ppSocket) { *ppSocket = NULL; } if (pSocket) { VmDnsSockPosixFreeSocket(pSocket); } if (fd >= 0) { close(fd); } goto cleanup; }
static DWORD _GetForwarders( PVMDNS_SERVER_CONTEXT pServerContext, PCSTR pszZone, PVMDNS_FORWARDERS* ppForwarders ) { DWORD dwError = 0; PVMDNS_FORWARDERS pDnsForwarders = NULL; PVMDNS_FORWARDERS pDnsForwardersOutput = NULL; PSTR* ppszForwarders = NULL; DWORD dwCount = 0; dwError = VmDnsValidateContext(pServerContext); BAIL_ON_VMDNS_ERROR(dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppForwarders, dwError); DCETHREAD_TRY { if (pszZone) { dwError = VmDnsRpcGetZoneForwarders( pServerContext->hBinding, (PDNS_STRING)pszZone, &pDnsForwarders); } else { dwError = VmDnsRpcGetForwarders( pServerContext->hBinding, &pDnsForwarders); } } DCETHREAD_CATCH_ALL(THIS_CATCH) { dwError = VmDnsRpcGetErrorCode(THIS_CATCH); } DCETHREAD_ENDTRY; BAIL_ON_VMDNS_ERROR(dwError); if (pDnsForwarders) { DWORD i = 0; PSTR szTemp = NULL; if (pDnsForwarders->dwCount > 0) { dwError = VmDnsAllocateMemory( pDnsForwarders->dwCount * sizeof(PSTR), (PVOID*)&ppszForwarders); BAIL_ON_VMDNS_ERROR(dwError); for (i = 0; i < pDnsForwarders->dwCount; ++i) { dwError = VmDnsAllocateStringA( pDnsForwarders->ppszName[i], &szTemp ); BAIL_ON_VMDNS_ERROR(dwError); ppszForwarders[i] = szTemp; ++dwCount; } } dwError = VmDnsAllocateMemory( sizeof(VMDNS_FORWARDERS), (PVOID*)&pDnsForwardersOutput); BAIL_ON_VMDNS_ERROR(dwError); pDnsForwardersOutput->dwCount = pDnsForwarders->dwCount; pDnsForwardersOutput->ppszName = ppszForwarders; } *ppForwarders = pDnsForwardersOutput; cleanup: if (pDnsForwarders) { VmDnsRpcFreeForwarders(pDnsForwarders); } return dwError; error: if (ppszForwarders) { VmDnsFreeStringCountedArrayA(ppszForwarders, dwCount); } if (pDnsForwardersOutput) { VMDNS_SAFE_FREE_MEMORY(pDnsForwardersOutput); } goto cleanup; }
DWORD VmDnsSockWinAcceptConnection( PVM_SOCKET pListenSocket, SOCKET clientSocket, struct sockaddr* pClientAddr, int addrlen ) { DWORD dwError = 0; HANDLE hTemp = NULL; const char chOpt = 1; PVM_SOCKET pClientSocket = NULL; PVM_SOCK_IO_BUFFER pIoBuffer = NULL; PVM_SOCK_IO_CONTEXT pIoContext = NULL; if (!pListenSocket || !pListenSocket->hSocket || !pListenSocket->pEventQueue || !pListenSocket->pEventQueue->hIOCP || clientSocket == INVALID_SOCKET) { dwError = ERROR_INVALID_SERVER_STATE; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory( sizeof(*pClientSocket), (PVOID*)&pClientSocket); BAIL_ON_VMDNS_ERROR(dwError); pClientSocket->hSocket = clientSocket; pClientSocket->pEventQueue = pListenSocket->pEventQueue; pClientSocket->protocol = pListenSocket->protocol; pClientSocket->type = VM_SOCK_TYPE_SERVER; memcpy_s(&pClientSocket->addr, sizeof pClientSocket->addr, pClientAddr, addrlen); pClientSocket->addrLen = addrlen; pClientSocket->refCount = 1; clientSocket = INVALID_SOCKET; if (setsockopt( pClientSocket->hSocket, IPPROTO_TCP, TCP_NODELAY, &chOpt, sizeof(char))) { dwError = WSAGetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } hTemp = CreateIoCompletionPort( (HANDLE)pClientSocket->hSocket, pListenSocket->pEventQueue->hIOCP, (ULONG_PTR)pClientSocket, 0 ); if (hTemp != pListenSocket->pEventQueue->hIOCP) { dwError = GetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsSockWinAllocateIoBuffer( VM_SOCK_EVENT_TYPE_TCP_NEW_CONNECTION, 0, &pIoBuffer); BAIL_ON_VMDNS_ERROR(dwError); pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer); VMDNS_LOG_DEBUG("New Connectiom - Socket: %d Address: %p, Event: %d, Size: %d", pClientSocket->hSocket, (DWORD)pIoBuffer, pIoContext->eventType, pIoBuffer->dwCurrentSize); if (!PostQueuedCompletionStatus( pListenSocket->pEventQueue->hIOCP, 0, (ULONG_PTR)pClientSocket, (LPOVERLAPPED)pIoContext)) { dwError = GetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } pClientSocket = NULL; pIoBuffer = NULL; cleanup: return dwError; error: if (pClientSocket) { VmDnsSockWinFreeSocket(pClientSocket); } if (pIoBuffer) { VmDnsSockWinFreeIoBuffer(pIoBuffer); } goto cleanup; }
/** * @brief Opens a server socket * * @param[in] usPort 16 bit local port number that the server listens on * @param[in,optional] iListenQueueSize * size of connection acceptance queue. * This value can be (-1) to use the default value. * * @param[in] dwFlags 32 bit flags defining socket creation preferences * @param[out] ppSocket Pointer to created socket * * @return 0 on success */ DWORD VmDnsSockWinOpenServer( USHORT usPort, int iListenQueueSize, VM_SOCK_CREATE_FLAGS dwFlags, PVM_SOCKET* ppSocket ) { DWORD dwError = 0; union { #ifdef AF_INET6 struct sockaddr_in6 servaddr_ipv6; #endif struct sockaddr_in servaddr_ipv4; } servaddr; struct { int domain; int type; int protocol; } socketParams; struct sockaddr* pSockAddr = NULL; socklen_t addrLen = 0; SOCKET socket = INVALID_SOCKET; PVM_SOCKET pSocket = NULL; DWORD dwSockFlags = 0; if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6) { #ifdef AF_INET6 socketParams.domain = AF_INET6; #else dwError = ERROR_NOT_SUPPORTED; BAIL_ON_VMDNS_ERROR(dwError); #endif } else { socketParams.domain = AF_INET; } if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP) { socketParams.type = SOCK_DGRAM; } else { socketParams.type = SOCK_STREAM; } socketParams.protocol = 0; if (dwFlags & VM_SOCK_CREATE_FLAGS_NON_BLOCK) { dwSockFlags = WSA_FLAG_OVERLAPPED; } socket = WSASocketW( socketParams.domain, socketParams.type, socketParams.protocol, NULL, 0, dwSockFlags); if (socket == INVALID_SOCKET) { dwError = WSAGetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } memset(&servaddr, 0, sizeof(servaddr)); if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6) { #ifdef AF_INET6 servaddr.servaddr_ipv6.sin6_family = AF_INET6; servaddr.servaddr_ipv6.sin6_addr = in6addr_any; servaddr.servaddr_ipv6.sin6_port = htons(usPort); pSockAddr = (struct sockaddr*) &servaddr.servaddr_ipv6; addrLen = sizeof(servaddr.servaddr_ipv6); #else dwError = ERROR_NOT_SUPPORTED; BAIL_ON_VMDNS_ERROR(dwError); #endif } else { servaddr.servaddr_ipv4.sin_family = AF_INET; servaddr.servaddr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.servaddr_ipv4.sin_port = htons(usPort); pSockAddr = (struct sockaddr*) &servaddr.servaddr_ipv4; addrLen = sizeof(servaddr.servaddr_ipv4); } if (bind(socket, pSockAddr, addrLen) < 0) { dwError = WSAGetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } if (!(dwFlags & VM_SOCK_CREATE_FLAGS_UDP)) { if (iListenQueueSize <= 0) { iListenQueueSize = VM_SOCK_WINDOWS_DEFAULT_LISTEN_QUEUE_SIZE; } if (listen(socket, iListenQueueSize) < 0) { dwError = WSAGetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } } dwError = VmDnsAllocateMemory(sizeof(*pSocket), (PVOID*)&pSocket); BAIL_ON_VMDNS_ERROR(dwError); pSocket->refCount = 1; pSocket->type = VM_SOCK_TYPE_LISTENER; if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP) { pSocket->protocol = VM_SOCK_PROTOCOL_UDP; } else { pSocket->protocol = VM_SOCK_PROTOCOL_TCP; } pSocket->hSocket = socket; socket = INVALID_SOCKET; *ppSocket = pSocket; cleanup: return dwError; error: if (ppSocket) { *ppSocket = NULL; } if (pSocket) { VmDnsSockWinFreeSocket(pSocket); } if (socket != INVALID_SOCKET) { closesocket(socket); } goto cleanup; }
/** * @brief Opens a client socket * * @param[in] pszHost Target host name or IP Address. * An empty string will imply the local host. * @param[in] usPort 16 bit port number * @param[in] dwFlags 32 bit flags specifying socket creation preferences * @param[out] ppSocket Pointer to created socket context * * @return 0 on success */ DWORD VmDnsSockWinOpenClient( PCSTR pszHost, USHORT usPort, VM_SOCK_CREATE_FLAGS dwFlags, PVM_SOCKET* ppSocket ) { DWORD dwError = 0; DWORD dwSockFlags = 0; int nAddressFamily = AF_INET; int nConnectionType = SOCK_STREAM; struct addrinfo hints = { 0 }; struct addrinfo* pAddrInfo = NULL; struct addrinfo* pInfo = NULL; struct addrinfo* pClientAddress = NULL; CHAR szPort[32] = { 0 }; SOCKET socket = INVALID_SOCKET; PVM_SOCKET pSocket = NULL; if (!pszHost || !usPort || !ppSocket) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6) { hints.ai_family = AF_INET6; } else if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV4) { hints.ai_family = AF_INET; } else { hints.ai_family = AF_UNSPEC; } if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP) { nConnectionType = hints.ai_socktype = SOCK_DGRAM; } else { nConnectionType = hints.ai_socktype = SOCK_STREAM; } hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV; sprintf_s(szPort, sizeof(szPort), "%d", usPort); if (getaddrinfo(pszHost, szPort, &hints, &pAddrInfo) != 0) { dwError = WSAGetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } for (pInfo = pAddrInfo; (socket == INVALID_SOCKET && pInfo != NULL); pInfo = pInfo->ai_next) { socket = WSASocketW( pInfo->ai_family, pInfo->ai_socktype, pInfo->ai_protocol, NULL, 0, dwSockFlags); if (socket == INVALID_SOCKET) { continue; } if (nConnectionType == SOCK_STREAM) { if (connect(socket, pInfo->ai_addr, pInfo->ai_addrlen) < 0) { dwError = WSAGetLastError(); continue; } } pClientAddress = pInfo; } if (socket == INVALID_SOCKET) { dwError = ERROR_CONNECTION_UNAVAIL; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateMemory(sizeof(*pSocket), (PVOID*)&pSocket); BAIL_ON_VMDNS_ERROR(dwError); pSocket->refCount = 1; pSocket->type = VM_SOCK_TYPE_CLIENT; if (nConnectionType == SOCK_STREAM) { pSocket->protocol = VM_SOCK_PROTOCOL_TCP; } else { pSocket->protocol = VM_SOCK_PROTOCOL_UDP; } dwError = VmDnsSockWinCopyTargetAddress(pClientAddress, pSocket); BAIL_ON_VMDNS_ERROR(dwError); pSocket->hSocket = socket; socket = INVALID_SOCKET; *ppSocket = pSocket; pSocket = NULL; cleanup: if (pAddrInfo) { freeaddrinfo(pAddrInfo); } return dwError; error : if (socket != INVALID_SOCKET) { closesocket(socket); } VMDNS_SAFE_FREE_MEMORY(pSocket); goto cleanup; }