# Маршрутизация (Routing)

### Добавление профилей

Профили маршрутизации можно добавлять через:

* Буфер обмена
* Deeplink-ссылки
* QR-коды
* HTTP-заголовки (`routing`)
* Тело подписки (body)

### Типы ссылок

| Формат ссылки                   | Описание                                                          |
| ------------------------------- | ----------------------------------------------------------------- |
| `incy://routing/add/{base64}`   | Добавляет профиль; активируется после успешной загрузки геофайлов |
| `incy://routing/onadd/{base64}` | Добавляет и сразу активирует профиль                              |

> `{base64}` — JSON-профиль, закодированный в base64.

> Обратная совместимость: ссылки `://routing/add/` и `://routing/onadd/` также поддерживаются.

### Обработка ошибок

Менеджер загрузки геофайлов работает в фоновом режиме:

* Загрузки, превышающие 3 минуты, прерываются
* Сообщения об ошибках отображаются на главном экране
* Проблемные профили отмечаются красным восклицательным знаком в списке
* Проблемы исчезают после успешной загрузки файлов или удаления профиля

### HTTP-заголовок

Профиль передаётся в заголовке `routing` в base64-формате. Поддерживаются два формата:

**Формат 1 — base64 напрямую:**

```
HTTP/2 200
routing: ewogICJOYW1lIjogIlJvc2NvbVZQTiIs...
```

**Формат 2 — полная ссылка (любая схема):**

```
HTTP/2 200
routing: ://routing/onadd/ewogICJOYW1lIjogIlJvc2NvbVZQTiIs...
```

### Тело подписки

Строка маршрутизации размещается в теле подписки наряду с серверными конфигурациями:

```
vless://uuid@server1:443?security=tls#Server1
vmess://eyJhZGQiOiAic2VydmVyMi...
incy://routing/onadd/ewogICJOYW1lIjogIlJvc2NvbVZQTiIs...
```

### Обновление существующих профилей

* Профили с одинаковым полем `Name` обновляются, а не дублируются
* Поле `LastUpdated` с Unix timestamp контролирует актуальность — обновление происходит при значении большем, чем у сохранённого профиля

***

### Структура профиля

#### Пример профиля

```json
{
    "Name": "RoscomVPN",
    "GlobalProxy": "true",
    "RemoteDNSType": "DoH",
    "RemoteDNSDomain": "https://cloudflare-dns.com/dns-query",
    "RemoteDNSIP": "1.1.1.1",
    "DomesticDNSType": "DoH",
    "DomesticDNSDomain": "https://dns.google/dns-query",
    "DomesticDNSIP": "8.8.8.8",
    "Geoipurl": "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat",
    "Geositeurl": "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat",
    "DnsHosts": {
        "cloudflare-dns.com": "1.1.1.1",
        "dns.google": "8.8.8.8"
    },
    "DirectSites": ["geosite:ru"],
    "DirectIp": ["geoip:ru", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "169.254.0.0/16", "224.0.0.0/4", "255.255.255.255"],
    "ProxySites": [],
    "ProxyIp": [],
    "BlockSites": ["geosite:category-ads-all"],
    "BlockIp": [],
    "DomainStrategy": "IPIfNonMatch",
    "FakeDNS": "false"
}
```

#### Описание полей

**Основные настройки**

| Поле          | Тип    | По умолчанию | Описание                                                                                                                                         |
| ------------- | ------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Name`        | string | `"Default"`  | Имя профиля                                                                                                                                      |
| `GlobalProxy` | string | `"true"`     | `"true"` — весь трафик через прокси; `"false"` — прямое соединение. Определяет поведение при отсутствии совпадений в правилах маршрутизации      |
| `LastUpdated` | string |              | Unix timestamp. Контролирует принудительное обновление геофайлов при первом сохранении или при обновлении профиля с более новой временной меткой |

**Настройки DNS**

Система разделяет DNS-запросы на удалённые (Remote, через прокси) и локальные (Domestic, прямое соединение).

**Удалённый DNS** (для прокси-ресурсов):

| Поле              | Тип    | По умолчанию                             | Описание                                                       |
| ----------------- | ------ | ---------------------------------------- | -------------------------------------------------------------- |
| `RemoteDNSType`   | string | `"DoH"`                                  | Протокол: `DoH`, `DoU`                                         |
| `RemoteDNSDomain` | string | `"https://cloudflare-dns.com/dns-query"` | Адрес DNS-сервера (обязателен для DoH)                         |
| `RemoteDNSIP`     | string | `"1.1.1.1"`                              | IP DNS-сервера                                                 |
| `RemoteDns`       | string |                                          | Альтернативное поле для `RemoteDNSIP` (обратная совместимость) |

**Локальный DNS** (для прямых ресурсов):

| Поле                | Тип    | По умолчанию                     | Описание                                                         |
| ------------------- | ------ | -------------------------------- | ---------------------------------------------------------------- |
| `DomesticDNSType`   | string | `"DoH"`                          | Протокол: `DoH`, `DoU`                                           |
| `DomesticDNSDomain` | string | `"https://dns.google/dns-query"` | Адрес DNS-сервера                                                |
| `DomesticDNSIP`     | string | `"8.8.8.8"`                      | IP DNS-сервера                                                   |
| `DomesticDns`       | string |                                  | Альтернативное поле для `DomesticDNSIP` (обратная совместимость) |

**Дополнительные DNS-настройки:**

| Поле       | Тип    | Описание                                                                                                        |
| ---------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| `DnsHosts` | object | Ручные DNS-записи (аналог файла hosts). Формат: `{"domain": "ip"}`                                              |
| `FakeDNS`  | string | `"true"` — подставляет виртуальные IP вместо реальных, чтобы Xray обрабатывал все запросы согласно конфигурации |

**Правила маршрутизации**

Трафик распределяется по трём категориям:

| Поле          | Тип       | Описание                                          |
| ------------- | --------- | ------------------------------------------------- |
| `DirectSites` | string\[] | Домены/категории для прямого доступа (без прокси) |
| `DirectIp`    | string\[] | IP-адреса и подсети для прямого доступа           |
| `ProxySites`  | string\[] | Домены/категории, направляемые через прокси       |
| `ProxyIp`     | string\[] | IP-адреса и подсети через прокси                  |
| `BlockSites`  | string\[] | Блокируемые домены/категории (реклама, трекеры)   |
| `BlockIp`     | string\[] | Блокируемые IP-адреса и подсети                   |

Правила поддерживают гео-категории (`geosite:ru`, `geoip:ru`), конкретные домены и IP/CIDR-подсети.

**Геофайлы**

| Поле         | Тип    | Описание                         |
| ------------ | ------ | -------------------------------- |
| `Geoipurl`   | string | URL для скачивания `geoip.dat`   |
| `Geositeurl` | string | URL для скачивания `geosite.dat` |

**Стратегия маршрутизации**

Поле `DomainStrategy` определяет порядок проверки правил:

| Значение       | Описание                                                                           |
| -------------- | ---------------------------------------------------------------------------------- |
| `AsIs`         | Домены передаются как есть, без DNS-резолва                                        |
| `IPIfNonMatch` | Сначала проверка по домену; если не совпало — резолв DNS и проверка по IP-правилам |
| `IPOnDemand`   | Всегда резолвит домены в IP перед проверкой правил                                 |

***

### Геофайлы: оптимизированное скачивание

Геофайлы (`geoip.dat`, `geosite.dat`) скачиваются с URL, указанных в профиле. Для экономии трафика используется хеш-проверка.

#### Алгоритм

1. Скачивается `{filename}.sha256` (несколько байт) с того же URL
2. Если хеш совпадает с сохранённым **и** файл существует локально → скачивание пропускается (даже при ручном обновлении)
3. Если файл `.sha256` недоступен → fallback на сравнение временных меток `LastUpdated`
4. Полный файл скачивается → вычисляется SHA-256 → файл заменяется
5. Новый хеш сохраняется в профиле

#### Рекомендация для провайдеров

Размещайте файл `geoip.dat.sha256` и `geosite.dat.sha256` рядом с геофайлами. Файл должен содержать только hex-строку SHA-256 хеша (64 символа). Это позволит клиентам пропускать скачивание неизменившихся файлов и экономить трафик.

Пример содержимого `geoip.dat.sha256`:

```
38c25fea171323e0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4
```

***

### Обрезка геофайлов (chunk files)

Полные geoip/geosite файлы весят десятки мегабайт. Если профиль использует только ограниченное подмножество `geoip:`/`geosite:` тегов, клиент может обрезать скачанные файлы до реально нужных записей.

#### Поле профиля

| Поле            | Тип     | Описание                                                                                                               |
| --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
| `useChunkFiles` | boolean | Если `true` — клиент вызывает внутреннее `CutGeoData()` после скачивания и оставляет только упомянутые в правилах теги |

* **По умолчанию** `false` на всех платформах — обратная совместимость со старыми профилями.
* **Android / iOS** реализуют обрезку через встроенный Go-модуль `incycore.CutGeoData()` (protobuf-парсинг geoip/geosite и выброс лишних записей).
* **Desktop (Linux / Windows)** пока использует полные файлы — `useChunkFiles` игнорируется; процесс xray работает с неукороченными `.dat`.
* После обрезки хеш пересчитывается локально и сохраняется в профиле — повторное скачивание не запустится, пока исходный `.sha256` на сервере не сменится.

#### Когда использовать

Включите, если:

* В `proxy` / `direct` / `block` используется мало геотегов (например, только `geoip:ru`, `geoip:cn`, `geosite:google`).
* Пользователи жалуются на память при загрузке тяжёлых списков.

Не включайте, если:

* Профиль использует много тегов — обрезка не даст выигрыша.
* Есть кастомные geosite-файлы с нестандартным layout — клиент может не распознать структуру.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://incy.gitbook.io/docs/dokumentaciya-dlya-razrabotchikov/marshrutizaciya-routing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
