native

package
v4.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package native implements part of the forward package's v2 routes in the package itself, on the kernel's forward tables adopted in place (kernel.storage.adopt): v2_forward, v2_forward_tunnel, v2_forward_user_tunnel, v2_speed_limit, v2_forward_rule and v2_forward_latency_bucket. Legacy handlers and native routes share the tables, so a route can switch between them at any time. Responses are byte-compatible with the legacy handlers (internal/tests/forwardcompat).

A route is native only when it neither changes what a node runs nor touches state the kernel keeps in memory: its writes leave the rows the kernel's handlers would, and the kernel's forward runtime re-reads them. Every route that pushes a forward or rule to a node (NodeX, the local Ansible executor or a clean agent), probes the network, authenticates an agent or accounts traffic stays bridged; the host's route map says why for each one.

Other domains, and the forward data that holds credentials, are read through kernel views only:

  • kapi_forward_node_v1: the forward nodes without their API tokens. v2_forward_node, v2_forward_clean_agent and v2_forward_runtime_job hold agent credentials and are protected kernel tables;
  • kapi_forward_runtime_settings_v1: the three system configuration keys that choose the forward runtime backend, no other row of the protected v2_system_config;
  • kapi_user_directory_v1, whether a user exists, and kapi_subscriber_entitlement_v1, a subscriber's speed limit.

The administrator's traffic reset of a subscriber (POST /api/v2/user/reset, type 1) goes through the kernel's KernelSubscriber.ResetTraffic (kernel.subscriber.traffic.v1); the package never writes v2_user.

Index

Constants

View Source
const (
	SpeedLimitCreateRouteID  = "forward.speed_limit.create.post"
	SpeedLimitListRouteID    = "forward.speed_limit.list.post"
	SpeedLimitDeleteRouteID  = "forward.speed_limit.delete.post"
	SpeedLimitTunnelsRouteID = "forward.speed_limit.tunnels.post"
)

Route ids of the speed limit routes with a native handler. The update stays bridged: it re-applies the forwards of every permission that names the limit on their nodes.

View Source
const ResetRouteID = "forward.user.reset.post"

ResetRouteID is the administrator's traffic reset, the one route that needs KernelSubscriber.

Variables

This section is empty.

Functions

func ResetRequestID

func ResetRequestID(userID uint64, token string) string

ResetRequestID names an administrator's subscriber traffic reset through POST /api/v2/user/reset in Control's subscriber request ledger, so a retried request is applied once. token identifies the HTTP request: its Idempotency-Key, else its request id. The kernel's legacy handler derives the same id (service.ForwardUserResetRequestID), so a retry is recognized whichever side serves it; a new request is a new reset, as in v2.

Types

type DirectoryUser

type DirectoryUser struct {
	ID uint `gorm:"primaryKey"`
}

DirectoryUser is the part of a kapi_user_directory_v1 row the routes read: that the user exists.

func (DirectoryUser) TableName

func (DirectoryUser) TableName() string

TableName is the kernel view.

type Entitlement

type Entitlement struct {
	ID         uint `gorm:"primaryKey"`
	SpeedLimit *int64
}

Entitlement is the part of a kapi_subscriber_entitlement_v1 row the routes read: the subscriber's speed limit.

func (Entitlement) TableName

func (Entitlement) TableName() string

TableName is the kernel view.

type Forward

type Forward struct {
	ID                uint    `gorm:"primaryKey"`
	UserID            uint    `gorm:"index;not null"`
	UserName          string  `gorm:"size:255"`
	Name              string  `gorm:"size:100;not null"`
	TunnelID          uint    `gorm:"index;not null"`
	Tunnel            *Tunnel `gorm:"foreignKey:TunnelID"`
	InPort            int     `gorm:"not null"`
	OutPort           int
	RemoteAddr        string `gorm:"type:text;not null"`
	InterfaceName     string `gorm:"size:255"`
	Strategy          string `gorm:"size:20;default:'fifo'"`
	Status            int    `gorm:"default:1"`
	RuntimeBackend    string `gorm:"size:50;default:'gost';index"`
	RuntimeStatus     int    `gorm:"default:0;index"`
	RuntimeMessage    string `gorm:"type:text"`
	RuntimeLastSyncAt *time.Time
	InFlow            int64 `gorm:"default:0"`
	OutFlow           int64 `gorm:"default:0"`
	Inx               int   `gorm:"default:0"`
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

Forward is a v2_forward row.

func (Forward) TableName

func (Forward) TableName() string

TableName is the adopted kernel table.

type LatencyBucket

type LatencyBucket struct {
	ID              uint `gorm:"primaryKey"`
	TargetKey       string
	TargetType      string
	TargetID        uint
	Label           string
	Host            string
	Port            int
	BucketAt        time.Time
	IntervalSeconds int
	SampleCount     int
	SuccessCount    int
	MinRTT          float64
	AvgRTT          float64
	MaxRTT          float64
	P95RTT          float64
	LossPct         float64
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

LatencyBucket is a v2_forward_latency_bucket row, written by the kernel's latency prober.

func (LatencyBucket) TableName

func (LatencyBucket) TableName() string

TableName is the adopted kernel table.

type Node

type Node struct {
	ID      uint   `gorm:"primaryKey" json:"id"`
	Name    string `json:"name"`
	Type    string `json:"type"`
	Host    string `json:"host"`
	Port    int    `json:"port"`
	APIPort int    `json:"api_port"`
	// APIToken is never read; answers to users show it empty.
	APIToken      string    `gorm:"-" json:"api_token"`
	MetricsPort   int       `json:"metrics_port"`
	Region        string    `json:"region"`
	ISP           string    `json:"isp"`
	Datacenter    string    `json:"datacenter"`
	Bandwidth     int64     `json:"bandwidth"`
	Status        int       `json:"status"`
	LastCheck     time.Time `json:"last_check"`
	Latency       int       `json:"latency"`
	Load          float64   `json:"load"`
	Uptime        float64   `json:"uptime"`
	Tags          string    `json:"tags"`
	Weight        int       `json:"weight"`
	MaxConn       int       `json:"max_conn"`
	Enabled       bool      `json:"enabled"`
	TotalUpload   int64     `json:"total_upload"`
	TotalDownload int64     `json:"total_download"`
	CurrentConn   int       `json:"current_conn"`
	CreatedAt     time.Time `json:"created_at"`
	UpdatedAt     time.Time `json:"updated_at"`
}

Node is a row of kapi_forward_node_v1: a forward node without its API token, which authenticates the node's agent and stays in the protected v2_forward_node. Its JSON is the kernel model's.

func (Node) TableName

func (Node) TableName() string

TableName is the kernel view.

type Rule

type Rule struct {
	ID           uint       `gorm:"primaryKey" json:"id"`
	Name         string     `gorm:"size:100;not null" json:"name"`
	Enabled      bool       `gorm:"default:true" json:"enabled"`
	RelayNodeID  uint       `gorm:"not null" json:"relay_node_id"`
	RelayNode    *Node      `gorm:"foreignKey:RelayNodeID" json:"relay_node,omitempty"`
	ListenPort   int        `gorm:"not null" json:"listen_port"`
	Protocol     string     `gorm:"size:10;default:'tcp'" json:"protocol"`
	ExitNodeID   uint       `gorm:"not null" json:"exit_node_id"`
	ExitNode     *Node      `gorm:"foreignKey:ExitNodeID" json:"exit_node,omitempty"`
	TargetHost   string     `gorm:"size:255;not null" json:"target_host"`
	TargetPort   int        `gorm:"not null" json:"target_port"`
	UserID       *uint      `json:"user_id"`
	UserGroupID  *uint      `json:"user_group_id"`
	AllowedIPs   string     `gorm:"size:1000" json:"allowed_ips"`
	SpeedLimit   *int64     `json:"speed_limit"`
	TrafficLimit *int64     `json:"traffic_limit"`
	ExpireTime   *time.Time `json:"expire_time"`
	Upload       int64      `json:"upload"`
	Download     int64      `json:"download"`
	Connections  int        `json:"connections"`
	TotalConns   int64      `json:"total_conns"`
	Remark       string     `gorm:"size:500" json:"remark"`
	CreatedAt    time.Time  `json:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at"`
}

Rule is a v2_forward_rule row, as the legacy answers show it: with its relay and exit nodes when they are loaded, and never its user.

func (Rule) TableName

func (Rule) TableName() string

TableName is the adopted kernel table.

type RuntimeSetting

type RuntimeSetting struct {
	Key   string
	Value string
}

RuntimeSetting is a row of kapi_forward_runtime_settings_v1: one of the system configuration keys that choose the forward runtime backend.

func (RuntimeSetting) TableName

func (RuntimeSetting) TableName() string

TableName is the kernel view.

type Service

type Service struct {
	// Open returns the package's storage connection, on which the adopted
	// tables and the granted views are visible.
	Open func(ctx context.Context) (*gorm.DB, error)
	// Subscriber is the kernel's KernelSubscriber; without it the traffic
	// reset has no native handler and stays legacy.
	Subscriber Subscriber
	// NewToken identifies a reset request that has neither an
	// Idempotency-Key nor a request id; it defaults to a random UUID.
	NewToken func() string
	// Now defaults to time.Now.
	Now func() time.Time
}

Service holds what the native routes need.

func (*Service) AssignUserTunnel

func (s *Service) AssignUserTunnel(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

AssignUserTunnel is POST /api/v2/tunnel/user/assign and its administrator route: it lets a user create forwards on a tunnel. A permission alone runs nothing on a node, so nothing is pushed; whether the user exists is read from kapi_user_directory_v1.

func (*Service) CreateSpeedLimit

func (s *Service) CreateSpeedLimit(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

CreateSpeedLimit is POST /api/v2/speed-limit/create: a named speed limit for a tunnel, which no permission uses yet, so nothing runs on a node.

func (*Service) CreateTunnel

CreateTunnel is POST /api/v2/admin/tunnel/create. A tunnel alone runs nothing on a node: forwards do, so nothing is pushed. Its nodes are read through kapi_forward_node_v1.

func (*Service) DeleteSpeedLimit

func (s *Service) DeleteSpeedLimit(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

DeleteSpeedLimit is POST /api/v2/speed-limit/delete: a speed limit no permission uses, so no forward runs with it.

func (*Service) DeleteTunnel

DeleteTunnel is POST /api/v2/admin/tunnel/delete: a tunnel no forward and no user permission uses, so no node runs anything for it.

func (*Service) Handlers

func (s *Service) Handlers() map[string]pluginhostsdk.NativeHandler

Handlers returns the native handlers by route id.

func (*Service) ListAdminTunnels

ListAdminTunnels is POST /api/v2/admin/tunnel/list: every tunnel.

func (*Service) ListForwards

ListForwards is POST /api/v2/forward/list (the caller's forwards) and POST /api/v2/admin/forward/list; an administrator sees every forward.

func (*Service) ListSpeedLimits

ListSpeedLimits is POST /api/v2/speed-limit/list: every speed limit by id.

func (*Service) ListTunnels

ListTunnels is POST /api/v2/tunnel/user/tunnel and its administrator route: the active tunnels the caller may use (every one for an administrator), as far as they suit the configured runtime backend.

func (*Service) ListUserTunnels

ListUserTunnels is POST /api/v2/tunnel/user/list and its administrator route: a user's tunnel permissions. As in the kernel, a permission's traffic catches up with its forwards' totals first. The speed is the permission's speed limit, else the subscriber's own (kapi_subscriber_entitlement_v1).

func (*Service) MultiIngressLatency

func (s *Service) MultiIngressLatency(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

MultiIngressLatency is GET /api/v2/admin/forward/observability/multi-ingress: for a forward, the latest ingress latency of every tunnel that reaches the same exit node, from the latency prober's buckets.

func (*Service) ResetFlow

ResetFlow is POST /api/v2/user/reset, the administrator's Flux-style reset: type 1 zeroes a subscriber's traffic through KernelSubscriber.ResetTraffic, type 2 a tunnel permission's traffic and that of the permission's forwards. Neither changes what a node runs.

func (*Service) SpeedLimitTunnels

func (s *Service) SpeedLimitTunnels(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

SpeedLimitTunnels is POST /api/v2/speed-limit/tunnels: the tunnels a speed limit may name, every active one as for an administrator, as far as they suit the configured runtime backend.

func (*Service) Stats

Stats is GET /api/v2/admin/forward/stats: the enabled relay and exit nodes, how many are online, and their traffic, from kapi_forward_node_v1.

func (*Service) UpdateForwardOrder

func (s *Service) UpdateForwardOrder(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

UpdateForwardOrder is POST /api/v2/forward/update-order and its administrator route: it sets the display order (inx) of the caller's forwards, or of any forward for an administrator. The order is not part of what a node runs, so nothing is pushed.

func (*Service) UserRules

UserRules is GET /api/v2/user/forward/rules: the caller's forward rules with their relay and exit nodes, which kapi_forward_node_v1 shows without their API tokens; the answer's api_token is empty, as the kernel's is.

type SpeedLimit

type SpeedLimit struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	CreatedTime int64  `gorm:"index;not null" json:"createdTime"`
	UpdatedTime int64  `gorm:"index;not null" json:"updatedTime"`
	Status      int    `gorm:"default:1" json:"status"`
	Name        string `gorm:"size:100;not null" json:"name"`
	Speed       int64  `gorm:"not null" json:"speed"`
	TunnelID    uint   `gorm:"index;not null" json:"tunnelId"`
	TunnelName  string `gorm:"size:100;not null" json:"tunnelName"`
}

SpeedLimit is a v2_speed_limit row: a tunnel's named speed limit, which the /speed-limit routes manage. Its fields and tags match the kernel model, so answers are the same.

func (SpeedLimit) TableName

func (SpeedLimit) TableName() string

TableName is the adopted kernel table.

type Subscriber

type Subscriber interface {
	ResetTraffic(ctx context.Context, in *kernelsubscriberv1.ResetTrafficRequest, opts ...grpc.CallOption) (*kernelsubscriberv1.ResetTrafficResponse, error)
}

Subscriber is the part of KernelSubscriber the native routes call.

type Tunnel

type Tunnel struct {
	ID            uint   `gorm:"primaryKey"`
	Name          string `gorm:"size:100;not null"`
	InNodeID      uint   `gorm:"index"`
	OutNodeID     *uint  `gorm:"index"`
	InIP          string `gorm:"size:255"`
	OutIP         string `gorm:"size:255"`
	InNodePortSta *int
	InNodePortEnd *int
	Type          int     `gorm:"default:1"`
	Flow          int     `gorm:"default:2"`
	Protocol      string  `gorm:"size:30;default:'tcp'"`
	TrafficRatio  float64 `gorm:"default:1"`
	InterfaceName string  `gorm:"size:255"`
	TCPListenAddr string  `gorm:"size:255;default:'0.0.0.0'"`
	UDPListenAddr string  `gorm:"size:255;default:'0.0.0.0'"`
	Status        int     `gorm:"default:1"`
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

Tunnel is a v2_forward_tunnel row.

func (Tunnel) TableName

func (Tunnel) TableName() string

TableName is the adopted kernel table.

type UserTunnel

type UserTunnel struct {
	ID            uint  `gorm:"primaryKey"`
	UserID        uint  `gorm:"uniqueIndex:idx_forward_user_tunnel"`
	TunnelID      uint  `gorm:"uniqueIndex:idx_forward_user_tunnel;index"`
	Flow          int64 `gorm:"default:0"`
	Num           int   `gorm:"default:0"`
	InFlow        int64 `gorm:"default:0"`
	OutFlow       int64 `gorm:"default:0"`
	FlowResetTime int64 `gorm:"default:0"`
	ExpTime       int64 `gorm:"default:0"`
	SpeedID       *uint
	Status        int `gorm:"default:1"`
	CreatedAt     time.Time
	UpdatedAt     time.Time

	Tunnel *Tunnel `gorm:"foreignKey:TunnelID"`
}

UserTunnel is a v2_forward_user_tunnel row: a user's permission to use a tunnel, with its quota and traffic.

func (UserTunnel) TableName

func (UserTunnel) TableName() string

TableName is the adopted kernel table.

Jump to

Keyboard shortcuts

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