示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
VOID
VmDnsFreeMutex(
    PVMDNS_MUTEX pMutex
)
{
    VmDnsFreeMutexContent(pMutex);
    VMDNS_SAFE_FREE_MEMORY( pMutex );
}
示例#4
0
VOID
VmDnsPropertyListFree(
    PVMDNS_PROPERTY_LIST pList
    )
{
    DWORD i = 0;

    if (pList)
    {
        for (i = 0; i < pList->dwCurrentSize; ++i)
        {
            VmDnsPropertyObjectRelease(pList->ppProperties[i]);
        }
        VMDNS_SAFE_FREE_MEMORY(pList->ppProperties);
        VMDNS_SAFE_FREE_MEMORY(pList);
    }
}
示例#5
0
VOID
VmDnsFreeCondition(
    PVMDNS_COND pCondition
)
{
    VmDnsFreeConditionContent( pCondition );
    VMDNS_SAFE_FREE_MEMORY( pCondition );
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
VOID
VmDnsSockWinFreeIoBuffer(
    PVM_SOCK_IO_BUFFER     pIoBuffer
    )
{
    PVM_SOCK_IO_CONTEXT pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer);
    VMDNS_LOG_INFO("Freeing Io Buffer - Address: %p, Event: %d, Size: %d", (DWORD)pIoBuffer, pIoContext->eventType, pIoBuffer->dwCurrentSize);
    VMDNS_SAFE_FREE_MEMORY(pIoContext);
}
示例#9
0
static
PVOID
ThreadFunction(
  PVOID pArgs
)
{
    DWORD dwError = ERROR_SUCCESS;
    PVMDNS_START_ROUTINE pThreadStart = NULL;
    PVOID pThreadArgs = NULL;
    union
    {
        DWORD dwError;
        PVOID pvRet;
    } retVal = { 0 };

    if( pArgs == NULL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    pThreadStart = ((PVMDNS_THREAD_START_INFO)pArgs)->pStartRoutine;
    pThreadArgs = ((PVMDNS_THREAD_START_INFO)pArgs)->pArgs;

    if( pThreadStart == NULL )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    VMDNS_SAFE_FREE_MEMORY( pArgs );

    dwError = pThreadStart( pThreadArgs );
    BAIL_ON_VMDNS_ERROR(dwError);

error:

    VMDNS_SAFE_FREE_MEMORY( pArgs );

    retVal.dwError = dwError;
    return retVal.pvRet;
}
示例#10
0
static
VOID
VmDnsFreeForwarderPacketContext(
    PVMDNS_FORWARDER_PACKET_CONTEXT pForwarderContext
    )
{
    if (pForwarderContext)
    {
        VMDNS_SAFE_FREE_MEMORY(pForwarderContext);
    }
}
示例#11
0
VOID
VmDnsClearPtrRecord(
    PVMDNS_RECORD   pRecord
    )
{
    if (pRecord)
    {
        VMDNS_SAFE_FREE_STRINGA(pRecord->pszName);
        VMDNS_SAFE_FREE_MEMORY(pRecord->Data.PTR.pNameHost);
    }
}
示例#12
0
static
VOID
VmDnsFreeForwarderEntry(
    PVMDNS_FORWARDER_ENTRY pForwarderEntry
    )
{
    if (pForwarderEntry)
    {
        (void) VmDnsForwarderMetricsDelete(pForwarderEntry);
        VMDNS_SAFE_FREE_STRINGA(pForwarderEntry->pszForwarder);
        VMDNS_SAFE_FREE_MEMORY(pForwarderEntry);
    }
}
示例#13
0
VOID
VmDnsSockPosixFreeIoBuffer(
    PVM_SOCK_IO_BUFFER     pIoBuffer
    )
{
//    VMDNS_LOG_DEBUG("pIoBuffer:%p released from thread %p", pIoBuffer, pthread_self());
    if (pIoBuffer && pIoBuffer->pClientSocket)
    {
        VmDnsSockPosixReleaseSocket(pIoBuffer->pClientSocket);
    }
    PVM_SOCK_IO_CONTEXT pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer);
    VMDNS_SAFE_FREE_MEMORY(pIoContext);
}
示例#14
0
VOID
VmDnsRecordObjectRelease(
    PVMDNS_RECORD_OBJECT    pRecordObj
    )
{
    if (pRecordObj)
    {
        if (0 == InterlockedDecrement(&pRecordObj->lRefCount))
        {
            VMDNS_FREE_RECORD(pRecordObj->pRecord);
            VMDNS_SAFE_FREE_MEMORY(pRecordObj);
        }
    }
}
示例#15
0
static VOID
VmDnsSockWinFreeSocket(
    PVM_SOCKET  pSocket
    )
{
    if (pSocket->hSocket != INVALID_SOCKET)
    {
        CancelIo((HANDLE)pSocket->hSocket);
        closesocket(pSocket->hSocket);
        pSocket->hSocket = INVALID_SOCKET;
    }

    VMDNS_SAFE_FREE_MEMORY(pSocket);
}
示例#16
0
static
VOID
VmDnsFreeMemberShips(
    PSTR* ppszMemberships,
    DWORD dwMemberships
    )
{
    DWORD i = 0;
    for(i = 0; i < dwMemberships; ++i)
    {
        VMDNS_SAFE_FREE_STRINGA(ppszMemberships[i]);
    }

    VMDNS_SAFE_FREE_MEMORY(ppszMemberships);
}
示例#17
0
文件: client.c 项目: vmware/lightwave
VMDNS_API
VOID
VmDnsCloseServer(PVMDNS_SERVER_CONTEXT pServerContext)
{
	if(pServerContext)
	{
		if (pServerContext->hBinding)
		{
			DWORD dwError = 0;
			rpc_binding_free(&pServerContext->hBinding, &dwError);
			pServerContext->hBinding = NULL;
		}

		VMDNS_SAFE_FREE_MEMORY(pServerContext);
	}
}
示例#18
0
static
DWORD
VmDnsPeekResponseCode(
    DWORD dwResponseSize,
    PBYTE pResponseBytes,
    PDWORD pdwResponseCode
    )
{
    DWORD dwError = ERROR_SUCCESS;
    PVMDNS_HEADER pDnsHeader = NULL;
    PVMDNS_MESSAGE_BUFFER pDnsMessageBuffer = NULL;

    if (!pdwResponseCode)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDNS_ERROR(dwError);
    }
    dwError = VmDnsGetDnsMessageBuffer(
                        pResponseBytes,
                        dwResponseSize,
                        &pDnsMessageBuffer
                        );
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsReadDnsHeaderFromBuffer(
                        pDnsMessageBuffer,
                        &pDnsHeader
                        );
    BAIL_ON_VMDNS_ERROR(dwError);

    *pdwResponseCode =  pDnsHeader->codes.RCODE;

cleanup:

    if (pDnsMessageBuffer)
    {
       VmDnsFreeBufferStream(pDnsMessageBuffer);
    }
    VMDNS_SAFE_FREE_MEMORY(pDnsHeader);

    return dwError;

error :

    goto cleanup;

}
示例#19
0
文件: socket.c 项目: vmware/lightwave
VOID
VmDnsSockPosixFreeIoBuffer(
    PVM_SOCK_IO_BUFFER     pIoBuffer
    )
{
    PVM_SOCK_IO_CONTEXT pIoContext = NULL;

    if (pIoBuffer)
    {
        if (pIoBuffer->pClientSocket)
        {
            VmDnsSockPosixReleaseSocket(pIoBuffer->pClientSocket);
        }
        pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer);
        VMDNS_SAFE_FREE_MEMORY(pIoContext);
    }
}
示例#20
0
VOID
VmDnsForwarderCleanup(
    PVMDNS_FORWARDER_CONTEXT    pForwarder
    )
{
    DWORD i = 0;

    if (pForwarder)
    {
        for (i = 0; i < pForwarder->dwCount; ++i)
        {
            if (pForwarder->pForwarderEntries[i])
            {
                VmDnsFreeForwarderEntry(pForwarder->pForwarderEntries[i]);
            }
        }
        VMDNS_FREE_RWLOCK(pForwarder->pLock);
        VMDNS_SAFE_FREE_MEMORY(pForwarder);
    }
}
示例#21
0
VOID
VmDnsSockWinCloseEventQueue(
    PVM_SOCK_EVENT_QUEUE pQueue
    )
{
    if (pQueue)
    {
        if (pQueue->hEventListen != WSA_INVALID_EVENT)
        {
            WSACloseEvent(pQueue->hEventListen);
        }

        if (pQueue->hIOCP)
        {
            CloseHandle(pQueue->hIOCP);
        }

        VMDNS_SAFE_FREE_MEMORY(pQueue);
    }
}
示例#22
0
DWORD
VmDnsForwardRequest(
    PVMDNS_FORWARDER_PACKET_CONTEXT      pForwarderPacketContext,
    BOOL                                 bUseUDP,
    PVM_SOCK_IO_BUFFER                   pIoBuffer
    )
{
    DWORD dwError = 0;
    PSTR  pszForwarder = NULL;
    VM_SOCK_CREATE_FLAGS flags = (bUseUDP) ? VM_SOCK_CREATE_FLAGS_UDP : VM_SOCK_CREATE_FLAGS_TCP;
    PVM_SOCKET pSocket = NULL;

    DWORD dwQuerySize = 0;
    PBYTE pQueryBuffer = NULL;
    struct sockaddr_storage address;
    socklen_t addLenth = sizeof address;
    PVM_SOCK_IO_BUFFER pIoRequest = NULL;
    PVM_SOCK_IO_BUFFER pOldRequest = NULL;
    PVMDNS_FORWARDER_PACKET_CONTEXT pCurrentContext = NULL;

    if (!pIoBuffer || (bUseUDP && (pIoBuffer->dwTotalBytesTransferred > VMDNS_UDP_PACKET_SIZE))||
        !pIoBuffer->pData ||
        !pForwarderPacketContext)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    dwQuerySize = pIoBuffer->dwTotalBytesTransferred;
    pQueryBuffer = pIoBuffer->pData;

    pCurrentContext = VmDnsAcquireForwarderPacketContext(pForwarderPacketContext);

    dwError = VmDnsGetForwarderAtIndex(
                                gpSrvContext->pForwarderContext,
                                pCurrentContext->dwCurrentIndex++,
                                &pszForwarder
                                );
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsSockOpenClient(
                    pszForwarder,
                    VMW_DNS_PORT,
                    flags,
                    &pSocket);
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsSockSetNonBlocking(pSocket);
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsSockGetAddress(
                    pSocket,
                    &address,
                    &addLenth);
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsSockAllocateIoBuffer(
                    bUseUDP?
                    VM_SOCK_EVENT_TYPE_UDP_FWD_RESPONSE_DATA_READ:
                    VM_SOCK_EVENT_TYPE_TCP_FWD_RESPONSE_DATA_READ,
                    (PVM_SOCK_EVENT_CONTEXT)pCurrentContext,
                    dwQuerySize,
                    &pIoRequest);
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsCopyMemory(
                    pIoRequest->pData,
                    pIoRequest->dwExpectedSize,
                    pQueryBuffer,
                    dwQuerySize);
    BAIL_ON_VMDNS_ERROR(dwError);

    memcpy(
        &pIoRequest->clientAddr,
        &pIoBuffer->clientAddr,
        pIoBuffer->addrLen);

    pIoRequest->addrLen = pIoBuffer->addrLen;
    pIoRequest->pClientSocket = VmDnsSockAcquire(pIoBuffer->pClientSocket);

    dwError = VmDnsSockSetData(
                            pSocket,
                            pIoRequest,
                            (PVOID*)&pOldRequest
                            );
    BAIL_ON_VMDNS_ERROR(dwError);

    (VOID)VmDnsLogDnsMessage(VMDNS_LOG_LEVEL_INFO, "DNS FWD REQ: ", pQueryBuffer, dwQuerySize);

    dwError = VmDnsSockWrite(
                    pSocket,
                    NULL,
                    0,
                    pIoRequest);
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsSockEventQueueAdd(
                                gpSrvContext->pSockContext->pEventQueue,
                                TRUE,
                                pSocket
                                );
    BAIL_ON_VMDNS_ERROR(dwError);

//    VmDnsOPStatisticUpdate(FORWARDER_QUERY_COUNT);

cleanup:

    VMDNS_SAFE_FREE_MEMORY(pszForwarder);

    if (pOldRequest)
    {
        VMDNS_LOG_IO_RELEASE(pOldRequest);
        VmDnsSockReleaseIoBuffer(pOldRequest);
    }
    if (pSocket)
    {
        VmDnsSockRelease(pSocket);
    }

    return dwError;

error:

    if (pCurrentContext)
    {
        VmDnsReleaseForwarderPacketContext(pCurrentContext);
    }
    if (pIoRequest)
    {
        VMDNS_LOG_IO_RELEASE(pIoRequest);
        VmDnsSockReleaseIoBuffer(pIoRequest);
    }
    goto cleanup;
}
示例#23
0
文件: client.c 项目: vmware/lightwave
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;
}
示例#24
0
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;
}
示例#25
0
/**
 * @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;
}