# Architecture of the Routing Service for V2Ray and Singbox Cores in v2rayN

> Understand the routing service architecture unifying V2Ray and Singbox cores in v2rayN. Learn how global settings translate to core-specific JSON schemas for efficient network routing.

- Repository: [2dust/v2rayN](https://github.com/2dust/v2rayN)
- Tags: architecture
- Published: 2026-02-27

---

**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`](https://github.com/2dust/v2rayN/blob/main/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):

```csharp
_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):

```csharp
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`](https://github.com/2dust/v2rayN/blob/main/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):

```csharp
_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`:

```csharp
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`](https://github.com/2dust/v2rayN/blob/main/RoutingSettingViewModel.cs) exposes properties that map directly to service consumption:

```csharp
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`](https://github.com/2dust/v2rayN/blob/main/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

```csharp
// 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

```csharp
// 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:

```csharp
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

```csharp
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`](https://github.com/2dust/v2rayN/blob/main/V2rayRoutingService.cs) | Generates V2Ray routing (`_coreConfig.routing`) | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs) |
| [`SingboxRoutingService.cs`](https://github.com/2dust/v2rayN/blob/main/SingboxRoutingService.cs) | Generates Singbox routing (`_coreConfig.route`) | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs) |
| [`RoutingSettingViewModel.cs`](https://github.com/2dust/v2rayN/blob/main/RoutingSettingViewModel.cs) | UI-side model that stores global & per-profile routing settings | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs) |
| [`RoutingItemModel.cs`](https://github.com/2dust/v2rayN/blob/main/RoutingItemModel.cs) | Represents a single routing rule set (profile-level) | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/Models/RoutingItemModel.cs) |
| [`RoutingBasicItem.cs`](https://github.com/2dust/v2rayN/blob/main/RoutingBasicItem.cs) (part of [`Config.cs`](https://github.com/2dust/v2rayN/blob/main/Config.cs)) | Holds the default routing configuration (domain strategy, etc.) | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/Models/Config.cs) |
| [`Global.cs`](https://github.com/2dust/v2rayN/blob/main/Global.cs) | Central constants (`Global.ProxyTag`, `Global.IPIfNonMatch`, DNS tags, etc.) | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/Global.cs) |
| [`CoreConfigContext.cs`](https://github.com/2dust/v2rayN/blob/main/CoreConfigContext.cs) | Carries all runtime objects (`Config`, `RoutingItem`, DNS items) into the core services | [↗](https://github.com/2dust/v2rayN/blob/master/v2rayN/ServiceLib/Models/CoreConfigContext.cs) |

## 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.