Documentation
¶
Overview ¶
Package wsnet handles client and server ends of Workspace networking negotiations and protocol.
Index ¶
- Constants
- Variables
- func ConnectEndpoint(baseURL *url.URL, workspace, token string) string
- func DialICE(server webrtc.ICEServer, options *DialICEOptions) error
- func Listen(ctx context.Context, log slog.Logger, broker string, turnProxyAuthToken string) (io.Closer, error)
- func ListenEndpoint(baseURL *url.URL, token string) string
- func TURNProxyICECandidate() webrtc.ICEServer
- type BrokerMessage
- type DialChannelResponse
- type DialICEOptions
- type DialOptions
- type DialPolicy
- type Dialer
- type DialerCache
Examples ¶
Constants ¶
const ( CodeDialErr = "dial_error" CodePermissionErr = "permission_error" CodeBadAddressErr = "bad_address_error" )
Codes for DialChannelResponse.
Variables ¶
var ( // ErrMismatchedProtocol occurs when a TURN is requested to a STUN server, // or a TURN server is requested instead of TURNS. ErrMismatchedProtocol = errors.New("mismatched protocols") // ErrInvalidCredentials occurs when invalid credentials are passed to a // TURN server. This error cannot occur for STUN servers, as they don't accept // credentials. ErrInvalidCredentials = errors.New("invalid credentials") )
Functions ¶
func ConnectEndpoint ¶
ConnectEndpoint returns the Coder endpoint to dial a connection for a workspace.
func DialICE ¶
func DialICE(server webrtc.ICEServer, options *DialICEOptions) error
DialICE confirms ICE servers are dialable. Timeout defaults to 200ms.
func Listen ¶
func Listen(ctx context.Context, log slog.Logger, broker string, turnProxyAuthToken string) (io.Closer, error)
Listen connects to the broker proxies connections to the local net. Close will end all RTC connections.
func ListenEndpoint ¶
ListenEndpoint returns the Coder endpoint to listen for workspace connections.
func TURNProxyICECandidate ¶ added in v1.21.0
func TURNProxyICECandidate() webrtc.ICEServer
TURNWebSocketICECandidate returns a fake TCP relay ICEServer. It's used to trigger the ICEProxyDialer.
Types ¶
type BrokerMessage ¶ added in v1.21.0
type BrokerMessage struct {
// Dialer -> Listener
Offer *webrtc.SessionDescription `json:"offer"`
Servers []webrtc.ICEServer `json:"servers"`
TURNProxyURL string `json:"turn_proxy_url"`
// Policies denote which addresses the client can dial. If empty or nil, all
// addresses are permitted.
Policies []DialPolicy `json:"ports"`
// Listener -> Dialer
Error string `json:"error"`
Answer *webrtc.SessionDescription `json:"answer"`
// Bidirectional
Candidate string `json:"candidate"`
}
BrokerMessage is used for brokering a dialer and listener.
Dialers initiate an exchange by providing an Offer, along with a list of ICE servers for the listener to peer with.
The listener should respond with an offer, then both sides can begin exchanging candidates.
type DialChannelResponse ¶ added in v1.21.0
type DialChannelResponse struct {
Code string
Err string
// Fields are set if the code is CodeDialErr.
Net string
Op string
}
DialChannelResponse is used to notify a dial channel of a listening state. Modeled after net.OpError, and marshalled to that if Net is not "".
type DialICEOptions ¶
type DialICEOptions struct {
Timeout time.Duration
// Whether to ignore TLS errors.
InsecureSkipVerify bool
}
DialICEOptions provides options for dialing an ICE server.
type DialOptions ¶ added in v1.21.0
type DialOptions struct {
// Logger is an optional logger to use for logging mostly debug messages. If
// set to nil, nothing will be logged.
Log *slog.Logger
// ICEServers is an array of STUN or TURN servers to use for negotiation purposes.
// See: https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration/iceServers
ICEServers []webrtc.ICEServer
// TURNProxyAuthToken is used to authenticate a TURN proxy request.
TURNProxyAuthToken string
// TURNRemoteProxyURL is the URL to proxy listener TURN data through.
TURNRemoteProxyURL *url.URL
// TURNLocalProxyURL is the URL to proxy client TURN data through.
TURNLocalProxyURL *url.URL
}
DialOptions are configurable options for a wsnet connection.
type DialPolicy ¶ added in v1.21.0
type DialPolicy struct {
// If network is empty, it applies to all networks.
Network string `json:"network"`
// Host is the IP or hostname of the address. It should not contain the
// port.If empty, it applies to all hosts. "localhost", [::1], and any IPv4
// address under "127.0.0.0/8" can be used interchangeably.
Host string `json:"address"`
// If port is 0, it applies to all ports.
Port uint16 `json:"port"`
}
DialPolicy a single network + address + port combinations that a connection is permitted to use.
type Dialer ¶
type Dialer struct {
// contains filtered or unexported fields
}
Dialer enables arbitrary dialing to any network and address inside a workspace. The opposing end of the WebSocket messages should be proxied with a Listener.
func Dial ¶
Dial negotiates a connection to a listener.
Example (Basic) ¶
servers := []webrtc.ICEServer{{
URLs: []string{"turns:master.cdr.dev"},
Username: "kyle",
Credential: "pass",
CredentialType: webrtc.ICECredentialTypePassword,
}}
for _, server := range servers {
err := DialICE(server, nil)
if errors.Is(err, ErrInvalidCredentials) {
// You could do something...
}
if errors.Is(err, ErrMismatchedProtocol) {
// Likely they used TURNS when they should have used TURN.
// Or they could have used TURN instead of TURNS.
}
}
dialer, err := DialWebsocket(context.Background(), "wss://master.cdr.dev/agent/workspace/connect", &DialOptions{
ICEServers: servers,
}, nil)
if err != nil {
// Do something...
}
conn, err := dialer.DialContext(context.Background(), "tcp", "localhost:13337")
if err != nil {
// Something...
}
defer conn.Close()
// You now have access to the proxied remote port in `conn`.
func DialWebsocket ¶
func DialWebsocket(ctx context.Context, broker string, netOpts *DialOptions, wsOpts *websocket.DialOptions) (*Dialer, error)
DialWebsocket dials the broker with a WebSocket and negotiates a connection.
func (*Dialer) Candidates ¶ added in v1.21.6
Candidates returns the candidate pair that was chosen for the connection.
func (*Dialer) DialContext ¶
DialContext dials the network and address on the remote listener.
type DialerCache ¶ added in v1.21.0
type DialerCache struct {
// contains filtered or unexported fields
}
func DialCache ¶ added in v1.21.0
func DialCache(ttl time.Duration) *DialerCache
DialCache constructs a new DialerCache. The cache clears connections that: 1. Are older than the TTL and have no active user-created connections. 2. Have been closed.
func (*DialerCache) Close ¶ added in v1.21.0
func (d *DialerCache) Close() error
Close closes all cached dialers.
func (*DialerCache) Dial ¶ added in v1.21.0
func (d *DialerCache) Dial(ctx context.Context, key string, dialerFunc func() (*Dialer, error)) (*Dialer, bool, error)
Dial returns a Dialer from the cache if one exists with the key provided, or dials a new connection using the dialerFunc. The bool returns whether the connection was found in the cache or not.