8000 feat: automatically use websockets if DERP upgrade is unavailable by kylecarbs · Pull Request #6381 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

feat: automatically use websockets if DERP upgrade is unavailable #6381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix requested changes
  • Loading branch information
kylecarbs committed Mar 1, 2023
commit b830fada3be7b32337727449c05a87215f3e6fd4
2 changes: 1 addition & 1 deletion coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func New(options *Options) *API {
apiRateLimiter := httpmw.RateLimit(options.APIRateLimit, time.Minute)

derpHandler := derphttp.Handler(api.DERPServer)
derpHandler, api.derpCloseFunc = tailnet.AddWebsocketSupport(api.DERPServer, derpHandler)
derpHandler, api.derpCloseFunc = tailnet.WithWebsocketSupport(api.DERPServer, derpHandler)

r.Use(
httpmw.Recover(api.Logger),
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ replace github.com/tcnksm/go-httpstat => github.com/kylecarbs/go-httpstat v0.0.0

// There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here:
// https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20230228220447-d27e5d3056e9
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20230301203426-fb16ae7c5bba

// Switch to our fork that imports fixes from http://github.com/tailscale/ssh.
// See: https://github.com/coder/coder/issues/3371
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ github.com/coder/tailscale v1.1.1-0.20230228215233-ba13d5ceee2a h1:eXE/5hMkcHfa3
github.com/coder/tailscale v1.1.1-0.20230228215233-ba13d5ceee2a/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
github.com/coder/tailscale v1.1.1-0.20230228220447-d27e5d3056e9 h1:bFcFXLUUi+cwgOqrjbXN+XmI7QvB1up/UZoNF1+9nuM=
github.com/coder/tailscale v1.1.1-0.20230228220447-d27e5d3056e9/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
github.com/coder/tailscale v1.1.1-0.20230301203426-fb16ae7c5bba h1:JOD5pqNtiz9lkSX74PY2BJOyNqsBmvGUjFGIuECtG+o=
github.com/coder/tailscale v1.1.1-0.20230301203426-fb16ae7c5bba/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
github.com/coder/terraform-provider-coder v0.6.14 h1:NsJ1mo0MN1x/VyNLYmsgPUYn2JgzdVNZBqnj9OSIDgY=
github.com/coder/terraform-provider-coder v0.6.14/go.mod h1:UIfU3bYNeSzJJvHyJ30tEKjD6Z9utloI+HUM/7n94CY=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
Expand Down
12 changes: 8 additions & 4 deletions tailnet/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/tailnet"
"github.com/coder/coder/tailnet/tailnettest"
"github.com/coder/coder/testutil"
)

func TestMain(m *testing.M) {
Expand Down Expand Up @@ -63,7 +64,7 @@ func TestTailnet(t *testing.T) {
assert.NoError(t, err)
})
require.True(t, w2.AwaitReachable(context.Background(), w1IP))
conn := make(chan struct{})
conn := make(chan struct{}, 1)
go func() {
listener, err := w1.Listen("tcp", ":35565")
assert.NoError(t, err)
Expand Down Expand Up @@ -98,6 +99,9 @@ func TestTailnet(t *testing.T) {

t.Run("ForcesWebSockets", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := testutil.Context(t)
defer cancelFunc()

w1IP := tailnet.IP()
derpMap := tailnettest.RunDERPOnlyWebSockets(t)
w1, err := tailnet.NewConn(&tailnet.Options{
Expand Down Expand Up @@ -127,8 +131,8 @@ func TestTailnet(t *testing.T) {
err := w1.UpdateNodes([]*tailnet.Node{node}, false)
assert.NoError(t, err)
})
require.True(t, w2.AwaitReachable(context.Background(), w1IP))
conn := make(chan struct{})
require.True(t, w2.AwaitReachable(ctx, w1IP))
conn := make(chan struct{}, 1)
go func() {
listener, err := w1.Listen("tcp", ":35565")
assert.NoError(t, err)
Expand All @@ -141,7 +145,7 @@ func TestTailnet(t *testing.T) {
conn <- struct{}{}
}()

nc, err := w2.DialContextTCP(context.Background(), netip.AddrPortFrom(w1IP, 35565))
nc, err := w2.DialContextTCP(ctx, netip.AddrPortFrom(w1IP, 35565))
require.NoError(t, err)
_ = nc.Close()
<-conn
Expand Down
10 changes: 7 additions & 3 deletions tailnet/derp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import (
"tailscale.com/net/wsconn"
)

// DERPWebsocketSupport returns an http.Handler that upgrades
// WithWebsocketSupport returns an http.Handler that upgrades
// connections to the "derp" subprotocol to WebSockets and
// passes them to the DERP server.
// Taken from: https://github.com/tailscale/tailscale/blob/e3211ff88ba85435f70984cf67d9b353f3d650d8/cmd/derper/websocket.go#L21
func AddWebsocketSupport(s *derp.Server, base http.Handler) (http.Handler, func()) {
func WithWebsocketSupport(s *derp.Server, base http.Handler) (http.Handler, func()) {
var mu sync.Mutex
var waitGroup sync.WaitGroup
ctx, cancelFunc := context.WithCancel(context.Background())
Expand All @@ -34,6 +34,10 @@ func AddWebsocketSupport(s *derp.Server, base http.Handler) (http.Handler, func(
}

mu.Lock()
if ctx.Err() != nil {
mu.Unlock()
return
}
waitGroup.Add(1)
mu.Unlock()
defer waitGroup.Done()
Expand All @@ -58,7 +62,7 @@ func AddWebsocketSupport(s *derp.Server, base http.Handler) (http.Handler, func(
}
wc := wsconn.NetConn(ctx, c, websocket.MessageBinary)
brw := bufio.NewReadWriter(bufio.NewReader(wc), bufio.NewWriter(wc))
s.Accept(r.Context(), wc, brw, r.RemoteAddr)
s.Accept(ctx, wc, brw, r.RemoteAddr)
}), func() {
cancelFunc()
mu.Lock()
Expand Down
4 changes: 2 additions & 2 deletions tailnet/tailnettest/tailnettest.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func RunDERPOnlyWebSockets(t *testing.T) *tailcfg.DERPMap {
d := derp.NewServer(key.NewNode(), logf)
handler := derphttp.Handler(d)
var closeFunc func()
handler, closeFunc = tailnet.AddWebsocketSupport(d, handler)
handler, closeFunc = tailnet.WithWebsocketSupport(d, handler)
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/derp" {
handler.ServeHTTP(w, r)
Expand All @@ -91,8 +91,8 @@ func RunDERPOnlyWebSockets(t *testing.T) *tailcfg.DERPMap {
t.Cleanup(func() {
server.CloseClientConnections()
server.Close()
d.Close()
closeFunc()
d.Close()
})

tcpAddr, ok := server.Listener.Addr().(*net.TCPAddr)
Expand Down
0