{"record":{"id":"3d6c79e5e5cdf9e7","repo":"netchx/netch","slug":"getbestroute","errorCode":null,"errorMessage":"GetBestRoute 搜索失败","messagePattern":"GetBestRoute 搜索失败","errorType":"exception","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"Netch/Models/NetRoute.cs","lineNumber":21,"sourceCode":"\nnamespace Netch.Models;\n\npublic struct NetRoute\n{\n    public static NetRoute TemplateBuilder(string gateway, int interfaceIndex, int metric = 0)\n    {\n        return new()\n        {\n            Gateway = gateway,\n            InterfaceIndex = interfaceIndex,\n            Metric = metric\n        };\n    }\n\n    public static NetRoute GetBestRouteTemplate()\n    {\n        if (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(\"114.114.114.114\").GetAddressBytes(), 0), 0, out var route) != 0)\n            throw new MessageException(\"GetBestRoute 搜索失败\");\n\n        var gateway = new IPAddress(route.dwForwardNextHop);\n        return TemplateBuilder(gateway.ToString(), (int)route.dwForwardIfIndex);\n    }\n\n    public int InterfaceIndex;\n\n    public string Gateway;\n\n    public string Network;\n\n    public byte Cidr;\n\n    public int Metric;\n\n    public NetRoute FillTemplate(string network, byte cidr, int? metric = null)\n    {\n        var o = (NetRoute)MemberwiseClone();","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/netchx/netch/blob/9d99eb1c5a2acbf2a34f2600f94242601019a300/Netch/Models/NetRoute.cs#L3-L39","documentation":"Calls the Win32 IP Helper GetBestRoute with destination 114.114.114.114 and source 0.0.0.0 to discover the default next-hop gateway and outbound interface index, then builds a NetRoute template used by redirector/TUN routing. GetBestRoute returns a non-zero error code when no matching IPv4 route exists in the forwarding table, so this fires whenever the host has no usable IPv4 route to that destination. The thrown MessageException is not caught locally; it propagates to callers building route templates.","triggerScenarios":"NetRoute.GetBestRouteTemplate is invoked while there is no IPv4 default route: all interfaces down/disabled, no default gateway configured, airplane mode, or a VPN/TUN client that deleted the default route. Any non-zero return from PInvoke.GetBestRoute triggers it.","commonSituations":"Starting Netch with no network; Wi-Fi/Ethernet disabled; a misconfigured VPN that removed the default route; a freshly imaged machine with no gateway; a custom routing policy that blackholes 114.114.114.114.","solutions":["Enable a network interface and ensure an IPv4 default gateway is configured (verify with `route print` or `ipconfig`).","Reconnect to Wi-Fi/Ethernet and retry - the template is rebuilt each time routing is set up.","If a VPN/TUN client removed the default route, disconnect it or restore the route before starting Netch.","As a last resort add a persistent default route: `route add 0.0.0.0 mask 0.0.0.0 <gateway>` (run as admin)."],"exampleFix":"// before\nif (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(\"114.114.114.114\").GetAddressBytes(), 0), 0, out var route) != 0)\n    throw new MessageException(\"GetBestRoute 搜索失败\");\n// after - capture the error code for diagnostics\nvar rc = PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(\"114.114.114.114\").GetAddressBytes(), 0), 0, out var route);\nif (rc != 0)\n    throw new MessageException($\"GetBestRoute failed (error={rc}). Ensure an IPv4 default route exists.\");","handlingStrategy":"validation","validationCode":"// Verify an IPv4 default route exists before building the route template\nvar hasRoute = NetworkInterface.GetAllNetworkInterfaces()\n    .Where(n => n.OperationalStatus == OperationalStatus.Up)\n    .Any(n => n.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily == AddressFamily.InterNetwork));\nif (!hasRoute)\n    throw new MessageException(\"No IPv4 default route; connect to a network first.\");","typeGuard":"bool HasIpv4DefaultRoute() => NetworkInterface.GetAllNetworkInterfaces()\n    .Any(n => n.OperationalStatus == OperationalStatus.Up\n              && n.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily == AddressFamily.InterNetwork));","tryCatchPattern":"try { var template = NetRoute.GetBestRouteTemplate(); }\ncatch (MessageException ex) when (ex.Message.Contains(\"GetBestRoute\"))\n{\n    Global.MainForm.NotifyTip(\"No network route found. Connect to a network and retry.\");\n    return;\n}","preventionTips":["Gate GetBestRouteTemplate behind a connectivity check (e.g. NetworkInterface.GetIsNetworkAvailable()).","Defer route-template building until NetworkChange.NetworkAddressChanged reports an Up IPv4 interface.","Never call it during startup before network initialisation completes."],"tags":["network","routing","p-invoke","windows","getbestroute"],"backgroundTag":null,"analyzedSha":"9d99eb1c5a2acbf2a34f2600f94242601019a300","analyzedAt":"2026-08-13T14:12:19.105Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}