From 2e0830201c2bbd3a021c7a741a6e02474d86577d Mon Sep 17 00:00:00 2001 From: Derek Collison Date: Fri, 29 Jun 2018 11:42:23 -0700 Subject: [PATCH] Make sure closed conn accounting correct for bad clients Signed-off-by: Derek Collison --- server/monitor_test.go | 86 +++++++++++++++++++++++++++++++++++++++++- server/server.go | 5 ++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/server/monitor_test.go b/server/monitor_test.go index 6139912d..c9db68ef 100644 --- a/server/monitor_test.go +++ b/server/monitor_test.go @@ -1199,8 +1199,7 @@ func TestConnzWithStateForClosedConns(t *testing.T) { } } -// Make sure options for ConnInfo like subs=1, authuser, etc do not cause a -// race. +// Make sure options for ConnInfo like subs=1, authuser, etc do not cause a race. func TestConnzClosedConnsRace(t *testing.T) { s := runMonitorServer() defer s.Shutdown() @@ -1235,6 +1234,89 @@ func TestConnzClosedConnsRace(t *testing.T) { wg.Wait() } +// Make sure a bad client that is disconnected right away has proper values. +func TestConnzClosedConnsBadClient(t *testing.T) { + s := runMonitorServer() + defer s.Shutdown() + + opts := s.getOpts() + + rc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", opts.Host, opts.Port)) + if err != nil { + t.Fatalf("Error on dial: %v", err) + } + rc.Close() + + checkClosedConns(t, s, 1, 2*time.Second) + + c := pollConz(t, s, 1, "", &ConnzOptions{State: ConnClosed}) + if len(c.Conns) != 1 { + t.Errorf("Incorrect Results: %+v\n", c) + } + ci := c.Conns[0] + + uptime := ci.Stop.Sub(ci.Start) + idle, err := time.ParseDuration(ci.Idle) + if err != nil { + t.Fatalf("Could not parse Idle: %v\n", err) + } + if idle > uptime { + t.Fatalf("Idle can't be larger then uptime, %v vs %v\n", idle, uptime) + } + if ci.LastActivity.IsZero() { + t.Fatalf("LastActivity should not be Zero\n") + } +} + +// Make sure a bad client that tries to connect plain to TLS has proper values. +func TestConnzClosedConnsBadTLSClient(t *testing.T) { + resetPreviousHTTPConnections() + + tc := &TLSConfigOpts{} + tc.CertFile = "configs/certs/server.pem" + tc.KeyFile = "configs/certs/key.pem" + + var err error + opts := DefaultMonitorOptions() + opts.TLSTimeout = 1.5 // 1.5 seconds + opts.TLSConfig, err = GenTLSConfig(tc) + if err != nil { + t.Fatalf("Error creating TSL config: %v", err) + } + + s := RunServer(opts) + defer s.Shutdown() + + opts = s.getOpts() + + rc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", opts.Host, opts.Port)) + if err != nil { + t.Fatalf("Error on dial: %v", err) + } + rc.Write([]byte("CONNECT {}\r\n")) + rc.Close() + + checkClosedConns(t, s, 1, 2*time.Second) + + c := pollConz(t, s, 1, "", &ConnzOptions{State: ConnClosed}) + if len(c.Conns) != 1 { + t.Errorf("Incorrect Results: %+v\n", c) + } + ci := c.Conns[0] + + uptime := ci.Stop.Sub(ci.Start) + idle, err := time.ParseDuration(ci.Idle) + if err != nil { + t.Fatalf("Could not parse Idle: %v\n", err) + } + if idle > uptime { + t.Fatalf("Idle can't be larger then uptime, %v vs %v\n", idle, uptime) + } + if ci.LastActivity.IsZero() { + t.Fatalf("LastActivity should not be Zero\n") + } +} + // Create a connection to test ConnInfo func createClientConnSubscribeAndPublish(t *testing.T, s *Server) *nats.Conn { natsURL := fmt.Sprintf("nats://127.0.0.1:%d", s.Addr().(*net.TCPAddr).Port) diff --git a/server/server.go b/server/server.go index 35e0e373..8a01f2a1 100644 --- a/server/server.go +++ b/server/server.go @@ -730,7 +730,10 @@ func (s *Server) createClient(conn net.Conn) *client { // Snapshot server options. opts := s.getOpts() - c := &client{srv: s, nc: conn, opts: defaultOpts, mpay: int64(opts.MaxPayload), start: time.Now()} + max_pay := int64(opts.MaxPayload) + now := time.Now() + + c := &client{srv: s, nc: conn, opts: defaultOpts, mpay: max_pay, start: now, last: now} // Grab JSON info string s.mu.Lock()