get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/events.go (about)

     1  // Copyright 2018-2024 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"bytes"
    18  	"compress/gzip"
    19  	"crypto/sha256"
    20  	"crypto/x509"
    21  	"encoding/json"
    22  	"errors"
    23  	"fmt"
    24  	"math/rand"
    25  	"net/http"
    26  	"runtime"
    27  	"strconv"
    28  	"strings"
    29  	"sync"
    30  	"sync/atomic"
    31  	"time"
    32  
    33  	"github.com/klauspost/compress/s2"
    34  
    35  	"get.pme.sh/pnats/server/certidp"
    36  	"get.pme.sh/pnats/server/pse"
    37  	"github.com/nats-io/jwt/v2"
    38  )
    39  
    40  const (
    41  	accLookupReqTokens = 6
    42  	accLookupReqSubj   = "$SYS.REQ.ACCOUNT.%s.CLAIMS.LOOKUP"
    43  	accPackReqSubj     = "$SYS.REQ.CLAIMS.PACK"
    44  	accListReqSubj     = "$SYS.REQ.CLAIMS.LIST"
    45  	accClaimsReqSubj   = "$SYS.REQ.CLAIMS.UPDATE"
    46  	accDeleteReqSubj   = "$SYS.REQ.CLAIMS.DELETE"
    47  
    48  	connectEventSubj    = "$SYS.ACCOUNT.%s.CONNECT"
    49  	disconnectEventSubj = "$SYS.ACCOUNT.%s.DISCONNECT"
    50  	accDirectReqSubj    = "$SYS.REQ.ACCOUNT.%s.%s"
    51  	accPingReqSubj      = "$SYS.REQ.ACCOUNT.PING.%s" // atm. only used for STATZ and CONNZ import from system account
    52  	// kept for backward compatibility when using http resolver
    53  	// this overlaps with the names for events but you'd have to have the operator private key in order to succeed.
    54  	accUpdateEventSubjOld     = "$SYS.ACCOUNT.%s.CLAIMS.UPDATE"
    55  	accUpdateEventSubjNew     = "$SYS.REQ.ACCOUNT.%s.CLAIMS.UPDATE"
    56  	connsRespSubj             = "$SYS._INBOX_.%s"
    57  	accConnsEventSubjNew      = "$SYS.ACCOUNT.%s.SERVER.CONNS"
    58  	accConnsEventSubjOld      = "$SYS.SERVER.ACCOUNT.%s.CONNS" // kept for backward compatibility
    59  	lameDuckEventSubj         = "$SYS.SERVER.%s.LAMEDUCK"
    60  	shutdownEventSubj         = "$SYS.SERVER.%s.SHUTDOWN"
    61  	clientKickReqSubj         = "$SYS.REQ.SERVER.%s.KICK"
    62  	clientLDMReqSubj          = "$SYS.REQ.SERVER.%s.LDM"
    63  	authErrorEventSubj        = "$SYS.SERVER.%s.CLIENT.AUTH.ERR"
    64  	authErrorAccountEventSubj = "$SYS.ACCOUNT.CLIENT.AUTH.ERR"
    65  	serverStatsSubj           = "$SYS.SERVER.%s.STATSZ"
    66  	serverDirectReqSubj       = "$SYS.REQ.SERVER.%s.%s"
    67  	serverPingReqSubj         = "$SYS.REQ.SERVER.PING.%s"
    68  	serverStatsPingReqSubj    = "$SYS.REQ.SERVER.PING"             // use $SYS.REQ.SERVER.PING.STATSZ instead
    69  	serverReloadReqSubj       = "$SYS.REQ.SERVER.%s.RELOAD"        // with server ID
    70  	leafNodeConnectEventSubj  = "$SYS.ACCOUNT.%s.LEAFNODE.CONNECT" // for internal use only
    71  	remoteLatencyEventSubj    = "$SYS.LATENCY.M2.%s"
    72  	inboxRespSubj             = "$SYS._INBOX.%s.%s"
    73  
    74  	// Used to return information to a user on bound account and user permissions.
    75  	userDirectInfoSubj = "$SYS.REQ.USER.INFO"
    76  	userDirectReqSubj  = "$SYS.REQ.USER.%s.INFO"
    77  
    78  	// FIXME(dlc) - Should account scope, even with wc for now, but later on
    79  	// we can then shard as needed.
    80  	accNumSubsReqSubj = "$SYS.REQ.ACCOUNT.NSUBS"
    81  
    82  	// These are for exported debug services. These are local to this server only.
    83  	accSubsSubj = "$SYS.DEBUG.SUBSCRIBERS"
    84  
    85  	shutdownEventTokens = 4
    86  	serverSubjectIndex  = 2
    87  	accUpdateTokensNew  = 6
    88  	accUpdateTokensOld  = 5
    89  	accUpdateAccIdxOld  = 2
    90  
    91  	accReqTokens   = 5
    92  	accReqAccIndex = 3
    93  
    94  	ocspPeerRejectEventSubj           = "$SYS.SERVER.%s.OCSP.PEER.CONN.REJECT"
    95  	ocspPeerChainlinkInvalidEventSubj = "$SYS.SERVER.%s.OCSP.PEER.LINK.INVALID"
    96  )
    97  
    98  // FIXME(dlc) - make configurable.
    99  var eventsHBInterval = 30 * time.Second
   100  
   101  type sysMsgHandler func(sub *subscription, client *client, acc *Account, subject, reply string, hdr, msg []byte)
   102  
   103  // Used if we have to queue things internally to avoid the route/gw path.
   104  type inSysMsg struct {
   105  	sub  *subscription
   106  	c    *client
   107  	acc  *Account
   108  	subj string
   109  	rply string
   110  	hdr  []byte
   111  	msg  []byte
   112  	cb   sysMsgHandler
   113  }
   114  
   115  // Used to send and receive messages from inside the server.
   116  type internal struct {
   117  	account        *Account
   118  	client         *client
   119  	seq            uint64
   120  	sid            int
   121  	servers        map[string]*serverUpdate
   122  	sweeper        *time.Timer
   123  	stmr           *time.Timer
   124  	replies        map[string]msgHandler
   125  	sendq          *ipQueue[*pubMsg]
   126  	recvq          *ipQueue[*inSysMsg]
   127  	resetCh        chan struct{}
   128  	wg             sync.WaitGroup
   129  	sq             *sendq
   130  	orphMax        time.Duration
   131  	chkOrph        time.Duration
   132  	statsz         time.Duration
   133  	cstatsz        time.Duration
   134  	shash          string
   135  	inboxPre       string
   136  	remoteStatsSub *subscription
   137  }
   138  
   139  // ServerStatsMsg is sent periodically with stats updates.
   140  type ServerStatsMsg struct {
   141  	Server ServerInfo  `json:"server"`
   142  	Stats  ServerStats `json:"statsz"`
   143  }
   144  
   145  // ConnectEventMsg is sent when a new connection is made that is part of an account.
   146  type ConnectEventMsg struct {
   147  	TypedEvent
   148  	Server ServerInfo `json:"server"`
   149  	Client ClientInfo `json:"client"`
   150  }
   151  
   152  // ConnectEventMsgType is the schema type for ConnectEventMsg
   153  const ConnectEventMsgType = "io.nats.server.advisory.v1.client_connect"
   154  
   155  // DisconnectEventMsg is sent when a new connection previously defined from a
   156  // ConnectEventMsg is closed.
   157  type DisconnectEventMsg struct {
   158  	TypedEvent
   159  	Server   ServerInfo `json:"server"`
   160  	Client   ClientInfo `json:"client"`
   161  	Sent     DataStats  `json:"sent"`
   162  	Received DataStats  `json:"received"`
   163  	Reason   string     `json:"reason"`
   164  }
   165  
   166  // DisconnectEventMsgType is the schema type for DisconnectEventMsg
   167  const DisconnectEventMsgType = "io.nats.server.advisory.v1.client_disconnect"
   168  
   169  // OCSPPeerRejectEventMsg is sent when a peer TLS handshake is ultimately rejected due to OCSP invalidation.
   170  // A "peer" can be an inbound client connection or a leaf connection to a remote server. Peer in event payload
   171  // is always the peer's (TLS) leaf cert, which may or may be the invalid cert (See also OCSPPeerChainlinkInvalidEventMsg)
   172  type OCSPPeerRejectEventMsg struct {
   173  	TypedEvent
   174  	Kind   string           `json:"kind"`
   175  	Peer   certidp.CertInfo `json:"peer"`
   176  	Server ServerInfo       `json:"server"`
   177  	Reason string           `json:"reason"`
   178  }
   179  
   180  // OCSPPeerRejectEventMsgType is the schema type for OCSPPeerRejectEventMsg
   181  const OCSPPeerRejectEventMsgType = "io.nats.server.advisory.v1.ocsp_peer_reject"
   182  
   183  // OCSPPeerChainlinkInvalidEventMsg is sent when a certificate (link) in a valid TLS chain is found to be OCSP invalid
   184  // during a peer TLS handshake. A "peer" can be an inbound client connection or a leaf connection to a remote server.
   185  // Peer and Link may be the same if the invalid cert was the peer's leaf cert
   186  type OCSPPeerChainlinkInvalidEventMsg struct {
   187  	TypedEvent
   188  	Link   certidp.CertInfo `json:"link"`
   189  	Peer   certidp.CertInfo `json:"peer"`
   190  	Server ServerInfo       `json:"server"`
   191  	Reason string           `json:"reason"`
   192  }
   193  
   194  // OCSPPeerChainlinkInvalidEventMsgType is the schema type for OCSPPeerChainlinkInvalidEventMsg
   195  const OCSPPeerChainlinkInvalidEventMsgType = "io.nats.server.advisory.v1.ocsp_peer_link_invalid"
   196  
   197  // AccountNumConns is an event that will be sent from a server that is tracking
   198  // a given account when the number of connections changes. It will also HB
   199  // updates in the absence of any changes.
   200  type AccountNumConns struct {
   201  	TypedEvent
   202  	Server ServerInfo `json:"server"`
   203  	AccountStat
   204  }
   205  
   206  // AccountStat contains the data common between AccountNumConns and AccountStatz
   207  type AccountStat struct {
   208  	Account       string    `json:"acc"`
   209  	Conns         int       `json:"conns"`
   210  	LeafNodes     int       `json:"leafnodes"`
   211  	TotalConns    int       `json:"total_conns"`
   212  	NumSubs       uint32    `json:"num_subscriptions"`
   213  	Sent          DataStats `json:"sent"`
   214  	Received      DataStats `json:"received"`
   215  	SlowConsumers int64     `json:"slow_consumers"`
   216  }
   217  
   218  const AccountNumConnsMsgType = "io.nats.server.advisory.v1.account_connections"
   219  
   220  // accNumConnsReq is sent when we are starting to track an account for the first
   221  // time. We will request others send info to us about their local state.
   222  type accNumConnsReq struct {
   223  	Server  ServerInfo `json:"server"`
   224  	Account string     `json:"acc"`
   225  }
   226  
   227  // ServerID is basic static info for a server.
   228  type ServerID struct {
   229  	Name string `json:"name"`
   230  	Host string `json:"host"`
   231  	ID   string `json:"id"`
   232  }
   233  
   234  // Type for our server capabilities.
   235  type ServerCapability uint64
   236  
   237  // ServerInfo identifies remote servers.
   238  type ServerInfo struct {
   239  	Name    string   `json:"name"`
   240  	Host    string   `json:"host"`
   241  	ID      string   `json:"id"`
   242  	Cluster string   `json:"cluster,omitempty"`
   243  	Domain  string   `json:"domain,omitempty"`
   244  	Version string   `json:"ver"`
   245  	Tags    []string `json:"tags,omitempty"`
   246  	// Whether JetStream is enabled (deprecated in favor of the `ServerCapability`).
   247  	JetStream bool `json:"jetstream"`
   248  	// Generic capability flags
   249  	Flags ServerCapability `json:"flags"`
   250  	// Sequence and Time from the remote server for this message.
   251  	Seq  uint64    `json:"seq"`
   252  	Time time.Time `json:"time"`
   253  }
   254  
   255  const (
   256  	JetStreamEnabled     ServerCapability = 1 << iota // Server had JetStream enabled.
   257  	BinaryStreamSnapshot                              // New stream snapshot capability.
   258  )
   259  
   260  // Set JetStream capability.
   261  func (si *ServerInfo) SetJetStreamEnabled() {
   262  	si.Flags |= JetStreamEnabled
   263  	// Still set old version.
   264  	si.JetStream = true
   265  }
   266  
   267  // JetStreamEnabled indicates whether or not we have JetStream enabled.
   268  func (si *ServerInfo) JetStreamEnabled() bool {
   269  	// Take into account old version.
   270  	return si.Flags&JetStreamEnabled != 0 || si.JetStream
   271  }
   272  
   273  // Set binary stream snapshot capability.
   274  func (si *ServerInfo) SetBinaryStreamSnapshot() {
   275  	si.Flags |= BinaryStreamSnapshot
   276  }
   277  
   278  // JetStreamEnabled indicates whether or not we have binary stream snapshot capbilities.
   279  func (si *ServerInfo) BinaryStreamSnapshot() bool {
   280  	return si.Flags&BinaryStreamSnapshot != 0
   281  }
   282  
   283  // ClientInfo is detailed information about the client forming a connection.
   284  type ClientInfo struct {
   285  	Start      *time.Time    `json:"start,omitempty"`
   286  	Host       string        `json:"host,omitempty"`
   287  	ID         uint64        `json:"id,omitempty"`
   288  	Account    string        `json:"acc,omitempty"`
   289  	Service    string        `json:"svc,omitempty"`
   290  	User       string        `json:"user,omitempty"`
   291  	Name       string        `json:"name,omitempty"`
   292  	Lang       string        `json:"lang,omitempty"`
   293  	Version    string        `json:"ver,omitempty"`
   294  	RTT        time.Duration `json:"rtt,omitempty"`
   295  	Server     string        `json:"server,omitempty"`
   296  	Cluster    string        `json:"cluster,omitempty"`
   297  	Alternates []string      `json:"alts,omitempty"`
   298  	Stop       *time.Time    `json:"stop,omitempty"`
   299  	Jwt        string        `json:"jwt,omitempty"`
   300  	IssuerKey  string        `json:"issuer_key,omitempty"`
   301  	NameTag    string        `json:"name_tag,omitempty"`
   302  	Tags       jwt.TagList   `json:"tags,omitempty"`
   303  	Kind       string        `json:"kind,omitempty"`
   304  	ClientType string        `json:"client_type,omitempty"`
   305  	MQTTClient string        `json:"client_id,omitempty"` // This is the MQTT client ID
   306  	Nonce      string        `json:"nonce,omitempty"`
   307  }
   308  
   309  // ServerStats hold various statistics that we will periodically send out.
   310  type ServerStats struct {
   311  	Start            time.Time      `json:"start"`
   312  	Mem              int64          `json:"mem"`
   313  	Cores            int            `json:"cores"`
   314  	CPU              float64        `json:"cpu"`
   315  	Connections      int            `json:"connections"`
   316  	TotalConnections uint64         `json:"total_connections"`
   317  	ActiveAccounts   int            `json:"active_accounts"`
   318  	NumSubs          uint32         `json:"subscriptions"`
   319  	Sent             DataStats      `json:"sent"`
   320  	Received         DataStats      `json:"received"`
   321  	SlowConsumers    int64          `json:"slow_consumers"`
   322  	Routes           []*RouteStat   `json:"routes,omitempty"`
   323  	Gateways         []*GatewayStat `json:"gateways,omitempty"`
   324  	ActiveServers    int            `json:"active_servers,omitempty"`
   325  	JetStream        *JetStreamVarz `json:"jetstream,omitempty"`
   326  }
   327  
   328  // RouteStat holds route statistics.
   329  type RouteStat struct {
   330  	ID       uint64    `json:"rid"`
   331  	Name     string    `json:"name,omitempty"`
   332  	Sent     DataStats `json:"sent"`
   333  	Received DataStats `json:"received"`
   334  	Pending  int       `json:"pending"`
   335  }
   336  
   337  // GatewayStat holds gateway statistics.
   338  type GatewayStat struct {
   339  	ID         uint64    `json:"gwid"`
   340  	Name       string    `json:"name"`
   341  	Sent       DataStats `json:"sent"`
   342  	Received   DataStats `json:"received"`
   343  	NumInbound int       `json:"inbound_connections"`
   344  }
   345  
   346  // DataStats reports how may msg and bytes. Applicable for both sent and received.
   347  type DataStats struct {
   348  	Msgs  int64 `json:"msgs"`
   349  	Bytes int64 `json:"bytes"`
   350  }
   351  
   352  // Used for internally queueing up messages that the server wants to send.
   353  type pubMsg struct {
   354  	c    *client
   355  	sub  string
   356  	rply string
   357  	si   *ServerInfo
   358  	hdr  map[string]string
   359  	msg  interface{}
   360  	oct  compressionType
   361  	echo bool
   362  	last bool
   363  }
   364  
   365  var pubMsgPool sync.Pool
   366  
   367  func newPubMsg(c *client, sub, rply string, si *ServerInfo, hdr map[string]string,
   368  	msg interface{}, oct compressionType, echo, last bool) *pubMsg {
   369  
   370  	var m *pubMsg
   371  	pm := pubMsgPool.Get()
   372  	if pm != nil {
   373  		m = pm.(*pubMsg)
   374  	} else {
   375  		m = &pubMsg{}
   376  	}
   377  	// When getting something from a pool it is critical that all fields are
   378  	// initialized. Doing this way guarantees that if someone adds a field to
   379  	// the structure, the compiler will fail the build if this line is not updated.
   380  	(*m) = pubMsg{c, sub, rply, si, hdr, msg, oct, echo, last}
   381  	return m
   382  }
   383  
   384  func (pm *pubMsg) returnToPool() {
   385  	if pm == nil {
   386  		return
   387  	}
   388  	pm.c, pm.sub, pm.rply, pm.si, pm.hdr, pm.msg = nil, _EMPTY_, _EMPTY_, nil, nil, nil
   389  	pubMsgPool.Put(pm)
   390  }
   391  
   392  // Used to track server updates.
   393  type serverUpdate struct {
   394  	seq   uint64
   395  	ltime time.Time
   396  }
   397  
   398  // TypedEvent is a event or advisory sent by the server that has nats type hints
   399  // typically used for events that might be consumed by 3rd party event systems
   400  type TypedEvent struct {
   401  	Type string    `json:"type"`
   402  	ID   string    `json:"id"`
   403  	Time time.Time `json:"timestamp"`
   404  }
   405  
   406  // internalReceiveLoop will be responsible for dispatching all messages that
   407  // a server receives and needs to internally process, e.g. internal subs.
   408  func (s *Server) internalReceiveLoop() {
   409  	s.mu.RLock()
   410  	if s.sys == nil || s.sys.recvq == nil {
   411  		s.mu.RUnlock()
   412  		return
   413  	}
   414  	recvq := s.sys.recvq
   415  	s.mu.RUnlock()
   416  
   417  	for s.eventsRunning() {
   418  		select {
   419  		case <-recvq.ch:
   420  			msgs := recvq.pop()
   421  			for _, m := range msgs {
   422  				if m.cb != nil {
   423  					m.cb(m.sub, m.c, m.acc, m.subj, m.rply, m.hdr, m.msg)
   424  				}
   425  			}
   426  			recvq.recycle(&msgs)
   427  		case <-s.quitCh:
   428  			return
   429  		}
   430  	}
   431  }
   432  
   433  // internalSendLoop will be responsible for serializing all messages that
   434  // a server wants to send.
   435  func (s *Server) internalSendLoop(wg *sync.WaitGroup) {
   436  	defer wg.Done()
   437  
   438  RESET:
   439  	s.mu.RLock()
   440  	if s.sys == nil || s.sys.sendq == nil {
   441  		s.mu.RUnlock()
   442  		return
   443  	}
   444  	sysc := s.sys.client
   445  	resetCh := s.sys.resetCh
   446  	sendq := s.sys.sendq
   447  	id := s.info.ID
   448  	host := s.info.Host
   449  	servername := s.info.Name
   450  	domain := s.info.Domain
   451  	seqp := &s.sys.seq
   452  	js := s.info.JetStream
   453  	cluster := s.info.Cluster
   454  	if s.gateway.enabled {
   455  		cluster = s.getGatewayName()
   456  	}
   457  	s.mu.RUnlock()
   458  
   459  	// Grab tags.
   460  	tags := s.getOpts().Tags
   461  
   462  	for s.eventsRunning() {
   463  		select {
   464  		case <-sendq.ch:
   465  			msgs := sendq.pop()
   466  			for _, pm := range msgs {
   467  				if si := pm.si; si != nil {
   468  					si.Name = servername
   469  					si.Domain = domain
   470  					si.Host = host
   471  					si.Cluster = cluster
   472  					si.ID = id
   473  					si.Seq = atomic.AddUint64(seqp, 1)
   474  					si.Version = VERSION
   475  					si.Time = time.Now().UTC()
   476  					si.Tags = tags
   477  					if js {
   478  						// New capability based flags.
   479  						si.SetJetStreamEnabled()
   480  						si.SetBinaryStreamSnapshot()
   481  					}
   482  				}
   483  				var b []byte
   484  				if pm.msg != nil {
   485  					switch v := pm.msg.(type) {
   486  					case string:
   487  						b = []byte(v)
   488  					case []byte:
   489  						b = v
   490  					default:
   491  						b, _ = json.Marshal(pm.msg)
   492  					}
   493  				}
   494  				// Setup our client. If the user wants to use a non-system account use our internal
   495  				// account scoped here so that we are not changing out accounts for the system client.
   496  				var c *client
   497  				if pm.c != nil {
   498  					c = pm.c
   499  				} else {
   500  					c = sysc
   501  				}
   502  
   503  				// Grab client lock.
   504  				c.mu.Lock()
   505  
   506  				// Prep internal structures needed to send message.
   507  				c.pa.subject, c.pa.reply = []byte(pm.sub), []byte(pm.rply)
   508  				c.pa.size, c.pa.szb = len(b), []byte(strconv.FormatInt(int64(len(b)), 10))
   509  				c.pa.hdr, c.pa.hdb = -1, nil
   510  				trace := c.trace
   511  
   512  				// Now check for optional compression.
   513  				var contentHeader string
   514  				var bb bytes.Buffer
   515  
   516  				if len(b) > 0 {
   517  					switch pm.oct {
   518  					case gzipCompression:
   519  						zw := gzip.NewWriter(&bb)
   520  						zw.Write(b)
   521  						zw.Close()
   522  						b = bb.Bytes()
   523  						contentHeader = "gzip"
   524  					case snappyCompression:
   525  						sw := s2.NewWriter(&bb, s2.WriterSnappyCompat())
   526  						sw.Write(b)
   527  						sw.Close()
   528  						b = bb.Bytes()
   529  						contentHeader = "snappy"
   530  					case unsupportedCompression:
   531  						contentHeader = "identity"
   532  					}
   533  				}
   534  				// Optional Echo
   535  				replaceEcho := c.echo != pm.echo
   536  				if replaceEcho {
   537  					c.echo = !c.echo
   538  				}
   539  				c.mu.Unlock()
   540  
   541  				// Add in NL
   542  				b = append(b, _CRLF_...)
   543  
   544  				// Check if we should set content-encoding
   545  				if contentHeader != _EMPTY_ {
   546  					b = c.setHeader(contentEncodingHeader, contentHeader, b)
   547  				}
   548  
   549  				// Optional header processing.
   550  				if pm.hdr != nil {
   551  					for k, v := range pm.hdr {
   552  						b = c.setHeader(k, v, b)
   553  					}
   554  				}
   555  				// Tracing
   556  				if trace {
   557  					c.traceInOp(fmt.Sprintf("PUB %s %s %d", c.pa.subject, c.pa.reply, c.pa.size), nil)
   558  					c.traceMsg(b)
   559  				}
   560  
   561  				// Process like a normal inbound msg.
   562  				c.processInboundClientMsg(b)
   563  
   564  				// Put echo back if needed.
   565  				if replaceEcho {
   566  					c.mu.Lock()
   567  					c.echo = !c.echo
   568  					c.mu.Unlock()
   569  				}
   570  
   571  				// See if we are doing graceful shutdown.
   572  				if !pm.last {
   573  					c.flushClients(0) // Never spend time in place.
   574  				} else {
   575  					// For the Shutdown event, we need to send in place otherwise
   576  					// there is a chance that the process will exit before the
   577  					// writeLoop has a chance to send it.
   578  					c.flushClients(time.Second)
   579  					sendq.recycle(&msgs)
   580  					return
   581  				}
   582  				pm.returnToPool()
   583  			}
   584  			sendq.recycle(&msgs)
   585  		case <-resetCh:
   586  			goto RESET
   587  		case <-s.quitCh:
   588  			return
   589  		}
   590  	}
   591  }
   592  
   593  // Will send a shutdown message for lame-duck. Unlike sendShutdownEvent, this will
   594  // not close off the send queue or reply handler, as we may still have a workload
   595  // that needs migrating off.
   596  // Lock should be held.
   597  func (s *Server) sendLDMShutdownEventLocked() {
   598  	if s.sys == nil || s.sys.sendq == nil {
   599  		return
   600  	}
   601  	subj := fmt.Sprintf(lameDuckEventSubj, s.info.ID)
   602  	si := &ServerInfo{}
   603  	s.sys.sendq.push(newPubMsg(nil, subj, _EMPTY_, si, nil, si, noCompression, false, true))
   604  }
   605  
   606  // Will send a shutdown message.
   607  func (s *Server) sendShutdownEvent() {
   608  	s.mu.Lock()
   609  	if s.sys == nil || s.sys.sendq == nil {
   610  		s.mu.Unlock()
   611  		return
   612  	}
   613  	subj := fmt.Sprintf(shutdownEventSubj, s.info.ID)
   614  	sendq := s.sys.sendq
   615  	// Stop any more messages from queueing up.
   616  	s.sys.sendq = nil
   617  	// Unhook all msgHandlers. Normal client cleanup will deal with subs, etc.
   618  	s.sys.replies = nil
   619  	// Send to the internal queue and mark as last.
   620  	si := &ServerInfo{}
   621  	sendq.push(newPubMsg(nil, subj, _EMPTY_, si, nil, si, noCompression, false, true))
   622  	s.mu.Unlock()
   623  }
   624  
   625  // Used to send an internal message to an arbitrary account.
   626  func (s *Server) sendInternalAccountMsg(a *Account, subject string, msg interface{}) error {
   627  	return s.sendInternalAccountMsgWithReply(a, subject, _EMPTY_, nil, msg, false)
   628  }
   629  
   630  // Used to send an internal message with an optional reply to an arbitrary account.
   631  func (s *Server) sendInternalAccountMsgWithReply(a *Account, subject, reply string, hdr map[string]string, msg interface{}, echo bool) error {
   632  	s.mu.RLock()
   633  	if s.sys == nil || s.sys.sendq == nil {
   634  		s.mu.RUnlock()
   635  		return ErrNoSysAccount
   636  	}
   637  	c := s.sys.client
   638  	// Replace our client with the account's internal client.
   639  	if a != nil {
   640  		a.mu.Lock()
   641  		c = a.internalClient()
   642  		a.mu.Unlock()
   643  	}
   644  	s.sys.sendq.push(newPubMsg(c, subject, reply, nil, hdr, msg, noCompression, echo, false))
   645  	s.mu.RUnlock()
   646  	return nil
   647  }
   648  
   649  // Send system style message to an account scope.
   650  func (s *Server) sendInternalAccountSysMsg(a *Account, subj string, si *ServerInfo, msg any, ct compressionType) {
   651  	s.mu.RLock()
   652  	if s.sys == nil || s.sys.sendq == nil || a == nil {
   653  		s.mu.RUnlock()
   654  		return
   655  	}
   656  	sendq := s.sys.sendq
   657  	s.mu.RUnlock()
   658  
   659  	a.mu.Lock()
   660  	c := a.internalClient()
   661  	a.mu.Unlock()
   662  
   663  	sendq.push(newPubMsg(c, subj, _EMPTY_, si, nil, msg, ct, false, false))
   664  }
   665  
   666  // This will queue up a message to be sent.
   667  // Lock should not be held.
   668  func (s *Server) sendInternalMsgLocked(subj, rply string, si *ServerInfo, msg interface{}) {
   669  	s.mu.RLock()
   670  	s.sendInternalMsg(subj, rply, si, msg)
   671  	s.mu.RUnlock()
   672  }
   673  
   674  // This will queue up a message to be sent.
   675  // Assumes lock is held on entry.
   676  func (s *Server) sendInternalMsg(subj, rply string, si *ServerInfo, msg interface{}) {
   677  	if s.sys == nil || s.sys.sendq == nil {
   678  		return
   679  	}
   680  	s.sys.sendq.push(newPubMsg(nil, subj, rply, si, nil, msg, noCompression, false, false))
   681  }
   682  
   683  // Will send an api response.
   684  func (s *Server) sendInternalResponse(subj string, response *ServerAPIResponse) {
   685  	s.mu.RLock()
   686  	if s.sys == nil || s.sys.sendq == nil {
   687  		s.mu.RUnlock()
   688  		return
   689  	}
   690  	s.sys.sendq.push(newPubMsg(nil, subj, _EMPTY_, response.Server, nil, response, response.compress, false, false))
   691  	s.mu.RUnlock()
   692  }
   693  
   694  // Used to send internal messages from other system clients to avoid no echo issues.
   695  func (c *client) sendInternalMsg(subj, rply string, si *ServerInfo, msg interface{}) {
   696  	if c == nil {
   697  		return
   698  	}
   699  	s := c.srv
   700  	if s == nil {
   701  		return
   702  	}
   703  	s.mu.RLock()
   704  	if s.sys == nil || s.sys.sendq == nil {
   705  		s.mu.RUnlock()
   706  		return
   707  	}
   708  	s.sys.sendq.push(newPubMsg(c, subj, rply, si, nil, msg, noCompression, false, false))
   709  	s.mu.RUnlock()
   710  }
   711  
   712  // Locked version of checking if events system running. Also checks server.
   713  func (s *Server) eventsRunning() bool {
   714  	if s == nil {
   715  		return false
   716  	}
   717  	s.mu.RLock()
   718  	er := s.isRunning() && s.eventsEnabled()
   719  	s.mu.RUnlock()
   720  	return er
   721  }
   722  
   723  // EventsEnabled will report if the server has internal events enabled via
   724  // a defined system account.
   725  func (s *Server) EventsEnabled() bool {
   726  	s.mu.RLock()
   727  	defer s.mu.RUnlock()
   728  	return s.eventsEnabled()
   729  }
   730  
   731  // eventsEnabled will report if events are enabled.
   732  // Lock should be held.
   733  func (s *Server) eventsEnabled() bool {
   734  	return s.sys != nil && s.sys.client != nil && s.sys.account != nil
   735  }
   736  
   737  // TrackedRemoteServers returns how many remote servers we are tracking
   738  // from a system events perspective.
   739  func (s *Server) TrackedRemoteServers() int {
   740  	s.mu.RLock()
   741  	defer s.mu.RUnlock()
   742  	if !s.isRunning() || !s.eventsEnabled() {
   743  		return -1
   744  	}
   745  	return len(s.sys.servers)
   746  }
   747  
   748  // Check for orphan servers who may have gone away without notification.
   749  // This should be wrapChk() to setup common locking.
   750  func (s *Server) checkRemoteServers() {
   751  	now := time.Now()
   752  	for sid, su := range s.sys.servers {
   753  		if now.Sub(su.ltime) > s.sys.orphMax {
   754  			s.Debugf("Detected orphan remote server: %q", sid)
   755  			// Simulate it going away.
   756  			s.processRemoteServerShutdown(sid)
   757  		}
   758  	}
   759  	if s.sys.sweeper != nil {
   760  		s.sys.sweeper.Reset(s.sys.chkOrph)
   761  	}
   762  }
   763  
   764  // Grab RSS and PCPU
   765  // Server lock will be held but released.
   766  func (s *Server) updateServerUsage(v *ServerStats) {
   767  	var vss int64
   768  	pse.ProcUsage(&v.CPU, &v.Mem, &vss)
   769  	v.Cores = runtime.NumCPU()
   770  }
   771  
   772  // Generate a route stat for our statz update.
   773  func routeStat(r *client) *RouteStat {
   774  	if r == nil {
   775  		return nil
   776  	}
   777  	r.mu.Lock()
   778  	// Note: *client.out[Msgs|Bytes] are not set using atomics,
   779  	// unlike in[Msgs|Bytes].
   780  	rs := &RouteStat{
   781  		ID: r.cid,
   782  		Sent: DataStats{
   783  			Msgs:  r.outMsgs,
   784  			Bytes: r.outBytes,
   785  		},
   786  		Received: DataStats{
   787  			Msgs:  atomic.LoadInt64(&r.inMsgs),
   788  			Bytes: atomic.LoadInt64(&r.inBytes),
   789  		},
   790  		Pending: int(r.out.pb),
   791  	}
   792  	if r.route != nil {
   793  		rs.Name = r.route.remoteName
   794  	}
   795  	r.mu.Unlock()
   796  	return rs
   797  }
   798  
   799  // Actual send method for statz updates.
   800  // Lock should be held.
   801  func (s *Server) sendStatsz(subj string) {
   802  	var m ServerStatsMsg
   803  	s.updateServerUsage(&m.Stats)
   804  
   805  	s.mu.RLock()
   806  	defer s.mu.RUnlock()
   807  
   808  	// Check that we have a system account, etc.
   809  	if s.sys == nil || s.sys.account == nil {
   810  		return
   811  	}
   812  
   813  	shouldCheckInterest := func() bool {
   814  		opts := s.getOpts()
   815  		if opts.Cluster.Port != 0 || opts.Gateway.Port != 0 || opts.LeafNode.Port != 0 {
   816  			return false
   817  		}
   818  		// If we are here we have no clustering or gateways and are not a leafnode hub.
   819  		// Check for leafnode remotes that connect the system account.
   820  		if len(opts.LeafNode.Remotes) > 0 {
   821  			sysAcc := s.sys.account.GetName()
   822  			for _, r := range opts.LeafNode.Remotes {
   823  				if r.LocalAccount == sysAcc {
   824  					return false
   825  				}
   826  			}
   827  		}
   828  		return true
   829  	}
   830  
   831  	// if we are running standalone, check for interest.
   832  	if shouldCheckInterest() {
   833  		// Check if we even have interest in this subject.
   834  		sacc := s.sys.account
   835  		rr := sacc.sl.Match(subj)
   836  		totalSubs := len(rr.psubs) + len(rr.qsubs)
   837  		if totalSubs == 0 {
   838  			return
   839  		} else if totalSubs == 1 && len(rr.psubs) == 1 {
   840  			// For the broadcast subject we listen to that ourselves with no echo for remote updates.
   841  			// If we are the only ones listening do not send either.
   842  			if rr.psubs[0] == s.sys.remoteStatsSub {
   843  				return
   844  			}
   845  		}
   846  	}
   847  
   848  	m.Stats.Start = s.start
   849  	m.Stats.Connections = len(s.clients)
   850  	m.Stats.TotalConnections = s.totalClients
   851  	m.Stats.ActiveAccounts = int(atomic.LoadInt32(&s.activeAccounts))
   852  	m.Stats.Received.Msgs = atomic.LoadInt64(&s.inMsgs)
   853  	m.Stats.Received.Bytes = atomic.LoadInt64(&s.inBytes)
   854  	m.Stats.Sent.Msgs = atomic.LoadInt64(&s.outMsgs)
   855  	m.Stats.Sent.Bytes = atomic.LoadInt64(&s.outBytes)
   856  	m.Stats.SlowConsumers = atomic.LoadInt64(&s.slowConsumers)
   857  	m.Stats.NumSubs = s.numSubscriptions()
   858  	// Routes
   859  	s.forEachRoute(func(r *client) {
   860  		m.Stats.Routes = append(m.Stats.Routes, routeStat(r))
   861  	})
   862  	// Gateways
   863  	if s.gateway.enabled {
   864  		gw := s.gateway
   865  		gw.RLock()
   866  		for name, c := range gw.out {
   867  			gs := &GatewayStat{Name: name}
   868  			c.mu.Lock()
   869  			gs.ID = c.cid
   870  			// Note that *client.out[Msgs|Bytes] are not set using atomic,
   871  			// unlike the in[Msgs|bytes].
   872  			gs.Sent = DataStats{
   873  				Msgs:  c.outMsgs,
   874  				Bytes: c.outBytes,
   875  			}
   876  			c.mu.Unlock()
   877  			// Gather matching inbound connections
   878  			gs.Received = DataStats{}
   879  			for _, c := range gw.in {
   880  				c.mu.Lock()
   881  				if c.gw.name == name {
   882  					gs.Received.Msgs += atomic.LoadInt64(&c.inMsgs)
   883  					gs.Received.Bytes += atomic.LoadInt64(&c.inBytes)
   884  					gs.NumInbound++
   885  				}
   886  				c.mu.Unlock()
   887  			}
   888  			m.Stats.Gateways = append(m.Stats.Gateways, gs)
   889  		}
   890  		gw.RUnlock()
   891  	}
   892  	// Active Servers
   893  	m.Stats.ActiveServers = len(s.sys.servers) + 1
   894  
   895  	// JetStream
   896  	if js := s.js.Load(); js != nil {
   897  		jStat := &JetStreamVarz{}
   898  		s.mu.RUnlock()
   899  		js.mu.RLock()
   900  		c := js.config
   901  		c.StoreDir = _EMPTY_
   902  		jStat.Config = &c
   903  		js.mu.RUnlock()
   904  		jStat.Stats = js.usageStats()
   905  		// Update our own usage since we do not echo so we will not hear ourselves.
   906  		ourNode := getHash(s.serverName())
   907  		if v, ok := s.nodeToInfo.Load(ourNode); ok && v != nil {
   908  			ni := v.(nodeInfo)
   909  			ni.stats = jStat.Stats
   910  			ni.cfg = jStat.Config
   911  			s.optsMu.RLock()
   912  			ni.tags = copyStrings(s.opts.Tags)
   913  			s.optsMu.RUnlock()
   914  			s.nodeToInfo.Store(ourNode, ni)
   915  		}
   916  		// Metagroup info.
   917  		if mg := js.getMetaGroup(); mg != nil {
   918  			if mg.Leader() {
   919  				if ci := s.raftNodeToClusterInfo(mg); ci != nil {
   920  					jStat.Meta = &MetaClusterInfo{
   921  						Name:     ci.Name,
   922  						Leader:   ci.Leader,
   923  						Peer:     getHash(ci.Leader),
   924  						Replicas: ci.Replicas,
   925  						Size:     mg.ClusterSize(),
   926  					}
   927  				}
   928  			} else {
   929  				// non leader only include a shortened version without peers
   930  				leader := s.serverNameForNode(mg.GroupLeader())
   931  				jStat.Meta = &MetaClusterInfo{
   932  					Name:   mg.Group(),
   933  					Leader: leader,
   934  					Peer:   getHash(leader),
   935  					Size:   mg.ClusterSize(),
   936  				}
   937  			}
   938  		}
   939  		m.Stats.JetStream = jStat
   940  		s.mu.RLock()
   941  	}
   942  	// Send message.
   943  	s.sendInternalMsg(subj, _EMPTY_, &m.Server, &m)
   944  }
   945  
   946  // Send out our statz update.
   947  // This should be wrapChk() to setup common locking.
   948  func (s *Server) heartbeatStatsz() {
   949  	if s.sys.stmr != nil {
   950  		// Increase after startup to our max.
   951  		if s.sys.cstatsz < s.sys.statsz {
   952  			s.sys.cstatsz *= 2
   953  			if s.sys.cstatsz > s.sys.statsz {
   954  				s.sys.cstatsz = s.sys.statsz
   955  			}
   956  		}
   957  		s.sys.stmr.Reset(s.sys.cstatsz)
   958  	}
   959  	// Do in separate Go routine.
   960  	go s.sendStatszUpdate()
   961  }
   962  
   963  func (s *Server) sendStatszUpdate() {
   964  	s.sendStatsz(fmt.Sprintf(serverStatsSubj, s.ID()))
   965  }
   966  
   967  // This should be wrapChk() to setup common locking.
   968  func (s *Server) startStatszTimer() {
   969  	// We will start by sending out more of these and trail off to the statsz being the max.
   970  	s.sys.cstatsz = 250 * time.Millisecond
   971  	// Send out the first one quickly, we will slowly back off.
   972  	s.sys.stmr = time.AfterFunc(s.sys.cstatsz, s.wrapChk(s.heartbeatStatsz))
   973  }
   974  
   975  // Start a ticker that will fire periodically and check for orphaned servers.
   976  // This should be wrapChk() to setup common locking.
   977  func (s *Server) startRemoteServerSweepTimer() {
   978  	s.sys.sweeper = time.AfterFunc(s.sys.chkOrph, s.wrapChk(s.checkRemoteServers))
   979  }
   980  
   981  // Length of our system hash used for server targeted messages.
   982  const sysHashLen = 8
   983  
   984  // Computes a hash of 8 characters for the name.
   985  func getHash(name string) string {
   986  	return getHashSize(name, sysHashLen)
   987  }
   988  
   989  // Computes a hash for the given `name`. The result will be `size` characters long.
   990  func getHashSize(name string, size int) string {
   991  	sha := sha256.New()
   992  	sha.Write([]byte(name))
   993  	b := sha.Sum(nil)
   994  	for i := 0; i < size; i++ {
   995  		b[i] = digits[int(b[i]%base)]
   996  	}
   997  	return string(b[:size])
   998  }
   999  
  1000  // Returns the node name for this server which is a hash of the server name.
  1001  func (s *Server) Node() string {
  1002  	s.mu.RLock()
  1003  	defer s.mu.RUnlock()
  1004  	if s.sys != nil {
  1005  		return s.sys.shash
  1006  	}
  1007  	return _EMPTY_
  1008  }
  1009  
  1010  // This will setup our system wide tracking subs.
  1011  // For now we will setup one wildcard subscription to
  1012  // monitor all accounts for changes in number of connections.
  1013  // We can make this on a per account tracking basis if needed.
  1014  // Tradeoff is subscription and interest graph events vs connect and
  1015  // disconnect events, etc.
  1016  func (s *Server) initEventTracking() {
  1017  	if !s.EventsEnabled() {
  1018  		return
  1019  	}
  1020  	// Create a system hash which we use for other servers to target us specifically.
  1021  	s.sys.shash = getHash(s.info.Name)
  1022  
  1023  	// This will be for all inbox responses.
  1024  	subject := fmt.Sprintf(inboxRespSubj, s.sys.shash, "*")
  1025  	if _, err := s.sysSubscribe(subject, s.inboxReply); err != nil {
  1026  		s.Errorf("Error setting up internal tracking: %v", err)
  1027  	}
  1028  	s.sys.inboxPre = subject
  1029  	// This is for remote updates for connection accounting.
  1030  	subject = fmt.Sprintf(accConnsEventSubjOld, "*")
  1031  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.remoteConnsUpdate)); err != nil {
  1032  		s.Errorf("Error setting up internal tracking for %s: %v", subject, err)
  1033  	}
  1034  	// This will be for responses for account info that we send out.
  1035  	subject = fmt.Sprintf(connsRespSubj, s.info.ID)
  1036  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.remoteConnsUpdate)); err != nil {
  1037  		s.Errorf("Error setting up internal tracking: %v", err)
  1038  	}
  1039  	// Listen for broad requests to respond with number of subscriptions for a given subject.
  1040  	if _, err := s.sysSubscribe(accNumSubsReqSubj, s.noInlineCallback(s.nsubsRequest)); err != nil {
  1041  		s.Errorf("Error setting up internal tracking: %v", err)
  1042  	}
  1043  	// Listen for statsz from others.
  1044  	subject = fmt.Sprintf(serverStatsSubj, "*")
  1045  	if sub, err := s.sysSubscribe(subject, s.noInlineCallback(s.remoteServerUpdate)); err != nil {
  1046  		s.Errorf("Error setting up internal tracking: %v", err)
  1047  	} else {
  1048  		// Keep track of this one.
  1049  		s.sys.remoteStatsSub = sub
  1050  	}
  1051  	// Listen for all server shutdowns.
  1052  	subject = fmt.Sprintf(shutdownEventSubj, "*")
  1053  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.remoteServerShutdown)); err != nil {
  1054  		s.Errorf("Error setting up internal tracking: %v", err)
  1055  	}
  1056  	// Listen for servers entering lame-duck mode.
  1057  	// NOTE: This currently is handled in the same way as a server shutdown, but has
  1058  	// a different subject in case we need to handle differently in future.
  1059  	subject = fmt.Sprintf(lameDuckEventSubj, "*")
  1060  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.remoteServerShutdown)); err != nil {
  1061  		s.Errorf("Error setting up internal tracking: %v", err)
  1062  	}
  1063  	// Listen for account claims updates.
  1064  	subscribeToUpdate := true
  1065  	if s.accResolver != nil {
  1066  		subscribeToUpdate = !s.accResolver.IsTrackingUpdate()
  1067  	}
  1068  	if subscribeToUpdate {
  1069  		for _, sub := range []string{accUpdateEventSubjOld, accUpdateEventSubjNew} {
  1070  			if _, err := s.sysSubscribe(fmt.Sprintf(sub, "*"), s.noInlineCallback(s.accountClaimUpdate)); err != nil {
  1071  				s.Errorf("Error setting up internal tracking: %v", err)
  1072  			}
  1073  		}
  1074  	}
  1075  	// Listen for ping messages that will be sent to all servers for statsz.
  1076  	// This subscription is kept for backwards compatibility. Got replaced by ...PING.STATZ from below
  1077  	if _, err := s.sysSubscribe(serverStatsPingReqSubj, s.noInlineCallback(s.statszReq)); err != nil {
  1078  		s.Errorf("Error setting up internal tracking: %v", err)
  1079  	}
  1080  	monSrvc := map[string]sysMsgHandler{
  1081  		"IDZ":    s.idzReq,
  1082  		"STATSZ": s.statszReq,
  1083  		"VARZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1084  			optz := &VarzEventOptions{}
  1085  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Varz(&optz.VarzOptions) })
  1086  		},
  1087  		"SUBSZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1088  			optz := &SubszEventOptions{}
  1089  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Subsz(&optz.SubszOptions) })
  1090  		},
  1091  		"CONNZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1092  			optz := &ConnzEventOptions{}
  1093  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Connz(&optz.ConnzOptions) })
  1094  		},
  1095  		"ROUTEZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1096  			optz := &RoutezEventOptions{}
  1097  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Routez(&optz.RoutezOptions) })
  1098  		},
  1099  		"GATEWAYZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1100  			optz := &GatewayzEventOptions{}
  1101  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Gatewayz(&optz.GatewayzOptions) })
  1102  		},
  1103  		"LEAFZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1104  			optz := &LeafzEventOptions{}
  1105  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Leafz(&optz.LeafzOptions) })
  1106  		},
  1107  		"ACCOUNTZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1108  			optz := &AccountzEventOptions{}
  1109  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Accountz(&optz.AccountzOptions) })
  1110  		},
  1111  		"JSZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1112  			optz := &JszEventOptions{}
  1113  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.Jsz(&optz.JSzOptions) })
  1114  		},
  1115  		"HEALTHZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1116  			optz := &HealthzEventOptions{}
  1117  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.healthz(&optz.HealthzOptions), nil })
  1118  		},
  1119  		"PROFILEZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1120  			optz := &ProfilezEventOptions{}
  1121  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) { return s.profilez(&optz.ProfilezOptions), nil })
  1122  		},
  1123  	}
  1124  	for name, req := range monSrvc {
  1125  		subject = fmt.Sprintf(serverDirectReqSubj, s.info.ID, name)
  1126  		if _, err := s.sysSubscribe(subject, s.noInlineCallback(req)); err != nil {
  1127  			s.Errorf("Error setting up internal tracking: %v", err)
  1128  		}
  1129  		subject = fmt.Sprintf(serverPingReqSubj, name)
  1130  		if _, err := s.sysSubscribe(subject, s.noInlineCallback(req)); err != nil {
  1131  			s.Errorf("Error setting up internal tracking: %v", err)
  1132  		}
  1133  	}
  1134  	extractAccount := func(c *client, subject string, msg []byte) (string, error) {
  1135  		if tk := strings.Split(subject, tsep); len(tk) != accReqTokens {
  1136  			return _EMPTY_, fmt.Errorf("subject %q is malformed", subject)
  1137  		} else {
  1138  			return tk[accReqAccIndex], nil
  1139  		}
  1140  	}
  1141  	monAccSrvc := map[string]sysMsgHandler{
  1142  		"SUBSZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1143  			optz := &SubszEventOptions{}
  1144  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1145  				if acc, err := extractAccount(c, subject, msg); err != nil {
  1146  					return nil, err
  1147  				} else {
  1148  					optz.SubszOptions.Subscriptions = true
  1149  					optz.SubszOptions.Account = acc
  1150  					return s.Subsz(&optz.SubszOptions)
  1151  				}
  1152  			})
  1153  		},
  1154  		"CONNZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1155  			optz := &ConnzEventOptions{}
  1156  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1157  				if acc, err := extractAccount(c, subject, msg); err != nil {
  1158  					return nil, err
  1159  				} else {
  1160  					optz.ConnzOptions.Account = acc
  1161  					return s.Connz(&optz.ConnzOptions)
  1162  				}
  1163  			})
  1164  		},
  1165  		"LEAFZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1166  			optz := &LeafzEventOptions{}
  1167  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1168  				if acc, err := extractAccount(c, subject, msg); err != nil {
  1169  					return nil, err
  1170  				} else {
  1171  					optz.LeafzOptions.Account = acc
  1172  					return s.Leafz(&optz.LeafzOptions)
  1173  				}
  1174  			})
  1175  		},
  1176  		"JSZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1177  			optz := &JszEventOptions{}
  1178  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1179  				if acc, err := extractAccount(c, subject, msg); err != nil {
  1180  					return nil, err
  1181  				} else {
  1182  					optz.Account = acc
  1183  					return s.JszAccount(&optz.JSzOptions)
  1184  				}
  1185  			})
  1186  		},
  1187  		"INFO": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1188  			optz := &AccInfoEventOptions{}
  1189  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1190  				if acc, err := extractAccount(c, subject, msg); err != nil {
  1191  					return nil, err
  1192  				} else {
  1193  					return s.accountInfo(acc)
  1194  				}
  1195  			})
  1196  		},
  1197  		// STATZ is essentially a duplicate of CONNS with an envelope identical to the others.
  1198  		// For historical reasons CONNS is the odd one out.
  1199  		// STATZ is also less heavy weight than INFO
  1200  		"STATZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1201  			optz := &AccountStatzEventOptions{}
  1202  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1203  				if acc, err := extractAccount(c, subject, msg); err != nil {
  1204  					return nil, err
  1205  				} else if acc == "PING" { // Filter PING subject. Happens for server as well. But wildcards are not used
  1206  					return nil, errSkipZreq
  1207  				} else {
  1208  					optz.Accounts = []string{acc}
  1209  					if stz, err := s.AccountStatz(&optz.AccountStatzOptions); err != nil {
  1210  						return nil, err
  1211  					} else if len(stz.Accounts) == 0 && !optz.IncludeUnused {
  1212  						return nil, errSkipZreq
  1213  					} else {
  1214  						return stz, nil
  1215  					}
  1216  				}
  1217  			})
  1218  		},
  1219  		"CONNS": s.connsRequest,
  1220  	}
  1221  	for name, req := range monAccSrvc {
  1222  		if _, err := s.sysSubscribe(fmt.Sprintf(accDirectReqSubj, "*", name), s.noInlineCallback(req)); err != nil {
  1223  			s.Errorf("Error setting up internal tracking: %v", err)
  1224  		}
  1225  	}
  1226  
  1227  	// User info.
  1228  	// TODO(dlc) - Can be internal and not forwarded since bound server for the client connection
  1229  	// is only one that will answer. This breaks tests since we still forward on remote server connect.
  1230  	if _, err := s.sysSubscribe(fmt.Sprintf(userDirectReqSubj, "*"), s.userInfoReq); err != nil {
  1231  		s.Errorf("Error setting up internal tracking: %v", err)
  1232  	}
  1233  
  1234  	// For now only the STATZ subject has an account specific ping equivalent.
  1235  	if _, err := s.sysSubscribe(fmt.Sprintf(accPingReqSubj, "STATZ"),
  1236  		s.noInlineCallback(func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1237  			optz := &AccountStatzEventOptions{}
  1238  			s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (interface{}, error) {
  1239  				if stz, err := s.AccountStatz(&optz.AccountStatzOptions); err != nil {
  1240  					return nil, err
  1241  				} else if len(stz.Accounts) == 0 && !optz.IncludeUnused {
  1242  					return nil, errSkipZreq
  1243  				} else {
  1244  					return stz, nil
  1245  				}
  1246  			})
  1247  		})); err != nil {
  1248  		s.Errorf("Error setting up internal tracking: %v", err)
  1249  	}
  1250  
  1251  	// Listen for updates when leaf nodes connect for a given account. This will
  1252  	// force any gateway connections to move to `modeInterestOnly`
  1253  	subject = fmt.Sprintf(leafNodeConnectEventSubj, "*")
  1254  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.leafNodeConnected)); err != nil {
  1255  		s.Errorf("Error setting up internal tracking: %v", err)
  1256  	}
  1257  	// For tracking remote latency measurements.
  1258  	subject = fmt.Sprintf(remoteLatencyEventSubj, s.sys.shash)
  1259  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.remoteLatencyUpdate)); err != nil {
  1260  		s.Errorf("Error setting up internal latency tracking: %v", err)
  1261  	}
  1262  	// This is for simple debugging of number of subscribers that exist in the system.
  1263  	if _, err := s.sysSubscribeInternal(accSubsSubj, s.noInlineCallback(s.debugSubscribers)); err != nil {
  1264  		s.Errorf("Error setting up internal debug service for subscribers: %v", err)
  1265  	}
  1266  
  1267  	// Listen for requests to reload the server configuration.
  1268  	subject = fmt.Sprintf(serverReloadReqSubj, s.info.ID)
  1269  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.reloadConfig)); err != nil {
  1270  		s.Errorf("Error setting up server reload handler: %v", err)
  1271  	}
  1272  
  1273  	// Client connection kick
  1274  	subject = fmt.Sprintf(clientKickReqSubj, s.info.ID)
  1275  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.kickClient)); err != nil {
  1276  		s.Errorf("Error setting up client kick service: %v", err)
  1277  	}
  1278  	// Client connection LDM
  1279  	subject = fmt.Sprintf(clientLDMReqSubj, s.info.ID)
  1280  	if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.ldmClient)); err != nil {
  1281  		s.Errorf("Error setting up client LDM service: %v", err)
  1282  	}
  1283  }
  1284  
  1285  // UserInfo returns basic information to a user about bound account and user permissions.
  1286  // For account information they will need to ping that separately, and this allows security
  1287  // controls on each subsystem if desired, e.g. account info, jetstream account info, etc.
  1288  type UserInfo struct {
  1289  	UserID      string        `json:"user"`
  1290  	Account     string        `json:"account"`
  1291  	Permissions *Permissions  `json:"permissions,omitempty"`
  1292  	Expires     time.Duration `json:"expires,omitempty"`
  1293  }
  1294  
  1295  // Process a user info request.
  1296  func (s *Server) userInfoReq(sub *subscription, c *client, _ *Account, subject, reply string, msg []byte) {
  1297  	if !s.EventsEnabled() || reply == _EMPTY_ {
  1298  		return
  1299  	}
  1300  
  1301  	response := &ServerAPIResponse{Server: &ServerInfo{}}
  1302  
  1303  	ci, _, _, _, err := s.getRequestInfo(c, msg)
  1304  	if err != nil {
  1305  		response.Error = &ApiError{Code: http.StatusBadRequest}
  1306  		s.sendInternalResponse(reply, response)
  1307  		return
  1308  	}
  1309  
  1310  	response.Data = &UserInfo{
  1311  		UserID:      ci.User,
  1312  		Account:     ci.Account,
  1313  		Permissions: c.publicPermissions(),
  1314  		Expires:     c.claimExpiration(),
  1315  	}
  1316  	s.sendInternalResponse(reply, response)
  1317  }
  1318  
  1319  // register existing accounts with any system exports.
  1320  func (s *Server) registerSystemImportsForExisting() {
  1321  	var accounts []*Account
  1322  
  1323  	s.mu.RLock()
  1324  	if s.sys == nil {
  1325  		s.mu.RUnlock()
  1326  		return
  1327  	}
  1328  	sacc := s.sys.account
  1329  	s.accounts.Range(func(k, v interface{}) bool {
  1330  		a := v.(*Account)
  1331  		if a != sacc {
  1332  			accounts = append(accounts, a)
  1333  		}
  1334  		return true
  1335  	})
  1336  	s.mu.RUnlock()
  1337  
  1338  	for _, a := range accounts {
  1339  		s.registerSystemImports(a)
  1340  	}
  1341  }
  1342  
  1343  // add all exports a system account will need
  1344  func (s *Server) addSystemAccountExports(sacc *Account) {
  1345  	if !s.EventsEnabled() {
  1346  		return
  1347  	}
  1348  	accConnzSubj := fmt.Sprintf(accDirectReqSubj, "*", "CONNZ")
  1349  	// prioritize not automatically added exports
  1350  	if !sacc.hasServiceExportMatching(accConnzSubj) {
  1351  		// pick export type that clamps importing account id into subject
  1352  		if err := sacc.addServiceExportWithResponseAndAccountPos(accConnzSubj, Streamed, nil, 4); err != nil {
  1353  			//if err := sacc.AddServiceExportWithResponse(accConnzSubj, Streamed, nil); err != nil {
  1354  			s.Errorf("Error adding system service export for %q: %v", accConnzSubj, err)
  1355  		}
  1356  	}
  1357  	// prioritize not automatically added exports
  1358  	accStatzSubj := fmt.Sprintf(accDirectReqSubj, "*", "STATZ")
  1359  	if !sacc.hasServiceExportMatching(accStatzSubj) {
  1360  		// pick export type that clamps importing account id into subject
  1361  		if err := sacc.addServiceExportWithResponseAndAccountPos(accStatzSubj, Streamed, nil, 4); err != nil {
  1362  			s.Errorf("Error adding system service export for %q: %v", accStatzSubj, err)
  1363  		}
  1364  	}
  1365  	// FIXME(dlc) - Old experiment, Remove?
  1366  	if !sacc.hasServiceExportMatching(accSubsSubj) {
  1367  		if err := sacc.AddServiceExport(accSubsSubj, nil); err != nil {
  1368  			s.Errorf("Error adding system service export for %q: %v", accSubsSubj, err)
  1369  		}
  1370  	}
  1371  
  1372  	// User info export.
  1373  	userInfoSubj := fmt.Sprintf(userDirectReqSubj, "*")
  1374  	if !sacc.hasServiceExportMatching(userInfoSubj) {
  1375  		if err := sacc.AddServiceExport(userInfoSubj, nil); err != nil {
  1376  			s.Errorf("Error adding system service export for %q: %v", userInfoSubj, err)
  1377  		}
  1378  		mappedSubj := fmt.Sprintf(userDirectReqSubj, sacc.GetName())
  1379  		if err := sacc.AddServiceImport(sacc, userDirectInfoSubj, mappedSubj); err != nil {
  1380  			s.Errorf("Error setting up system service import %s: %v", mappedSubj, err)
  1381  		}
  1382  		// Make sure to share details.
  1383  		sacc.setServiceImportSharing(sacc, mappedSubj, false, true)
  1384  	}
  1385  
  1386  	// Register any accounts that existed prior.
  1387  	s.registerSystemImportsForExisting()
  1388  
  1389  	// in case of a mixed mode setup, enable js exports anyway
  1390  	if s.JetStreamEnabled() || !s.standAloneMode() {
  1391  		s.checkJetStreamExports()
  1392  	}
  1393  }
  1394  
  1395  // accountClaimUpdate will receive claim updates for accounts.
  1396  func (s *Server) accountClaimUpdate(sub *subscription, c *client, _ *Account, subject, resp string, hdr, msg []byte) {
  1397  	if !s.EventsEnabled() {
  1398  		return
  1399  	}
  1400  	var pubKey string
  1401  	toks := strings.Split(subject, tsep)
  1402  	if len(toks) == accUpdateTokensNew {
  1403  		pubKey = toks[accReqAccIndex]
  1404  	} else if len(toks) == accUpdateTokensOld {
  1405  		pubKey = toks[accUpdateAccIdxOld]
  1406  	} else {
  1407  		s.Debugf("Received account claims update on bad subject %q", subject)
  1408  		return
  1409  	}
  1410  	if len(msg) == 0 {
  1411  		err := errors.New("request body is empty")
  1412  		respondToUpdate(s, resp, pubKey, "jwt update error", err)
  1413  	} else if claim, err := jwt.DecodeAccountClaims(string(msg)); err != nil {
  1414  		respondToUpdate(s, resp, pubKey, "jwt update resulted in error", err)
  1415  	} else if claim.Subject != pubKey {
  1416  		err := errors.New("subject does not match jwt content")
  1417  		respondToUpdate(s, resp, pubKey, "jwt update resulted in error", err)
  1418  	} else if v, ok := s.accounts.Load(pubKey); !ok {
  1419  		respondToUpdate(s, resp, pubKey, "jwt update skipped", nil)
  1420  	} else if err := s.updateAccountWithClaimJWT(v.(*Account), string(msg)); err != nil {
  1421  		respondToUpdate(s, resp, pubKey, "jwt update resulted in error", err)
  1422  	} else {
  1423  		respondToUpdate(s, resp, pubKey, "jwt updated", nil)
  1424  	}
  1425  }
  1426  
  1427  // processRemoteServerShutdown will update any affected accounts.
  1428  // Will update the remote count for clients.
  1429  // Lock assume held.
  1430  func (s *Server) processRemoteServerShutdown(sid string) {
  1431  	s.accounts.Range(func(k, v interface{}) bool {
  1432  		v.(*Account).removeRemoteServer(sid)
  1433  		return true
  1434  	})
  1435  	// Update any state in nodeInfo.
  1436  	s.nodeToInfo.Range(func(k, v interface{}) bool {
  1437  		ni := v.(nodeInfo)
  1438  		if ni.id == sid {
  1439  			ni.offline = true
  1440  			s.nodeToInfo.Store(k, ni)
  1441  			return false
  1442  		}
  1443  		return true
  1444  	})
  1445  	delete(s.sys.servers, sid)
  1446  }
  1447  
  1448  func (s *Server) sameDomain(domain string) bool {
  1449  	return domain == _EMPTY_ || s.info.Domain == _EMPTY_ || domain == s.info.Domain
  1450  }
  1451  
  1452  // remoteServerShutdownEvent is called when we get an event from another server shutting down.
  1453  func (s *Server) remoteServerShutdown(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1454  	s.mu.Lock()
  1455  	defer s.mu.Unlock()
  1456  	if !s.eventsEnabled() {
  1457  		return
  1458  	}
  1459  	toks := strings.Split(subject, tsep)
  1460  	if len(toks) < shutdownEventTokens {
  1461  		s.Debugf("Received remote server shutdown on bad subject %q", subject)
  1462  		return
  1463  	}
  1464  
  1465  	if len(msg) == 0 {
  1466  		s.Errorf("Remote server sent invalid (empty) shutdown message to %q", subject)
  1467  		return
  1468  	}
  1469  
  1470  	// We have an optional serverInfo here, remove from nodeToX lookups.
  1471  	var si ServerInfo
  1472  	if err := json.Unmarshal(msg, &si); err != nil {
  1473  		s.Debugf("Received bad server info for remote server shutdown")
  1474  		return
  1475  	}
  1476  
  1477  	// JetStream node updates if applicable.
  1478  	node := getHash(si.Name)
  1479  	if v, ok := s.nodeToInfo.Load(node); ok && v != nil {
  1480  		ni := v.(nodeInfo)
  1481  		ni.offline = true
  1482  		s.nodeToInfo.Store(node, ni)
  1483  	}
  1484  
  1485  	sid := toks[serverSubjectIndex]
  1486  	if su := s.sys.servers[sid]; su != nil {
  1487  		s.processRemoteServerShutdown(sid)
  1488  	}
  1489  }
  1490  
  1491  // remoteServerUpdate listens for statsz updates from other servers.
  1492  func (s *Server) remoteServerUpdate(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1493  	var ssm ServerStatsMsg
  1494  	if len(msg) == 0 {
  1495  		s.Debugf("Received empty server info for remote server update")
  1496  		return
  1497  	} else if err := json.Unmarshal(msg, &ssm); err != nil {
  1498  		s.Debugf("Received bad server info for remote server update")
  1499  		return
  1500  	}
  1501  	si := ssm.Server
  1502  
  1503  	// Should do normal updates before bailing if wrong domain.
  1504  	s.mu.Lock()
  1505  	if s.isRunning() && s.eventsEnabled() && ssm.Server.ID != s.info.ID {
  1506  		s.updateRemoteServer(&si)
  1507  	}
  1508  	s.mu.Unlock()
  1509  
  1510  	// JetStream node updates.
  1511  	if !s.sameDomain(si.Domain) {
  1512  		return
  1513  	}
  1514  
  1515  	var cfg *JetStreamConfig
  1516  	var stats *JetStreamStats
  1517  
  1518  	if ssm.Stats.JetStream != nil {
  1519  		cfg = ssm.Stats.JetStream.Config
  1520  		stats = ssm.Stats.JetStream.Stats
  1521  	}
  1522  
  1523  	node := getHash(si.Name)
  1524  	s.nodeToInfo.Store(node, nodeInfo{
  1525  		si.Name,
  1526  		si.Version,
  1527  		si.Cluster,
  1528  		si.Domain,
  1529  		si.ID,
  1530  		si.Tags,
  1531  		cfg,
  1532  		stats,
  1533  		false,
  1534  		si.JetStreamEnabled(),
  1535  		si.BinaryStreamSnapshot(),
  1536  	})
  1537  }
  1538  
  1539  // updateRemoteServer is called when we have an update from a remote server.
  1540  // This allows us to track remote servers, respond to shutdown messages properly,
  1541  // make sure that messages are ordered, and allow us to prune dead servers.
  1542  // Lock should be held upon entry.
  1543  func (s *Server) updateRemoteServer(si *ServerInfo) {
  1544  	su := s.sys.servers[si.ID]
  1545  	if su == nil {
  1546  		s.sys.servers[si.ID] = &serverUpdate{si.Seq, time.Now()}
  1547  		s.processNewServer(si)
  1548  	} else {
  1549  		// Should always be going up.
  1550  		if si.Seq <= su.seq {
  1551  			s.Errorf("Received out of order remote server update from: %q", si.ID)
  1552  			return
  1553  		}
  1554  		su.seq = si.Seq
  1555  		su.ltime = time.Now()
  1556  	}
  1557  }
  1558  
  1559  // processNewServer will hold any logic we want to use when we discover a new server.
  1560  // Lock should be held upon entry.
  1561  func (s *Server) processNewServer(si *ServerInfo) {
  1562  	// Right now we only check if we have leafnode servers and if so send another
  1563  	// connect update to make sure they switch this account to interest only mode.
  1564  	s.ensureGWsInterestOnlyForLeafNodes()
  1565  
  1566  	// Add to our nodeToName
  1567  	if s.sameDomain(si.Domain) {
  1568  		node := getHash(si.Name)
  1569  		// Only update if non-existent
  1570  		if _, ok := s.nodeToInfo.Load(node); !ok {
  1571  			s.nodeToInfo.Store(node, nodeInfo{
  1572  				si.Name,
  1573  				si.Version,
  1574  				si.Cluster,
  1575  				si.Domain,
  1576  				si.ID,
  1577  				si.Tags,
  1578  				nil,
  1579  				nil,
  1580  				false,
  1581  				si.JetStreamEnabled(),
  1582  				si.BinaryStreamSnapshot(),
  1583  			})
  1584  		}
  1585  	}
  1586  	// Announce ourselves..
  1587  	// Do this in a separate Go routine.
  1588  	go s.sendStatszUpdate()
  1589  }
  1590  
  1591  // If GW is enabled on this server and there are any leaf node connections,
  1592  // this function will send a LeafNode connect system event to the super cluster
  1593  // to ensure that the GWs are in interest-only mode for this account.
  1594  // Lock should be held upon entry.
  1595  // TODO(dlc) - this will cause this account to be loaded on all servers. Need a better
  1596  // way with GW2.
  1597  func (s *Server) ensureGWsInterestOnlyForLeafNodes() {
  1598  	if !s.gateway.enabled || len(s.leafs) == 0 {
  1599  		return
  1600  	}
  1601  	sent := make(map[*Account]bool, len(s.leafs))
  1602  	for _, c := range s.leafs {
  1603  		if !sent[c.acc] {
  1604  			s.sendLeafNodeConnectMsg(c.acc.Name)
  1605  			sent[c.acc] = true
  1606  		}
  1607  	}
  1608  }
  1609  
  1610  // shutdownEventing will clean up all eventing state.
  1611  func (s *Server) shutdownEventing() {
  1612  	if !s.eventsRunning() {
  1613  		return
  1614  	}
  1615  
  1616  	s.mu.Lock()
  1617  	clearTimer(&s.sys.sweeper)
  1618  	clearTimer(&s.sys.stmr)
  1619  	rc := s.sys.resetCh
  1620  	s.sys.resetCh = nil
  1621  	wg := &s.sys.wg
  1622  	s.mu.Unlock()
  1623  
  1624  	// We will queue up a shutdown event and wait for the
  1625  	// internal send loop to exit.
  1626  	s.sendShutdownEvent()
  1627  	wg.Wait()
  1628  
  1629  	s.mu.Lock()
  1630  	defer s.mu.Unlock()
  1631  
  1632  	// Whip through all accounts.
  1633  	s.accounts.Range(func(k, v interface{}) bool {
  1634  		v.(*Account).clearEventing()
  1635  		return true
  1636  	})
  1637  	// Turn everything off here.
  1638  	s.sys = nil
  1639  	// Make sure this is done after s.sys = nil, so that we don't
  1640  	// get sends to closed channels on badly-timed config reloads.
  1641  	close(rc)
  1642  }
  1643  
  1644  // Request for our local connection count.
  1645  func (s *Server) connsRequest(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1646  	if !s.eventsRunning() {
  1647  		return
  1648  	}
  1649  	tk := strings.Split(subject, tsep)
  1650  	if len(tk) != accReqTokens {
  1651  		s.sys.client.Errorf("Bad subject account connections request message")
  1652  		return
  1653  	}
  1654  	a := tk[accReqAccIndex]
  1655  	m := accNumConnsReq{Account: a}
  1656  	if len(msg) > 0 {
  1657  		if err := json.Unmarshal(msg, &m); err != nil {
  1658  			s.sys.client.Errorf("Error unmarshalling account connections request message: %v", err)
  1659  			return
  1660  		}
  1661  	}
  1662  	if m.Account != a {
  1663  		s.sys.client.Errorf("Error unmarshalled account does not match subject")
  1664  		return
  1665  	}
  1666  	// Here we really only want to lookup the account if its local. We do not want to fetch this
  1667  	// account if we have no interest in it.
  1668  	var acc *Account
  1669  	if v, ok := s.accounts.Load(m.Account); ok {
  1670  		acc = v.(*Account)
  1671  	}
  1672  	if acc == nil {
  1673  		return
  1674  	}
  1675  	// We know this is a local connection.
  1676  	if nlc := acc.NumLocalConnections(); nlc > 0 {
  1677  		s.mu.Lock()
  1678  		s.sendAccConnsUpdate(acc, reply)
  1679  		s.mu.Unlock()
  1680  	}
  1681  }
  1682  
  1683  // leafNodeConnected is an event we will receive when a leaf node for a given account connects.
  1684  func (s *Server) leafNodeConnected(sub *subscription, _ *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1685  	m := accNumConnsReq{}
  1686  	if err := json.Unmarshal(msg, &m); err != nil {
  1687  		s.sys.client.Errorf("Error unmarshalling account connections request message: %v", err)
  1688  		return
  1689  	}
  1690  
  1691  	s.mu.RLock()
  1692  	na := m.Account == _EMPTY_ || !s.eventsEnabled() || !s.gateway.enabled
  1693  	s.mu.RUnlock()
  1694  
  1695  	if na {
  1696  		return
  1697  	}
  1698  
  1699  	if acc, _ := s.lookupAccount(m.Account); acc != nil {
  1700  		s.switchAccountToInterestMode(acc.Name)
  1701  	}
  1702  }
  1703  
  1704  // Common filter options for system requests STATSZ VARZ SUBSZ CONNZ ROUTEZ GATEWAYZ LEAFZ
  1705  type EventFilterOptions struct {
  1706  	Name    string   `json:"server_name,omitempty"` // filter by server name
  1707  	Cluster string   `json:"cluster,omitempty"`     // filter by cluster name
  1708  	Host    string   `json:"host,omitempty"`        // filter by host name
  1709  	Tags    []string `json:"tags,omitempty"`        // filter by tags (must match all tags)
  1710  	Domain  string   `json:"domain,omitempty"`      // filter by JS domain
  1711  }
  1712  
  1713  // StatszEventOptions are options passed to Statsz
  1714  type StatszEventOptions struct {
  1715  	// No actual options yet
  1716  	EventFilterOptions
  1717  }
  1718  
  1719  // Options for account Info
  1720  type AccInfoEventOptions struct {
  1721  	// No actual options yet
  1722  	EventFilterOptions
  1723  }
  1724  
  1725  // In the context of system events, ConnzEventOptions are options passed to Connz
  1726  type ConnzEventOptions struct {
  1727  	ConnzOptions
  1728  	EventFilterOptions
  1729  }
  1730  
  1731  // In the context of system events, RoutezEventOptions are options passed to Routez
  1732  type RoutezEventOptions struct {
  1733  	RoutezOptions
  1734  	EventFilterOptions
  1735  }
  1736  
  1737  // In the context of system events, SubzEventOptions are options passed to Subz
  1738  type SubszEventOptions struct {
  1739  	SubszOptions
  1740  	EventFilterOptions
  1741  }
  1742  
  1743  // In the context of system events, VarzEventOptions are options passed to Varz
  1744  type VarzEventOptions struct {
  1745  	VarzOptions
  1746  	EventFilterOptions
  1747  }
  1748  
  1749  // In the context of system events, GatewayzEventOptions are options passed to Gatewayz
  1750  type GatewayzEventOptions struct {
  1751  	GatewayzOptions
  1752  	EventFilterOptions
  1753  }
  1754  
  1755  // In the context of system events, LeafzEventOptions are options passed to Leafz
  1756  type LeafzEventOptions struct {
  1757  	LeafzOptions
  1758  	EventFilterOptions
  1759  }
  1760  
  1761  // In the context of system events, AccountzEventOptions are options passed to Accountz
  1762  type AccountzEventOptions struct {
  1763  	AccountzOptions
  1764  	EventFilterOptions
  1765  }
  1766  
  1767  // In the context of system events, AccountzEventOptions are options passed to Accountz
  1768  type AccountStatzEventOptions struct {
  1769  	AccountStatzOptions
  1770  	EventFilterOptions
  1771  }
  1772  
  1773  // In the context of system events, JszEventOptions are options passed to Jsz
  1774  type JszEventOptions struct {
  1775  	JSzOptions
  1776  	EventFilterOptions
  1777  }
  1778  
  1779  // In the context of system events, HealthzEventOptions are options passed to Healthz
  1780  type HealthzEventOptions struct {
  1781  	HealthzOptions
  1782  	EventFilterOptions
  1783  }
  1784  
  1785  // In the context of system events, ProfilezEventOptions are options passed to Profilez
  1786  type ProfilezEventOptions struct {
  1787  	ProfilezOptions
  1788  	EventFilterOptions
  1789  }
  1790  
  1791  // returns true if the request does NOT apply to this server and can be ignored.
  1792  // DO NOT hold the server lock when
  1793  func (s *Server) filterRequest(fOpts *EventFilterOptions) bool {
  1794  	if fOpts.Name != _EMPTY_ && !strings.Contains(s.info.Name, fOpts.Name) {
  1795  		return true
  1796  	}
  1797  	if fOpts.Host != _EMPTY_ && !strings.Contains(s.info.Host, fOpts.Host) {
  1798  		return true
  1799  	}
  1800  	if fOpts.Cluster != _EMPTY_ {
  1801  		if !strings.Contains(s.ClusterName(), fOpts.Cluster) {
  1802  			return true
  1803  		}
  1804  	}
  1805  	if len(fOpts.Tags) > 0 {
  1806  		opts := s.getOpts()
  1807  		for _, t := range fOpts.Tags {
  1808  			if !opts.Tags.Contains(t) {
  1809  				return true
  1810  			}
  1811  		}
  1812  	}
  1813  	if fOpts.Domain != _EMPTY_ && s.getOpts().JetStreamDomain != fOpts.Domain {
  1814  		return true
  1815  	}
  1816  	return false
  1817  }
  1818  
  1819  // Encoding support (compression)
  1820  type compressionType int8
  1821  
  1822  const (
  1823  	noCompression = compressionType(iota)
  1824  	gzipCompression
  1825  	snappyCompression
  1826  	unsupportedCompression
  1827  )
  1828  
  1829  // ServerAPIResponse is the response type for the server API like varz, connz etc.
  1830  type ServerAPIResponse struct {
  1831  	Server *ServerInfo `json:"server"`
  1832  	Data   interface{} `json:"data,omitempty"`
  1833  	Error  *ApiError   `json:"error,omitempty"`
  1834  
  1835  	// Private to indicate compression if any.
  1836  	compress compressionType
  1837  }
  1838  
  1839  // Specialized response types for unmarshalling.
  1840  
  1841  // ServerAPIConnzResponse is the response type connz
  1842  type ServerAPIConnzResponse struct {
  1843  	Server *ServerInfo `json:"server"`
  1844  	Data   *Connz      `json:"data,omitempty"`
  1845  	Error  *ApiError   `json:"error,omitempty"`
  1846  }
  1847  
  1848  // statszReq is a request for us to respond with current statsz.
  1849  func (s *Server) statszReq(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1850  	if !s.EventsEnabled() {
  1851  		return
  1852  	}
  1853  
  1854  	// No reply is a signal that we should use our normal broadcast subject.
  1855  	if reply == _EMPTY_ {
  1856  		reply = fmt.Sprintf(serverStatsSubj, s.info.ID)
  1857  	}
  1858  
  1859  	opts := StatszEventOptions{}
  1860  	if len(msg) != 0 {
  1861  		if err := json.Unmarshal(msg, &opts); err != nil {
  1862  			response := &ServerAPIResponse{
  1863  				Server: &ServerInfo{},
  1864  				Error:  &ApiError{Code: http.StatusBadRequest, Description: err.Error()},
  1865  			}
  1866  			s.sendInternalMsgLocked(reply, _EMPTY_, response.Server, response)
  1867  			return
  1868  		} else if ignore := s.filterRequest(&opts.EventFilterOptions); ignore {
  1869  			return
  1870  		}
  1871  	}
  1872  	s.sendStatsz(reply)
  1873  }
  1874  
  1875  // idzReq is for a request for basic static server info.
  1876  // Try to not hold the write lock or dynamically create data.
  1877  func (s *Server) idzReq(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1878  	s.mu.RLock()
  1879  	defer s.mu.RUnlock()
  1880  	id := &ServerID{
  1881  		Name: s.info.Name,
  1882  		Host: s.info.Host,
  1883  		ID:   s.info.ID,
  1884  	}
  1885  	s.sendInternalMsg(reply, _EMPTY_, nil, &id)
  1886  }
  1887  
  1888  var errSkipZreq = errors.New("filtered response")
  1889  
  1890  const (
  1891  	acceptEncodingHeader  = "Accept-Encoding"
  1892  	contentEncodingHeader = "Content-Encoding"
  1893  )
  1894  
  1895  // This is not as formal as it could be. We see if anything has s2 or snappy first, then gzip.
  1896  func getAcceptEncoding(hdr []byte) compressionType {
  1897  	ae := strings.ToLower(string(getHeader(acceptEncodingHeader, hdr)))
  1898  	if ae == _EMPTY_ {
  1899  		return noCompression
  1900  	}
  1901  	if strings.Contains(ae, "snappy") || strings.Contains(ae, "s2") {
  1902  		return snappyCompression
  1903  	}
  1904  	if strings.Contains(ae, "gzip") {
  1905  		return gzipCompression
  1906  	}
  1907  	return unsupportedCompression
  1908  }
  1909  
  1910  func (s *Server) zReq(c *client, reply string, hdr, msg []byte, fOpts *EventFilterOptions, optz interface{}, respf func() (interface{}, error)) {
  1911  	if !s.EventsEnabled() || reply == _EMPTY_ {
  1912  		return
  1913  	}
  1914  	response := &ServerAPIResponse{Server: &ServerInfo{}}
  1915  	var err error
  1916  	status := 0
  1917  	if len(msg) != 0 {
  1918  		if err = json.Unmarshal(msg, optz); err != nil {
  1919  			status = http.StatusBadRequest // status is only included on error, so record how far execution got
  1920  		} else if s.filterRequest(fOpts) {
  1921  			return
  1922  		}
  1923  	}
  1924  	if err == nil {
  1925  		response.Data, err = respf()
  1926  		if errors.Is(err, errSkipZreq) {
  1927  			return
  1928  		} else if err != nil {
  1929  			status = http.StatusInternalServerError
  1930  		}
  1931  	}
  1932  	if err != nil {
  1933  		response.Error = &ApiError{Code: status, Description: err.Error()}
  1934  	} else if len(hdr) > 0 {
  1935  		response.compress = getAcceptEncoding(hdr)
  1936  	}
  1937  	s.sendInternalResponse(reply, response)
  1938  }
  1939  
  1940  // remoteConnsUpdate gets called when we receive a remote update from another server.
  1941  func (s *Server) remoteConnsUpdate(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  1942  	if !s.eventsRunning() {
  1943  		return
  1944  	}
  1945  	var m AccountNumConns
  1946  	if len(msg) == 0 {
  1947  		s.sys.client.Errorf("No message body provided")
  1948  		return
  1949  	} else if err := json.Unmarshal(msg, &m); err != nil {
  1950  		s.sys.client.Errorf("Error unmarshalling account connection event message: %v", err)
  1951  		return
  1952  	}
  1953  
  1954  	// See if we have the account registered, if not drop it.
  1955  	// Make sure this does not force us to load this account here.
  1956  	var acc *Account
  1957  	if v, ok := s.accounts.Load(m.Account); ok {
  1958  		acc = v.(*Account)
  1959  	}
  1960  	// Silently ignore these if we do not have local interest in the account.
  1961  	if acc == nil {
  1962  		return
  1963  	}
  1964  
  1965  	s.mu.Lock()
  1966  
  1967  	// check again here if we have been shutdown.
  1968  	if !s.isRunning() || !s.eventsEnabled() {
  1969  		s.mu.Unlock()
  1970  		return
  1971  	}
  1972  	// Double check that this is not us, should never happen, so error if it does.
  1973  	if m.Server.ID == s.info.ID {
  1974  		s.sys.client.Errorf("Processing our own account connection event message: ignored")
  1975  		s.mu.Unlock()
  1976  		return
  1977  	}
  1978  	// If we are here we have interest in tracking this account. Update our accounting.
  1979  	clients := acc.updateRemoteServer(&m)
  1980  	s.updateRemoteServer(&m.Server)
  1981  	s.mu.Unlock()
  1982  	// Need to close clients outside of server lock
  1983  	for _, c := range clients {
  1984  		c.maxAccountConnExceeded()
  1985  	}
  1986  }
  1987  
  1988  // This will import any system level exports.
  1989  func (s *Server) registerSystemImports(a *Account) {
  1990  	if a == nil || !s.EventsEnabled() {
  1991  		return
  1992  	}
  1993  	sacc := s.SystemAccount()
  1994  	if sacc == nil || sacc == a {
  1995  		return
  1996  	}
  1997  	// FIXME(dlc) - make a shared list between sys exports etc.
  1998  
  1999  	importSrvc := func(subj, mappedSubj string) {
  2000  		if !a.serviceImportExists(subj) {
  2001  			if err := a.addServiceImportWithClaim(sacc, subj, mappedSubj, nil, true); err != nil {
  2002  				s.Errorf("Error setting up system service import %s -> %s for account: %v",
  2003  					subj, mappedSubj, err)
  2004  			}
  2005  		}
  2006  	}
  2007  	// Add in this to the account in 2 places.
  2008  	// "$SYS.REQ.SERVER.PING.CONNZ" and "$SYS.REQ.ACCOUNT.PING.CONNZ"
  2009  	mappedConnzSubj := fmt.Sprintf(accDirectReqSubj, a.Name, "CONNZ")
  2010  	importSrvc(fmt.Sprintf(accPingReqSubj, "CONNZ"), mappedConnzSubj)
  2011  	importSrvc(fmt.Sprintf(serverPingReqSubj, "CONNZ"), mappedConnzSubj)
  2012  	importSrvc(fmt.Sprintf(accPingReqSubj, "STATZ"), fmt.Sprintf(accDirectReqSubj, a.Name, "STATZ"))
  2013  
  2014  	// This is for user's looking up their own info.
  2015  	mappedSubject := fmt.Sprintf(userDirectReqSubj, a.Name)
  2016  	importSrvc(userDirectInfoSubj, mappedSubject)
  2017  	// Make sure to share details.
  2018  	a.setServiceImportSharing(sacc, mappedSubject, false, true)
  2019  }
  2020  
  2021  // Setup tracking for this account. This allows us to track global account activity.
  2022  // Lock should be held on entry.
  2023  func (s *Server) enableAccountTracking(a *Account) {
  2024  	if a == nil || !s.eventsEnabled() {
  2025  		return
  2026  	}
  2027  
  2028  	// TODO(ik): Generate payload although message may not be sent.
  2029  	// May need to ensure we do so only if there is a known interest.
  2030  	// This can get complicated with gateways.
  2031  
  2032  	subj := fmt.Sprintf(accDirectReqSubj, a.Name, "CONNS")
  2033  	reply := fmt.Sprintf(connsRespSubj, s.info.ID)
  2034  	m := accNumConnsReq{Account: a.Name}
  2035  	s.sendInternalMsg(subj, reply, &m.Server, &m)
  2036  }
  2037  
  2038  // Event on leaf node connect.
  2039  // Lock should NOT be held on entry.
  2040  func (s *Server) sendLeafNodeConnect(a *Account) {
  2041  	s.mu.Lock()
  2042  	// If we are not in operator mode, or do not have any gateways defined, this should also be a no-op.
  2043  	if a == nil || !s.eventsEnabled() || !s.gateway.enabled {
  2044  		s.mu.Unlock()
  2045  		return
  2046  	}
  2047  	s.sendLeafNodeConnectMsg(a.Name)
  2048  	s.mu.Unlock()
  2049  
  2050  	s.switchAccountToInterestMode(a.Name)
  2051  }
  2052  
  2053  // Send the leafnode connect message.
  2054  // Lock should be held.
  2055  func (s *Server) sendLeafNodeConnectMsg(accName string) {
  2056  	subj := fmt.Sprintf(leafNodeConnectEventSubj, accName)
  2057  	m := accNumConnsReq{Account: accName}
  2058  	s.sendInternalMsg(subj, _EMPTY_, &m.Server, &m)
  2059  }
  2060  
  2061  // sendAccConnsUpdate is called to send out our information on the
  2062  // account's local connections.
  2063  // Lock should be held on entry.
  2064  func (s *Server) sendAccConnsUpdate(a *Account, subj ...string) {
  2065  	if !s.eventsEnabled() || a == nil {
  2066  		return
  2067  	}
  2068  	sendQ := s.sys.sendq
  2069  	if sendQ == nil {
  2070  		return
  2071  	}
  2072  	// Build event with account name and number of local clients and leafnodes.
  2073  	eid := s.nextEventID()
  2074  	a.mu.Lock()
  2075  	stat := a.statz()
  2076  	m := AccountNumConns{
  2077  		TypedEvent: TypedEvent{
  2078  			Type: AccountNumConnsMsgType,
  2079  			ID:   eid,
  2080  			Time: time.Now().UTC(),
  2081  		},
  2082  		AccountStat: *stat,
  2083  	}
  2084  	// Set timer to fire again unless we are at zero.
  2085  	if m.TotalConns == 0 {
  2086  		clearTimer(&a.ctmr)
  2087  	} else {
  2088  		// Check to see if we have an HB running and update.
  2089  		if a.ctmr == nil {
  2090  			a.ctmr = time.AfterFunc(eventsHBInterval, func() { s.accConnsUpdate(a) })
  2091  		} else {
  2092  			a.ctmr.Reset(eventsHBInterval)
  2093  		}
  2094  	}
  2095  	for _, sub := range subj {
  2096  		msg := newPubMsg(nil, sub, _EMPTY_, &m.Server, nil, &m, noCompression, false, false)
  2097  		sendQ.push(msg)
  2098  	}
  2099  	a.mu.Unlock()
  2100  }
  2101  
  2102  // Lock should be held on entry.
  2103  func (a *Account) statz() *AccountStat {
  2104  	localConns := a.numLocalConnections()
  2105  	leafConns := a.numLocalLeafNodes()
  2106  	return &AccountStat{
  2107  		Account:    a.Name,
  2108  		Conns:      localConns,
  2109  		LeafNodes:  leafConns,
  2110  		TotalConns: localConns + leafConns,
  2111  		NumSubs:    a.sl.Count(),
  2112  		Received: DataStats{
  2113  			Msgs:  atomic.LoadInt64(&a.inMsgs),
  2114  			Bytes: atomic.LoadInt64(&a.inBytes),
  2115  		},
  2116  		Sent: DataStats{
  2117  			Msgs:  atomic.LoadInt64(&a.outMsgs),
  2118  			Bytes: atomic.LoadInt64(&a.outBytes),
  2119  		},
  2120  		SlowConsumers: atomic.LoadInt64(&a.slowConsumers),
  2121  	}
  2122  }
  2123  
  2124  // accConnsUpdate is called whenever there is a change to the account's
  2125  // number of active connections, or during a heartbeat.
  2126  // We will not send for $G.
  2127  func (s *Server) accConnsUpdate(a *Account) {
  2128  	s.mu.Lock()
  2129  	defer s.mu.Unlock()
  2130  	if !s.eventsEnabled() || a == nil || a == s.gacc {
  2131  		return
  2132  	}
  2133  	s.sendAccConnsUpdate(a, fmt.Sprintf(accConnsEventSubjOld, a.Name), fmt.Sprintf(accConnsEventSubjNew, a.Name))
  2134  }
  2135  
  2136  // server lock should be held
  2137  func (s *Server) nextEventID() string {
  2138  	return s.eventIds.Next()
  2139  }
  2140  
  2141  // accountConnectEvent will send an account client connect event if there is interest.
  2142  // This is a billing event.
  2143  func (s *Server) accountConnectEvent(c *client) {
  2144  	s.mu.Lock()
  2145  	if !s.eventsEnabled() {
  2146  		s.mu.Unlock()
  2147  		return
  2148  	}
  2149  	gacc := s.gacc
  2150  	eid := s.nextEventID()
  2151  	s.mu.Unlock()
  2152  
  2153  	c.mu.Lock()
  2154  	// Ignore global account activity
  2155  	if c.acc == nil || c.acc == gacc {
  2156  		c.mu.Unlock()
  2157  		return
  2158  	}
  2159  
  2160  	m := ConnectEventMsg{
  2161  		TypedEvent: TypedEvent{
  2162  			Type: ConnectEventMsgType,
  2163  			ID:   eid,
  2164  			Time: time.Now().UTC(),
  2165  		},
  2166  		Client: ClientInfo{
  2167  			Start:      &c.start,
  2168  			Host:       c.host,
  2169  			ID:         c.cid,
  2170  			Account:    accForClient(c),
  2171  			User:       c.getRawAuthUser(),
  2172  			Name:       c.opts.Name,
  2173  			Lang:       c.opts.Lang,
  2174  			Version:    c.opts.Version,
  2175  			Jwt:        c.opts.JWT,
  2176  			IssuerKey:  issuerForClient(c),
  2177  			Tags:       c.tags,
  2178  			NameTag:    c.nameTag,
  2179  			Kind:       c.kindString(),
  2180  			ClientType: c.clientTypeString(),
  2181  			MQTTClient: c.getMQTTClientID(),
  2182  		},
  2183  	}
  2184  	subj := fmt.Sprintf(connectEventSubj, c.acc.Name)
  2185  	c.mu.Unlock()
  2186  
  2187  	s.sendInternalMsgLocked(subj, _EMPTY_, &m.Server, &m)
  2188  }
  2189  
  2190  // accountDisconnectEvent will send an account client disconnect event if there is interest.
  2191  // This is a billing event.
  2192  func (s *Server) accountDisconnectEvent(c *client, now time.Time, reason string) {
  2193  	s.mu.Lock()
  2194  	if !s.eventsEnabled() {
  2195  		s.mu.Unlock()
  2196  		return
  2197  	}
  2198  	gacc := s.gacc
  2199  	eid := s.nextEventID()
  2200  	s.mu.Unlock()
  2201  
  2202  	c.mu.Lock()
  2203  
  2204  	// Ignore global account activity
  2205  	if c.acc == nil || c.acc == gacc {
  2206  		c.mu.Unlock()
  2207  		return
  2208  	}
  2209  
  2210  	m := DisconnectEventMsg{
  2211  		TypedEvent: TypedEvent{
  2212  			Type: DisconnectEventMsgType,
  2213  			ID:   eid,
  2214  			Time: now,
  2215  		},
  2216  		Client: ClientInfo{
  2217  			Start:      &c.start,
  2218  			Stop:       &now,
  2219  			Host:       c.host,
  2220  			ID:         c.cid,
  2221  			Account:    accForClient(c),
  2222  			User:       c.getRawAuthUser(),
  2223  			Name:       c.opts.Name,
  2224  			Lang:       c.opts.Lang,
  2225  			Version:    c.opts.Version,
  2226  			RTT:        c.getRTT(),
  2227  			Jwt:        c.opts.JWT,
  2228  			IssuerKey:  issuerForClient(c),
  2229  			Tags:       c.tags,
  2230  			NameTag:    c.nameTag,
  2231  			Kind:       c.kindString(),
  2232  			ClientType: c.clientTypeString(),
  2233  			MQTTClient: c.getMQTTClientID(),
  2234  		},
  2235  		Sent: DataStats{
  2236  			Msgs:  atomic.LoadInt64(&c.inMsgs),
  2237  			Bytes: atomic.LoadInt64(&c.inBytes),
  2238  		},
  2239  		Received: DataStats{
  2240  			Msgs:  c.outMsgs,
  2241  			Bytes: c.outBytes,
  2242  		},
  2243  		Reason: reason,
  2244  	}
  2245  	accName := c.acc.Name
  2246  	c.mu.Unlock()
  2247  
  2248  	subj := fmt.Sprintf(disconnectEventSubj, accName)
  2249  	s.sendInternalMsgLocked(subj, _EMPTY_, &m.Server, &m)
  2250  }
  2251  
  2252  // This is the system level event sent to the system account for operators.
  2253  func (s *Server) sendAuthErrorEvent(c *client) {
  2254  	s.mu.Lock()
  2255  	if !s.eventsEnabled() {
  2256  		s.mu.Unlock()
  2257  		return
  2258  	}
  2259  	eid := s.nextEventID()
  2260  	s.mu.Unlock()
  2261  
  2262  	now := time.Now().UTC()
  2263  	c.mu.Lock()
  2264  	m := DisconnectEventMsg{
  2265  		TypedEvent: TypedEvent{
  2266  			Type: DisconnectEventMsgType,
  2267  			ID:   eid,
  2268  			Time: now,
  2269  		},
  2270  		Client: ClientInfo{
  2271  			Start:      &c.start,
  2272  			Stop:       &now,
  2273  			Host:       c.host,
  2274  			ID:         c.cid,
  2275  			Account:    accForClient(c),
  2276  			User:       c.getRawAuthUser(),
  2277  			Name:       c.opts.Name,
  2278  			Lang:       c.opts.Lang,
  2279  			Version:    c.opts.Version,
  2280  			RTT:        c.getRTT(),
  2281  			Jwt:        c.opts.JWT,
  2282  			IssuerKey:  issuerForClient(c),
  2283  			Tags:       c.tags,
  2284  			NameTag:    c.nameTag,
  2285  			Kind:       c.kindString(),
  2286  			ClientType: c.clientTypeString(),
  2287  			MQTTClient: c.getMQTTClientID(),
  2288  		},
  2289  		Sent: DataStats{
  2290  			Msgs:  c.inMsgs,
  2291  			Bytes: c.inBytes,
  2292  		},
  2293  		Received: DataStats{
  2294  			Msgs:  c.outMsgs,
  2295  			Bytes: c.outBytes,
  2296  		},
  2297  		Reason: AuthenticationViolation.String(),
  2298  	}
  2299  	c.mu.Unlock()
  2300  
  2301  	s.mu.Lock()
  2302  	subj := fmt.Sprintf(authErrorEventSubj, s.info.ID)
  2303  	s.sendInternalMsg(subj, _EMPTY_, &m.Server, &m)
  2304  	s.mu.Unlock()
  2305  }
  2306  
  2307  // This is the account level event sent to the origin account for account owners.
  2308  func (s *Server) sendAccountAuthErrorEvent(c *client, acc *Account, reason string) {
  2309  	if acc == nil {
  2310  		return
  2311  	}
  2312  	s.mu.Lock()
  2313  	if !s.eventsEnabled() {
  2314  		s.mu.Unlock()
  2315  		return
  2316  	}
  2317  	eid := s.nextEventID()
  2318  	s.mu.Unlock()
  2319  
  2320  	now := time.Now().UTC()
  2321  	c.mu.Lock()
  2322  	m := DisconnectEventMsg{
  2323  		TypedEvent: TypedEvent{
  2324  			Type: DisconnectEventMsgType,
  2325  			ID:   eid,
  2326  			Time: now,
  2327  		},
  2328  		Client: ClientInfo{
  2329  			Start:      &c.start,
  2330  			Stop:       &now,
  2331  			Host:       c.host,
  2332  			ID:         c.cid,
  2333  			Account:    acc.Name,
  2334  			User:       c.getRawAuthUser(),
  2335  			Name:       c.opts.Name,
  2336  			Lang:       c.opts.Lang,
  2337  			Version:    c.opts.Version,
  2338  			RTT:        c.getRTT(),
  2339  			Jwt:        c.opts.JWT,
  2340  			IssuerKey:  issuerForClient(c),
  2341  			Tags:       c.tags,
  2342  			NameTag:    c.nameTag,
  2343  			Kind:       c.kindString(),
  2344  			ClientType: c.clientTypeString(),
  2345  			MQTTClient: c.getMQTTClientID(),
  2346  		},
  2347  		Sent: DataStats{
  2348  			Msgs:  c.inMsgs,
  2349  			Bytes: c.inBytes,
  2350  		},
  2351  		Received: DataStats{
  2352  			Msgs:  c.outMsgs,
  2353  			Bytes: c.outBytes,
  2354  		},
  2355  		Reason: reason,
  2356  	}
  2357  	c.mu.Unlock()
  2358  
  2359  	s.sendInternalAccountSysMsg(acc, authErrorAccountEventSubj, &m.Server, &m, noCompression)
  2360  }
  2361  
  2362  // Internal message callback.
  2363  // If the msg is needed past the callback it is required to be copied.
  2364  // rmsg contains header and the message. use client.msgParts(rmsg) to split them apart
  2365  type msgHandler func(sub *subscription, client *client, acc *Account, subject, reply string, rmsg []byte)
  2366  
  2367  // Create a wrapped callback handler for the subscription that will move it to an
  2368  // internal recvQ for processing not inline with routes etc.
  2369  func (s *Server) noInlineCallback(cb sysMsgHandler) msgHandler {
  2370  	s.mu.RLock()
  2371  	if !s.eventsEnabled() {
  2372  		s.mu.RUnlock()
  2373  		return nil
  2374  	}
  2375  	// Capture here for direct reference to avoid any unnecessary blocking inline with routes, gateways etc.
  2376  	recvq := s.sys.recvq
  2377  	s.mu.RUnlock()
  2378  
  2379  	return func(sub *subscription, c *client, acc *Account, subj, rply string, rmsg []byte) {
  2380  		// Need to copy and split here.
  2381  		hdr, msg := c.msgParts(rmsg)
  2382  		recvq.push(&inSysMsg{sub, c, acc, subj, rply, copyBytes(hdr), copyBytes(msg), cb})
  2383  	}
  2384  }
  2385  
  2386  // Create an internal subscription. sysSubscribeQ for queue groups.
  2387  func (s *Server) sysSubscribe(subject string, cb msgHandler) (*subscription, error) {
  2388  	return s.systemSubscribe(subject, _EMPTY_, false, nil, cb)
  2389  }
  2390  
  2391  // Create an internal subscription with queue
  2392  func (s *Server) sysSubscribeQ(subject, queue string, cb msgHandler) (*subscription, error) {
  2393  	return s.systemSubscribe(subject, queue, false, nil, cb)
  2394  }
  2395  
  2396  // Create an internal subscription but do not forward interest.
  2397  func (s *Server) sysSubscribeInternal(subject string, cb msgHandler) (*subscription, error) {
  2398  	return s.systemSubscribe(subject, _EMPTY_, true, nil, cb)
  2399  }
  2400  
  2401  func (s *Server) systemSubscribe(subject, queue string, internalOnly bool, c *client, cb msgHandler) (*subscription, error) {
  2402  	s.mu.Lock()
  2403  	if !s.eventsEnabled() {
  2404  		s.mu.Unlock()
  2405  		return nil, ErrNoSysAccount
  2406  	}
  2407  	if cb == nil {
  2408  		s.mu.Unlock()
  2409  		return nil, fmt.Errorf("undefined message handler")
  2410  	}
  2411  	if c == nil {
  2412  		c = s.sys.client
  2413  	}
  2414  	trace := c.trace
  2415  	s.sys.sid++
  2416  	sid := strconv.Itoa(s.sys.sid)
  2417  	s.mu.Unlock()
  2418  
  2419  	// Now create the subscription
  2420  	if trace {
  2421  		c.traceInOp("SUB", []byte(subject+" "+queue+" "+sid))
  2422  	}
  2423  
  2424  	var q []byte
  2425  	if queue != _EMPTY_ {
  2426  		q = []byte(queue)
  2427  	}
  2428  
  2429  	// Now create the subscription
  2430  	return c.processSub([]byte(subject), q, []byte(sid), cb, internalOnly)
  2431  }
  2432  
  2433  func (s *Server) sysUnsubscribe(sub *subscription) {
  2434  	if sub == nil {
  2435  		return
  2436  	}
  2437  	s.mu.RLock()
  2438  	if !s.eventsEnabled() {
  2439  		s.mu.RUnlock()
  2440  		return
  2441  	}
  2442  	c := sub.client
  2443  	s.mu.RUnlock()
  2444  
  2445  	if c != nil {
  2446  		c.processUnsub(sub.sid)
  2447  	}
  2448  }
  2449  
  2450  // This will generate the tracking subject for remote latency from the response subject.
  2451  func remoteLatencySubjectForResponse(subject []byte) string {
  2452  	if !isTrackedReply(subject) {
  2453  		return ""
  2454  	}
  2455  	toks := bytes.Split(subject, []byte(tsep))
  2456  	// FIXME(dlc) - Sprintf may become a performance concern at some point.
  2457  	return fmt.Sprintf(remoteLatencyEventSubj, toks[len(toks)-2])
  2458  }
  2459  
  2460  // remoteLatencyUpdate is used to track remote latency measurements for tracking on exported services.
  2461  func (s *Server) remoteLatencyUpdate(sub *subscription, _ *client, _ *Account, subject, _ string, hdr, msg []byte) {
  2462  	if !s.eventsRunning() {
  2463  		return
  2464  	}
  2465  	var rl remoteLatency
  2466  	if err := json.Unmarshal(msg, &rl); err != nil {
  2467  		s.Errorf("Error unmarshalling remote latency measurement: %v", err)
  2468  		return
  2469  	}
  2470  	// Now we need to look up the responseServiceImport associated with this measurement.
  2471  	acc, err := s.LookupAccount(rl.Account)
  2472  	if err != nil {
  2473  		s.Warnf("Could not lookup account %q for latency measurement", rl.Account)
  2474  		return
  2475  	}
  2476  	// Now get the request id / reply. We need to see if we have a GW prefix and if so strip that off.
  2477  	reply := rl.ReqId
  2478  	if gwPrefix, old := isGWRoutedSubjectAndIsOldPrefix([]byte(reply)); gwPrefix {
  2479  		reply = string(getSubjectFromGWRoutedReply([]byte(reply), old))
  2480  	}
  2481  	acc.mu.RLock()
  2482  	si := acc.exports.responses[reply]
  2483  	if si == nil {
  2484  		acc.mu.RUnlock()
  2485  		return
  2486  	}
  2487  	lsub := si.latency.subject
  2488  	acc.mu.RUnlock()
  2489  
  2490  	si.acc.mu.Lock()
  2491  	m1 := si.m1
  2492  	m2 := rl.M2
  2493  
  2494  	// So we have not processed the response tracking measurement yet.
  2495  	if m1 == nil {
  2496  		// Store our value there for them to pick up.
  2497  		si.m1 = &m2
  2498  	}
  2499  	si.acc.mu.Unlock()
  2500  
  2501  	if m1 == nil {
  2502  		return
  2503  	}
  2504  
  2505  	// Calculate the correct latencies given M1 and M2.
  2506  	m1.merge(&m2)
  2507  
  2508  	// Clear the requesting client since we send the result here.
  2509  	acc.mu.Lock()
  2510  	si.rc = nil
  2511  	acc.mu.Unlock()
  2512  
  2513  	// Make sure we remove the entry here.
  2514  	acc.removeServiceImport(si.from)
  2515  	// Send the metrics
  2516  	s.sendInternalAccountMsg(acc, lsub, m1)
  2517  }
  2518  
  2519  // This is used for all inbox replies so that we do not send supercluster wide interest
  2520  // updates for every request. Same trick used in modern NATS clients.
  2521  func (s *Server) inboxReply(sub *subscription, c *client, acc *Account, subject, reply string, msg []byte) {
  2522  	s.mu.RLock()
  2523  	if !s.eventsEnabled() || s.sys.replies == nil {
  2524  		s.mu.RUnlock()
  2525  		return
  2526  	}
  2527  	cb, ok := s.sys.replies[subject]
  2528  	s.mu.RUnlock()
  2529  
  2530  	if ok && cb != nil {
  2531  		cb(sub, c, acc, subject, reply, msg)
  2532  	}
  2533  }
  2534  
  2535  // Copied from go client.
  2536  // We could use serviceReply here instead to save some code.
  2537  // I prefer these semantics for the moment, when tracing you know what this is.
  2538  const (
  2539  	InboxPrefix        = "$SYS._INBOX."
  2540  	inboxPrefixLen     = len(InboxPrefix)
  2541  	respInboxPrefixLen = inboxPrefixLen + sysHashLen + 1
  2542  	replySuffixLen     = 8 // Gives us 62^8
  2543  )
  2544  
  2545  // Creates an internal inbox used for replies that will be processed by the global wc handler.
  2546  func (s *Server) newRespInbox() string {
  2547  	var b [respInboxPrefixLen + replySuffixLen]byte
  2548  	pres := b[:respInboxPrefixLen]
  2549  	copy(pres, s.sys.inboxPre)
  2550  	rn := rand.Int63()
  2551  	for i, l := respInboxPrefixLen, rn; i < len(b); i++ {
  2552  		b[i] = digits[l%base]
  2553  		l /= base
  2554  	}
  2555  	return string(b[:])
  2556  }
  2557  
  2558  // accNumSubsReq is sent when we need to gather remote info on subs.
  2559  type accNumSubsReq struct {
  2560  	Account string `json:"acc"`
  2561  	Subject string `json:"subject"`
  2562  	Queue   []byte `json:"queue,omitempty"`
  2563  }
  2564  
  2565  // helper function to total information from results to count subs.
  2566  func totalSubs(rr *SublistResult, qg []byte) (nsubs int32) {
  2567  	if rr == nil {
  2568  		return
  2569  	}
  2570  	checkSub := func(sub *subscription) {
  2571  		// TODO(dlc) - This could be smarter.
  2572  		if qg != nil && !bytes.Equal(qg, sub.queue) {
  2573  			return
  2574  		}
  2575  		if sub.client.kind == CLIENT || sub.client.isHubLeafNode() {
  2576  			nsubs++
  2577  		}
  2578  	}
  2579  	if qg == nil {
  2580  		for _, sub := range rr.psubs {
  2581  			checkSub(sub)
  2582  		}
  2583  	}
  2584  	for _, qsub := range rr.qsubs {
  2585  		for _, sub := range qsub {
  2586  			checkSub(sub)
  2587  		}
  2588  	}
  2589  	return
  2590  }
  2591  
  2592  // Allows users of large systems to debug active subscribers for a given subject.
  2593  // Payload should be the subject of interest.
  2594  func (s *Server) debugSubscribers(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  2595  	// Even though this is an internal only subscription, meaning interest was not forwarded, we could
  2596  	// get one here from a GW in optimistic mode. Ignore for now.
  2597  	// FIXME(dlc) - Should we send no interest here back to the GW?
  2598  	if c.kind != CLIENT {
  2599  		return
  2600  	}
  2601  
  2602  	var ci ClientInfo
  2603  	if len(hdr) > 0 {
  2604  		if err := json.Unmarshal(getHeader(ClientInfoHdr, hdr), &ci); err != nil {
  2605  			return
  2606  		}
  2607  	}
  2608  
  2609  	var acc *Account
  2610  	if ci.Service != _EMPTY_ {
  2611  		acc, _ = s.LookupAccount(ci.Service)
  2612  	} else if ci.Account != _EMPTY_ {
  2613  		acc, _ = s.LookupAccount(ci.Account)
  2614  	} else {
  2615  		// Direct $SYS access.
  2616  		acc = c.acc
  2617  		if acc == nil {
  2618  			acc = s.SystemAccount()
  2619  		}
  2620  	}
  2621  	if acc == nil {
  2622  		return
  2623  	}
  2624  
  2625  	// We could have a single subject or we could have a subject and a wildcard separated by whitespace.
  2626  	args := strings.Split(strings.TrimSpace(string(msg)), " ")
  2627  	if len(args) == 0 {
  2628  		s.sendInternalAccountMsg(acc, reply, 0)
  2629  		return
  2630  	}
  2631  
  2632  	tsubj := args[0]
  2633  	var qgroup []byte
  2634  	if len(args) > 1 {
  2635  		qgroup = []byte(args[1])
  2636  	}
  2637  
  2638  	var nsubs int32
  2639  
  2640  	if subjectIsLiteral(tsubj) {
  2641  		// We will look up subscribers locally first then determine if we need to solicit other servers.
  2642  		rr := acc.sl.Match(tsubj)
  2643  		nsubs = totalSubs(rr, qgroup)
  2644  	} else {
  2645  		// We have a wildcard, so this is a bit slower path.
  2646  		var _subs [32]*subscription
  2647  		subs := _subs[:0]
  2648  		acc.sl.All(&subs)
  2649  		for _, sub := range subs {
  2650  			if subjectIsSubsetMatch(string(sub.subject), tsubj) {
  2651  				if qgroup != nil && !bytes.Equal(qgroup, sub.queue) {
  2652  					continue
  2653  				}
  2654  				if sub.client.kind == CLIENT || sub.client.isHubLeafNode() {
  2655  					nsubs++
  2656  				}
  2657  			}
  2658  		}
  2659  	}
  2660  
  2661  	// We should have an idea of how many responses to expect from remote servers.
  2662  	var expected = acc.expectedRemoteResponses()
  2663  
  2664  	// If we are only local, go ahead and return.
  2665  	if expected == 0 {
  2666  		s.sendInternalAccountMsg(nil, reply, nsubs)
  2667  		return
  2668  	}
  2669  
  2670  	// We need to solicit from others.
  2671  	// To track status.
  2672  	responses := int32(0)
  2673  	done := make(chan (bool))
  2674  
  2675  	s.mu.Lock()
  2676  	// Create direct reply inbox that we multiplex under the WC replies.
  2677  	replySubj := s.newRespInbox()
  2678  	// Store our handler.
  2679  	s.sys.replies[replySubj] = func(sub *subscription, _ *client, _ *Account, subject, _ string, msg []byte) {
  2680  		if n, err := strconv.Atoi(string(msg)); err == nil {
  2681  			atomic.AddInt32(&nsubs, int32(n))
  2682  		}
  2683  		if atomic.AddInt32(&responses, 1) >= expected {
  2684  			select {
  2685  			case done <- true:
  2686  			default:
  2687  			}
  2688  		}
  2689  	}
  2690  	// Send the request to the other servers.
  2691  	request := &accNumSubsReq{
  2692  		Account: acc.Name,
  2693  		Subject: tsubj,
  2694  		Queue:   qgroup,
  2695  	}
  2696  	s.sendInternalMsg(accNumSubsReqSubj, replySubj, nil, request)
  2697  	s.mu.Unlock()
  2698  
  2699  	// FIXME(dlc) - We should rate limit here instead of blind Go routine.
  2700  	go func() {
  2701  		select {
  2702  		case <-done:
  2703  		case <-time.After(500 * time.Millisecond):
  2704  		}
  2705  		// Cleanup the WC entry.
  2706  		var sendResponse bool
  2707  		s.mu.Lock()
  2708  		if s.sys != nil && s.sys.replies != nil {
  2709  			delete(s.sys.replies, replySubj)
  2710  			sendResponse = true
  2711  		}
  2712  		s.mu.Unlock()
  2713  		if sendResponse {
  2714  			// Send the response.
  2715  			s.sendInternalAccountMsg(nil, reply, atomic.LoadInt32(&nsubs))
  2716  		}
  2717  	}()
  2718  }
  2719  
  2720  // Request for our local subscription count. This will come from a remote origin server
  2721  // that received the initial request.
  2722  func (s *Server) nsubsRequest(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  2723  	if !s.eventsRunning() {
  2724  		return
  2725  	}
  2726  	m := accNumSubsReq{}
  2727  	if len(msg) == 0 {
  2728  		s.sys.client.Errorf("request requires a body")
  2729  		return
  2730  	} else if err := json.Unmarshal(msg, &m); err != nil {
  2731  		s.sys.client.Errorf("Error unmarshalling account nsubs request message: %v", err)
  2732  		return
  2733  	}
  2734  	// Grab account.
  2735  	acc, _ := s.lookupAccount(m.Account)
  2736  	if acc == nil || acc.numLocalAndLeafConnections() == 0 {
  2737  		return
  2738  	}
  2739  	// We will look up subscribers locally first then determine if we need to solicit other servers.
  2740  	var nsubs int32
  2741  	if subjectIsLiteral(m.Subject) {
  2742  		rr := acc.sl.Match(m.Subject)
  2743  		nsubs = totalSubs(rr, m.Queue)
  2744  	} else {
  2745  		// We have a wildcard, so this is a bit slower path.
  2746  		var _subs [32]*subscription
  2747  		subs := _subs[:0]
  2748  		acc.sl.All(&subs)
  2749  		for _, sub := range subs {
  2750  			if (sub.client.kind == CLIENT || sub.client.isHubLeafNode()) && subjectIsSubsetMatch(string(sub.subject), m.Subject) {
  2751  				if m.Queue != nil && !bytes.Equal(m.Queue, sub.queue) {
  2752  					continue
  2753  				}
  2754  				nsubs++
  2755  			}
  2756  		}
  2757  	}
  2758  	s.sendInternalMsgLocked(reply, _EMPTY_, nil, nsubs)
  2759  }
  2760  
  2761  func (s *Server) reloadConfig(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  2762  	if !s.eventsRunning() {
  2763  		return
  2764  	}
  2765  
  2766  	optz := &EventFilterOptions{}
  2767  	s.zReq(c, reply, hdr, msg, optz, optz, func() (interface{}, error) {
  2768  		// Reload the server config, as requested.
  2769  		return nil, s.Reload()
  2770  	})
  2771  }
  2772  
  2773  type KickClientReq struct {
  2774  	CID uint64 `json:"cid"`
  2775  }
  2776  
  2777  type LDMClientReq struct {
  2778  	CID uint64 `json:"cid"`
  2779  }
  2780  
  2781  func (s *Server) kickClient(_ *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  2782  	if !s.eventsRunning() {
  2783  		return
  2784  	}
  2785  
  2786  	var req KickClientReq
  2787  	if err := json.Unmarshal(msg, &req); err != nil {
  2788  		s.sys.client.Errorf("Error unmarshalling kick client request: %v", err)
  2789  		return
  2790  	}
  2791  
  2792  	optz := &EventFilterOptions{}
  2793  	s.zReq(c, reply, hdr, msg, optz, optz, func() (interface{}, error) {
  2794  		return nil, s.DisconnectClientByID(req.CID)
  2795  	})
  2796  
  2797  }
  2798  
  2799  func (s *Server) ldmClient(_ *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
  2800  	if !s.eventsRunning() {
  2801  		return
  2802  	}
  2803  
  2804  	var req LDMClientReq
  2805  	if err := json.Unmarshal(msg, &req); err != nil {
  2806  		s.sys.client.Errorf("Error unmarshalling kick client request: %v", err)
  2807  		return
  2808  	}
  2809  
  2810  	optz := &EventFilterOptions{}
  2811  	s.zReq(c, reply, hdr, msg, optz, optz, func() (interface{}, error) {
  2812  		return nil, s.LDMClientByID(req.CID)
  2813  	})
  2814  }
  2815  
  2816  // Helper to grab account name for a client.
  2817  func accForClient(c *client) string {
  2818  	if c.acc != nil {
  2819  		return c.acc.Name
  2820  	}
  2821  	return "N/A"
  2822  }
  2823  
  2824  // Helper to grab issuer for a client.
  2825  func issuerForClient(c *client) (issuerKey string) {
  2826  	if c == nil || c.user == nil {
  2827  		return
  2828  	}
  2829  	issuerKey = c.user.SigningKey
  2830  	if issuerKey == _EMPTY_ && c.user.Account != nil {
  2831  		issuerKey = c.user.Account.Name
  2832  	}
  2833  	return
  2834  }
  2835  
  2836  // Helper to clear timers.
  2837  func clearTimer(tp **time.Timer) {
  2838  	if t := *tp; t != nil {
  2839  		t.Stop()
  2840  		*tp = nil
  2841  	}
  2842  }
  2843  
  2844  // Helper function to wrap functions with common test
  2845  // to lock server and return if events not enabled.
  2846  func (s *Server) wrapChk(f func()) func() {
  2847  	return func() {
  2848  		s.mu.Lock()
  2849  		if !s.eventsEnabled() {
  2850  			s.mu.Unlock()
  2851  			return
  2852  		}
  2853  		f()
  2854  		s.mu.Unlock()
  2855  	}
  2856  }
  2857  
  2858  // sendOCSPPeerRejectEvent sends a system level event to system account when a peer connection is
  2859  // rejected due to OCSP invalid status of its trust chain(s).
  2860  func (s *Server) sendOCSPPeerRejectEvent(kind string, peer *x509.Certificate, reason string) {
  2861  	s.mu.Lock()
  2862  	defer s.mu.Unlock()
  2863  	if !s.eventsEnabled() {
  2864  		return
  2865  	}
  2866  	if peer == nil {
  2867  		s.Errorf(certidp.ErrPeerEmptyNoEvent)
  2868  		return
  2869  	}
  2870  	eid := s.nextEventID()
  2871  	now := time.Now().UTC()
  2872  	m := OCSPPeerRejectEventMsg{
  2873  		TypedEvent: TypedEvent{
  2874  			Type: OCSPPeerRejectEventMsgType,
  2875  			ID:   eid,
  2876  			Time: now,
  2877  		},
  2878  		Kind: kind,
  2879  		Peer: certidp.CertInfo{
  2880  			Subject:     certidp.GetSubjectDNForm(peer),
  2881  			Issuer:      certidp.GetIssuerDNForm(peer),
  2882  			Fingerprint: certidp.GenerateFingerprint(peer),
  2883  			Raw:         peer.Raw,
  2884  		},
  2885  		Reason: reason,
  2886  	}
  2887  	subj := fmt.Sprintf(ocspPeerRejectEventSubj, s.info.ID)
  2888  	s.sendInternalMsg(subj, _EMPTY_, &m.Server, &m)
  2889  }
  2890  
  2891  // sendOCSPPeerChainlinkInvalidEvent sends a system level event to system account when a link in a peer's trust chain
  2892  // is OCSP invalid.
  2893  func (s *Server) sendOCSPPeerChainlinkInvalidEvent(peer *x509.Certificate, link *x509.Certificate, reason string) {
  2894  	s.mu.Lock()
  2895  	defer s.mu.Unlock()
  2896  	if !s.eventsEnabled() {
  2897  		return
  2898  	}
  2899  	if peer == nil || link == nil {
  2900  		s.Errorf(certidp.ErrPeerEmptyNoEvent)
  2901  		return
  2902  	}
  2903  	eid := s.nextEventID()
  2904  	now := time.Now().UTC()
  2905  	m := OCSPPeerChainlinkInvalidEventMsg{
  2906  		TypedEvent: TypedEvent{
  2907  			Type: OCSPPeerChainlinkInvalidEventMsgType,
  2908  			ID:   eid,
  2909  			Time: now,
  2910  		},
  2911  		Link: certidp.CertInfo{
  2912  			Subject:     certidp.GetSubjectDNForm(link),
  2913  			Issuer:      certidp.GetIssuerDNForm(link),
  2914  			Fingerprint: certidp.GenerateFingerprint(link),
  2915  			Raw:         link.Raw,
  2916  		},
  2917  		Peer: certidp.CertInfo{
  2918  			Subject:     certidp.GetSubjectDNForm(peer),
  2919  			Issuer:      certidp.GetIssuerDNForm(peer),
  2920  			Fingerprint: certidp.GenerateFingerprint(peer),
  2921  			Raw:         peer.Raw,
  2922  		},
  2923  		Reason: reason,
  2924  	}
  2925  	subj := fmt.Sprintf(ocspPeerChainlinkInvalidEventSubj, s.info.ID)
  2926  	s.sendInternalMsg(subj, _EMPTY_, &m.Server, &m)
  2927  }