Skip to content
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

[CHANGED] LeafNode: remotes from same server binding to same hub account #4259

Merged
merged 1 commit into from Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions server/client.go
Expand Up @@ -624,6 +624,9 @@ type ClientOpts struct {
// Routes and Leafnodes only
Import *SubjectPermission `json:"import,omitempty"`
Export *SubjectPermission `json:"export,omitempty"`

// Leafnodes
RemoteAccount string `json:"remote_account,omitempty"`
}

var defaultOpts = ClientOpts{Verbose: true, Pedantic: true, Echo: true}
Expand Down
38 changes: 25 additions & 13 deletions server/leafnode.go
Expand Up @@ -78,6 +78,8 @@ type leaf struct {
remoteServer string
// domain name of remote server
remoteDomain string
// account name of remote server
remoteAccName string
// Used to suppress sub and unsub interest. Same as routes but our audience
// here is tied to this leaf node. This will hold all subscriptions except this
// leaf nodes. This represents all the interest we want to send to the other side.
Expand Down Expand Up @@ -348,8 +350,8 @@ func (s *Server) updateRemoteLeafNodesTLSConfig(opts *Options) {
return
}

s.mu.Lock()
defer s.mu.Unlock()
s.mu.RLock()
defer s.mu.RUnlock()

// Changes in the list of remote leaf nodes is not supported.
// However, make sure that we don't go over the arrays.
Expand Down Expand Up @@ -764,16 +766,17 @@ var credsRe = regexp.MustCompile(`\s*(?:(?:[-]{3,}[^\n]*[-]{3,}\n)(.+)(?:\n\s*[-
func (c *client) sendLeafConnect(clusterName string, headers bool) error {
// We support basic user/pass and operator based user JWT with signatures.
cinfo := leafConnectInfo{
Version: VERSION,
ID: c.srv.info.ID,
Domain: c.srv.info.Domain,
Name: c.srv.info.Name,
Hub: c.leaf.remote.Hub,
Cluster: clusterName,
Headers: headers,
JetStream: c.acc.jetStreamConfigured(),
DenyPub: c.leaf.remote.DenyImports,
Compression: c.leaf.compression,
Version: VERSION,
ID: c.srv.info.ID,
Domain: c.srv.info.Domain,
Name: c.srv.info.Name,
Hub: c.leaf.remote.Hub,
Cluster: clusterName,
Headers: headers,
JetStream: c.acc.jetStreamConfigured(),
DenyPub: c.leaf.remote.DenyImports,
Compression: c.leaf.compression,
RemoteAccount: c.acc.GetName(),
}

// If a signature callback is specified, this takes precedence over anything else.
Expand Down Expand Up @@ -1310,6 +1313,8 @@ func (c *client) processLeafnodeInfo(info *Info) {
// Clear deadline that was set in createLeafNode while waiting for the INFO.
c.nc.SetDeadline(time.Time{})
resumeConnect = true
} else if !firstINFO && didSolicit {
c.leaf.remoteAccName = info.RemoteAccount
}

// Check if we have the remote account information and if so make sure it's stored.
Expand Down Expand Up @@ -1503,6 +1508,7 @@ func (s *Server) addLeafNodeConnection(c *client, srvName, clusterName string, c
}
myRemoteDomain := c.leaf.remoteDomain
mySrvName := c.leaf.remoteServer
remoteAccName := c.leaf.remoteAccName
myClustName := c.leaf.remoteCluster
solicited := c.leaf.remote != nil
c.mu.Unlock()
Expand All @@ -1518,7 +1524,8 @@ func (s *Server) addLeafNodeConnection(c *client, srvName, clusterName string, c
// We have code for the loop detection elsewhere, which also delays
// attempt to reconnect.
if !ol.isSolicitedLeafNode() && ol.leaf.remoteServer == srvName &&
ol.leaf.remoteCluster == clusterName && ol.acc.Name == accName {
ol.leaf.remoteCluster == clusterName && ol.acc.Name == accName &&
remoteAccName != _EMPTY_ && ol.leaf.remoteAccName == remoteAccName {
old = ol
}
ol.mu.Unlock()
Expand Down Expand Up @@ -1693,6 +1700,9 @@ type leafConnectInfo struct {

// Just used to detect wrong connection attempts.
Gateway string `json:"gateway,omitempty"`

// Tells the accept side which account the remote is binding to.
RemoteAccount string `json:"remote_account,omitempty"`
}

// processLeafNodeConnect will process the inbound connect args.
Expand Down Expand Up @@ -1774,6 +1784,8 @@ func (c *client) processLeafNodeConnect(s *Server, arg []byte, lang string) erro

// Remember the remote server.
c.leaf.remoteServer = proto.Name
// Remember the remote account name
c.leaf.remoteAccName = proto.RemoteAccount

// If the other side has declared itself a hub, so we will take on the spoke role.
if proto.Hub {
Expand Down