get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/client.go (about) 1 // Copyright 2012-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 "crypto/tls" 19 "crypto/x509" 20 "encoding/json" 21 "errors" 22 "fmt" 23 "io" 24 "math/rand" 25 "net" 26 "net/http" 27 "net/url" 28 "regexp" 29 "runtime" 30 "strconv" 31 "strings" 32 "sync" 33 "sync/atomic" 34 "time" 35 36 "get.pme.sh/pnats/internal/fastrand" 37 "github.com/klauspost/compress/s2" 38 "github.com/nats-io/jwt/v2" 39 ) 40 41 // Type of client connection. 42 const ( 43 // CLIENT is an end user. 44 CLIENT = iota 45 // ROUTER represents another server in the cluster. 46 ROUTER 47 // GATEWAY is a link between 2 clusters. 48 GATEWAY 49 // SYSTEM is an internal system client. 50 SYSTEM 51 // LEAF is for leaf node connections. 52 LEAF 53 // JETSTREAM is an internal jetstream client. 54 JETSTREAM 55 // ACCOUNT is for the internal client for accounts. 56 ACCOUNT 57 ) 58 59 // Extended type of a CLIENT connection. This is returned by c.clientType() 60 // and indicate what type of client connection we are dealing with. 61 // If invoked on a non CLIENT connection, NON_CLIENT type is returned. 62 const ( 63 // If the connection is not a CLIENT connection. 64 NON_CLIENT = iota 65 // Regular NATS client. 66 NATS 67 // MQTT client. 68 MQTT 69 // Websocket client. 70 WS 71 ) 72 73 const ( 74 // ClientProtoZero is the original Client protocol from 2009. 75 // http://nats.io/documentation/internals/nats-protocol/ 76 ClientProtoZero = iota 77 // ClientProtoInfo signals a client can receive more then the original INFO block. 78 // This can be used to update clients on other cluster members, etc. 79 ClientProtoInfo 80 ) 81 82 const ( 83 pingProto = "PING" + _CRLF_ 84 pongProto = "PONG" + _CRLF_ 85 errProto = "-ERR '%s'" + _CRLF_ 86 okProto = "+OK" + _CRLF_ 87 ) 88 89 // TLS Hanshake client types 90 const ( 91 tlsHandshakeLeaf = "leafnode" 92 tlsHandshakeMQTT = "mqtt" 93 ) 94 95 const ( 96 // Scratch buffer size for the processMsg() calls. 97 msgScratchSize = 1024 98 msgHeadProto = "RMSG " 99 msgHeadProtoLen = len(msgHeadProto) 100 101 // For controlling dynamic buffer sizes. 102 startBufSize = 512 // For INFO/CONNECT block 103 minBufSize = 64 // Smallest to shrink to for PING/PONG 104 maxBufSize = 65536 // 64k 105 shortsToShrink = 2 // Trigger to shrink dynamic buffers 106 maxFlushPending = 10 // Max fsps to have in order to wait for writeLoop 107 readLoopReport = 2 * time.Second 108 109 // Server should not send a PING (for RTT) before the first PONG has 110 // been sent to the client. However, in case some client libs don't 111 // send CONNECT+PING, cap the maximum time before server can send 112 // the RTT PING. 113 maxNoRTTPingBeforeFirstPong = 2 * time.Second 114 115 // For stalling fast producers 116 stallClientMinDuration = 100 * time.Millisecond 117 stallClientMaxDuration = time.Second 118 ) 119 120 var readLoopReportThreshold = readLoopReport 121 122 // Represent client booleans with a bitmask 123 type clientFlag uint16 124 125 const ( 126 hdrLine = "NATS/1.0\r\n" 127 emptyHdrLine = "NATS/1.0\r\n\r\n" 128 ) 129 130 // Some client state represented as flags 131 const ( 132 connectReceived clientFlag = 1 << iota // The CONNECT proto has been received 133 infoReceived // The INFO protocol has been received 134 firstPongSent // The first PONG has been sent 135 handshakeComplete // For TLS clients, indicate that the handshake is complete 136 flushOutbound // Marks client as having a flushOutbound call in progress. 137 noReconnect // Indicate that on close, this connection should not attempt a reconnect 138 closeConnection // Marks that closeConnection has already been called. 139 connMarkedClosed // Marks that markConnAsClosed has already been called. 140 writeLoopStarted // Marks that the writeLoop has been started. 141 skipFlushOnClose // Marks that flushOutbound() should not be called on connection close. 142 expectConnect // Marks if this connection is expected to send a CONNECT 143 connectProcessFinished // Marks if this connection has finished the connect process. 144 compressionNegotiated // Marks if this connection has negotiated compression level with remote. 145 didTLSFirst // Marks if this connection requested and was accepted doing the TLS handshake first (prior to INFO). 146 isSlowConsumer // Marks connection as a slow consumer. 147 ) 148 149 // set the flag (would be equivalent to set the boolean to true) 150 func (cf *clientFlag) set(c clientFlag) { 151 *cf |= c 152 } 153 154 // clear the flag (would be equivalent to set the boolean to false) 155 func (cf *clientFlag) clear(c clientFlag) { 156 *cf &= ^c 157 } 158 159 // isSet returns true if the flag is set, false otherwise 160 func (cf clientFlag) isSet(c clientFlag) bool { 161 return cf&c != 0 162 } 163 164 // setIfNotSet will set the flag `c` only if that flag was not already 165 // set and return true to indicate that the flag has been set. Returns 166 // false otherwise. 167 func (cf *clientFlag) setIfNotSet(c clientFlag) bool { 168 if *cf&c == 0 { 169 *cf |= c 170 return true 171 } 172 return false 173 } 174 175 // ClosedState is the reason client was closed. This will 176 // be passed into calls to clearConnection, but will only 177 // be stored in ConnInfo for monitoring. 178 type ClosedState int 179 180 const ( 181 ClientClosed = ClosedState(iota + 1) 182 AuthenticationTimeout 183 AuthenticationViolation 184 TLSHandshakeError 185 SlowConsumerPendingBytes 186 SlowConsumerWriteDeadline 187 WriteError 188 ReadError 189 ParseError 190 StaleConnection 191 ProtocolViolation 192 BadClientProtocolVersion 193 WrongPort 194 MaxAccountConnectionsExceeded 195 MaxConnectionsExceeded 196 MaxPayloadExceeded 197 MaxControlLineExceeded 198 MaxSubscriptionsExceeded 199 DuplicateRoute 200 RouteRemoved 201 ServerShutdown 202 AuthenticationExpired 203 WrongGateway 204 MissingAccount 205 Revocation 206 InternalClient 207 MsgHeaderViolation 208 NoRespondersRequiresHeaders 209 ClusterNameConflict 210 DuplicateRemoteLeafnodeConnection 211 DuplicateClientID 212 DuplicateServerName 213 MinimumVersionRequired 214 ClusterNamesIdentical 215 Kicked 216 ) 217 218 // Some flags passed to processMsgResults 219 const pmrNoFlag int = 0 220 const ( 221 pmrCollectQueueNames int = 1 << iota 222 pmrIgnoreEmptyQueueFilter 223 pmrAllowSendFromRouteToRoute 224 pmrMsgImportedFromService 225 ) 226 227 type client struct { 228 // Here first because of use of atomics, and memory alignment. 229 stats 230 gwReplyMapping 231 kind int 232 srv *Server 233 acc *Account 234 perms *permissions 235 in readCache 236 parseState 237 opts ClientOpts 238 rrTracking *rrTracking 239 mpay int32 240 msubs int32 241 mcl int32 242 mu sync.Mutex 243 cid uint64 244 start time.Time 245 nonce []byte 246 pubKey string 247 nc net.Conn 248 ncs atomic.Value 249 out outbound 250 user *NkeyUser 251 host string 252 port uint16 253 subs map[string]*subscription 254 replies map[string]*resp 255 mperms *msgDeny 256 darray []string 257 pcd map[*client]struct{} 258 atmr *time.Timer 259 expires time.Time 260 ping pinfo 261 msgb [msgScratchSize]byte 262 last time.Time 263 lastIn time.Time 264 265 headers bool 266 267 rtt time.Duration 268 rttStart time.Time 269 270 route *route 271 gw *gateway 272 leaf *leaf 273 ws *websocket 274 mqtt *mqtt 275 276 flags clientFlag // Compact booleans into a single field. Size will be increased when needed. 277 278 rref byte 279 280 trace bool 281 echo bool 282 noIcb bool 283 284 tags jwt.TagList 285 nameTag string 286 287 tlsTo *time.Timer 288 } 289 290 type rrTracking struct { 291 rmap map[string]*remoteLatency 292 ptmr *time.Timer 293 lrt time.Duration 294 } 295 296 // Struct for PING initiation from the server. 297 type pinfo struct { 298 tmr *time.Timer 299 out int 300 } 301 302 // outbound holds pending data for a socket. 303 type outbound struct { 304 nb net.Buffers // Pending buffers for send, each has fixed capacity as per nbPool below. 305 wnb net.Buffers // Working copy of "nb", reused on each flushOutbound call, partial writes may leave entries here for next iteration. 306 pb int64 // Total pending/queued bytes. 307 fsp int32 // Flush signals that are pending per producer from readLoop's pcd. 308 sg *sync.Cond // To signal writeLoop that there is data to flush. 309 wdl time.Duration // Snapshot of write deadline. 310 mp int64 // Snapshot of max pending for client. 311 lft time.Duration // Last flush time for Write. 312 stc chan struct{} // Stall chan we create to slow down producers on overrun, e.g. fan-in. 313 cw *s2.Writer 314 } 315 316 const nbPoolSizeSmall = 512 // Underlying array size of small buffer 317 const nbPoolSizeMedium = 4096 // Underlying array size of medium buffer 318 const nbPoolSizeLarge = 65536 // Underlying array size of large buffer 319 320 var nbPoolSmall = &sync.Pool{ 321 New: func() any { 322 b := [nbPoolSizeSmall]byte{} 323 return &b 324 }, 325 } 326 327 var nbPoolMedium = &sync.Pool{ 328 New: func() any { 329 b := [nbPoolSizeMedium]byte{} 330 return &b 331 }, 332 } 333 334 var nbPoolLarge = &sync.Pool{ 335 New: func() any { 336 b := [nbPoolSizeLarge]byte{} 337 return &b 338 }, 339 } 340 341 // nbPoolGet returns a frame that is a best-effort match for the given size. 342 // Once a pooled frame is no longer needed, it should be recycled by passing 343 // it to nbPoolPut. 344 func nbPoolGet(sz int) []byte { 345 switch { 346 case sz <= nbPoolSizeSmall: 347 return nbPoolSmall.Get().(*[nbPoolSizeSmall]byte)[:0] 348 case sz <= nbPoolSizeMedium: 349 return nbPoolMedium.Get().(*[nbPoolSizeMedium]byte)[:0] 350 default: 351 return nbPoolLarge.Get().(*[nbPoolSizeLarge]byte)[:0] 352 } 353 } 354 355 // nbPoolPut recycles a frame that was retrieved from nbPoolGet. It is not 356 // safe to return multiple slices referring to chunks of the same underlying 357 // array as this may create overlaps when the buffers are returned to their 358 // original size, resulting in race conditions. 359 func nbPoolPut(b []byte) { 360 switch cap(b) { 361 case nbPoolSizeSmall: 362 b := (*[nbPoolSizeSmall]byte)(b[0:nbPoolSizeSmall]) 363 nbPoolSmall.Put(b) 364 case nbPoolSizeMedium: 365 b := (*[nbPoolSizeMedium]byte)(b[0:nbPoolSizeMedium]) 366 nbPoolMedium.Put(b) 367 case nbPoolSizeLarge: 368 b := (*[nbPoolSizeLarge]byte)(b[0:nbPoolSizeLarge]) 369 nbPoolLarge.Put(b) 370 default: 371 // Ignore frames that are the wrong size, this might happen 372 // with WebSocket/MQTT messages as they are framed 373 } 374 } 375 376 type perm struct { 377 allow *Sublist 378 deny *Sublist 379 } 380 381 type permissions struct { 382 // Have these 2 first for memory alignment due to the use of atomic. 383 pcsz int32 384 prun int32 385 sub perm 386 pub perm 387 resp *ResponsePermission 388 pcache sync.Map 389 } 390 391 // This is used to dynamically track responses and reply subjects 392 // for dynamic permissioning. 393 type resp struct { 394 t time.Time 395 n int 396 } 397 398 // msgDeny is used when a user permission for subscriptions has a deny 399 // clause but a subscription could be made that is of broader scope. 400 // e.g. deny = "foo", but user subscribes to "*". That subscription should 401 // succeed but no message sent on foo should be delivered. 402 type msgDeny struct { 403 deny *Sublist 404 dcache map[string]bool 405 } 406 407 // routeTarget collects information regarding routes and queue groups for 408 // sending information to a remote. 409 type routeTarget struct { 410 sub *subscription 411 qs []byte 412 _qs [32]byte 413 } 414 415 const ( 416 maxResultCacheSize = 512 417 maxDenyPermCacheSize = 256 418 maxPermCacheSize = 128 419 pruneSize = 32 420 routeTargetInit = 8 421 replyPermLimit = 4096 422 ) 423 424 // Represent read cache booleans with a bitmask 425 type readCacheFlag uint16 426 427 const ( 428 hasMappings readCacheFlag = 1 << iota // For account subject mappings. 429 switchToCompression readCacheFlag = 1 << 1 430 ) 431 432 const sysGroup = "_sys_" 433 434 // Used in readloop to cache hot subject lookups and group statistics. 435 type readCache struct { 436 // These are for clients who are bound to a single account. 437 genid uint64 438 results map[string]*SublistResult 439 440 // This is for routes and gateways to have their own L1 as well that is account aware. 441 pacache map[string]*perAccountCache 442 443 // This is for when we deliver messages across a route. We use this structure 444 // to make sure to only send one message and properly scope to queues as needed. 445 rts []routeTarget 446 447 // These are all temporary totals for an invocation of a read in readloop. 448 msgs int32 449 bytes int32 450 subs int32 451 452 rsz int32 // Read buffer size 453 srs int32 // Short reads, used for dynamic buffer resizing. 454 455 // These are for readcache flags to avoid locks. 456 flags readCacheFlag 457 458 // Capture the time we started processing our readLoop. 459 start time.Time 460 } 461 462 // set the flag (would be equivalent to set the boolean to true) 463 func (rcf *readCacheFlag) set(c readCacheFlag) { 464 *rcf |= c 465 } 466 467 // clear the flag (would be equivalent to set the boolean to false) 468 func (rcf *readCacheFlag) clear(c readCacheFlag) { 469 *rcf &= ^c 470 } 471 472 // isSet returns true if the flag is set, false otherwise 473 func (rcf readCacheFlag) isSet(c readCacheFlag) bool { 474 return rcf&c != 0 475 } 476 477 const ( 478 defaultMaxPerAccountCacheSize = 4096 479 defaultPrunePerAccountCacheSize = 256 480 defaultClosedSubsCheckInterval = 5 * time.Minute 481 ) 482 483 var ( 484 maxPerAccountCacheSize = defaultMaxPerAccountCacheSize 485 prunePerAccountCacheSize = defaultPrunePerAccountCacheSize 486 closedSubsCheckInterval = defaultClosedSubsCheckInterval 487 ) 488 489 // perAccountCache is for L1 semantics for inbound messages from a route or gateway to mimic the performance of clients. 490 type perAccountCache struct { 491 acc *Account 492 results *SublistResult 493 genid uint64 494 } 495 496 func (c *client) String() (id string) { 497 loaded := c.ncs.Load() 498 if loaded != nil { 499 return loaded.(string) 500 } 501 502 return _EMPTY_ 503 } 504 505 // GetNonce returns the nonce that was presented to the user on connection 506 func (c *client) GetNonce() []byte { 507 c.mu.Lock() 508 defer c.mu.Unlock() 509 510 return c.nonce 511 } 512 513 // GetName returns the application supplied name for the connection. 514 func (c *client) GetName() string { 515 c.mu.Lock() 516 name := c.opts.Name 517 c.mu.Unlock() 518 return name 519 } 520 521 // GetOpts returns the client options provided by the application. 522 func (c *client) GetOpts() *ClientOpts { 523 return &c.opts 524 } 525 526 // GetTLSConnectionState returns the TLS ConnectionState if TLS is enabled, nil 527 // otherwise. Implements the ClientAuth interface. 528 func (c *client) GetTLSConnectionState() *tls.ConnectionState { 529 c.mu.Lock() 530 defer c.mu.Unlock() 531 if c.nc == nil { 532 return nil 533 } 534 tc, ok := c.nc.(*tls.Conn) 535 if !ok { 536 return nil 537 } 538 state := tc.ConnectionState() 539 return &state 540 } 541 542 // For CLIENT connections, this function returns the client type, that is, 543 // NATS (for regular clients), MQTT or WS for websocket. 544 // If this is invoked for a non CLIENT connection, NON_CLIENT is returned. 545 // 546 // This function does not lock the client and accesses fields that are supposed 547 // to be immutable and therefore it can be invoked outside of the client's lock. 548 func (c *client) clientType() int { 549 switch c.kind { 550 case CLIENT: 551 if c.isMqtt() { 552 return MQTT 553 } else if c.isWebsocket() { 554 return WS 555 } 556 return NATS 557 default: 558 return NON_CLIENT 559 } 560 } 561 562 var clientTypeStringMap = map[int]string{ 563 NON_CLIENT: _EMPTY_, 564 NATS: "nats", 565 WS: "websocket", 566 MQTT: "mqtt", 567 } 568 569 func (c *client) clientTypeString() string { 570 if typeStringVal, ok := clientTypeStringMap[c.clientType()]; ok { 571 return typeStringVal 572 } 573 return _EMPTY_ 574 } 575 576 // This is the main subscription struct that indicates 577 // interest in published messages. 578 // FIXME(dlc) - This is getting bloated for normal subs, need 579 // to optionally have an opts section for non-normal stuff. 580 type subscription struct { 581 client *client 582 im *streamImport // This is for import stream support. 583 rsi bool 584 si bool 585 shadow []*subscription // This is to track shadowed accounts. 586 icb msgHandler 587 subject []byte 588 queue []byte 589 sid []byte 590 origin []byte 591 nm int64 592 max int64 593 qw int32 594 closed int32 595 mqtt *mqttSub 596 } 597 598 // Indicate that this subscription is closed. 599 // This is used in pruning of route and gateway cache items. 600 func (s *subscription) close() { 601 atomic.StoreInt32(&s.closed, 1) 602 } 603 604 // Return true if this subscription was unsubscribed 605 // or its connection has been closed. 606 func (s *subscription) isClosed() bool { 607 return atomic.LoadInt32(&s.closed) == 1 608 } 609 610 type ClientOpts struct { 611 Echo bool `json:"echo"` 612 Verbose bool `json:"verbose"` 613 Pedantic bool `json:"pedantic"` 614 TLSRequired bool `json:"tls_required"` 615 Nkey string `json:"nkey,omitempty"` 616 JWT string `json:"jwt,omitempty"` 617 Sig string `json:"sig,omitempty"` 618 Token string `json:"auth_token,omitempty"` 619 Username string `json:"user,omitempty"` 620 Password string `json:"pass,omitempty"` 621 Name string `json:"name"` 622 Lang string `json:"lang"` 623 Version string `json:"version"` 624 Protocol int `json:"protocol"` 625 Account string `json:"account,omitempty"` 626 AccountNew bool `json:"new_account,omitempty"` 627 Headers bool `json:"headers,omitempty"` 628 NoResponders bool `json:"no_responders,omitempty"` 629 630 // Routes and Leafnodes only 631 Import *SubjectPermission `json:"import,omitempty"` 632 Export *SubjectPermission `json:"export,omitempty"` 633 634 // Leafnodes 635 RemoteAccount string `json:"remote_account,omitempty"` 636 } 637 638 var defaultOpts = ClientOpts{Verbose: true, Pedantic: true, Echo: true} 639 var internalOpts = ClientOpts{Verbose: false, Pedantic: false, Echo: false} 640 641 func (c *client) setTraceLevel() { 642 if c.kind == SYSTEM && !(atomic.LoadInt32(&c.srv.logging.traceSysAcc) != 0) { 643 c.trace = false 644 } else { 645 c.trace = (atomic.LoadInt32(&c.srv.logging.trace) != 0) 646 } 647 } 648 649 // Lock should be held 650 func (c *client) initClient() { 651 s := c.srv 652 c.cid = atomic.AddUint64(&s.gcid, 1) 653 654 // Outbound data structure setup 655 c.out.sg = sync.NewCond(&(c.mu)) 656 opts := s.getOpts() 657 // Snapshots to avoid mutex access in fast paths. 658 c.out.wdl = opts.WriteDeadline 659 c.out.mp = opts.MaxPending 660 // Snapshot max control line since currently can not be changed on reload and we 661 // were checking it on each call to parse. If this changes and we allow MaxControlLine 662 // to be reloaded without restart, this code will need to change. 663 c.mcl = int32(opts.MaxControlLine) 664 if c.mcl == 0 { 665 c.mcl = MAX_CONTROL_LINE_SIZE 666 } 667 668 c.subs = make(map[string]*subscription) 669 c.echo = true 670 671 c.setTraceLevel() 672 673 // This is a scratch buffer used for processMsg() 674 // The msg header starts with "RMSG ", which can be used 675 // for both local and routes. 676 // in bytes that is [82 77 83 71 32]. 677 c.msgb = [msgScratchSize]byte{82, 77, 83, 71, 32} 678 679 // This is to track pending clients that have data to be flushed 680 // after we process inbound msgs from our own connection. 681 c.pcd = make(map[*client]struct{}) 682 683 // snapshot the string version of the connection 684 var conn string 685 if c.nc != nil { 686 if addr := c.nc.RemoteAddr(); addr != nil { 687 if conn = addr.String(); conn != _EMPTY_ { 688 host, port, _ := net.SplitHostPort(conn) 689 iPort, _ := strconv.Atoi(port) 690 c.host, c.port = host, uint16(iPort) 691 if c.isWebsocket() && c.ws.clientIP != _EMPTY_ { 692 cip := c.ws.clientIP 693 // Surround IPv6 addresses with square brackets, as 694 // net.JoinHostPort would do... 695 if strings.Contains(cip, ":") { 696 cip = "[" + cip + "]" 697 } 698 conn = fmt.Sprintf("%s/%s", cip, conn) 699 } 700 // Now that we have extracted host and port, escape 701 // the string because it is going to be used in Sprintf 702 conn = strings.ReplaceAll(conn, "%", "%%") 703 } 704 } 705 } 706 707 switch c.kind { 708 case CLIENT: 709 switch c.clientType() { 710 case NATS: 711 c.ncs.Store(fmt.Sprintf("%s - cid:%d", conn, c.cid)) 712 case WS: 713 c.ncs.Store(fmt.Sprintf("%s - wid:%d", conn, c.cid)) 714 case MQTT: 715 var ws string 716 if c.isWebsocket() { 717 ws = "_ws" 718 } 719 c.ncs.Store(fmt.Sprintf("%s - mid%s:%d", conn, ws, c.cid)) 720 } 721 case ROUTER: 722 c.ncs.Store(fmt.Sprintf("%s - rid:%d", conn, c.cid)) 723 case GATEWAY: 724 c.ncs.Store(fmt.Sprintf("%s - gid:%d", conn, c.cid)) 725 case LEAF: 726 var ws string 727 if c.isWebsocket() { 728 ws = "_ws" 729 } 730 c.ncs.Store(fmt.Sprintf("%s - lid%s:%d", conn, ws, c.cid)) 731 case SYSTEM: 732 c.ncs.Store("SYSTEM") 733 case JETSTREAM: 734 c.ncs.Store("JETSTREAM") 735 case ACCOUNT: 736 c.ncs.Store("ACCOUNT") 737 } 738 } 739 740 // RemoteAddress expose the Address of the client connection, 741 // nil when not connected or unknown 742 func (c *client) RemoteAddress() net.Addr { 743 c.mu.Lock() 744 defer c.mu.Unlock() 745 746 if c.nc == nil { 747 return nil 748 } 749 750 return c.nc.RemoteAddr() 751 } 752 753 // Helper function to report errors. 754 func (c *client) reportErrRegisterAccount(acc *Account, err error) { 755 if err == ErrTooManyAccountConnections { 756 c.maxAccountConnExceeded() 757 return 758 } 759 c.Errorf("Problem registering with account %q: %s", acc.Name, err) 760 c.sendErr("Failed Account Registration") 761 } 762 763 // Kind returns the client kind and will be one of the defined constants like CLIENT, ROUTER, GATEWAY, LEAF 764 func (c *client) Kind() int { 765 c.mu.Lock() 766 kind := c.kind 767 c.mu.Unlock() 768 769 return kind 770 } 771 772 // registerWithAccount will register the given user with a specific 773 // account. This will change the subject namespace. 774 func (c *client) registerWithAccount(acc *Account) error { 775 if acc == nil { 776 return ErrBadAccount 777 } 778 acc.mu.RLock() 779 bad := acc.sl == nil 780 acc.mu.RUnlock() 781 if bad { 782 return ErrBadAccount 783 } 784 // If we were previously registered, usually to $G, do accounting here to remove. 785 if c.acc != nil { 786 if prev := c.acc.removeClient(c); prev == 1 && c.srv != nil { 787 c.srv.decActiveAccounts() 788 } 789 } 790 791 c.mu.Lock() 792 kind := c.kind 793 srv := c.srv 794 c.acc = acc 795 c.applyAccountLimits() 796 c.mu.Unlock() 797 798 // Check if we have a max connections violation 799 if kind == CLIENT && acc.MaxTotalConnectionsReached() { 800 return ErrTooManyAccountConnections 801 } else if kind == LEAF { 802 // Check if we are already connected to this cluster. 803 if rc := c.remoteCluster(); rc != _EMPTY_ && acc.hasLeafNodeCluster(rc) { 804 return ErrLeafNodeLoop 805 } 806 if acc.MaxTotalLeafNodesReached() { 807 return ErrTooManyAccountConnections 808 } 809 } 810 811 // Add in new one. 812 if prev := acc.addClient(c); prev == 0 && srv != nil { 813 srv.incActiveAccounts() 814 } 815 816 return nil 817 } 818 819 // Helper to determine if we have met or exceeded max subs. 820 func (c *client) subsAtLimit() bool { 821 return c.msubs != jwt.NoLimit && len(c.subs) >= int(c.msubs) 822 } 823 824 func minLimit(value *int32, limit int32) bool { 825 v := atomic.LoadInt32(value) 826 if v != jwt.NoLimit { 827 if limit != jwt.NoLimit { 828 if limit < v { 829 atomic.StoreInt32(value, limit) 830 return true 831 } 832 } 833 } else if limit != jwt.NoLimit { 834 atomic.StoreInt32(value, limit) 835 return true 836 } 837 return false 838 } 839 840 // Apply account limits 841 // Lock is held on entry. 842 // FIXME(dlc) - Should server be able to override here? 843 func (c *client) applyAccountLimits() { 844 if c.acc == nil || (c.kind != CLIENT && c.kind != LEAF) { 845 return 846 } 847 atomic.StoreInt32(&c.mpay, jwt.NoLimit) 848 c.msubs = jwt.NoLimit 849 if c.opts.JWT != _EMPTY_ { // user jwt implies account 850 if uc, _ := jwt.DecodeUserClaims(c.opts.JWT); uc != nil { 851 c.mpay = int32(uc.Limits.Payload) 852 c.msubs = int32(uc.Limits.Subs) 853 if uc.IssuerAccount != _EMPTY_ && uc.IssuerAccount != uc.Issuer { 854 if scope, ok := c.acc.signingKeys[uc.Issuer]; ok { 855 if userScope, ok := scope.(*jwt.UserScope); ok { 856 // if signing key disappeared or changed and we don't get here, the client will be disconnected 857 c.mpay = int32(userScope.Template.Limits.Payload) 858 c.msubs = int32(userScope.Template.Limits.Subs) 859 } 860 } 861 } 862 } 863 } 864 865 c.acc.mu.RLock() 866 minLimit(&c.mpay, c.acc.mpay) 867 minLimit(&c.msubs, c.acc.msubs) 868 c.acc.mu.RUnlock() 869 870 s := c.srv 871 opts := s.getOpts() 872 mPay := opts.MaxPayload 873 // options encode unlimited differently 874 if mPay == 0 { 875 mPay = jwt.NoLimit 876 } 877 mSubs := int32(opts.MaxSubs) 878 if mSubs == 0 { 879 mSubs = jwt.NoLimit 880 } 881 wasUnlimited := c.mpay == jwt.NoLimit 882 if minLimit(&c.mpay, mPay) && !wasUnlimited { 883 c.Errorf("Max Payload set to %d from server overrides account or user config", opts.MaxPayload) 884 } 885 wasUnlimited = c.msubs == jwt.NoLimit 886 if minLimit(&c.msubs, mSubs) && !wasUnlimited { 887 c.Errorf("Max Subscriptions set to %d from server overrides account or user config", opts.MaxSubs) 888 } 889 if c.subsAtLimit() { 890 go func() { 891 c.maxSubsExceeded() 892 time.Sleep(20 * time.Millisecond) 893 c.closeConnection(MaxSubscriptionsExceeded) 894 }() 895 } 896 } 897 898 // RegisterUser allows auth to call back into a new client 899 // with the authenticated user. This is used to map 900 // any permissions into the client and setup accounts. 901 func (c *client) RegisterUser(user *User) { 902 // Register with proper account and sublist. 903 if user.Account != nil { 904 if err := c.registerWithAccount(user.Account); err != nil { 905 c.reportErrRegisterAccount(user.Account, err) 906 return 907 } 908 } 909 910 c.mu.Lock() 911 912 // Assign permissions. 913 if user.Permissions == nil { 914 // Reset perms to nil in case client previously had them. 915 c.perms = nil 916 c.mperms = nil 917 } else { 918 c.setPermissions(user.Permissions) 919 } 920 921 // allows custom authenticators to set a username to be reported in 922 // server events and more 923 if user.Username != _EMPTY_ { 924 c.opts.Username = user.Username 925 } 926 927 // if a deadline time stamp is set we start a timer to disconnect the user at that time 928 if !user.ConnectionDeadline.IsZero() { 929 c.setExpirationTimerUnlocked(time.Until(user.ConnectionDeadline)) 930 } 931 932 c.mu.Unlock() 933 } 934 935 // RegisterNkeyUser allows auth to call back into a new nkey 936 // client with the authenticated user. This is used to map 937 // any permissions into the client and setup accounts. 938 func (c *client) RegisterNkeyUser(user *NkeyUser) error { 939 // Register with proper account and sublist. 940 if user.Account != nil { 941 if err := c.registerWithAccount(user.Account); err != nil { 942 c.reportErrRegisterAccount(user.Account, err) 943 return err 944 } 945 } 946 947 c.mu.Lock() 948 c.user = user 949 // Assign permissions. 950 if user.Permissions == nil { 951 // Reset perms to nil in case client previously had them. 952 c.perms = nil 953 c.mperms = nil 954 } else { 955 c.setPermissions(user.Permissions) 956 } 957 c.mu.Unlock() 958 return nil 959 } 960 961 func splitSubjectQueue(sq string) ([]byte, []byte, error) { 962 vals := strings.Fields(strings.TrimSpace(sq)) 963 s := []byte(vals[0]) 964 var q []byte 965 if len(vals) == 2 { 966 q = []byte(vals[1]) 967 } else if len(vals) > 2 { 968 return nil, nil, fmt.Errorf("invalid subject-queue %q", sq) 969 } 970 return s, q, nil 971 } 972 973 // Initializes client.perms structure. 974 // Lock is held on entry. 975 func (c *client) setPermissions(perms *Permissions) { 976 if perms == nil { 977 return 978 } 979 c.perms = &permissions{} 980 981 // Loop over publish permissions 982 if perms.Publish != nil { 983 if perms.Publish.Allow != nil { 984 c.perms.pub.allow = NewSublistWithCache() 985 } 986 for _, pubSubject := range perms.Publish.Allow { 987 sub := &subscription{subject: []byte(pubSubject)} 988 c.perms.pub.allow.Insert(sub) 989 } 990 if len(perms.Publish.Deny) > 0 { 991 c.perms.pub.deny = NewSublistWithCache() 992 } 993 for _, pubSubject := range perms.Publish.Deny { 994 sub := &subscription{subject: []byte(pubSubject)} 995 c.perms.pub.deny.Insert(sub) 996 } 997 } 998 999 // Check if we are allowed to send responses. 1000 if perms.Response != nil { 1001 rp := *perms.Response 1002 c.perms.resp = &rp 1003 c.replies = make(map[string]*resp) 1004 } 1005 1006 // Loop over subscribe permissions 1007 if perms.Subscribe != nil { 1008 var err error 1009 if len(perms.Subscribe.Allow) > 0 { 1010 c.perms.sub.allow = NewSublistWithCache() 1011 } 1012 for _, subSubject := range perms.Subscribe.Allow { 1013 sub := &subscription{} 1014 sub.subject, sub.queue, err = splitSubjectQueue(subSubject) 1015 if err != nil { 1016 c.Errorf("%s", err.Error()) 1017 continue 1018 } 1019 c.perms.sub.allow.Insert(sub) 1020 } 1021 if len(perms.Subscribe.Deny) > 0 { 1022 c.perms.sub.deny = NewSublistWithCache() 1023 // Also hold onto this array for later. 1024 c.darray = perms.Subscribe.Deny 1025 } 1026 for _, subSubject := range perms.Subscribe.Deny { 1027 sub := &subscription{} 1028 sub.subject, sub.queue, err = splitSubjectQueue(subSubject) 1029 if err != nil { 1030 c.Errorf("%s", err.Error()) 1031 continue 1032 } 1033 c.perms.sub.deny.Insert(sub) 1034 } 1035 } 1036 1037 // If we are a leafnode and we are the hub copy the extracted perms 1038 // to resend back to soliciting server. These are reversed from the 1039 // way routes interpret them since this is how the soliciting server 1040 // will receive these back in an update INFO. 1041 if c.isHubLeafNode() { 1042 c.opts.Import = perms.Subscribe 1043 c.opts.Export = perms.Publish 1044 } 1045 } 1046 1047 // Build public permissions from internal ones. 1048 // Used for user info requests. 1049 func (c *client) publicPermissions() *Permissions { 1050 c.mu.Lock() 1051 defer c.mu.Unlock() 1052 1053 if c.perms == nil { 1054 return nil 1055 } 1056 perms := &Permissions{ 1057 Publish: &SubjectPermission{}, 1058 Subscribe: &SubjectPermission{}, 1059 } 1060 1061 _subs := [32]*subscription{} 1062 1063 // Publish 1064 if c.perms.pub.allow != nil { 1065 subs := _subs[:0] 1066 c.perms.pub.allow.All(&subs) 1067 for _, sub := range subs { 1068 perms.Publish.Allow = append(perms.Publish.Allow, string(sub.subject)) 1069 } 1070 } 1071 if c.perms.pub.deny != nil { 1072 subs := _subs[:0] 1073 c.perms.pub.deny.All(&subs) 1074 for _, sub := range subs { 1075 perms.Publish.Deny = append(perms.Publish.Deny, string(sub.subject)) 1076 } 1077 } 1078 // Subsribe 1079 if c.perms.sub.allow != nil { 1080 subs := _subs[:0] 1081 c.perms.sub.allow.All(&subs) 1082 for _, sub := range subs { 1083 perms.Subscribe.Allow = append(perms.Subscribe.Allow, string(sub.subject)) 1084 } 1085 } 1086 if c.perms.sub.deny != nil { 1087 subs := _subs[:0] 1088 c.perms.sub.deny.All(&subs) 1089 for _, sub := range subs { 1090 perms.Subscribe.Deny = append(perms.Subscribe.Deny, string(sub.subject)) 1091 } 1092 } 1093 // Responses. 1094 if c.perms.resp != nil { 1095 rp := *c.perms.resp 1096 perms.Response = &rp 1097 } 1098 1099 return perms 1100 } 1101 1102 type denyType int 1103 1104 const ( 1105 pub = denyType(iota + 1) 1106 sub 1107 both 1108 ) 1109 1110 // Merge client.perms structure with additional pub deny permissions 1111 // Lock is held on entry. 1112 func (c *client) mergeDenyPermissions(what denyType, denyPubs []string) { 1113 if len(denyPubs) == 0 { 1114 return 1115 } 1116 if c.perms == nil { 1117 c.perms = &permissions{} 1118 } 1119 var perms []*perm 1120 switch what { 1121 case pub: 1122 perms = []*perm{&c.perms.pub} 1123 case sub: 1124 perms = []*perm{&c.perms.sub} 1125 case both: 1126 perms = []*perm{&c.perms.pub, &c.perms.sub} 1127 } 1128 for _, p := range perms { 1129 if p.deny == nil { 1130 p.deny = NewSublistWithCache() 1131 } 1132 FOR_DENY: 1133 for _, subj := range denyPubs { 1134 r := p.deny.Match(subj) 1135 for _, v := range r.qsubs { 1136 for _, s := range v { 1137 if string(s.subject) == subj { 1138 continue FOR_DENY 1139 } 1140 } 1141 } 1142 for _, s := range r.psubs { 1143 if string(s.subject) == subj { 1144 continue FOR_DENY 1145 } 1146 } 1147 sub := &subscription{subject: []byte(subj)} 1148 p.deny.Insert(sub) 1149 } 1150 } 1151 } 1152 1153 // Merge client.perms structure with additional pub deny permissions 1154 // Client lock must not be held on entry 1155 func (c *client) mergeDenyPermissionsLocked(what denyType, denyPubs []string) { 1156 c.mu.Lock() 1157 c.mergeDenyPermissions(what, denyPubs) 1158 c.mu.Unlock() 1159 } 1160 1161 // Check to see if we have an expiration for the user JWT via base claims. 1162 // FIXME(dlc) - Clear on connect with new JWT. 1163 func (c *client) setExpiration(claims *jwt.ClaimsData, validFor time.Duration) { 1164 if claims.Expires == 0 { 1165 if validFor != 0 { 1166 c.setExpirationTimer(validFor) 1167 } 1168 return 1169 } 1170 expiresAt := time.Duration(0) 1171 tn := time.Now().Unix() 1172 if claims.Expires > tn { 1173 expiresAt = time.Duration(claims.Expires-tn) * time.Second 1174 } 1175 if validFor != 0 && validFor < expiresAt { 1176 c.setExpirationTimer(validFor) 1177 } else { 1178 c.setExpirationTimer(expiresAt) 1179 } 1180 } 1181 1182 // This will load up the deny structure used for filtering delivered 1183 // messages based on a deny clause for subscriptions. 1184 // Lock should be held. 1185 func (c *client) loadMsgDenyFilter() { 1186 c.mperms = &msgDeny{NewSublistWithCache(), make(map[string]bool)} 1187 for _, sub := range c.darray { 1188 c.mperms.deny.Insert(&subscription{subject: []byte(sub)}) 1189 } 1190 } 1191 1192 // writeLoop is the main socket write functionality. 1193 // Runs in its own Go routine. 1194 func (c *client) writeLoop() { 1195 defer c.srv.grWG.Done() 1196 c.mu.Lock() 1197 if c.isClosed() { 1198 c.mu.Unlock() 1199 return 1200 } 1201 c.flags.set(writeLoopStarted) 1202 c.mu.Unlock() 1203 1204 // Used to check that we did flush from last wake up. 1205 waitOk := true 1206 var closed bool 1207 1208 // Main loop. Will wait to be signaled and then will use 1209 // buffered outbound structure for efficient writev to the underlying socket. 1210 for { 1211 c.mu.Lock() 1212 if closed = c.isClosed(); !closed { 1213 owtf := c.out.fsp > 0 && c.out.pb < maxBufSize && c.out.fsp < maxFlushPending 1214 if waitOk && (c.out.pb == 0 || owtf) { 1215 c.out.sg.Wait() 1216 // Check that connection has not been closed while lock was released 1217 // in the conditional wait. 1218 closed = c.isClosed() 1219 } 1220 } 1221 if closed { 1222 c.flushAndClose(false) 1223 c.mu.Unlock() 1224 1225 // We should always call closeConnection() to ensure that state is 1226 // properly cleaned-up. It will be a no-op if already done. 1227 c.closeConnection(WriteError) 1228 1229 // Now explicitly call reconnect(). Thanks to ref counting, we know 1230 // that the reconnect will execute only after connection has been 1231 // removed from the server state. 1232 c.reconnect() 1233 return 1234 } 1235 // Flush data 1236 waitOk = c.flushOutbound() 1237 c.mu.Unlock() 1238 } 1239 } 1240 1241 // flushClients will make sure to flush any clients we may have 1242 // sent to during processing. We pass in a budget as a time.Duration 1243 // for how much time to spend in place flushing for this client. 1244 func (c *client) flushClients(budget time.Duration) time.Time { 1245 last := time.Now() 1246 1247 // Check pending clients for flush. 1248 for cp := range c.pcd { 1249 // TODO(dlc) - Wonder if it makes more sense to create a new map? 1250 delete(c.pcd, cp) 1251 1252 // Queue up a flush for those in the set 1253 cp.mu.Lock() 1254 // Update last activity for message delivery 1255 cp.last = last 1256 // Remove ourselves from the pending list. 1257 cp.out.fsp-- 1258 1259 // Just ignore if this was closed. 1260 if cp.isClosed() { 1261 cp.mu.Unlock() 1262 continue 1263 } 1264 1265 if budget > 0 && cp.out.lft < 2*budget && cp.flushOutbound() { 1266 budget -= cp.out.lft 1267 } else { 1268 cp.flushSignal() 1269 } 1270 1271 cp.mu.Unlock() 1272 } 1273 return last 1274 } 1275 1276 // readLoop is the main socket read functionality. 1277 // Runs in its own Go routine. 1278 func (c *client) readLoop(pre []byte) { 1279 // Grab the connection off the client, it will be cleared on a close. 1280 // We check for that after the loop, but want to avoid a nil dereference 1281 c.mu.Lock() 1282 s := c.srv 1283 defer s.grWG.Done() 1284 if c.isClosed() { 1285 c.mu.Unlock() 1286 return 1287 } 1288 nc := c.nc 1289 ws := c.isWebsocket() 1290 if c.isMqtt() { 1291 c.mqtt.r = &mqttReader{reader: nc} 1292 } 1293 c.in.rsz = startBufSize 1294 1295 // Check the per-account-cache for closed subscriptions 1296 cpacc := c.kind == ROUTER || c.kind == GATEWAY 1297 // Last per-account-cache check for closed subscriptions 1298 lpacc := time.Now() 1299 acc := c.acc 1300 var masking bool 1301 if ws { 1302 masking = c.ws.maskread 1303 } 1304 checkCompress := c.kind == ROUTER || c.kind == LEAF 1305 c.mu.Unlock() 1306 1307 defer func() { 1308 if c.isMqtt() { 1309 s.mqttHandleClosedClient(c) 1310 } 1311 // These are used only in the readloop, so we can set them to nil 1312 // on exit of the readLoop. 1313 c.in.results, c.in.pacache = nil, nil 1314 }() 1315 1316 // Start read buffer. 1317 b := make([]byte, c.in.rsz) 1318 1319 // Websocket clients will return several slices if there are multiple 1320 // websocket frames in the blind read. For non WS clients though, we 1321 // will always have 1 slice per loop iteration. So we define this here 1322 // so non WS clients will use bufs[0] = b[:n]. 1323 var _bufs [1][]byte 1324 bufs := _bufs[:1] 1325 1326 var wsr *wsReadInfo 1327 if ws { 1328 wsr = &wsReadInfo{mask: masking} 1329 wsr.init() 1330 } 1331 1332 var decompress bool 1333 var reader io.Reader 1334 reader = nc 1335 1336 for { 1337 var n int 1338 var err error 1339 1340 // If we have a pre buffer parse that first. 1341 if len(pre) > 0 { 1342 b = pre 1343 n = len(pre) 1344 pre = nil 1345 } else { 1346 n, err = reader.Read(b) 1347 // If we have any data we will try to parse and exit at the end. 1348 if n == 0 && err != nil { 1349 c.closeConnection(closedStateForErr(err)) 1350 return 1351 } 1352 } 1353 if ws { 1354 bufs, err = c.wsRead(wsr, reader, b[:n]) 1355 if bufs == nil && err != nil { 1356 if err != io.EOF { 1357 c.Errorf("read error: %v", err) 1358 } 1359 c.closeConnection(closedStateForErr(err)) 1360 return 1361 } else if bufs == nil { 1362 continue 1363 } 1364 } else { 1365 bufs[0] = b[:n] 1366 } 1367 1368 // Check if the account has mappings and if so set the local readcache flag. 1369 // We check here to make sure any changes such as config reload are reflected here. 1370 if c.kind == CLIENT || c.kind == LEAF { 1371 if acc.hasMappings() { 1372 c.in.flags.set(hasMappings) 1373 } else { 1374 c.in.flags.clear(hasMappings) 1375 } 1376 } 1377 1378 c.in.start = time.Now() 1379 1380 // Clear inbound stats cache 1381 c.in.msgs = 0 1382 c.in.bytes = 0 1383 c.in.subs = 0 1384 1385 // Main call into parser for inbound data. This will generate callouts 1386 // to process messages, etc. 1387 for i := 0; i < len(bufs); i++ { 1388 if err := c.parse(bufs[i]); err != nil { 1389 if err == ErrMinimumVersionRequired { 1390 // Special case here, currently only for leaf node connections. 1391 // When process the CONNECT protocol, if the minimum version 1392 // required was not met, an error was printed and sent back to 1393 // the remote, and connection was closed after a certain delay 1394 // (to avoid "rapid" reconnection from the remote). 1395 // We don't need to do any of the things below, simply return. 1396 return 1397 } 1398 if dur := time.Since(c.in.start); dur >= readLoopReportThreshold { 1399 c.Warnf("Readloop processing time: %v", dur) 1400 } 1401 // Need to call flushClients because some of the clients have been 1402 // assigned messages and their "fsp" incremented, and need now to be 1403 // decremented and their writeLoop signaled. 1404 c.flushClients(0) 1405 // handled inline 1406 if err != ErrMaxPayload && err != ErrAuthentication { 1407 c.Error(err) 1408 c.closeConnection(ProtocolViolation) 1409 } 1410 return 1411 } 1412 } 1413 1414 // If we are a ROUTER/LEAF and have processed an INFO, it is possible that 1415 // we are asked to switch to compression now. 1416 if checkCompress && c.in.flags.isSet(switchToCompression) { 1417 c.in.flags.clear(switchToCompression) 1418 // For now we support only s2 compression... 1419 reader = s2.NewReader(nc) 1420 decompress = true 1421 } 1422 1423 // Updates stats for client and server that were collected 1424 // from parsing through the buffer. 1425 if c.in.msgs > 0 { 1426 atomic.AddInt64(&c.inMsgs, int64(c.in.msgs)) 1427 atomic.AddInt64(&c.inBytes, int64(c.in.bytes)) 1428 if acc != nil { 1429 atomic.AddInt64(&acc.inMsgs, int64(c.in.msgs)) 1430 atomic.AddInt64(&acc.inBytes, int64(c.in.bytes)) 1431 } 1432 atomic.AddInt64(&s.inMsgs, int64(c.in.msgs)) 1433 atomic.AddInt64(&s.inBytes, int64(c.in.bytes)) 1434 } 1435 1436 // Signal to writeLoop to flush to socket. 1437 last := c.flushClients(0) 1438 1439 // Update activity, check read buffer size. 1440 c.mu.Lock() 1441 1442 // Activity based on interest changes or data/msgs. 1443 // Also update last receive activity for ping sender 1444 if c.in.msgs > 0 || c.in.subs > 0 { 1445 c.last = last 1446 c.lastIn = last 1447 } 1448 1449 if n >= cap(b) { 1450 c.in.srs = 0 1451 } else if n < cap(b)/2 { // divide by 2 b/c we want less than what we would shrink to. 1452 c.in.srs++ 1453 } 1454 1455 // Update read buffer size as/if needed. 1456 if n >= cap(b) && cap(b) < maxBufSize { 1457 // Grow 1458 c.in.rsz = int32(cap(b) * 2) 1459 b = make([]byte, c.in.rsz) 1460 } else if n < cap(b) && cap(b) > minBufSize && c.in.srs > shortsToShrink { 1461 // Shrink, for now don't accelerate, ping/pong will eventually sort it out. 1462 c.in.rsz = int32(cap(b) / 2) 1463 b = make([]byte, c.in.rsz) 1464 } 1465 // re-snapshot the account since it can change during reload, etc. 1466 acc = c.acc 1467 // Refresh nc because in some cases, we have upgraded c.nc to TLS. 1468 if nc != c.nc { 1469 nc = c.nc 1470 if decompress && nc != nil { 1471 // For now we support only s2 compression... 1472 reader.(*s2.Reader).Reset(nc) 1473 } else if !decompress { 1474 reader = nc 1475 } 1476 } 1477 c.mu.Unlock() 1478 1479 // Connection was closed 1480 if nc == nil { 1481 return 1482 } 1483 1484 if dur := time.Since(c.in.start); dur >= readLoopReportThreshold { 1485 c.Warnf("Readloop processing time: %v", dur) 1486 } 1487 1488 // We could have had a read error from above but still read some data. 1489 // If so do the close here unconditionally. 1490 if err != nil { 1491 c.closeConnection(closedStateForErr(err)) 1492 return 1493 } 1494 1495 if cpacc && (c.in.start.Sub(lpacc)) >= closedSubsCheckInterval { 1496 c.pruneClosedSubFromPerAccountCache() 1497 lpacc = time.Now() 1498 } 1499 } 1500 } 1501 1502 // Returns the appropriate closed state for a given read error. 1503 func closedStateForErr(err error) ClosedState { 1504 if err == io.EOF { 1505 return ClientClosed 1506 } 1507 return ReadError 1508 } 1509 1510 // collapsePtoNB will either returned framed WebSocket buffers or it will 1511 // return a reference to c.out.nb. 1512 func (c *client) collapsePtoNB() (net.Buffers, int64) { 1513 if c.isWebsocket() { 1514 return c.wsCollapsePtoNB() 1515 } 1516 return c.out.nb, c.out.pb 1517 } 1518 1519 // flushOutbound will flush outbound buffer to a client. 1520 // Will return true if data was attempted to be written. 1521 // Lock must be held 1522 func (c *client) flushOutbound() bool { 1523 if c.flags.isSet(flushOutbound) { 1524 // For CLIENT connections, it is possible that the readLoop calls 1525 // flushOutbound(). If writeLoop and readLoop compete and we are 1526 // here we should release the lock to reduce the risk of spinning. 1527 c.mu.Unlock() 1528 runtime.Gosched() 1529 c.mu.Lock() 1530 return false 1531 } 1532 c.flags.set(flushOutbound) 1533 defer c.flags.clear(flushOutbound) 1534 1535 // Check for nothing to do. 1536 if c.nc == nil || c.srv == nil || c.out.pb == 0 { 1537 return true // true because no need to queue a signal. 1538 } 1539 1540 // In the case of a normal socket connection, "collapsed" is just a ref 1541 // to "nb". In the case of WebSockets, additional framing is added to 1542 // anything that is waiting in "nb". Also keep a note of how many bytes 1543 // were queued before we release the mutex. 1544 collapsed, attempted := c.collapsePtoNB() 1545 1546 // Frustratingly, (net.Buffers).WriteTo() modifies the receiver so we 1547 // can't work on "nb" directly — while the mutex is unlocked during IO, 1548 // something else might call queueOutbound and modify it. So instead we 1549 // need a working copy — we'll operate on "wnb" instead. Note that in 1550 // the case of a partial write, "wnb" may have remaining data from the 1551 // previous write, and in the case of WebSockets, that data may already 1552 // be framed, so we are careful not to re-frame "wnb" here. Instead we 1553 // will just frame up "nb" and append it onto whatever is left on "wnb". 1554 // "nb" will be set to nil so that we can manipulate "collapsed" outside 1555 // of the client's lock, which is interesting in case of compression. 1556 c.out.nb = nil 1557 1558 // In case it goes away after releasing the lock. 1559 nc := c.nc 1560 1561 // Capture this (we change the value in some tests) 1562 wdl := c.out.wdl 1563 1564 // Check for compression 1565 cw := c.out.cw 1566 if cw != nil { 1567 // We will have to adjust once we have compressed, so remove for now. 1568 c.out.pb -= attempted 1569 if c.isWebsocket() { 1570 c.ws.fs -= attempted 1571 } 1572 } 1573 1574 // Do NOT hold lock during actual IO. 1575 c.mu.Unlock() 1576 1577 // Compress outside of the lock 1578 if cw != nil { 1579 var err error 1580 bb := bytes.Buffer{} 1581 1582 cw.Reset(&bb) 1583 for _, buf := range collapsed { 1584 if _, err = cw.Write(buf); err != nil { 1585 break 1586 } 1587 } 1588 if err == nil { 1589 err = cw.Close() 1590 } 1591 if err != nil { 1592 c.Errorf("Error compressing data: %v", err) 1593 c.markConnAsClosed(WriteError) 1594 return false 1595 } 1596 collapsed = append(net.Buffers(nil), bb.Bytes()) 1597 attempted = int64(len(collapsed[0])) 1598 } 1599 1600 // This is safe to do outside of the lock since "collapsed" is no longer 1601 // referenced in c.out.nb (which can be modified in queueOutboud() while 1602 // the lock is released). 1603 c.out.wnb = append(c.out.wnb, collapsed...) 1604 var _orig [1024][]byte 1605 orig := append(_orig[:0], c.out.wnb...) 1606 1607 // Since WriteTo is lopping things off the beginning, we need to remember 1608 // the start position of the underlying array so that we can get back to it. 1609 // Otherwise we'll always "slide forward" and that will result in reallocs. 1610 startOfWnb := c.out.wnb[0:] 1611 1612 // flush here 1613 start := time.Now() 1614 1615 // FIXME(dlc) - writev will do multiple IOs past 1024 on 1616 // most platforms, need to account for that with deadline? 1617 nc.SetWriteDeadline(start.Add(wdl)) 1618 1619 // Actual write to the socket. 1620 n, err := c.out.wnb.WriteTo(nc) 1621 nc.SetWriteDeadline(time.Time{}) 1622 1623 lft := time.Since(start) 1624 1625 // Re-acquire client lock. 1626 c.mu.Lock() 1627 1628 // Adjust if we were compressing. 1629 if cw != nil { 1630 c.out.pb += attempted 1631 if c.isWebsocket() { 1632 c.ws.fs += attempted 1633 } 1634 } 1635 1636 // At this point, "wnb" has been mutated by WriteTo and any consumed 1637 // buffers have been lopped off the beginning, so in order to return 1638 // them to the pool, we need to look at the difference between "orig" 1639 // and "wnb". 1640 for i := 0; i < len(orig)-len(c.out.wnb); i++ { 1641 nbPoolPut(orig[i]) 1642 } 1643 1644 // At this point it's possible that "nb" has been modified by another 1645 // call to queueOutbound while the lock was released, so we'll leave 1646 // those for the next iteration. Meanwhile it's possible that we only 1647 // managed a partial write of "wnb", so we'll shift anything that 1648 // remains up to the beginning of the array to prevent reallocating. 1649 // Anything left in "wnb" has already been framed for WebSocket conns 1650 // so leave them alone for the next call to flushOutbound. 1651 c.out.wnb = append(startOfWnb[:0], c.out.wnb...) 1652 1653 // If we've written everything but the underlying array of our working 1654 // buffer has grown excessively then free it — the GC will tidy it up 1655 // and we can allocate a new one next time. 1656 if len(c.out.wnb) == 0 && cap(c.out.wnb) > nbPoolSizeLarge*8 { 1657 c.out.wnb = nil 1658 } 1659 1660 // Ignore ErrShortWrite errors, they will be handled as partials. 1661 var gotWriteTimeout bool 1662 if err != nil && err != io.ErrShortWrite { 1663 // Handle timeout error (slow consumer) differently 1664 if ne, ok := err.(net.Error); ok && ne.Timeout() { 1665 gotWriteTimeout = true 1666 if closed := c.handleWriteTimeout(n, attempted, len(orig)); closed { 1667 return true 1668 } 1669 } else { 1670 // Other errors will cause connection to be closed. 1671 // For clients, report as debug but for others report as error. 1672 report := c.Debugf 1673 if c.kind != CLIENT { 1674 report = c.Errorf 1675 } 1676 report("Error flushing: %v", err) 1677 c.markConnAsClosed(WriteError) 1678 return true 1679 } 1680 } 1681 1682 // Update flush time statistics. 1683 c.out.lft = lft 1684 1685 // Subtract from pending bytes and messages. 1686 c.out.pb -= n 1687 if c.isWebsocket() { 1688 c.ws.fs -= n 1689 } 1690 1691 // Check that if there is still data to send and writeLoop is in wait, 1692 // then we need to signal. 1693 if c.out.pb > 0 { 1694 c.flushSignal() 1695 } 1696 1697 // Check if we have a stalled gate and if so and we are recovering release 1698 // any stalled producers. Only kind==CLIENT will stall. 1699 if c.out.stc != nil && (n == attempted || c.out.pb < c.out.mp/2) { 1700 close(c.out.stc) 1701 c.out.stc = nil 1702 } 1703 // Check if the connection is recovering from being a slow consumer. 1704 if !gotWriteTimeout && c.flags.isSet(isSlowConsumer) { 1705 c.Noticef("Slow Consumer Recovered: Flush took %.3fs with %d chunks of %d total bytes.", time.Since(start).Seconds(), len(orig), attempted) 1706 c.flags.clear(isSlowConsumer) 1707 } 1708 1709 return true 1710 } 1711 1712 // This is invoked from flushOutbound() for io/timeout error (slow consumer). 1713 // Returns a boolean to indicate if the connection has been closed or not. 1714 // Lock is held on entry. 1715 func (c *client) handleWriteTimeout(written, attempted int64, numChunks int) bool { 1716 if tlsConn, ok := c.nc.(*tls.Conn); ok { 1717 if !tlsConn.ConnectionState().HandshakeComplete { 1718 // Likely a TLSTimeout error instead... 1719 c.markConnAsClosed(TLSHandshakeError) 1720 // Would need to coordinate with tlstimeout() 1721 // to avoid double logging, so skip logging 1722 // here, and don't report a slow consumer error. 1723 return true 1724 } 1725 } else if c.flags.isSet(expectConnect) && !c.flags.isSet(connectReceived) { 1726 // Under some conditions, a connection may hit a slow consumer write deadline 1727 // before the authorization timeout. If that is the case, then we handle 1728 // as slow consumer though we do not increase the counter as that can be 1729 // misleading. 1730 c.markConnAsClosed(SlowConsumerWriteDeadline) 1731 return true 1732 } 1733 alreadySC := c.flags.isSet(isSlowConsumer) 1734 scState := "Detected" 1735 if alreadySC { 1736 scState = "State" 1737 } 1738 1739 // Aggregate slow consumers. 1740 atomic.AddInt64(&c.srv.slowConsumers, 1) 1741 switch c.kind { 1742 case CLIENT: 1743 c.srv.scStats.clients.Add(1) 1744 case ROUTER: 1745 // Only count each Slow Consumer event once. 1746 if !alreadySC { 1747 c.srv.scStats.routes.Add(1) 1748 } 1749 case GATEWAY: 1750 c.srv.scStats.gateways.Add(1) 1751 case LEAF: 1752 c.srv.scStats.leafs.Add(1) 1753 } 1754 if c.acc != nil { 1755 atomic.AddInt64(&c.acc.slowConsumers, 1) 1756 } 1757 c.Noticef("Slow Consumer %s: WriteDeadline of %v exceeded with %d chunks of %d total bytes.", 1758 scState, c.out.wdl, numChunks, attempted) 1759 1760 // We always close CLIENT connections, or when nothing was written at all... 1761 if c.kind == CLIENT || written == 0 { 1762 c.markConnAsClosed(SlowConsumerWriteDeadline) 1763 return true 1764 } else { 1765 c.flags.setIfNotSet(isSlowConsumer) 1766 } 1767 return false 1768 } 1769 1770 // Marks this connection has closed with the given reason. 1771 // Sets the connMarkedClosed flag and skipFlushOnClose depending on the reason. 1772 // Depending on the kind of connection, the connection will be saved. 1773 // If a writeLoop has been started, the final flush will be done there, otherwise 1774 // flush and close of TCP connection is done here in place. 1775 // Returns true if closed in place, flase otherwise. 1776 // Lock is held on entry. 1777 func (c *client) markConnAsClosed(reason ClosedState) { 1778 // Possibly set skipFlushOnClose flag even if connection has already been 1779 // mark as closed. The rationale is that a connection may be closed with 1780 // a reason that justifies a flush (say after sending an -ERR), but then 1781 // the flushOutbound() gets a write error. If that happens, connection 1782 // being lost, there is no reason to attempt to flush again during the 1783 // teardown when the writeLoop exits. 1784 var skipFlush bool 1785 switch reason { 1786 case ReadError, WriteError, SlowConsumerPendingBytes, SlowConsumerWriteDeadline, TLSHandshakeError: 1787 c.flags.set(skipFlushOnClose) 1788 skipFlush = true 1789 } 1790 if c.flags.isSet(connMarkedClosed) { 1791 return 1792 } 1793 c.flags.set(connMarkedClosed) 1794 // For a websocket client, unless we are told not to flush, enqueue 1795 // a websocket CloseMessage based on the reason. 1796 if !skipFlush && c.isWebsocket() && !c.ws.closeSent { 1797 c.wsEnqueueCloseMessage(reason) 1798 } 1799 // Be consistent with the creation: for routes, gateways and leaf, 1800 // we use Noticef on create, so use that too for delete. 1801 if c.srv != nil { 1802 if c.kind == LEAF { 1803 if c.acc != nil { 1804 c.Noticef("%s connection closed: %s - Account: %s", c.kindString(), reason, c.acc.traceLabel()) 1805 } else { 1806 c.Noticef("%s connection closed: %s", c.kindString(), reason) 1807 } 1808 } else if c.kind == ROUTER || c.kind == GATEWAY { 1809 c.Noticef("%s connection closed: %s", c.kindString(), reason) 1810 } else { // Client, System, Jetstream, and Account connections. 1811 c.Debugf("%s connection closed: %s", c.kindString(), reason) 1812 } 1813 } 1814 1815 // Save off the connection if its a client or leafnode. 1816 if c.kind == CLIENT || c.kind == LEAF { 1817 if nc := c.nc; nc != nil && c.srv != nil { 1818 // TODO: May want to send events to single go routine instead 1819 // of creating a new go routine for each save. 1820 go c.srv.saveClosedClient(c, nc, reason) 1821 } 1822 } 1823 // If writeLoop exists, let it do the final flush, close and teardown. 1824 if c.flags.isSet(writeLoopStarted) { 1825 // Since we want the writeLoop to do the final flush and tcp close, 1826 // we want the reconnect to be done there too. However, it should'nt 1827 // happen before the connection has been removed from the server 1828 // state (end of closeConnection()). This ref count allows us to 1829 // guarantee that. 1830 c.rref++ 1831 c.flushSignal() 1832 return 1833 } 1834 // Flush (if skipFlushOnClose is not set) and close in place. If flushing, 1835 // use a small WriteDeadline. 1836 c.flushAndClose(true) 1837 } 1838 1839 // flushSignal will use server to queue the flush IO operation to a pool of flushers. 1840 // Lock must be held. 1841 func (c *client) flushSignal() { 1842 c.out.sg.Signal() 1843 } 1844 1845 // Traces a message. 1846 // Will NOT check if tracing is enabled, does NOT need the client lock. 1847 func (c *client) traceMsg(msg []byte) { 1848 maxTrace := c.srv.getOpts().MaxTracedMsgLen 1849 if maxTrace > 0 && (len(msg)-LEN_CR_LF) > maxTrace { 1850 tm := fmt.Sprintf("%q", msg[:maxTrace]) 1851 c.Tracef("<<- MSG_PAYLOAD: [\"%s...\"]", tm[1:maxTrace+1]) 1852 } else { 1853 c.Tracef("<<- MSG_PAYLOAD: [%q]", msg[:len(msg)-LEN_CR_LF]) 1854 } 1855 } 1856 1857 // Traces an incoming operation. 1858 // Will NOT check if tracing is enabled, does NOT need the client lock. 1859 func (c *client) traceInOp(op string, arg []byte) { 1860 c.traceOp("<<- %s", op, arg) 1861 } 1862 1863 // Traces an outgoing operation. 1864 // Will NOT check if tracing is enabled, does NOT need the client lock. 1865 func (c *client) traceOutOp(op string, arg []byte) { 1866 c.traceOp("->> %s", op, arg) 1867 } 1868 1869 func (c *client) traceOp(format, op string, arg []byte) { 1870 opa := []interface{}{} 1871 if op != _EMPTY_ { 1872 opa = append(opa, op) 1873 } 1874 if arg != nil { 1875 opa = append(opa, bytesToString(arg)) 1876 } 1877 c.Tracef(format, opa) 1878 } 1879 1880 // Process the information messages from Clients and other Routes. 1881 func (c *client) processInfo(arg []byte) error { 1882 info := Info{} 1883 if err := json.Unmarshal(arg, &info); err != nil { 1884 return err 1885 } 1886 switch c.kind { 1887 case ROUTER: 1888 c.processRouteInfo(&info) 1889 case GATEWAY: 1890 c.processGatewayInfo(&info) 1891 case LEAF: 1892 c.processLeafnodeInfo(&info) 1893 } 1894 return nil 1895 } 1896 1897 func (c *client) processErr(errStr string) { 1898 close := true 1899 switch c.kind { 1900 case CLIENT: 1901 c.Errorf("Client Error %s", errStr) 1902 case ROUTER: 1903 c.Errorf("Route Error %s", errStr) 1904 case GATEWAY: 1905 c.Errorf("Gateway Error %s", errStr) 1906 case LEAF: 1907 c.Errorf("Leafnode Error %s", errStr) 1908 c.leafProcessErr(errStr) 1909 close = false 1910 case JETSTREAM: 1911 c.Errorf("JetStream Error %s", errStr) 1912 } 1913 if close { 1914 c.closeConnection(ParseError) 1915 } 1916 } 1917 1918 // Password pattern matcher. 1919 var passPat = regexp.MustCompile(`"?\s*pass\S*?"?\s*[:=]\s*"?(([^",\r\n}])*)`) 1920 1921 // removePassFromTrace removes any notion of passwords from trace 1922 // messages for logging. 1923 func removePassFromTrace(arg []byte) []byte { 1924 if !bytes.Contains(arg, []byte(`pass`)) { 1925 return arg 1926 } 1927 // Take a copy of the connect proto just for the trace message. 1928 var _arg [4096]byte 1929 buf := append(_arg[:0], arg...) 1930 1931 m := passPat.FindAllSubmatchIndex(buf, -1) 1932 if len(m) == 0 { 1933 return arg 1934 } 1935 1936 redactedPass := []byte("[REDACTED]") 1937 for _, i := range m { 1938 if len(i) < 4 { 1939 continue 1940 } 1941 start := i[2] 1942 end := i[3] 1943 1944 // Replace password substring. 1945 buf = append(buf[:start], append(redactedPass, buf[end:]...)...) 1946 break 1947 } 1948 return buf 1949 } 1950 1951 // Returns the RTT by computing the elapsed time since now and `start`. 1952 // On Windows VM where I (IK) run tests, time.Since() will return 0 1953 // (I suspect some time granularity issues). So return at minimum 1ns. 1954 func computeRTT(start time.Time) time.Duration { 1955 rtt := time.Since(start) 1956 if rtt <= 0 { 1957 rtt = time.Nanosecond 1958 } 1959 return rtt 1960 } 1961 1962 // processConnect will process a client connect op. 1963 func (c *client) processConnect(arg []byte) error { 1964 supportsHeaders := c.srv.supportsHeaders() 1965 c.mu.Lock() 1966 // If we can't stop the timer because the callback is in progress... 1967 if !c.clearAuthTimer() { 1968 // wait for it to finish and handle sending the failure back to 1969 // the client. 1970 for !c.isClosed() { 1971 c.mu.Unlock() 1972 time.Sleep(25 * time.Millisecond) 1973 c.mu.Lock() 1974 } 1975 c.mu.Unlock() 1976 return nil 1977 } 1978 c.last = time.Now().UTC() 1979 // Estimate RTT to start. 1980 if c.kind == CLIENT { 1981 c.rtt = computeRTT(c.start) 1982 if c.srv != nil { 1983 c.clearPingTimer() 1984 c.setFirstPingTimer() 1985 } 1986 } 1987 kind := c.kind 1988 srv := c.srv 1989 1990 // Moved unmarshalling of clients' Options under the lock. 1991 // The client has already been added to the server map, so it is possible 1992 // that other routines lookup the client, and access its options under 1993 // the client's lock, so unmarshalling the options outside of the lock 1994 // would cause data RACEs. 1995 if err := json.Unmarshal(arg, &c.opts); err != nil { 1996 c.mu.Unlock() 1997 return err 1998 } 1999 // Indicate that the CONNECT protocol has been received, and that the 2000 // server now knows which protocol this client supports. 2001 c.flags.set(connectReceived) 2002 // Capture these under lock 2003 c.echo = c.opts.Echo 2004 proto := c.opts.Protocol 2005 verbose := c.opts.Verbose 2006 lang := c.opts.Lang 2007 account := c.opts.Account 2008 accountNew := c.opts.AccountNew 2009 2010 if c.kind == CLIENT { 2011 var ncs string 2012 if c.opts.Version != _EMPTY_ { 2013 ncs = fmt.Sprintf("v%s", c.opts.Version) 2014 } 2015 if c.opts.Lang != _EMPTY_ { 2016 if c.opts.Version == _EMPTY_ { 2017 ncs = c.opts.Lang 2018 } else { 2019 ncs = fmt.Sprintf("%s:%s", ncs, c.opts.Lang) 2020 } 2021 } 2022 if c.opts.Name != _EMPTY_ { 2023 if c.opts.Version == _EMPTY_ && c.opts.Lang == _EMPTY_ { 2024 ncs = c.opts.Name 2025 } else { 2026 ncs = fmt.Sprintf("%s:%s", ncs, c.opts.Name) 2027 } 2028 } 2029 if ncs != _EMPTY_ { 2030 c.ncs.CompareAndSwap(nil, fmt.Sprintf("%s - %q", c, ncs)) 2031 } 2032 } 2033 2034 // if websocket client, maybe some options through cookies 2035 if ws := c.ws; ws != nil { 2036 // if JWT not in the CONNECT, use the cookie JWT (possibly empty). 2037 if c.opts.JWT == _EMPTY_ { 2038 c.opts.JWT = ws.cookieJwt 2039 } 2040 // if user not in the CONNECT, use the cookie user (possibly empty) 2041 if c.opts.Username == _EMPTY_ { 2042 c.opts.Username = ws.cookieUsername 2043 } 2044 // if pass not in the CONNECT, use the cookie password (possibly empty). 2045 if c.opts.Password == _EMPTY_ { 2046 c.opts.Password = ws.cookiePassword 2047 } 2048 // if token not in the CONNECT, use the cookie token (possibly empty). 2049 if c.opts.Token == _EMPTY_ { 2050 c.opts.Token = ws.cookieToken 2051 } 2052 } 2053 2054 // when not in operator mode, discard the jwt 2055 if srv != nil && srv.trustedKeys == nil { 2056 c.opts.JWT = _EMPTY_ 2057 } 2058 ujwt := c.opts.JWT 2059 2060 // For headers both client and server need to support. 2061 c.headers = supportsHeaders && c.opts.Headers 2062 c.mu.Unlock() 2063 2064 if srv != nil { 2065 // Applicable to clients only: 2066 // As soon as c.opts is unmarshalled and if the proto is at 2067 // least ClientProtoInfo, we need to increment the following counter. 2068 // This is decremented when client is removed from the server's 2069 // clients map. 2070 if kind == CLIENT && proto >= ClientProtoInfo { 2071 srv.mu.Lock() 2072 srv.cproto++ 2073 srv.mu.Unlock() 2074 } 2075 2076 // Check for Auth 2077 if ok := srv.checkAuthentication(c); !ok { 2078 // We may fail here because we reached max limits on an account. 2079 if ujwt != _EMPTY_ { 2080 c.mu.Lock() 2081 acc := c.acc 2082 c.mu.Unlock() 2083 srv.mu.Lock() 2084 tooManyAccCons := acc != nil && acc != srv.gacc 2085 srv.mu.Unlock() 2086 if tooManyAccCons { 2087 return ErrTooManyAccountConnections 2088 } 2089 } 2090 c.authViolation() 2091 return ErrAuthentication 2092 } 2093 2094 // Check for Account designation, we used to have this as an optional feature for dynamic 2095 // sandbox environments. Now its considered an error. 2096 if accountNew || account != _EMPTY_ { 2097 c.authViolation() 2098 return ErrAuthentication 2099 } 2100 2101 // If no account designation. 2102 if c.acc == nil { 2103 // By default register with the global account. 2104 c.registerWithAccount(srv.globalAccount()) 2105 } 2106 } 2107 2108 switch kind { 2109 case CLIENT: 2110 // Check client protocol request if it exists. 2111 if proto < ClientProtoZero || proto > ClientProtoInfo { 2112 c.sendErr(ErrBadClientProtocol.Error()) 2113 c.closeConnection(BadClientProtocolVersion) 2114 return ErrBadClientProtocol 2115 } 2116 // Check to see that if no_responders is requested 2117 // they have header support on as well. 2118 c.mu.Lock() 2119 misMatch := c.opts.NoResponders && !c.headers 2120 c.mu.Unlock() 2121 if misMatch { 2122 c.sendErr(ErrNoRespondersRequiresHeaders.Error()) 2123 c.closeConnection(NoRespondersRequiresHeaders) 2124 return ErrNoRespondersRequiresHeaders 2125 } 2126 if verbose { 2127 c.sendOK() 2128 } 2129 case ROUTER: 2130 // Delegate the rest of processing to the route 2131 return c.processRouteConnect(srv, arg, lang) 2132 case GATEWAY: 2133 // Delegate the rest of processing to the gateway 2134 return c.processGatewayConnect(arg) 2135 case LEAF: 2136 // Delegate the rest of processing to the leaf node 2137 return c.processLeafNodeConnect(srv, arg, lang) 2138 } 2139 return nil 2140 } 2141 2142 func (c *client) sendErrAndErr(err string) { 2143 c.sendErr(err) 2144 c.Errorf(err) 2145 } 2146 2147 func (c *client) sendErrAndDebug(err string) { 2148 c.sendErr(err) 2149 c.Debugf(err) 2150 } 2151 2152 func (c *client) authTimeout() { 2153 c.sendErrAndDebug("Authentication Timeout") 2154 c.closeConnection(AuthenticationTimeout) 2155 } 2156 2157 func (c *client) authExpired() { 2158 c.sendErrAndDebug("User Authentication Expired") 2159 c.closeConnection(AuthenticationExpired) 2160 } 2161 2162 func (c *client) accountAuthExpired() { 2163 c.sendErrAndDebug("Account Authentication Expired") 2164 c.closeConnection(AuthenticationExpired) 2165 } 2166 2167 func (c *client) authViolation() { 2168 var s *Server 2169 var hasTrustedNkeys, hasNkeys, hasUsers bool 2170 if s = c.srv; s != nil { 2171 s.mu.RLock() 2172 hasTrustedNkeys = s.trustedKeys != nil 2173 hasNkeys = s.nkeys != nil 2174 hasUsers = s.users != nil 2175 s.mu.RUnlock() 2176 defer s.sendAuthErrorEvent(c) 2177 } 2178 2179 if hasTrustedNkeys { 2180 c.Errorf("%v", ErrAuthentication) 2181 } else if hasNkeys { 2182 c.Errorf("%s - Nkey %q", 2183 ErrAuthentication.Error(), 2184 c.opts.Nkey) 2185 } else if hasUsers { 2186 c.Errorf("%s - User %q", 2187 ErrAuthentication.Error(), 2188 c.opts.Username) 2189 } else { 2190 if c.srv != nil { 2191 c.Errorf(ErrAuthentication.Error()) 2192 } 2193 } 2194 if c.isMqtt() { 2195 c.mqttEnqueueConnAck(mqttConnAckRCNotAuthorized, false) 2196 } else { 2197 c.sendErr("Authorization Violation") 2198 } 2199 c.closeConnection(AuthenticationViolation) 2200 } 2201 2202 func (c *client) maxAccountConnExceeded() { 2203 c.sendErrAndErr(ErrTooManyAccountConnections.Error()) 2204 c.closeConnection(MaxAccountConnectionsExceeded) 2205 } 2206 2207 func (c *client) maxConnExceeded() { 2208 c.sendErrAndErr(ErrTooManyConnections.Error()) 2209 c.closeConnection(MaxConnectionsExceeded) 2210 } 2211 2212 func (c *client) maxSubsExceeded() { 2213 if c.acc.shouldLogMaxSubErr() { 2214 c.Errorf(ErrTooManySubs.Error()) 2215 } 2216 c.sendErr(ErrTooManySubs.Error()) 2217 } 2218 2219 func (c *client) maxPayloadViolation(sz int, max int32) { 2220 c.Errorf("%s: %d vs %d", ErrMaxPayload.Error(), sz, max) 2221 c.sendErr("Maximum Payload Violation") 2222 c.closeConnection(MaxPayloadExceeded) 2223 } 2224 2225 // queueOutbound queues data for a clientconnection. 2226 // Lock should be held. 2227 func (c *client) queueOutbound(data []byte) { 2228 // Do not keep going if closed 2229 if c.isClosed() { 2230 return 2231 } 2232 2233 // Add to pending bytes total. 2234 c.out.pb += int64(len(data)) 2235 2236 // Take a copy of the slice ref so that we can chop bits off the beginning 2237 // without affecting the original "data" slice. 2238 toBuffer := data 2239 2240 // All of the queued []byte have a fixed capacity, so if there's a []byte 2241 // at the tail of the buffer list that isn't full yet, we should top that 2242 // up first. This helps to ensure we aren't pulling more []bytes from the 2243 // pool than we need to. 2244 if len(c.out.nb) > 0 { 2245 last := &c.out.nb[len(c.out.nb)-1] 2246 if free := cap(*last) - len(*last); free > 0 { 2247 if l := len(toBuffer); l < free { 2248 free = l 2249 } 2250 *last = append(*last, toBuffer[:free]...) 2251 toBuffer = toBuffer[free:] 2252 } 2253 } 2254 2255 // Now we can push the rest of the data into new []bytes from the pool 2256 // in fixed size chunks. This ensures we don't go over the capacity of any 2257 // of the buffers and end up reallocating. 2258 for len(toBuffer) > 0 { 2259 new := nbPoolGet(len(toBuffer)) 2260 n := copy(new[:cap(new)], toBuffer) 2261 c.out.nb = append(c.out.nb, new[:n]) 2262 toBuffer = toBuffer[n:] 2263 } 2264 2265 // Check for slow consumer via pending bytes limit. 2266 // ok to return here, client is going away. 2267 if c.kind == CLIENT && c.out.pb > c.out.mp { 2268 // Perf wise, it looks like it is faster to optimistically add than 2269 // checking current pb+len(data) and then add to pb. 2270 c.out.pb -= int64(len(data)) 2271 2272 // Increment the total and client's slow consumer counters. 2273 atomic.AddInt64(&c.srv.slowConsumers, 1) 2274 c.srv.scStats.clients.Add(1) 2275 if c.acc != nil { 2276 atomic.AddInt64(&c.acc.slowConsumers, 1) 2277 } 2278 c.Noticef("Slow Consumer Detected: MaxPending of %d Exceeded", c.out.mp) 2279 c.markConnAsClosed(SlowConsumerPendingBytes) 2280 return 2281 } 2282 2283 // Check here if we should create a stall channel if we are falling behind. 2284 // We do this here since if we wait for consumer's writeLoop it could be 2285 // too late with large number of fan in producers. 2286 if c.out.pb > c.out.mp/2 && c.out.stc == nil { 2287 c.out.stc = make(chan struct{}) 2288 } 2289 } 2290 2291 // Assume the lock is held upon entry. 2292 func (c *client) enqueueProtoAndFlush(proto []byte, doFlush bool) { 2293 if c.isClosed() { 2294 return 2295 } 2296 c.queueOutbound(proto) 2297 if !(doFlush && c.flushOutbound()) { 2298 c.flushSignal() 2299 } 2300 } 2301 2302 // Queues and then flushes the connection. This should only be called when 2303 // the writeLoop cannot be started yet. Use enqueueProto() otherwise. 2304 // Lock is held on entry. 2305 func (c *client) sendProtoNow(proto []byte) { 2306 c.enqueueProtoAndFlush(proto, true) 2307 } 2308 2309 // Enqueues the given protocol and signal the writeLoop if necessary. 2310 // Lock is held on entry. 2311 func (c *client) enqueueProto(proto []byte) { 2312 c.enqueueProtoAndFlush(proto, false) 2313 } 2314 2315 // Assume the lock is held upon entry. 2316 func (c *client) sendPong() { 2317 if c.trace { 2318 c.traceOutOp("PONG", nil) 2319 } 2320 c.enqueueProto([]byte(pongProto)) 2321 } 2322 2323 // Used to kick off a RTT measurement for latency tracking. 2324 func (c *client) sendRTTPing() bool { 2325 c.mu.Lock() 2326 sent := c.sendRTTPingLocked() 2327 c.mu.Unlock() 2328 return sent 2329 } 2330 2331 // Used to kick off a RTT measurement for latency tracking. 2332 // This is normally called only when the caller has checked that 2333 // the c.rtt is 0 and wants to force an update by sending a PING. 2334 // Client lock held on entry. 2335 func (c *client) sendRTTPingLocked() bool { 2336 if c.isMqtt() { 2337 return false 2338 } 2339 // Most client libs send a CONNECT+PING and wait for a PONG from the 2340 // server. So if firstPongSent flag is set, it is ok for server to 2341 // send the PING. But in case we have client libs that don't do that, 2342 // allow the send of the PING if more than 2 secs have elapsed since 2343 // the client TCP connection was accepted. 2344 if !c.isClosed() && 2345 (c.flags.isSet(firstPongSent) || time.Since(c.start) > maxNoRTTPingBeforeFirstPong) { 2346 c.sendPing() 2347 return true 2348 } 2349 return false 2350 } 2351 2352 // Assume the lock is held upon entry. 2353 func (c *client) sendPing() { 2354 c.rttStart = time.Now().UTC() 2355 c.ping.out++ 2356 if c.trace { 2357 c.traceOutOp("PING", nil) 2358 } 2359 c.enqueueProto([]byte(pingProto)) 2360 } 2361 2362 // Generates the INFO to be sent to the client with the client ID included. 2363 // info arg will be copied since passed by value. 2364 // Assume lock is held. 2365 func (c *client) generateClientInfoJSON(info Info) []byte { 2366 info.CID = c.cid 2367 info.ClientIP = c.host 2368 info.MaxPayload = c.mpay 2369 if c.isWebsocket() { 2370 info.ClientConnectURLs = info.WSConnectURLs 2371 if c.srv != nil { // Otherwise lame duck info can panic 2372 c.srv.websocket.mu.RLock() 2373 info.TLSAvailable = c.srv.websocket.tls 2374 if c.srv.websocket.tls && c.srv.websocket.server != nil { 2375 if tc := c.srv.websocket.server.TLSConfig; tc != nil { 2376 info.TLSRequired = !tc.InsecureSkipVerify 2377 } 2378 } 2379 if c.srv.websocket.listener != nil { 2380 laddr := c.srv.websocket.listener.Addr().String() 2381 if h, p, err := net.SplitHostPort(laddr); err == nil { 2382 if p, err := strconv.Atoi(p); err == nil { 2383 info.Host = h 2384 info.Port = p 2385 } 2386 } 2387 } 2388 c.srv.websocket.mu.RUnlock() 2389 } 2390 } 2391 info.WSConnectURLs = nil 2392 return generateInfoJSON(&info) 2393 } 2394 2395 func (c *client) sendErr(err string) { 2396 c.mu.Lock() 2397 if c.trace { 2398 c.traceOutOp("-ERR", []byte(err)) 2399 } 2400 if !c.isMqtt() { 2401 c.enqueueProto([]byte(fmt.Sprintf(errProto, err))) 2402 } 2403 c.mu.Unlock() 2404 } 2405 2406 func (c *client) sendOK() { 2407 c.mu.Lock() 2408 if c.trace { 2409 c.traceOutOp("OK", nil) 2410 } 2411 c.enqueueProto([]byte(okProto)) 2412 c.mu.Unlock() 2413 } 2414 2415 func (c *client) processPing() { 2416 c.mu.Lock() 2417 2418 if c.isClosed() { 2419 c.mu.Unlock() 2420 return 2421 } 2422 2423 c.sendPong() 2424 2425 // Record this to suppress us sending one if this 2426 // is within a given time interval for activity. 2427 c.lastIn = time.Now() 2428 2429 // If not a CLIENT, we are done. Also the CONNECT should 2430 // have been received, but make sure it is so before proceeding 2431 if c.kind != CLIENT || !c.flags.isSet(connectReceived) { 2432 c.mu.Unlock() 2433 return 2434 } 2435 2436 // If we are here, the CONNECT has been received so we know 2437 // if this client supports async INFO or not. 2438 var ( 2439 checkInfoChange bool 2440 srv = c.srv 2441 ) 2442 // For older clients, just flip the firstPongSent flag if not already 2443 // set and we are done. 2444 if c.opts.Protocol < ClientProtoInfo || srv == nil { 2445 c.flags.setIfNotSet(firstPongSent) 2446 } else { 2447 // This is a client that supports async INFO protocols. 2448 // If this is the first PING (so firstPongSent is not set yet), 2449 // we will need to check if there was a change in cluster topology 2450 // or we have a different max payload. We will send this first before 2451 // pong since most clients do flush after connect call. 2452 checkInfoChange = !c.flags.isSet(firstPongSent) 2453 } 2454 c.mu.Unlock() 2455 2456 if checkInfoChange { 2457 opts := srv.getOpts() 2458 srv.mu.Lock() 2459 c.mu.Lock() 2460 // Now that we are under both locks, we can flip the flag. 2461 // This prevents sendAsyncInfoToClients() and code here to 2462 // send a double INFO protocol. 2463 c.flags.set(firstPongSent) 2464 // If there was a cluster update since this client was created, 2465 // send an updated INFO protocol now. 2466 if srv.lastCURLsUpdate >= c.start.UnixNano() || c.mpay != int32(opts.MaxPayload) { 2467 c.enqueueProto(c.generateClientInfoJSON(srv.copyInfo())) 2468 } 2469 c.mu.Unlock() 2470 srv.mu.Unlock() 2471 } 2472 } 2473 2474 func (c *client) processPong() { 2475 c.mu.Lock() 2476 c.ping.out = 0 2477 c.rtt = computeRTT(c.rttStart) 2478 srv := c.srv 2479 reorderGWs := c.kind == GATEWAY && c.gw.outbound 2480 // If compression is currently active for a route/leaf connection, if the 2481 // compression configuration is s2_auto, check if we should change 2482 // the compression level. 2483 if c.kind == ROUTER && needsCompression(c.route.compression) { 2484 c.updateS2AutoCompressionLevel(&srv.getOpts().Cluster.Compression, &c.route.compression) 2485 } else if c.kind == LEAF && needsCompression(c.leaf.compression) { 2486 var co *CompressionOpts 2487 if r := c.leaf.remote; r != nil { 2488 co = &r.Compression 2489 } else { 2490 co = &srv.getOpts().LeafNode.Compression 2491 } 2492 c.updateS2AutoCompressionLevel(co, &c.leaf.compression) 2493 } 2494 c.mu.Unlock() 2495 if reorderGWs { 2496 srv.gateway.orderOutboundConnections() 2497 } 2498 } 2499 2500 // Select the s2 compression level based on the client's current RTT and the configured 2501 // RTT thresholds slice. If current level is different than selected one, save the 2502 // new compression level string and create a new s2 writer. 2503 // Lock held on entry. 2504 func (c *client) updateS2AutoCompressionLevel(co *CompressionOpts, compression *string) { 2505 if co.Mode != CompressionS2Auto { 2506 return 2507 } 2508 if cm := selectS2AutoModeBasedOnRTT(c.rtt, co.RTTThresholds); cm != *compression { 2509 *compression = cm 2510 c.out.cw = s2.NewWriter(nil, s2WriterOptions(cm)...) 2511 } 2512 } 2513 2514 // Will return the parts from the raw wire msg. 2515 func (c *client) msgParts(data []byte) (hdr []byte, msg []byte) { 2516 if c != nil && c.pa.hdr > 0 { 2517 return data[:c.pa.hdr], data[c.pa.hdr:] 2518 } 2519 return nil, data 2520 } 2521 2522 // Header pubs take form HPUB <subject> [reply] <hdr_len> <total_len>\r\n 2523 func (c *client) processHeaderPub(arg, remaining []byte) error { 2524 if !c.headers { 2525 return ErrMsgHeadersNotSupported 2526 } 2527 2528 // Unroll splitArgs to avoid runtime/heap issues 2529 a := [MAX_HPUB_ARGS][]byte{} 2530 args := a[:0] 2531 start := -1 2532 for i, b := range arg { 2533 switch b { 2534 case ' ', '\t': 2535 if start >= 0 { 2536 args = append(args, arg[start:i]) 2537 start = -1 2538 } 2539 default: 2540 if start < 0 { 2541 start = i 2542 } 2543 } 2544 } 2545 if start >= 0 { 2546 args = append(args, arg[start:]) 2547 } 2548 2549 c.pa.arg = arg 2550 switch len(args) { 2551 case 3: 2552 c.pa.subject = args[0] 2553 c.pa.reply = nil 2554 c.pa.hdr = parseSize(args[1]) 2555 c.pa.size = parseSize(args[2]) 2556 c.pa.hdb = args[1] 2557 c.pa.szb = args[2] 2558 case 4: 2559 c.pa.subject = args[0] 2560 c.pa.reply = args[1] 2561 c.pa.hdr = parseSize(args[2]) 2562 c.pa.size = parseSize(args[3]) 2563 c.pa.hdb = args[2] 2564 c.pa.szb = args[3] 2565 default: 2566 return fmt.Errorf("processHeaderPub Parse Error: %q", arg) 2567 } 2568 if c.pa.hdr < 0 { 2569 return fmt.Errorf("processHeaderPub Bad or Missing Header Size: %q", arg) 2570 } 2571 // If number overruns an int64, parseSize() will have returned a negative value 2572 if c.pa.size < 0 { 2573 return fmt.Errorf("processHeaderPub Bad or Missing Total Size: %q", arg) 2574 } 2575 if c.pa.hdr > c.pa.size { 2576 return fmt.Errorf("processHeaderPub Header Size larger then TotalSize: %q", arg) 2577 } 2578 maxPayload := atomic.LoadInt32(&c.mpay) 2579 // Use int64() to avoid int32 overrun... 2580 if maxPayload != jwt.NoLimit && int64(c.pa.size) > int64(maxPayload) { 2581 // If we are given the remaining read buffer (since we do blind reads 2582 // we may have the beginning of the message header/payload), we will 2583 // look for the tracing header and if found, we will generate a 2584 // trace event with the max payload ingress error. 2585 // Do this only for CLIENT connections. 2586 if c.kind == CLIENT && len(remaining) > 0 { 2587 if td := getHeader(MsgTraceDest, remaining); len(td) > 0 { 2588 c.initAndSendIngressErrEvent(remaining, string(td), ErrMaxPayload) 2589 } 2590 } 2591 c.maxPayloadViolation(c.pa.size, maxPayload) 2592 return ErrMaxPayload 2593 } 2594 if c.opts.Pedantic && !IsValidLiteralSubject(bytesToString(c.pa.subject)) { 2595 c.sendErr("Invalid Publish Subject") 2596 } 2597 return nil 2598 } 2599 2600 func (c *client) processPub(arg []byte) error { 2601 // Unroll splitArgs to avoid runtime/heap issues 2602 a := [MAX_PUB_ARGS][]byte{} 2603 args := a[:0] 2604 start := -1 2605 for i, b := range arg { 2606 switch b { 2607 case ' ', '\t': 2608 if start >= 0 { 2609 args = append(args, arg[start:i]) 2610 start = -1 2611 } 2612 default: 2613 if start < 0 { 2614 start = i 2615 } 2616 } 2617 } 2618 if start >= 0 { 2619 args = append(args, arg[start:]) 2620 } 2621 2622 c.pa.arg = arg 2623 switch len(args) { 2624 case 2: 2625 c.pa.subject = args[0] 2626 c.pa.reply = nil 2627 c.pa.size = parseSize(args[1]) 2628 c.pa.szb = args[1] 2629 case 3: 2630 c.pa.subject = args[0] 2631 c.pa.reply = args[1] 2632 c.pa.size = parseSize(args[2]) 2633 c.pa.szb = args[2] 2634 default: 2635 return fmt.Errorf("processPub Parse Error: %q", arg) 2636 } 2637 // If number overruns an int64, parseSize() will have returned a negative value 2638 if c.pa.size < 0 { 2639 return fmt.Errorf("processPub Bad or Missing Size: %q", arg) 2640 } 2641 maxPayload := atomic.LoadInt32(&c.mpay) 2642 // Use int64() to avoid int32 overrun... 2643 if maxPayload != jwt.NoLimit && int64(c.pa.size) > int64(maxPayload) { 2644 c.maxPayloadViolation(c.pa.size, maxPayload) 2645 return ErrMaxPayload 2646 } 2647 if c.opts.Pedantic && !IsValidLiteralSubject(bytesToString(c.pa.subject)) { 2648 c.sendErr("Invalid Publish Subject") 2649 } 2650 return nil 2651 } 2652 2653 func splitArg(arg []byte) [][]byte { 2654 a := [MAX_MSG_ARGS][]byte{} 2655 args := a[:0] 2656 start := -1 2657 for i, b := range arg { 2658 switch b { 2659 case ' ', '\t', '\r', '\n': 2660 if start >= 0 { 2661 args = append(args, arg[start:i]) 2662 start = -1 2663 } 2664 default: 2665 if start < 0 { 2666 start = i 2667 } 2668 } 2669 } 2670 if start >= 0 { 2671 args = append(args, arg[start:]) 2672 } 2673 return args 2674 } 2675 2676 func (c *client) parseSub(argo []byte, noForward bool) error { 2677 // Copy so we do not reference a potentially large buffer 2678 // FIXME(dlc) - make more efficient. 2679 arg := make([]byte, len(argo)) 2680 copy(arg, argo) 2681 args := splitArg(arg) 2682 var ( 2683 subject []byte 2684 queue []byte 2685 sid []byte 2686 ) 2687 switch len(args) { 2688 case 2: 2689 subject = args[0] 2690 queue = nil 2691 sid = args[1] 2692 case 3: 2693 subject = args[0] 2694 queue = args[1] 2695 sid = args[2] 2696 default: 2697 return fmt.Errorf("processSub Parse Error: %q", arg) 2698 } 2699 // If there was an error, it has been sent to the client. We don't return an 2700 // error here to not close the connection as a parsing error. 2701 c.processSub(subject, queue, sid, nil, noForward) 2702 return nil 2703 } 2704 2705 func (c *client) processSub(subject, queue, bsid []byte, cb msgHandler, noForward bool) (*subscription, error) { 2706 return c.processSubEx(subject, queue, bsid, cb, noForward, false, false) 2707 } 2708 2709 func (c *client) processSubEx(subject, queue, bsid []byte, cb msgHandler, noForward, si, rsi bool) (*subscription, error) { 2710 // Create the subscription 2711 sub := &subscription{client: c, subject: subject, queue: queue, sid: bsid, icb: cb, si: si, rsi: rsi} 2712 2713 c.mu.Lock() 2714 2715 // Indicate activity. 2716 c.in.subs++ 2717 2718 // Grab connection type, account and server info. 2719 kind := c.kind 2720 acc := c.acc 2721 srv := c.srv 2722 2723 sid := bytesToString(sub.sid) 2724 2725 // This check does not apply to SYSTEM or JETSTREAM or ACCOUNT clients (because they don't have a `nc`...) 2726 if c.isClosed() && (kind != SYSTEM && kind != JETSTREAM && kind != ACCOUNT) { 2727 c.mu.Unlock() 2728 return nil, ErrConnectionClosed 2729 } 2730 2731 // Check permissions if applicable. 2732 if kind == CLIENT { 2733 // First do a pass whether queue subscription is valid. This does not necessarily 2734 // mean that it will not be able to plain subscribe. 2735 // 2736 // allow = ["foo"] -> can subscribe or queue subscribe to foo using any queue 2737 // allow = ["foo v1"] -> can only queue subscribe to 'foo v1', no plain subs allowed. 2738 // allow = ["foo", "foo v1"] -> can subscribe to 'foo' but can only queue subscribe to 'foo v1' 2739 // 2740 if sub.queue != nil { 2741 if !c.canSubscribe(string(sub.subject), string(sub.queue)) || string(sub.queue) == sysGroup { 2742 c.mu.Unlock() 2743 c.subPermissionViolation(sub) 2744 return nil, ErrSubscribePermissionViolation 2745 } 2746 } else if !c.canSubscribe(string(sub.subject)) { 2747 c.mu.Unlock() 2748 c.subPermissionViolation(sub) 2749 return nil, ErrSubscribePermissionViolation 2750 } 2751 2752 if opts := srv.getOpts(); opts != nil && opts.MaxSubTokens > 0 { 2753 if len(bytes.Split(sub.subject, []byte(tsep))) > int(opts.MaxSubTokens) { 2754 c.mu.Unlock() 2755 c.maxTokensViolation(sub) 2756 return nil, ErrTooManySubTokens 2757 } 2758 } 2759 } 2760 2761 // Check if we have a maximum on the number of subscriptions. 2762 if c.subsAtLimit() { 2763 c.mu.Unlock() 2764 c.maxSubsExceeded() 2765 return nil, ErrTooManySubs 2766 } 2767 2768 var updateGWs bool 2769 var err error 2770 2771 // Subscribe here. 2772 es := c.subs[sid] 2773 if es == nil { 2774 c.subs[sid] = sub 2775 if acc != nil && acc.sl != nil { 2776 err = acc.sl.Insert(sub) 2777 if err != nil { 2778 delete(c.subs, sid) 2779 } else { 2780 updateGWs = c.srv.gateway.enabled 2781 } 2782 } 2783 } 2784 // Unlocked from here onward 2785 c.mu.Unlock() 2786 2787 if err != nil { 2788 c.sendErr("Invalid Subject") 2789 return nil, ErrMalformedSubject 2790 } else if c.opts.Verbose && kind != SYSTEM { 2791 c.sendOK() 2792 } 2793 2794 // If it was already registered, return it. 2795 if es != nil { 2796 return es, nil 2797 } 2798 2799 // No account just return. 2800 if acc == nil { 2801 return sub, nil 2802 } 2803 2804 if err := c.addShadowSubscriptions(acc, sub, true); err != nil { 2805 c.Errorf(err.Error()) 2806 } 2807 2808 if noForward { 2809 return sub, nil 2810 } 2811 2812 // If we are routing and this is a local sub, add to the route map for the associated account. 2813 if kind == CLIENT || kind == SYSTEM || kind == JETSTREAM || kind == ACCOUNT { 2814 srv.updateRouteSubscriptionMap(acc, sub, 1) 2815 if updateGWs { 2816 srv.gatewayUpdateSubInterest(acc.Name, sub, 1) 2817 } 2818 } 2819 // Now check on leafnode updates. 2820 acc.updateLeafNodes(sub, 1) 2821 return sub, nil 2822 } 2823 2824 // Used to pass stream import matches to addShadowSub 2825 type ime struct { 2826 im *streamImport 2827 overlapSubj string 2828 dyn bool 2829 } 2830 2831 // If the client's account has stream imports and there are matches for this 2832 // subscription's subject, then add shadow subscriptions in the other accounts 2833 // that export this subject. 2834 // 2835 // enact=false allows MQTT clients to get the list of shadow subscriptions 2836 // without enacting them, in order to first obtain matching "retained" messages. 2837 func (c *client) addShadowSubscriptions(acc *Account, sub *subscription, enact bool) error { 2838 if acc == nil { 2839 return ErrMissingAccount 2840 } 2841 2842 var ( 2843 _ims [16]ime 2844 ims = _ims[:0] 2845 imTsa [32]string 2846 tokens []string 2847 tsa [32]string 2848 hasWC bool 2849 tokensModified bool 2850 ) 2851 2852 acc.mu.RLock() 2853 // If this is from a service import, ignore. 2854 if sub.si { 2855 acc.mu.RUnlock() 2856 return nil 2857 } 2858 subj := bytesToString(sub.subject) 2859 if len(acc.imports.streams) > 0 { 2860 tokens = tokenizeSubjectIntoSlice(tsa[:0], subj) 2861 for _, tk := range tokens { 2862 if tk == pwcs { 2863 hasWC = true 2864 break 2865 } 2866 } 2867 if !hasWC && tokens[len(tokens)-1] == fwcs { 2868 hasWC = true 2869 } 2870 } 2871 // Loop over the import subjects. We have 4 scenarios. If we have an 2872 // exact match or a superset match we should use the from field from 2873 // the import. If we are a subset or overlap, we have to dynamically calculate 2874 // the subject. On overlap, ime requires the overlap subject. 2875 for _, im := range acc.imports.streams { 2876 if im.invalid { 2877 continue 2878 } 2879 if subj == im.to { 2880 ims = append(ims, ime{im, _EMPTY_, false}) 2881 continue 2882 } 2883 if tokensModified { 2884 // re-tokenize subj to overwrite modifications from a previous iteration 2885 tokens = tokenizeSubjectIntoSlice(tsa[:0], subj) 2886 tokensModified = false 2887 } 2888 imTokens := tokenizeSubjectIntoSlice(imTsa[:0], im.to) 2889 2890 if isSubsetMatchTokenized(tokens, imTokens) { 2891 ims = append(ims, ime{im, _EMPTY_, true}) 2892 } else if hasWC { 2893 if isSubsetMatchTokenized(imTokens, tokens) { 2894 ims = append(ims, ime{im, _EMPTY_, false}) 2895 } else { 2896 imTokensLen := len(imTokens) 2897 for i, t := range tokens { 2898 if i >= imTokensLen { 2899 break 2900 } 2901 if t == pwcs && imTokens[i] != fwcs { 2902 tokens[i] = imTokens[i] 2903 tokensModified = true 2904 } 2905 } 2906 tokensLen := len(tokens) 2907 lastIdx := tokensLen - 1 2908 if tokens[lastIdx] == fwcs { 2909 if imTokensLen >= tokensLen { 2910 // rewrite ">" in tokens to be more specific 2911 tokens[lastIdx] = imTokens[lastIdx] 2912 tokensModified = true 2913 if imTokensLen > tokensLen { 2914 // copy even more specific parts from import 2915 tokens = append(tokens, imTokens[tokensLen:]...) 2916 } 2917 } 2918 } 2919 if isSubsetMatchTokenized(tokens, imTokens) { 2920 // As isSubsetMatchTokenized was already called with tokens and imTokens, 2921 // we wouldn't be here if it where not for tokens being modified. 2922 // Hence, Join to re compute the subject string 2923 ims = append(ims, ime{im, strings.Join(tokens, tsep), true}) 2924 } 2925 } 2926 } 2927 } 2928 acc.mu.RUnlock() 2929 2930 var shadow []*subscription 2931 2932 if len(ims) > 0 { 2933 shadow = make([]*subscription, 0, len(ims)) 2934 } 2935 2936 // Now walk through collected stream imports that matched. 2937 for i := 0; i < len(ims); i++ { 2938 ime := &ims[i] 2939 // We will create a shadow subscription. 2940 nsub, err := c.addShadowSub(sub, ime, enact) 2941 if err != nil { 2942 return err 2943 } 2944 shadow = append(shadow, nsub) 2945 } 2946 2947 if shadow != nil { 2948 c.mu.Lock() 2949 sub.shadow = shadow 2950 c.mu.Unlock() 2951 } 2952 2953 return nil 2954 } 2955 2956 // Add in the shadow subscription. 2957 func (c *client) addShadowSub(sub *subscription, ime *ime, enact bool) (*subscription, error) { 2958 im := ime.im 2959 nsub := *sub // copy 2960 nsub.im = im 2961 2962 if !im.usePub && ime.dyn && im.tr != nil { 2963 if im.rtr == nil { 2964 im.rtr = im.tr.reverse() 2965 } 2966 s := bytesToString(nsub.subject) 2967 if ime.overlapSubj != _EMPTY_ { 2968 s = ime.overlapSubj 2969 } 2970 subj := im.rtr.TransformSubject(s) 2971 2972 nsub.subject = []byte(subj) 2973 } else if !im.usePub || (im.usePub && ime.overlapSubj != _EMPTY_) || !ime.dyn { 2974 if ime.overlapSubj != _EMPTY_ { 2975 nsub.subject = []byte(ime.overlapSubj) 2976 } else { 2977 nsub.subject = []byte(im.from) 2978 } 2979 } 2980 // Else use original subject 2981 2982 if !enact { 2983 return &nsub, nil 2984 } 2985 2986 c.Debugf("Creating import subscription on %q from account %q", nsub.subject, im.acc.Name) 2987 2988 if err := im.acc.sl.Insert(&nsub); err != nil { 2989 errs := fmt.Sprintf("Could not add shadow import subscription for account %q", im.acc.Name) 2990 c.Debugf(errs) 2991 return nil, fmt.Errorf(errs) 2992 } 2993 2994 // Update our route map here. 2995 c.srv.updateRemoteSubscription(im.acc, &nsub, 1) 2996 2997 return &nsub, nil 2998 } 2999 3000 // canSubscribe determines if the client is authorized to subscribe to the 3001 // given subject. Assumes caller is holding lock. 3002 func (c *client) canSubscribe(subject string, optQueue ...string) bool { 3003 if c.perms == nil { 3004 return true 3005 } 3006 3007 allowed := true 3008 3009 // Optional queue group. 3010 var queue string 3011 if len(optQueue) > 0 { 3012 queue = optQueue[0] 3013 } 3014 3015 // Check allow list. If no allow list that means all are allowed. Deny can overrule. 3016 if c.perms.sub.allow != nil { 3017 r := c.perms.sub.allow.Match(subject) 3018 allowed = len(r.psubs) > 0 3019 if queue != _EMPTY_ && len(r.qsubs) > 0 { 3020 // If the queue appears in the allow list, then DO allow. 3021 allowed = queueMatches(queue, r.qsubs) 3022 } 3023 // Leafnodes operate slightly differently in that they allow broader scoped subjects. 3024 // They will prune based on publish perms before sending to a leafnode client. 3025 if !allowed && c.kind == LEAF && subjectHasWildcard(subject) { 3026 r := c.perms.sub.allow.ReverseMatch(subject) 3027 allowed = len(r.psubs) != 0 3028 } 3029 } 3030 // If we have a deny list and we think we are allowed, check that as well. 3031 if allowed && c.perms.sub.deny != nil { 3032 r := c.perms.sub.deny.Match(subject) 3033 allowed = len(r.psubs) == 0 3034 3035 if queue != _EMPTY_ && len(r.qsubs) > 0 { 3036 // If the queue appears in the deny list, then DO NOT allow. 3037 allowed = !queueMatches(queue, r.qsubs) 3038 } 3039 3040 // We use the actual subscription to signal us to spin up the deny mperms 3041 // and cache. We check if the subject is a wildcard that contains any of 3042 // the deny clauses. 3043 // FIXME(dlc) - We could be smarter and track when these go away and remove. 3044 if allowed && c.mperms == nil && subjectHasWildcard(subject) { 3045 // Whip through the deny array and check if this wildcard subject is within scope. 3046 for _, sub := range c.darray { 3047 if subjectIsSubsetMatch(sub, subject) { 3048 c.loadMsgDenyFilter() 3049 break 3050 } 3051 } 3052 } 3053 } 3054 return allowed 3055 } 3056 3057 func queueMatches(queue string, qsubs [][]*subscription) bool { 3058 if len(qsubs) == 0 { 3059 return true 3060 } 3061 for _, qsub := range qsubs { 3062 qs := qsub[0] 3063 qname := bytesToString(qs.queue) 3064 3065 // NOTE: '*' and '>' tokens can also be valid 3066 // queue names so we first check against the 3067 // literal name. e.g. v1.* == v1.* 3068 if queue == qname || (subjectHasWildcard(qname) && subjectIsSubsetMatch(queue, qname)) { 3069 return true 3070 } 3071 } 3072 return false 3073 } 3074 3075 // Low level unsubscribe for a given client. 3076 func (c *client) unsubscribe(acc *Account, sub *subscription, force, remove bool) { 3077 if s := c.srv; s != nil && s.isShuttingDown() { 3078 return 3079 } 3080 3081 c.mu.Lock() 3082 if !force && sub.max > 0 && sub.nm < sub.max { 3083 c.Debugf("Deferring actual UNSUB(%s): %d max, %d received", sub.subject, sub.max, sub.nm) 3084 c.mu.Unlock() 3085 return 3086 } 3087 3088 if c.trace { 3089 c.traceOp("<-> %s", "DELSUB", sub.sid) 3090 } 3091 3092 // Remove accounting if requested. This will be false when we close a connection 3093 // with open subscriptions. 3094 if remove { 3095 delete(c.subs, bytesToString(sub.sid)) 3096 if acc != nil { 3097 acc.sl.Remove(sub) 3098 } 3099 } 3100 3101 // Check to see if we have shadow subscriptions. 3102 var updateRoute bool 3103 var updateGWs bool 3104 shadowSubs := sub.shadow 3105 sub.shadow = nil 3106 if len(shadowSubs) > 0 { 3107 updateRoute = (c.kind == CLIENT || c.kind == SYSTEM || c.kind == LEAF) && c.srv != nil 3108 if updateRoute { 3109 updateGWs = c.srv.gateway.enabled 3110 } 3111 } 3112 sub.close() 3113 c.mu.Unlock() 3114 3115 // Process shadow subs if we have them. 3116 for _, nsub := range shadowSubs { 3117 if err := nsub.im.acc.sl.Remove(nsub); err != nil { 3118 c.Debugf("Could not remove shadow import subscription for account %q", nsub.im.acc.Name) 3119 } else { 3120 if updateRoute { 3121 c.srv.updateRouteSubscriptionMap(nsub.im.acc, nsub, -1) 3122 } 3123 if updateGWs { 3124 c.srv.gatewayUpdateSubInterest(nsub.im.acc.Name, nsub, -1) 3125 } 3126 } 3127 // Now check on leafnode updates. 3128 nsub.im.acc.updateLeafNodes(nsub, -1) 3129 } 3130 3131 // Now check to see if this was part of a respMap entry for service imports. 3132 // We can skip subscriptions on reserved replies. 3133 if acc != nil && !isReservedReply(sub.subject) { 3134 acc.checkForReverseEntry(string(sub.subject), nil, true) 3135 } 3136 } 3137 3138 func (c *client) processUnsub(arg []byte) error { 3139 args := splitArg(arg) 3140 var sid []byte 3141 max := int64(-1) 3142 3143 switch len(args) { 3144 case 1: 3145 sid = args[0] 3146 case 2: 3147 sid = args[0] 3148 max = int64(parseSize(args[1])) 3149 default: 3150 return fmt.Errorf("processUnsub Parse Error: %q", arg) 3151 } 3152 3153 var sub *subscription 3154 var ok, unsub bool 3155 3156 c.mu.Lock() 3157 3158 // Indicate activity. 3159 c.in.subs++ 3160 3161 // Grab connection type. 3162 kind := c.kind 3163 srv := c.srv 3164 var acc *Account 3165 3166 updateGWs := false 3167 if sub, ok = c.subs[string(sid)]; ok { 3168 acc = c.acc 3169 if max > 0 && max > sub.nm { 3170 sub.max = max 3171 } else { 3172 // Clear it here to override 3173 sub.max = 0 3174 unsub = true 3175 } 3176 updateGWs = srv.gateway.enabled 3177 } 3178 c.mu.Unlock() 3179 3180 if c.opts.Verbose { 3181 c.sendOK() 3182 } 3183 3184 if unsub { 3185 c.unsubscribe(acc, sub, false, true) 3186 if acc != nil && (kind == CLIENT || kind == SYSTEM || kind == ACCOUNT || kind == JETSTREAM) { 3187 srv.updateRouteSubscriptionMap(acc, sub, -1) 3188 if updateGWs { 3189 srv.gatewayUpdateSubInterest(acc.Name, sub, -1) 3190 } 3191 } 3192 // Now check on leafnode updates. 3193 acc.updateLeafNodes(sub, -1) 3194 } 3195 3196 return nil 3197 } 3198 3199 // checkDenySub will check if we are allowed to deliver this message in the 3200 // presence of deny clauses for subscriptions. Deny clauses will not prevent 3201 // larger scoped wildcard subscriptions, so we need to check at delivery time. 3202 // Lock should be held. 3203 func (c *client) checkDenySub(subject string) bool { 3204 if denied, ok := c.mperms.dcache[subject]; ok { 3205 return denied 3206 } else if r := c.mperms.deny.Match(subject); len(r.psubs) != 0 { 3207 c.mperms.dcache[subject] = true 3208 return true 3209 } else { 3210 c.mperms.dcache[subject] = false 3211 } 3212 if len(c.mperms.dcache) > maxDenyPermCacheSize { 3213 c.pruneDenyCache() 3214 } 3215 return false 3216 } 3217 3218 // Create a message header for routes or leafnodes. Header and origin cluster aware. 3219 func (c *client) msgHeaderForRouteOrLeaf(subj, reply []byte, rt *routeTarget, acc *Account) []byte { 3220 hasHeader := c.pa.hdr > 0 3221 subclient := rt.sub.client 3222 canReceiveHeader := subclient.headers 3223 3224 mh := c.msgb[:msgHeadProtoLen] 3225 kind := subclient.kind 3226 var lnoc bool 3227 3228 if kind == ROUTER { 3229 // If we are coming from a leaf with an origin cluster we need to handle differently 3230 // if we can. We will send a route based LMSG which has origin cluster and headers 3231 // by default. 3232 if c.kind == LEAF && c.remoteCluster() != _EMPTY_ { 3233 subclient.mu.Lock() 3234 lnoc = subclient.route.lnoc 3235 subclient.mu.Unlock() 3236 } 3237 if lnoc { 3238 mh[0] = 'L' 3239 mh = append(mh, c.remoteCluster()...) 3240 mh = append(mh, ' ') 3241 } else { 3242 // Router (and Gateway) nodes are RMSG. Set here since leafnodes may rewrite. 3243 mh[0] = 'R' 3244 } 3245 if len(subclient.route.accName) == 0 { 3246 mh = append(mh, acc.Name...) 3247 mh = append(mh, ' ') 3248 } 3249 } else { 3250 // Leaf nodes are LMSG 3251 mh[0] = 'L' 3252 // Remap subject if its a shadow subscription, treat like a normal client. 3253 if rt.sub.im != nil { 3254 if rt.sub.im.tr != nil { 3255 to := rt.sub.im.tr.TransformSubject(bytesToString(subj)) 3256 subj = []byte(to) 3257 } else if !rt.sub.im.usePub { 3258 subj = []byte(rt.sub.im.to) 3259 } 3260 } 3261 } 3262 mh = append(mh, subj...) 3263 mh = append(mh, ' ') 3264 3265 if len(rt.qs) > 0 { 3266 if len(reply) > 0 { 3267 mh = append(mh, "+ "...) // Signal that there is a reply. 3268 mh = append(mh, reply...) 3269 mh = append(mh, ' ') 3270 } else { 3271 mh = append(mh, "| "...) // Only queues 3272 } 3273 mh = append(mh, rt.qs...) 3274 } else if len(reply) > 0 { 3275 mh = append(mh, reply...) 3276 mh = append(mh, ' ') 3277 } 3278 3279 if lnoc { 3280 // leafnode origin LMSG always have a header entry even if zero. 3281 if c.pa.hdr <= 0 { 3282 mh = append(mh, '0') 3283 } else { 3284 mh = append(mh, c.pa.hdb...) 3285 } 3286 mh = append(mh, ' ') 3287 mh = append(mh, c.pa.szb...) 3288 } else if hasHeader { 3289 if canReceiveHeader { 3290 mh[0] = 'H' 3291 mh = append(mh, c.pa.hdb...) 3292 mh = append(mh, ' ') 3293 mh = append(mh, c.pa.szb...) 3294 } else { 3295 // If we are here we need to truncate the payload size 3296 nsz := strconv.Itoa(c.pa.size - c.pa.hdr) 3297 mh = append(mh, nsz...) 3298 } 3299 } else { 3300 mh = append(mh, c.pa.szb...) 3301 } 3302 return append(mh, _CRLF_...) 3303 } 3304 3305 // Create a message header for clients. Header aware. 3306 func (c *client) msgHeader(subj, reply []byte, sub *subscription) []byte { 3307 // See if we should do headers. We have to have a headers msg and 3308 // the client we are going to deliver to needs to support headers as well. 3309 hasHeader := c.pa.hdr > 0 3310 canReceiveHeader := sub.client != nil && sub.client.headers 3311 3312 var mh []byte 3313 if hasHeader && canReceiveHeader { 3314 mh = c.msgb[:msgHeadProtoLen] 3315 mh[0] = 'H' 3316 } else { 3317 mh = c.msgb[1:msgHeadProtoLen] 3318 } 3319 mh = append(mh, subj...) 3320 mh = append(mh, ' ') 3321 3322 if len(sub.sid) > 0 { 3323 mh = append(mh, sub.sid...) 3324 mh = append(mh, ' ') 3325 } 3326 if reply != nil { 3327 mh = append(mh, reply...) 3328 mh = append(mh, ' ') 3329 } 3330 if hasHeader { 3331 if canReceiveHeader { 3332 mh = append(mh, c.pa.hdb...) 3333 mh = append(mh, ' ') 3334 mh = append(mh, c.pa.szb...) 3335 } else { 3336 // If we are here we need to truncate the payload size 3337 nsz := strconv.Itoa(c.pa.size - c.pa.hdr) 3338 mh = append(mh, nsz...) 3339 } 3340 } else { 3341 mh = append(mh, c.pa.szb...) 3342 } 3343 mh = append(mh, _CRLF_...) 3344 return mh 3345 } 3346 3347 func (c *client) stalledWait(producer *client) { 3348 stall := c.out.stc 3349 ttl := stallDuration(c.out.pb, c.out.mp) 3350 c.mu.Unlock() 3351 defer c.mu.Lock() 3352 3353 delay := time.NewTimer(ttl) 3354 defer delay.Stop() 3355 3356 select { 3357 case <-stall: 3358 case <-delay.C: 3359 producer.Debugf("Timed out of fast producer stall (%v)", ttl) 3360 } 3361 } 3362 3363 func stallDuration(pb, mp int64) time.Duration { 3364 ttl := stallClientMinDuration 3365 if pb >= mp { 3366 ttl = stallClientMaxDuration 3367 } else if hmp := mp / 2; pb > hmp { 3368 bsz := hmp / 10 3369 additional := int64(ttl) * ((pb - hmp) / bsz) 3370 ttl += time.Duration(additional) 3371 } 3372 return ttl 3373 } 3374 3375 // Used to treat maps as efficient set 3376 var needFlush = struct{}{} 3377 3378 // deliverMsg will deliver a message to a matching subscription and its underlying client. 3379 // We process all connection/client types. mh is the part that will be protocol/client specific. 3380 func (c *client) deliverMsg(prodIsMQTT bool, sub *subscription, acc *Account, subject, reply, mh, msg []byte, gwrply bool) bool { 3381 // Check if message tracing is enabled. 3382 mt, traceOnly := c.isMsgTraceEnabled() 3383 3384 client := sub.client 3385 // Check sub client and check echo. Only do this if not a service import. 3386 if client == nil || (c == client && !client.echo && !sub.si) { 3387 if client != nil && mt != nil { 3388 client.mu.Lock() 3389 mt.addEgressEvent(client, sub, errMsgTraceNoEcho) 3390 client.mu.Unlock() 3391 } 3392 return false 3393 } 3394 3395 client.mu.Lock() 3396 3397 // Check if we have a subscribe deny clause. This will trigger us to check the subject 3398 // for a match against the denied subjects. 3399 if client.mperms != nil && client.checkDenySub(string(subject)) { 3400 mt.addEgressEvent(client, sub, errMsgTraceSubDeny) 3401 client.mu.Unlock() 3402 return false 3403 } 3404 3405 // New race detector forces this now. 3406 if sub.isClosed() { 3407 mt.addEgressEvent(client, sub, errMsgTraceSubClosed) 3408 client.mu.Unlock() 3409 return false 3410 } 3411 3412 // Check if we are a leafnode and have perms to check. 3413 if client.kind == LEAF && client.perms != nil { 3414 if !client.pubAllowedFullCheck(string(subject), true, true) { 3415 mt.addEgressEvent(client, sub, errMsgTracePubViolation) 3416 client.mu.Unlock() 3417 client.Debugf("Not permitted to deliver to %q", subject) 3418 return false 3419 } 3420 } 3421 3422 var mtErr string 3423 if mt != nil { 3424 // For non internal subscription, and if the remote does not support 3425 // the tracing feature... 3426 if sub.icb == nil && !client.msgTraceSupport() { 3427 if traceOnly { 3428 // We are not sending the message at all because the user 3429 // expects a trace-only and the remote does not support 3430 // tracing, which means that it would process/deliver this 3431 // message, which may break applications. 3432 // Add the Egress with the no-support error message. 3433 mt.addEgressEvent(client, sub, errMsgTraceOnlyNoSupport) 3434 client.mu.Unlock() 3435 return false 3436 } 3437 // If we are doing delivery, we will still forward the message, 3438 // but we add an error to the Egress event to hint that one should 3439 // not expect a tracing event from that remote. 3440 mtErr = errMsgTraceNoSupport 3441 } 3442 // For ROUTER, GATEWAY and LEAF, even if we intend to do tracing only, 3443 // we will still deliver the message. The remote side will 3444 // generate an event based on what happened on that server. 3445 if traceOnly && (client.kind == ROUTER || client.kind == GATEWAY || client.kind == LEAF) { 3446 traceOnly = false 3447 } 3448 // If we skip delivery and this is not for a service import, we are done. 3449 if traceOnly && (sub.icb == nil || c.noIcb) { 3450 mt.addEgressEvent(client, sub, _EMPTY_) 3451 client.mu.Unlock() 3452 // Although the message is not actually delivered, for the 3453 // purpose of "didDeliver", we need to return "true" here. 3454 return true 3455 } 3456 } 3457 3458 srv := client.srv 3459 3460 // We don't want to bump the number of delivered messages to the subscription 3461 // if we are doing trace-only (since really we are not sending it to the sub). 3462 if !traceOnly { 3463 sub.nm++ 3464 } 3465 3466 // Check if we should auto-unsubscribe. 3467 if sub.max > 0 { 3468 if client.kind == ROUTER && sub.nm >= sub.max { 3469 // The only router based messages that we will see here are remoteReplies. 3470 // We handle these slightly differently. 3471 defer client.removeReplySub(sub) 3472 } else { 3473 // For routing.. 3474 shouldForward := client.kind == CLIENT || client.kind == SYSTEM && client.srv != nil 3475 // If we are at the exact number, unsubscribe but 3476 // still process the message in hand, otherwise 3477 // unsubscribe and drop message on the floor. 3478 if sub.nm == sub.max { 3479 client.Debugf("Auto-unsubscribe limit of %d reached for sid '%s'", sub.max, sub.sid) 3480 // Due to defer, reverse the code order so that execution 3481 // is consistent with other cases where we unsubscribe. 3482 if shouldForward { 3483 defer srv.updateRemoteSubscription(client.acc, sub, -1) 3484 } 3485 defer client.unsubscribe(client.acc, sub, true, true) 3486 } else if sub.nm > sub.max { 3487 client.Debugf("Auto-unsubscribe limit [%d] exceeded", sub.max) 3488 mt.addEgressEvent(client, sub, errMsgTraceAutoSubExceeded) 3489 client.mu.Unlock() 3490 client.unsubscribe(client.acc, sub, true, true) 3491 if shouldForward { 3492 srv.updateRemoteSubscription(client.acc, sub, -1) 3493 } 3494 return false 3495 } 3496 } 3497 } 3498 3499 // Check here if we have a header with our message. If this client can not 3500 // support we need to strip the headers from the payload. 3501 // The actual header would have been processed correctly for us, so just 3502 // need to update payload. 3503 if c.pa.hdr > 0 && !sub.client.headers { 3504 msg = msg[c.pa.hdr:] 3505 } 3506 3507 // Update statistics 3508 3509 // The msg includes the CR_LF, so pull back out for accounting. 3510 msgSize := int64(len(msg)) 3511 // MQTT producers send messages without CR_LF, so don't remove it for them. 3512 if !prodIsMQTT { 3513 msgSize -= int64(LEN_CR_LF) 3514 } 3515 3516 // We do not update the outbound stats if we are doing trace only since 3517 // this message will not be sent out. 3518 if !traceOnly { 3519 // No atomic needed since accessed under client lock. 3520 // Monitor is reading those also under client's lock. 3521 client.outMsgs++ 3522 client.outBytes += msgSize 3523 } 3524 3525 // Check for internal subscriptions. 3526 if sub.icb != nil && !c.noIcb { 3527 if gwrply { 3528 // We will store in the account, not the client since it will likely 3529 // be a different client that will send the reply. 3530 srv.trackGWReply(nil, client.acc, reply, c.pa.reply) 3531 } 3532 client.mu.Unlock() 3533 3534 // Internal account clients are for service imports and need the '\r\n'. 3535 start := time.Now() 3536 if client.kind == ACCOUNT { 3537 sub.icb(sub, c, acc, string(subject), string(reply), msg) 3538 } else { 3539 sub.icb(sub, c, acc, string(subject), string(reply), msg[:msgSize]) 3540 } 3541 if dur := time.Since(start); dur >= readLoopReportThreshold { 3542 srv.Warnf("Internal subscription on %q took too long: %v", subject, dur) 3543 } 3544 return true 3545 } 3546 3547 // If we are a client and we detect that the consumer we are 3548 // sending to is in a stalled state, go ahead and wait here 3549 // with a limit. 3550 if c.kind == CLIENT && client.out.stc != nil { 3551 client.stalledWait(c) 3552 } 3553 3554 // Check for closed connection 3555 if client.isClosed() { 3556 mt.addEgressEvent(client, sub, errMsgTraceClientClosed) 3557 client.mu.Unlock() 3558 return false 3559 } 3560 3561 // We have passed cases where we could possibly fail to deliver. 3562 // Do not call for service-import. 3563 if mt != nil && sub.icb == nil { 3564 mt.addEgressEvent(client, sub, mtErr) 3565 } 3566 3567 // Do a fast check here to see if we should be tracking this from a latency 3568 // perspective. This will be for a request being received for an exported service. 3569 // This needs to be from a non-client (otherwise tracking happens at requestor). 3570 // 3571 // Also this check captures if the original reply (c.pa.reply) is a GW routed 3572 // reply (since it is known to be > minReplyLen). If that is the case, we need to 3573 // track the binding between the routed reply and the reply set in the message 3574 // header (which is c.pa.reply without the GNR routing prefix). 3575 if client.kind == CLIENT && len(c.pa.reply) > minReplyLen { 3576 if gwrply { 3577 // Note that we keep track of the GW routed reply in the destination 3578 // connection (`client`). The routed reply subject is in `c.pa.reply`, 3579 // should that change, we would have to pass the GW routed reply as 3580 // a parameter of deliverMsg(). 3581 srv.trackGWReply(client, nil, reply, c.pa.reply) 3582 } 3583 3584 // If we do not have a registered RTT queue that up now. 3585 if client.rtt == 0 { 3586 client.sendRTTPingLocked() 3587 } 3588 // FIXME(dlc) - We may need to optimize this. 3589 // We will have tagged this with a suffix ('.T') if we are tracking. This is 3590 // needed from sampling. Not all will be tracked. 3591 if c.kind != CLIENT && isTrackedReply(c.pa.reply) { 3592 client.trackRemoteReply(string(subject), string(c.pa.reply)) 3593 } 3594 } 3595 3596 // Queue to outbound buffer 3597 client.queueOutbound(mh) 3598 client.queueOutbound(msg) 3599 if prodIsMQTT { 3600 // Need to add CR_LF since MQTT producers don't send CR_LF 3601 client.queueOutbound([]byte(CR_LF)) 3602 } 3603 3604 // If we are tracking dynamic publish permissions that track reply subjects, 3605 // do that accounting here. We only look at client.replies which will be non-nil. 3606 if client.replies != nil && len(reply) > 0 { 3607 client.replies[string(reply)] = &resp{time.Now(), 0} 3608 if len(client.replies) > replyPermLimit { 3609 client.pruneReplyPerms() 3610 } 3611 } 3612 3613 // Check outbound threshold and queue IO flush if needed. 3614 // This is specifically looking at situations where we are getting behind and may want 3615 // to intervene before this producer goes back to top of readloop. We are in the producer's 3616 // readloop go routine at this point. 3617 // FIXME(dlc) - We may call this alot, maybe suppress after first call? 3618 if len(client.out.nb) != 0 { 3619 client.flushSignal() 3620 } 3621 3622 // Add the data size we are responsible for here. This will be processed when we 3623 // return to the top of the readLoop. 3624 c.addToPCD(client) 3625 3626 if client.trace { 3627 client.traceOutOp(bytesToString(mh[:len(mh)-LEN_CR_LF]), nil) 3628 } 3629 3630 client.mu.Unlock() 3631 3632 return true 3633 } 3634 3635 // Add the given sub's client to the list of clients that need flushing. 3636 // This must be invoked from `c`'s readLoop. No lock for c is required, 3637 // however, `client` lock must be held on entry. This holds true even 3638 // if `client` is same than `c`. 3639 func (c *client) addToPCD(client *client) { 3640 if _, ok := c.pcd[client]; !ok { 3641 client.out.fsp++ 3642 c.pcd[client] = needFlush 3643 } 3644 } 3645 3646 // This will track a remote reply for an exported service that has requested 3647 // latency tracking. 3648 // Lock assumed to be held. 3649 func (c *client) trackRemoteReply(subject, reply string) { 3650 a := c.acc 3651 if a == nil { 3652 return 3653 } 3654 3655 var lrt time.Duration 3656 var respThresh time.Duration 3657 3658 a.mu.RLock() 3659 se := a.getServiceExport(subject) 3660 if se != nil { 3661 lrt = a.lowestServiceExportResponseTime() 3662 respThresh = se.respThresh 3663 } 3664 a.mu.RUnlock() 3665 3666 if se == nil { 3667 return 3668 } 3669 3670 if c.rrTracking == nil { 3671 c.rrTracking = &rrTracking{ 3672 rmap: make(map[string]*remoteLatency), 3673 ptmr: time.AfterFunc(lrt, c.pruneRemoteTracking), 3674 lrt: lrt, 3675 } 3676 } 3677 rl := remoteLatency{ 3678 Account: a.Name, 3679 ReqId: reply, 3680 respThresh: respThresh, 3681 } 3682 rl.M2.RequestStart = time.Now().UTC() 3683 c.rrTracking.rmap[reply] = &rl 3684 } 3685 3686 // pruneRemoteTracking will prune any remote tracking objects 3687 // that are too old. These are orphaned when a service is not 3688 // sending reponses etc. 3689 // Lock should be held upon entry. 3690 func (c *client) pruneRemoteTracking() { 3691 c.mu.Lock() 3692 if c.rrTracking == nil { 3693 c.mu.Unlock() 3694 return 3695 } 3696 now := time.Now() 3697 for subject, rl := range c.rrTracking.rmap { 3698 if now.After(rl.M2.RequestStart.Add(rl.respThresh)) { 3699 delete(c.rrTracking.rmap, subject) 3700 } 3701 } 3702 if len(c.rrTracking.rmap) > 0 { 3703 t := c.rrTracking.ptmr 3704 t.Stop() 3705 t.Reset(c.rrTracking.lrt) 3706 } else { 3707 c.rrTracking.ptmr.Stop() 3708 c.rrTracking = nil 3709 } 3710 c.mu.Unlock() 3711 } 3712 3713 // pruneReplyPerms will remove any stale or expired entries 3714 // in our reply cache. We make sure to not check too often. 3715 func (c *client) pruneReplyPerms() { 3716 // Make sure we do not check too often. 3717 if c.perms.resp == nil { 3718 return 3719 } 3720 3721 mm := c.perms.resp.MaxMsgs 3722 ttl := c.perms.resp.Expires 3723 now := time.Now() 3724 3725 for k, resp := range c.replies { 3726 if mm > 0 && resp.n >= mm { 3727 delete(c.replies, k) 3728 } else if ttl > 0 && now.Sub(resp.t) > ttl { 3729 delete(c.replies, k) 3730 } 3731 } 3732 } 3733 3734 // pruneDenyCache will prune the deny cache via randomly 3735 // deleting items. Doing so pruneSize items at a time. 3736 // Lock must be held for this one since it is shared under 3737 // deliverMsg. 3738 func (c *client) pruneDenyCache() { 3739 r := 0 3740 for subject := range c.mperms.dcache { 3741 delete(c.mperms.dcache, subject) 3742 if r++; r > pruneSize { 3743 break 3744 } 3745 } 3746 } 3747 3748 // prunePubPermsCache will prune the cache via randomly 3749 // deleting items. Doing so pruneSize items at a time. 3750 func (c *client) prunePubPermsCache() { 3751 // There is a case where we can invoke this from multiple go routines, 3752 // (in deliverMsg() if sub.client is a LEAF), so we make sure to prune 3753 // from only one go routine at a time. 3754 if !atomic.CompareAndSwapInt32(&c.perms.prun, 0, 1) { 3755 return 3756 } 3757 const maxPruneAtOnce = 1000 3758 r := 0 3759 c.perms.pcache.Range(func(k, _ interface{}) bool { 3760 c.perms.pcache.Delete(k) 3761 if r++; (r > pruneSize && atomic.LoadInt32(&c.perms.pcsz) < int32(maxPermCacheSize)) || 3762 (r > maxPruneAtOnce) { 3763 return false 3764 } 3765 return true 3766 }) 3767 atomic.AddInt32(&c.perms.pcsz, -int32(r)) 3768 atomic.StoreInt32(&c.perms.prun, 0) 3769 } 3770 3771 // pubAllowed checks on publish permissioning. 3772 // Lock should not be held. 3773 func (c *client) pubAllowed(subject string) bool { 3774 return c.pubAllowedFullCheck(subject, true, false) 3775 } 3776 3777 // pubAllowedFullCheck checks on all publish permissioning depending 3778 // on the flag for dynamic reply permissions. 3779 func (c *client) pubAllowedFullCheck(subject string, fullCheck, hasLock bool) bool { 3780 if c.perms == nil || (c.perms.pub.allow == nil && c.perms.pub.deny == nil) { 3781 return true 3782 } 3783 // Check if published subject is allowed if we have permissions in place. 3784 v, ok := c.perms.pcache.Load(subject) 3785 if ok { 3786 return v.(bool) 3787 } 3788 allowed := true 3789 // Cache miss, check allow then deny as needed. 3790 if c.perms.pub.allow != nil { 3791 r := c.perms.pub.allow.Match(subject) 3792 allowed = len(r.psubs) != 0 3793 } 3794 // If we have a deny list and are currently allowed, check that as well. 3795 if allowed && c.perms.pub.deny != nil { 3796 r := c.perms.pub.deny.Match(subject) 3797 allowed = len(r.psubs) == 0 3798 } 3799 3800 // If we are currently not allowed but we are tracking reply subjects 3801 // dynamically, check to see if we are allowed here but avoid pcache. 3802 // We need to acquire the lock though. 3803 if !allowed && fullCheck && c.perms.resp != nil { 3804 if !hasLock { 3805 c.mu.Lock() 3806 } 3807 if resp := c.replies[subject]; resp != nil { 3808 resp.n++ 3809 // Check if we have sent too many responses. 3810 if c.perms.resp.MaxMsgs > 0 && resp.n > c.perms.resp.MaxMsgs { 3811 delete(c.replies, subject) 3812 } else if c.perms.resp.Expires > 0 && time.Since(resp.t) > c.perms.resp.Expires { 3813 delete(c.replies, subject) 3814 } else { 3815 allowed = true 3816 } 3817 } 3818 if !hasLock { 3819 c.mu.Unlock() 3820 } 3821 } else { 3822 // Update our cache here. 3823 c.perms.pcache.Store(subject, allowed) 3824 if n := atomic.AddInt32(&c.perms.pcsz, 1); n > maxPermCacheSize { 3825 c.prunePubPermsCache() 3826 } 3827 } 3828 return allowed 3829 } 3830 3831 // Test whether a reply subject is a service import reply. 3832 func isServiceReply(reply []byte) bool { 3833 // This function is inlined and checking this way is actually faster 3834 // than byte-by-byte comparison. 3835 return len(reply) > 3 && bytesToString(reply[:4]) == replyPrefix 3836 } 3837 3838 // Test whether a reply subject is a service import or a gateway routed reply. 3839 func isReservedReply(reply []byte) bool { 3840 if isServiceReply(reply) { 3841 return true 3842 } 3843 rLen := len(reply) 3844 // Faster to check with string([:]) than byte-by-byte 3845 if rLen > jsAckPreLen && bytesToString(reply[:jsAckPreLen]) == jsAckPre { 3846 return true 3847 } else if rLen > gwReplyPrefixLen && bytesToString(reply[:gwReplyPrefixLen]) == gwReplyPrefix { 3848 return true 3849 } 3850 return false 3851 } 3852 3853 // This will decide to call the client code or router code. 3854 func (c *client) processInboundMsg(msg []byte) { 3855 switch c.kind { 3856 case CLIENT: 3857 c.processInboundClientMsg(msg) 3858 case ROUTER: 3859 c.processInboundRoutedMsg(msg) 3860 case GATEWAY: 3861 c.processInboundGatewayMsg(msg) 3862 case LEAF: 3863 c.processInboundLeafMsg(msg) 3864 } 3865 } 3866 3867 // selectMappedSubject will choose the mapped subject based on the client's inbound subject. 3868 func (c *client) selectMappedSubject() bool { 3869 nsubj, changed := c.acc.selectMappedSubject(bytesToString(c.pa.subject)) 3870 if changed { 3871 c.pa.mapped = c.pa.subject 3872 c.pa.subject = []byte(nsubj) 3873 } 3874 return changed 3875 } 3876 3877 // processInboundClientMsg is called to process an inbound msg from a client. 3878 // Return if the message was delivered, and if the message was not delivered 3879 // due to a permission issue. 3880 func (c *client) processInboundClientMsg(msg []byte) (bool, bool) { 3881 // Update statistics 3882 // The msg includes the CR_LF, so pull back out for accounting. 3883 c.in.msgs++ 3884 c.in.bytes += int32(len(msg) - LEN_CR_LF) 3885 3886 // Check that client (could be here with SYSTEM) is not publishing on reserved "$GNR" prefix. 3887 if c.kind == CLIENT && hasGWRoutedReplyPrefix(c.pa.subject) { 3888 c.pubPermissionViolation(c.pa.subject) 3889 return false, true 3890 } 3891 3892 // Mostly under testing scenarios. 3893 c.mu.Lock() 3894 if c.srv == nil || c.acc == nil { 3895 c.mu.Unlock() 3896 return false, false 3897 } 3898 acc := c.acc 3899 genidAddr := &acc.sl.genid 3900 3901 // Check pub permissions 3902 if c.perms != nil && (c.perms.pub.allow != nil || c.perms.pub.deny != nil) && !c.pubAllowedFullCheck(string(c.pa.subject), true, true) { 3903 c.mu.Unlock() 3904 c.pubPermissionViolation(c.pa.subject) 3905 return false, true 3906 } 3907 c.mu.Unlock() 3908 3909 // Now check for reserved replies. These are used for service imports. 3910 if c.kind == CLIENT && len(c.pa.reply) > 0 && isReservedReply(c.pa.reply) { 3911 c.replySubjectViolation(c.pa.reply) 3912 return false, true 3913 } 3914 3915 if c.opts.Verbose { 3916 c.sendOK() 3917 } 3918 3919 // If MQTT client, check for retain flag now that we have passed permissions check 3920 if c.isMqtt() { 3921 c.mqttHandlePubRetain() 3922 } 3923 3924 // Doing this inline as opposed to create a function (which otherwise has a measured 3925 // performance impact reported in our bench) 3926 var isGWRouted bool 3927 if c.kind != CLIENT { 3928 if atomic.LoadInt32(&acc.gwReplyMapping.check) > 0 { 3929 acc.mu.RLock() 3930 c.pa.subject, isGWRouted = acc.gwReplyMapping.get(c.pa.subject) 3931 acc.mu.RUnlock() 3932 } 3933 } else if atomic.LoadInt32(&c.gwReplyMapping.check) > 0 { 3934 c.mu.Lock() 3935 c.pa.subject, isGWRouted = c.gwReplyMapping.get(c.pa.subject) 3936 c.mu.Unlock() 3937 } 3938 3939 // If we have an exported service and we are doing remote tracking, check this subject 3940 // to see if we need to report the latency. 3941 if c.rrTracking != nil { 3942 c.mu.Lock() 3943 rl := c.rrTracking.rmap[string(c.pa.subject)] 3944 if rl != nil { 3945 delete(c.rrTracking.rmap, bytesToString(c.pa.subject)) 3946 } 3947 c.mu.Unlock() 3948 3949 if rl != nil { 3950 sl := &rl.M2 3951 // Fill this in and send it off to the other side. 3952 sl.Status = 200 3953 sl.Responder = c.getClientInfo(true) 3954 sl.ServiceLatency = time.Since(sl.RequestStart) - sl.Responder.RTT 3955 sl.TotalLatency = sl.ServiceLatency + sl.Responder.RTT 3956 sanitizeLatencyMetric(sl) 3957 lsub := remoteLatencySubjectForResponse(c.pa.subject) 3958 c.srv.sendInternalAccountMsg(nil, lsub, rl) // Send to SYS account 3959 } 3960 } 3961 3962 // If the subject was converted to the gateway routed subject, then handle it now 3963 // and be done with the rest of this function. 3964 if isGWRouted { 3965 c.handleGWReplyMap(msg) 3966 return true, false 3967 } 3968 3969 // Match the subscriptions. We will use our own L1 map if 3970 // it's still valid, avoiding contention on the shared sublist. 3971 var r *SublistResult 3972 var ok bool 3973 3974 genid := atomic.LoadUint64(genidAddr) 3975 if genid == c.in.genid && c.in.results != nil { 3976 r, ok = c.in.results[string(c.pa.subject)] 3977 } else { 3978 // Reset our L1 completely. 3979 c.in.results = make(map[string]*SublistResult) 3980 c.in.genid = genid 3981 } 3982 3983 // Go back to the sublist data structure. 3984 if !ok { 3985 // Match may use the subject here to populate a cache, so can not use bytesToString here. 3986 r = acc.sl.Match(string(c.pa.subject)) 3987 if len(r.psubs)+len(r.qsubs) > 0 { 3988 c.in.results[string(c.pa.subject)] = r 3989 // Prune the results cache. Keeps us from unbounded growth. Random delete. 3990 if len(c.in.results) > maxResultCacheSize { 3991 n := 0 3992 for subject := range c.in.results { 3993 delete(c.in.results, subject) 3994 if n++; n > pruneSize { 3995 break 3996 } 3997 } 3998 } 3999 } 4000 } 4001 4002 // Indication if we attempted to deliver the message to anyone. 4003 var didDeliver bool 4004 var qnames [][]byte 4005 4006 // Check for no interest, short circuit if so. 4007 // This is the fanout scale. 4008 if len(r.psubs)+len(r.qsubs) > 0 { 4009 flag := pmrNoFlag 4010 // If there are matching queue subs and we are in gateway mode, 4011 // we need to keep track of the queue names the messages are 4012 // delivered to. When sending to the GWs, the RMSG will include 4013 // those names so that the remote clusters do not deliver messages 4014 // to their queue subs of the same names. 4015 if len(r.qsubs) > 0 && c.srv.gateway.enabled && 4016 atomic.LoadInt64(&c.srv.gateway.totalQSubs) > 0 { 4017 flag |= pmrCollectQueueNames 4018 } 4019 didDeliver, qnames = c.processMsgResults(acc, r, msg, c.pa.deliver, c.pa.subject, c.pa.reply, flag) 4020 } 4021 4022 // Now deal with gateways 4023 if c.srv.gateway.enabled { 4024 reply := c.pa.reply 4025 if len(c.pa.deliver) > 0 && c.kind == JETSTREAM && len(c.pa.reply) > 0 { 4026 reply = append(reply, '@') 4027 reply = append(reply, c.pa.deliver...) 4028 } 4029 didDeliver = c.sendMsgToGateways(acc, msg, c.pa.subject, reply, qnames) || didDeliver 4030 } 4031 4032 // Check to see if we did not deliver to anyone and the client has a reply subject set 4033 // and wants notification of no_responders. 4034 if !didDeliver && len(c.pa.reply) > 0 { 4035 c.mu.Lock() 4036 if c.opts.NoResponders { 4037 if sub := c.subForReply(c.pa.reply); sub != nil { 4038 proto := fmt.Sprintf("HMSG %s %s 16 16\r\nNATS/1.0 503\r\n\r\n\r\n", c.pa.reply, sub.sid) 4039 c.queueOutbound([]byte(proto)) 4040 c.addToPCD(c) 4041 } 4042 } 4043 c.mu.Unlock() 4044 } 4045 4046 return didDeliver, false 4047 } 4048 4049 // Return the subscription for this reply subject. Only look at normal subs for this client. 4050 func (c *client) subForReply(reply []byte) *subscription { 4051 r := c.acc.sl.Match(string(reply)) 4052 for _, sub := range r.psubs { 4053 if sub.client == c { 4054 return sub 4055 } 4056 } 4057 return nil 4058 } 4059 4060 // This is invoked knowing that c.pa.subject has been set to the gateway routed subject. 4061 // This function will send the message to possibly LEAFs and directly back to the origin 4062 // gateway. 4063 func (c *client) handleGWReplyMap(msg []byte) bool { 4064 // Check for leaf nodes 4065 if c.srv.gwLeafSubs.Count() > 0 { 4066 if r := c.srv.gwLeafSubs.Match(string(c.pa.subject)); len(r.psubs) > 0 { 4067 c.processMsgResults(c.acc, r, msg, c.pa.deliver, c.pa.subject, c.pa.reply, pmrNoFlag) 4068 } 4069 } 4070 if c.srv.gateway.enabled { 4071 reply := c.pa.reply 4072 if len(c.pa.deliver) > 0 && c.kind == JETSTREAM && len(c.pa.reply) > 0 { 4073 reply = append(reply, '@') 4074 reply = append(reply, c.pa.deliver...) 4075 } 4076 c.sendMsgToGateways(c.acc, msg, c.pa.subject, reply, nil) 4077 } 4078 return true 4079 } 4080 4081 // Used to setup the response map for a service import request that has a reply subject. 4082 func (c *client) setupResponseServiceImport(acc *Account, si *serviceImport, tracking bool, header http.Header) *serviceImport { 4083 rsi := si.acc.addRespServiceImport(acc, string(c.pa.reply), si, tracking, header) 4084 if si.latency != nil { 4085 if c.rtt == 0 { 4086 // We have a service import that we are tracking but have not established RTT. 4087 c.sendRTTPing() 4088 } 4089 si.acc.mu.Lock() 4090 rsi.rc = c 4091 si.acc.mu.Unlock() 4092 } 4093 return rsi 4094 } 4095 4096 // Will remove a header if present. 4097 func removeHeaderIfPresent(hdr []byte, key string) []byte { 4098 start := bytes.Index(hdr, []byte(key)) 4099 // key can't be first and we want to check that it is preceded by a '\n' 4100 if start < 1 || hdr[start-1] != '\n' { 4101 return hdr 4102 } 4103 index := start + len(key) 4104 if index >= len(hdr) || hdr[index] != ':' { 4105 return hdr 4106 } 4107 end := bytes.Index(hdr[start:], []byte(_CRLF_)) 4108 if end < 0 { 4109 return hdr 4110 } 4111 hdr = append(hdr[:start], hdr[start+end+len(_CRLF_):]...) 4112 if len(hdr) <= len(emptyHdrLine) { 4113 return nil 4114 } 4115 return hdr 4116 } 4117 4118 // Generate a new header based on optional original header and key value. 4119 // More used in JetStream layers. 4120 func genHeader(hdr []byte, key, value string) []byte { 4121 var bb bytes.Buffer 4122 if len(hdr) > LEN_CR_LF { 4123 bb.Write(hdr[:len(hdr)-LEN_CR_LF]) 4124 } else { 4125 bb.WriteString(hdrLine) 4126 } 4127 http.Header{key: []string{value}}.Write(&bb) 4128 bb.WriteString(CR_LF) 4129 return bb.Bytes() 4130 } 4131 4132 // This will set a header for the message. 4133 // Lock does not need to be held but this should only be called 4134 // from the inbound go routine. We will update the pubArgs. 4135 // This will replace any previously set header and not add to it per normal spec. 4136 func (c *client) setHeader(key, value string, msg []byte) []byte { 4137 var bb bytes.Buffer 4138 var omi int 4139 // Write original header if present. 4140 if c.pa.hdr > LEN_CR_LF { 4141 omi = c.pa.hdr 4142 hdr := removeHeaderIfPresent(msg[:c.pa.hdr-LEN_CR_LF], key) 4143 if len(hdr) == 0 { 4144 bb.WriteString(hdrLine) 4145 } else { 4146 bb.Write(hdr) 4147 } 4148 } else { 4149 bb.WriteString(hdrLine) 4150 } 4151 http.Header{key: []string{value}}.Write(&bb) 4152 bb.WriteString(CR_LF) 4153 nhdr := bb.Len() 4154 // Put the original message back. 4155 // FIXME(dlc) - This is inefficient. 4156 bb.Write(msg[omi:]) 4157 nsize := bb.Len() - LEN_CR_LF 4158 // MQTT producers don't have CRLF, so add it back. 4159 if c.isMqtt() { 4160 nsize += LEN_CR_LF 4161 } 4162 // Update pubArgs 4163 // If others will use this later we need to save and restore original. 4164 c.pa.hdr = nhdr 4165 c.pa.size = nsize 4166 c.pa.hdb = []byte(strconv.Itoa(nhdr)) 4167 c.pa.szb = []byte(strconv.Itoa(nsize)) 4168 return bb.Bytes() 4169 } 4170 4171 // Will return the value for the header denoted by key or nil if it does not exists. 4172 // This function ignores errors and tries to achieve speed and no additional allocations. 4173 func getHeader(key string, hdr []byte) []byte { 4174 if len(hdr) == 0 { 4175 return nil 4176 } 4177 index := bytes.Index(hdr, []byte(key)) 4178 hdrLen := len(hdr) 4179 // Check that we have enough characters, this will handle the -1 case of the key not 4180 // being found and will also handle not having enough characters for trailing CRLF. 4181 if index < 2 { 4182 return nil 4183 } 4184 // There should be a terminating CRLF. 4185 if index >= hdrLen-1 || hdr[index-1] != '\n' || hdr[index-2] != '\r' { 4186 return nil 4187 } 4188 // The key should be immediately followed by a : separator. 4189 index += len(key) + 1 4190 if index >= hdrLen || hdr[index-1] != ':' { 4191 return nil 4192 } 4193 // Skip over whitespace before the value. 4194 for index < hdrLen && hdr[index] == ' ' { 4195 index++ 4196 } 4197 // Collect together the rest of the value until we hit a CRLF. 4198 var value []byte 4199 for index < hdrLen { 4200 if hdr[index] == '\r' && index < hdrLen-1 && hdr[index+1] == '\n' { 4201 break 4202 } 4203 value = append(value, hdr[index]) 4204 index++ 4205 } 4206 return value 4207 } 4208 4209 // For bytes.HasPrefix below. 4210 var ( 4211 jsRequestNextPreB = []byte(jsRequestNextPre) 4212 jsDirectGetPreB = []byte(jsDirectGetPre) 4213 ) 4214 4215 // processServiceImport is an internal callback when a subscription matches an imported service 4216 // from another account. This includes response mappings as well. 4217 func (c *client) processServiceImport(si *serviceImport, acc *Account, msg []byte) { 4218 // If we are a GW and this is not a direct serviceImport ignore. 4219 isResponse := si.isRespServiceImport() 4220 if (c.kind == GATEWAY || c.kind == ROUTER) && !isResponse { 4221 return 4222 } 4223 // Detect cycles and ignore (return) when we detect one. 4224 if len(c.pa.psi) > 0 { 4225 for i := len(c.pa.psi) - 1; i >= 0; i-- { 4226 if psi := c.pa.psi[i]; psi.se == si.se { 4227 return 4228 } 4229 } 4230 } 4231 4232 acc.mu.RLock() 4233 var checkJS bool 4234 shouldReturn := si.invalid || acc.sl == nil 4235 if !shouldReturn && !isResponse && si.to == jsAllAPI { 4236 if bytes.HasPrefix(c.pa.subject, jsDirectGetPreB) || bytes.HasPrefix(c.pa.subject, jsRequestNextPreB) { 4237 checkJS = true 4238 } 4239 } 4240 siAcc := si.acc 4241 allowTrace := si.atrc 4242 acc.mu.RUnlock() 4243 4244 // We have a special case where JetStream pulls in all service imports through one export. 4245 // However the GetNext for consumers and DirectGet for streams are a no-op and causes buildups of service imports, 4246 // response service imports and rrMap entries which all will need to simply expire. 4247 // TODO(dlc) - Come up with something better. 4248 if shouldReturn || (checkJS && si.se != nil && si.se.acc == c.srv.SystemAccount()) { 4249 return 4250 } 4251 4252 mt, traceOnly := c.isMsgTraceEnabled() 4253 4254 var nrr []byte 4255 var rsi *serviceImport 4256 4257 // Check if there is a reply present and set up a response. 4258 tracking, headers := shouldSample(si.latency, c) 4259 if len(c.pa.reply) > 0 { 4260 // Special case for now, need to formalize. 4261 // TODO(dlc) - Formalize as a service import option for reply rewrite. 4262 // For now we can't do $JS.ACK since that breaks pull consumers across accounts. 4263 if !bytes.HasPrefix(c.pa.reply, []byte(jsAckPre)) { 4264 if rsi = c.setupResponseServiceImport(acc, si, tracking, headers); rsi != nil { 4265 nrr = []byte(rsi.from) 4266 } 4267 } else { 4268 // This only happens when we do a pull subscriber that trampolines through another account. 4269 // Normally this code is not called. 4270 nrr = c.pa.reply 4271 } 4272 } else if !isResponse && si.latency != nil && tracking { 4273 // Check to see if this was a bad request with no reply and we were supposed to be tracking. 4274 siAcc.sendBadRequestTrackingLatency(si, c, headers) 4275 } 4276 4277 // Send tracking info here if we are tracking this response. 4278 // This is always a response. 4279 var didSendTL bool 4280 if si.tracking && !si.didDeliver { 4281 // Stamp that we attempted delivery. 4282 si.didDeliver = true 4283 didSendTL = acc.sendTrackingLatency(si, c) 4284 } 4285 4286 // Pick correct "to" subject. If we matched on a wildcard use the literal publish subject. 4287 to, subject := si.to, string(c.pa.subject) 4288 4289 if si.tr != nil { 4290 // FIXME(dlc) - This could be slow, may want to look at adding cache to bare transforms? 4291 to = si.tr.TransformSubject(subject) 4292 } else if si.usePub { 4293 to = subject 4294 } 4295 4296 // Copy our pubArg since this gets modified as we process the service import itself. 4297 pacopy := c.pa 4298 4299 // Now check to see if this account has mappings that could affect the service import. 4300 // Can't use non-locked trick like in processInboundClientMsg, so just call into selectMappedSubject 4301 // so we only lock once. 4302 nsubj, changed := siAcc.selectMappedSubject(to) 4303 if changed { 4304 c.pa.mapped = []byte(to) 4305 to = nsubj 4306 } 4307 4308 // Set previous service import to detect chaining. 4309 lpsi := len(c.pa.psi) 4310 hadPrevSi, share := lpsi > 0, si.share 4311 if hadPrevSi { 4312 share = c.pa.psi[lpsi-1].share 4313 } 4314 c.pa.psi = append(c.pa.psi, si) 4315 4316 // Place our client info for the request in the original message. 4317 // This will survive going across routes, etc. 4318 if !isResponse { 4319 isSysImport := siAcc == c.srv.SystemAccount() 4320 var ci *ClientInfo 4321 if hadPrevSi && c.pa.hdr >= 0 { 4322 var cis ClientInfo 4323 if err := json.Unmarshal(getHeader(ClientInfoHdr, msg[:c.pa.hdr]), &cis); err == nil { 4324 ci = &cis 4325 ci.Service = acc.Name 4326 // Check if we are moving into a share details account from a non-shared 4327 // and add in server and cluster details. 4328 if !share && (si.share || isSysImport) { 4329 c.addServerAndClusterInfo(ci) 4330 } 4331 } 4332 } else if c.kind != LEAF || c.pa.hdr < 0 || len(getHeader(ClientInfoHdr, msg[:c.pa.hdr])) == 0 { 4333 ci = c.getClientInfo(share) 4334 // If we did not share but the imports destination is the system account add in the server and cluster info. 4335 if !share && isSysImport { 4336 c.addServerAndClusterInfo(ci) 4337 } 4338 } else if c.kind == LEAF && (si.share || isSysImport) { 4339 // We have a leaf header here for ci, augment as above. 4340 ci = c.getClientInfo(si.share) 4341 if !si.share && isSysImport { 4342 c.addServerAndClusterInfo(ci) 4343 } 4344 } 4345 // Set clientInfo if present. 4346 if ci != nil { 4347 if b, _ := json.Marshal(ci); b != nil { 4348 msg = c.setHeader(ClientInfoHdr, bytesToString(b), msg) 4349 } 4350 } 4351 } 4352 4353 // Set our optional subject(to) and reply. 4354 if !isResponse && to != subject { 4355 c.pa.subject = []byte(to) 4356 } 4357 c.pa.reply = nrr 4358 4359 if changed && c.isMqtt() && c.pa.hdr > 0 { 4360 c.srv.mqttStoreQoSMsgForAccountOnNewSubject(c.pa.hdr, msg, siAcc.GetName(), to) 4361 } 4362 4363 // FIXME(dlc) - Do L1 cache trick like normal client? 4364 rr := siAcc.sl.Match(to) 4365 4366 // If we are a route or gateway or leafnode and this message is flipped to a queue subscriber we 4367 // need to handle that since the processMsgResults will want a queue filter. 4368 flags := pmrMsgImportedFromService 4369 if c.kind == GATEWAY || c.kind == ROUTER || c.kind == LEAF { 4370 flags |= pmrIgnoreEmptyQueueFilter 4371 } 4372 4373 // We will be calling back into processMsgResults since we are now being called as a normal sub. 4374 // We need to take care of the c.in.rts, so save off what is there and use a local version. We 4375 // will put back what was there after. 4376 4377 orts := c.in.rts 4378 4379 var lrts [routeTargetInit]routeTarget 4380 c.in.rts = lrts[:0] 4381 4382 var skipProcessing bool 4383 // If message tracing enabled, add the service import trace. 4384 if mt != nil { 4385 mt.addServiceImportEvent(siAcc.GetName(), string(pacopy.subject), to) 4386 // If we are not allowing tracing and doing trace only, we stop at this level. 4387 if !allowTrace { 4388 if traceOnly { 4389 skipProcessing = true 4390 } else { 4391 // We are going to do normal processing, and possibly chainning 4392 // with other server imports, but the rest won't be traced. 4393 // We do so by setting the c.pa.trace to nil (it will be restored 4394 // with c.pa = pacopy). 4395 c.pa.trace = nil 4396 // We also need to disable the message trace headers so that 4397 // if the message is routed, it does not initialize tracing in the 4398 // remote. 4399 positions := disableTraceHeaders(c, msg) 4400 defer enableTraceHeaders(c, msg, positions) 4401 } 4402 } 4403 } 4404 4405 var didDeliver bool 4406 4407 if !skipProcessing { 4408 // If this is not a gateway connection but gateway is enabled, 4409 // try to send this converted message to all gateways. 4410 if c.srv.gateway.enabled { 4411 flags |= pmrCollectQueueNames 4412 var queues [][]byte 4413 didDeliver, queues = c.processMsgResults(siAcc, rr, msg, c.pa.deliver, []byte(to), nrr, flags) 4414 didDeliver = c.sendMsgToGateways(siAcc, msg, []byte(to), nrr, queues) || didDeliver 4415 } else { 4416 didDeliver, _ = c.processMsgResults(siAcc, rr, msg, c.pa.deliver, []byte(to), nrr, flags) 4417 } 4418 } 4419 4420 // Restore to original values. 4421 c.in.rts = orts 4422 c.pa = pacopy 4423 4424 // If this was a message trace but we skip last-mile delivery, we need to 4425 // do the remove, so: 4426 if mt != nil && traceOnly && didDeliver { 4427 didDeliver = false 4428 } 4429 4430 // Determine if we should remove this service import. This is for response service imports. 4431 // We will remove if we did not deliver, or if we are a response service import and we are 4432 // a singleton, or we have an EOF message. 4433 shouldRemove := !didDeliver || (isResponse && (si.rt == Singleton || len(msg) == LEN_CR_LF)) 4434 // If we are tracking and we did not actually send the latency info we need to suppress the removal. 4435 if si.tracking && !didSendTL { 4436 shouldRemove = false 4437 } 4438 // If we are streamed or chunked we need to update our timestamp to avoid cleanup. 4439 if si.rt != Singleton && didDeliver { 4440 acc.mu.Lock() 4441 si.ts = time.Now().UnixNano() 4442 acc.mu.Unlock() 4443 } 4444 4445 // Cleanup of a response service import 4446 if shouldRemove { 4447 reason := rsiOk 4448 if !didDeliver { 4449 reason = rsiNoDelivery 4450 } 4451 if isResponse { 4452 acc.removeRespServiceImport(si, reason) 4453 } else { 4454 // This is a main import and since we could not even deliver to the exporting account 4455 // go ahead and remove the respServiceImport we created above. 4456 siAcc.removeRespServiceImport(rsi, reason) 4457 } 4458 } 4459 } 4460 4461 func (c *client) addSubToRouteTargets(sub *subscription) { 4462 if c.in.rts == nil { 4463 c.in.rts = make([]routeTarget, 0, routeTargetInit) 4464 } 4465 4466 for i := range c.in.rts { 4467 rt := &c.in.rts[i] 4468 if rt.sub.client == sub.client { 4469 if sub.queue != nil { 4470 rt.qs = append(rt.qs, sub.queue...) 4471 rt.qs = append(rt.qs, ' ') 4472 } 4473 return 4474 } 4475 } 4476 4477 var rt *routeTarget 4478 lrts := len(c.in.rts) 4479 4480 // If we are here we do not have the sub yet in our list 4481 // If we have to grow do so here. 4482 if lrts == cap(c.in.rts) { 4483 c.in.rts = append(c.in.rts, routeTarget{}) 4484 } 4485 4486 c.in.rts = c.in.rts[:lrts+1] 4487 rt = &c.in.rts[lrts] 4488 rt.sub = sub 4489 rt.qs = rt._qs[:0] 4490 if sub.queue != nil { 4491 rt.qs = append(rt.qs, sub.queue...) 4492 rt.qs = append(rt.qs, ' ') 4493 } 4494 } 4495 4496 // This processes the sublist results for a given message. 4497 // Returns if the message was delivered to at least target and queue filters. 4498 func (c *client) processMsgResults(acc *Account, r *SublistResult, msg, deliver, subject, reply []byte, flags int) (bool, [][]byte) { 4499 // For sending messages across routes and leafnodes. 4500 // Reset if we have one since we reuse this data structure. 4501 if c.in.rts != nil { 4502 c.in.rts = c.in.rts[:0] 4503 } 4504 4505 var rplyHasGWPrefix bool 4506 var creply = reply 4507 4508 // If the reply subject is a GW routed reply, we will perform some 4509 // tracking in deliverMsg(). We also want to send to the user the 4510 // reply without the prefix. `creply` will be set to that and be 4511 // used to create the message header for client connections. 4512 if rplyHasGWPrefix = isGWRoutedReply(reply); rplyHasGWPrefix { 4513 creply = reply[gwSubjectOffset:] 4514 } 4515 4516 // With JetStream we now have times where we want to match a subscription 4517 // on one subject, but deliver it with another. e.g. JetStream deliverables. 4518 // This only works for last mile, meaning to a client. For other types we need 4519 // to use the original subject. 4520 subj := subject 4521 if len(deliver) > 0 { 4522 subj = deliver 4523 } 4524 4525 // Check for JetStream encoded reply subjects. 4526 // For now these will only be on $JS.ACK prefixed reply subjects. 4527 var remapped bool 4528 if len(creply) > 0 && 4529 c.kind != CLIENT && c.kind != SYSTEM && c.kind != JETSTREAM && c.kind != ACCOUNT && 4530 bytes.HasPrefix(creply, []byte(jsAckPre)) { 4531 // We need to rewrite the subject and the reply. 4532 if li := bytes.LastIndex(creply, []byte("@")); li != -1 && li < len(creply)-1 { 4533 remapped = true 4534 subj, creply = creply[li+1:], creply[:li] 4535 } 4536 } 4537 4538 var didDeliver bool 4539 4540 // delivery subject for clients 4541 var dsubj []byte 4542 // Used as scratch if mapping 4543 var _dsubj [128]byte 4544 4545 // For stats, we will keep track of the number of messages that have been 4546 // delivered and then multiply by the size of that message and update 4547 // server and account stats in a "single" operation (instead of per-sub). 4548 // However, we account for situations where the message is possibly changed 4549 // by having an extra size 4550 var dlvMsgs int64 4551 var dlvExtraSize int64 4552 4553 // We need to know if this is a MQTT producer because they send messages 4554 // without CR_LF (we otherwise remove the size of CR_LF from message size). 4555 prodIsMQTT := c.isMqtt() 4556 4557 updateStats := func() { 4558 if dlvMsgs == 0 { 4559 return 4560 } 4561 totalBytes := dlvMsgs*int64(len(msg)) + dlvExtraSize 4562 // For non MQTT producers, remove the CR_LF * number of messages 4563 if !prodIsMQTT { 4564 totalBytes -= dlvMsgs * int64(LEN_CR_LF) 4565 } 4566 if acc != nil { 4567 atomic.AddInt64(&acc.outMsgs, dlvMsgs) 4568 atomic.AddInt64(&acc.outBytes, totalBytes) 4569 } 4570 if srv := c.srv; srv != nil { 4571 atomic.AddInt64(&srv.outMsgs, dlvMsgs) 4572 atomic.AddInt64(&srv.outBytes, totalBytes) 4573 } 4574 } 4575 4576 mt, traceOnly := c.isMsgTraceEnabled() 4577 4578 // Loop over all normal subscriptions that match. 4579 for _, sub := range r.psubs { 4580 // Check if this is a send to a ROUTER. We now process 4581 // these after everything else. 4582 switch sub.client.kind { 4583 case ROUTER: 4584 if (c.kind != ROUTER && !c.isSpokeLeafNode()) || (flags&pmrAllowSendFromRouteToRoute != 0) { 4585 c.addSubToRouteTargets(sub) 4586 } 4587 continue 4588 case GATEWAY: 4589 // Never send to gateway from here. 4590 continue 4591 case LEAF: 4592 // We handle similarly to routes and use the same data structures. 4593 // Leaf node delivery audience is different however. 4594 // Also leaf nodes are always no echo, so we make sure we are not 4595 // going to send back to ourselves here. For messages from routes we want 4596 // to suppress in general unless we know from the hub or its a service reply. 4597 if c != sub.client && (c.kind != ROUTER || sub.client.isHubLeafNode() || isServiceReply(c.pa.subject)) { 4598 c.addSubToRouteTargets(sub) 4599 } 4600 continue 4601 } 4602 4603 // Assume delivery subject is the normal subject to this point. 4604 dsubj = subj 4605 4606 // We may need to disable tracing, by setting c.pa.trace to `nil` 4607 // before the call to deliverMsg, if so, this will indicate that 4608 // we need to put it back. 4609 var restorePaTrace bool 4610 4611 // Check for stream import mapped subs (shadow subs). These apply to local subs only. 4612 if sub.im != nil { 4613 // If this message was a service import do not re-export to an exported stream. 4614 if flags&pmrMsgImportedFromService != 0 { 4615 continue 4616 } 4617 if sub.im.tr != nil { 4618 to := sub.im.tr.TransformSubject(bytesToString(subject)) 4619 dsubj = append(_dsubj[:0], to...) 4620 } else if sub.im.usePub { 4621 dsubj = append(_dsubj[:0], subj...) 4622 } else { 4623 dsubj = append(_dsubj[:0], sub.im.to...) 4624 } 4625 4626 if mt != nil { 4627 mt.addStreamExportEvent(sub.client, dsubj) 4628 // If allow_trace is false... 4629 if !sub.im.atrc { 4630 // If we are doing only message tracing, we can move to the 4631 // next sub. 4632 if traceOnly { 4633 // Although the message was not delivered, for the purpose 4634 // of didDeliver, we need to set to true (to avoid possible 4635 // no responders). 4636 didDeliver = true 4637 continue 4638 } 4639 // If we are delivering the message, we need to disable tracing 4640 // before calling deliverMsg(). 4641 c.pa.trace, restorePaTrace = nil, true 4642 } 4643 } 4644 4645 // Make sure deliver is set if inbound from a route. 4646 if remapped && (c.kind == GATEWAY || c.kind == ROUTER || c.kind == LEAF) { 4647 deliver = subj 4648 } 4649 // If we are mapping for a deliver subject we will reverse roles. 4650 // The original subj we set from above is correct for the msg header, 4651 // but we need to transform the deliver subject to properly route. 4652 if len(deliver) > 0 { 4653 dsubj, subj = subj, dsubj 4654 } 4655 } 4656 4657 // Remap to the original subject if internal. 4658 if sub.icb != nil && sub.rsi { 4659 dsubj = subject 4660 } 4661 4662 // Normal delivery 4663 mh := c.msgHeader(dsubj, creply, sub) 4664 if c.deliverMsg(prodIsMQTT, sub, acc, dsubj, creply, mh, msg, rplyHasGWPrefix) { 4665 // We don't count internal deliveries, so do only when sub.icb is nil. 4666 if sub.icb == nil { 4667 dlvMsgs++ 4668 } 4669 didDeliver = true 4670 } 4671 if restorePaTrace { 4672 c.pa.trace = mt 4673 } 4674 } 4675 4676 // Set these up to optionally filter based on the queue lists. 4677 // This is for messages received from routes which will have directed 4678 // guidance on which queue groups we should deliver to. 4679 qf := c.pa.queues 4680 4681 // Declared here because of goto. 4682 var queues [][]byte 4683 4684 // For all routes/leaf/gateway connections, we may still want to send messages to 4685 // leaf nodes or routes even if there are no queue filters since we collect 4686 // them above and do not process inline like normal clients. 4687 // However, do select queue subs if asked to ignore empty queue filter. 4688 if (c.kind == LEAF || c.kind == ROUTER || c.kind == GATEWAY) && len(qf) == 0 && flags&pmrIgnoreEmptyQueueFilter == 0 { 4689 goto sendToRoutesOrLeafs 4690 } 4691 4692 // Process queue subs 4693 for i := 0; i < len(r.qsubs); i++ { 4694 qsubs := r.qsubs[i] 4695 // If we have a filter check that here. We could make this a map or someting more 4696 // complex but linear search since we expect queues to be small. Should be faster 4697 // and more cache friendly. 4698 if qf != nil && len(qsubs) > 0 { 4699 tqn := qsubs[0].queue 4700 for _, qn := range qf { 4701 if bytes.Equal(qn, tqn) { 4702 goto selectQSub 4703 } 4704 } 4705 continue 4706 } 4707 4708 selectQSub: 4709 // We will hold onto remote or lead qsubs when we are coming from 4710 // a route or a leaf node just in case we can no longer do local delivery. 4711 var rsub, sub *subscription 4712 var _ql [32]*subscription 4713 4714 src := c.kind 4715 // If we just came from a route we want to prefer local subs. 4716 // So only select from local subs but remember the first rsub 4717 // in case all else fails. 4718 if src == ROUTER { 4719 ql := _ql[:0] 4720 for i := 0; i < len(qsubs); i++ { 4721 sub = qsubs[i] 4722 if sub.client.kind == LEAF || sub.client.kind == ROUTER { 4723 // If we have assigned an rsub already, replace if the destination is a LEAF 4724 // since we want to favor that compared to a ROUTER. We could make sure that 4725 // we override only if previous was a ROUTE and not a LEAF, but we don't have to. 4726 if rsub == nil || sub.client.kind == LEAF { 4727 rsub = sub 4728 } 4729 } else { 4730 ql = append(ql, sub) 4731 } 4732 } 4733 qsubs = ql 4734 } 4735 4736 sindex := 0 4737 lqs := len(qsubs) 4738 if lqs > 1 { 4739 sindex = int(fastrand.Uint32()) % lqs 4740 } 4741 4742 // Find a subscription that is able to deliver this message starting at a random index. 4743 for i := 0; i < lqs; i++ { 4744 if sindex+i < lqs { 4745 sub = qsubs[sindex+i] 4746 } else { 4747 sub = qsubs[(sindex+i)%lqs] 4748 } 4749 if sub == nil { 4750 continue 4751 } 4752 4753 // If we are a spoke leaf node make sure to not forward across routes. 4754 // This mimics same behavior for normal subs above. 4755 if c.kind == LEAF && c.isSpokeLeafNode() && sub.client.kind == ROUTER { 4756 continue 4757 } 4758 4759 // We have taken care of preferring local subs for a message from a route above. 4760 // Here we just care about a client or leaf and skipping a leaf and preferring locals. 4761 if dst := sub.client.kind; dst == ROUTER || dst == LEAF { 4762 if (src == LEAF || src == CLIENT) && dst == LEAF { 4763 if rsub == nil { 4764 rsub = sub 4765 } 4766 continue 4767 } else { 4768 c.addSubToRouteTargets(sub) 4769 // Clear rsub since we added a sub. 4770 rsub = nil 4771 if flags&pmrCollectQueueNames != 0 { 4772 queues = append(queues, sub.queue) 4773 } 4774 } 4775 break 4776 } 4777 4778 // Assume delivery subject is normal subject to this point. 4779 dsubj = subj 4780 4781 // We may need to disable tracing, by setting c.pa.trace to `nil` 4782 // before the call to deliverMsg, if so, this will indicate that 4783 // we need to put it back. 4784 var restorePaTrace bool 4785 var skipDelivery bool 4786 4787 // Check for stream import mapped subs. These apply to local subs only. 4788 if sub.im != nil { 4789 // If this message was a service import do not re-export to an exported stream. 4790 if flags&pmrMsgImportedFromService != 0 { 4791 continue 4792 } 4793 if sub.im.tr != nil { 4794 to := sub.im.tr.TransformSubject(bytesToString(subject)) 4795 dsubj = append(_dsubj[:0], to...) 4796 } else if sub.im.usePub { 4797 dsubj = append(_dsubj[:0], subj...) 4798 } else { 4799 dsubj = append(_dsubj[:0], sub.im.to...) 4800 } 4801 4802 if mt != nil { 4803 mt.addStreamExportEvent(sub.client, dsubj) 4804 // If allow_trace is false... 4805 if !sub.im.atrc { 4806 // If we are doing only message tracing, we are done 4807 // with this queue group. 4808 if traceOnly { 4809 skipDelivery = true 4810 } else { 4811 // If we are delivering, we need to disable tracing 4812 // before the call to deliverMsg() 4813 c.pa.trace, restorePaTrace = nil, true 4814 } 4815 } 4816 } 4817 4818 // Make sure deliver is set if inbound from a route. 4819 if remapped && (c.kind == GATEWAY || c.kind == ROUTER || c.kind == LEAF) { 4820 deliver = subj 4821 } 4822 // If we are mapping for a deliver subject we will reverse roles. 4823 // The original subj we set from above is correct for the msg header, 4824 // but we need to transform the deliver subject to properly route. 4825 if len(deliver) > 0 { 4826 dsubj, subj = subj, dsubj 4827 } 4828 } 4829 4830 var delivered bool 4831 if !skipDelivery { 4832 mh := c.msgHeader(dsubj, creply, sub) 4833 delivered = c.deliverMsg(prodIsMQTT, sub, acc, subject, creply, mh, msg, rplyHasGWPrefix) 4834 if restorePaTrace { 4835 c.pa.trace = mt 4836 } 4837 } 4838 if skipDelivery || delivered { 4839 // Update only if not skipped. 4840 if !skipDelivery && sub.icb == nil { 4841 dlvMsgs++ 4842 } 4843 // Do the rest even when message delivery was skipped. 4844 didDeliver = true 4845 // Clear rsub 4846 rsub = nil 4847 if flags&pmrCollectQueueNames != 0 { 4848 queues = append(queues, sub.queue) 4849 } 4850 break 4851 } 4852 } 4853 4854 if rsub != nil { 4855 // If we are here we tried to deliver to a local qsub 4856 // but failed. So we will send it to a remote or leaf node. 4857 c.addSubToRouteTargets(rsub) 4858 if flags&pmrCollectQueueNames != 0 { 4859 queues = append(queues, rsub.queue) 4860 } 4861 } 4862 } 4863 4864 sendToRoutesOrLeafs: 4865 4866 // If no messages for routes or leafnodes return here. 4867 if len(c.in.rts) == 0 { 4868 updateStats() 4869 return didDeliver, queues 4870 } 4871 4872 // If we do have a deliver subject we need to do something with it. 4873 // Again this is when JetStream (but possibly others) wants the system 4874 // to rewrite the delivered subject. The way we will do that is place it 4875 // at the end of the reply subject if it exists. 4876 if len(deliver) > 0 && len(reply) > 0 { 4877 reply = append(reply, '@') 4878 reply = append(reply, deliver...) 4879 } 4880 4881 // Copy off original pa in case it changes. 4882 pa := c.pa 4883 4884 if mt != nil { 4885 // We are going to replace "pa" with our copy of c.pa, but to restore 4886 // to the original copy of c.pa, we need to save it again. 4887 cpa := pa 4888 msg = mt.setOriginAccountHeaderIfNeeded(c, acc, msg) 4889 defer func() { c.pa = cpa }() 4890 // Update pa with our current c.pa state. 4891 pa = c.pa 4892 } 4893 4894 // We address by index to avoid struct copy. 4895 // We have inline structs for memory layout and cache coherency. 4896 for i := range c.in.rts { 4897 rt := &c.in.rts[i] 4898 dc := rt.sub.client 4899 dmsg, hset := msg, false 4900 4901 // Check if we have an origin cluster set from a leafnode message. 4902 // If so make sure we do not send it back to the same cluster for a different 4903 // leafnode. Cluster wide no echo. 4904 if dc.kind == LEAF { 4905 // Check two scenarios. One is inbound from a route (c.pa.origin) 4906 if c.kind == ROUTER && len(c.pa.origin) > 0 { 4907 if bytesToString(c.pa.origin) == dc.remoteCluster() { 4908 continue 4909 } 4910 } 4911 // The other is leaf to leaf. 4912 if c.kind == LEAF { 4913 src, dest := c.remoteCluster(), dc.remoteCluster() 4914 if src != _EMPTY_ && src == dest { 4915 continue 4916 } 4917 } 4918 4919 // We need to check if this is a request that has a stamped client information header. 4920 // This will contain an account but will represent the account from the leafnode. If 4921 // they are not named the same this would cause an account lookup failure trying to 4922 // process the request for something like JetStream or other system services that rely 4923 // on the client info header. We can just check for reply and the presence of a header 4924 // to avoid slow downs for all traffic. 4925 if len(c.pa.reply) > 0 && c.pa.hdr >= 0 { 4926 dmsg, hset = c.checkLeafClientInfoHeader(msg) 4927 } 4928 } 4929 4930 if mt != nil { 4931 dmsg = mt.setHopHeader(c, dmsg) 4932 hset = true 4933 } 4934 4935 mh := c.msgHeaderForRouteOrLeaf(subject, reply, rt, acc) 4936 if c.deliverMsg(prodIsMQTT, rt.sub, acc, subject, reply, mh, dmsg, false) { 4937 if rt.sub.icb == nil { 4938 dlvMsgs++ 4939 dlvExtraSize += int64(len(dmsg) - len(msg)) 4940 } 4941 didDeliver = true 4942 } 4943 4944 // If we set the header reset the origin pub args. 4945 if hset { 4946 c.pa = pa 4947 } 4948 } 4949 updateStats() 4950 return didDeliver, queues 4951 } 4952 4953 // Check and swap accounts on a client info header destined across a leafnode. 4954 func (c *client) checkLeafClientInfoHeader(msg []byte) (dmsg []byte, setHdr bool) { 4955 if c.pa.hdr < 0 || len(msg) < c.pa.hdr { 4956 return msg, false 4957 } 4958 cir := getHeader(ClientInfoHdr, msg[:c.pa.hdr]) 4959 if len(cir) == 0 { 4960 return msg, false 4961 } 4962 4963 dmsg = msg 4964 4965 var ci ClientInfo 4966 if err := json.Unmarshal(cir, &ci); err == nil { 4967 if v, _ := c.srv.leafRemoteAccounts.Load(ci.Account); v != nil { 4968 remoteAcc := v.(string) 4969 if ci.Account != remoteAcc { 4970 ci.Account = remoteAcc 4971 if b, _ := json.Marshal(ci); b != nil { 4972 dmsg, setHdr = c.setHeader(ClientInfoHdr, bytesToString(b), msg), true 4973 } 4974 } 4975 } 4976 } 4977 return dmsg, setHdr 4978 } 4979 4980 func (c *client) pubPermissionViolation(subject []byte) { 4981 errTxt := fmt.Sprintf("Permissions Violation for Publish to %q", subject) 4982 if mt, _ := c.isMsgTraceEnabled(); mt != nil { 4983 mt.setIngressError(errTxt) 4984 } 4985 c.sendErr(errTxt) 4986 c.Errorf("Publish Violation - %s, Subject %q", c.getAuthUser(), subject) 4987 } 4988 4989 func (c *client) subPermissionViolation(sub *subscription) { 4990 errTxt := fmt.Sprintf("Permissions Violation for Subscription to %q", sub.subject) 4991 logTxt := fmt.Sprintf("Subscription Violation - %s, Subject %q, SID %s", 4992 c.getAuthUser(), sub.subject, sub.sid) 4993 4994 if sub.queue != nil { 4995 errTxt = fmt.Sprintf("Permissions Violation for Subscription to %q using queue %q", sub.subject, sub.queue) 4996 logTxt = fmt.Sprintf("Subscription Violation - %s, Subject %q, Queue: %q, SID %s", 4997 c.getAuthUser(), sub.subject, sub.queue, sub.sid) 4998 } 4999 5000 c.sendErr(errTxt) 5001 c.Errorf(logTxt) 5002 } 5003 5004 func (c *client) replySubjectViolation(reply []byte) { 5005 errTxt := fmt.Sprintf("Permissions Violation for Publish with Reply of %q", reply) 5006 if mt, _ := c.isMsgTraceEnabled(); mt != nil { 5007 mt.setIngressError(errTxt) 5008 } 5009 c.sendErr(errTxt) 5010 c.Errorf("Publish Violation - %s, Reply %q", c.getAuthUser(), reply) 5011 } 5012 5013 func (c *client) maxTokensViolation(sub *subscription) { 5014 errTxt := fmt.Sprintf("Permissions Violation for Subscription to %q, too many tokens", sub.subject) 5015 logTxt := fmt.Sprintf("Subscription Violation Too Many Tokens - %s, Subject %q, SID %s", 5016 c.getAuthUser(), sub.subject, sub.sid) 5017 c.sendErr(errTxt) 5018 c.Errorf(logTxt) 5019 } 5020 5021 func (c *client) processPingTimer() { 5022 c.mu.Lock() 5023 c.ping.tmr = nil 5024 // Check if connection is still opened 5025 if c.isClosed() { 5026 c.mu.Unlock() 5027 return 5028 } 5029 5030 c.Debugf("%s Ping Timer", c.kindString()) 5031 5032 var sendPing bool 5033 5034 opts := c.srv.getOpts() 5035 pingInterval := opts.PingInterval 5036 if c.kind == ROUTER && opts.Cluster.PingInterval > 0 { 5037 pingInterval = opts.Cluster.PingInterval 5038 } 5039 pingInterval = adjustPingInterval(c.kind, pingInterval) 5040 now := time.Now() 5041 needRTT := c.rtt == 0 || now.Sub(c.rttStart) > DEFAULT_RTT_MEASUREMENT_INTERVAL 5042 5043 // Do not delay PINGs for ROUTER, GATEWAY or spoke LEAF connections. 5044 if c.kind == ROUTER || c.kind == GATEWAY || c.isSpokeLeafNode() { 5045 sendPing = true 5046 } else { 5047 // If we received client data or a ping from the other side within the PingInterval, 5048 // then there is no need to send a ping. 5049 if delta := now.Sub(c.lastIn); delta < pingInterval && !needRTT { 5050 c.Debugf("Delaying PING due to remote client data or ping %v ago", delta.Round(time.Second)) 5051 } else { 5052 sendPing = true 5053 } 5054 } 5055 5056 if sendPing { 5057 // Check for violation 5058 maxPingsOut := opts.MaxPingsOut 5059 if c.kind == ROUTER && opts.Cluster.MaxPingsOut > 0 { 5060 maxPingsOut = opts.Cluster.MaxPingsOut 5061 } 5062 if c.ping.out+1 > maxPingsOut { 5063 c.Debugf("Stale Client Connection - Closing") 5064 c.enqueueProto([]byte(fmt.Sprintf(errProto, "Stale Connection"))) 5065 c.mu.Unlock() 5066 c.closeConnection(StaleConnection) 5067 return 5068 } 5069 // Send PING 5070 c.sendPing() 5071 } 5072 5073 // Reset to fire again. 5074 c.setPingTimer() 5075 c.mu.Unlock() 5076 } 5077 5078 // Returns the smallest value between the given `d` and some max value 5079 // based on the connection kind. 5080 func adjustPingInterval(kind int, d time.Duration) time.Duration { 5081 switch kind { 5082 case ROUTER: 5083 if d > routeMaxPingInterval { 5084 return routeMaxPingInterval 5085 } 5086 case GATEWAY: 5087 if d > gatewayMaxPingInterval { 5088 return gatewayMaxPingInterval 5089 } 5090 } 5091 return d 5092 } 5093 5094 // Lock should be held 5095 func (c *client) setPingTimer() { 5096 if c.srv == nil { 5097 return 5098 } 5099 opts := c.srv.getOpts() 5100 d := opts.PingInterval 5101 if c.kind == ROUTER && opts.Cluster.PingInterval > 0 { 5102 d = opts.Cluster.PingInterval 5103 } 5104 d = adjustPingInterval(c.kind, d) 5105 c.ping.tmr = time.AfterFunc(d, c.processPingTimer) 5106 } 5107 5108 // Lock should be held 5109 func (c *client) clearPingTimer() { 5110 if c.ping.tmr == nil { 5111 return 5112 } 5113 c.ping.tmr.Stop() 5114 c.ping.tmr = nil 5115 } 5116 5117 func (c *client) clearTlsToTimer() { 5118 if c.tlsTo == nil { 5119 return 5120 } 5121 c.tlsTo.Stop() 5122 c.tlsTo = nil 5123 } 5124 5125 // Lock should be held 5126 func (c *client) setAuthTimer(d time.Duration) { 5127 c.atmr = time.AfterFunc(d, c.authTimeout) 5128 } 5129 5130 // Lock should be held 5131 func (c *client) clearAuthTimer() bool { 5132 if c.atmr == nil { 5133 return true 5134 } 5135 stopped := c.atmr.Stop() 5136 c.atmr = nil 5137 return stopped 5138 } 5139 5140 // We may reuse atmr for expiring user jwts, 5141 // so check connectReceived. 5142 // Lock assume held on entry. 5143 func (c *client) awaitingAuth() bool { 5144 return !c.flags.isSet(connectReceived) && c.atmr != nil 5145 } 5146 5147 // This will set the atmr for the JWT expiration time. 5148 // We will lock on entry. 5149 func (c *client) setExpirationTimer(d time.Duration) { 5150 c.mu.Lock() 5151 c.setExpirationTimerUnlocked(d) 5152 c.mu.Unlock() 5153 } 5154 5155 // This will set the atmr for the JWT expiration time. client lock should be held before call 5156 func (c *client) setExpirationTimerUnlocked(d time.Duration) { 5157 c.atmr = time.AfterFunc(d, c.authExpired) 5158 // This is an JWT expiration. 5159 if c.flags.isSet(connectReceived) { 5160 c.expires = time.Now().Add(d).Truncate(time.Second) 5161 } 5162 } 5163 5164 // Return when this client expires via a claim, or 0 if not set. 5165 func (c *client) claimExpiration() time.Duration { 5166 c.mu.Lock() 5167 defer c.mu.Unlock() 5168 if c.expires.IsZero() { 5169 return 0 5170 } 5171 return time.Until(c.expires).Truncate(time.Second) 5172 } 5173 5174 // Possibly flush the connection and then close the low level connection. 5175 // The boolean `minimalFlush` indicates if the flush operation should have a 5176 // minimal write deadline. 5177 // Lock is held on entry. 5178 func (c *client) flushAndClose(minimalFlush bool) { 5179 if !c.flags.isSet(skipFlushOnClose) && c.out.pb > 0 { 5180 if minimalFlush { 5181 const lowWriteDeadline = 100 * time.Millisecond 5182 5183 // Reduce the write deadline if needed. 5184 if c.out.wdl > lowWriteDeadline { 5185 c.out.wdl = lowWriteDeadline 5186 } 5187 } 5188 c.flushOutbound() 5189 } 5190 for i := range c.out.nb { 5191 nbPoolPut(c.out.nb[i]) 5192 } 5193 c.out.nb = nil 5194 5195 // Close the low level connection. 5196 if c.nc != nil { 5197 // Starting with Go 1.16, the low level close will set its own deadline 5198 // of 5 seconds, so setting our own deadline does not work. Instead, 5199 // we will close the TLS connection in separate go routine. 5200 nc := c.nc 5201 c.nc = nil 5202 if _, ok := nc.(*tls.Conn); ok { 5203 go func() { nc.Close() }() 5204 } else { 5205 nc.Close() 5206 } 5207 } 5208 } 5209 5210 var kindStringMap = map[int]string{ 5211 CLIENT: "Client", 5212 ROUTER: "Router", 5213 GATEWAY: "Gateway", 5214 LEAF: "Leafnode", 5215 JETSTREAM: "JetStream", 5216 ACCOUNT: "Account", 5217 SYSTEM: "System", 5218 } 5219 5220 func (c *client) kindString() string { 5221 if kindStringVal, ok := kindStringMap[c.kind]; ok { 5222 return kindStringVal 5223 } 5224 return "Unknown Type" 5225 } 5226 5227 // swapAccountAfterReload will check to make sure the bound account for this client 5228 // is current. Under certain circumstances after a reload we could be pointing to 5229 // an older one. 5230 func (c *client) swapAccountAfterReload() { 5231 c.mu.Lock() 5232 srv := c.srv 5233 an := c.acc.GetName() 5234 c.mu.Unlock() 5235 if srv == nil { 5236 return 5237 } 5238 if acc, _ := srv.LookupAccount(an); acc != nil { 5239 c.mu.Lock() 5240 if c.acc != acc { 5241 c.acc = acc 5242 } 5243 c.mu.Unlock() 5244 } 5245 } 5246 5247 // processSubsOnConfigReload removes any subscriptions the client has that are no 5248 // longer authorized, and checks for imports (accounts) due to a config reload. 5249 func (c *client) processSubsOnConfigReload(awcsti map[string]struct{}) { 5250 c.mu.Lock() 5251 var ( 5252 checkPerms = c.perms != nil 5253 checkAcc = c.acc != nil 5254 acc = c.acc 5255 ) 5256 if !checkPerms && !checkAcc { 5257 c.mu.Unlock() 5258 return 5259 } 5260 var ( 5261 _subs [32]*subscription 5262 subs = _subs[:0] 5263 _removed [32]*subscription 5264 removed = _removed[:0] 5265 srv = c.srv 5266 ) 5267 if checkAcc { 5268 // We actually only want to check if stream imports have changed. 5269 if _, ok := awcsti[acc.Name]; !ok { 5270 checkAcc = false 5271 } 5272 } 5273 // We will clear any mperms we have here. It will rebuild on the fly with canSubscribe, 5274 // so we do that here as we collect them. We will check result down below. 5275 c.mperms = nil 5276 // Collect client's subs under the lock 5277 for _, sub := range c.subs { 5278 // Just checking to rebuild mperms under the lock, will collect removed though here. 5279 // Only collect under subs array of canSubscribe and checkAcc true. 5280 canSub := c.canSubscribe(string(sub.subject)) 5281 canQSub := sub.queue != nil && c.canSubscribe(string(sub.subject), string(sub.queue)) 5282 5283 if !canSub && !canQSub { 5284 removed = append(removed, sub) 5285 } else if checkAcc { 5286 subs = append(subs, sub) 5287 } 5288 } 5289 c.mu.Unlock() 5290 5291 // This list is all subs who are allowed and we need to check accounts. 5292 for _, sub := range subs { 5293 c.mu.Lock() 5294 oldShadows := sub.shadow 5295 sub.shadow = nil 5296 c.mu.Unlock() 5297 c.addShadowSubscriptions(acc, sub, true) 5298 for _, nsub := range oldShadows { 5299 nsub.im.acc.sl.Remove(nsub) 5300 } 5301 } 5302 5303 // Unsubscribe all that need to be removed and report back to client and logs. 5304 for _, sub := range removed { 5305 c.unsubscribe(acc, sub, true, true) 5306 c.sendErr(fmt.Sprintf("Permissions Violation for Subscription to %q (sid %q)", 5307 sub.subject, sub.sid)) 5308 srv.Noticef("Removed sub %q (sid %q) for %s - not authorized", 5309 sub.subject, sub.sid, c.getAuthUser()) 5310 } 5311 } 5312 5313 // Allows us to count up all the queue subscribers during close. 5314 type qsub struct { 5315 sub *subscription 5316 n int32 5317 } 5318 5319 func (c *client) closeConnection(reason ClosedState) { 5320 c.mu.Lock() 5321 if c.flags.isSet(closeConnection) { 5322 c.mu.Unlock() 5323 return 5324 } 5325 // Note that we may have markConnAsClosed() invoked before closeConnection(), 5326 // so don't set this to 1, instead bump the count. 5327 c.rref++ 5328 c.flags.set(closeConnection) 5329 c.clearAuthTimer() 5330 c.clearPingTimer() 5331 c.clearTlsToTimer() 5332 c.markConnAsClosed(reason) 5333 5334 // Unblock anyone who is potentially stalled waiting on us. 5335 if c.out.stc != nil { 5336 close(c.out.stc) 5337 c.out.stc = nil 5338 } 5339 5340 // If we have remote latency tracking running shut that down. 5341 if c.rrTracking != nil { 5342 c.rrTracking.ptmr.Stop() 5343 c.rrTracking = nil 5344 } 5345 5346 // If we are shutting down, no need to do all the accounting on subs, etc. 5347 if reason == ServerShutdown { 5348 s := c.srv 5349 c.mu.Unlock() 5350 if s != nil { 5351 // Unregister 5352 s.removeClient(c) 5353 } 5354 return 5355 } 5356 5357 var ( 5358 kind = c.kind 5359 srv = c.srv 5360 noReconnect = c.flags.isSet(noReconnect) 5361 acc = c.acc 5362 spoke bool 5363 ) 5364 5365 // Snapshot for use if we are a client connection. 5366 // FIXME(dlc) - we can just stub in a new one for client 5367 // and reference existing one. 5368 var subs []*subscription 5369 if kind == CLIENT || kind == LEAF || kind == JETSTREAM { 5370 var _subs [32]*subscription 5371 subs = _subs[:0] 5372 for _, sub := range c.subs { 5373 // Auto-unsubscribe subscriptions must be unsubscribed forcibly. 5374 sub.max = 0 5375 sub.close() 5376 subs = append(subs, sub) 5377 } 5378 spoke = c.isSpokeLeafNode() 5379 } 5380 5381 c.mu.Unlock() 5382 5383 // Remove client's or leaf node or jetstream subscriptions. 5384 if acc != nil && (kind == CLIENT || kind == LEAF || kind == JETSTREAM) { 5385 acc.sl.RemoveBatch(subs) 5386 } else if kind == ROUTER { 5387 c.removeRemoteSubs() 5388 } 5389 5390 if srv != nil { 5391 // Unregister 5392 srv.removeClient(c) 5393 5394 // Update remote subscriptions. 5395 if acc != nil && (kind == CLIENT || kind == LEAF || kind == JETSTREAM) { 5396 qsubs := map[string]*qsub{} 5397 for _, sub := range subs { 5398 // Call unsubscribe here to cleanup shadow subscriptions and such. 5399 c.unsubscribe(acc, sub, true, false) 5400 // Update route as normal for a normal subscriber. 5401 if sub.queue == nil { 5402 if !spoke { 5403 srv.updateRouteSubscriptionMap(acc, sub, -1) 5404 if srv.gateway.enabled { 5405 srv.gatewayUpdateSubInterest(acc.Name, sub, -1) 5406 } 5407 } 5408 acc.updateLeafNodes(sub, -1) 5409 } else { 5410 // We handle queue subscribers special in case we 5411 // have a bunch we can just send one update to the 5412 // connected routes. 5413 num := int32(1) 5414 if kind == LEAF { 5415 num = sub.qw 5416 } 5417 // TODO(dlc) - Better to use string builder? 5418 key := bytesToString(sub.subject) + " " + bytesToString(sub.queue) 5419 if esub, ok := qsubs[key]; ok { 5420 esub.n += num 5421 } else { 5422 qsubs[key] = &qsub{sub, num} 5423 } 5424 } 5425 } 5426 // Process any qsubs here. 5427 for _, esub := range qsubs { 5428 if !spoke { 5429 srv.updateRouteSubscriptionMap(acc, esub.sub, -(esub.n)) 5430 if srv.gateway.enabled { 5431 srv.gatewayUpdateSubInterest(acc.Name, esub.sub, -(esub.n)) 5432 } 5433 } 5434 acc.updateLeafNodes(esub.sub, -(esub.n)) 5435 } 5436 if prev := acc.removeClient(c); prev == 1 { 5437 srv.decActiveAccounts() 5438 } 5439 } 5440 } 5441 5442 // Don't reconnect connections that have been marked with 5443 // the no reconnect flag. 5444 if noReconnect { 5445 return 5446 } 5447 5448 c.reconnect() 5449 } 5450 5451 // Depending on the kind of connections, this may attempt to recreate a connection. 5452 // The actual reconnect attempt will be started in a go routine. 5453 func (c *client) reconnect() { 5454 var ( 5455 retryImplicit bool 5456 gwName string 5457 gwIsOutbound bool 5458 gwCfg *gatewayCfg 5459 ) 5460 5461 c.mu.Lock() 5462 // Decrease the ref count and perform the reconnect only if == 0. 5463 c.rref-- 5464 if c.flags.isSet(noReconnect) || c.rref > 0 { 5465 c.mu.Unlock() 5466 return 5467 } 5468 if c.route != nil { 5469 // A route is marked as solicited if it was given an URL to connect to, 5470 // which would be the case even with implicit (due to gossip), so mark this 5471 // as a retry for a route that is solicited and not explicit. 5472 retryImplicit = c.route.retry || (c.route.didSolicit && c.route.routeType == Implicit) 5473 } 5474 kind := c.kind 5475 if kind == GATEWAY { 5476 gwName = c.gw.name 5477 gwIsOutbound = c.gw.outbound 5478 gwCfg = c.gw.cfg 5479 } 5480 srv := c.srv 5481 c.mu.Unlock() 5482 5483 // Check for a solicited route. If it was, start up a reconnect unless 5484 // we are already connected to the other end. 5485 if didSolicit := c.isSolicitedRoute(); didSolicit || retryImplicit { 5486 srv.mu.Lock() 5487 defer srv.mu.Unlock() 5488 5489 // Capture these under lock 5490 c.mu.Lock() 5491 rid := c.route.remoteID 5492 rtype := c.route.routeType 5493 rurl := c.route.url 5494 accName := string(c.route.accName) 5495 checkRID := accName == _EMPTY_ && srv.getOpts().Cluster.PoolSize < 1 && rid != _EMPTY_ 5496 c.mu.Unlock() 5497 5498 // It is possible that the server is being shutdown. 5499 // If so, don't try to reconnect 5500 if !srv.isRunning() { 5501 return 5502 } 5503 5504 if checkRID && srv.routes[rid] != nil { 5505 // This is the case of "no pool". Make sure that the registered one 5506 // is upgraded to solicited if the connection trying to reconnect 5507 // was a solicited one. 5508 if didSolicit { 5509 if remote := srv.routes[rid][0]; remote != nil { 5510 upgradeRouteToSolicited(remote, rurl, rtype) 5511 } 5512 } 5513 srv.Debugf("Not attempting reconnect for solicited route, already connected to %q", rid) 5514 return 5515 } else if rid == srv.info.ID { 5516 srv.Debugf("Detected route to self, ignoring %q", rurl.Redacted()) 5517 return 5518 } else if rtype != Implicit || retryImplicit { 5519 srv.Debugf("Attempting reconnect for solicited route %q", rurl.Redacted()) 5520 // Keep track of this go-routine so we can wait for it on 5521 // server shutdown. 5522 srv.startGoRoutine(func() { srv.reConnectToRoute(rurl, rtype, accName) }) 5523 } 5524 } else if srv != nil && kind == GATEWAY && gwIsOutbound { 5525 if gwCfg != nil { 5526 srv.Debugf("Attempting reconnect for gateway %q", gwName) 5527 // Run this as a go routine since we may be called within 5528 // the solicitGateway itself if there was an error during 5529 // the creation of the gateway connection. 5530 srv.startGoRoutine(func() { srv.reconnectGateway(gwCfg) }) 5531 } else { 5532 srv.Debugf("Gateway %q not in configuration, not attempting reconnect", gwName) 5533 } 5534 } else if c.isSolicitedLeafNode() { 5535 // Check if this is a solicited leaf node. Start up a reconnect. 5536 srv.startGoRoutine(func() { srv.reConnectToRemoteLeafNode(c.leaf.remote) }) 5537 } 5538 } 5539 5540 // Set the noReconnect flag. This is used before a call to closeConnection() 5541 // to prevent the connection to reconnect (routes, gateways). 5542 func (c *client) setNoReconnect() { 5543 c.mu.Lock() 5544 c.flags.set(noReconnect) 5545 c.mu.Unlock() 5546 } 5547 5548 // Returns the client's RTT value with the protection of the client's lock. 5549 func (c *client) getRTTValue() time.Duration { 5550 c.mu.Lock() 5551 rtt := c.rtt 5552 c.mu.Unlock() 5553 return rtt 5554 } 5555 5556 // This function is used by ROUTER and GATEWAY connections to 5557 // look for a subject on a given account (since these type of 5558 // connections are not bound to a specific account). 5559 // If the c.pa.subject is found in the cache, the cached result 5560 // is returned, otherwse, we match the account's sublist and update 5561 // the cache. The cache is pruned if reaching a certain size. 5562 func (c *client) getAccAndResultFromCache() (*Account, *SublistResult) { 5563 var ( 5564 acc *Account 5565 pac *perAccountCache 5566 r *SublistResult 5567 ok bool 5568 ) 5569 // Check our cache. 5570 if pac, ok = c.in.pacache[string(c.pa.pacache)]; ok { 5571 // Check the genid to see if it's still valid. 5572 // Since v2.10.0, the config reload of accounts has been fixed 5573 // and an account's sublist pointer should not change, so no need to 5574 // lock to access it. 5575 sl := pac.acc.sl 5576 5577 if genid := atomic.LoadUint64(&sl.genid); genid != pac.genid { 5578 ok = false 5579 delete(c.in.pacache, bytesToString(c.pa.pacache)) 5580 } else { 5581 acc = pac.acc 5582 r = pac.results 5583 } 5584 } 5585 5586 if !ok { 5587 if c.kind == ROUTER && len(c.route.accName) > 0 { 5588 acc = c.acc 5589 } else { 5590 // Match correct account and sublist. 5591 if acc, _ = c.srv.LookupAccount(string(c.pa.account)); acc == nil { 5592 return nil, nil 5593 } 5594 } 5595 sl := acc.sl 5596 5597 // Match against the account sublist. 5598 r = sl.Match(string(c.pa.subject)) 5599 5600 // Store in our cache 5601 c.in.pacache[string(c.pa.pacache)] = &perAccountCache{acc, r, atomic.LoadUint64(&sl.genid)} 5602 5603 // Check if we need to prune. 5604 if len(c.in.pacache) > maxPerAccountCacheSize { 5605 c.prunePerAccountCache() 5606 } 5607 } 5608 return acc, r 5609 } 5610 5611 // Account will return the associated account for this client. 5612 func (c *client) Account() *Account { 5613 if c == nil { 5614 return nil 5615 } 5616 c.mu.Lock() 5617 acc := c.acc 5618 c.mu.Unlock() 5619 return acc 5620 } 5621 5622 // prunePerAccountCache will prune off a random number of cache entries. 5623 func (c *client) prunePerAccountCache() { 5624 n := 0 5625 for cacheKey := range c.in.pacache { 5626 delete(c.in.pacache, cacheKey) 5627 if n++; n > prunePerAccountCacheSize { 5628 break 5629 } 5630 } 5631 } 5632 5633 // pruneClosedSubFromPerAccountCache remove entries that contain subscriptions 5634 // that have been closed. 5635 func (c *client) pruneClosedSubFromPerAccountCache() { 5636 for cacheKey, pac := range c.in.pacache { 5637 for _, sub := range pac.results.psubs { 5638 if sub.isClosed() { 5639 goto REMOVE 5640 } 5641 } 5642 for _, qsub := range pac.results.qsubs { 5643 for _, sub := range qsub { 5644 if sub.isClosed() { 5645 goto REMOVE 5646 } 5647 } 5648 } 5649 continue 5650 REMOVE: 5651 delete(c.in.pacache, cacheKey) 5652 } 5653 } 5654 5655 // Returns our service account for this request. 5656 func (ci *ClientInfo) serviceAccount() string { 5657 if ci == nil { 5658 return _EMPTY_ 5659 } 5660 if ci.Service != _EMPTY_ { 5661 return ci.Service 5662 } 5663 return ci.Account 5664 } 5665 5666 // Add in our server and cluster information to this client info. 5667 func (c *client) addServerAndClusterInfo(ci *ClientInfo) { 5668 if ci == nil { 5669 return 5670 } 5671 // Server 5672 if c.kind != LEAF { 5673 ci.Server = c.srv.Name() 5674 } else if c.kind == LEAF { 5675 ci.Server = c.leaf.remoteServer 5676 } 5677 // Cluster 5678 ci.Cluster = c.srv.cachedClusterName() 5679 // If we have gateways fill in cluster alternates. 5680 // These will be in RTT asc order. 5681 if c.srv.gateway.enabled { 5682 var gws []*client 5683 c.srv.getOutboundGatewayConnections(&gws) 5684 for _, c := range gws { 5685 c.mu.Lock() 5686 cn := c.gw.name 5687 c.mu.Unlock() 5688 ci.Alternates = append(ci.Alternates, cn) 5689 } 5690 } 5691 } 5692 5693 // Grabs the information for this client. 5694 func (c *client) getClientInfo(detailed bool) *ClientInfo { 5695 if c == nil || (c.kind != CLIENT && c.kind != LEAF && c.kind != JETSTREAM && c.kind != ACCOUNT) { 5696 return nil 5697 } 5698 5699 // Result 5700 var ci ClientInfo 5701 5702 if detailed { 5703 c.addServerAndClusterInfo(&ci) 5704 } 5705 5706 c.mu.Lock() 5707 // RTT and Account are always added. 5708 ci.Account = accForClient(c) 5709 ci.RTT = c.rtt 5710 // Detailed signals additional opt in. 5711 if detailed { 5712 ci.Start = &c.start 5713 ci.Host = c.host 5714 ci.ID = c.cid 5715 ci.Name = c.opts.Name 5716 ci.User = c.getRawAuthUser() 5717 ci.Lang = c.opts.Lang 5718 ci.Version = c.opts.Version 5719 ci.Jwt = c.opts.JWT 5720 ci.IssuerKey = issuerForClient(c) 5721 ci.NameTag = c.nameTag 5722 ci.Tags = c.tags 5723 ci.Kind = c.kindString() 5724 ci.ClientType = c.clientTypeString() 5725 } 5726 c.mu.Unlock() 5727 return &ci 5728 } 5729 5730 func (c *client) doTLSServerHandshake(typ string, tlsConfig *tls.Config, timeout float64, pCerts PinnedCertSet) error { 5731 _, err := c.doTLSHandshake(typ, false, nil, tlsConfig, _EMPTY_, timeout, pCerts) 5732 return err 5733 } 5734 5735 func (c *client) doTLSClientHandshake(typ string, url *url.URL, tlsConfig *tls.Config, tlsName string, timeout float64, pCerts PinnedCertSet) (bool, error) { 5736 return c.doTLSHandshake(typ, true, url, tlsConfig, tlsName, timeout, pCerts) 5737 } 5738 5739 // Performs either server or client side (if solicit is true) TLS Handshake. 5740 // On error, the TLS handshake error has been logged and the connection 5741 // has been closed. 5742 // 5743 // Lock is held on entry. 5744 func (c *client) doTLSHandshake(typ string, solicit bool, url *url.URL, tlsConfig *tls.Config, tlsName string, timeout float64, pCerts PinnedCertSet) (bool, error) { 5745 var host string 5746 var resetTLSName bool 5747 var err error 5748 5749 // Capture kind for some debug/error statements. 5750 kind := c.kind 5751 5752 // If we solicited, we will act like the client, otherwise the server. 5753 if solicit { 5754 c.Debugf("Starting TLS %s client handshake", typ) 5755 if tlsConfig.ServerName == _EMPTY_ { 5756 // If the given url is a hostname, use this hostname for the 5757 // ServerName. If it is an IP, use the cfg's tlsName. If none 5758 // is available, resort to current IP. 5759 host = url.Hostname() 5760 if tlsName != _EMPTY_ && net.ParseIP(host) != nil { 5761 host = tlsName 5762 } 5763 tlsConfig.ServerName = host 5764 } 5765 c.nc = tls.Client(c.nc, tlsConfig) 5766 } else { 5767 if kind == CLIENT { 5768 c.Debugf("Starting TLS client connection handshake") 5769 } else { 5770 c.Debugf("Starting TLS %s server handshake", typ) 5771 } 5772 c.nc = tls.Server(c.nc, tlsConfig) 5773 } 5774 5775 conn := c.nc.(*tls.Conn) 5776 5777 // Setup the timeout 5778 ttl := secondsToDuration(timeout) 5779 c.tlsTo = time.AfterFunc(ttl, func() { tlsTimeout(c, conn) }) 5780 conn.SetReadDeadline(time.Now().Add(ttl)) 5781 5782 c.mu.Unlock() 5783 if err = conn.Handshake(); err != nil { 5784 if solicit { 5785 // Based on type of error, possibly clear the saved tlsName 5786 // See: https://github.com/nats-io/nats-server/issues/1256 5787 // NOTE: As of Go 1.20, the HostnameError is wrapped so cannot 5788 // type assert to check directly. 5789 var hostnameErr x509.HostnameError 5790 if errors.As(err, &hostnameErr) { 5791 if host == tlsName { 5792 resetTLSName = true 5793 } 5794 } 5795 } 5796 } else if !c.matchesPinnedCert(pCerts) { 5797 err = ErrCertNotPinned 5798 } 5799 5800 if err != nil { 5801 if kind == CLIENT { 5802 c.Errorf("TLS handshake error: %v", err) 5803 } else { 5804 c.Errorf("TLS %s handshake error: %v", typ, err) 5805 } 5806 c.closeConnection(TLSHandshakeError) 5807 5808 // Grab the lock before returning since the caller was holding the lock on entry 5809 c.mu.Lock() 5810 // Returning any error is fine. Since the connection is closed ErrConnectionClosed 5811 // is appropriate. 5812 return resetTLSName, ErrConnectionClosed 5813 } 5814 5815 // Reset the read deadline 5816 conn.SetReadDeadline(time.Time{}) 5817 5818 // Re-Grab lock 5819 c.mu.Lock() 5820 5821 // To be consistent with client, set this flag to indicate that handshake is done 5822 c.flags.set(handshakeComplete) 5823 5824 // The connection still may have been closed on success handshake due 5825 // to a race with tls timeout. If that the case, return error indicating 5826 // that the connection is closed. 5827 if c.isClosed() { 5828 err = ErrConnectionClosed 5829 } 5830 5831 return false, err 5832 } 5833 5834 // getRawAuthUserLock returns the raw auth user for the client. 5835 // Will acquire the client lock. 5836 func (c *client) getRawAuthUserLock() string { 5837 c.mu.Lock() 5838 defer c.mu.Unlock() 5839 return c.getRawAuthUser() 5840 } 5841 5842 // getRawAuthUser returns the raw auth user for the client. 5843 // Lock should be held. 5844 func (c *client) getRawAuthUser() string { 5845 switch { 5846 case c.opts.Nkey != _EMPTY_: 5847 return c.opts.Nkey 5848 case c.opts.Username != _EMPTY_: 5849 return c.opts.Username 5850 case c.opts.JWT != _EMPTY_: 5851 return c.pubKey 5852 case c.opts.Token != _EMPTY_: 5853 return c.opts.Token 5854 default: 5855 return _EMPTY_ 5856 } 5857 } 5858 5859 // getAuthUser returns the auth user for the client. 5860 // Lock should be held. 5861 func (c *client) getAuthUser() string { 5862 switch { 5863 case c.opts.Nkey != _EMPTY_: 5864 return fmt.Sprintf("Nkey %q", c.opts.Nkey) 5865 case c.opts.Username != _EMPTY_: 5866 return fmt.Sprintf("User %q", c.opts.Username) 5867 case c.opts.JWT != _EMPTY_: 5868 return fmt.Sprintf("JWT User %q", c.pubKey) 5869 case c.opts.Token != _EMPTY_: 5870 return fmt.Sprintf("Token %q", c.opts.Token) 5871 default: 5872 return `User "N/A"` 5873 } 5874 } 5875 5876 // Given an array of strings, this function converts it to a map as long 5877 // as all the content (converted to upper-case) matches some constants. 5878 5879 // Converts the given array of strings to a map of string. 5880 // The strings are converted to upper-case and added to the map only 5881 // if the server recognize them as valid connection types. 5882 // If there are unknown connection types, the map of valid ones is returned 5883 // along with an error that contains the name of the unknown. 5884 func convertAllowedConnectionTypes(cts []string) (map[string]struct{}, error) { 5885 var unknown []string 5886 m := make(map[string]struct{}, len(cts)) 5887 for _, i := range cts { 5888 i = strings.ToUpper(i) 5889 switch i { 5890 case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket, 5891 jwt.ConnectionTypeLeafnode, jwt.ConnectionTypeLeafnodeWS, 5892 jwt.ConnectionTypeMqtt, jwt.ConnectionTypeMqttWS: 5893 m[i] = struct{}{} 5894 default: 5895 unknown = append(unknown, i) 5896 } 5897 } 5898 var err error 5899 // We will still return the map of valid ones. 5900 if len(unknown) != 0 { 5901 err = fmt.Errorf("invalid connection types %q", unknown) 5902 } 5903 return m, err 5904 } 5905 5906 // This will return true if the connection is of a type present in the given `acts` map. 5907 // Note that so far this is used only for CLIENT or LEAF connections. 5908 // But a CLIENT can be standard or websocket (and other types in the future). 5909 func (c *client) connectionTypeAllowed(acts map[string]struct{}) bool { 5910 // Empty means all type of clients are allowed 5911 if len(acts) == 0 { 5912 return true 5913 } 5914 var want string 5915 switch c.kind { 5916 case CLIENT: 5917 switch c.clientType() { 5918 case NATS: 5919 want = jwt.ConnectionTypeStandard 5920 case WS: 5921 want = jwt.ConnectionTypeWebsocket 5922 case MQTT: 5923 if c.isWebsocket() { 5924 want = jwt.ConnectionTypeMqttWS 5925 } else { 5926 want = jwt.ConnectionTypeMqtt 5927 } 5928 } 5929 case LEAF: 5930 if c.isWebsocket() { 5931 want = jwt.ConnectionTypeLeafnodeWS 5932 } else { 5933 want = jwt.ConnectionTypeLeafnode 5934 } 5935 } 5936 _, ok := acts[want] 5937 return ok 5938 } 5939 5940 // isClosed returns true if either closeConnection or connMarkedClosed 5941 // flag have been set, or if `nc` is nil, which may happen in tests. 5942 func (c *client) isClosed() bool { 5943 return c.flags.isSet(closeConnection) || c.flags.isSet(connMarkedClosed) || c.nc == nil 5944 } 5945 5946 // Logging functionality scoped to a client or route. 5947 func (c *client) Error(err error) { 5948 c.srv.Errors(c, err) 5949 } 5950 5951 func (c *client) Errorf(format string, v ...interface{}) { 5952 format = fmt.Sprintf("%s - %s", c, format) 5953 c.srv.Errorf(format, v...) 5954 } 5955 5956 func (c *client) Debugf(format string, v ...interface{}) { 5957 format = fmt.Sprintf("%s - %s", c, format) 5958 c.srv.Debugf(format, v...) 5959 } 5960 5961 func (c *client) Noticef(format string, v ...interface{}) { 5962 format = fmt.Sprintf("%s - %s", c, format) 5963 c.srv.Noticef(format, v...) 5964 } 5965 5966 func (c *client) Tracef(format string, v ...interface{}) { 5967 format = fmt.Sprintf("%s - %s", c, format) 5968 c.srv.Tracef(format, v...) 5969 } 5970 5971 func (c *client) Warnf(format string, v ...interface{}) { 5972 format = fmt.Sprintf("%s - %s", c, format) 5973 c.srv.Warnf(format, v...) 5974 } 5975 5976 func (c *client) RateLimitWarnf(format string, v ...interface{}) { 5977 // Do the check before adding the client info to the format... 5978 statement := fmt.Sprintf(format, v...) 5979 if _, loaded := c.srv.rateLimitLogging.LoadOrStore(statement, time.Now()); loaded { 5980 return 5981 } 5982 c.Warnf("%s", statement) 5983 } 5984 5985 // Set the very first PING to a lower interval to capture the initial RTT. 5986 // After that the PING interval will be set to the user defined value. 5987 // Client lock should be held. 5988 func (c *client) setFirstPingTimer() { 5989 s := c.srv 5990 if s == nil { 5991 return 5992 } 5993 opts := s.getOpts() 5994 d := opts.PingInterval 5995 5996 if c.kind == ROUTER && opts.Cluster.PingInterval > 0 { 5997 d = opts.Cluster.PingInterval 5998 } 5999 if !opts.DisableShortFirstPing { 6000 if c.kind != CLIENT { 6001 if d > firstPingInterval { 6002 d = firstPingInterval 6003 } 6004 d = adjustPingInterval(c.kind, d) 6005 } else if d > firstClientPingInterval { 6006 d = firstClientPingInterval 6007 } 6008 } 6009 // We randomize the first one by an offset up to 20%, e.g. 2m ~= max 24s. 6010 addDelay := rand.Int63n(int64(d / 5)) 6011 d += time.Duration(addDelay) 6012 // In the case of ROUTER/LEAF and when compression is configured, it is possible 6013 // that this timer was already set, but just to detect a stale connection 6014 // since we have to delay the first PING after compression negotiation 6015 // occurred. 6016 if c.ping.tmr != nil { 6017 c.ping.tmr.Stop() 6018 } 6019 c.ping.tmr = time.AfterFunc(d, c.processPingTimer) 6020 }