client

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package client реализует клиентскую половину туннеля: держит QUIC-соединение с сервером, проводит рукопожатие Noise и перекладывает пакеты между TUN и сетью.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateKeyPair added in v0.2.0

func GenerateKeyPair() (privateKey, publicKey string, err error)

GenerateKeyPair создаёт пару ключей клиента в виде строк base64.

Обёртка над noise.GenerateKey для тех, кому неудобно тянуть отдельный пакет ради одной операции, - например для мобильного фасада, где через границу проходят только простые типы.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client держит состояние подключения. Устройство создаётся один раз после первого удачного рукопожатия и переживает переподключения: так при обрыве не рушатся маршруты и сокеты приложений.

func New

func New(cfg Config, log *slog.Logger) *Client

New создаёт клиента с платформенными настройками по умолчанию.

func NewWithOptions

func NewWithOptions(cfg Config, opts Options) *Client

NewWithOptions создаёт клиента, которому устройство и настройку сети задаёт вызывающая сторона. Это точка встраивания ядра в приложение.

func (*Client) Run

func (c *Client) Run(ctx context.Context) error

Run подключается к серверу и держит туннель, переподключаясь при обрывах, пока не отменят контекст.

func (*Client) Status added in v0.2.0

func (c *Client) Status() Status

Status возвращает снимок состояния туннеля. Безопасен для вызова из любой горутины в любой момент, в том числе до запуска.

type Config

type Config struct {
	// Server - адрес сервера в виде host:port.
	Server string `json:"server"`
	// ServerKey - публичный ключ сервера. Именно он, а не TLS-сертификат,
	// определяет, с кем мы согласны разговаривать.
	ServerKey noise.PublicKey `json:"server_key"`
	// PrivateKey - статический ключ клиента; его публичная часть должна
	// быть в списке peers на сервере.
	PrivateKey noise.PrivateKey `json:"private_key"`
	// Name попадает в логи сервера, ни на что больше не влияет.
	Name string `json:"name,omitempty"`
	// TunName - имя интерфейса; пустое значение отдаёт выбор ядру.
	TunName string `json:"tun_name,omitempty"`
	// FullTunnel заворачивает в туннель весь IPv4-трафик, кроме пути до сервера.
	FullTunnel bool `json:"full_tunnel,omitempty"`
	// Routes - дополнительные подсети поверх тех, что предложил сервер.
	Routes []netip.Prefix `json:"routes,omitempty"`

	// SNI - имя, которое уедет в ClientHello открытым текстом.
	// Пустое значение означает: взять хост из Server, если это не IP-адрес.
	SNI string `json:"sni,omitempty"`

	// DNS переопределяет резолверы, предложенные сервером.
	DNS []netip.Addr `json:"dns,omitempty"`
	// KeepIPv6 оставляет исходящий IPv6 включённым при полном туннеле.
	//
	// По умолчанию он запрещается: туннель возит только IPv4, и без запрета
	// IPv6-трафик уходит мимо туннеля с настоящим адресом. Включайте, только
	// если понимаете, что тем самым возвращаете утечку.
	KeepIPv6 bool `json:"keep_ipv6,omitempty"`
	// KeepSystemDNS запрещает трогать системные настройки DNS.
	// По умолчанию клиент их меняет - иначе запросы уходят мимо туннеля
	// и выдают провайдеру всё, что вы открываете.
	KeepSystemDNS bool `json:"keep_system_dns,omitempty"`
}

Config - конфигурация клиента.

func LoadConfig

func LoadConfig(path string) (Config, error)

LoadConfig читает конфигурацию клиента из JSON-файла.

func ParseConfig added in v0.2.0

func ParseConfig(data []byte) (Config, error)

ParseConfig разбирает конфигурацию из памяти.

Нужен встраиваемым приложениям: у них конфигурация приходит из хранилища платформы или по сети, а не из файла на диске.

func (Config) SNIOrDerived

func (c Config) SNIOrDerived() string

SNIOrDerived возвращает имя для ClientHello так же, как его выбирает клиент. Нужно внешним инструментам, подключающимся тем же способом.

type Options

type Options struct {
	// Device - готовое туннельное устройство. Пусто - ядро откроет само.
	Device device.Device
	// Network - настройка системной сети. Пусто - платформенная по умолчанию.
	Network netconf.Configurator
	// Logger - журнал. Пусто - журнал отключён.
	Logger *slog.Logger
	// OnState вызывается при каждой смене состояния туннеля. Нужен тем,
	// кто показывает состояние в интерфейсе приложения.
	OnState StateFunc
	// ProtectSocket выводит сокет из-под туннеля до подключения.
	//
	// Обязателен на Android: там VpnService заворачивает в туннель весь
	// трафик приложения, включая его собственный. Без защиты пакеты QUIC
	// ушли бы в туннель, который они же и обслуживают, и подключение
	// не состоялось бы никогда. На платформах, где такой проблемы нет,
	// поле оставляют пустым.
	ProtectSocket func(fd uintptr) error
}

Options - платформенная обвязка ядра.

Оба поля можно не задавать: на Linux ядро само откроет TUN и настроит сеть. Встраивая ядро в приложение на другой платформе, передайте готовое устройство и, если систему настраивает ОС, netconf.Noop.

type State added in v0.2.0

type State int

State - в каком состоянии находится туннель.

const (
	// StateStopped - клиент не запущен либо остановлен.
	StateStopped State = iota
	// StateConnecting - идёт подключение или рукопожатие.
	StateConnecting
	// StateConnected - туннель поднят, трафик идёт.
	StateConnected
	// StateReconnecting - связь оборвалась, ждём следующей попытки.
	StateReconnecting
)

func (State) String added in v0.2.0

func (s State) String() string

String возвращает состояние в виде, пригодном и для журнала, и для показа пользователю приложения.

type StateFunc added in v0.2.0

type StateFunc func(Status)

StateFunc вызывается при каждой смене состояния.

Вызов происходит из внутренних горутин ядра, поэтому обработчик должен возвращаться быстро: долгая работа в нём задержит переподключение.

type Status added in v0.2.0

type Status struct {
	State State
	// Address - виртуальный адрес, выданный сервером. Пуст, пока не подключены.
	Address netip.Prefix
	// Server - адрес сервера из конфигурации.
	Server string
	// Interface - имя интерфейса туннеля.
	Interface string
	// MTU, применённый к интерфейсу. Может отличаться от предложенного
	// сервером, если путь не держит.
	MTU int
	// Since - когда состояние стало текущим.
	Since time.Time
	// RxBytes и TxBytes - объём расшифрованного и зашифрованного трафика
	// с момента запуска, без учёта служебных данных.
	RxBytes uint64
	TxBytes uint64
	// LastError - причина последнего обрыва. Пусто, если обрывов не было.
	LastError string
}

Status - снимок состояния туннеля.

Нужен тем, кто встраивает ядро: показать пользователю, что происходит, без разбора журнала. Все поля заполнены по состоянию на момент вызова.

func (Status) Connected added in v0.2.0

func (s Status) Connected() bool

Connected сообщает, что туннель готов передавать трафик.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL