资源简介
设计一个DNS服务器程序,读入“域名-IP地址”对照表,当客户端查询域名对应的IP地址时,用域名检索该对照表,三种检索结果:
检索结果为ip地址0.0.0.0,则向客户端返回“域名不存在”的报错消息(不良网站拦截功能)
检索结果为普通IP地址,则向客户返回这个地址(服务器功能)
表中未检到该域名,则向因特网DNS服务器发出查询,并将结果返给客户端(中继功能)
考虑多个计算机上的客户端会同时查询,需要进行消息ID的转换
代码片段和文件信息
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#pragma comment(lib “Ws2_32.lib“)
#define DEF_DNS_ADDRESS “192.168.146.2“ //外部DNS服务器地址
#define LOCAL_ADDRESS “127.0.0.1“ //本地DNS服务器地址
#define DNS_PORT 53 //进行DNS服务的53端口
#define BUF_SIZE 512
#define LENGTH 65
#define AMOUNT 300
#define NOTFOUND -1
//DNS报文首部
typedef struct DNSHeader
{
unsigned short ID;
unsigned short Flags;
unsigned short QuestNum;
unsigned short AnswerNum;
unsigned short AuthorNum;
unsigned short AdditionNum;
} DNSHDR *pDNSHDR;
//DNS域名解析表结构
typedef struct translate
{
string IP; //IP地址
string domain; //域名
} Translate;
//ID转换表结构
typedef struct IDChange
{
unsigned short oldID; //原有ID
BOOL done; //标记是否完成解析
SOCKADDR_IN client; //请求者套接字地址
} IDTransform;
Translate DNS_table[AMOUNT]; //DNS域名解析表
IDTransform IDTransTable[AMOUNT]; //ID转换表
int IDcount = 0; //转换表中的条目个数
char url[LENGTH]; //域名
SYSTEMTIME sys; //系统时间
int Day Hour Minute Second Milliseconds;//保存系统时间的变量
//函数:获取域名解析表
int GetTable(char *tablePath)
{
int i=0 j pos=0;
string table[AMOUNT];
ifstream infile(tablePath ios::in); //以读入方式打开文本文件
if(! infile) {
cerr << “Open“ << tablePath << “error!“ < exit(1);
}
//每次从文件中读入一行,直至读到文件结束符为止
while (getline(infile table[i]) && i < AMOUNT)
i++;
if (i == AMOUNT-1)
cout << “The DNS table memory is full. “ << endl;
for (j = 0; j < i-1; j++) {
pos = table[j].find(‘ ‘);
if (pos > table[j].size())
cout << “The record is not in a correct format. “ << endl;
else {
DNS_table[j].IP = table[j].substr(0 pos);
DNS_table[j].domain = table[j].substr(pos+1);
}
}
infile.close(); //关闭文件
cout << “Load records succeed. “ << endl;
return i-1; //返回域名解析表中条目个数
}
//函数:获取DNS请求中的域名
void GetUrl(char *recvbuf int recvnum)
{
char urlname[LENGTH];
int i = 0 j k = 0;
memset(url 0 LENGTH);
memcpy(urlname &(recvbuf[sizeof(DNSHDR)]) recvnum-16); //获取请求报文中的域名表示
int len = strlen(urlname);
//域名转换
while (i < len) {
if (urlname[i] > 0 && urlname[i] <= 63)
for (j = urlname[i] i++; j > 0; j-- i++ k++)
url[k] = urlname[i];
if (urlname[i] != 0) {
url[k] = ‘.‘;
k++;
}
}
url[k] = ‘\0‘;
}
//函数:判断是否在表中找到DNS请求中的域名,找到返回下标
int IsFind(char* url int num)
{
int find = NOTFOUND;
char* domain;
for (int i = 0; i < num; i++) {
domain = (char *)DNS_table[i].domain.c_str();
if (strcmp(domain url) == 0) { //找到
find = i;
break;
}
}
return find;
}
//函数:将请求ID转换为新的ID,并将信息写入ID转换表中
unsigned short RegisterNewID (unsigned short oID SOCKADDR_IN temp BOOL ifdone)
{
srand(time(NULL));
IDTransTable[IDcount].oldID = oID;
IDTransTable[IDcount].client = temp;
- 上一篇:北京邮电大学大三下计算机图形学作业一
- 下一篇:操作系统实习-快速文件系统
评论
共有 条评论