qsocket

package module
v0.0.5-beta Latest Latest
Warning

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

Go to latest
Published: Jan 16, 2024 License: MIT Imports: 16 Imported by: 1

README

QSocket Go

Go library for qsocket...

Documentation

GoDoc Go Report Card

Example

Usage is really simple, qsocket.New() function simply creates a new quantum socket with given secret, it includes all the functions of standard net sockets and also implements io Read/Write. After creating a socket you need to dial the QSRN network by calling Dial* functions. Simple example below...

    qsock := qsocket.New("my-secret");  // Create a new QSocket with TLS fingerprint checking...
    qsock.Dial() // Dial using TLS and certificate fingerprint checking...
    // OR
    qsock.DialTCP() // Dial using TCP... 

After dialing the QSRN, socket is ready for read/write operations.

Documentation

Index

Constants

View Source
const (
	// QSRN_GATE is the static gate address for the QSocket network.
	QSRN_GATE = "gate.qsocket.io"
	// QSRN_TOR_GATE is the static ONION address for the QSocket network.
	QSRN_TOR_GATE = "5cah65fto4tjklhocryenlgti6bfnh4y5szjfvxeqqh3vvw2ff4uq2id.onion"
	// QSRN_GATE_TLS_PORT Default TLS port for the QSocket gate.
	QSRN_GATE_TLS_PORT = 443
	// QSRN_GATE_PORT Default TCP port for the QSocket gate.
	QSRN_GATE_PORT = 80
	// KNOCK_CHECKSUM_BASE is the constant base value for calculating knock packet checksums.
	KNOCK_CHECKSUM_BASE = 0xEE
	CRLF                = "\r\n"
)

Some global constants for These values can be changed for obfuscating the knock protocol

View Source
const (
	// ================ KNOCK RESPONSE CODES ================
	// KNOCK_SUCCESS is the knock sequence response code indicating successful connection.
	KNOCK_SUCCESS = iota // Protocol switch
	// KNOCK_FAIL is the knock sequence response code indicating no peer is listening with the given secret.
	KNOCK_FAIL
	// KNOCK_COLLISION is the knock sequence response code indicating another server is already listening with the given secret.
	KNOCK_COLLISION
)
View Source
const (
	// Tag ID for representing server mode connections.
	TAG_PEER_SRV = iota // 00000000 => Server
	// Tag ID for representing client mode connections.
	TAG_PEER_CLI
	// TAG_PEER_PROXY Tag ID for representing proxy mode connections.
	TAG_PEER_PROXY

	SRP_BITS = 4096
)
View Source
const (
	TAG_OS_UNKNOWN = iota
	TAG_OS_LINUX
	TAG_OS_DARWIN
	TAG_OS_WINDOWS
	TAG_OS_ANDROID
	TAG_OS_IOS
	TAG_OS_FREEBSD
	TAG_OS_OPENBSD
	TAG_OS_NETBSD
	TAG_OS_JS
	TAG_OS_SOLARIS
	TAG_OS_DRAGONFLY
	TAG_OS_ILLUMOS
	TAG_OS_AIX
	TAG_OS_ZOS
	TAG_OS_NACL
	TAG_OS_PLAN9
	TAG_OS_HURD
)
View Source
const (
	TAG_ARCH_UNKNOWN = iota
	TAG_ARCH_386
	TAG_ARCH_AMD64
	TAG_ARCH_ARM64P32
	TAG_ARCH_ARM
	TAG_ARCH_ARM64
	TAG_ARCH_ARM64BE
	TAG_ARCH_ARMBE
	TAG_ARCH_LOONG64
	TAG_ARCH_MIPS
	TAG_ARCH_MIPS64
	TAG_ARCH_MIPS64LE
	TAG_ARCH_MIPS64P32
	TAG_ARCH_MIPS64P32LE
	TAG_ARCH_MIPSLE
	TAG_ARCH_PPC
	TAG_ARCH_PPC64
	TAG_ARCH_PPC64LE
	TAG_ARCH_RISCV
	TAG_ARCH_RISCV64
	TAG_ARCH_S390
	TAG_ARCH_S390X
	TAG_ARCH_SPARC
	TAG_ARCH_SPARC64
	TAG_ARCH_WASM
)

Variables

View Source
var (
	ErrFailedReadingKnockResponse = errors.New("failed reading knock response")
	ErrInvalidKnockResponse       = errors.New("invalid knock response")
	ErrKnockSendFailed            = errors.New("knock sequence send failed")
	ErrConnRefused                = errors.New("connection refused (no server listening with given secret)")

	HttpResponseRgx    = regexp.MustCompile(`^HTTP/([0-9]|[0-9]\.[0-9]) ([0-9]{1,3}) [a-z A-Z]+`)
	WebsocketAcceptRgx = regexp.MustCompile(`Sec-WebSocket-Accept: ([A-Za-z0-9+/]+={0,2})`)
)
View Source
var (
	ErrUntrustedCert          = errors.New("certificate fingerprint mismatch")
	ErrUninitializedSocket    = errors.New("socket not initiated")
	ErrQSocketSessionEnd      = errors.New("QSocket session has ended")
	ErrUnexpectedSocket       = errors.New("unexpected socket type")
	ErrInvalidIdTag           = errors.New("invalid peer ID tag")
	ErrNoTlsConnection        = errors.New("TLS socket is nil")
	ErrSocketNotConnected     = errors.New("socket is not connected")
	ErrSrpFailed              = errors.New("SRP auth failed")
	ErrSocketInUse            = errors.New("socket already dialed")
	ErrAddressInUse           = errors.New("address already in use (server secret collision)")
	ErrInvalidCertFingerprint = errors.New("invalid TLS certificate fingerprint (expected MD5)")
)

Functions

func BindSockets

func BindSockets(con1, con2 *QSocket) error

BindSockets is used for creating a full duplex channel between `con1` and `con2` sockets, effectively binding two sockets.

func CalcChecksum

func CalcChecksum(data []byte, base byte) byte

CalcChecksum calculates the modulus based checksum of the given data, modulus base is given in the base variable.

func CreateSocketChan

func CreateSocketChan(sock *QSocket) chan []byte

chanFromConn creates a channel from a Conn object, and sends everything it

Read()s from the socket to the channel.

func GetArchTag

func GetArchTag() byte

func GetOsTag

func GetOsTag() byte

Types

type KnockResponse

type KnockResponse struct {
	Success bool
	Forward bool
	Data    []byte
}

func ParseKnockResponse

func ParseKnockResponse(buf []byte) (*KnockResponse, error)

type QSocket

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

A QSocket structure contains required values for performing a knock sequence with the QSRN gate.

`Secret` value can be considered as the password for the QSocket connection, It will be used for generating a 128bit unique identifier (UID) for the connection.

`*tag` values are used internally for QoS purposes. It specifies the operating system, architecture and the type of connection initiated by the peers, the relay server uses these values for optimizing the connection performance.

func NewSocket

func NewSocket(secret string) *QSocket

NewSocket creates a new QSocket structure with the given secret. `certVerify` value is used for enabling the certificate validation on TLS connections

func (*QSocket) AddIdTag

func (qs *QSocket) AddIdTag(idTag byte) error

AddIdTag adds a peer identification tag to the QSocket.

func (*QSocket) Close

func (qs *QSocket) Close()

Close closes the QSocket connection and underlying TCP/TLS connections.

func (*QSocket) Dial

func (qs *QSocket) Dial() error

Dial creates a TLS connection to the `QSRN_GATE` on `QSRN_GATE_TLS_PORT`. Based on the `VerifyCert` parameter, certificate fingerprint validation (a.k.a. SSL pinning) will be performed after establishing the TLS connection.

func (*QSocket) DialProxy

func (qs *QSocket) DialProxy(proxyAddr string, useTls bool) error

DialProxy tries to create TCP/TLS connection to the `QSRN_GATE` using a SOCKS5 proxy. `proxyAddr` should contain a valid SOCKS5 proxy whitout the socks5:// schema. `useTls` used for enabling/disabling TLS connection.

func (*QSocket) DialTCP

func (qs *QSocket) DialTCP() error

DialTCP creates a TCP connection to the `QSRN_GATE` on `QSRN_GATE_PORT`.

func (*QSocket) GetForwardAddr

func (qs *QSocket) GetForwardAddr() string

func (*QSocket) InitClientSRP

func (qs *QSocket) InitClientSRP() ([]byte, error)

InitClientSRP performs the client SRP sequence for establishing PAKE.

func (*QSocket) InitE2ECipher

func (qs *QSocket) InitE2ECipher(key []byte) error

InitE2ECipher initiates the end-to-end encrypted stream with the given key.

func (*QSocket) InitServerSRP

func (qs *QSocket) InitServerSRP() ([]byte, error)

InitServerSRP performs the server SRP sequence for establishing PAKE.

func (*QSocket) IsClient

func (qs *QSocket) IsClient() bool

IsClient checks if the QSocket connection is initiated as a client or a server.

func (*QSocket) IsClosed

func (qs *QSocket) IsClosed() bool

IsClosed checks if the QSocket connection to the `QSRN_GATE` is ended.

func (*QSocket) IsE2E

func (qs *QSocket) IsE2E() bool

IsE2E checks if the underlying connection is E2E encrypted or not.

func (*QSocket) IsServer

func (qs *QSocket) IsServer() bool

IsClient checks if the QSocket connection is initiated as a client or a server.

func (*QSocket) IsTLS

func (qs *QSocket) IsTLS() bool

IsTLS checks if the underlying connection is TLS or not.

func (*QSocket) LocalAddr

func (qs *QSocket) LocalAddr() net.Addr

LocalAddr returns the local network address.

func (*QSocket) NewKnockSequence

func (qs *QSocket) NewKnockSequence() ([]byte, error)

NewKnockSequence generates a new knock packet with given UUID and tag values.

func (*QSocket) Read

func (qs *QSocket) Read(b []byte) (int, error)

Read reads data from the connection.

As Read calls Handshake, in order to prevent indefinite blocking a deadline must be set for both Read and Write before Read is called when the handshake has not yet completed. See SetDeadline, SetReadDeadline, and SetWriteDeadline.

func (*QSocket) RemoteAddr

func (qs *QSocket) RemoteAddr() net.Addr

RemoteAddr returns the remote network address.

func (*QSocket) SendKnockSequence

func (qs *QSocket) SendKnockSequence() (*KnockResponse, error)

SendKnockSequence sends a knock sequence to the QSRN gate with the socket properties.

func (*QSocket) SetCertFingerprint

func (qs *QSocket) SetCertFingerprint(h string) error

AddIdTag adds a peer identification tag to the QSocket.

func (*QSocket) SetE2E

func (qs *QSocket) SetE2E(v bool) error

AddIdTag adds a peer identification tag to the QSocket.

func (*QSocket) SetForwardAddr

func (qs *QSocket) SetForwardAddr(addr string)

func (*QSocket) SetReadDeadline

func (qs *QSocket) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline on the underlying connection. A zero value for t means Read will not time out.

func (*QSocket) SetWriteDeadline

func (qs *QSocket) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the write deadline on the underlying connection. A zero value for t means Write will not time out. After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. Even if write times out, it may return n > 0, indicating that some of the data was successfully written. A zero value for t means Write will not time out.

func (*QSocket) Write

func (qs *QSocket) Write(b []byte) (int, error)

Write writes data to the connection.

As Write calls Handshake, in order to prevent indefinite blocking a deadline must be set for both Read and Write before Write is called when the handshake has not yet completed. See SetDeadline, SetReadDeadline, and SetWriteDeadline.

Jump to

Keyboard shortcuts

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