relay

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: May 20, 2026 License: MIT Imports: 7 Imported by: 53

README

GOST Relay Protocol

Go Reference

Zero-dependency Go implementation of the GOST relay wire protocol (v1). Used by go-gost/gost for relay tunnel communication.

Install

go get github.com/go-gost/relay

Protocol

Fixed 4-byte header, version always 0x01.

Request:   | VER(1) | CMD/FLAGS(1) | FEALEN(2) | FEATURES(VAR) |
Response:  | VER(1) | STATUS(1)    | FEALEN(2) | FEATURES(VAR) |
Commands
Constant Value Purpose
CmdConnect 0x01 TCP forward
CmdBind 0x02 Bind listener
CmdAssociate 0x03 UDP associate
Features

Each feature has a 3-byte header: TYPE(1) + LEN(2) + DATA(VAR).

Type Payload
FeatureUserAuth (0x01) Username/password for authentication
FeatureAddr (0x02) Target address (IPv4, IPv6, or domain + port)
FeatureTunnel (0x03) 20-byte tunnel/connector ID
FeatureNetwork (0x04) 2-byte network type (TCP, UDP, IP, Unix, Serial)

Usage

package main

import (
    "bytes"
    "net"

    "github.com/go-gost/relay"
)

func main() {
    // Build a request
    req := &relay.Request{
        Version: relay.Version1,
        Cmd:     relay.CmdConnect,
        Features: []relay.Feature{
            &relay.UserAuthFeature{Username: "user", Password: "pass"},
            &relay.AddrFeature{AType: relay.AddrDomain, Host: "example.com", Port: 443},
            &relay.NetworkFeature{Network: relay.NetworkTCP},
        },
    }

    // Write to a connection
    conn, _ := net.Dial("tcp", "relay-server:8421")
    req.WriteTo(conn)

    // Read the response
    var resp relay.Response
    resp.ReadFrom(conn)
}
AddrFeature from string
var f relay.AddrFeature
f.ParseFrom("example.com:8080") // auto-detects IPv4/IPv6/domain
TunnelID / ConnectorID

Both are 20-byte value types with UUID-format string output:

tid := relay.NewTunnelID(uuidBytes)         // standard
tid := relay.NewPrivateTunnelID(uuidBytes)  // sets private flag (0x80)
tid.String() // "abababab-abab-abab-abab-abababababab"

cid := relay.NewConnectorID(uuidBytes)
cid := relay.NewUDPConnectorID(uuidBytes)   // sets UDP flag (0x01)

All setter methods (SetPrivate, SetUDP, SetWeight) return a new value — they do not mutate the receiver.

License

MIT

Documentation

Index

Constants

View Source
const (
	StatusOK                  = 0x00
	StatusBadRequest          = 0x01
	StatusUnauthorized        = 0x02
	StatusForbidden           = 0x03
	StatusTimeout             = 0x04
	StatusServiceUnavailable  = 0x05
	StatusHostUnreachable     = 0x06
	StatusNetworkUnreachable  = 0x07
	StatusInternalServerError = 0x08
)

response status list

View Source
const (
	Version1 = 0x01
)

Variables

View Source
var (
	ErrShortBuffer    = errors.New("short buffer")
	ErrBadAddrType    = errors.New("bad address type")
	ErrBadTunnelID    = errors.New("bad tunnel id")
	ErrBadConnectorID = errors.New("bad connector id")
	ErrBadNetworkID   = errors.New("bad network id")
)
View Source
var (
	ErrBadVersion = errors.New("bad version")
)

Functions

This section is empty.

Types

type AddrFeature

type AddrFeature struct {
	AType AddrType
	Host  string
	Port  uint16
	// contains filtered or unexported fields
}

AddrFeature is a relay feature,

Protocol spec:

+------+----------+----------+
| ATYP |   ADDR   |   PORT   |
+------+----------+----------+
|  1   | Variable |    2     |
+------+----------+----------+

ATYP - address type, 0x01 - IPv4, 0x03 - domain name, 0x04 - IPv6. 1 byte.
ADDR - host address, IPv4 (4 bytes), IPV6 (16 bytes) or doman name based on ATYP. For domain name, the first byte is the length of the domain name.
PORT - port number, 2 bytes.

func (*AddrFeature) Decode

func (f *AddrFeature) Decode(b []byte) error

func (*AddrFeature) Encode

func (f *AddrFeature) Encode() ([]byte, error)

func (*AddrFeature) ParseFrom

func (f *AddrFeature) ParseFrom(address string) error

func (*AddrFeature) Type

func (f *AddrFeature) Type() FeatureType

type AddrType

type AddrType uint8
const (
	AddrIPv4   AddrType = 1
	AddrDomain AddrType = 3
	AddrIPv6   AddrType = 4
)

type CmdType

type CmdType uint8
const (
	CmdConnect   CmdType = 0x01
	CmdBind      CmdType = 0x02
	CmdAssociate CmdType = 0x03
	CmdMask      CmdType = 0x0F

	// FUDP is a command flag indicating that the request is UDP-oriented.
	// DEPRECATED by network feature.
	FUDP CmdType = 0x80
)

request commands

type ConnectorFlag added in v0.4.0

type ConnectorFlag uint8
const (
	ConnectorUDP ConnectorFlag = 0x01
)

type ConnectorID

type ConnectorID [20]byte

ConnectorID is an identification for tunnel connection.

+------------------+-------+--------+
|   ID   |  FLAG   |  RSV  | WEIGHT |
+------------------+-------+--------+
|   16   |    1    |   2   |    1   |
+------------------+-------+--------+

ID: 16-byte connector ID value, should be a valid UUID.
FLAG: 1-byte flag, 0x1 for UDP connector.
RSV: 2-byte reserved field.
WEIGHT: connector weight

func NewConnectorID added in v0.4.0

func NewConnectorID(v []byte) (cid ConnectorID)

func NewUDPConnectorID added in v0.4.0

func NewUDPConnectorID(v []byte) (cid ConnectorID)

func (ConnectorID) Equal added in v0.4.0

func (cid ConnectorID) Equal(x ConnectorID) bool

func (ConnectorID) ID added in v0.4.0

func (cid ConnectorID) ID() (id [connectorIDLen]byte)

func (ConnectorID) IsUDP added in v0.4.0

func (cid ConnectorID) IsUDP() bool

func (ConnectorID) IsZero added in v0.4.0

func (cid ConnectorID) IsZero() bool

func (ConnectorID) SetUDP added in v0.5.0

func (cid ConnectorID) SetUDP(udp bool) ConnectorID

func (ConnectorID) SetWeight added in v0.5.0

func (cid ConnectorID) SetWeight(weight uint8) ConnectorID

func (ConnectorID) String added in v0.4.0

func (cid ConnectorID) String() string

func (ConnectorID) Weight added in v0.5.0

func (cid ConnectorID) Weight() uint8

type Feature

type Feature interface {
	Type() FeatureType
	Encode() ([]byte, error)
	Decode([]byte) error
}

Feature represents a feature the client or server owned.

Protocol spec:

+------+----------+------+
| TYPE |  LEN  | FEATURE |
+------+-------+---------+
|  1   |   2   |   VAR   |
+------+-------+---------+

TYPE - feature type, 1 byte.
LEN - length of feature data, 2 bytes.
FEATURE - feature data.

func NewFeature

func NewFeature(t FeatureType, data []byte) (f Feature, err error)

func ReadFeature

func ReadFeature(r io.Reader) (Feature, error)

type FeatureType

type FeatureType uint8
const (
	FeatureUserAuth FeatureType = 0x01
	FeatureAddr     FeatureType = 0x02
	FeatureTunnel   FeatureType = 0x03
	FeatureNetwork  FeatureType = 0x04
)

type NetworkFeature added in v0.5.0

type NetworkFeature struct {
	Network NetworkID
}

NetworkFeature is a relay feature,

Protocol spec:

+---------------------+
|       NETWORK       |
+---------------------+
|          2          |
+---------------------+

NETWORK - 2-byte network ID.

func (*NetworkFeature) Decode added in v0.5.0

func (f *NetworkFeature) Decode(b []byte) error

func (*NetworkFeature) Encode added in v0.5.0

func (f *NetworkFeature) Encode() ([]byte, error)

func (*NetworkFeature) Type added in v0.5.0

func (f *NetworkFeature) Type() FeatureType

type NetworkID added in v0.5.0

type NetworkID uint16
const (
	NetworkTCP    NetworkID = 0x0
	NetworkUDP    NetworkID = 0x1
	NetworkIP     NetworkID = 0x2
	NetworkUnix   NetworkID = 0x10
	NetworkSerial NetworkID = 0x11
)

func (NetworkID) String added in v0.5.0

func (p NetworkID) String() string

type Request

type Request struct {
	Version  uint8
	Cmd      CmdType
	Features []Feature
}

Request is a relay client request.

Protocol spec:

+-----+-------------+----+---+-----+----+
| VER |  CMD/FLAGS  | FEALEN | FEATURES |
+-----+-------------+----+---+-----+----+
|  1  |      1      |    2   |    VAR   |
+-----+-------------+--------+----------+

VER - protocol version, 1 byte.
CMD/FLAGS - command (low 4-bit) and flags (high 4-bit), 1 byte.
FEALEN - length of features, 2 bytes.
FEATURES - feature list.

func (*Request) ReadFrom

func (req *Request) ReadFrom(r io.Reader) (n int64, err error)

func (*Request) WriteTo

func (req *Request) WriteTo(w io.Writer) (n int64, err error)

type Response

type Response struct {
	Version  uint8
	Status   uint8
	Features []Feature
}

Response is a relay server response.

Protocol spec:

+-----+--------+----+---+-----+----+
| VER | STATUS | FEALEN | FEATURES |
+-----+--------+----+---+-----+----+
|  1  |    1   |    2   |    VAR   |
+-----+--------+--------+----------+

VER - protocol version, 1 byte.
STATUS - server status, 1 byte.
FEALEN - length of features, 2 bytes.
FEATURES - feature list.

func (*Response) ReadFrom

func (resp *Response) ReadFrom(r io.Reader) (n int64, err error)

func (*Response) WriteTo

func (resp *Response) WriteTo(w io.Writer) (n int64, err error)

type TunnelFeature

type TunnelFeature struct {
	ID [20]byte
}

TunnelFeature is a relay feature,

Protocol spec:

+---------------------+
| TUNNEL/CONNECTOR ID |
+---------------------+
|          20         |
+---------------------+

ID - 20-byte tunnel ID for request or connector ID for response.

func (*TunnelFeature) Decode

func (f *TunnelFeature) Decode(b []byte) error

func (*TunnelFeature) Encode

func (f *TunnelFeature) Encode() ([]byte, error)

func (*TunnelFeature) Type

func (f *TunnelFeature) Type() FeatureType

type TunnelFlag added in v0.3.0

type TunnelFlag uint8
const (
	TunnelPrivate TunnelFlag = 0x80
)

type TunnelID

type TunnelID [20]byte

TunnelID is an identification for tunnel.

+------------------+-------+--------+
|   ID   |  FLAG   |  RSV  | WEIGHT |
+------------------+-------+--------+
|   16   |    1    |   2   |    1   |
+------------------+-------+--------+

ID: 16-byte tunnel ID value, should be a valid UUID.
FLAG: 1-byte flag, 0x80 for private tunnel.
RSV: 2-byte reserved field.
WEIGHT: tunnel weight

func NewPrivateTunnelID added in v0.3.0

func NewPrivateTunnelID(v []byte) (tid TunnelID)

func NewTunnelID added in v0.3.0

func NewTunnelID(v []byte) (tid TunnelID)

func (TunnelID) Equal added in v0.3.0

func (tid TunnelID) Equal(x TunnelID) bool

func (TunnelID) ID added in v0.4.0

func (tid TunnelID) ID() (id [tunnelIDLen]byte)

func (TunnelID) IsPrivate added in v0.3.0

func (tid TunnelID) IsPrivate() bool

func (TunnelID) IsZero

func (tid TunnelID) IsZero() bool

func (TunnelID) SetPrivate added in v0.5.0

func (tid TunnelID) SetPrivate(private bool) TunnelID

func (TunnelID) SetWeight added in v0.5.0

func (tid TunnelID) SetWeight(weight uint8) TunnelID

func (TunnelID) String

func (tid TunnelID) String() string

func (TunnelID) Weight added in v0.5.0

func (tid TunnelID) Weight() uint8

type UserAuthFeature

type UserAuthFeature struct {
	Username string
	Password string
}

UserAuthFeature is a relay feature, it contains the username and password for user authentication on server side.

Protocol spec:

+------+----------+------+----------+
| ULEN |  UNAME   | PLEN |  PASSWD  |
+------+----------+------+----------+
|  1   | 0 to 255 |  1   | 1 to 255 |
+------+----------+------+----------+

ULEN - length of username field, 1 byte.
UNAME - username, variable length, 0 to 255 bytes, 0 means no username.
PLEN - length of password field, 1 byte.
PASSWD - password, variable length, 0 to 255 bytes, 0 means no password.

func (*UserAuthFeature) Decode

func (f *UserAuthFeature) Decode(b []byte) error

func (*UserAuthFeature) Encode

func (f *UserAuthFeature) Encode() ([]byte, error)

func (*UserAuthFeature) Type

func (f *UserAuthFeature) Type() FeatureType

Jump to

Keyboard shortcuts

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