-
Notifications
You must be signed in to change notification settings - Fork 5
/
connect.go
106 lines (89 loc) · 3.57 KB
/
connect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package connect
import (
"context"
"net"
"go.minekube.com/connect/internal/ctxkey"
)
// Well-known headers / metadata keys
const (
MDPrefix = "connect-" // The prefix of Connect metadata keys.
MDSession = MDPrefix + "session" // Metadata key specifying the session id for a Tunnel.
MDEndpoint = MDPrefix + "endpoint" // Metadata key specifying the watching Endpoint.
)
// Tunnel represents an outbound only tunnel initiated by
// an Endpoint for a specific SessionProposal.
type Tunnel net.Conn
// Tunneler creates a Tunnel.
type Tunneler interface {
Tunnel(context.Context) (Tunnel, error)
}
// Watcher registers the calling endpoint and watches for sessions
// proposed by the WatchService. To stop watching cancel the context.
// If ReceiveProposal returns a non-nil non-EOF error Watch returns it.
type Watcher interface {
Watch(context.Context, ReceiveProposal) error
}
// ReceiveProposal is called when Watcher receives a SessionProposal.
type ReceiveProposal func(proposal SessionProposal) error
// SessionProposal specifies an incoming session proposal.
// Use the Session to create the connection tunnel or reject the session with an optional reason.
type SessionProposal interface {
Session() *Session // The session proposed to connect to the Endpoint.
Reject(context.Context, *RejectionReason) error // Rejects the session proposal with an optional reason.
}
// Endpoint is an endpoint that listens for
// sessions to either reject them or establish
// a tunnel for receiving the connection.
type Endpoint interface {
Watcher
Tunneler
}
// TunnelListener is a network listener for tunnel connections.
type TunnelListener interface {
AcceptTunnel(context.Context, Tunnel) error
}
// EndpointListener is a network listener for endpoint watches.
type EndpointListener interface {
AcceptEndpoint(context.Context, EndpointWatch) error
}
// EndpointWatch is a watching Endpoint.
type EndpointWatch interface {
// Propose proposes a session to the Endpoint.
// The Endpoint either rejects the proposal or initiates
// a Tunnel to receive the session connection.
Propose(context.Context, *Session) error
Rejections() <-chan *SessionRejection // Rejections receives rejected session proposals from the Endpoint.
}
// Listener listens for watching endpoints and tunnel connections from endpoints.
type Listener interface {
EndpointListener
TunnelListener
}
// TunnelOptions are options for Tunneler and TunnelListener.
// Use WithTunnelOptions to propagate TunnelOptions in context.
type TunnelOptions struct {
// LocalAddr fakes the local address of the Tunnel when specified.
//
// If this TunnelOptions destine to Tunneler
// it is recommended to use the Endpoint address/name.
//
// If this TunnelOptions destine to TunnelListener
// it is recommended to use the underlying network listener address.
LocalAddr net.Addr
// RemoteAddr fakes the remote address of the Tunnel when specified.
//
// If this TunnelOptions destine to Tunneler
// it is recommended to use the underlying connection remote address.
//
// If this TunnelOptions destine to TunnelListener
// it is recommended to use the Endpoint address/name.
RemoteAddr net.Addr // It is recommended to use the player address.
}
// WithTunnelOptions stores TunnelOptions in a context.
func WithTunnelOptions(ctx context.Context, opts TunnelOptions) context.Context {
return context.WithValue(ctx, ctxkey.TunnelOptions{}, opts)
}
// Addr is an address in the "connect" network.
type Addr string
func (a Addr) String() string { return string(a) }
func (a Addr) Network() string { return "connect" }