mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-14 18:20:42 -07:00
Perform the check on accept, not in processing CONNECT
This will protect the server from non NATS clients (telnet, etc), or misbehaving clients that would create the tcp connection but block before sending the CONNECT. The drawback is that the client may or may not receive the error message (in my tests, it was getting only between 10%-20% of times).
This commit is contained in:
@@ -447,12 +447,6 @@ func (c *client) processConnect(arg []byte) error {
|
||||
srv.mu.Unlock()
|
||||
}
|
||||
|
||||
// Check for max connections
|
||||
if ok := srv.checkMaxConn(c); !ok {
|
||||
c.maxConnLimit()
|
||||
return ErrTooManyConnections
|
||||
}
|
||||
|
||||
// Check for Auth
|
||||
if ok := srv.checkAuth(c); !ok {
|
||||
c.authViolation()
|
||||
@@ -496,14 +490,8 @@ func (c *client) authViolation() {
|
||||
c.closeConnection()
|
||||
}
|
||||
|
||||
func (c *client) maxConnLimit() {
|
||||
if c.srv != nil && c.srv.opts.Users != nil {
|
||||
c.Errorf("%s - User %q",
|
||||
ErrTooManyConnections.Error(),
|
||||
c.opts.Username)
|
||||
} else {
|
||||
c.Errorf(ErrTooManyConnections.Error())
|
||||
}
|
||||
func (c *client) maxConnExceeded() {
|
||||
c.Errorf(ErrTooManyConnections.Error())
|
||||
c.sendErr(ErrTooManyConnections.Error())
|
||||
c.closeConnection()
|
||||
}
|
||||
|
||||
@@ -28,5 +28,5 @@ var (
|
||||
|
||||
// ErrTooManyConnections signals a client that the maximum number of connections supported by the
|
||||
// server has been reached.
|
||||
ErrTooManyConnections = errors.New("Too many connections")
|
||||
ErrTooManyConnections = errors.New("Maximum Connections Exceeded")
|
||||
)
|
||||
|
||||
@@ -546,6 +546,13 @@ func (s *Server) createClient(conn net.Conn) *client {
|
||||
s.mu.Unlock()
|
||||
return c
|
||||
}
|
||||
// If there is a max connections specified, check that adding
|
||||
// this new client would not push us over the max
|
||||
if s.opts.MaxConn > 0 && len(s.clients) >= s.opts.MaxConn {
|
||||
s.mu.Unlock()
|
||||
c.maxConnExceeded()
|
||||
return nil
|
||||
}
|
||||
s.clients[c.cid] = c
|
||||
s.mu.Unlock()
|
||||
|
||||
@@ -731,17 +738,6 @@ func (s *Server) checkAuth(c *client) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Check that number of clients is below Max connection setting.
|
||||
func (s *Server) checkMaxConn(c *client) bool {
|
||||
if c.typ == CLIENT {
|
||||
s.mu.Lock()
|
||||
ok := len(s.clients) <= s.opts.MaxConn
|
||||
s.mu.Unlock()
|
||||
return ok
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Remove a client or route from our internal accounting.
|
||||
func (s *Server) removeClient(c *client) {
|
||||
var rID string
|
||||
|
||||
@@ -242,9 +242,7 @@ func TestMaxConnections(t *testing.T) {
|
||||
|
||||
nc2, err := nats.Connect(addr)
|
||||
if err == nil {
|
||||
if nc2 != nil {
|
||||
nc2.Close()
|
||||
}
|
||||
nc2.Close()
|
||||
t.Fatal("Expected connection to fail")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user