mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-16 19:14:41 -07:00
Rework closeConnection()
This change allows the removal of the connection and update of the server state to be done "in place" but still delay the flushing of and close of tcp connection to the writeLoop. With ref counting we ensure that the reconnect happens after the flushing but not before the state has been updated. Had to fix some places where we may have called closeConnection() from under the server lock since it now would deadlock for sure. Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This commit is contained in:
@@ -429,7 +429,7 @@ func (s *Server) startLeafNodeAcceptLoop() {
|
||||
var credsRe = regexp.MustCompile(`\s*(?:(?:[-]{3,}[^\n]*[-]{3,}\n)(.+)(?:\n\s*[-]{3,}[^\n]*[-]{3,}\n))`)
|
||||
|
||||
// Lock should be held entering here.
|
||||
func (c *client) sendLeafConnect(clusterName string, tlsRequired bool) {
|
||||
func (c *client) sendLeafConnect(clusterName string, tlsRequired bool) error {
|
||||
// We support basic user/pass and operator based user JWT with signatures.
|
||||
cinfo := leafConnectInfo{
|
||||
TLS: tlsRequired,
|
||||
@@ -444,13 +444,13 @@ func (c *client) sendLeafConnect(clusterName string, tlsRequired bool) {
|
||||
contents, err := ioutil.ReadFile(creds)
|
||||
if err != nil {
|
||||
c.Errorf("%v", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer wipeSlice(contents)
|
||||
items := credsRe.FindAllSubmatch(contents, -1)
|
||||
if len(items) < 2 {
|
||||
c.Errorf("Credentials file malformed")
|
||||
return
|
||||
return err
|
||||
}
|
||||
// First result should be the user JWT.
|
||||
// We copy here so that the file containing the seed will be wiped appropriately.
|
||||
@@ -461,7 +461,7 @@ func (c *client) sendLeafConnect(clusterName string, tlsRequired bool) {
|
||||
kp, err := nkeys.FromSeed(items[1][1])
|
||||
if err != nil {
|
||||
c.Errorf("Credentials file has malformed seed")
|
||||
return
|
||||
return err
|
||||
}
|
||||
// Wipe our key on exit.
|
||||
defer kp.Wipe()
|
||||
@@ -480,13 +480,13 @@ func (c *client) sendLeafConnect(clusterName string, tlsRequired bool) {
|
||||
b, err := json.Marshal(cinfo)
|
||||
if err != nil {
|
||||
c.Errorf("Error marshaling CONNECT to route: %v\n", err)
|
||||
c.closeConnection(ProtocolViolation)
|
||||
return
|
||||
return err
|
||||
}
|
||||
// Although this call is made before the writeLoop is created,
|
||||
// we don't really need to send in place. The protocol will be
|
||||
// sent out by the writeLoop.
|
||||
c.enqueueProto([]byte(fmt.Sprintf(ConProto, b)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Makes a deep copy of the LeafNode Info structure.
|
||||
@@ -714,7 +714,11 @@ func (s *Server) createLeafNode(conn net.Conn, remote *leafNodeCfg) *client {
|
||||
c.mu.Lock()
|
||||
}
|
||||
|
||||
c.sendLeafConnect(clusterName, tlsRequired)
|
||||
if err := c.sendLeafConnect(clusterName, tlsRequired); err != nil {
|
||||
c.mu.Unlock()
|
||||
c.closeConnection(ProtocolViolation)
|
||||
return nil
|
||||
}
|
||||
c.Debugf("Remote leafnode connect msg sent")
|
||||
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user