Documentation
¶
Index ¶
- Constants
- Variables
- type Addr
- type Conn
- func (c *Conn) Close() (err error)
- func (c *Conn) LocalAddr() net.Addr
- func (c *Conn) PacketHeader() (byte, bool)
- func (c *Conn) Read(b []byte) (n int, err error)
- func (c *Conn) ReadPacket() ([]byte, error)
- func (c *Conn) RemoteAddr() net.Addr
- func (*Conn) SetDeadline(time.Time) error
- func (*Conn) SetReadDeadline(time.Time) error
- func (*Conn) SetWriteDeadline(time.Time) error
- func (c *Conn) Write(b []byte) (n int, err error)
- type Credentials
- type Dialer
- type ICEServer
- type ListenConfig
- type Listener
- type Notifier
- 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 ErrSignalingStopped = errors.New("nethernet: Notifier stopped")
ErrSignalingStopped is notified to Notifier by Signaling through [Notifier.NotifyError] when the function returned by [Signaling.Notify] has been called to stop receiving notifications. Once ErrSignalingStopped is notified, the Notifier will no longer receive notifications, and the underlying Listener or Dialer should be closed or returned.
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 uint64 // 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 'ReliableDataChannel' 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) 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) LocalAddr ¶
LocalAddr returns an Addr that includes the local network ID of the Conn with locally-gathered ICE candidates.
func (*Conn) PacketHeader ¶
PacketHeader always returns 0 and false as no header is prefixed before packets.
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) 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) 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 'listener' 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 uint64, signaling Signaling) (*Conn, error)
DialContext establishes a Conn with a remote network referenced by the ID. The Signaling implementation may be used to signal an offer and local ICE candidates, and to notify Signals of SignalTypeAnswer and SignalTypeCandidate signaled from the remote connection. The context.Context may be used to cancel the connection as soon as possible. If the context.Context is done, and context.Context.Err returns context.DeadlineExceeded, it signals back a Signal of SignalTypeError with ErrorCodeInactivityTimeout or ErrorCodeNegotiationTimeoutWaitingForAccept based on the progress. 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 Notifier ¶
type Notifier interface { // NotifySignal notifies the Signal to the Notifier. It is called by Signaling when a Signal // has been signaled from the remote network denoted in [Signal.NetworkID]. NotifySignal(signal *Signal) // NotifyError notifies the error to the Notifier. If the error is ErrSignalingStopped, the // Dialer will return immediately, and the Listener will close itself. NotifyError(err error) }
Notifier receives notifications from Signaling.
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 uint64 }
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]. Signal(signal *Signal) error // Notify registers a Notifier to receive notifications for signals and errors. It returns // a function to stop receiving notifications on Notifier. Once the stopping function is called, // ErrSignalingStopped will be notified to the Notifier, and the underlying negotiator should // handle the error by closing or returning. Notify(n Notifier) (stop func()) // 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() uint64 // 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.