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 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; }
static DWORD VmDnsCliCreatePrimaryZone( PVM_DNS_CLI_CONTEXT pContext ) { DWORD dwError = 0; PSTR pszMboxDomain = NULL; VMDNS_ZONE_INFO zoneInfo = { 0 }; VMDNS_RECORD nsRecord = {0}; VMDNS_RECORD addrRecord = {0}; PSTR pszTargetFQDN = NULL; int ret = 0; int af = AF_INET; unsigned char buf[sizeof(struct in6_addr)]; if (IsNullOrEmptyString(pContext->pszZone)) { fprintf(stderr, "Error: DNS Zone is not specified\n"); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (IsNullOrEmptyString(pContext->pszNSHost) || VmDnsCheckIfIPV4AddressA(pContext->pszNSHost) || VmDnsCheckIfIPV6AddressA(pContext->pszNSHost)) { fprintf(stderr, "Error: Primary Nameserver host is not specified or the format is invalid\n"); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (pContext->dwZoneType == VMDNS_ZONE_TYPE_FORWARD && IsNullOrEmptyString(pContext->pszNSIp)) { fprintf(stderr, "Error: Primary Nameserver IP Address is not specified\n"); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (IsNullOrEmptyString(pContext->pszMboxDomain)) { dwError = VmDnsAllocateStringA("hostmaster", &pszMboxDomain); BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsMakeFQDN(pContext->pszNSHost, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); zoneInfo.pszName = pContext->pszZone; zoneInfo.pszPrimaryDnsSrvName = pszTargetFQDN; zoneInfo.pszRName = pszMboxDomain ? pszMboxDomain : pContext->pszMboxDomain; zoneInfo.serial = 1; zoneInfo.refreshInterval = VMDNS_DEFAULT_REFRESH_INTERVAL; zoneInfo.retryInterval = VMDNS_DEFAULT_RETRY_INTERVAL; zoneInfo.expire = VMDNS_DEFAULT_EXPIRE; zoneInfo.minimum = VMDNS_DEFAULT_TTL; zoneInfo.dwFlags = 0; zoneInfo.dwZoneType = pContext->dwZoneType; dwError = VmDnsCreateZoneA(pContext->pServerContext, &zoneInfo); BAIL_ON_VMDNS_ERROR(dwError); if (!IsNullOrEmptyString(pContext->pszNSHost)) { nsRecord.pszName = pContext->pszZone; nsRecord.Data.NS.pNameHost = pszTargetFQDN; nsRecord.iClass = VMDNS_CLASS_IN; nsRecord.pszName = pContext->pszZone; nsRecord.dwType = VMDNS_RR_TYPE_NS; nsRecord.dwTtl = pContext->record.dwTtl; dwError = VmDnsAddRecordA( pContext->pServerContext, pContext->pszZone, &nsRecord); BAIL_ON_VMDNS_ERROR(dwError); } if (!IsNullOrEmptyString(pContext->pszNSHost) && !IsNullOrEmptyString(pContext->pszNSIp) && pContext->dwZoneType == VMDNS_ZONE_TYPE_FORWARD) { addrRecord.iClass = VMDNS_CLASS_IN; addrRecord.pszName = pszTargetFQDN; addrRecord.dwType = VMDNS_RR_TYPE_A; addrRecord.dwTtl = pContext->record.dwTtl; if (VmDnsStringChrA(pContext->pszNSIp, ':')) { af = AF_INET6; } ret = inet_pton(af, pContext->pszNSIp, buf); if (ret <= 0) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (af == AF_INET) { addrRecord.Data.A.IpAddress = (VMDNS_IP4_ADDRESS)ntohl(((struct in_addr *)buf)->s_addr); } else if (af == AF_INET6) { addrRecord.dwType = VMDNS_RR_TYPE_AAAA; dwError = VmDnsCopyMemory( addrRecord.Data.AAAA.Ip6Address.IP6Byte, sizeof(addrRecord.Data.AAAA.Ip6Address.IP6Byte), #ifdef _WIN32 ((struct in6_addr*)buf)->u.Byte, #else ((struct in6_addr*)buf)->s6_addr, #endif sizeof(addrRecord.Data.AAAA.Ip6Address.IP6Byte)); BAIL_ON_VMDNS_ERROR(dwError); } else { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAddRecordA( pContext->pServerContext, pContext->pszZone, &addrRecord); BAIL_ON_VMDNS_ERROR(dwError); } if (!IsNullOrEmptyString(pContext->pszNSHost) && !IsNullOrEmptyString(pContext->pszNSIp) && pContext->dwZoneType == VMDNS_ZONE_TYPE_REVERSE) { addrRecord.iClass = VMDNS_CLASS_IN; addrRecord.dwType = VMDNS_RR_TYPE_PTR; addrRecord.dwTtl = VMDNS_DEFAULT_TTL; addrRecord.Data.PTR.pNameHost = pszTargetFQDN; dwError = VmDnsGeneratePtrNameFromIp(pContext->pszNSIp,&addrRecord.pszName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAddRecordA( pContext->pServerContext, pContext->pszZone, &addrRecord ); BAIL_ON_VMDNS_ERROR(dwError); } cleanup: if (pszMboxDomain) { VmDnsFreeStringA(pszMboxDomain); } return dwError; error: 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 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; }