-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathresolve_core.cpp
138 lines (115 loc) · 4.17 KB
/
resolve_core.cpp
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
#include <QDebug>
#include "resolve_core.h"
#include "tracing_utils.h"
ResolveCore::ResolveCore() {
// 没什么需要准备的
}
ResolveCore::~ResolveCore() {
// 没什么需要销毁的
}
void ResolveCore::run() {
// 获得主机名字符串
std::string hostStdStr = hostname.toStdString();
const char * hostCharStr = hostStdStr.c_str();
qDebug() << "[Resolve Core]"
<< "Target host: " << hostCharStr;
sockaddr_storage targetIPAddress; // 用于存储目标地址
// 清空目标地址
ZeroMemory(&targetIPAddress, sizeof(sockaddr_storage));
if (ParseIPAddress(hostCharStr, targetIPAddress)) {
// 解析成功,更新状态
GetInfo(1, &targetIPAddress);
} else {
// 按照主机名解析
qDebug() << "[Resolve Core]"
<< "Target host is not IP address, resolving...";
auto resolveResult = ResolveAllAddress(hostCharStr);
if (resolveResult != NULL) {
int idCounter = 1;
while (resolveResult != NULL) {
bool isAddressValid = true;
switch (resolveResult->ai_family) {
case AF_INET:
// 是 IPv4
targetIPAddress.ss_family = AF_INET;
(*(sockaddr_in*)&targetIPAddress).sin_addr.s_addr = (*(sockaddr_in*)resolveResult->ai_addr).sin_addr.s_addr;
break;
case AF_INET6:
// 是 IPv6
targetIPAddress.ss_family = AF_INET6;
memcpy((*(sockaddr_in6*)&targetIPAddress).sin6_addr.s6_addr, (*(sockaddr_in6*)resolveResult->ai_addr).sin6_addr.s6_addr, resolveResult->ai_addrlen);
break;
default:
// 不是 IPv4 也不是 IPv6
isAddressValid = false;
}
if (isAddressValid) {
GetInfo(idCounter, &targetIPAddress);
idCounter++;
}
resolveResult = resolveResult->ai_next;
}
} else {
// 解析失败
auto err = WSAGetLastError();
qWarning() << "[Resolve Core]"
<< "Failed to resolve host with error: " << err;
emit setMessage(QString("主机名解析失败,错误代码: %1 。").arg(err));
emit end(false);
return; // 结束
}
}
emit end(true);
}
void ResolveCore::GetInfo(int id, sockaddr_storage * targetIPAddress) {
// 查询 IP 对应的信息
char printIPAddress[INET6_ADDRSTRLEN]; // INET6_ADDRSTRLEN 大于 INET_ADDRSTRLEN ,所以可以兼容(虽然可能有点浪费)
ZeroMemory(printIPAddress, sizeof(printIPAddress));
PrintIPAddress(targetIPAddress, printIPAddress);
// 准备从 City 数据库中查询结果
QString cityName;
QString countryName;
double latitude = 0.0;
double longitude = 0.0;
uint16_t accuracyRadius = 0;
bool isLocationValid = true;
// 准备从 ISP 数据库中查询结果
QString isp;
QString org;
uint asn = 0;
QString asOrg;
// 在 City 数据库中查询当前 IP 对应信息
if (!ipdb->LookUpIPCityInfo(
(sockaddr *)targetIPAddress,
cityName,
countryName,
latitude,
longitude,
accuracyRadius,
isLocationValid
)) {
// 查询失败,使用填充字符
cityName = QString("未知");
countryName = QString("");
isLocationValid = false;
}
// 在 ISP 数据库中查询当前 IP 对应信息
if (!ipdb->LookUpIPISPInfo(
(sockaddr *)targetIPAddress,
isp,
org,
asn,
asOrg
)) {
// 查询失败,使用填充字符
isp = QString("未知");
org = QString("");
asOrg = QString("未知");
}
// 更新数据
emit setInformation(
id, QString(printIPAddress),
cityName, countryName, latitude, longitude, accuracyRadius, isLocationValid, // GeoIP2 City
isp, org, asn, asOrg // GeoIP2 ISP
);
}