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.RoutingBasicItem for global defaults
  • RoutingItem for 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

  1. Apply Global Defaults: Domain strategy, final outbound tags, and DNS resolver settings are populated from RoutingBasicItem.

  2. Process User-Defined Rules: Enabled RulesItem entries are transformed into core-specific objects (RulesItem4Ray for V2Ray, Rule4Sbox for Singbox) via GenRoutingUserRule().

  3. Resolve Special Cases: Load balancers, Tun mode, sniffing, DNS hijacking, and resolve rules are handled through conditional branches.

  4. 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 resolution
  • rules: List of Rule4Sbox objects

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) via ParseV2Domain()
  • IP parsing: Maps to geoip, ip_cidr, ip_is_private via ParseV2Address()
  • 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:

  • Config object with routing basics
  • RoutingItem for 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: V2rayRoutingService generates routing objects with domainStrategy and RulesItem4Ray, while SingboxRoutingService generates route objects with final tags, default_domain_resolver, and Rule4Sbox.
  • 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →