MCPcopy Create free account
hub / github.com/Windscribe/Desktop-App / setCustomDnsWhileConnected

Function setCustomDnsWhileConnected

src/helper/windows/process_command.cpp:331–395  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

329}
330
331std::string setCustomDnsWhileConnected(const std::string &pars)
332{
333 unsigned long ifIndex;
334 std::wstring overrideDnsIpAddress;
335 deserializePars(pars, ifIndex, overrideDnsIpAddress);
336
337 if (!NetworkValidation::isValidIpAddress(overrideDnsIpAddress)) {
338 spdlog::error(L"setCustomDnsWhileConnected: invalid IP address: \"{}\"", overrideDnsIpAddress);
339 return serializeResult(false);
340 }
341
342 // Prefer the structured SetInterfaceDnsSettings API (Win10 2004+) so the IP is passed
343 // through a typed field instead of being interpolated into a command line. The IP is
344 // validated above, so command injection isn't reachable today, but the typed call
345 // closes the netsh parsing sink entirely as defense-in-depth.
346 try {
347 wsl::SystemLibLoader iphlpapi("iphlpapi.dll");
348 const auto pSetInterfaceDnsSettings = iphlpapi.getFunction<DWORD WINAPI(GUID, const DNS_INTERFACE_SETTINGS *)>("SetInterfaceDnsSettings");
349
350 NET_LUID luid = {};
351 DWORD ret = ::ConvertInterfaceIndexToLuid(ifIndex, &luid);
352 if (ret != NO_ERROR) {
353 spdlog::error("setCustomDnsWhileConnected: ConvertInterfaceIndexToLuid failed ({})", ret);
354 return serializeResult(false);
355 }
356
357 GUID guid = {};
358 ret = ::ConvertInterfaceLuidToGuid(&luid, &guid);
359 if (ret != NO_ERROR) {
360 spdlog::error("setCustomDnsWhileConnected: ConvertInterfaceLuidToGuid failed ({})", ret);
361 return serializeResult(false);
362 }
363
364 IN6_ADDR addr6;
365 const bool isV6 = (::InetPtonW(AF_INET6, overrideDnsIpAddress.c_str(), &addr6) == 1);
366
367 // DNS_INTERFACE_SETTINGS::NameServer is PWSTR; copy into a non-const buffer so we
368 // don't const_cast away the std::wstring's immutability.
369 std::wstring nameServer = overrideDnsIpAddress;
370 DNS_INTERFACE_SETTINGS settings = {};
371 settings.Version = DNS_INTERFACE_SETTINGS_VERSION1;
372 settings.Flags = DNS_SETTING_NAMESERVER | (isV6 ? DNS_SETTING_IPV6 : 0);
373 settings.NameServer = nameServer.data();
374
375 ret = pSetInterfaceDnsSettings(guid, &settings);
376 if (ret != NO_ERROR) {
377 spdlog::error(L"setCustomDnsWhileConnected: SetInterfaceDnsSettings failed for ifIndex={} dns=\"{}\" ({})", ifIndex, overrideDnsIpAddress, ret);
378 return serializeResult(false);
379 }
380
381 spdlog::debug(L"setCustomDnsWhileConnected: ifIndex={} dns={}", ifIndex, overrideDnsIpAddress);
382 return serializeResult(true);
383 }
384 catch (const std::system_error &ex) {
385 // SetInterfaceDnsSettings unavailable on this OS — fall through to the netsh path below.
386 spdlog::debug("setCustomDnsWhileConnected: SetInterfaceDnsSettings API unavailable ({}), falling back to netsh", ex.what());
387 }
388

Callers

nothing calls this directly

Calls 7

deserializeParsFunction · 0.85
serializeResultFunction · 0.85
to_wstringFunction · 0.85
isValidIpAddressFunction · 0.70
getSystemDirFunction · 0.70
dataMethod · 0.45
executeBlockingCmdMethod · 0.45

Tested by

no test coverage detected