Architecture of the Routing Service for V2Ray and Singbox Cores in v2rayN
The v2rayN client unifies routing configuration for V2Ray and Singbox cores through a context-driven pipeline that translates global UI settings into core-specific JSON schemas via dedicated routing services.
The architecture of the routing service for V2Ray and Singbox cores in v2rayN enables seamless switching between proxy engines while maintaining a consistent user experience. This system abstracts the distinct routing schemas of V2Ray and Singbox behind a unified configuration model, transforming user-defined rules from the global Config object into executable JSON configurations tailored to each core's requirements.
High-Level Routing Workflow Common to Both Cores
Both V2rayRoutingService and SingboxRoutingService implement a six-stage pipeline that processes routing configuration through the CoreConfigContext transport layer.
Context Gathering and Initialization
The CoreConfigContext class carries all runtime configuration objects to the routing services:
Config.RoutingBasicItemfor global defaultsRoutingItemfor profile-specific rules- DNS configuration items (
SimpleDnsItem,RawDnsItem)
Each service initializes its core-specific routing object: V2Ray uses _coreConfig.routing while Singbox uses _coreConfig.route.
Configuration Generation Pipeline
-
Apply Global Defaults: Domain strategy, final outbound tags, and DNS resolver settings are populated from
RoutingBasicItem. -
Process User-Defined Rules: Enabled
RulesItementries are transformed into core-specific objects (RulesItem4Rayfor V2Ray,Rule4Sboxfor Singbox) viaGenRoutingUserRule(). -
Resolve Special Cases: Load balancers, Tun mode, sniffing, DNS hijacking, and resolve rules are handled through conditional branches.
-
Finalize: The populated configuration object is serialized to JSON and passed to the core executor.
V2Ray Routing Implementation
The V2Ray routing service in v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs generates configurations following the Xray/V2Ray routing schema.
Domain Strategy Configuration
The service applies domain resolution strategies through Config.RoutingBasicItem.DomainStrategy, with profile-level overrides supported (lines 9-13):
_coreConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
if (routing?.DomainStrategy.IsNotEmpty())
_coreConfig.routing.domainStrategy = routing.DomainStrategy;
User Rule Transformation
The GenRoutingUserRule() method normalizes user-defined rules into RulesItem4Ray objects with type = "field". It processes port ranges, network protocols, domains, IP CIDRs, and process names to match V2Ray's rule format.
Load Balancer Handling
When balancer tags exist, the service remaps outbound tags to balancer tags (lines 42-47):
rulesItem.balancerTag = rulesItem.outboundTag + Global.BalancerTagSuffix;
rulesItem.outboundTag = null;
Final Catch-All Rule
The BuildFinalRule() method ensures unmatched traffic routes to the global proxy tag (Global.ProxyTag), with optional IP-only matching when DomainStrategy equals Global.IPIfNonMatch.
Singbox Routing Implementation
The Singbox routing service in v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs generates configurations for the Singbox core, which uses a distinct schema emphasizing explicit rule actions and DNS resolution.
Route Object Structure
Singbox uses _coreConfig.route containing:
final: The default outbound tag (Global.ProxyTag)default_domain_resolver: DNS server configuration for domain resolutionrules: List ofRule4Sboxobjects
DNS Resolver Integration
The service constructs the default domain resolver from DNS settings (lines 9-26):
_coreConfig.route.default_domain_resolver = new()
{
server = defaultDomainResolverTag,
strategy = directDnsStrategy
};
Tun Mode Configuration
When Tun mode is enabled (lines 31-50), the service sets auto_detect_interface = true and injects pre-packed Tun rules from TunSingboxRulesFileName:
if (_config.TunModeItem.EnableTun)
{
_coreConfig.route.auto_detect_interface = true;
// Inject Tun rules...
}
Advanced Rule Types
Singbox supports specialized rule types processed in GenRoutingUserRule():
- Domain parsing: Converts V2Ray-style domains to Singbox formats (
geosite,domain_regex,domain_suffix,domain,domain_keyword) viaParseV2Domain() - IP parsing: Maps to
geoip,ip_cidr,ip_is_privateviaParseV2Address() - Process matching: Distinguishes process name from path (Singbox only supports name matching, requiring fallback logic)
Resolve Rules
Optional resolve rules are added when RoutingBasicItem.DomainStrategy equals Global.IPIfNonMatch or IPOnDemand (lines 105-119), enabling on-demand DNS resolution for specific traffic patterns.
UI Integration and Configuration Flow
The routing architecture connects to the user interface through view models that persist settings to the global configuration object.
Routing Settings View Model
RoutingSettingViewModel.cs exposes properties that map directly to service consumption:
public string DomainStrategy { get; set; } // V2Ray
public string DomainStrategy4Singbox { get; set; } // Singbox
public ObservableCollection<RoutingItemModel> Routes { get; }
Configuration Persistence
When users save routing settings, the view model writes values to Config.RoutingBasicItem and the selected RoutingItem. These objects are later passed to the core services via CoreConfigContext.
Core Configuration Context
CoreConfigContext.cs serves as the transport layer, carrying:
Configobject with routing basicsRoutingItemfor profile-specific rules- DNS configuration items (
SimpleDnsItem,RawDnsItem)
This context enables the routing services to remain stateless while accessing all necessary configuration data.
Practical Configuration Examples
Setting V2Ray Domain Strategy
// Assume vm is an instance of RoutingSettingViewModel
vm.DomainStrategy = Global.IPIfNonMatch; // "IP-if-non-match" mode
vm.SaveCommand.Execute(null); // persist to Config.RoutingBasicItem
This affects V2rayRoutingService.GenRouting() lines 9-13, where the domain strategy is applied to _coreConfig.routing.domainStrategy.
Loading Custom Singbox Rulesets
// In the UI: user selects a JSON file that contains Singbox rules
var routing = vm.SelectedRouting; // RoutingItemModel
routing.CustomRulesetPath4Singbox = "myRuleset.json";
vm.SaveCommand.Execute(null);
During SingboxRoutingService.GenRouting() the following code loads the file:
if (routing.CustomRulesetPath4Singbox.IsNotEmpty())
{
var result = EmbedUtils.LoadResource(routing.CustomRulesetPath4Singbox);
// `result` (JSON) is deserialized into Rule4Sbox objects and appended to route.rules
}
Enabling Tun Mode for Singbox
var opt = vm.OptionSetting; // OptionSettingViewModel
opt.EnableTun = true;
vm.SaveCommand.Execute(null);
GenRouting() will set auto_detect_interface = true and inject the bundled Tun rule set (lines 31-35).
Key Source Files
| File | Role | Link |
|---|---|---|
V2rayRoutingService.cs |
Generates V2Ray routing (_coreConfig.routing) |
↗ |
SingboxRoutingService.cs |
Generates Singbox routing (_coreConfig.route) |
↗ |
RoutingSettingViewModel.cs |
UI-side model that stores global & per-profile routing settings | ↗ |
RoutingItemModel.cs |
Represents a single routing rule set (profile-level) | ↗ |
RoutingBasicItem.cs (part of Config.cs) |
Holds the default routing configuration (domain strategy, etc.) | ↗ |
Global.cs |
Central constants (Global.ProxyTag, Global.IPIfNonMatch, DNS tags, etc.) |
↗ |
CoreConfigContext.cs |
Carries all runtime objects (Config, RoutingItem, DNS items) into the core services |
↗ |
Summary
- Unified Context Pipeline: Both V2Ray and Singbox routing services consume configuration through
CoreConfigContext, enabling consistent UI interactions despite different core schemas. - Schema-Specific Generation:
V2rayRoutingServicegeneratesroutingobjects withdomainStrategyandRulesItem4Ray, whileSingboxRoutingServicegeneratesrouteobjects withfinaltags,default_domain_resolver, andRule4Sbox. - Advanced Feature Support: Both services handle complex scenarios including load balancers (V2Ray), Tun mode (Singbox), DNS resolution strategies, and process-based routing.
- Clear Separation of Concerns: UI view models (
RoutingSettingViewModel) manage user input and persistence, while core services handle JSON generation and core-specific optimizations.
Frequently Asked Questions
How does v2rayN handle different routing schemas between V2Ray and Singbox?
v2rayN abstracts routing configuration through the CoreConfigContext class, which carries global settings and profile-specific rules to dedicated services. V2rayRoutingService translates these into V2Ray's routing object with domainStrategy and rules, while SingboxRoutingService generates Singbox's route object with final outbound tags and default_domain_resolver settings.
What is the difference between domain strategy handling in V2Ray versus Singbox?
In V2Ray, the domain strategy (such as IPIfNonMatch or IPOnDemand) is set as a string property on the routing object and affects how domain rules are matched against IPs. In Singbox, domain strategy influences the default_domain_resolver configuration and determines whether resolve rules are injected into the routing ruleset to handle on-demand DNS resolution.
Can I use custom routing rulesets with Singbox in v2rayN?
Yes, v2rayN supports custom Singbox rulesets through the CustomRulesetPath4Singbox property in RoutingItemModel. When specified, SingboxRoutingService.GenRouting() loads the JSON file via EmbedUtils.LoadResource(), deserializes the content into Rule4Sbox objects, and appends them to the generated configuration's route.rules list.
How does Tun mode affect Singbox routing configuration?
When Tun mode is enabled in the options, SingboxRoutingService automatically sets auto_detect_interface = true on the route object and injects a predefined set of Tun-specific rules loaded from TunSingboxRulesFileName. This ensures traffic captured by the TUN interface is properly routed through the Singbox engine without requiring manual rule configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →