⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dualserver.cpp

📁 Combined DHCP/DNS Server. DHCP Server allots addresses and DNS Server first try resolving from DHCP
💻 CPP
📖 第 1 页 / 共 5 页
字号:

WORD scanloc(data5 *req)
{
	if (cfig.dns[0])
		req->dnsp->header.ra = 1;

	if (!req->query[0])
		return 0;

	strcpy(req->mapname, req->query);
	strcpy(req->cname, req->query);
	myLower(req->mapname);

	//printf("%s\n",req->query);

	switch (req->qtype)
	{
		case DNS_TYPE_PTR:
			{
				char *dp = strstr(req->mapname, arpa);

				if (dp)
					*dp = 0;

				req->localCode = makeLocal(htonl(my_inet_addr(req->mapname)));
			}
			break;

		case DNS_TYPE_A:
			req->localCode = makeLocal(req->mapname);
			if (req->localCode == 1)
			{
				sprintf(req->cname, "%s.%s", req->mapname, cfig.zone);
			}
			else if (req->localCode == 3)
			{
				req->localCode = 1;
				sprintf(req->mapname, "www");
				sprintf(req->cname, "www.%s", cfig.zone);
			}
			break;

		case DNS_TYPE_MX:
			req->localCode = makeLocal(req->mapname);
			if (req->localCode == 0 || req->localCode == 2)
			{
				return 0;
			}
			else if (req->localCode == 1)
			{
				req->dnsp->header.rcode = RCODE_NAMEERROR;
				return 1;
			}
			break;

		case DNS_TYPE_NS:
			if (!strcasecmp(req->query, cfig.authority))
			{
				if (cfig.authorized)
				{
					addRRNSPtr(req);
					return 1;
				}
				else
				{
					req->dnsp->header.rcode = RCODE_NOTAUTH;
					return 1;
				}
			}
			else
			{
				req->localCode = makeLocal(req->mapname);
				if (req->localCode == 3)
				{
					if (cfig.authorized)
					{
						addRRNSA(req);
						return 1;
					}
					else
					{
						req->dnsp->header.rcode = RCODE_NOTAUTH;
						return 1;
					}
				}
			}
			return 0;

		case DNS_TYPE_SOA:

			req->localCode = makeLocal(req->mapname);
			if (req->localCode == 3)
			{
				if (cfig.authorized)
				{
					addRRSOA(req);
					return 1;
				}
				else
				{
					req->dnsp->header.rcode = RCODE_NOTAUTH;
					return 1;
				}
			}
			return 0;

		default:
			req->localCode = makeLocal(req->mapname);
			if (req->localCode)
			{
				req->dnsp->header.rcode = RCODE_NOTIMPL;
				return 1;
			}
			else
				return 0;
	}

	for (int m = 0; m < 3; m++)
	{
		//printf("%s has %u Entries\n", req->mapname, dnsCache[cacheInd].count(req->mapname));
		req->iterBegin = dnsCache[cacheInd].find(req->mapname);
		if (req->iterBegin != dnsCache[cacheInd].end() && req->iterBegin->second->expiry > time(NULL))
		{
			memcpy(&req->cache, req->iterBegin->second, sizeof(data7));
			//printf("mapname=%s, datatype=%i exp=%u\n",req->cache.mapname, req->cache.dataType,req->cache.expiry);

			switch (req->cache.dataType)
			{
				case LOCAL_A:
				case STATIC_A_AUTH:
					addRRA(req);
					addAuth(req);
					return 1;

				case LOCAL_PTR:
				case STATIC_PTR_AUTH:
				case SERVER_PTR_AUTH:
					addRRPtr(req);
					addAuth(req);
					return 1;

				case LOCALHOST_A:
					addRRLocalhostA(req);
					addAuth(req);
					return 1;

				case LOCALHOST_PTR:
					addRRLocalhostPtr(req);
					addAuth(req);
					return 1;

				case STATIC_A_NAUTH:
					addRRA(req);
					return 1;

				case SERVER_PTR_NAUTH:
				case STATIC_PTR_NAUTH:
					addRRPtr(req);
					return 1;

				case SERVER_A_AUTH:
					addRRServerA(req);
					addAuth(req);
					return 1;

				case SERVER_A_NAUTH:
					addRRServerA(req);
					return 1;

				case MX:
					addRRMX(req);
					return 1;

				case CACHED:
					addRRExt(req);
					return 1;

				case LOCAL_CNAME:
					sprintf(req->cname, "%s.%s", req->cache.hostname, cfig.zone);
					strcpy(req->mapname, req->cache.hostname);
					myLower(req->mapname);
					continue;

				case EXT_CNAME:
					strcpy(req->cname, req->cache.hostname);
					strcpy(req->mapname, req->cache.hostname);
					myLower(req->mapname);
					continue;

				default:
					break;
			}
		}

		break;
	}

	if (req->cache.dataType == LOCAL_CNAME)
	{
		addRRA(req);
		addAuth(req);
		return 1;
	}
	else if (req->cache.dataType == EXT_CNAME)
	{
		req->data = &req->dnsp->data;
		req->data += pQu(req->data, req->mapname);
		req->data += pShort(req->data, DNS_TYPE_A);
		req->data += pShort(req->data, DNS_CLASS_IN);
		req->bytes = (DWORD)req->data - (DWORD)req->raw;
	}
	else if (req->localCode == 1 || req->localCode == 3 || !req->dnsp->header.rd)
	{
		req->dnsp->header.rcode = RCODE_NAMEERROR;
		return 1;
	}

	return 0;
}

WORD fdnmess(data5 *req)
{
	bool tryDefault = true;
	BYTE zoneDNS;
	int nRet = -1;
	WORD qLen = strlen(req->query);

	for (zoneDNS = 0; zoneDNS < 32 && cfig.dnsRoutes[zoneDNS].dnLen; zoneDNS++)
	{
		if (qLen >= cfig.dnsRoutes[zoneDNS].dnLen)
		{
			char *dp = req->query + (qLen - cfig.dnsRoutes[zoneDNS].dnLen);
			//printf("%s=%s\n",dp,cfig.dnsRoutes[zoneDNS].zone);
			if (!strcasecmp(dp, cfig.dnsRoutes[zoneDNS].zone))
			{
				tryDefault = false;
				cfig.forwConn.addr.sin_family = AF_INET;
				cfig.forwConn.addr.sin_addr.s_addr = cfig.dnsRoutes[zoneDNS].dns;
				cfig.forwConn.addr.sin_port = htons(IPPORT_DNS);
				errno = 0;

				nRet = sendto(cfig.forwConn.sock,
				              req->raw,
				              req->bytes,
				              0,
				              (sockaddr*) & cfig.forwConn.addr,
				              sizeof(cfig.forwConn.addr));

				errno = WSAGetLastError();

				if (errno)
				{
					if (cfig.logLevel)
					{
						sprintf(logBuff, "Error %i Routing DNS Message to DNS %s", errno, IP2String(tempbuff, cfig.dnsRoutes[zoneDNS].dns));
						logMess(logBuff, 1);
					}
					return 0;
				}
				else if (nRet <= 0)
				{
					if (cfig.logLevel)
					{
						sprintf(logBuff, "Error Routing DNS Message to DNS %s", IP2String(tempbuff, cfig.dnsRoutes[zoneDNS].dns));
						logMess(logBuff, 1);
					}
					return 0;
				}
				else
				{
					if (cfig.logLevel == 2)
					{
						sprintf(logBuff, "%s Routed to DNS %s", req->cname, IP2String(tempbuff, cfig.dnsRoutes[zoneDNS].dns));
						logMess(logBuff, 2);
					}
				}
				break;
			}
		}
	}

	if (nRet <= 0 && req->localCode == 2)
	{
		req->dnsp->header.rcode = RCODE_NAMEERROR;
		return 1;
	}

	if (tryDefault)
	{
		if (!cfig.dns[0])
		{
			req->dnsp->header.rcode = RCODE_NAMEERROR;
			return 1;
		}

		//printf("Queries Awaited = %i currentDNS=%i\n", cfig.queriesFailed, cfig.currentDNS);
		if (cfig.queriesFailed >= 5)
		{
			cfig.queriesFailed = 0;

			if (cfig.dns[1])
			{
				cfig.currentDNS++;
				if (cfig.currentDNS >= MAX_SERVERS || !cfig.dns[cfig.currentDNS])
					cfig.currentDNS = 0;

				if (cfig.logLevel)
				{
					sprintf(logBuff, "Switching the Forwading DNS Server to %s", IP2String(tempbuff, cfig.dns[cfig.currentDNS]));
					logMess(logBuff, 1);
				}
			}
		}

		for (int i = 0; i < MAX_SERVERS && cfig.dns[i]; i++)
		{
			if (req->addr.sin_addr.s_addr != cfig.dns[cfig.currentDNS])
			{
				cfig.forwConn.addr.sin_family = AF_INET;
				cfig.forwConn.addr.sin_addr.s_addr = cfig.dns[cfig.currentDNS];
				cfig.forwConn.addr.sin_port = htons(IPPORT_DNS);
				errno = 0;

				nRet = sendto(cfig.forwConn.sock,
				              req->raw,
				              req->bytes,
				              0,
				              (sockaddr*) & cfig.forwConn.addr,
				              sizeof(cfig.forwConn.addr));

				errno = WSAGetLastError();

				if (errno)
				{
					if (cfig.logLevel)
					{
						sprintf(logBuff, "Error %i Forwading DNS Message to %s", errno, IP2String(tempbuff, cfig.dns[cfig.currentDNS]));
						logMess(logBuff, 1);
					}

					cfig.currentDNS++;
					if (cfig.currentDNS >= MAX_SERVERS || !cfig.dns[cfig.currentDNS])
						cfig.currentDNS = 0;

				}
				else if (nRet <= 0)
				{
					if (cfig.logLevel)
					{
						sprintf(logBuff, "Error Forwading DNS Message to %s", IP2String(tempbuff, cfig.dns[cfig.currentDNS]));
						logMess(logBuff, 1);
					}

					cfig.currentDNS++;
					if (cfig.currentDNS >= MAX_SERVERS || !cfig.dns[cfig.currentDNS])
						cfig.currentDNS = 0;
				}
				else
				{
					if (cfig.logLevel == 2)
					{
						sprintf(logBuff, "%s Forwarded to DNS %s", req->cname, IP2String(tempbuff, cfig.dns[cfig.currentDNS]));
						logMess(logBuff, 2);
					}
					break;
				}
			}
		}
	}

	if (nRet <= 0)
	{
		req->dnsp->header.rcode = RCODE_NAMEERROR;
		return 1;
	}

	char mapname[8];
	sprintf(mapname, "%u", req->dnsp->header.xid);
	data7 *queue = findEntry(cacheInd, mapname, QUEUE);

	if (!queue)
	{
		//checkSize();
		queue = (data7*)calloc(1, sizeof(data7));
		if (queue)
		{
			queue->mapname = cloneString(mapname);
			queue->source = (SOCKADDR_IN*)calloc(1, sizeof(SOCKADDR_IN));
			queue->query = cloneString(req->query);

			if (!queue->mapname || !queue->source || !queue->query)
			{
				if (queue->mapname)
					free(queue->mapname);

				if (queue->source)
					free(queue->source);

				if (queue->query)
					free(queue->query);

				free(queue);
				sprintf(logBuff, "Memory Allocation Error");
				logMess(logBuff, 1);
				return 0;
			}

			memcpy(queue->source, &req->addr, sizeof(SOCKADDR_IN));
			queue->expiry = 5 + time(NULL);
			queue->dataType = QUEUE;
			addEntry(cacheInd, queue);
		}
		else
		{
			sprintf(logBuff, "Memory Allocation Error");
			logMess(logBuff, 1);
			return 0;
		}
	}
	else
	{
		queue->expiry = 5 + time(NULL);
		memcpy(queue->source, &req->addr, sizeof(SOCKADDR_IN));

		if (strcasecmp(queue->query, req->query))
		{
			char *query = cloneString(req->query);

			if (query)
			{
				free(queue->query);
				queue->query = query;
			}
			else
			{
				sprintf(logBuff, "Memory Allocation Error");
				logMess(logBuff, 1);
				return 0;
			}
		}
	}

	queue->sockInd = req->sockInd;

	if (tryDefault)
	{
		queue->dnsIndex = cfig.currentDNS;
	}
	else
	{
		queue->dnsIndex = UCHAR_MAX;
	}

	return (nRet);
}

WORD frdnmess(data5 *req)
{
	socklen_t nRet = sizeof(cfig.forwConn.addr);
	errno = 0;

	req->bytes = recvfrom(cfig.forwConn.sock,
	                      req->raw,
	                      sizeof(req->raw),
	                      0,
	                      (sockaddr*) & cfig.forwConn.addr,
	                      &nRet);

	errno = WSAGetLastError();

	if (errno || req->bytes <= 0)
	{
		if (cfig.logLevel)
		{
			sprintf(logBuff, "Error %i Receiving Reply from Forwarding Server", errno);
			logMess(logBuff, 1);
		}
		return 0;
	}

	req->dnsp = (dnsPacket*)req->raw;

	char mapname[8];
	WORD type = 0;
	sprintf(mapname, "%u", req->dnsp->header.xid);
	data7 *queue = findEntry(cacheInd, mapname, QUEUE);

	if (queue && queue->expiry > time(NULL))
	{
		if (queue->dnsIndex == cfig.currentDNS)
			cfig.queriesFailed = 0;

		que

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -