spec

package
v0.0.0-...-f701b90 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2025 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

This package implements several different functions and types that are common to both the client and the server, and strictly follows the protocol specification.

Please refer to the Implementation and the Specification for more information:

Index

Constants

View Source
const (
	ProtocolVersion  uint8  = 1                  // Current version of the protocol
	NullOp           Action = 0                  // Invalid operation code
	NullID           ID     = 0                  // Only valid for specific documented cases
	MaxID            ID     = 1<<10 - 1          // Maximum value according to the bit field
	EmptyInfo        byte   = 0xFF               // No information provided
	HeaderSize       int    = 8                  // Max size of the header in bytes
	MaxArgs          int    = (1 << 4) - 1       // Max amount of arguments
	MaxPayload       int    = (1 << 14) - 1      // Max amount of total arguments size
	MaxArgSize       int    = (1 << 11) - 1      // Max amount of single argument size
	RSABitSize       int    = 4096               // Size of the RSA keypair used by the spec crypto functions
	UsernameSize     int    = 32                 // Max size of a username in bytes
	LoginTimeout     int    = 2                  // Timeout for a handshake process in minutes
	ReadTimeout      int    = 25                 // Timeout for a TCP read block in minutes
	HandshakeTimeout int    = 20                 // Timeout for a connection handshake block in seconds
	TokenExpiration  int    = 30                 // Deadline for a reusable token expiration in minutes
	UsernameRegex    string = "^[0-9a-z]{0,32}$" // To check if a username is valid
)

Variables

View Source
var (
	ErrorUndefined    error = SpecError{0x00, "ERR_UNDEFINED", "undefined problem occured"}             // undefined problem occured
	ErrorInvalid      error = SpecError{0x01, "ERR_INVALID", "invalid operation performed"}             // invalid operation performed
	ErrorNotFound     error = SpecError{0x02, "ERR_NOTFOUND", "content can not be found"}               // content can not be found
	ErrorVersion      error = SpecError{0x03, "ERR_VERSION", "server and client versions do not match"} // server and client versions do not match
	ErrorHandshake    error = SpecError{0x04, "ERR_HANDSHAKE", "handshake process failed"}              // handshake process failed
	ErrorArguments    error = SpecError{0x05, "ERR_ARGS", "invalid arguments given"}                    // invalid arguments given
	ErrorMaxSize      error = SpecError{0x06, "ERR_MAXSIZE", "data size is too big"}                    // data size is too big
	ErrorHeader       error = SpecError{0x07, "ERR_HEADER", "invalid header provided"}                  // invalid header provided
	ErrorNoSession    error = SpecError{0x08, "ERR_NOSESS", "user is not connected"}                    // user is not connected
	ErrorLogin        error = SpecError{0x09, "ERR_LOGIN", "user can not be logged in"}                 // user can not be logged in
	ErrorConnection   error = SpecError{0x0A, "ERR_CONN", "connection problem occured"}                 // connection problem occured
	ErrorEmpty        error = SpecError{0x0B, "ERR_EMPTY", "queried data is empty"}                     // queried data is empty
	ErrorPacket       error = SpecError{0x0C, "ERR_PACKET", "packet could not be delivered"}            // packet could not be delivered
	ErrorPrivileges   error = SpecError{0x0D, "ERR_PERMS", "missing privileges to run"}                 // missing privileges to run
	ErrorServer       error = SpecError{0x0E, "ERR_SERVER", "server operation failed"}                  // server operation failed
	ErrorIdle         error = SpecError{0x0F, "ERR_IDLE", "user has been idle for too long"}            // user has been idle for too long
	ErrorExists       error = SpecError{0x10, "ERR_EXISTS", "content already exists"}                   // content already exists
	ErrorDeregistered error = SpecError{0x11, "ERR_DEREG", "user has been deleted"}                     // user has been deleted
	ErrorDupSession   error = SpecError{0x12, "ERR_DUPSESS", "session exists in another endpoint"}      // session exists in another endpoint
	ErrorUnsecure     error = SpecError{0x13, "ERR_NOSECURE", "secured connection required"}            // secure connection required
	ErrorCorrupted    error = SpecError{0x14, "ERR_CORRUPTED", "queried data is currupted"}             // queried data is corrupted
	ErrorOption       error = SpecError{0x15, "ERR_OPTION", "invalid option provided"}                  // invalid option provided
	ErrorDisconnected error = SpecError{0x16, "ERR_DISCN", "connection was manually closed"}            // connection manually closed
)

Array with all possible existing hooks for easier traversal

Functions

func AdminArgs

func AdminArgs(a Admin) int

Returns the amount of arguments the hook should have Result is -1 if not found

func AdminString

func AdminString(a Admin) string

Returns the admin string asocciated to a hex byte. Result is an empty string if not found.

func BytesToPermission

func BytesToPermission(perm []byte) (uint, error)

Reads a byte array corresponding to the permission argument of a command and returns the unsigned integer asocciated to said array or an error if the reading failed.

func BytesToUnixStamp

func BytesToUnixStamp(b []byte) (t time.Time, e error)

Turns a byte slice into a time type by reading it as a unix timestamp, according to the size specified by the time package.

func ClientArgs

func ClientArgs(a Action) int

Returns the minimum amount of arguments needed to send to the client. Result is -1 if it cannot be sent to the client.

func CodeToString

func CodeToString(a Action) string

Returns the string associated to an operation code. Result is an empty string if not found.

func DecryptText

func DecryptText(e []byte, priv *rsa.PrivateKey) ([]byte, error)

Decrypts a cyphertext using a private key and the OAEP method with SHA256.

func EncryptText

func EncryptText(t []byte, pub *rsa.PublicKey) ([]byte, error)

Encrypts a text using a public key and the OAEP method with SHA256.

func ErrorCode

func ErrorCode(err error) byte

Returns the error asocciated to a hex byte. Result is EmptyInfo if not found.

func ErrorCodeToError

func ErrorCodeToError(b byte) error

Returns the hex byte asocciated to an error. Result is nil if not found.

func ErrorString

func ErrorString(err error) string

Returns the formal error string as defined by the implementation. If the provided error is not a spec error an empty string is returned.

func HookArgs

func HookArgs(h Hook) int

Returns the amount of arguments the hook should have Result is -1 if not found

func HookString

func HookString(h Hook) string

Returns the hook string asocciated to a hex byte. Result is an empty string if not found.

func IDToCode

func IDToCode(a Action) byte

Returns the hex byte asocciated to an operation code. Result is 0x0 if not found.

func NewPacket

func NewPacket(op Action, id ID, inf byte, arg ...[]byte) ([]byte, error)

Creates a packet ready to be sent through a TCP connection with all header fields, arguments, and delimiters. Arguments are optional and an error will be returned if any of the function parameters are malformed.

func PEMToPrivkey

func PEMToPrivkey(privPEM []byte) (*rsa.PrivateKey, error)

Gets the private RSA key from a PEM byte array using the PKCS1 format.

func PEMToPubkey

func PEMToPubkey(pubPEM []byte) (*rsa.PublicKey, error)

Gets the public RSA key from a PEM byte array using the PKIX format.

func PermissionToBytes

func PermissionToBytes(perm uint) []byte

func PrivkeytoPEM

func PrivkeytoPEM(privkey *rsa.PrivateKey) []byte

Turns an RSA private key into a PEM byte array using the PKCS1 format.

func PubkeytoPEM

func PubkeytoPEM(pubkey *rsa.PublicKey) ([]byte, error)

Turn an RSA public key into a PEM byte array using the PKIX format.

func ServerArgs

func ServerArgs(a Action) int

Returns the minimum amount of arguments needed to send to the server. Result is -1 if it cannot be sent to the server.

func UnixStampToBytes

func UnixStampToBytes(s time.Time) []byte

Turns a time type into its unix timestamp as a byte slice, following the size specified by the Unix() function of the time package.

func UserlistString

func UserlistString(u Userlist) string

Types

type Action

type Action uint8

Specifies an operation to be performed.

const (
	OK Action = iota + 1
	ERR
	KEEP
	REG
	DEREG
	LOGIN
	LOGOUT
	VERIF
	REQ
	USRS
	MSG
	RECIV
	SHTDWN
	ADMIN
	SUB
	UNSUB
	HOOK
	HELLO
)

The integer follows the actual binary value of the operation.

func CodeToID

func CodeToID(b byte) Action

Returns the operation code associated to a hex byte. Result is NullOp if not found.

func StringToCode

func StringToCode(s string) Action

Returns the action code associated to a string. Result is NullOp if not found.

type Admin

type Admin uint8

Specifies an admin operation to be performed

const (
	AdminShutdown    Admin = 0x00 // Send a shutdown signal to the server
	AdminDeregister  Admin = 0x01 // Force the deregistration of a user
	AdminBroadcast   Admin = 0x02 // Broadcast a message to all online users
	AdminChangePerms Admin = 0x03 // Increase the permission level of a user
	AdminDisconnect  Admin = 0x04 // Disconnect an online user
	AdminMotd        Admin = 0x05 // Changes the MOTD of the server
)

type Command

type Command struct {
	HD   Header   // Packet header
	Args [][]byte // Packet arguments
}

Specifies a command together with header and arguments.

func ParsePacket

func ParsePacket(p []byte) Command

Returns the command asocciated to a byte slice without doing any additional checks. This is mostly meant for debugging purposes and not actual packet reading..

func (*Command) CheckArgs

func (cmd *Command) CheckArgs() error

Checks the arguments of a command to validate sizes.

func (*Command) Contents

func (cmd *Command) Contents() string

Returns a string that contains full information about a command

func (*Command) ListenHeader

func (cmd *Command) ListenHeader(cl Connection) error

Factory method that reads from a connection and modifies the header values of the command accordingly.

func (*Command) ListenPayload

func (cmd *Command) ListenPayload(cl Connection) error

Factory method that reads from a connection and modifies the arguments of the command accordingly.

type Connection

type Connection struct {
	Conn net.Conn // TCP connection
	TLS  bool     // Whether it is connected through TLS
}

Identifies a TCP established connection that can be communicated with using a buffered reader that is assigned to the connection when using the NewConnection() method.

Note that a established connection does not imply a logged in user.

func NewConnection

func NewConnection(cl net.Conn, tls bool) Connection

Returns a new TCP connection with a buffered reader and TLS information using the connection from the net package as a base.

type Header struct {
	Ver  uint8  // Protocol version
	Op   Action // Operation to be performed
	Info uint8  // Additional pacjet information
	Args uint8  // Amount of arguments
	Len  uint16 // Total length of all arguments
	ID   ID     // Packet identifier
}

Identifies the header of a packet split into its fields depending on the bit size of each field.

func NewHeader

func NewHeader(hdr []byte) Header

Splits a byte slice into the fields of a header.

func (Header) ClientCheck

func (hd Header) ClientCheck() error

Checks the validity of the header fields Follows the specification of commands sent to the client.

func (Header) ServerCheck

func (hd Header) ServerCheck() error

Checks the validity of the header fields Follows the specification of commands sent to the server.

type Hook

type Hook uint8

Specifies a hook that triggers on a specific event

const (
	HookAllHooks         Hook = 0x00 // Subscribe or unsubscribe to all existing hooks
	HookNewLogin         Hook = 0x01 // Triggers when a user comes online
	HookNewLogout        Hook = 0x02 // Triggers when a user goes offline
	HookDuplicateSession Hook = 0x03 // Triggers when a session for the user is opened from another endpoint
	HookPermsChange      Hook = 0x04 // Triggers when a user's permission level changes
)

type ID

type ID uint16

Specifies the identifier of the packet that has been sent.

type Message

type Message struct {
	Sender  string    // Person that sent the message
	Content []byte    // Encrypted content
	Stamp   time.Time // Specifies when the message was sent
}

Specifies a message that can be sent between clients and that is either sent directly through the server or stored in the database.

type SpecError

type SpecError struct {
	Code        uint8
	Text        string
	Description string
}

Error that implements the error interface from the errors package with specific information that follows the protocol specification.

func (SpecError) Error

func (err SpecError) Error() string

Returns the text asocciated to the error.

type Userlist

type Userlist uint8

Specifies the user option for the command

const (
	UsersAll         Userlist = 0x0
	UsersOnline      Userlist = 0x1
	UsersAllPerms    Userlist = 0x2
	UsersOnlinePerms Userlist = 0x3
)

Jump to

Keyboard shortcuts

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