multiserver

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 17, 2021 License: MIT Imports: 22 Imported by: 0

README

multiserver

Minetest reverse proxy supporting multiple servers and media multiplexing

Installation

Go 1.15 or higher is required

go get github.com/HimbeerserverDE/multiserver

cd ~/go/src/github.com/HimbeerserverDE/multiserver/multiserver

go build

Updating

go get -u github.com/HimbeerserverDE/multiserver

cd ~/go/src/github.com/HimbeerserverDE/multiserver/multiserver

go build

How to use

Note: This shouldn't be used with existing minetest servers without moving authentication data (not the database files) to the proxy and then deleting the auth databases on the minetest servers! Not doing so can cause proxy <-> mt_server authentication to fail.

Running

The go build command will create an executable file in ~/go/src/github.com/HimbeerserverDE/multiserver/multiserver/multiserver. This file should always be run from the same working directory. If you don't do this, the program will be unable to read the old data and will create the default files in the new working directory.

Configuration

The configuration file is located in WORKING_DIR/config/multiserver.yml

  • Default config file
host: "0.0.0.0:33000"
player_limit: -1
servers:
  lobby:
    address: "127.0.0.1:30000"
default_server: lobby
force_default_server: true

host

Type: String
Description: The IP address and port the proxy will be running on

player_limit

Type: Integer
Description: Maximum number of concurrent connections, unlimited if the value is negative

servers

Type: Dictionary
Description: List of all servers

servers.*

Type: Dictionary
Description: Contains server details

servers.*.address

Type: String
Description: The IP address and port this server is running on

servers.*.priv

Type: String
Description: If this is set, players need this privilege (on the proxy) to connect to this server.
Leave this empty to require no special privilege. Note that this only affects the #server command. This means that
players can still be connected to this server if it is the default server, a minetest server requests it
or if a different command is used.

default_server

Type: String
Description: Name of the minetest server new players are sent to

force_default_server

Type: Boolean
Description: If this is false known players are sent to the last server they were connected to, not to the default server

admin

Type: String
Description: The "privs" privilege is granted to the player with this name on startup

Documentation

Overview

Package multiserver provides features for building a multi-server reverse proxy for the minetest network protocol

Index

Constants

View Source
const (
	AuthMechSRP      = 0x00000002
	AuthMechFirstSRP = 0x00000004
)
View Source
const (
	ChatCommandPrefix       = "#"
	ServerChatCommandPrefix = ":"
)
View Source
const (
	ToClientHello                 = 0x02
	ToClientAuthAccept            = 0x03
	ToClientAcceptSudoMode        = 0x04
	ToClientDenySudoMode          = 0x05
	ToClientAccessDenied          = 0x0A
	ToClientBlockdata             = 0x20
	ToClientAddNode               = 0x21
	ToClientRemoveNode            = 0x22
	ToClientInventory             = 0x27
	ToClientTimeOfDay             = 0x29
	ToClientCsmRestrictionFlags   = 0x2A
	ToClientPlayerSpeed           = 0x2B
	ToClientMediaPush             = 0x2C
	ToClientChatMessage           = 0x2F
	ToClientActiveObjectRemoveAdd = 0x31
	ToClientActiveObjectMessages  = 0x32
	ToClientHp                    = 0x33
	ToClientMovePlayer            = 0x34
	ToClientFov                   = 0x36
	ToClientDeathscreen           = 0x37
	ToClientMedia                 = 0x38
	ToClientTooldef               = 0x39
	ToClientNodedef               = 0x3A
	ToClientCraftitemdef          = 0x3B
	ToClientAnnounceMedia         = 0x3C
	ToClientItemdef               = 0x3D
	ToClientPlaySound             = 0x3F
	ToClientStopSound             = 0x40
	ToClientPrivileges            = 0x41
	ToClientInventoryFormspec     = 0x42
	ToClientDetachedInventory     = 0x43
	ToClientShowFormspec          = 0x44
	ToClientMovement              = 0x45
	ToClientSpawnParticle         = 0x46
	ToClientAddParticlespawner    = 0x47
	ToClientHudAdd                = 0x49
	ToClientHudRm                 = 0x4A
	ToClientHudChange             = 0x4B
	ToClientHudSetFlags           = 0x4C
	ToClientHudSetParam           = 0x4D
	ToClientBreath                = 0x4E
	ToClientSetSky                = 0x4F
	ToClientOverrideDayNightRatio = 0x50
	ToClientLocalPlayerAnimations = 0x51
	ToClientEyeOffset             = 0x52
	ToClientDeleteParticlespawner = 0x53
	ToClientCloudParams           = 0x54
	ToClientFadeSound             = 0x55
	ToClientUpdatePlayerList      = 0x56
	ToClientModchannelMsg         = 0x57
	ToClientModchannelSignal      = 0x58
	ToClientNodeMetaChanged       = 0x59
	ToClientSetSun                = 0x5A
	ToClientSetMoon               = 0x5B
	ToClientSetStars              = 0x5C
	ToClientSrpBytesSB            = 0x60
	ToClientFormspecPrepend       = 0x61
	ToClientMinimapModes          = 0x62
)
View Source
const (
	ToServerInit            = 0x02
	ToServerInit2           = 0x11
	ToServerModchannelJoin  = 0x17
	ToServerModchannelLeave = 0x18
	ToServerModchannelMsg   = 0x19
	ToServerPlayerPos       = 0x23
	ToServerGotblocks       = 0x24
	ToServerDeletedblocks   = 0x25
	ToServerInventoryAction = 0x31
	ToServerChatMessage     = 0x32
	ToServerDamage          = 0x35
	ToServerPlayerItem      = 0x37
	ToServerRespawn         = 0x38
	ToServerInteract        = 0x39
	ToServerRemovedSounds   = 0x3A
	ToServerNodeMetaFields  = 0x3B
	ToServerInventoryFields = 0x3C
	ToServerRequestMedia    = 0x40
	ToServerClientReady     = 0x43
	ToServerFirstSrp        = 0x50
	ToServerSrpBytesA       = 0x51
	ToServerSrpBytesM       = 0x52
)
View Source
const (
	AccessDeniedWrongPassword = iota
	AccessDeniedUnexpectedData
	AccessDeniedSingleplayer
	AccessDeniedWrongVersion
	AccessDeniedWrongCharsInName
	AccessDeniedWrongName
	AccessDeniedTooManyUsers
	AccessDeniedEmptyPassword
	AccessDeniedAlreadyConnected
	AccessDeniedServerFail
	AccessDeniedCustomString
	AccessDeniedShutdown
	AccessDeniedCrash
)
View Source
const (
	// ConnTimeout is the amount of time after no packets being received
	// from a Peer that it is automatically disconnected
	ConnTimeout = 30 * time.Second

	// PingTimeout is the amount of time after no packets being sent
	// to a Peer that a CtlPing is automatically sent to prevent timeout
	PingTimeout = 5 * time.Second
)
View Source
const (
	// protoID + src PeerID + channel number
	MtHdrSize = 4 + 2 + 1

	// rawTypeOrig
	OrigHdrSize = 1

	// rawTypeSplit + seqnum + chunk count + chunk number
	SplitHdrSize = 1 + 2 + 2 + 2

	// rawTypeRel + seqnum
	RelHdrSize = 1 + 2
)
View Source
const (
	MaxNetPktSize = 512

	MaxUnrelRawPktSize = MaxNetPktSize - MtHdrSize
	MaxRelRawPktSize   = MaxUnrelRawPktSize - RelHdrSize

	MaxRelPktSize   = (MaxRelRawPktSize - SplitHdrSize) * math.MaxUint16
	MaxUnrelPktSize = (MaxUnrelRawPktSize - SplitHdrSize) * math.MaxUint16
)
View Source
const ChannelCount = 3

ChannelCount is the maximum channel number + 1

Variables

View Source
var ErrAlreadyConnected = errors.New("already connected to server")
View Source
var ErrAuthFailed = errors.New("authentication failure")
View Source
var ErrChNoTooBig = errors.New("can't send pkt: channel number >= ChannelCount")
View Source
var ErrClosed = errors.New("use of closed peer")
View Source
var ErrOutOfPeerIDs = errors.New("out of peer IDs")
View Source
var ErrPktTooBig = errors.New("can't send pkt: too big")
View Source
var ErrPlayerLimitReached = errors.New("player limit reached")
View Source
var ErrServerDoesNotExist = errors.New("server doesn't exist")
View Source
var ErrServerUnreachable = errors.New("server is unreachable")

Functions

func ChatSendAll

func ChatSendAll(msg string)

ChatSendAll sends a chat message to all connected client Peers

func End

func End(crash, reconnect bool)

End disconnects (from) all Peers and stops the process

func GetConfKey

func GetConfKey(key string) interface{}

GetConfKey returns a key in the configuration

func GetPeerCount

func GetPeerCount() int

GetPeerCount reports how many client Peers are connected

func GetStorageKey

func GetStorageKey(key string) (string, error)

GetStorageKey gets an entry in the storage database

func Init

func Init(p, p2 *Peer, ignMedia, noAccessDenied bool, fin chan struct{})

Init authenticates to the server srv and finishes the initialisation process if ignMedia is true

func IsOnline

func IsOnline(name string) bool

IsOnline reports if a player is connected

func Proxy

func Proxy(src, dst *Peer)

Proxy processes and forwards packets from src to dst

func RegisterChatCommand

func RegisterChatCommand(name string, privs map[string]bool, function func(*Peer, string))

RegisterChatCommand registers a callback function that is called when a client executes the command and has the required privileges

func RegisterOnChatMessage

func RegisterOnChatMessage(function func(*Peer, string) bool)

RegisterOnChatMessage registers a callback function that is called when a client sends a chat message If a callback function returns true the message is not forwarded to the minetest server

func RegisterOnJoinPlayer

func RegisterOnJoinPlayer(function func(*Peer))

RegisterOnJoinPlayer registers a callback function that is called when a TOSERVER_CLIENT_READY pkt is received from the Peer

func RegisterOnLeavePlayer

func RegisterOnLeavePlayer(function func(*Peer))

RegisterOnLeavePlayer registers a callback function that is called when a client Peer disconnects

func RegisterOnRedirectDone

func RegisterOnRedirectDone(function func(*Peer, string, bool))

RegisterOnRedirectDone registers a callback function that is called when the Peer.Redirect method exits

func RegisterOnServerChatMessage

func RegisterOnServerChatMessage(function func(*Peer, string) bool)

RegisterOnServerChatMessage registers a callback function that is called when a server sends a chat message If a callback function returns true the message is not forwarded to the minetest clients

func RegisterServerChatCommand

func RegisterServerChatCommand(name string, function func(*Peer, string))

RegisterServerChatCommand registers a callback function that is called when a server executes the command

func SetListener

func SetListener(l *Listener)

SetListener is used to make a listener available globally This can only be done once

func SetStorageKey

func SetStorageKey(key, value string) error

SetStorageKey sets an entry in the storage database

Types

type Listener

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

func GetListener

func GetListener() *Listener

GetListener returns the global listener

func Listen

func Listen(conn net.PacketConn) *Listener

Listen listens for packets on conn until it is closed

func (*Listener) Accept

func (l *Listener) Accept() (*Peer, error)

Accept waits for and returns a connecting Peer You should keep calling this until it returns ErrClosed so it doesn't leak a goroutine

func (*Listener) Conn

func (l *Listener) Conn() net.PacketConn

Addr returns the net.PacketConn the Listener is listening on

func (*Listener) GetPeerByUsername

func (l *Listener) GetPeerByUsername(name string) *Peer

GetPeerByUsername returns the Peer that is using name for authentication

func (*Listener) GetPeers

func (l *Listener) GetPeers() []*Peer

GetPeers returns an array containing all connected client Peers

type Peer

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

A Peer is a connection to a client or server

func Connect

func Connect(conn net.PacketConn, addr net.Addr) *Peer

Connect connects to the server on conn and closes conn when the Peer disconnects

func (*Peer) Addr

func (p *Peer) Addr() net.Addr

Addr returns the address of the peer

func (*Peer) CheckPrivs

func (p *Peer) CheckPrivs(req map[string]bool) (bool, error)

CheckPrivs reports if the Peer has all ofthe specified privileges

func (*Peer) Close

func (p *Peer) Close() error

Close closes the Peer but does not send a disconnect packet

func (*Peer) Conn

func (p *Peer) Conn() net.PacketConn

Conn returns the net.PacketConn used to communicate with the Peer

func (*Peer) Disco

func (p *Peer) Disco() <-chan struct{}

Disco returns a channel that is closed when the Peer is closed

func (*Peer) Forward

func (p *Peer) Forward() bool

Forward reports whether the Proxy func should continue or stop

func (*Peer) GetPrivs

func (p *Peer) GetPrivs() (map[string]bool, error)

GetPrivs returns the privileges of the Peer

func (*Peer) ID

func (p *Peer) ID() PeerID

ID returns the ID of the Peer

func (*Peer) IsSrv

func (p *Peer) IsSrv() bool

IsSrv reports whether the Peer is a server

func (*Peer) Recv

func (p *Peer) Recv() (Pkt, error)

Recv receives a packet from the Peer You should keep calling this until it returns ErrClosed so it doesn't leak a goroutine

func (*Peer) Redirect

func (p *Peer) Redirect(newsrv string) error

Redirect sends the Peer to the minetest server named newsrv

func (*Peer) Send

func (p *Peer) Send(pkt Pkt) (ack <-chan struct{}, err error)

Send sends a packet to the Peer It returns a channel that's closed when all chunks are acked or an error The ack channel is nil if pkt.Unrel is true

func (*Peer) SendChatMsg

func (p *Peer) SendChatMsg(msg string)

SendChatMsg sends a chat message to the Peer if it isn't a server

func (*Peer) SendDisco

func (p *Peer) SendDisco(chno uint8, unrel bool) (ack <-chan struct{}, err error)

SendDisco sends a disconnect packet to the Peer but does not close it It returns a channel that's closed when it's acked or an error The ack channel is nil if unrel is true

func (*Peer) Server

func (p *Peer) Server() *Peer

Server returns the Peer this Peer is connected to if it isn't a server

func (*Peer) ServerName

func (p *Peer) ServerName() string

ServerName returns the name of the Peer this Peer is connected to if this Peer is not a server

func (*Peer) SetPrivs

func (p *Peer) SetPrivs(privs map[string]bool) error

SetPrivs sets the privileges for the Peer

func (*Peer) SetServer

func (p *Peer) SetServer(s *Peer)

SetServer sets the Peer this Peer is connected to if this Peer is not a server

func (*Peer) TimedOut

func (p *Peer) TimedOut() bool

TimedOut reports whether the Peer has timed out

func (*Peer) Username

func (p *Peer) Username() string

Username returns the username of the Peer if it isn't a server

type PeerID

type PeerID uint16

PeerIDs aren't actually used to identify peers, network addresses are, these just exist for backwards compatibility

const (
	// Used by clients before the server sets their ID
	PeerIDNil PeerID = iota

	// The server always has this ID
	PeerIDSrv

	// Lowest ID the server can assign to a client
	PeerIDCltMin
)

type Pkt

type Pkt struct {
	Data  []byte
	ChNo  uint8
	Unrel bool
}

type PktError

type PktError struct {
	Type string // "net", "raw" or "rel"
	Data []byte
	Err  error
}

A PktError is an error that occured while processing a packet

func (PktError) Error

func (e PktError) Error() string

func (PktError) Unwrap

func (e PktError) Unwrap() error

type TrailingDataError

type TrailingDataError []byte

A TrailingDataError reports a packet with trailing data, it doesn't stop a packet from being processed

func (TrailingDataError) Error

func (e TrailingDataError) Error() string

Directories

Path Synopsis
Multiserver is a multi-server minetest reverse proxy capable of media multiplexing
Multiserver is a multi-server minetest reverse proxy capable of media multiplexing

Jump to

Keyboard shortcuts

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