- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C++如何实现DNS域名解析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1、概述 。
现在来搞定DNS域名解析,其实这是前面一篇文章C++实现Ping里面的遗留问题,要干的活是ping的过程中画红线的部分:
cmd下域名解析的命令是nslookup,比如“nslookup www.baidu.com”的结果如下:
其中,Address返回的就是www.baidu.com对应的IP地址,这个可能有多个 。
Alias指别名,也就是说www.baidu.com是www.a.shifen.com的别名,而www.a.shifen.com则是www.baidu.com的规范名(Canonical Name,CName),具体参考RFC1035 3.2.2 & wikipedia 。
。
2、实现结果预览 。
先看一下最终搞成了什么样子 。
输入:域名字符串 。
输出:IP列表、CName列表、DNS查询所用时间 。
3、相关技术 。
。
3.1、UDP or TCP ? (RFC1035 4.2) 。
UDP:DNS查询和回复采用低开销高性能的UDP,端口号为53.
TCP:辅助DNS服务器从主DNS服务器拉取最新数据时,采用可靠的TCP传输,端口号也为53.
我们这里做DNS查询采用UDP,53端口.
3.2、DNS查询/回复包头部解析 (RFC1035 4.1.1) 。
重点介绍一下我们关心的部分:
ID(16bits):标识符,一般填入本进程的标识符 。
QR(1bits):标志位,查询包为0,回复包为1 。
Opcode(4bits):查询的种类,标准查询为0 。
QDCOUNT(16bits):DNS查询/回复包数据部分Question字段的个数 。
ANCOUNT(16bits):DNS查询/回复包数据部分Answer字段的个数 。
3.2、DNS查询/回复包数据部分解析 (RFC1035 4.1.2 & 4.1.3) 。
查询/回复包的数据部分依次为QDCOUNT个Question字段、ANCOUNT个Answer字段.... 。
对于任意字段,其格式如下:
Name(不定长):域名,这部分的格式比较复杂,后面单独说.
TYPE(16bits):查询类型/回复包RDATA类型,比如TYPE=1表示主机IP地址、TYPE=5表示CNAME,详见RFC1035 3.2.2 。
CLASS(16bits):类,一般情况下CLASS=1表示Internet,详见RFC1035 3.2.4 。
TTL(32bits,仅回复包):生存时间 。
RDLENGTH(16bits,仅回复包):RDATA部分的字节数 。
RDATA(不定长,仅回复包):资源数据,具体格式取决于TYPE和CLASS,比如TYPE=1、CLASS=1时,RDATA为四个字节的IP地址 。
3.3、Name解析&消息压缩 。
3.3.1、一般格式 (RFC1035 4.1.2) 。
标签内容长度(1个字节) + 标签内容,以标签内容长度0作为Name的结束符,例如:
3.3.2、消息压缩格式 (RFC1035 4.1.4) 。
如果标签内容长度的二进制前两位是11,则表示消息压缩.
此时,标签内容长度1个字节+后面的1个字节一共16位,后14位表示相对DNS包起始地址的偏移(Byte),例如:
上述例子中,DNS包起始地址为0x0000,c0 13的二进制为11000000 00010003,即跳转偏移为0x13个字节,对应的数据为03 63 6f 6d 00.
RFC1035中规定,支持的消息压缩规则为:
①以内容长度0结尾的标签序列 。
②偏移指针 。
③标签序列+偏移指针 。
也就是说,Name的消息压缩要求偏移指针必须在Name的尾部,且不支持同一级存在多个偏移指针(偏移指针序列), 。
但Name的消息压缩支持嵌套的偏移指针,即指针指向的偏移位置仍然是以偏移指针结尾的数据 。
4、代码实现 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
|
#pragma once
//这里需要导入库 Ws2_32.lib,在不同的IDE下可能不太一样
//#pragma comment(lib, "Ws2_32.lib")
#include <windows.h>
#include <string>
#include <vector>
#define MAX_DOMAINNAME_LEN 255
#define DNS_PORT 53
#define DNS_TYPE_SIZE 2
#define DNS_CLASS_SIZE 2
#define DNS_TTL_SIZE 4
#define DNS_DATALEN_SIZE 2
#define DNS_TYPE_A 0x0001 //1 a host address
#define DNS_TYPE_CNAME 0x0005 //5 the canonical name for an alias
#define DNS_PACKET_MAX_SIZE (sizeof(DNSHeader) + MAX_DOMAINNAME_LEN + DNS_TYPE_SIZE + DNS_CLASS_SIZE)
struct
DNSHeader
{
USHORT
usTransID;
//标识符
USHORT
usFlags;
//各种标志位
USHORT
usQuestionCount;
//Question字段个数
USHORT
usAnswerCount;
//Answer字段个数
USHORT
usAuthorityCount;
//Authority字段个数
USHORT
usAdditionalCount;
//Additional字段个数
};
class
CDNSLookup
{
public
:
CDNSLookup();
~CDNSLookup();
BOOL
DNSLookup(
ULONG
ulDNSServerIP,
char
*szDomainName, std::vector<
ULONG
> *pveculIPList = NULL, std::vector<std::string> *pvecstrCNameList = NULL,
ULONG
ulTimeout = 1000,
ULONG
*pulTimeSpent = NULL);
BOOL
DNSLookup(
ULONG
ulDNSServerIP,
char
*szDomainName, std::vector<std::string> *pvecstrIPList = NULL, std::vector<std::string> *pvecstrCNameList = NULL,
ULONG
ulTimeout = 1000,
ULONG
*pulTimeSpent = NULL);
private
:
BOOL
Init();
BOOL
UnInit();
BOOL
DNSLookupCore(
ULONG
ulDNSServerIP,
char
*szDomainName, std::vector<
ULONG
> *pveculIPList, std::vector<std::string> *pvecstrCNameList,
ULONG
ulTimeout,
ULONG
*pulTimeSpent);
BOOL
SendDNSRequest(sockaddr_in sockAddrDNSServer,
char
*szDomainName);
BOOL
RecvDNSResponse(sockaddr_in sockAddrDNSServer,
ULONG
ulTimeout, std::vector<
ULONG
> *pveculIPList, std::vector<std::string> *pvecstrCNameList,
ULONG
*pulTimeSpent);
BOOL
EncodeDotStr(
char
*szDotStr,
char
*szEncodedStr,
USHORT
nEncodedStrSize);
BOOL
DecodeDotStr(
char
*szEncodedStr,
USHORT
*pusEncodedStrLen,
char
*szDotStr,
USHORT
nDotStrSize,
char
*szPacketStartPos = NULL);
ULONG
GetTickCountCalibrate();
private
:
BOOL
m_bIsInitOK;
SOCKET m_sock;
WSAEVENT m_event;
USHORT
m_usCurrentProcID;
char
*m_szDNSPacket;
};
[DNSLookup.h]
#include "DNSLookup.h"
#include <stdio.h>
#include <string.h>
CDNSLookup::CDNSLookup() :
m_bIsInitOK(FALSE),
m_sock(INVALID_SOCKET),
m_szDNSPacket(NULL)
{
m_bIsInitOK = Init();
}
CDNSLookup::~CDNSLookup()
{
UnInit();
}
BOOL
CDNSLookup::DNSLookup(
ULONG
ulDNSServerIP,
char
*szDomainName, std::vector<
ULONG
> *pveculIPList, std::vector<std::string> *pvecstrCNameList,
ULONG
ulTimeout,
ULONG
*pulTimeSpent)
{
return
DNSLookupCore(ulDNSServerIP, szDomainName, pveculIPList, pvecstrCNameList, ulTimeout, pulTimeSpent);
}
BOOL
CDNSLookup::DNSLookup(
ULONG
ulDNSServerIP,
char
*szDomainName, std::vector<std::string> *pvecstrIPList, std::vector<std::string> *pvecstrCNameList,
ULONG
ulTimeout,
ULONG
*pulTimeSpent)
{
std::vector<
ULONG
> *pveculIPList = NULL;
if
(pvecstrIPList != NULL)
{
std::vector<
ULONG
> veculIPList;
pveculIPList = &veculIPList;
}
BOOL
bRet = DNSLookupCore(ulDNSServerIP, szDomainName, pveculIPList, pvecstrCNameList, ulTimeout, pulTimeSpent);
if
(bRet)
{
pvecstrIPList->clear();
char
szIP[16] = {
'\0'
};
for
(std::vector<
ULONG
>::iterator iter = pveculIPList->begin(); iter != pveculIPList->end(); ++iter)
{
BYTE
*pbyIPSegment = (
BYTE
*)(&(*iter));
//sprintf_s(szIP, 16, "%d.%d.%d.%d", pbyIPSegment[0], pbyIPSegment[1], pbyIPSegment[2], pbyIPSegment[3]);
sprintf
(szIP,
"%d.%d.%d.%d"
, pbyIPSegment[0], pbyIPSegment[1], pbyIPSegment[2], pbyIPSegment[3]);
pvecstrIPList->push_back(szIP);
}
}
return
bRet;
}
BOOL
CDNSLookup::Init()
{
WSADATA wsaData;
if
(WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR)
{
return
FALSE;
}
if
((m_sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
return
FALSE;
}
m_event = WSACreateEvent();
WSAEventSelect(m_sock, m_event, FD_READ);
m_szDNSPacket =
new
(std::
nothrow
)
char
[DNS_PACKET_MAX_SIZE];
if
(m_szDNSPacket == NULL)
{
return
FALSE;
}
m_usCurrentProcID = (
USHORT
)GetCurrentProcessId();
return
TRUE;
}
BOOL
CDNSLookup::UnInit()
{
WSACleanup();
if
(m_szDNSPacket != NULL)
{
delete
[] m_szDNSPacket;
}
return
TRUE;
}
BOOL
CDNSLookup::DNSLookupCore(
ULONG
ulDNSServerIP,
char
*szDomainName, std::vector<
ULONG
> *pveculIPList, std::vector<std::string> *pvecstrCNameList,
ULONG
ulTimeout,
ULONG
*pulTimeSpent)
{
if
(m_bIsInitOK == FALSE || szDomainName == NULL)
{
return
FALSE;
}
//配置SOCKET
sockaddr_in sockAddrDNSServer;
sockAddrDNSServer.sin_family = AF_INET;
sockAddrDNSServer.sin_addr.s_addr = ulDNSServerIP;
sockAddrDNSServer.sin_port = htons( DNS_PORT );
//DNS查询与解析
if
(!SendDNSRequest(sockAddrDNSServer, szDomainName)
|| !RecvDNSResponse(sockAddrDNSServer, ulTimeout, pveculIPList, pvecstrCNameList, pulTimeSpent))
{
return
FALSE;
}
return
TRUE;
}
BOOL
CDNSLookup::SendDNSRequest(sockaddr_in sockAddrDNSServer,
char
*szDomainName)
{
char
*pWriteDNSPacket = m_szDNSPacket;
memset
(pWriteDNSPacket, 0, DNS_PACKET_MAX_SIZE);
//填充DNS查询报文头部
DNSHeader *pDNSHeader = (DNSHeader*)pWriteDNSPacket;
pDNSHeader->usTransID = m_usCurrentProcID;
pDNSHeader->usFlags = htons(0x0100);
pDNSHeader->usQuestionCount = htons(0x0001);
pDNSHeader->usAnswerCount = 0x0000;
pDNSHeader->usAuthorityCount = 0x0000;
pDNSHeader->usAdditionalCount = 0x0000;
//设置DNS查询报文内容
USHORT
usQType = htons(0x0001);
USHORT
usQClass = htons(0x0001);
USHORT
nDomainNameLen =
strlen
(szDomainName);
char
*szEncodedDomainName = (
char
*)
malloc
(nDomainNameLen + 2);
if
(szEncodedDomainName == NULL)
{
return
FALSE;
}
if
(!EncodeDotStr(szDomainName, szEncodedDomainName, nDomainNameLen + 2))
{
return
FALSE;
}
//填充DNS查询报文内容
USHORT
nEncodedDomainNameLen =
strlen
(szEncodedDomainName) + 1;
memcpy
(pWriteDNSPacket +=
sizeof
(DNSHeader), szEncodedDomainName, nEncodedDomainNameLen);
memcpy
(pWriteDNSPacket += nEncodedDomainNameLen, (
char
*)(&usQType), DNS_TYPE_SIZE);
memcpy
(pWriteDNSPacket += DNS_TYPE_SIZE, (
char
*)(&usQClass), DNS_CLASS_SIZE);
free
(szEncodedDomainName);
//发送DNS查询报文
USHORT
nDNSPacketSize =
sizeof
(DNSHeader) + nEncodedDomainNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE;
if
(sendto(m_sock, m_szDNSPacket, nDNSPacketSize, 0, (sockaddr*)&sockAddrDNSServer,
sizeof
(sockAddrDNSServer)) == SOCKET_ERROR)
{
return
FALSE;
}
return
TRUE;
}
BOOL
CDNSLookup::RecvDNSResponse(sockaddr_in sockAddrDNSServer,
ULONG
ulTimeout, std::vector<
ULONG
> *pveculIPList, std::vector<std::string> *pvecstrCNameList,
ULONG
*pulTimeSpent)
{
ULONG
ulSendTimestamp = GetTickCountCalibrate();
if
(pveculIPList != NULL)
{
pveculIPList->clear();
}
if
(pvecstrCNameList != NULL)
{
pvecstrCNameList->clear();
}
char
recvbuf[1024] = {
'\0'
};
char
szDotName[128] = {
'\0'
};
USHORT
nEncodedNameLen = 0;
while
(TRUE)
{
if
(WSAWaitForMultipleEvents(1, &m_event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT)
{
WSANETWORKEVENTS netEvent;
WSAEnumNetworkEvents(m_sock, m_event, &netEvent);
if
(netEvent.lNetworkEvents & FD_READ)
{
ULONG
ulRecvTimestamp = GetTickCountCalibrate();
int
nSockaddrDestSize =
sizeof
(sockAddrDNSServer);
//接收响应报文
if
(recvfrom(m_sock, recvbuf, 1024, 0, (
struct
sockaddr*)&sockAddrDNSServer, &nSockaddrDestSize) != SOCKET_ERROR)
{
DNSHeader *pDNSHeader = (DNSHeader*)recvbuf;
USHORT
usQuestionCount = 0;
USHORT
usAnswerCount = 0;
if
(pDNSHeader->usTransID == m_usCurrentProcID
&& (ntohs(pDNSHeader->usFlags) & 0xfb7f) == 0x8100
//RFC1035 4.1.1(Header section format)
&& (usQuestionCount = ntohs(pDNSHeader->usQuestionCount)) >= 0
&& (usAnswerCount = ntohs(pDNSHeader->usAnswerCount)) > 0)
{
char
*pDNSData = recvbuf +
sizeof
(DNSHeader);
//解析Question字段
for
(
int
q = 0; q != usQuestionCount; ++q)
{
if
(!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName,
sizeof
(szDotName)))
{
return
FALSE;
}
pDNSData += (nEncodedNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE);
}
//解析Answer字段
for
(
int
a = 0; a != usAnswerCount; ++a)
{
if
(!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName,
sizeof
(szDotName), recvbuf))
{
return
FALSE;
}
pDNSData += nEncodedNameLen;
USHORT
usAnswerType = ntohs(*(
USHORT
*)(pDNSData));
USHORT
usAnswerClass = ntohs(*(
USHORT
*)(pDNSData + DNS_TYPE_SIZE));
ULONG
usAnswerTTL = ntohl(*(
ULONG
*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE));
USHORT
usAnswerDataLen = ntohs(*(
USHORT
*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE));
pDNSData += (DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE + DNS_DATALEN_SIZE);
if
(usAnswerType == DNS_TYPE_A && pveculIPList != NULL)
{
ULONG
ulIP = *(
ULONG
*)(pDNSData);
pveculIPList->push_back(ulIP);
}
else
if
(usAnswerType == DNS_TYPE_CNAME && pvecstrCNameList != NULL)
{
if
(!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName,
sizeof
(szDotName), recvbuf))
{
return
FALSE;
}
pvecstrCNameList->push_back(szDotName);
}
pDNSData += (usAnswerDataLen);
}
//计算DNS查询所用时间
if
(pulTimeSpent != NULL)
{
*pulTimeSpent = ulRecvTimestamp - ulSendTimestamp;
}
break
;
}
}
}
}
//超时退出
if
(GetTickCountCalibrate() - ulSendTimestamp > ulTimeout)
{
*pulTimeSpent = ulTimeout + 1;
return
FALSE;
}
}
return
TRUE;
}
/*
* convert "www.baidu.com" to "\x03www\x05baidu\x03com"
* 0x0000 03 77 77 77 05 62 61 69 64 75 03 63 6f 6d 00 ff
*/
BOOL
CDNSLookup::EncodeDotStr(
char
*szDotStr,
char
*szEncodedStr,
USHORT
nEncodedStrSize)
{
USHORT
nDotStrLen =
strlen
(szDotStr);
if
(szDotStr == NULL || szEncodedStr == NULL || nEncodedStrSize < nDotStrLen + 2)
{
return
FALSE;
}
char
*szDotStrCopy =
new
char
[nDotStrLen + 1];
//strcpy_s(szDotStrCopy, nDotStrLen + 1, szDotStr);
strcpy
(szDotStrCopy, szDotStr);
char
*pNextToken = NULL;
//char *pLabel = strtok_s(szDotStrCopy, ".", &pNextToken);
char
*pLabel =
strtok
(szDotStrCopy,
"."
);
USHORT
nLabelLen = 0;
USHORT
nEncodedStrLen = 0;
while
(pLabel != NULL)
{
if
((nLabelLen =
strlen
(pLabel)) != 0)
{
//sprintf_s(szEncodedStr + nEncodedStrLen, nEncodedStrSize - nEncodedStrLen, "%c%s", nLabelLen, pLabel);
sprintf
(szEncodedStr + nEncodedStrLen,
"%c%s"
, nLabelLen, pLabel);
nEncodedStrLen += (nLabelLen + 1);
}
//pLabel = strtok_s(NULL, ".", &pNextToken);
pLabel =
strtok
(NULL,
"."
);
}
delete
[] szDotStrCopy;
return
TRUE;
}
/*
* convert "\x03www\x05baidu\x03com\x00" to "www.baidu.com"
* 0x0000 03 77 77 77 05 62 61 69 64 75 03 63 6f 6d 00 ff
* convert "\x03www\x05baidu\xc0\x13" to "www.baidu.com"
* 0x0000 03 77 77 77 05 62 61 69 64 75 c0 13 ff ff ff ff
* 0x0010 ff ff ff 03 63 6f 6d 00 ff ff ff ff ff ff ff ff
*/
BOOL
CDNSLookup::DecodeDotStr(
char
*szEncodedStr,
USHORT
*pusEncodedStrLen,
char
*szDotStr,
USHORT
nDotStrSize,
char
*szPacketStartPos)
{
if
(szEncodedStr == NULL || pusEncodedStrLen == NULL || szDotStr == NULL)
{
return
FALSE;
}
char
*pDecodePos = szEncodedStr;
USHORT
usPlainStrLen = 0;
BYTE
nLabelDataLen = 0;
*pusEncodedStrLen = 0;
while
((nLabelDataLen = *pDecodePos) != 0x00)
{
if
((nLabelDataLen & 0xc0) == 0)
//普通格式,LabelDataLen + Label
{
if
(usPlainStrLen + nLabelDataLen + 1 > nDotStrSize)
{
return
FALSE;
}
memcpy
(szDotStr + usPlainStrLen, pDecodePos + 1, nLabelDataLen);
memcpy
(szDotStr + usPlainStrLen + nLabelDataLen,
"."
, 1);
pDecodePos += (nLabelDataLen + 1);
usPlainStrLen += (nLabelDataLen + 1);
*pusEncodedStrLen += (nLabelDataLen + 1);
}
else
//消息压缩格式,11000000 00000000,两个字节,前2位为跳转标志,后14位为跳转的偏移
{
if
(szPacketStartPos == NULL)
{
return
FALSE;
}
USHORT
usJumpPos = ntohs(*(
USHORT
*)(pDecodePos)) & 0x3fff;
USHORT
nEncodeStrLen = 0;
if
(!DecodeDotStr(szPacketStartPos + usJumpPos, &nEncodeStrLen, szDotStr + usPlainStrLen, nDotStrSize - usPlainStrLen, szPacketStartPos))
{
return
FALSE;
}
else
{
*pusEncodedStrLen += 2;
return
TRUE;
}
}
}
szDotStr[usPlainStrLen - 1] =
'\0'
;
*pusEncodedStrLen += 1;
return
TRUE;
}
ULONG
CDNSLookup::GetTickCountCalibrate()
{
static
ULONG
s_ulFirstCallTick = 0;
static
LONGLONG
s_ullFirstCallTickMS = 0;
SYSTEMTIME systemtime;
FILETIME filetime;
GetLocalTime(&systemtime);
SystemTimeToFileTime(&systemtime, &filetime);
LARGE_INTEGER liCurrentTime;
liCurrentTime.HighPart = filetime.dwHighDateTime;
liCurrentTime.LowPart = filetime.dwLowDateTime;
LONGLONG
llCurrentTimeMS = liCurrentTime.QuadPart / 10000;
if
(s_ulFirstCallTick == 0)
{
s_ulFirstCallTick = GetTickCount();
}
if
(s_ullFirstCallTickMS == 0)
{
s_ullFirstCallTickMS = llCurrentTimeMS;
}
return
s_ulFirstCallTick + (
ULONG
)(llCurrentTimeMS - s_ullFirstCallTickMS);
}
[DNSLookup.cpp]
#include <stdio.h>
#include <windows.h>
#include "DNSLookup.h"
int
main(
void
)
{
char
szDomainName[] =
"www.baidu.com"
;
std::vector<
ULONG
> veculIPList;
std::vector<std::string> vecstrIPList;
std::vector<std::string> vecCNameList;
ULONG
ulTimeSpent = 0;
CDNSLookup dnslookup;
BOOL
bRet = dnslookup.DNSLookup(inet_addr(
"114.114.114.114"
), szDomainName, &vecstrIPList, &vecCNameList, 1000, &ulTimeSpent);
printf
(
"DNSLookup result (%s):\n"
, szDomainName);
if
(!bRet)
{
printf
(
"timeout!\n"
);
return
-1;
}
for
(
int
i = 0; i != veculIPList.size(); ++i)
{
printf
(
"IP%d(ULONG) = %u\n"
, i + 1, veculIPList[i]);
}
for
(
int
i = 0; i != vecstrIPList.size(); ++i)
{
printf
(
"IP%d(string) = %s\n"
, i + 1, vecstrIPList[i].c_str());
}
for
(
int
i = 0; i != vecCNameList.size(); ++i)
{
printf
(
"CName%d = %s\n"
, i + 1, vecCNameList[i].c_str());
}
printf
(
"time spent = %ums\n"
, ulTimeSpent);
return
0;
}
|
以上就是C++实现DNS域名解析的全部内容,希望对大家的学习有所帮助.
最后此篇关于C++如何实现DNS域名解析的文章就讲到这里了,如果你想了解更多关于C++如何实现DNS域名解析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要为一系列 Linux 容器运行本地 BIND DNS 服务器。假设区域是 example.com 我的基础架构中已经有一个 example.com 域,我想使用我的本地 DNS 服务器覆盖一些记
当“Google Public DNS”免费时,为什么要使用“Google Cloud DNS”? 如何设置 DNS/名称服务器以指向计算引擎: 1. 将您的域注册器(在我的情况下为 GoDaddy.
我有一些主机在 EC2 中按需出现,当它们执行启动它们的服务时,它们会在现有区域下的 Route53 中创建一条 A 记录。 A 记录的格式为:randomid.example.com。所以它不是现有
我目前拥有自己的域名和专用服务器,并且为我的客户提供不同的软件包。我希望能够做的是让他们在我的网站上注册并自动创建一个包,他们可以通过他们的用户名作为子域进行访问,例如 http://youruser
我想知道如何只为一级子域设置通配符 DNS,示例: user.example.com // valid www.user.example.com // invalid 我的 BIND 区域域配
我正在努力将我的域的名称服务器切换到新的 DNS 服务。 将新设置与现有 DNS 设置进行比较的最佳工具是什么。 我尝试使用带有和不带有 @nameserver 的 dig 来确保 DNS 记录在新旧
我是一名长期开发人员,但对 DNS 的经验并不丰富。这是我的问题: 我们的应用程序在 Amazon EC2 上为客户启动服务器。一个客户希望为每台启动的服务器使用自定义 DNS,而不是 AWS 提供的
Closed. This question is off-topic。它当前不接受答案。 想改善这个问题吗? Update the question,所以它是用于堆栈溢出的on-topic。 9年前关
我看到几个提到 DNS 名称(域名)的最大字符串长度为 253 个字符。维基百科似乎指的是这篇旧博文: https://en.wikipedia.org/wiki/Hostname http://bl
这可能是完全不可能实现的,但在我尝试之前,我想我可能会从一位极客那里得到一些建议。 Squid 也会代理 DNS 查询吗?我想转发DNS查询以通过squid并使用squid的DNS错误页面,当然是通过
在我的 Rails 应用程序中,我使用 ruby 库 resolv 进行 nslookup。如果输入像 dgdfgdfgdfg.com 这样的网站,则说明时间太长而无法解决。在某些情况下,例如 2
我正在研究一个带有每 5 秒刷新一次(轮询)的实时仪表板(Angular Web 应用程序)的场景。 API 位于 Azure 流量管理器之后,如果主要区域发生故障,它将故障转移到第二个区域。请记住,
我正在使用 fortify,它显示了攻击者可以在我尝试在 java 应用程序中获取主机名时进行 DNS 欺骗的漏洞。我有一个解决方案,通过匹配正向 DNS 和反向 DNS 条目可以避免这种情况。但它有
我正在尝试使用 cert-manager 为我的 istio-ingress-gateway 订购证书。为此,我在 AKS 上的 kubernetes 集群 (1.13.7) 上安装了 istio (
我正在尝试创建一个家庭自动化系统,它可以在我工作的白天照看我的狗。我在这个项目中的目标是学习一些关于 DNS、文件服务和 RaspberryPi 的知识。 我的硬件设置是这样的: 1 个 Raspbe
我想在一台服务器上创建一个 Web 界面,以管理另一台服务器上的几个 dns 服务器。 如何以编程方式远程管理绑定(bind) dns 服务器? 我想添加/编辑/删除区域。 我看到有 rndc,但它只
我对 TTL 和传播时间的概念有点困惑,我想澄清一些我没有设法在网上找到具体答案的事情。 AFAIK,TTL(生存时间)表示世界各地的服务器更新特定 DNS 的缓存值所需的(最高)时间。 所以...
我正在尝试学习 kubernetes,并且我已成功在裸机上设置集群(1 节点)、部署服务并通过入口公开它。 我尝试实现 traefik,以获取 Lets 加密证书,但我无法使其工作,并且在调试时我注意
我想以编程方式自动更新我的 DNS 多个域。我在 GoDaddy 上运行 BIND 服务器(在 FreeBSD 上)以及主机域和 DNS。我找不到供 GoDaddy 访问和更新他们托管的 DNS 的
我正在尝试记录 DNS“泄漏”,换句话说,我网站的访问者使用的 DNS 服务器。 如何确定网络请求来自哪个 DNS 服务器到我的服务器(即获取 DNS 泄漏)。本站 dnsleaktest.com是吗
我是一名优秀的程序员,十分优秀!