|
34 | 34 | #include <ziti/ziti_log.h> |
35 | 35 | #include <netioapi.h> |
36 | 36 | #include <stdlib.h> |
37 | | -#include <combaseapi.h> |
38 | 37 | #include <ziti/model_support.h> |
39 | 38 |
|
40 | 39 | #include "tun.h" |
@@ -437,43 +436,71 @@ int tun_del_route(netif_handle tun, const char *dest) { |
437 | 436 | return 0; |
438 | 437 | } |
439 | 438 |
|
| 439 | +static bool update_default_route(void) { |
| 440 | + PMIB_IPFORWARD_TABLE2 table; |
| 441 | + ULONG rc = GetIpForwardTable2(AF_INET, &table); |
| 442 | + if (rc != NO_ERROR) { |
| 443 | + char err[256]; |
| 444 | + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), |
| 445 | + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 446 | + err, sizeof(err), NULL); |
| 447 | + ZITI_LOG(WARN, "failed to get forward table: %lu(%s)", rc, err); |
| 448 | + return false; |
| 449 | + } |
| 450 | + |
| 451 | + MIB_IPFORWARD_ROW2 *best_rt = NULL; |
| 452 | + |
| 453 | + // Find 0.0.0.0/0 route with the lowest metric |
| 454 | + for (ULONG i = 0; i < table->NumEntries; i++) { |
| 455 | + MIB_IPFORWARD_ROW2 *rt = &table->Table[i]; |
| 456 | + |
| 457 | + if (rt->DestinationPrefix.PrefixLength == 0 && |
| 458 | + rt->DestinationPrefix.Prefix.Ipv4.sin_family == AF_INET) { |
| 459 | + |
| 460 | + if (best_rt == NULL || rt->Metric < best_rt->Metric) { |
| 461 | + best_rt = rt; |
| 462 | + } |
| 463 | + } |
| 464 | + } |
| 465 | + |
| 466 | + bool changed = false; |
| 467 | + if (best_rt) { |
| 468 | + if (default_rt.InterfaceIndex != best_rt->InterfaceIndex || default_rt.Metric != best_rt->Metric) { |
| 469 | + ZITI_LOG(INFO, "default route is now via if_idx[%lu], metric=%lu", |
| 470 | + best_rt->InterfaceIndex, best_rt->Metric); |
| 471 | + memcpy(&default_rt, best_rt, sizeof(MIB_IPFORWARD_ROW2)); |
| 472 | + changed = true; |
| 473 | + } |
| 474 | + } else { |
| 475 | + ZITI_LOG(WARN, "no default route found"); |
| 476 | + } |
| 477 | + |
| 478 | + FreeMibTable(table); |
| 479 | + return changed; |
| 480 | +} |
| 481 | + |
440 | 482 | static void WINAPI if_change_cb(PVOID CallerContext, PMIB_IPINTERFACE_ROW Row, MIB_NOTIFICATION_TYPE NotificationType) { |
441 | 483 | struct netif_handle_s *tun = CallerContext; |
442 | 484 |
|
443 | | - MIB_IPFORWARD_ROW2 rt = {0}; |
444 | | - rt.DestinationPrefix.Prefix.Ipv4.sin_family = AF_INET; |
445 | | - ZITI_LOG(DEBUG, "interface change: if_idx = %d, change = %d", Row ? Row->InterfaceIndex : 0, NotificationType); |
446 | | - int rc = GetIpForwardEntry2(&rt); |
447 | | - if (rc == NO_ERROR) { |
448 | | - if (default_rt.InterfaceIndex != rt.InterfaceIndex) { |
449 | | - ZITI_LOG(INFO, "default route is now via if_idx[%d]", rt.InterfaceIndex); |
450 | | - default_rt.InterfaceIndex = rt.InterfaceIndex; |
451 | | - default_rt.InterfaceLuid = rt.InterfaceLuid; |
452 | | - default_rt.Metric = rt.Metric; |
453 | | - default_rt.NextHop = rt.NextHop; |
454 | | - |
455 | | - ZITI_LOG(INFO, "updating excluded routes"); |
456 | | - const char *dest; |
457 | | - MIB_IPFORWARD_ROW2 *route; |
458 | | - MODEL_MAP_FOREACH(dest, route, &tun->excluded_routes) { |
459 | | - route->NextHop = rt.NextHop; |
460 | | - route->InterfaceIndex = rt.InterfaceIndex; |
461 | | - route->InterfaceLuid = rt.InterfaceLuid; |
462 | | - if (SetIpForwardEntry2(route) != NO_ERROR) { |
463 | | - char err[256]; |
464 | | - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), |
465 | | - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
466 | | - err, sizeof(err), NULL); |
467 | | - ZITI_LOG(WARN, "failed to update route[%s]: %d(%s)", dest, rc, err); |
468 | | - } |
| 485 | + ZITI_LOG(DEBUG, "interface change: if_idx = %lu, change = %d", Row ? Row->InterfaceIndex : 0, NotificationType); |
| 486 | + bool changed = update_default_route(); |
| 487 | + if (changed) { |
| 488 | + ZITI_LOG(INFO, "updating excluded routes"); |
| 489 | + const char *dest; |
| 490 | + MIB_IPFORWARD_ROW2 *route; |
| 491 | + MODEL_MAP_FOREACH(dest, route, &tun->excluded_routes) { |
| 492 | + route->NextHop = default_rt.NextHop; |
| 493 | + route->InterfaceIndex = default_rt.InterfaceIndex; |
| 494 | + route->InterfaceLuid = default_rt.InterfaceLuid; |
| 495 | + DWORD rc = SetIpForwardEntry2(route); |
| 496 | + if (rc != NO_ERROR) { |
| 497 | + char err[256]; |
| 498 | + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, |
| 499 | + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 500 | + err, sizeof(err), NULL); |
| 501 | + ZITI_LOG(WARN, "failed to update route[%s]: %lu(%s)", dest, rc, err); |
469 | 502 | } |
470 | 503 | } |
471 | | - } else { |
472 | | - char err[256]; |
473 | | - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), |
474 | | - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
475 | | - err, sizeof(err), NULL); |
476 | | - ZITI_LOG(WARN, "failed to get default route: %d(%s)", rc, err); |
477 | 504 | } |
478 | 505 | } |
479 | 506 |
|
|
0 commit comments