Skip to content

Commit

Permalink
Merge pull request #2305 from nats-io/fix_missing_unlock
Browse files Browse the repository at this point in the history
[FIXED] Failed route TLS handshake would leave failed conn's lock, locked
  • Loading branch information
kozlovic committed Jun 22, 2021
2 parents 23ec1da + d793363 commit cf59e4c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions server/route.go
Expand Up @@ -1333,6 +1333,7 @@ func (s *Server) createRoute(conn net.Conn, rURL *url.URL) *client {
}
// Perform (server or client side) TLS handshake.
if _, err := c.doTLSHandshake("route", didSolicit, rURL, tlsConfig, _EMPTY_, opts.Cluster.TLSTimeout, opts.Cluster.TLSPinnedCerts); err != nil {
c.mu.Unlock()
return nil
}
}
Expand Down
49 changes: 49 additions & 0 deletions server/routes_test.go
Expand Up @@ -14,11 +14,13 @@
package server

import (
"bytes"
"context"
"crypto/tls"
"fmt"
"net"
"net/url"
"runtime"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -1381,3 +1383,50 @@ func TestRouteDuplicateServerName(t *testing.T) {
t.Fatal("Should have gotten a warning regarding duplicate server name")
}
}

func TestRouteLockReleasedOnTLSFailure(t *testing.T) {
o1 := DefaultOptions()
o1.Cluster.Name = "abc"
o1.Cluster.Host = "127.0.0.1"
o1.Cluster.Port = -1
o1.Cluster.TLSTimeout = 0.25
tc := &TLSConfigOpts{
CertFile: "./configs/certs/server.pem",
KeyFile: "./configs/certs/key.pem",
Insecure: true,
}
tlsConf, err := GenTLSConfig(tc)
if err != nil {
t.Fatalf("Error generating tls config: %v", err)
}
o1.Cluster.TLSConfig = tlsConf
s1 := RunServer(o1)
defer s1.Shutdown()

l := &captureErrorLogger{errCh: make(chan string, 10)}
s1.SetLogger(l, false, false)

o2 := DefaultOptions()
o2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", o1.Cluster.Port))
s2 := RunServer(o2)
defer s2.Shutdown()

select {
case err := <-l.errCh:
if !strings.Contains(err, "TLS") {
t.Fatalf("Unexpected error: %v", err)
}
case <-time.After(time.Second):
}

s2.Shutdown()

// Wait for longer than the TLS timeout and check that tlsTimeout is not stuck
time.Sleep(500 * time.Millisecond)

buf := make([]byte, 10000)
n := runtime.Stack(buf, true)
if bytes.Contains(buf[:n], []byte("tlsTimeout")) {
t.Fatal("Seem connection lock was not released")
}
}

0 comments on commit cf59e4c

Please sign in to comment.