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 }