Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cross platform tracing #10

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,6 @@ Thumbs.db

# Built data for installer creation
installer/packages/net.candymade.nyatrace/data/

# macOS build
build/
2 changes: 1 addition & 1 deletion ipdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <QString>

#include "libmaxminddb\maxminddb.h"
#include "libmaxminddb/maxminddb.h"

// IPDB 类:操作基于 MMDB 的数据读取工作,
// 以后可能会改成基于 web 请求的格式以优化封装体积
Expand Down
12 changes: 6 additions & 6 deletions nyatrace.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs depr
SOURCES += \
configs.cpp \
ipdb.cpp \
libmaxminddb\data-pool.c \
libmaxminddb\maxminddb.c \
libmaxminddb/data-pool.c \
libmaxminddb/maxminddb.c \
nyatrace_about.cpp \
nyatrace_configs.cpp \
nyatrace_gui.cpp \
Expand All @@ -35,10 +35,10 @@ HEADERS += \
data-pool.h \
ipdb.h \
ipdb_settings.h \
libmaxminddb\data-pool.h \
libmaxminddb\maxminddb-compat-util.h \
libmaxminddb\maxminddb.h \
libmaxminddb\maxminddb_config.h \
libmaxminddb/data-pool.h \
libmaxminddb/maxminddb-compat-util.h \
libmaxminddb/maxminddb.h \
libmaxminddb/maxminddb_config.h \
mode.h \
nyatrace_about.h \
nyatrace_configs.h \
Expand Down
9 changes: 9 additions & 0 deletions nyatrace_gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,18 @@ private slots:
// 界面 UI
Ui::NyaTraceGUI *ui;

#ifdef Q_OS_WIN

// 一种数据结构。这个结构被用来存储被 WSAStartup 函数调用后返回的 Windows Sockets 数据
WSADATA wsa;

#endif
#ifdef Q_OS_UNIX

// TODO

#endif

// 用于路由追踪的子线程
TracingCore * tracingThread;

Expand Down
33 changes: 31 additions & 2 deletions resolve_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void ResolveCore::run() {
sockaddr_storage targetIPAddress; // 用于存储目标地址

// 清空目标地址
ZeroMemory(&targetIPAddress, sizeof(sockaddr_storage));
memset(&targetIPAddress, 0, sizeof(sockaddr_storage));

if (ParseIPAddress(hostCharStr, targetIPAddress)) {
// 解析成功,更新状态
Expand Down Expand Up @@ -64,7 +64,36 @@ void ResolveCore::run() {
}
} else {
// 解析失败

#ifdef Q_OS_WIN

auto err = WSAGetLastError();

#endif
#ifdef Q_OS_UNIX

QString err;

switch (h_errno) {
case HOST_NOT_FOUND:
err = "找不到主机";
break;
case NO_ADDRESS:
err = "没有查询到地址";
break;
case NO_RECOVERY:
err = "无法恢复的解析错误";
break;
case TRY_AGAIN:
err = "名称解析暂时不可用";
break;
default:
err = "未知问题";
break;
}

#endif

qWarning() << "[Resolve Core]"
<< "Failed to resolve host with error: " << err;
emit setMessage(QString("主机名解析失败,错误代码: %1 。").arg(err));
Expand All @@ -81,7 +110,7 @@ void ResolveCore::GetInfo(int id, sockaddr_storage * targetIPAddress) {
// 查询 IP 对应的信息

char printIPAddress[INET6_ADDRSTRLEN]; // INET6_ADDRSTRLEN 大于 INET_ADDRSTRLEN ,所以可以兼容(虽然可能有点浪费)
ZeroMemory(printIPAddress, sizeof(printIPAddress));
memset(printIPAddress, 0, sizeof(printIPAddress));
PrintIPAddress(targetIPAddress, printIPAddress);

// 准备从 City 数据库中查询结果
Expand Down
55 changes: 52 additions & 3 deletions tracing_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@
#include "tracing_core.h"
#include "tracing_utils.h"

#ifdef Q_OS_WIN

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#endif
#ifdef Q_OS_UNIX

// TODO

#endif

/**
* TracingCore
* 执行追踪程序的核心,涉及到基础数据的转化、追踪线程的管理和对 UI 状态的更新
Expand All @@ -18,6 +27,8 @@ TracingCore::TracingCore() {
qDebug() << "[Trace Core]"
<< "Tracing Core start constructing...";

#ifdef Q_OS_WIN

// 载入依赖的动态链接库
hIcmpDll = LoadLibraryA("IPHLPAPI.DLL");
if (hIcmpDll == NULL) {
Expand Down Expand Up @@ -46,6 +57,13 @@ TracingCore::TracingCore() {
<< "Failed to open ICMP6 handle";
}

#endif
#ifdef Q_OS_UNIX

// TODO

#endif

// 新建一个线程池
tracingPool = new QThreadPool;

Expand All @@ -62,12 +80,21 @@ TracingCore::~TracingCore() {
// 销毁线程池
delete tracingPool;

#ifdef Q_OS_WIN

// 回收资源
IcmpCloseHandle(hIcmp);
IcmpCloseHandle(hIcmp6);

// 释放动态链接库
FreeLibrary(hIcmpDll);

#endif
#ifdef Q_OS_UNIX

// TODO

#endif
}

void TracingCore::run() {
Expand All @@ -84,10 +111,10 @@ void TracingCore::run() {
sockaddr_storage targetIPAddress; // 用于存储目标地址

// 清空目标地址
ZeroMemory(&targetIPAddress, sizeof(sockaddr_storage));
memset(&targetIPAddress, 0, sizeof(sockaddr_storage));

char printIPAddress[INET6_ADDRSTRLEN]; // INET6_ADDRSTRLEN 大于 INET_ADDRSTRLEN ,所以可以兼容(虽然可能有点浪费)
ZeroMemory(printIPAddress, sizeof(printIPAddress));
memset(printIPAddress, 0, sizeof(printIPAddress));

if (ParseIPAddress(hostCharStr, targetIPAddress)) {
// 解析成功,更新状态
Expand Down Expand Up @@ -115,7 +142,7 @@ void TracingCore::run() {
sockaddr_storage sourceIPAddress;

// 清空当前地址
ZeroMemory(&sourceIPAddress, sizeof(sockaddr_storage));
memset(&sourceIPAddress, 0, sizeof(sockaddr_storage));

// 相同传输协议栈
sourceIPAddress.ss_family = targetIPAddress.ss_family;
Expand All @@ -125,7 +152,18 @@ void TracingCore::run() {
case AF_INET:
qDebug() << "[Trace Core]"
<< "Binding any outbound IPv4 address";

#ifdef Q_OS_WIN

((sockaddr_in*)&sourceIPAddress)->sin_addr = in4addr_any;

#endif
#ifdef Q_OS_UNIX

((sockaddr_in*)&sourceIPAddress)->sin_addr.s_addr = htonl(INADDR_ANY);

#endif

break;
case AF_INET6:
qDebug() << "[Trace Core]"
Expand All @@ -144,8 +182,19 @@ void TracingCore::run() {
workers[i]->iTTL = i + 1;
workers[i]->sourceIPAddress = &sourceIPAddress;
workers[i]->targetIPAddress = &targetIPAddress;

#ifdef Q_OS_WIN

workers[i]->hIcmp = hIcmp;
workers[i]->hIcmp6 = hIcmp6;

#endif
#ifdef Q_OS_UNIX

// TODO

#endif

workers[i]->ipdb = ipdb;

connect(workers[i], &TracingWorker::reportIPAndTimeConsumption, this, [=](const int hop, const unsigned long timeConsumption, const QString & ipAddress, const bool isValid, const bool isTargetHost) {
Expand Down
9 changes: 9 additions & 0 deletions tracing_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class TracingCore : public QThread

private: // 私有变量区

#ifdef Q_OS_WIN

// 定义动态链接库
HMODULE hIcmpDll;

Expand All @@ -33,6 +35,13 @@ class TracingCore : public QThread
HANDLE hIcmp;
HANDLE hIcmp6;

#endif
#ifdef Q_OS_UNIX

// TODO

#endif

// 追踪线程的线程池
QThreadPool * tracingPool;

Expand Down
25 changes: 25 additions & 0 deletions tracing_defs.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifndef TRACING_DEFS_H
#define TRACING_DEFS_H

#include <QtGlobal>

#ifdef Q_OS_WIN

#include <winsock2.h> // 类型定义
#include <IPHlpApi.h>
#include <IcmpAPI.h>
Expand All @@ -9,6 +13,27 @@
typedef HANDLE (WINAPI *lpIcmpCreateFile )(VOID);
typedef BOOL (WINAPI *lpIcmpCloseHandle)(HANDLE IcmpHandle);

#endif
#ifdef Q_OS_UNIX

#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>

#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>

#include <arpa/inet.h>

#include <netdb.h>

#endif

// 常量定义
const int DEF_ICMP_DATA_SIZE = 32; // 默认ICMP数据部分长度

Expand Down
6 changes: 3 additions & 3 deletions tracing_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ addrinfo * ResolveAllAddress(const char * hostname) {
addrinfo * resolveResult = NULL;
addrinfo resolveHints;

ZeroMemory(&resolveHints, sizeof(resolveHints));
memset(&resolveHints, 0, sizeof(resolveHints));

resolveHints.ai_family = AF_UNSPEC;
resolveHints.ai_socktype = SOCK_STREAM;
Expand All @@ -21,8 +21,8 @@ addrinfo * ResolveAllAddress(const char * hostname) {

bool ParseIPAddress(const char * ipStr, sockaddr_storage & targetIPAddress) {

IN_ADDR addr4; // IPv4 地址的暂存区域
IN6_ADDR addr6; // IPv6 地址的暂存区域
in_addr addr4; // IPv4 地址的暂存区域
in6_addr addr6; // IPv6 地址的暂存区域

if (inet_pton(AF_INET, ipStr, &addr4) != 0) {
// 输入是 IPv4 地址
Expand Down
12 changes: 11 additions & 1 deletion tracing_utils.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
#ifndef TRACING_UTILS_H
#define TRACING_UTILS_H

#include <WS2tcpip.h>
#include "tracing_defs.h"

#ifdef Q_OS_WIN

#include <WS2tcpip.h>

#endif
#ifdef Q_OS_UNIX

// TODO

#endif

addrinfo * ResolveAllAddress(const char * hostname);
bool ParseIPAddress(const char * ipStr, sockaddr_storage & targetIPAddress);
bool PrintIPAddress(sockaddr_storage * targetIPAddress, char * printIPAddress);
Expand Down
Loading