Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
/**
 * @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;
}
Example #8
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
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;
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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;
}
Example #18
0
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;
}
Example #19
0
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;
}
Example #20
0
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;
}
Example #21
0
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;
}
Example #22
0
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;
}
Example #23
0
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;
}
Example #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;
}
Example #25
0
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;
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
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;
}
Example #29
0
/**
 * @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;
}
Example #30
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;
}