Documentation
¶
Index ¶
- Constants
- Variables
- func HandleUnconnectedMessage(packetInterface protocol.IPacket, addr *net.UDPAddr, manager *Manager)
- type Indexes
- type Manager
- type Priority
- type PriorityQueue
- type Queues
- type RawPacket
- type ReceiveWindow
- type RecoveryQueue
- func (queue *RecoveryQueue) AddRecovery(datagram *protocol.Datagram)
- func (queue *RecoveryQueue) IsRecoverable(sequenceNumber uint32) bool
- func (queue *RecoveryQueue) Recover(sequenceNumbers []uint32) ([]*protocol.Datagram, []uint32)
- func (queue *RecoveryQueue) RemoveRecovery(sequenceNumbers []uint32)
- type Session
- func (session *Session) Close()
- func (session *Session) FlagForClose()
- func (session *Session) HandleACK(ack *protocol.ACK)
- func (session *Session) HandleConnectedPing(packet *protocol.EncapsulatedPacket, timestamp int64)
- func (session *Session) HandleConnectedPong(packet *protocol.EncapsulatedPacket, timestamp int64)
- func (session *Session) HandleConnectionRequest(packet *protocol.EncapsulatedPacket)
- func (session *Session) HandleDatagram(datagram TimestampedDatagram)
- func (session *Session) HandleEncapsulated(packet *protocol.EncapsulatedPacket, timestamp int64)
- func (session *Session) HandleNACK(nack *protocol.NAK)
- func (session *Session) HandleSplitEncapsulated(packet *protocol.EncapsulatedPacket, timestamp int64)
- func (session *Session) IsClosed() bool
- func (session *Session) Send(buffer []byte) (int, error)
- func (session *Session) SendACK(sequenceNumber uint32)
- func (session *Session) SendPacket(packet protocol.IConnectedPacket, reliability byte, priority Priority)
- func (session *Session) Tick(currentTick int64)
- type SessionManager
- type TimestampedDatagram
- type UDPServer
Constants ¶
const ( // Maximum MTU size is the maximum packet size. // Any MTU size above this will get limited to the maximum. MaximumMTUSize = 1492 // MinimumMTUSize is the minimum packet size. // Any MTU size below this will get set to the minimum. MinimumMTUSize = 400 )
Variables ¶
var NotStarted = errors.New("udp server has not started")
NotStarted is an error returned for the Read and Write functions if the server has not yet been started.
Functions ¶
func HandleUnconnectedMessage ¶
func HandleUnconnectedMessage(packetInterface protocol.IPacket, addr *net.UDPAddr, manager *Manager)
HandleUnconnectedMessage handles an incoming unconnected message from a UDPAddr. A response will be made for every packet, which gets sent back to the sender. A session gets created for the sender once the OpenConnectionRequest2 gets sent.
Types ¶
type Indexes ¶
Indexes is used for the collection of indexes related to datagrams and encapsulated packets. It uses several maps and is therefore protected by a mutex.
type Manager ¶
type Manager struct { Server *UDPServer Sessions SessionManager // PongData is the data returned when the server gets an unconnected ping. PongData string // Security ensures a secure connection between a pair of systems. // Setting this to false is often the best idea for mobile devices. Security bool // Encryption encrypts all packets sent over RakNet. // Encryption should be disabled if used for Minecraft. Encryption bool // ServerId is a random ID to identify servers. It is randomly generated for each manager. ServerId int64 // Running specifies the running state of the manager. // The manager will automatically stop working if the running state is false. Running bool // CurrentTick is the current tick of the manager. This current Tick increments for every // time the manager ticks. CurrentTick int64 // TimeoutDuration is the duration after which a session gets timed out. // Timed out sessions get closed and removed immediately. // The default timeout duration is 6 seconds. TimeoutDuration time.Duration // RawPacketFunction gets called when a raw packet is processed. // The address given is the address of the sender, and the byte array the buffer of the packet. RawPacketFunction func(packet []byte, addr *net.UDPAddr) // PacketFunction gets called once an encapsulated packet is fully processed. // This function only gets called for encapsulated packets not recognized as RakNet internal packets. // A byte array argument gets passed, which is the buffer of the buffer in the encapsulated packet. PacketFunction func(packet []byte, session *Session) // ConnectFunction gets called once a session is fully connected to the server, // and packets of the game protocol start to get sent. ConnectFunction func(session *Session) // DisconnectFunction gets called with the associated session on a disconnect. // This disconnect may be either client initiated or server initiated. DisconnectFunction func(session *Session) *sync.RWMutex // contains filtered or unexported fields }
Manager manages a UDP server and its components.
func NewManager ¶
func NewManager() *Manager
NewManager returns a new Manager for a UDP Server. A random server ID gets generated.
func (*Manager) BlockIP ¶
BlockIP blocks the IP of the given UDP address, ignoring any further packets until the duration runs out.
func (*Manager) IsIPBlocked ¶
IsIPBlocked checks if the IP of a UDP address is blocked. If true, packets are not processed of the address.
func (*Manager) Start ¶
Start starts the UDP server on the given address and port. Start returns an error if any might have occurred during starting. The manager will keep processing incoming packets until it has been Stop()ed.
type Priority ¶
type Priority byte
Priority is the priority at which packets will be sent out when queued. PriorityImmediate will make packets get sent out immediately.
const ( // PriorityImmediate is the highest possible priority. // Packets with this priority get sent out immediately. PriorityImmediate Priority = iota // PriorityHigh is the highest possible priority that gets buffered. // High priority packets get sent out every tick. PriorityHigh // PriorityMedium is the priority most used. // Medium priority packets get sent out every other tick. PriorityMedium // PriorityLow is the lowest possible priority. // Low priority packets get sent out every fourth tick. PriorityLow )
type PriorityQueue ¶
type PriorityQueue chan *protocol.EncapsulatedPacket
A PriorityQueue is used to send packets with a certain priority. Encapsulated packets can be queued in these queues.
func NewPriorityQueue ¶
func NewPriorityQueue(bufferingSize int) *PriorityQueue
NewPriorityQueue returns a new priority queue with buffering size. The buffering size specifies the maximum amount of packets in the queue, and the queue becomes blocking once the amount of packets exceeds the buffering size.
func (*PriorityQueue) AddEncapsulated ¶
func (queue *PriorityQueue) AddEncapsulated(packet *protocol.EncapsulatedPacket, session *Session)
AddEncapsulated adds an encapsulated packet to a priority queue. The packet will first be split into smaller sub packets if needed, after which all packets will be added to the queue.
func (*PriorityQueue) Flush ¶
func (queue *PriorityQueue) Flush(session *Session)
Flush flushes all encapsulated packets in the priority queue, and sends them to a session. All encapsulated packets will first be fetched from the channel, after which they will be put into datagrams. A new datagram is made once an encapsulated packet makes the size of a datagram exceed the MTU size of the session.
func (*PriorityQueue) Split ¶
func (queue *PriorityQueue) Split(packet *protocol.EncapsulatedPacket, session *Session) []*protocol.EncapsulatedPacket
Split splits an encapsulated packet into smaller sub packets. Every encapsulated packet that exceeds the MTUSize of the session will be split into sub packets, and returned into a slice.
type Queues ¶
type Queues struct { Immediate *PriorityQueue High *PriorityQueue Medium *PriorityQueue Low *PriorityQueue }
Queues is a container of four priority queues. Immediate priority, high priority, medium priority and low priority queues.
func (Queues) AddEncapsulated ¶
func (queues Queues) AddEncapsulated(packet *protocol.EncapsulatedPacket, priority Priority, session *Session)
AddEncapsulated adds an encapsulated packet at the given priority. The queue gets flushed immediately if the priority is immediate priority.
type RawPacket ¶
A RawPacket is used to identify packets that do not follow the RakNet protocol. Raw packets may be of different protocols, query protocols as an example. They are simply ignored and forwarded to the managing program. Raw packets serve no purpose other than simply forwarding data.
type ReceiveWindow ¶
type ReceiveWindow struct { // DatagramHandleFunction is a function that gets called once a datagram gets released from the receive window. // A timestamped datagram gets returned with the timestamp of the time the datagram entered the receive window. DatagramHandleFunction func(datagram TimestampedDatagram) // contains filtered or unexported fields }
ReceiveWindow is a window used to hold datagrams until they're read to be released. ReceiveWindow restores the order of datagrams that arrived out of order, and sends NAKs where needed.
func NewReceiveWindow ¶
func NewReceiveWindow() *ReceiveWindow
NewReceiveWindow returns a new receive window.
func (*ReceiveWindow) AddDatagram ¶
func (window *ReceiveWindow) AddDatagram(datagram *protocol.Datagram)
AddDatagram adds a datagram to the receive window. The datagram is first encapsulated with a timestamp, and is added to a channel in order to await the next tick for further processing.
func (*ReceiveWindow) Tick ¶
func (window *ReceiveWindow) Tick()
Tick ticks the ReceiveWindow and releases any datagrams when possible. Tick also fetches all datagrams that are currently in the channel.
type RecoveryQueue ¶
A RecoveryQueue manages the recovery of lost datagrams over the connection. Datagrams get restored by the client sending a NAK. The recovery queue holds every datagram sent and releases them, once an ACK is received with the datagram's sequence number.
func NewRecoveryQueue ¶
func NewRecoveryQueue() *RecoveryQueue
NewRecoveryQueue returns a new recovery queue.
func (*RecoveryQueue) AddRecovery ¶
func (queue *RecoveryQueue) AddRecovery(datagram *protocol.Datagram)
AddRecovery adds recovery for the given datagram. The recovery will consist until an ACK gets sent by the client, and the datagram is safe to be removed.
func (*RecoveryQueue) IsRecoverable ¶
func (queue *RecoveryQueue) IsRecoverable(sequenceNumber uint32) bool
IsRecoverable checks if the datagram with the given sequence number is recoverable.
func (*RecoveryQueue) Recover ¶
func (queue *RecoveryQueue) Recover(sequenceNumbers []uint32) ([]*protocol.Datagram, []uint32)
Recover recovers all datagrams associated with the sequence numbers in the array given. Every recoverable datagram with sequence number in the array will be returned, along with an array containing all recovered sequence numbers.
func (*RecoveryQueue) RemoveRecovery ¶
func (queue *RecoveryQueue) RemoveRecovery(sequenceNumbers []uint32)
RemoveRecovery removes recovery for all sequence numbers given. Removed datagrams can not be retrieved in any way, therefore this function should only be used once the client sends an ACK to ensure arrival.
type Session ¶
type Session struct { *net.UDPAddr Manager *Manager ReceiveWindow *ReceiveWindow RecoveryQueue *RecoveryQueue // MTUSize is the maximum size of packets sent and received to and from this sessoin. MTUSize int16 // Indexes holds all datagram and encapsulated packet indexes. Indexes Indexes // Queues holds all send queues of the session. Queues Queues // ClientId is the unique client ID of the session. ClientId uint64 // CurrentPing is the current latency of the session. CurrentPing int64 // LastUpdate is the last update time of the session. LastUpdate time.Time // FlaggedForClose indicates if this session has been flagged to close. // Sessions flagged for close will be closed next tick safely. FlaggedForClose bool }
Session is a manager of a connection between the client and the server. Sessions manage everything related to packet ordering and processing.
func NewSession ¶
NewSession returns a new session with UDP address. The MTUSize provided is the maximum packet size of the session.
func (*Session) Close ¶
func (session *Session) Close()
Close removes all references of the session, and removes the capability to send and handle packets. Sessions can not be opened once closed. It is strongly unrecommended to use this function directly. Use FlagForClose instead.
func (*Session) FlagForClose ¶
func (session *Session) FlagForClose()
FlagForClose flags the session for close. It is always recommended to use this function over direct Close. Sessions flagged for close will be closed the next tick.
func (*Session) HandleACK ¶
HandleACK handles an incoming ACK packet. Recovery gets removed for every datagram with a sequence number in the ACK.
func (*Session) HandleConnectedPing ¶
func (session *Session) HandleConnectedPing(packet *protocol.EncapsulatedPacket, timestamp int64)
HandleConnectedPing handles a connected ping from the client. A pong is sent back at low priority.
func (*Session) HandleConnectedPong ¶
func (session *Session) HandleConnectedPong(packet *protocol.EncapsulatedPacket, timestamp int64)
HandleConnectedPong handles a pong reply of our own sent ping.
func (*Session) HandleConnectionRequest ¶
func (session *Session) HandleConnectionRequest(packet *protocol.EncapsulatedPacket)
HandleConnectionRequest handles a connection request from the session. A connection accept gets sent back to the client.
func (*Session) HandleDatagram ¶
func (session *Session) HandleDatagram(datagram TimestampedDatagram)
HandleDatagram handles an incoming datagram encapsulated by a timestamp. The actual receive time of the datagram can be checked.
func (*Session) HandleEncapsulated ¶
func (session *Session) HandleEncapsulated(packet *protocol.EncapsulatedPacket, timestamp int64)
HandleEncapsulated handles an encapsulated packet from a datagram. A timestamp is passed, which is the timestamp of which the datagram received in the receive window.
func (*Session) HandleNACK ¶
HandleNACK handles an incoming NACK packet. All packets requested in the NACK get resent to the client.
func (*Session) HandleSplitEncapsulated ¶
func (session *Session) HandleSplitEncapsulated(packet *protocol.EncapsulatedPacket, timestamp int64)
HandleSplitEncapsulated handles a split encapsulated packet. Split encapsulated packets are first collected into an array, and are merged once all fragments of the encapsulated packets have arrived.
func (*Session) IsClosed ¶
IsClosed checks if the session is closed. Sending and handling packets for a session is impossible once the session is closed.
func (*Session) Send ¶
Send sends the given buffer to the session over UDP. Returns an int describing the amount of bytes written, and an error if unsuccessful.
func (*Session) SendACK ¶
SendACK sends an ACK packet to the session for the given sequence number. ACKs should only be sent once a datagram is received.
func (*Session) SendPacket ¶
func (session *Session) SendPacket(packet protocol.IConnectedPacket, reliability byte, priority Priority)
SendPacket sends an external packet to a session. The reliability given will be added to the encapsulated packet. The packet will be added with the given priority. Immediate priority packets are sent out immediately.
type SessionManager ¶
SessionManager is a manager of all sessions in the Manager.
func NewSessionManager ¶
func NewSessionManager() SessionManager
NewSessionManager returns a new session manager.
func (SessionManager) GetSession ¶
func (manager SessionManager) GetSession(addr *net.UDPAddr) (*Session, bool)
GetSession returns a session by a UDP address. GetSession also returns a bool indicating success of the call.
func (SessionManager) SessionExists ¶
func (manager SessionManager) SessionExists(addr *net.UDPAddr) bool
SessionExists checks if the session manager has a session with a UDPAddr.
type TimestampedDatagram ¶
TimestampedDatagram is a datagram encapsulated by a timestamp. Every datagram added to the receive window gets its timestamp recorded immediately.
type UDPServer ¶
UDPServer is a wrapper around a UDPConn. It can be started on a given address and port, and provides functions to read and write packets to the connection.
func NewUDPServer ¶
func NewUDPServer() *UDPServer
NewUDPServer returns a new UDP server. The UDPServer will not have a default connection, and all actions executed on it before starting will fail.
func (*UDPServer) HasStarted ¶
HasStarted checks if a UDPServer has been started. No actions can be executed on the UDPServer while not started.
func (*UDPServer) Read ¶
Read reads any data from the UDP connection into the given byte array. The IP address and port of the client that sent the data will be returned, along with an error that might have occurred during reading.