parent
24759c92ad
commit
5bd8c33a6d
22 changed files with 319 additions and 172 deletions
|
|
@ -4,8 +4,11 @@
|
|||
|
||||
#include "dnsutilswindows.h"
|
||||
|
||||
#include <WS2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2ipdef.h>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QTextStream>
|
||||
|
|
@ -39,30 +42,27 @@ DnsUtilsWindows::~DnsUtilsWindows() {
|
|||
|
||||
bool DnsUtilsWindows::updateResolvers(const QString& ifname,
|
||||
const QList<QHostAddress>& resolvers) {
|
||||
NET_LUID luid;
|
||||
if (ConvertInterfaceAliasToLuid((wchar_t*)ifname.utf16(), &luid) != 0) {
|
||||
MIB_IF_ROW2 entry;
|
||||
if (ConvertInterfaceAliasToLuid((wchar_t*)ifname.utf16(),
|
||||
&entry.InterfaceLuid) != 0) {
|
||||
logger.error() << "Failed to resolve LUID for" << ifname;
|
||||
return false;
|
||||
}
|
||||
m_luid = luid.Value;
|
||||
if (GetIfEntry2(&entry) != NO_ERROR) {
|
||||
logger.error() << "Failed to resolve interface for" << ifname;
|
||||
return false;
|
||||
}
|
||||
m_luid = entry.InterfaceLuid.Value;
|
||||
|
||||
logger.debug() << "Configuring DNS for" << ifname;
|
||||
if (m_setInterfaceDnsSettingsProcAddr == nullptr) {
|
||||
return updateResolversNetsh(resolvers);
|
||||
return updateResolversNetsh(entry.InterfaceIndex, resolvers);
|
||||
}
|
||||
return updateResolversWin32(resolvers);
|
||||
return updateResolversWin32(entry.InterfaceGuid, resolvers);
|
||||
}
|
||||
|
||||
bool DnsUtilsWindows::updateResolversWin32(
|
||||
const QList<QHostAddress>& resolvers) {
|
||||
GUID guid;
|
||||
NET_LUID luid;
|
||||
luid.Value = m_luid;
|
||||
if (ConvertInterfaceLuidToGuid(&luid, &guid) != NO_ERROR) {
|
||||
logger.error() << "Failed to resolve GUID";
|
||||
return false;
|
||||
}
|
||||
|
||||
GUID guid, const QList<QHostAddress>& resolvers) {
|
||||
QStringList v4resolvers;
|
||||
QStringList v6resolvers;
|
||||
for (const QHostAddress& addr : resolvers) {
|
||||
|
|
@ -113,16 +113,8 @@ constexpr const char* netshAddTemplate =
|
|||
"interface %1 add dnsservers name=%2 address=%3 validate=no\r\n";
|
||||
|
||||
bool DnsUtilsWindows::updateResolversNetsh(
|
||||
const QList<QHostAddress>& resolvers) {
|
||||
int ifindex, const QList<QHostAddress>& resolvers) {
|
||||
QProcess netsh;
|
||||
NET_LUID luid;
|
||||
NET_IFINDEX ifindex;
|
||||
luid.Value = m_luid;
|
||||
if (ConvertInterfaceLuidToIndex(&luid, &ifindex) != NO_ERROR) {
|
||||
logger.error() << "Failed to resolve GUID";
|
||||
return false;
|
||||
}
|
||||
|
||||
netsh.setProgram("netsh");
|
||||
netsh.start();
|
||||
if (!netsh.waitForStarted(WINDOWS_NETSH_TIMEOUT_MSEC)) {
|
||||
|
|
@ -166,12 +158,26 @@ bool DnsUtilsWindows::updateResolversNetsh(
|
|||
|
||||
bool DnsUtilsWindows::restoreResolvers() {
|
||||
if (m_luid == 0) {
|
||||
// If the DNS hasn't been configured, there is nothing to restore.
|
||||
return true;
|
||||
}
|
||||
|
||||
MIB_IF_ROW2 entry;
|
||||
DWORD error;
|
||||
entry.InterfaceLuid.Value = m_luid;
|
||||
error = GetIfEntry2(&entry);
|
||||
if (error == ERROR_FILE_NOT_FOUND) {
|
||||
// If the interface no longer exists, there is nothing to restore.
|
||||
return true;
|
||||
}
|
||||
if (error != NO_ERROR) {
|
||||
logger.error() << "Failed to resolve interface entry:" << error;
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QHostAddress> empty;
|
||||
if (m_setInterfaceDnsSettingsProcAddr == nullptr) {
|
||||
return updateResolversNetsh(empty);
|
||||
return updateResolversNetsh(entry.InterfaceIndex, empty);
|
||||
}
|
||||
return updateResolversWin32(empty);
|
||||
return updateResolversWin32(entry.InterfaceGuid, empty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class DnsUtilsWindows final : public DnsUtils {
|
|||
quint64 m_luid = 0;
|
||||
DWORD (*m_setInterfaceDnsSettingsProcAddr)(GUID, const void*) = nullptr;
|
||||
|
||||
bool updateResolversWin32(const QList<QHostAddress>& resolvers);
|
||||
bool updateResolversNetsh(const QList<QHostAddress>& resolvers);
|
||||
bool updateResolversWin32(GUID, const QList<QHostAddress>& resolvers);
|
||||
bool updateResolversNetsh(int ifindex, const QList<QHostAddress>& resolvers);
|
||||
};
|
||||
|
||||
#endif // DNSUTILSWINDOWS_H
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ class WindowsDaemon final : public Daemon {
|
|||
Inactive,
|
||||
};
|
||||
|
||||
State m_state = Inactive;
|
||||
int m_inetAdapterIndex = -1;
|
||||
|
||||
WireguardUtilsWindows* m_wgutils = nullptr;
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ void WindowsRouteMonitor::updateValidInterfaces(int family) {
|
|||
void WindowsRouteMonitor::updateExclusionRoute(MIB_IPFORWARD_ROW2* data,
|
||||
void* ptable) {
|
||||
PMIB_IPFORWARD_TABLE2 table = reinterpret_cast<PMIB_IPFORWARD_TABLE2>(ptable);
|
||||
SOCKADDR_INET nexthop = {0};
|
||||
SOCKADDR_INET nexthop = {};
|
||||
quint64 bestLuid = 0;
|
||||
int bestMatch = -1;
|
||||
ULONG bestMetric = ULONG_MAX;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Logger logger("tunnel.dll");
|
|||
|
||||
WindowsTunnelLogger::WindowsTunnelLogger(const QString& filename,
|
||||
QObject* parent)
|
||||
: QObject(parent), m_logfile(filename, this), m_timer(this) {
|
||||
: QObject(parent), m_timer(this), m_logfile(filename, this) {
|
||||
MZ_COUNT_CTOR(WindowsTunnelLogger);
|
||||
|
||||
m_startTime = QDateTime::currentMSecsSinceEpoch() * 1000000;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WindowsTunnelService.h"
|
||||
#include "windowstunnelservice.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
|
|
@ -30,12 +30,22 @@ static bool waitForServiceStatus(SC_HANDLE service, DWORD expectedStatus);
|
|||
|
||||
WindowsTunnelService::WindowsTunnelService(QObject* parent) : QObject(parent) {
|
||||
MZ_COUNT_CTOR(WindowsTunnelService);
|
||||
logger.debug() << "WindowsTunnelService created.";
|
||||
|
||||
m_scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
||||
if (m_scm == nullptr) {
|
||||
WindowsUtils::windowsLog("Failed to open SCManager");
|
||||
}
|
||||
|
||||
// Is the service already running? Terminate it.
|
||||
SC_HANDLE service =
|
||||
OpenService((SC_HANDLE)m_scm, TUNNEL_SERVICE_NAME, SERVICE_ALL_ACCESS);
|
||||
if (service != nullptr) {
|
||||
logger.info() << "Tunnel already exists. Terminating it.";
|
||||
stopAndDeleteTunnelService(service);
|
||||
CloseServiceHandle(service);
|
||||
}
|
||||
|
||||
connect(&m_timer, &QTimer::timeout, this, &WindowsTunnelService::timeout);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue