Documentation
¶
Index ¶
- Constants
- Variables
- type Addr
- type Conn
- func (conn *Conn) BatchHeader() []byte
- func (conn *Conn) Close() (err error)
- func (conn *Conn) Context() context.Context
- func (conn *Conn) DisableEncryption() bool
- func (conn *Conn) Latency() time.Duration
- func (conn *Conn) LocalAddr() net.Addr
- func (conn *Conn) Read(b []byte) (n int, err error)
- func (conn *Conn) ReadPacket() ([]byte, error)
- func (conn *Conn) Receive(r MessageReliability) ([]byte, error)
- func (conn *Conn) RemoteAddr() net.Addr
- func (conn *Conn) Send(data []byte, reliability MessageReliability) (n int, err error)
- func (*Conn) SetDeadline(time.Time) error
- func (*Conn) SetReadDeadline(time.Time) error
- func (*Conn) SetWriteDeadline(time.Time) error
- func (conn *Conn) Write(b []byte) (n int, err error)
- type Credentials
- type Dialer
- type ICEServer
- type ListenConfig
- type Listener
- type MessageReliability
- type Signal
- type Signaling
Constants ¶
const ( // SignalTypeOffer is signaled by a client to request a connection to the remote host. // Signals of SignalTypeOffer typically contain a data for a local description of the connection. SignalTypeOffer = "CONNECTREQUEST" // SignalTypeAnswer is signaled by a server in response to a SignalTypeOffer. // Signals with SignalTypeAnswer typically contain a data for a local description of the host. SignalTypeAnswer = "CONNECTRESPONSE" // SignalTypeCandidate is signaled by both server and client to notify an ICE candidate to the remote // connection. It is typically sent after a SignalTypeOffer or SignalTypeAnswer. Signals with SignalTypeCandidate // typically contain a data for the ICE candidate formatted with the standard format used by the C++ // implementation of WebRTC, otherwise it may be ignored. SignalTypeCandidate = "CANDIDATEADD" // SignalTypeError is signaled by both server and client to report an error that occurred during the connection. // Signals with SignalTypeError typically contain a data of the error code, which is one of the constants // defined below. SignalTypeError = "CONNECTERROR" )
const ( ErrorCodeNone = iota ErrorCodeDestinationNotLoggedIn ErrorCodeNegotiationTimeout ErrorCodeWrongTransportVersion ErrorCodeFailedToCreatePeerConnection ErrorCodeICE ErrorCodeConnectRequest ErrorCodeConnectResponse ErrorCodeCandidateAdd ErrorCodeInactivityTimeout ErrorCodeFailedToCreateOffer ErrorCodeFailedToCreateAnswer ErrorCodeFailedToSetLocalDescription ErrorCodeFailedToSetRemoteDescription ErrorCodeNegotiationTimeoutWaitingForResponse ErrorCodeNegotiationTimeoutWaitingForAccept ErrorCodeIncomingConnectionIgnored ErrorCodeSignalingParsingFailure ErrorCodeSignalingUnknownError ErrorCodeSignalingUnicastMessageDeliveryFailed ErrorCodeSignalingBroadcastDeliveryFailed ErrorCodeSignalingMessageDeliveryFailed ErrorCodeSignalingTurnAuthFailed ErrorCodeSignalingFallbackToBestEffortDelivery ErrorCodeNoSignalingChannel ErrorCodeNotLoggedIn ErrorCodeSignalingFailedToSend )
Variables ¶
var ErrUnsupported = errors.New("nethernet: unsupported")
Functions ¶
This section is empty.
Types ¶
type Addr ¶
type Addr struct {
// ConnectionID is a unique ID assigned to a connection. It is generated by the client and
// used in Signals signaled between clients and servers to uniquely reference a specific connection.
ConnectionID uint64
// NetworkID is a unique ID for the NetherNet network.
NetworkID string
// Candidates contains a list of ICE candidates. These candidates are either gathered locally or
// signaled from a remote connection. ICE candidates are used to determine the UDP/TCP addresses
// for establishing ICE transport and can be used to determine the network address of the connection.
Candidates []webrtc.ICECandidate
// SelectedCandidate is the candidate selected to connect with the ICE transport within a Conn.
// An ICE candidate may be used to determine the UDP/TCP address of the connection. It may be nil
// if the Conn has been closed, or if the Conn has encountered an error when obtaining the selected
// ICE candidate pair.
SelectedCandidate *webrtc.ICECandidate
}
Addr represents a network address that encapsulates both local and remote connection IDs and implements net.Addr.
The Addr provides details for the unique IDs of Conn and ICE Candidates used for establishing network connectivity.
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn is an implementation of net.Conn for a peer connection between a specific remote NetherNet network/connection. Conn is safe for concurrent use by multiple goroutines except Read and ReadPacket.
A Conn represents a WebRTC peer connection using ICE, DTLS, and SCTP transports and encapsulates two data channels labeled 'ReliableDataChannel' and 'UnreliableDataChannel'. Most methods within Conn utilize the 'ReliableDataChannel', as the functionality of the 'UnreliableDataChannel' is less defined.
A Conn may be established by dialing a remote network ID using Dialer.DialContext (and other aliases), or by accepting connections from a Listener that listens on a local network.
The Conn do not utilize webrtc.PeerConnection as it does not allow creating a sdp.SessionDescription with custom.
Once established and negotiated through either Dialer or Listener, Conn handles messages sent over the 'ReliableDataChannel' (which may be read using Read or ReadPacket), and ensures closure of its WebRTC transports to confirm that all transports within Conn are closed.
func (*Conn) BatchHeader ¶
BatchHeader always returns a nil slice as no header is prefixed before packets.
func (*Conn) Close ¶
Close closes the 'ReliableDataChannel' and 'UnreliableDataChannel', then closes the SCTP, DTLS, and ICE transports of the Conn. An error may be returned using errors.Join, which contains non-nil errors encountered during closure.
func (*Conn) Context ¶ added in v1.0.1
Context returns the background context associated with the Conn. The returned context is canceled when the Conn is no longer usable. Its cancellation cause describes the reason the Conn was closed.
func (*Conn) DisableEncryption ¶
DisableEncryption always reports true as no encryption should be done on Minecraft connection. Disabling encryption is insecure and may allow attackers to replay Login packets. Servers should perform additional verification (for example, ensuring the player joined the Xbox Live multiplayer session) to confirm the client is legitimately authenticated.
func (*Conn) Latency ¶
Latency returns the current latency to the remote connection as half the Smoothed Round Trip Time (SRTT) from the statistics of the SCTP transport.
func (*Conn) LocalAddr ¶
LocalAddr returns an Addr that includes the local network ID of the Conn with locally-gathered ICE candidates.
func (*Conn) Read ¶
Read receives a message from the 'ReliableDataChannel'. The bytes of the message data are copied to the given data. An error may be returned if the Conn has been closed by Conn.Close.
func (*Conn) ReadPacket ¶
ReadPacket receives a message from the 'ReliableDataChannel' and returns the bytes. It is implemented for Minecraft read operations to avoid some bugs related to the Read method in their decoder.
func (*Conn) Receive ¶
func (conn *Conn) Receive(r MessageReliability) ([]byte, error)
Receive receives a packet in fully reconstructed state combined from multiple segments received from the data channel responsible for the MessageReliability. An error may be returned if the Conn has been closed by Conn.Close.
func (*Conn) RemoteAddr ¶
RemoteAddr returns an Addr that includes the remote network ID of the Conn with remotely-signaled ICE candidates. Candidates are atomically added when a Signal of type SignalTypeCandidate has been handled.
func (*Conn) Send ¶
func (conn *Conn) Send(data []byte, reliability MessageReliability) (n int, err error)
Send writes the data into the data channel responsible for the given MessageReliability. If the data exceeds 10,000 bytes, it is split into multiple segments. An error may be returned while writing one or more segments or the Conn has been closed by Conn.Close.
func (*Conn) SetDeadline ¶
SetDeadline is a no-op implementation of net.Conn.SetDeadline and returns ErrUnsupported.
func (*Conn) SetReadDeadline ¶
SetReadDeadline is a no-op implementation of net.Conn.SetReadDeadline and returns ErrUnsupported.
func (*Conn) SetWriteDeadline ¶
SetWriteDeadline is a no-op implementation of net.Conn.SetWriteDeadline and returns ErrUnsupported.
type Credentials ¶
type Credentials struct {
ExpirationInSeconds int `json:"ExpirationInSeconds"`
ICEServers []ICEServer `json:"TurnAuthServers"`
}
Credentials holds the configuration for ICE servers used for gathering local ICE candidates.
type Dialer ¶
type Dialer struct {
// ConnectionID is the unique ID of a Conn being established. If zero, a random value will be automatically
// set from [rand.Uint64].
ConnectionID uint64
// Log is used for logging messages at various log levels. If nil, the default [slog.Logger] will be automatically
// set from [slog.Default]. Log will be extended when a Conn is being established by [Dialer] with additional attributes
// such as the connection ID and network ID, and will have a 'src' attribute set to 'dialer' to mark that the Conn
// has been negotiated by Dialer.
Log *slog.Logger
// API specifies custom configuration for WebRTC transports and data channels. If nil, a new [webrtc.API] will be
// set from [webrtc.NewAPI]. The [webrtc.SettingEngine] of the API should not allow detaching data channels, as it requires
// additional steps on the Conn (which cannot be determined by the Conn).
API *webrtc.API
}
Dialer encapsulates options for establishing a connection with a NetherNet network through Dialer.DialContext and other aliases. It allows customizing logging, WebRTC API settings, and contexts for a negotiation.
func (Dialer) DialContext ¶
func (d Dialer) DialContext(ctx context.Context, networkID string, signaling Signaling) (_ *Conn, err error)
DialContext establishes a Conn with a remote network referenced by the ID. The Signaling is used to signal an offer with local candidates, and also to notify incoming signals received from the remote network. The context.Context may be used to cancel the connection as soon as possible. A Conn may be returned, that is ready to receive and send packets.
type ICEServer ¶
type ICEServer struct {
Username string `json:"Username"`
Password string `json:"Password"`
URLs []string `json:"Urls"`
}
ICEServer represents a single ICE server configuration, including its authentication details and connection URLs. Each server requires a username and password for authentication.
type ListenConfig ¶
type ListenConfig struct {
// Log is used for logging messages at various levels. If nil, the default [slog.Logger] will be set from
// [slog.Default]. Log will be extended when a Conn is being accepted by [Listener.Accept] with additional
// attributes such as the connection ID and network ID, and will have a 'src' attribute set to 'listener'
// to mark that the Conn has been negotiated by Listener.
Log *slog.Logger
// API specifies custom configuration for WebRTC transports and data channels. If nil, a new [webrtc.API] will
// be set from [webrtc.NewAPI]. The [webrtc.SettingEngine] of the API should not allow detaching data channels,
// as it requires additional steps on the Conn (which cannot be determined by the Conn).
API *webrtc.API
// ConnContext provides a [context.Context] for starting the ICE, DTLS, and SCTP transports of the Conn. If nil,
// a default [context.Context] with 5 seconds timeout will be used. The parent [context.Context] may be used to
// create a [context.Context] to be returned (likely using [context.WithCancel] or [context.WithTimeout]).
ConnContext func(parent context.Context, conn *Conn) context.Context
// NegotiationContext provides a [context.Context] for the negotiation. If nil, a default [context.Context]
// with 5 seconds timeout will be used. The parent [context.Context] may be used to create a [context.Context]
// to be returned (likely using [context.WithCancel] or [context.WithTimeout]). If the deadline of the context
// is exceeded, a Signal of SignalTypeError with ErrorCodeNegotiationTimeoutWaitingForAccept will be signaled back.
NegotiationContext func(parent context.Context) context.Context
}
ListenConfig encapsulates options for creating a new Listener through ListenConfig.Listen. It allows customizing logging, WebRTC API settings, and contexts for negotiations.
func (ListenConfig) Listen ¶
func (conf ListenConfig) Listen(signaling Signaling) (*Listener, error)
Listen listens on the local network ID specified by the Signaling implementation. It returns a Listener that may be used to accept established connections from Listener.Accept. Signaling will be used to notify incoming Signals from remote connections.
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener implements a NetherNet connection listener.
func (*Listener) Accept ¶
Accept waits for and returns the next Conn to the Listener. An error may be returned, if the Listener has been closed.
func (*Listener) Close ¶
Close closes the Listener, ensuring that any blocking methods will return net.ErrClosed as an error.
type MessageReliability ¶
type MessageReliability uint8
MessageReliability represents the reliability of messages sent in a data channel. It is an internal type specific to this package's implementation, and shouldn't be sent over network in any way.
const ( // MessageReliabilityReliable guarantees the ordering of messages. Currently, this is the // only reliability parameter used in the game. MessageReliabilityReliable MessageReliability = iota // MessageReliabilityUnreliable seems to be unused, and it is unclear how it // works with multiple segments as packet drops could leave the message data // in unconstructed state. // While it is technically possible to send or receive packets in this channel, // it is currently recommended to use only MessageReliabilityReliable. MessageReliabilityUnreliable )
func (MessageReliability) Parameters ¶
func (r MessageReliability) Parameters() *webrtc.DataChannelParameters
Parameters returns a webrtc.DataChannelParameters, which may be used for creating a data channel for the MessageReliability or to ensure that a data channel is valid to handle it in the Conn.
func (MessageReliability) Valid ¶
func (r MessageReliability) Valid(channel *webrtc.DataChannel) bool
Valid determines whether the webrtc.DataChannel can be safe to use in Conn. If the data channel does not have the exact same parameters returned by MessageReliability.Parameters, it will return false.
type Signal ¶
type Signal struct {
// Type indicates the type of Signal. It is one of constants defined above.
Type string
// ConnectionID is the unique ID of the connection that has sent the Signal.
// It is used by both server and client to uniquely reference the connection.
ConnectionID uint64
// Data is the actual data of the Signal, represented as a string.
Data string
// NetworkID is the internal ID used by Signaling to reference a remote network and not
// included to the String representation to be signaled to the remote network. If sent by
// a server, it represents the sender ID. If sent by a client, it represents the recipient ID.
NetworkID string
}
Signal represents a signal sent or received to negotiate a connection in NetherNet network.
func (*Signal) MarshalText ¶
MarshalText returns the bytes of a string representation returned from Signal.String.
func (*Signal) String ¶
String returns a string representation of the Signal in the format '[Signal.Type] [Signal.ConnectionID] [Signal.Data]'.
func (*Signal) UnmarshalText ¶
UnmarshalText decodes the text into the Signal. An error may be returned, if the text is invalid or does not follow the format '[Signal.Type] [Signal.ConnectionID] [Signal.Data]'.
type Signaling ¶
type Signaling interface {
// Signal sends a Signal to a remote network referenced by [Signal.NetworkID].
// The [context.Context] is used to cancel waiting for the acknowledgement from
// the signaling server as soon as possible.
Signal(ctx context.Context, signal *Signal) error
// Notify registers a channel so that can be used to receive incoming signals from remote networks.
// It also returns a function to stop receiving signals on the channel.
Notify(ch chan<- *Signal) (stop func())
// Context returns a context for Signaling that is canceled optionally with a cause when a fatal
// error has occurred on the signaling server. It is used by both Dialer and Listener to notify
// a fatal error so they can no longer listen or dial for a connection that is no longer notified.
Context() context.Context
// Credentials blocks until Credentials are received by Signaling, and returns them. If Signaling
// does not support returning Credentials, it will return nil. Credentials are typically received
// from a WebSocket connection. The [context.Context] may be used to cancel the blocking.
Credentials(ctx context.Context) (*Credentials, error)
// NetworkID returns the local network ID of Signaling. It is used by Listener to obtain its local
// network ID.
NetworkID() string
// PongData sets the server data in the format of a RakNet pong response. It is used by the Listener
// to respond to a ping request in the correct format.
PongData(b []byte)
}
Signaling implements an interface for sending and receiving Signals over a network.
