get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/mqtt.go (about) 1 // Copyright 2020-2023 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 "encoding/binary" 20 "encoding/json" 21 "errors" 22 "fmt" 23 "io" 24 "net" 25 "net/http" 26 "sort" 27 "strconv" 28 "strings" 29 "sync" 30 "time" 31 "unicode/utf8" 32 33 "github.com/nats-io/nuid" 34 ) 35 36 // References to "spec" here is from https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.pdf 37 38 const ( 39 mqttPacketConnect = byte(0x10) 40 mqttPacketConnectAck = byte(0x20) 41 mqttPacketPub = byte(0x30) 42 mqttPacketPubAck = byte(0x40) 43 mqttPacketPubRec = byte(0x50) 44 mqttPacketPubRel = byte(0x60) 45 mqttPacketPubComp = byte(0x70) 46 mqttPacketSub = byte(0x80) 47 mqttPacketSubAck = byte(0x90) 48 mqttPacketUnsub = byte(0xa0) 49 mqttPacketUnsubAck = byte(0xb0) 50 mqttPacketPing = byte(0xc0) 51 mqttPacketPingResp = byte(0xd0) 52 mqttPacketDisconnect = byte(0xe0) 53 mqttPacketMask = byte(0xf0) 54 mqttPacketFlagMask = byte(0x0f) 55 56 mqttProtoLevel = byte(0x4) 57 58 // Connect flags 59 mqttConnFlagReserved = byte(0x1) 60 mqttConnFlagCleanSession = byte(0x2) 61 mqttConnFlagWillFlag = byte(0x04) 62 mqttConnFlagWillQoS = byte(0x18) 63 mqttConnFlagWillRetain = byte(0x20) 64 mqttConnFlagPasswordFlag = byte(0x40) 65 mqttConnFlagUsernameFlag = byte(0x80) 66 67 // Publish flags 68 mqttPubFlagRetain = byte(0x01) 69 mqttPubFlagQoS = byte(0x06) 70 mqttPubFlagDup = byte(0x08) 71 mqttPubQos1 = byte(0x1 << 1) 72 mqttPubQoS2 = byte(0x2 << 1) 73 74 // Subscribe flags 75 mqttSubscribeFlags = byte(0x2) 76 mqttSubAckFailure = byte(0x80) 77 78 // Unsubscribe flags 79 mqttUnsubscribeFlags = byte(0x2) 80 81 // ConnAck returned codes 82 mqttConnAckRCConnectionAccepted = byte(0x0) 83 mqttConnAckRCUnacceptableProtocolVersion = byte(0x1) 84 mqttConnAckRCIdentifierRejected = byte(0x2) 85 mqttConnAckRCServerUnavailable = byte(0x3) 86 mqttConnAckRCBadUserOrPassword = byte(0x4) 87 mqttConnAckRCNotAuthorized = byte(0x5) 88 mqttConnAckRCQoS2WillRejected = byte(0x10) 89 90 // Maximum payload size of a control packet 91 mqttMaxPayloadSize = 0xFFFFFFF 92 93 // Topic/Filter characters 94 mqttTopicLevelSep = '/' 95 mqttSingleLevelWC = '+' 96 mqttMultiLevelWC = '#' 97 mqttReservedPre = '$' 98 99 // This is appended to the sid of a subscription that is 100 // created on the upper level subject because of the MQTT 101 // wildcard '#' semantic. 102 mqttMultiLevelSidSuffix = " fwc" 103 104 // This is the prefix for NATS subscriptions subjects associated as delivery 105 // subject of JS consumer. We want to make them unique so will prevent users 106 // MQTT subscriptions to start with this. 107 mqttSubPrefix = "$MQTT.sub." 108 109 // Stream name for MQTT messages on a given account 110 mqttStreamName = "$MQTT_msgs" 111 mqttStreamSubjectPrefix = "$MQTT.msgs." 112 113 // Stream name for MQTT retained messages on a given account 114 mqttRetainedMsgsStreamName = "$MQTT_rmsgs" 115 mqttRetainedMsgsStreamSubject = "$MQTT.rmsgs." 116 117 // Stream name for MQTT sessions on a given account 118 mqttSessStreamName = "$MQTT_sess" 119 mqttSessStreamSubjectPrefix = "$MQTT.sess." 120 121 // Stream name prefix for MQTT sessions on a given account 122 mqttSessionsStreamNamePrefix = "$MQTT_sess_" 123 124 // Stream name and subject for incoming MQTT QoS2 messages 125 mqttQoS2IncomingMsgsStreamName = "$MQTT_qos2in" 126 mqttQoS2IncomingMsgsStreamSubjectPrefix = "$MQTT.qos2.in." 127 128 // Stream name and subjects for outgoing MQTT QoS (PUBREL) messages 129 mqttOutStreamName = "$MQTT_out" 130 mqttOutSubjectPrefix = "$MQTT.out." 131 mqttPubRelSubjectPrefix = "$MQTT.out.pubrel." 132 mqttPubRelDeliverySubjectPrefix = "$MQTT.deliver.pubrel." 133 mqttPubRelConsumerDurablePrefix = "$MQTT_PUBREL_" 134 135 // As per spec, MQTT server may not redeliver QoS 1 and 2 messages to 136 // clients, except after client reconnects. However, NATS Server will 137 // redeliver unacknowledged messages after this default interval. This can 138 // be changed with the server.Options.MQTT.AckWait option. 139 mqttDefaultAckWait = 30 * time.Second 140 141 // This is the default for the outstanding number of pending QoS 1 142 // messages sent to a session with QoS 1 subscriptions. 143 mqttDefaultMaxAckPending = 1024 144 145 // A session's list of subscriptions cannot have a cumulative MaxAckPending 146 // of more than this limit. 147 mqttMaxAckTotalLimit = 0xFFFF 148 149 // Prefix of the reply subject for JS API requests. 150 mqttJSARepliesPrefix = "$MQTT.JSA." 151 152 // Those are tokens that are used for the reply subject of JS API requests. 153 // For instance "$MQTT.JSA.<node id>.SC.<number>" is the reply subject 154 // for a request to create a stream (where <node id> is the server name hash), 155 // while "$MQTT.JSA.<node id>.SL.<number>" is for a stream lookup, etc... 156 mqttJSAIdTokenPos = 3 157 mqttJSATokenPos = 4 158 mqttJSAClientIDPos = 5 159 mqttJSAStreamCreate = "SC" 160 mqttJSAStreamUpdate = "SU" 161 mqttJSAStreamLookup = "SL" 162 mqttJSAStreamDel = "SD" 163 mqttJSAConsumerCreate = "CC" 164 mqttJSAConsumerLookup = "CL" 165 mqttJSAConsumerDel = "CD" 166 mqttJSAMsgStore = "MS" 167 mqttJSAMsgLoad = "ML" 168 mqttJSAMsgDelete = "MD" 169 mqttJSASessPersist = "SP" 170 mqttJSARetainedMsgDel = "RD" 171 mqttJSAStreamNames = "SN" 172 173 // This is how long to keep a client in the flappers map before closing the 174 // connection. This prevent quick reconnect from those clients that keep 175 // wanting to connect with a client ID already in use. 176 mqttSessFlappingJailDur = time.Second 177 178 // This is how frequently the timer to cleanup the sessions flappers map is firing. 179 mqttSessFlappingCleanupInterval = 5 * time.Second 180 181 // Default retry delay if transfer of old session streams to new one fails 182 mqttDefaultTransferRetry = 5 * time.Second 183 184 // For Websocket URLs 185 mqttWSPath = "/mqtt" 186 187 mqttInitialPubHeader = 16 // An overkill, should need 7 bytes max 188 mqttProcessSubTooLong = 100 * time.Millisecond 189 mqttDefaultRetainedCacheTTL = 2 * time.Minute 190 mqttRetainedTransferTimeout = 10 * time.Second 191 ) 192 193 var ( 194 mqttPingResponse = []byte{mqttPacketPingResp, 0x0} 195 mqttProtoName = []byte("MQTT") 196 mqttOldProtoName = []byte("MQIsdp") 197 mqttSessJailDur = mqttSessFlappingJailDur 198 mqttFlapCleanItvl = mqttSessFlappingCleanupInterval 199 mqttJSAPITimeout = 4 * time.Second 200 mqttRetainedCacheTTL = mqttDefaultRetainedCacheTTL 201 ) 202 203 var ( 204 errMQTTNotWebsocketPort = errors.New("MQTT clients over websocket must connect to the Websocket port, not the MQTT port") 205 errMQTTTopicFilterCannotBeEmpty = errors.New("topic filter cannot be empty") 206 errMQTTMalformedVarInt = errors.New("malformed variable int") 207 errMQTTSecondConnectPacket = errors.New("received a second CONNECT packet") 208 errMQTTServerNameMustBeSet = errors.New("mqtt requires server name to be explicitly set") 209 errMQTTUserMixWithUsersNKeys = errors.New("mqtt authentication username not compatible with presence of users/nkeys") 210 errMQTTTokenMixWIthUsersNKeys = errors.New("mqtt authentication token not compatible with presence of users/nkeys") 211 errMQTTAckWaitMustBePositive = errors.New("ack wait must be a positive value") 212 errMQTTStandaloneNeedsJetStream = errors.New("mqtt requires JetStream to be enabled if running in standalone mode") 213 errMQTTConnFlagReserved = errors.New("connect flags reserved bit not set to 0") 214 errMQTTWillAndRetainFlag = errors.New("if Will flag is set to 0, Will Retain flag must be 0 too") 215 errMQTTPasswordFlagAndNoUser = errors.New("password flag set but username flag is not") 216 errMQTTCIDEmptyNeedsCleanFlag = errors.New("when client ID is empty, clean session flag must be set to 1") 217 errMQTTEmptyWillTopic = errors.New("empty Will topic not allowed") 218 errMQTTEmptyUsername = errors.New("empty user name not allowed") 219 errMQTTTopicIsEmpty = errors.New("topic cannot be empty") 220 errMQTTPacketIdentifierIsZero = errors.New("packet identifier cannot be 0") 221 errMQTTUnsupportedCharacters = errors.New("character ' ' not supported for MQTT topics") 222 errMQTTInvalidSession = errors.New("invalid MQTT session") 223 ) 224 225 type srvMQTT struct { 226 listener net.Listener 227 listenerErr error 228 authOverride bool 229 sessmgr mqttSessionManager 230 } 231 232 type mqttSessionManager struct { 233 mu sync.RWMutex 234 sessions map[string]*mqttAccountSessionManager // key is account name 235 } 236 237 var testDisableRMSCache = false 238 239 type mqttAccountSessionManager struct { 240 mu sync.RWMutex 241 sessions map[string]*mqttSession // key is MQTT client ID 242 sessByHash map[string]*mqttSession // key is MQTT client ID hash 243 sessLocked map[string]struct{} // key is MQTT client ID and indicate that a session can not be taken by a new client at this time 244 flappers map[string]int64 // When connection connects with client ID already in use 245 flapTimer *time.Timer // Timer to perform some cleanup of the flappers map 246 sl *Sublist // sublist allowing to find retained messages for given subscription 247 retmsgs map[string]*mqttRetainedMsgRef // retained messages 248 rmsCache *sync.Map // map[subject]mqttRetainedMsg 249 jsa mqttJSA 250 rrmLastSeq uint64 // Restore retained messages expected last sequence 251 rrmDoneCh chan struct{} // To notify the caller that all retained messages have been loaded 252 domainTk string // Domain (with trailing "."), or possibly empty. This is added to session subject. 253 } 254 255 type mqttJSAResponse struct { 256 reply string // will be used to map to the original request in jsa.NewRequestExMulti 257 value any 258 } 259 260 type mqttJSA struct { 261 mu sync.Mutex 262 id string 263 c *client 264 sendq *ipQueue[*mqttJSPubMsg] 265 rplyr string 266 replies sync.Map // [string]chan *mqttJSAResponse 267 nuid *nuid.NUID 268 quitCh chan struct{} 269 domain string // Domain or possibly empty. This is added to session subject. 270 domainSet bool // covers if domain was set, even to empty 271 } 272 273 type mqttJSPubMsg struct { 274 subj string 275 reply string 276 hdr int 277 msg []byte 278 } 279 280 type mqttRetMsgDel struct { 281 Subject string `json:"subject"` 282 Seq uint64 `json:"seq"` 283 } 284 285 type mqttSession struct { 286 // subsMu is a "quick" version of the session lock, sufficient for the QoS0 287 // callback. It only guarantees that a new subscription is initialized, and 288 // its retained messages if any have been queued up for delivery. The QoS12 289 // callback uses the session lock. 290 mu sync.Mutex 291 subsMu sync.RWMutex 292 293 id string // client ID 294 idHash string // client ID hash 295 c *client 296 jsa *mqttJSA 297 subs map[string]byte // Key is MQTT SUBSCRIBE filter, value is the subscription QoS 298 cons map[string]*ConsumerConfig 299 pubRelConsumer *ConsumerConfig 300 pubRelSubscribed bool 301 pubRelDeliverySubject string 302 pubRelDeliverySubjectB []byte 303 pubRelSubject string 304 seq uint64 305 306 // pendingPublish maps packet identifiers (PI) to JetStream ACK subjects for 307 // QoS1 and 2 PUBLISH messages pending delivery to the session's client. 308 pendingPublish map[uint16]*mqttPending 309 310 // pendingPubRel maps PIs to JetStream ACK subjects for QoS2 PUBREL 311 // messages pending delivery to the session's client. 312 pendingPubRel map[uint16]*mqttPending 313 314 // cpending maps delivery attempts (that come with a JS ACK subject) to 315 // existing PIs. 316 cpending map[string]map[uint64]uint16 // composite key: jsDur, sseq 317 318 // "Last used" publish packet identifier (PI). starting point searching for the next available. 319 last_pi uint16 320 321 // Maximum number of pending acks for this session. 322 maxp uint16 323 tmaxack int 324 clean bool 325 domainTk string 326 } 327 328 type mqttPersistedSession struct { 329 Origin string `json:"origin,omitempty"` 330 ID string `json:"id,omitempty"` 331 Clean bool `json:"clean,omitempty"` 332 Subs map[string]byte `json:"subs,omitempty"` 333 Cons map[string]*ConsumerConfig `json:"cons,omitempty"` 334 PubRel *ConsumerConfig `json:"pubrel,omitempty"` 335 } 336 337 type mqttRetainedMsg struct { 338 Origin string `json:"origin,omitempty"` 339 Subject string `json:"subject,omitempty"` 340 Topic string `json:"topic,omitempty"` 341 Msg []byte `json:"msg,omitempty"` 342 Flags byte `json:"flags,omitempty"` 343 Source string `json:"source,omitempty"` 344 345 expiresFromCache time.Time 346 } 347 348 type mqttRetainedMsgRef struct { 349 sseq uint64 350 floor uint64 351 sub *subscription 352 } 353 354 // mqttSub contains fields associated with a MQTT subscription, and is added to 355 // the main subscription struct for MQTT message delivery subscriptions. The 356 // delivery callbacks may get invoked before sub.mqtt is set up, so they should 357 // acquire either sess.mu or sess.subsMu before accessing it. 358 type mqttSub struct { 359 // The sub's QOS and the JS durable name. They can change when 360 // re-subscribing, and are used in the delivery callbacks. They can be 361 // quickly accessed using sess.subsMu.RLock, or under the main session lock. 362 qos byte 363 jsDur string 364 365 // Pending serialization of retained messages to be sent when subscription 366 // is registered. The sub's delivery callbacks must wait until `prm` is 367 // ready (can block on sess.mu for that, too). 368 prm [][]byte 369 370 // If this subscription needs to be checked for being reserved. E.g. '#' or 371 // '*' or '*/'. It is set up at the time of subscription and is immutable 372 // after that. 373 reserved bool 374 } 375 376 type mqtt struct { 377 r *mqttReader 378 cp *mqttConnectProto 379 pp *mqttPublish 380 asm *mqttAccountSessionManager // quick reference to account session manager, immutable after processConnect() 381 sess *mqttSession // quick reference to session, immutable after processConnect() 382 cid string // client ID 383 384 // rejectQoS2Pub tells the MQTT client to not accept QoS2 PUBLISH, instead 385 // error and terminate the connection. 386 rejectQoS2Pub bool 387 388 // downgradeQOS2Sub tells the MQTT client to downgrade QoS2 SUBSCRIBE 389 // requests to QoS1. 390 downgradeQoS2Sub bool 391 } 392 393 type mqttPending struct { 394 sseq uint64 // stream sequence 395 jsAckSubject string // the ACK subject to send the ack to 396 jsDur string // JS durable name 397 } 398 399 type mqttConnectProto struct { 400 rd time.Duration 401 will *mqttWill 402 flags byte 403 } 404 405 type mqttIOReader interface { 406 io.Reader 407 SetReadDeadline(time.Time) error 408 } 409 410 type mqttReader struct { 411 reader mqttIOReader 412 buf []byte 413 pos int 414 pstart int 415 pbuf []byte 416 } 417 418 type mqttWriter struct { 419 bytes.Buffer 420 } 421 422 type mqttWill struct { 423 topic []byte 424 subject []byte 425 mapped []byte 426 message []byte 427 qos byte 428 retain bool 429 } 430 431 type mqttFilter struct { 432 filter string 433 qos byte 434 // Used only for tracing and should not be used after parsing of (un)sub protocols. 435 ttopic []byte 436 } 437 438 type mqttPublish struct { 439 topic []byte 440 subject []byte 441 mapped []byte 442 msg []byte 443 sz int 444 pi uint16 445 flags byte 446 } 447 448 // When we re-encode incoming MQTT PUBLISH messages for NATS delivery, we add 449 // the following headers: 450 // - "Nmqtt-Pub" (*always) indicates that the message originated from MQTT, and 451 // contains the original message QoS. 452 // - "Nmqtt-Subject" contains the original MQTT subject from mqttParsePub. 453 // - "Nmqtt-Mapped" contains the mapping during mqttParsePub. 454 // 455 // When we submit a PUBREL for delivery, we add a "Nmqtt-PubRel" header that 456 // contains the PI. 457 const ( 458 mqttNatsHeader = "Nmqtt-Pub" 459 mqttNatsRetainedMessageTopic = "Nmqtt-RTopic" 460 mqttNatsRetainedMessageOrigin = "Nmqtt-ROrigin" 461 mqttNatsRetainedMessageFlags = "Nmqtt-RFlags" 462 mqttNatsRetainedMessageSource = "Nmqtt-RSource" 463 mqttNatsPubRelHeader = "Nmqtt-PubRel" 464 mqttNatsHeaderSubject = "Nmqtt-Subject" 465 mqttNatsHeaderMapped = "Nmqtt-Mapped" 466 ) 467 468 type mqttParsedPublishNATSHeader struct { 469 qos byte 470 subject []byte 471 mapped []byte 472 } 473 474 func (s *Server) startMQTT() { 475 if s.isShuttingDown() { 476 return 477 } 478 479 sopts := s.getOpts() 480 o := &sopts.MQTT 481 482 var hl net.Listener 483 var err error 484 485 port := o.Port 486 if port == -1 { 487 port = 0 488 } 489 hp := net.JoinHostPort(o.Host, strconv.Itoa(port)) 490 s.mu.Lock() 491 s.mqtt.sessmgr.sessions = make(map[string]*mqttAccountSessionManager) 492 hl, err = s.network.ListenCause("tcp", hp, "mqtt") 493 s.mqtt.listenerErr = err 494 if err != nil { 495 s.mu.Unlock() 496 s.Fatalf("Unable to listen for MQTT connections: %v", err) 497 return 498 } 499 if port == 0 { 500 o.Port = hl.Addr().(*net.TCPAddr).Port 501 } 502 s.mqtt.listener = hl 503 scheme := "mqtt" 504 if o.TLSConfig != nil { 505 scheme = "tls" 506 } 507 s.Noticef("Listening for MQTT clients on %s://%s:%d", scheme, o.Host, o.Port) 508 go s.acceptConnections(hl, "MQTT", func(conn net.Conn) { s.createMQTTClient(conn, nil) }, nil) 509 s.mu.Unlock() 510 } 511 512 // This is similar to createClient() but has some modifications specifi to MQTT clients. 513 // The comments have been kept to minimum to reduce code size. Check createClient() for 514 // more details. 515 func (s *Server) createMQTTClient(conn net.Conn, ws *websocket) *client { 516 opts := s.getOpts() 517 518 maxPay := int32(opts.MaxPayload) 519 maxSubs := int32(opts.MaxSubs) 520 if maxSubs == 0 { 521 maxSubs = -1 522 } 523 now := time.Now() 524 525 mqtt := &mqtt{ 526 rejectQoS2Pub: opts.MQTT.rejectQoS2Pub, 527 downgradeQoS2Sub: opts.MQTT.downgradeQoS2Sub, 528 } 529 c := &client{srv: s, nc: conn, mpay: maxPay, msubs: maxSubs, start: now, last: now, mqtt: mqtt, ws: ws} 530 c.headers = true 531 c.mqtt.pp = &mqttPublish{} 532 // MQTT clients don't send NATS CONNECT protocols. So make it an "echo" 533 // client, but disable verbose and pedantic (by not setting them). 534 c.opts.Echo = true 535 536 c.registerWithAccount(s.globalAccount()) 537 538 s.mu.Lock() 539 // Check auth, override if applicable. 540 authRequired := s.info.AuthRequired || s.mqtt.authOverride 541 s.totalClients++ 542 s.mu.Unlock() 543 544 c.mu.Lock() 545 if authRequired { 546 c.flags.set(expectConnect) 547 } 548 c.initClient() 549 c.Debugf("Client connection created") 550 c.mu.Unlock() 551 552 s.mu.Lock() 553 if !s.isRunning() || s.ldm { 554 if s.isShuttingDown() { 555 conn.Close() 556 } 557 s.mu.Unlock() 558 return c 559 } 560 561 if opts.MaxConn > 0 && len(s.clients) >= opts.MaxConn { 562 s.mu.Unlock() 563 c.maxConnExceeded() 564 return nil 565 } 566 s.clients[c.cid] = c 567 568 // Websocket TLS handshake is already done when getting to this function. 569 tlsRequired := opts.MQTT.TLSConfig != nil && ws == nil 570 s.mu.Unlock() 571 572 c.mu.Lock() 573 574 // In case connection has already been closed 575 if c.isClosed() { 576 c.mu.Unlock() 577 c.closeConnection(WriteError) 578 return nil 579 } 580 581 var pre []byte 582 if tlsRequired && opts.AllowNonTLS { 583 pre = make([]byte, 4) 584 c.nc.SetReadDeadline(time.Now().Add(secondsToDuration(opts.MQTT.TLSTimeout))) 585 n, _ := io.ReadFull(c.nc, pre[:]) 586 c.nc.SetReadDeadline(time.Time{}) 587 pre = pre[:n] 588 if n > 0 && pre[0] == 0x16 { 589 tlsRequired = true 590 } else { 591 tlsRequired = false 592 } 593 } 594 595 if tlsRequired { 596 if len(pre) > 0 { 597 c.nc = &tlsMixConn{c.nc, bytes.NewBuffer(pre)} 598 pre = nil 599 } 600 601 // Perform server-side TLS handshake. 602 if err := c.doTLSServerHandshake(tlsHandshakeMQTT, opts.MQTT.TLSConfig, opts.MQTT.TLSTimeout, opts.MQTT.TLSPinnedCerts); err != nil { 603 c.mu.Unlock() 604 return nil 605 } 606 } 607 608 if authRequired { 609 timeout := opts.AuthTimeout 610 // Possibly override with MQTT specific value. 611 if opts.MQTT.AuthTimeout != 0 { 612 timeout = opts.MQTT.AuthTimeout 613 } 614 c.setAuthTimer(secondsToDuration(timeout)) 615 } 616 617 // No Ping timer for MQTT clients... 618 619 s.startGoRoutine(func() { c.readLoop(pre) }) 620 s.startGoRoutine(func() { c.writeLoop() }) 621 622 if tlsRequired { 623 c.Debugf("TLS handshake complete") 624 cs := c.nc.(*tls.Conn).ConnectionState() 625 c.Debugf("TLS version %s, cipher suite %s", tlsVersion(cs.Version), tlsCipher(cs.CipherSuite)) 626 } 627 628 c.mu.Unlock() 629 630 return c 631 } 632 633 // Given the mqtt options, we check if any auth configuration 634 // has been provided. If so, possibly create users/nkey users and 635 // store them in s.mqtt.users/nkeys. 636 // Also update a boolean that indicates if auth is required for 637 // mqtt clients. 638 // Server lock is held on entry. 639 func (s *Server) mqttConfigAuth(opts *MQTTOpts) { 640 mqtt := &s.mqtt 641 // If any of those is specified, we consider that there is an override. 642 mqtt.authOverride = opts.Username != _EMPTY_ || opts.Token != _EMPTY_ || opts.NoAuthUser != _EMPTY_ 643 } 644 645 // Validate the mqtt related options. 646 func validateMQTTOptions(o *Options) error { 647 mo := &o.MQTT 648 // If no port is defined, we don't care about other options 649 if mo.Port == 0 { 650 return nil 651 } 652 // We have to force the server name to be explicitly set and be unique when 653 // in cluster mode. 654 if o.ServerName == _EMPTY_ && (o.Cluster.Port != 0 || o.Gateway.Port != 0) { 655 return errMQTTServerNameMustBeSet 656 } 657 // If there is a NoAuthUser, we need to have Users defined and 658 // the user to be present. 659 if mo.NoAuthUser != _EMPTY_ { 660 if err := validateNoAuthUser(o, mo.NoAuthUser); err != nil { 661 return err 662 } 663 } 664 // Token/Username not possible if there are users/nkeys 665 if len(o.Users) > 0 || len(o.Nkeys) > 0 { 666 if mo.Username != _EMPTY_ { 667 return errMQTTUserMixWithUsersNKeys 668 } 669 if mo.Token != _EMPTY_ { 670 return errMQTTTokenMixWIthUsersNKeys 671 } 672 } 673 if mo.AckWait < 0 { 674 return errMQTTAckWaitMustBePositive 675 } 676 // If strictly standalone and there is no JS enabled, then it won't work... 677 // For leafnodes, we could either have remote(s) and it would be ok, or no 678 // remote but accept from a remote side that has "hub" property set, which 679 // then would ok too. So we fail only if we have no leafnode config at all. 680 if !o.JetStream && o.Cluster.Port == 0 && o.Gateway.Port == 0 && 681 o.LeafNode.Port == 0 && len(o.LeafNode.Remotes) == 0 { 682 return errMQTTStandaloneNeedsJetStream 683 } 684 if err := validatePinnedCerts(mo.TLSPinnedCerts); err != nil { 685 return fmt.Errorf("mqtt: %v", err) 686 } 687 if mo.ConsumerReplicas > 0 && mo.StreamReplicas > 0 && mo.ConsumerReplicas > mo.StreamReplicas { 688 return fmt.Errorf("mqtt: consumer_replicas (%v) cannot be higher than stream_replicas (%v)", 689 mo.ConsumerReplicas, mo.StreamReplicas) 690 } 691 return nil 692 } 693 694 // Returns true if this connection is from a MQTT client. 695 // Lock held on entry. 696 func (c *client) isMqtt() bool { 697 return c.mqtt != nil 698 } 699 700 // If this is an MQTT client, returns the session client ID, 701 // otherwise returns the empty string. 702 // Lock held on entry 703 func (c *client) getMQTTClientID() string { 704 if !c.isMqtt() { 705 return _EMPTY_ 706 } 707 return c.mqtt.cid 708 } 709 710 // Parse protocols inside the given buffer. 711 // This is invoked from the readLoop. 712 func (c *client) mqttParse(buf []byte) error { 713 c.mu.Lock() 714 s := c.srv 715 trace := c.trace 716 connected := c.flags.isSet(connectReceived) 717 mqtt := c.mqtt 718 r := mqtt.r 719 var rd time.Duration 720 if mqtt.cp != nil { 721 rd = mqtt.cp.rd 722 if rd > 0 { 723 r.reader.SetReadDeadline(time.Time{}) 724 } 725 } 726 hasMappings := c.in.flags.isSet(hasMappings) 727 c.mu.Unlock() 728 729 r.reset(buf) 730 731 var err error 732 var b byte 733 var pl int 734 var complete bool 735 736 for err == nil && r.hasMore() { 737 738 // Keep track of the starting of the packet, in case we have a partial 739 r.pstart = r.pos 740 741 // Read packet type and flags 742 if b, err = r.readByte("packet type"); err != nil { 743 break 744 } 745 746 // Packet type 747 pt := b & mqttPacketMask 748 749 // If client was not connected yet, the first packet must be 750 // a mqttPacketConnect otherwise we fail the connection. 751 if !connected && pt != mqttPacketConnect { 752 // If the buffer indicates that it may be a websocket handshake 753 // but the client is not websocket, it means that the client 754 // connected to the MQTT port instead of the Websocket port. 755 if bytes.HasPrefix(buf, []byte("GET ")) && !c.isWebsocket() { 756 err = errMQTTNotWebsocketPort 757 } else { 758 err = fmt.Errorf("the first packet should be a CONNECT (%v), got %v", mqttPacketConnect, pt) 759 } 760 break 761 } 762 763 pl, complete, err = r.readPacketLen() 764 if err != nil || !complete { 765 break 766 } 767 768 switch pt { 769 // Packets that we receive back when we act as the "sender": PUBACK, 770 // PUBREC, PUBCOMP. 771 case mqttPacketPubAck: 772 var pi uint16 773 pi, err = mqttParsePIPacket(r, pl) 774 if trace { 775 c.traceInOp("PUBACK", errOrTrace(err, fmt.Sprintf("pi=%v", pi))) 776 } 777 if err == nil { 778 err = c.mqttProcessPubAck(pi) 779 } 780 781 case mqttPacketPubRec: 782 var pi uint16 783 pi, err = mqttParsePIPacket(r, pl) 784 if trace { 785 c.traceInOp("PUBREC", errOrTrace(err, fmt.Sprintf("pi=%v", pi))) 786 } 787 if err == nil { 788 err = c.mqttProcessPubRec(pi) 789 } 790 791 case mqttPacketPubComp: 792 var pi uint16 793 pi, err = mqttParsePIPacket(r, pl) 794 if trace { 795 c.traceInOp("PUBCOMP", errOrTrace(err, fmt.Sprintf("pi=%v", pi))) 796 } 797 if err == nil { 798 c.mqttProcessPubComp(pi) 799 } 800 801 // Packets where we act as the "receiver": PUBLISH, PUBREL, SUBSCRIBE, UNSUBSCRIBE. 802 case mqttPacketPub: 803 pp := c.mqtt.pp 804 pp.flags = b & mqttPacketFlagMask 805 err = c.mqttParsePub(r, pl, pp, hasMappings) 806 if trace { 807 c.traceInOp("PUBLISH", errOrTrace(err, mqttPubTrace(pp))) 808 if err == nil { 809 c.mqttTraceMsg(pp.msg) 810 } 811 } 812 if err == nil { 813 err = s.mqttProcessPub(c, pp, trace) 814 } 815 816 case mqttPacketPubRel: 817 var pi uint16 818 pi, err = mqttParsePIPacket(r, pl) 819 if trace { 820 c.traceInOp("PUBREL", errOrTrace(err, fmt.Sprintf("pi=%v", pi))) 821 } 822 if err == nil { 823 err = s.mqttProcessPubRel(c, pi, trace) 824 } 825 826 case mqttPacketSub: 827 var pi uint16 // packet identifier 828 var filters []*mqttFilter 829 var subs []*subscription 830 pi, filters, err = c.mqttParseSubs(r, b, pl) 831 if trace { 832 c.traceInOp("SUBSCRIBE", errOrTrace(err, mqttSubscribeTrace(pi, filters))) 833 } 834 if err == nil { 835 subs, err = c.mqttProcessSubs(filters) 836 if err == nil && trace { 837 c.traceOutOp("SUBACK", []byte(fmt.Sprintf("pi=%v", pi))) 838 } 839 } 840 if err == nil { 841 c.mqttEnqueueSubAck(pi, filters) 842 c.mqttSendRetainedMsgsToNewSubs(subs) 843 } 844 845 case mqttPacketUnsub: 846 var pi uint16 // packet identifier 847 var filters []*mqttFilter 848 pi, filters, err = c.mqttParseUnsubs(r, b, pl) 849 if trace { 850 c.traceInOp("UNSUBSCRIBE", errOrTrace(err, mqttUnsubscribeTrace(pi, filters))) 851 } 852 if err == nil { 853 err = c.mqttProcessUnsubs(filters) 854 if err == nil && trace { 855 c.traceOutOp("UNSUBACK", []byte(fmt.Sprintf("pi=%v", pi))) 856 } 857 } 858 if err == nil { 859 c.mqttEnqueueUnsubAck(pi) 860 } 861 862 // Packets that we get both as a receiver and sender: PING, CONNECT, DISCONNECT 863 case mqttPacketPing: 864 if trace { 865 c.traceInOp("PINGREQ", nil) 866 } 867 c.mqttEnqueuePingResp() 868 if trace { 869 c.traceOutOp("PINGRESP", nil) 870 } 871 872 case mqttPacketConnect: 873 // It is an error to receive a second connect packet 874 if connected { 875 err = errMQTTSecondConnectPacket 876 break 877 } 878 var rc byte 879 var cp *mqttConnectProto 880 var sessp bool 881 rc, cp, err = c.mqttParseConnect(r, pl, hasMappings) 882 // Add the client id to the client's string, regardless of error. 883 // We may still get the client_id if the call above fails somewhere 884 // after parsing the client ID itself. 885 c.ncs.Store(fmt.Sprintf("%s - %q", c, c.mqtt.cid)) 886 if trace && cp != nil { 887 c.traceInOp("CONNECT", errOrTrace(err, c.mqttConnectTrace(cp))) 888 } 889 if rc != 0 { 890 c.mqttEnqueueConnAck(rc, sessp) 891 if trace { 892 c.traceOutOp("CONNACK", []byte(fmt.Sprintf("sp=%v rc=%v", sessp, rc))) 893 } 894 } else if err == nil { 895 if err = s.mqttProcessConnect(c, cp, trace); err != nil { 896 err = fmt.Errorf("unable to connect: %v", err) 897 } else { 898 // Add this debug statement so users running in Debug mode 899 // will have the client id printed here for the first time. 900 c.Debugf("Client connected") 901 connected = true 902 rd = cp.rd 903 } 904 } 905 906 case mqttPacketDisconnect: 907 if trace { 908 c.traceInOp("DISCONNECT", nil) 909 } 910 // Normal disconnect, we need to discard the will. 911 // Spec [MQTT-3.1.2-8] 912 c.mu.Lock() 913 if c.mqtt.cp != nil { 914 c.mqtt.cp.will = nil 915 } 916 c.mu.Unlock() 917 s.mqttHandleClosedClient(c) 918 c.closeConnection(ClientClosed) 919 return nil 920 921 default: 922 err = fmt.Errorf("received unknown packet type %d", pt>>4) 923 } 924 } 925 if err == nil && rd > 0 { 926 r.reader.SetReadDeadline(time.Now().Add(rd)) 927 } 928 return err 929 } 930 931 func (c *client) mqttTraceMsg(msg []byte) { 932 maxTrace := c.srv.getOpts().MaxTracedMsgLen 933 if maxTrace > 0 && len(msg) > maxTrace { 934 c.Tracef("<<- MSG_PAYLOAD: [\"%s...\"]", msg[:maxTrace]) 935 } else { 936 c.Tracef("<<- MSG_PAYLOAD: [%q]", msg) 937 } 938 } 939 940 // The MQTT client connection has been closed, or the DISCONNECT packet was received. 941 // For a "clean" session, we will delete the session, otherwise, simply removing 942 // the binding. We will also send the "will" message if applicable. 943 // 944 // Runs from the client's readLoop. 945 // No lock held on entry. 946 func (s *Server) mqttHandleClosedClient(c *client) { 947 c.mu.Lock() 948 asm := c.mqtt.asm 949 sess := c.mqtt.sess 950 c.mu.Unlock() 951 952 // If asm or sess are nil, it means that we have failed a client 953 // before it was associated with a session, so nothing more to do. 954 if asm == nil || sess == nil { 955 return 956 } 957 958 // Add this session to the locked map for the rest of the execution. 959 if err := asm.lockSession(sess, c); err != nil { 960 return 961 } 962 defer asm.unlockSession(sess) 963 964 asm.mu.Lock() 965 // Clear the client from the session, but session may stay. 966 sess.mu.Lock() 967 sess.c = nil 968 doClean := sess.clean 969 sess.mu.Unlock() 970 // If it was a clean session, then we remove from the account manager, 971 // and we will call clear() outside of any lock. 972 if doClean { 973 asm.removeSession(sess, false) 974 } 975 // Remove in case it was in the flappers map. 976 asm.removeSessFromFlappers(sess.id) 977 asm.mu.Unlock() 978 979 // This needs to be done outside of any lock. 980 if doClean { 981 if err := sess.clear(); err != nil { 982 c.Errorf(err.Error()) 983 } 984 } 985 986 // Now handle the "will". This function will be a no-op if there is no "will" to send. 987 s.mqttHandleWill(c) 988 } 989 990 // Updates the MaxAckPending for all MQTT sessions, updating the 991 // JetStream consumers and updating their max ack pending and forcing 992 // a expiration of pending messages. 993 // 994 // Runs from a server configuration reload routine. 995 // No lock held on entry. 996 func (s *Server) mqttUpdateMaxAckPending(newmaxp uint16) { 997 msm := &s.mqtt.sessmgr 998 s.accounts.Range(func(k, _ interface{}) bool { 999 accName := k.(string) 1000 msm.mu.RLock() 1001 asm := msm.sessions[accName] 1002 msm.mu.RUnlock() 1003 if asm == nil { 1004 // Move to next account 1005 return true 1006 } 1007 asm.mu.RLock() 1008 for _, sess := range asm.sessions { 1009 sess.mu.Lock() 1010 sess.maxp = newmaxp 1011 sess.mu.Unlock() 1012 } 1013 asm.mu.RUnlock() 1014 return true 1015 }) 1016 } 1017 1018 func (s *Server) mqttGetJSAForAccount(acc string) *mqttJSA { 1019 sm := &s.mqtt.sessmgr 1020 1021 sm.mu.RLock() 1022 asm := sm.sessions[acc] 1023 sm.mu.RUnlock() 1024 1025 if asm == nil { 1026 return nil 1027 } 1028 1029 asm.mu.RLock() 1030 jsa := &asm.jsa 1031 asm.mu.RUnlock() 1032 return jsa 1033 } 1034 1035 func (s *Server) mqttStoreQoSMsgForAccountOnNewSubject(hdr int, msg []byte, acc, subject string) { 1036 if s == nil || hdr <= 0 { 1037 return 1038 } 1039 h := mqttParsePublishNATSHeader(msg[:hdr]) 1040 if h == nil || h.qos == 0 { 1041 return 1042 } 1043 jsa := s.mqttGetJSAForAccount(acc) 1044 if jsa == nil { 1045 return 1046 } 1047 jsa.storeMsg(mqttStreamSubjectPrefix+subject, hdr, msg) 1048 } 1049 1050 func mqttParsePublishNATSHeader(headerBytes []byte) *mqttParsedPublishNATSHeader { 1051 if len(headerBytes) == 0 { 1052 return nil 1053 } 1054 1055 pubValue := getHeader(mqttNatsHeader, headerBytes) 1056 if len(pubValue) == 0 { 1057 return nil 1058 } 1059 return &mqttParsedPublishNATSHeader{ 1060 qos: pubValue[0] - '0', 1061 subject: getHeader(mqttNatsHeaderSubject, headerBytes), 1062 mapped: getHeader(mqttNatsHeaderMapped, headerBytes), 1063 } 1064 } 1065 1066 func mqttParsePubRelNATSHeader(headerBytes []byte) uint16 { 1067 if len(headerBytes) == 0 { 1068 return 0 1069 } 1070 1071 pubrelValue := getHeader(mqttNatsPubRelHeader, headerBytes) 1072 if len(pubrelValue) == 0 { 1073 return 0 1074 } 1075 pi, _ := strconv.Atoi(string(pubrelValue)) 1076 return uint16(pi) 1077 } 1078 1079 // Returns the MQTT sessions manager for a given account. 1080 // If new, creates the required JetStream streams/consumers 1081 // for handling of sessions and messages. 1082 func (s *Server) getOrCreateMQTTAccountSessionManager(clientID string, c *client) (*mqttAccountSessionManager, error) { 1083 sm := &s.mqtt.sessmgr 1084 1085 c.mu.Lock() 1086 acc := c.acc 1087 c.mu.Unlock() 1088 accName := acc.GetName() 1089 1090 sm.mu.RLock() 1091 asm, ok := sm.sessions[accName] 1092 sm.mu.RUnlock() 1093 1094 if ok { 1095 return asm, nil 1096 } 1097 1098 // We will pass the quitCh to the account session manager if we happen to create it. 1099 s.mu.Lock() 1100 quitCh := s.quitCh 1101 s.mu.Unlock() 1102 1103 // Not found, now take the write lock and check again 1104 sm.mu.Lock() 1105 defer sm.mu.Unlock() 1106 asm, ok = sm.sessions[accName] 1107 if ok { 1108 return asm, nil 1109 } 1110 // Need to create one here. 1111 asm, err := s.mqttCreateAccountSessionManager(acc, quitCh) 1112 if err != nil { 1113 return nil, err 1114 } 1115 sm.sessions[accName] = asm 1116 return asm, nil 1117 } 1118 1119 // Creates JS streams/consumers for handling of sessions and messages for this account. 1120 // 1121 // Global session manager lock is held on entry. 1122 func (s *Server) mqttCreateAccountSessionManager(acc *Account, quitCh chan struct{}) (*mqttAccountSessionManager, error) { 1123 var err error 1124 1125 accName := acc.GetName() 1126 1127 opts := s.getOpts() 1128 c := s.createInternalAccountClient() 1129 c.acc = acc 1130 1131 id := s.NodeName() 1132 replicas := opts.MQTT.StreamReplicas 1133 if replicas <= 0 { 1134 replicas = s.mqttDetermineReplicas() 1135 } 1136 qname := fmt.Sprintf("[ACC:%s] MQTT ", accName) 1137 as := &mqttAccountSessionManager{ 1138 sessions: make(map[string]*mqttSession), 1139 sessByHash: make(map[string]*mqttSession), 1140 sessLocked: make(map[string]struct{}), 1141 flappers: make(map[string]int64), 1142 jsa: mqttJSA{ 1143 id: id, 1144 c: c, 1145 rplyr: mqttJSARepliesPrefix + id + ".", 1146 sendq: newIPQueue[*mqttJSPubMsg](s, qname+"send"), 1147 nuid: nuid.New(), 1148 quitCh: quitCh, 1149 }, 1150 } 1151 if !testDisableRMSCache { 1152 as.rmsCache = &sync.Map{} 1153 } 1154 // TODO record domain name in as here 1155 1156 // The domain to communicate with may be required for JS calls. 1157 // Search from specific (per account setting) to generic (mqtt setting) 1158 if opts.JsAccDefaultDomain != nil { 1159 if d, ok := opts.JsAccDefaultDomain[accName]; ok { 1160 if d != _EMPTY_ { 1161 as.jsa.domain = d 1162 } 1163 as.jsa.domainSet = true 1164 } 1165 // in case domain was set to empty, check if there are more generic domain overwrites 1166 } 1167 if as.jsa.domain == _EMPTY_ { 1168 if d := opts.MQTT.JsDomain; d != _EMPTY_ { 1169 as.jsa.domain = d 1170 as.jsa.domainSet = true 1171 } 1172 } 1173 // We need to include the domain in the subject prefix used to store sessions in the $MQTT_sess stream. 1174 if as.jsa.domainSet { 1175 if as.jsa.domain != _EMPTY_ { 1176 as.domainTk = as.jsa.domain + "." 1177 } 1178 } else if d := s.getOpts().JetStreamDomain; d != _EMPTY_ { 1179 as.domainTk = d + "." 1180 } 1181 if as.jsa.domainSet { 1182 s.Noticef("Creating MQTT streams/consumers with replicas %v for account %q in domain %q", replicas, accName, as.jsa.domain) 1183 } else { 1184 s.Noticef("Creating MQTT streams/consumers with replicas %v for account %q", replicas, accName) 1185 } 1186 1187 var subs []*subscription 1188 var success bool 1189 closeCh := make(chan struct{}) 1190 1191 defer func() { 1192 if success { 1193 return 1194 } 1195 for _, sub := range subs { 1196 c.processUnsub(sub.sid) 1197 } 1198 close(closeCh) 1199 }() 1200 1201 // We create all subscriptions before starting the go routine that will do 1202 // sends otherwise we could get races. 1203 // Note that using two different clients (one for the subs, one for the 1204 // sends) would cause other issues such as registration of recent subs in 1205 // the "sub" client would be invisible to the check for GW routed replies 1206 // (shouldMapReplyForGatewaySend) since the client there would be the "sender". 1207 1208 jsa := &as.jsa 1209 sid := int64(1) 1210 // This is a subscription that will process all JS API replies. We could split to 1211 // individual subscriptions if needed, but since there is a bit of common code, 1212 // that seemed like a good idea to be all in one place. 1213 if err := as.createSubscription(jsa.rplyr+">", 1214 as.processJSAPIReplies, &sid, &subs); err != nil { 1215 return nil, err 1216 } 1217 1218 // We will listen for replies to session persist requests so that we can 1219 // detect the use of a session with the same client ID anywhere in the cluster. 1220 // `$MQTT.JSA.{js-id}.SP.{client-id-hash}.{uuid}` 1221 if err := as.createSubscription(mqttJSARepliesPrefix+"*."+mqttJSASessPersist+".*.*", 1222 as.processSessionPersist, &sid, &subs); err != nil { 1223 return nil, err 1224 } 1225 1226 // We create the subscription on "$MQTT.sub.<nuid>" to limit the subjects 1227 // that a user would allow permissions on. 1228 rmsubj := mqttSubPrefix + nuid.Next() 1229 if err := as.createSubscription(rmsubj, as.processRetainedMsg, &sid, &subs); err != nil { 1230 return nil, err 1231 } 1232 1233 // Create a subscription to be notified of retained messages delete requests. 1234 rmdelsubj := mqttJSARepliesPrefix + "*." + mqttJSARetainedMsgDel 1235 if err := as.createSubscription(rmdelsubj, as.processRetainedMsgDel, &sid, &subs); err != nil { 1236 return nil, err 1237 } 1238 1239 // No more creation of subscriptions past this point otherwise RACEs may happen. 1240 1241 // Start the go routine that will send JS API requests. 1242 s.startGoRoutine(func() { 1243 defer s.grWG.Done() 1244 as.sendJSAPIrequests(s, c, accName, closeCh) 1245 }) 1246 1247 // Start the go routine that will clean up cached retained messages that expired. 1248 if as.rmsCache != nil { 1249 s.startGoRoutine(func() { 1250 defer s.grWG.Done() 1251 as.cleanupRetainedMessageCache(s, closeCh) 1252 }) 1253 } 1254 1255 lookupStream := func(stream, txt string) (*StreamInfo, error) { 1256 si, err := jsa.lookupStream(stream) 1257 if err != nil { 1258 if IsNatsErr(err, JSStreamNotFoundErr) { 1259 return nil, nil 1260 } 1261 return nil, fmt.Errorf("lookup %s stream for account %q: %v", txt, accName, err) 1262 } 1263 if opts.MQTT.StreamReplicas == 0 { 1264 return si, nil 1265 } 1266 sr := 1 1267 if si.Cluster != nil { 1268 sr += len(si.Cluster.Replicas) 1269 } 1270 if replicas != sr { 1271 s.Warnf("MQTT %s stream replicas mismatch: current is %v but configuration is %v for '%s > %s'", 1272 txt, sr, replicas, accName, stream) 1273 } 1274 return si, nil 1275 } 1276 1277 if si, err := lookupStream(mqttSessStreamName, "sessions"); err != nil { 1278 return nil, err 1279 } else if si == nil { 1280 // Create the stream for the sessions. 1281 cfg := &StreamConfig{ 1282 Name: mqttSessStreamName, 1283 Subjects: []string{mqttSessStreamSubjectPrefix + as.domainTk + ">"}, 1284 Storage: FileStorage, 1285 Retention: LimitsPolicy, 1286 Replicas: replicas, 1287 MaxMsgsPer: 1, 1288 } 1289 if _, created, err := jsa.createStream(cfg); err == nil && created { 1290 as.transferUniqueSessStreamsToMuxed(s) 1291 } else if isErrorOtherThan(err, JSStreamNameExistErr) { 1292 return nil, fmt.Errorf("create sessions stream for account %q: %v", accName, err) 1293 } 1294 } 1295 1296 if si, err := lookupStream(mqttStreamName, "messages"); err != nil { 1297 return nil, err 1298 } else if si == nil { 1299 // Create the stream for the messages. 1300 cfg := &StreamConfig{ 1301 Name: mqttStreamName, 1302 Subjects: []string{mqttStreamSubjectPrefix + ">"}, 1303 Storage: FileStorage, 1304 Retention: InterestPolicy, 1305 Replicas: replicas, 1306 } 1307 if _, _, err := jsa.createStream(cfg); isErrorOtherThan(err, JSStreamNameExistErr) { 1308 return nil, fmt.Errorf("create messages stream for account %q: %v", accName, err) 1309 } 1310 } 1311 1312 if si, err := lookupStream(mqttQoS2IncomingMsgsStreamName, "QoS2 incoming messages"); err != nil { 1313 return nil, err 1314 } else if si == nil { 1315 // Create the stream for the incoming QoS2 messages that have not been 1316 // PUBREL-ed by the sender. Subject is 1317 // "$MQTT.qos2.<session>.<PI>", the .PI is to achieve exactly 1318 // once for each PI. 1319 cfg := &StreamConfig{ 1320 Name: mqttQoS2IncomingMsgsStreamName, 1321 Subjects: []string{mqttQoS2IncomingMsgsStreamSubjectPrefix + ">"}, 1322 Storage: FileStorage, 1323 Retention: LimitsPolicy, 1324 Discard: DiscardNew, 1325 MaxMsgsPer: 1, 1326 DiscardNewPer: true, 1327 Replicas: replicas, 1328 } 1329 if _, _, err := jsa.createStream(cfg); isErrorOtherThan(err, JSStreamNameExistErr) { 1330 return nil, fmt.Errorf("create QoS2 incoming messages stream for account %q: %v", accName, err) 1331 } 1332 } 1333 1334 if si, err := lookupStream(mqttOutStreamName, "QoS2 outgoing PUBREL"); err != nil { 1335 return nil, err 1336 } else if si == nil { 1337 // Create the stream for the incoming QoS2 messages that have not been 1338 // PUBREL-ed by the sender. NATS messages are submitted as 1339 // "$MQTT.pubrel.<session hash>" 1340 cfg := &StreamConfig{ 1341 Name: mqttOutStreamName, 1342 Subjects: []string{mqttOutSubjectPrefix + ">"}, 1343 Storage: FileStorage, 1344 Retention: InterestPolicy, 1345 Replicas: replicas, 1346 } 1347 if _, _, err := jsa.createStream(cfg); isErrorOtherThan(err, JSStreamNameExistErr) { 1348 return nil, fmt.Errorf("create QoS2 outgoing PUBREL stream for account %q: %v", accName, err) 1349 } 1350 } 1351 1352 // This is the only case where we need "si" after lookup/create 1353 needToTransfer := true 1354 si, err := lookupStream(mqttRetainedMsgsStreamName, "retained messages") 1355 switch { 1356 case err != nil: 1357 return nil, err 1358 1359 case si == nil: 1360 // Create the stream for retained messages. 1361 cfg := &StreamConfig{ 1362 Name: mqttRetainedMsgsStreamName, 1363 Subjects: []string{mqttRetainedMsgsStreamSubject + ">"}, 1364 Storage: FileStorage, 1365 Retention: LimitsPolicy, 1366 Replicas: replicas, 1367 MaxMsgsPer: 1, 1368 } 1369 // We will need "si" outside of this block. 1370 si, _, err = jsa.createStream(cfg) 1371 if err != nil { 1372 if isErrorOtherThan(err, JSStreamNameExistErr) { 1373 return nil, fmt.Errorf("create retained messages stream for account %q: %v", accName, err) 1374 } 1375 // Suppose we had a race and the stream was actually created by another 1376 // node, we really need "si" after that, so lookup the stream again here. 1377 si, err = lookupStream(mqttRetainedMsgsStreamName, "retained messages") 1378 if err != nil { 1379 return nil, err 1380 } 1381 } 1382 needToTransfer = false 1383 1384 default: 1385 needToTransfer = si.Config.MaxMsgsPer != 1 1386 } 1387 1388 // Doing this check outside of above if/else due to possible race when 1389 // creating the stream. 1390 wantedSubj := mqttRetainedMsgsStreamSubject + ">" 1391 if len(si.Config.Subjects) != 1 || si.Config.Subjects[0] != wantedSubj { 1392 // Update only the Subjects at this stage, not MaxMsgsPer yet. 1393 si.Config.Subjects = []string{wantedSubj} 1394 if si, err = jsa.updateStream(&si.Config); err != nil { 1395 return nil, fmt.Errorf("failed to update stream config: %w", err) 1396 } 1397 } 1398 1399 transferRMS := func() error { 1400 if !needToTransfer { 1401 return nil 1402 } 1403 1404 as.transferRetainedToPerKeySubjectStream(s) 1405 1406 // We need another lookup to have up-to-date si.State values in order 1407 // to load all retained messages. 1408 si, err = lookupStream(mqttRetainedMsgsStreamName, "retained messages") 1409 if err != nil { 1410 return err 1411 } 1412 needToTransfer = false 1413 return nil 1414 } 1415 1416 // Attempt to transfer all "single subject" retained messages to new 1417 // subjects. It may fail, will log its own error; ignore it the first time 1418 // and proceed to updating MaxMsgsPer. Then we invoke transferRMS() again, 1419 // which will get another chance to resolve the error; if not we bail there. 1420 if err = transferRMS(); err != nil { 1421 return nil, err 1422 } 1423 1424 // Now, if the stream does not have MaxMsgsPer set to 1, and there are no 1425 // more messages on the single $MQTT.rmsgs subject, update the stream again. 1426 if si.Config.MaxMsgsPer != 1 { 1427 si.Config.MaxMsgsPer = 1 1428 // We will need an up-to-date si, so don't use local variable here. 1429 if si, err = jsa.updateStream(&si.Config); err != nil { 1430 return nil, fmt.Errorf("failed to update stream config: %w", err) 1431 } 1432 } 1433 1434 // If we failed the first time, there is now at most one lingering message 1435 // in the old subject. Try again (it will be a NO-OP if succeeded the first 1436 // time). 1437 if err = transferRMS(); err != nil { 1438 return nil, err 1439 } 1440 1441 var lastSeq uint64 1442 var rmDoneCh chan struct{} 1443 st := si.State 1444 if st.Msgs > 0 { 1445 lastSeq = st.LastSeq 1446 if lastSeq > 0 { 1447 rmDoneCh = make(chan struct{}) 1448 as.rrmLastSeq = lastSeq 1449 as.rrmDoneCh = rmDoneCh 1450 } 1451 } 1452 1453 // Opportunistically delete the old (legacy) consumer, from v2.10.10 and 1454 // before. Ignore any errors that might arise. 1455 rmLegacyDurName := mqttRetainedMsgsStreamName + "_" + jsa.id 1456 jsa.deleteConsumer(mqttRetainedMsgsStreamName, rmLegacyDurName) 1457 1458 // Create a new, uniquely names consumer for retained messages for this 1459 // server. The prior one will expire eventually. 1460 ccfg := &CreateConsumerRequest{ 1461 Stream: mqttRetainedMsgsStreamName, 1462 Config: ConsumerConfig{ 1463 Name: mqttRetainedMsgsStreamName + "_" + nuid.Next(), 1464 FilterSubject: mqttRetainedMsgsStreamSubject + ">", 1465 DeliverSubject: rmsubj, 1466 ReplayPolicy: ReplayInstant, 1467 AckPolicy: AckNone, 1468 InactiveThreshold: 5 * time.Minute, 1469 }, 1470 } 1471 if _, err := jsa.createEphemeralConsumer(ccfg); err != nil { 1472 return nil, fmt.Errorf("create retained messages consumer for account %q: %v", accName, err) 1473 } 1474 1475 if lastSeq > 0 { 1476 ttl := time.NewTimer(mqttJSAPITimeout) 1477 defer ttl.Stop() 1478 1479 select { 1480 case <-rmDoneCh: 1481 case <-ttl.C: 1482 s.Warnf("Timing out waiting to load %v retained messages", st.Msgs) 1483 case <-quitCh: 1484 return nil, ErrServerNotRunning 1485 } 1486 } 1487 1488 // Set this so that on defer we don't cleanup. 1489 success = true 1490 1491 return as, nil 1492 } 1493 1494 func (s *Server) mqttDetermineReplicas() int { 1495 // If not clustered, then replica will be 1. 1496 if !s.JetStreamIsClustered() { 1497 return 1 1498 } 1499 opts := s.getOpts() 1500 replicas := 0 1501 for _, u := range opts.Routes { 1502 host := u.Hostname() 1503 // If this is an IP just add one. 1504 if net.ParseIP(host) != nil { 1505 replicas++ 1506 } else { 1507 addrs, _ := net.LookupHost(host) 1508 replicas += len(addrs) 1509 } 1510 } 1511 if replicas < 1 { 1512 replicas = 1 1513 } else if replicas > 3 { 1514 replicas = 3 1515 } 1516 return replicas 1517 } 1518 1519 ////////////////////////////////////////////////////////////////////////////// 1520 // 1521 // JS APIs related functions 1522 // 1523 ////////////////////////////////////////////////////////////////////////////// 1524 1525 func (jsa *mqttJSA) newRequest(kind, subject string, hdr int, msg []byte) (interface{}, error) { 1526 return jsa.newRequestEx(kind, subject, _EMPTY_, hdr, msg, mqttJSAPITimeout) 1527 } 1528 1529 func (jsa *mqttJSA) prefixDomain(subject string) string { 1530 if jsa.domain != _EMPTY_ { 1531 // rewrite js api prefix with domain 1532 if sub := strings.TrimPrefix(subject, JSApiPrefix+"."); sub != subject { 1533 subject = fmt.Sprintf("$JS.%s.API.%s", jsa.domain, sub) 1534 } 1535 } 1536 return subject 1537 } 1538 1539 func (jsa *mqttJSA) newRequestEx(kind, subject, cidHash string, hdr int, msg []byte, timeout time.Duration) (any, error) { 1540 responses, err := jsa.newRequestExMulti(kind, subject, cidHash, []int{hdr}, [][]byte{msg}, timeout) 1541 if err != nil { 1542 return nil, err 1543 } 1544 if len(responses) != 1 { 1545 return nil, fmt.Errorf("unreachable: invalid number of responses (%d)", len(responses)) 1546 } 1547 return responses[0].value, nil 1548 } 1549 1550 // newRequestExMulti sends multiple messages on the same subject and waits for 1551 // all responses. It returns the same number of responses in the same order as 1552 // msgs parameter. In case of a timeout it returns an error as well as all 1553 // responses received as a sparsely populated array, matching msgs, with nils 1554 // for the values that have not yet been received. 1555 // 1556 // Note that each response may represent an error and should be inspected as 1557 // such by the caller. 1558 func (jsa *mqttJSA) newRequestExMulti(kind, subject, cidHash string, hdrs []int, msgs [][]byte, timeout time.Duration) ([]*mqttJSAResponse, error) { 1559 if len(hdrs) != len(msgs) { 1560 return nil, fmt.Errorf("unreachable: invalid number of messages (%d) or header offsets (%d)", len(msgs), len(hdrs)) 1561 } 1562 responseCh := make(chan *mqttJSAResponse, len(msgs)) 1563 1564 // Generate and queue all outgoing requests, have all results reported to 1565 // responseCh, and store a map of reply subjects to the original subjects' 1566 // indices. 1567 r2i := map[string]int{} 1568 for i, msg := range msgs { 1569 hdr := hdrs[i] 1570 var sb strings.Builder 1571 // Either we use nuid.Next() which uses a global lock, or our own nuid object, but 1572 // then it needs to be "write" protected. This approach will reduce across account 1573 // contention since we won't use the global nuid's lock. 1574 jsa.mu.Lock() 1575 uid := jsa.nuid.Next() 1576 sb.WriteString(jsa.rplyr) 1577 jsa.mu.Unlock() 1578 1579 sb.WriteString(kind) 1580 sb.WriteByte(btsep) 1581 if cidHash != _EMPTY_ { 1582 sb.WriteString(cidHash) 1583 sb.WriteByte(btsep) 1584 } 1585 sb.WriteString(uid) 1586 reply := sb.String() 1587 1588 // Add responseCh to the reply channel map. It will be cleaned out on 1589 // timeout (see below), or in processJSAPIReplies upon receiving the 1590 // response. 1591 jsa.replies.Store(reply, responseCh) 1592 1593 subject = jsa.prefixDomain(subject) 1594 jsa.sendq.push(&mqttJSPubMsg{ 1595 subj: subject, 1596 reply: reply, 1597 hdr: hdr, 1598 msg: msg, 1599 }) 1600 r2i[reply] = i 1601 } 1602 1603 // Wait for all responses to come back, or for the timeout to expire. We 1604 // don't want to use time.After() which causes memory growth because the 1605 // timer can't be stopped and will need to expire to then be garbage 1606 // collected. 1607 c := 0 1608 responses := make([]*mqttJSAResponse, len(msgs)) 1609 start := time.Now() 1610 t := time.NewTimer(timeout) 1611 defer t.Stop() 1612 for { 1613 select { 1614 case r := <-responseCh: 1615 i := r2i[r.reply] 1616 responses[i] = r 1617 c++ 1618 if c == len(msgs) { 1619 return responses, nil 1620 } 1621 1622 case <-jsa.quitCh: 1623 return nil, ErrServerNotRunning 1624 1625 case <-t.C: 1626 var reply string 1627 now := time.Now() 1628 for reply = range r2i { // preserve the last value for Errorf 1629 jsa.replies.Delete(reply) 1630 } 1631 1632 if len(msgs) == 1 { 1633 return responses, fmt.Errorf("timeout after %v: request type %q on %q (reply=%q)", now.Sub(start), kind, subject, reply) 1634 } else { 1635 return responses, fmt.Errorf("timeout after %v: request type %q on %q: got %d out of %d", now.Sub(start), kind, subject, c, len(msgs)) 1636 } 1637 } 1638 } 1639 } 1640 1641 func (jsa *mqttJSA) sendAck(ackSubject string) { 1642 if ackSubject == _EMPTY_ { 1643 return 1644 } 1645 1646 // We pass -1 for the hdr so that the send loop does not need to 1647 // add the "client info" header. This is not a JS API request per se. 1648 jsa.sendq.push(&mqttJSPubMsg{subj: ackSubject, hdr: -1}) 1649 } 1650 1651 func (jsa *mqttJSA) createEphemeralConsumer(cfg *CreateConsumerRequest) (*JSApiConsumerCreateResponse, error) { 1652 cfgb, err := json.Marshal(cfg) 1653 if err != nil { 1654 return nil, err 1655 } 1656 subj := fmt.Sprintf(JSApiConsumerCreateT, cfg.Stream) 1657 ccri, err := jsa.newRequest(mqttJSAConsumerCreate, subj, 0, cfgb) 1658 if err != nil { 1659 return nil, err 1660 } 1661 ccr := ccri.(*JSApiConsumerCreateResponse) 1662 return ccr, ccr.ToError() 1663 } 1664 1665 func (jsa *mqttJSA) createDurableConsumer(cfg *CreateConsumerRequest) (*JSApiConsumerCreateResponse, error) { 1666 cfgb, err := json.Marshal(cfg) 1667 if err != nil { 1668 return nil, err 1669 } 1670 subj := fmt.Sprintf(JSApiDurableCreateT, cfg.Stream, cfg.Config.Durable) 1671 ccri, err := jsa.newRequest(mqttJSAConsumerCreate, subj, 0, cfgb) 1672 if err != nil { 1673 return nil, err 1674 } 1675 ccr := ccri.(*JSApiConsumerCreateResponse) 1676 return ccr, ccr.ToError() 1677 } 1678 1679 func (jsa *mqttJSA) deleteConsumer(streamName, consName string) (*JSApiConsumerDeleteResponse, error) { 1680 subj := fmt.Sprintf(JSApiConsumerDeleteT, streamName, consName) 1681 cdri, err := jsa.newRequest(mqttJSAConsumerDel, subj, 0, nil) 1682 if err != nil { 1683 return nil, err 1684 } 1685 cdr := cdri.(*JSApiConsumerDeleteResponse) 1686 return cdr, cdr.ToError() 1687 } 1688 1689 func (jsa *mqttJSA) createStream(cfg *StreamConfig) (*StreamInfo, bool, error) { 1690 cfgb, err := json.Marshal(cfg) 1691 if err != nil { 1692 return nil, false, err 1693 } 1694 scri, err := jsa.newRequest(mqttJSAStreamCreate, fmt.Sprintf(JSApiStreamCreateT, cfg.Name), 0, cfgb) 1695 if err != nil { 1696 return nil, false, err 1697 } 1698 scr := scri.(*JSApiStreamCreateResponse) 1699 return scr.StreamInfo, scr.DidCreate, scr.ToError() 1700 } 1701 1702 func (jsa *mqttJSA) updateStream(cfg *StreamConfig) (*StreamInfo, error) { 1703 cfgb, err := json.Marshal(cfg) 1704 if err != nil { 1705 return nil, err 1706 } 1707 scri, err := jsa.newRequest(mqttJSAStreamUpdate, fmt.Sprintf(JSApiStreamUpdateT, cfg.Name), 0, cfgb) 1708 if err != nil { 1709 return nil, err 1710 } 1711 scr := scri.(*JSApiStreamUpdateResponse) 1712 return scr.StreamInfo, scr.ToError() 1713 } 1714 1715 func (jsa *mqttJSA) lookupStream(name string) (*StreamInfo, error) { 1716 slri, err := jsa.newRequest(mqttJSAStreamLookup, fmt.Sprintf(JSApiStreamInfoT, name), 0, nil) 1717 if err != nil { 1718 return nil, err 1719 } 1720 slr := slri.(*JSApiStreamInfoResponse) 1721 return slr.StreamInfo, slr.ToError() 1722 } 1723 1724 func (jsa *mqttJSA) deleteStream(name string) (bool, error) { 1725 sdri, err := jsa.newRequest(mqttJSAStreamDel, fmt.Sprintf(JSApiStreamDeleteT, name), 0, nil) 1726 if err != nil { 1727 return false, err 1728 } 1729 sdr := sdri.(*JSApiStreamDeleteResponse) 1730 return sdr.Success, sdr.ToError() 1731 } 1732 1733 func (jsa *mqttJSA) loadLastMsgFor(streamName string, subject string) (*StoredMsg, error) { 1734 mreq := &JSApiMsgGetRequest{LastFor: subject} 1735 req, err := json.Marshal(mreq) 1736 if err != nil { 1737 return nil, err 1738 } 1739 lmri, err := jsa.newRequest(mqttJSAMsgLoad, fmt.Sprintf(JSApiMsgGetT, streamName), 0, req) 1740 if err != nil { 1741 return nil, err 1742 } 1743 lmr := lmri.(*JSApiMsgGetResponse) 1744 return lmr.Message, lmr.ToError() 1745 } 1746 1747 func (jsa *mqttJSA) loadLastMsgForMulti(streamName string, subjects []string) ([]*JSApiMsgGetResponse, error) { 1748 marshaled := make([][]byte, 0, len(subjects)) 1749 headerBytes := make([]int, 0, len(subjects)) 1750 for _, subject := range subjects { 1751 mreq := &JSApiMsgGetRequest{LastFor: subject} 1752 bb, err := json.Marshal(mreq) 1753 if err != nil { 1754 return nil, err 1755 } 1756 marshaled = append(marshaled, bb) 1757 headerBytes = append(headerBytes, 0) 1758 } 1759 1760 all, err := jsa.newRequestExMulti(mqttJSAMsgLoad, fmt.Sprintf(JSApiMsgGetT, streamName), _EMPTY_, headerBytes, marshaled, mqttJSAPITimeout) 1761 // all has the same order as subjects, preserve it as we unmarshal 1762 responses := make([]*JSApiMsgGetResponse, len(all)) 1763 for i, v := range all { 1764 if v != nil { 1765 responses[i] = v.value.(*JSApiMsgGetResponse) 1766 } 1767 } 1768 return responses, err 1769 } 1770 1771 func (jsa *mqttJSA) loadNextMsgFor(streamName string, subject string) (*StoredMsg, error) { 1772 mreq := &JSApiMsgGetRequest{NextFor: subject} 1773 req, err := json.Marshal(mreq) 1774 if err != nil { 1775 return nil, err 1776 } 1777 lmri, err := jsa.newRequest(mqttJSAMsgLoad, fmt.Sprintf(JSApiMsgGetT, streamName), 0, req) 1778 if err != nil { 1779 return nil, err 1780 } 1781 lmr := lmri.(*JSApiMsgGetResponse) 1782 return lmr.Message, lmr.ToError() 1783 } 1784 1785 func (jsa *mqttJSA) loadMsg(streamName string, seq uint64) (*StoredMsg, error) { 1786 mreq := &JSApiMsgGetRequest{Seq: seq} 1787 req, err := json.Marshal(mreq) 1788 if err != nil { 1789 return nil, err 1790 } 1791 lmri, err := jsa.newRequest(mqttJSAMsgLoad, fmt.Sprintf(JSApiMsgGetT, streamName), 0, req) 1792 if err != nil { 1793 return nil, err 1794 } 1795 lmr := lmri.(*JSApiMsgGetResponse) 1796 return lmr.Message, lmr.ToError() 1797 } 1798 1799 func (jsa *mqttJSA) storeMsg(subject string, headers int, msg []byte) (*JSPubAckResponse, error) { 1800 return jsa.storeMsgWithKind(mqttJSAMsgStore, subject, headers, msg) 1801 } 1802 1803 func (jsa *mqttJSA) storeMsgWithKind(kind, subject string, headers int, msg []byte) (*JSPubAckResponse, error) { 1804 smri, err := jsa.newRequest(kind, subject, headers, msg) 1805 if err != nil { 1806 return nil, err 1807 } 1808 smr := smri.(*JSPubAckResponse) 1809 return smr, smr.ToError() 1810 } 1811 1812 func (jsa *mqttJSA) storeSessionMsg(domainTk, cidHash string, hdr int, msg []byte) (*JSPubAckResponse, error) { 1813 // Compute subject where the session is being stored 1814 subject := mqttSessStreamSubjectPrefix + domainTk + cidHash 1815 1816 // Passing cidHash will add it to the JS reply subject, so that we can use 1817 // it in processSessionPersist. 1818 smri, err := jsa.newRequestEx(mqttJSASessPersist, subject, cidHash, hdr, msg, mqttJSAPITimeout) 1819 if err != nil { 1820 return nil, err 1821 } 1822 smr := smri.(*JSPubAckResponse) 1823 return smr, smr.ToError() 1824 } 1825 1826 func (jsa *mqttJSA) loadSessionMsg(domainTk, cidHash string) (*StoredMsg, error) { 1827 subject := mqttSessStreamSubjectPrefix + domainTk + cidHash 1828 return jsa.loadLastMsgFor(mqttSessStreamName, subject) 1829 } 1830 1831 func (jsa *mqttJSA) deleteMsg(stream string, seq uint64, wait bool) error { 1832 dreq := JSApiMsgDeleteRequest{Seq: seq, NoErase: true} 1833 req, _ := json.Marshal(dreq) 1834 subj := jsa.prefixDomain(fmt.Sprintf(JSApiMsgDeleteT, stream)) 1835 if !wait { 1836 jsa.sendq.push(&mqttJSPubMsg{ 1837 subj: subj, 1838 msg: req, 1839 }) 1840 return nil 1841 } 1842 dmi, err := jsa.newRequest(mqttJSAMsgDelete, subj, 0, req) 1843 if err != nil { 1844 return err 1845 } 1846 dm := dmi.(*JSApiMsgDeleteResponse) 1847 return dm.ToError() 1848 } 1849 1850 ////////////////////////////////////////////////////////////////////////////// 1851 // 1852 // Account Sessions Manager related functions 1853 // 1854 ////////////////////////////////////////////////////////////////////////////// 1855 1856 // Returns true if `err` is not nil and does not match the api error with ErrorIdentifier id 1857 func isErrorOtherThan(err error, id ErrorIdentifier) bool { 1858 return err != nil && !IsNatsErr(err, id) 1859 } 1860 1861 // Process JS API replies. 1862 // 1863 // Can run from various go routines (consumer's loop, system send loop, etc..). 1864 func (as *mqttAccountSessionManager) processJSAPIReplies(_ *subscription, pc *client, _ *Account, subject, _ string, msg []byte) { 1865 token := tokenAt(subject, mqttJSATokenPos) 1866 if token == _EMPTY_ { 1867 return 1868 } 1869 jsa := &as.jsa 1870 chi, ok := jsa.replies.Load(subject) 1871 if !ok { 1872 return 1873 } 1874 jsa.replies.Delete(subject) 1875 ch := chi.(chan *mqttJSAResponse) 1876 out := func(value any) { 1877 ch <- &mqttJSAResponse{reply: subject, value: value} 1878 } 1879 switch token { 1880 case mqttJSAStreamCreate: 1881 var resp = &JSApiStreamCreateResponse{} 1882 if err := json.Unmarshal(msg, resp); err != nil { 1883 resp.Error = NewJSInvalidJSONError() 1884 } 1885 out(resp) 1886 case mqttJSAStreamUpdate: 1887 var resp = &JSApiStreamUpdateResponse{} 1888 if err := json.Unmarshal(msg, resp); err != nil { 1889 resp.Error = NewJSInvalidJSONError() 1890 } 1891 out(resp) 1892 case mqttJSAStreamLookup: 1893 var resp = &JSApiStreamInfoResponse{} 1894 if err := json.Unmarshal(msg, &resp); err != nil { 1895 resp.Error = NewJSInvalidJSONError() 1896 } 1897 out(resp) 1898 case mqttJSAStreamDel: 1899 var resp = &JSApiStreamDeleteResponse{} 1900 if err := json.Unmarshal(msg, &resp); err != nil { 1901 resp.Error = NewJSInvalidJSONError() 1902 } 1903 out(resp) 1904 case mqttJSAConsumerCreate: 1905 var resp = &JSApiConsumerCreateResponse{} 1906 if err := json.Unmarshal(msg, resp); err != nil { 1907 resp.Error = NewJSInvalidJSONError() 1908 } 1909 out(resp) 1910 case mqttJSAConsumerDel: 1911 var resp = &JSApiConsumerDeleteResponse{} 1912 if err := json.Unmarshal(msg, resp); err != nil { 1913 resp.Error = NewJSInvalidJSONError() 1914 } 1915 out(resp) 1916 case mqttJSAMsgStore, mqttJSASessPersist: 1917 var resp = &JSPubAckResponse{} 1918 if err := json.Unmarshal(msg, resp); err != nil { 1919 resp.Error = NewJSInvalidJSONError() 1920 } 1921 out(resp) 1922 case mqttJSAMsgLoad: 1923 var resp = &JSApiMsgGetResponse{} 1924 if err := json.Unmarshal(msg, &resp); err != nil { 1925 resp.Error = NewJSInvalidJSONError() 1926 } 1927 out(resp) 1928 case mqttJSAStreamNames: 1929 var resp = &JSApiStreamNamesResponse{} 1930 if err := json.Unmarshal(msg, resp); err != nil { 1931 resp.Error = NewJSInvalidJSONError() 1932 } 1933 out(resp) 1934 case mqttJSAMsgDelete: 1935 var resp = &JSApiMsgDeleteResponse{} 1936 if err := json.Unmarshal(msg, resp); err != nil { 1937 resp.Error = NewJSInvalidJSONError() 1938 } 1939 out(resp) 1940 default: 1941 pc.Warnf("Unknown reply code %q", token) 1942 } 1943 } 1944 1945 // This will both load all retained messages and process updates from the cluster. 1946 // 1947 // Run from various go routines (JS consumer, etc..). 1948 // No lock held on entry. 1949 func (as *mqttAccountSessionManager) processRetainedMsg(_ *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) { 1950 h, m := c.msgParts(rmsg) 1951 rm, err := mqttDecodeRetainedMessage(h, m) 1952 if err != nil { 1953 return 1954 } 1955 // If lastSeq is 0 (nothing to recover, or done doing it) and this is 1956 // from our own server, ignore. 1957 if as.rrmLastSeq == 0 && rm.Origin == as.jsa.id { 1958 return 1959 } 1960 // At this point we either recover from our own server, or process a remote retained message. 1961 seq, _, _ := ackReplyInfo(reply) 1962 1963 // Handle this retained message, no need to copy the bytes. 1964 as.handleRetainedMsg(rm.Subject, &mqttRetainedMsgRef{sseq: seq}, rm, false) 1965 1966 // If we were recovering (lastSeq > 0), then check if we are done. 1967 if as.rrmLastSeq > 0 && seq >= as.rrmLastSeq { 1968 as.rrmLastSeq = 0 1969 close(as.rrmDoneCh) 1970 as.rrmDoneCh = nil 1971 } 1972 } 1973 1974 func (as *mqttAccountSessionManager) processRetainedMsgDel(_ *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) { 1975 idHash := tokenAt(subject, 3) 1976 if idHash == _EMPTY_ || idHash == as.jsa.id { 1977 return 1978 } 1979 _, msg := c.msgParts(rmsg) 1980 if len(msg) < LEN_CR_LF { 1981 return 1982 } 1983 var drm mqttRetMsgDel 1984 if err := json.Unmarshal(msg, &drm); err != nil { 1985 return 1986 } 1987 as.handleRetainedMsgDel(drm.Subject, drm.Seq) 1988 } 1989 1990 // This will receive all JS API replies for a request to store a session record, 1991 // including the reply for our own server, which we will ignore. 1992 // This allows us to detect that some application somewhere else in the cluster 1993 // is connecting with the same client ID, and therefore we need to close the 1994 // connection that is currently using this client ID. 1995 // 1996 // Can run from various go routines (system send loop, etc..). 1997 // No lock held on entry. 1998 func (as *mqttAccountSessionManager) processSessionPersist(_ *subscription, pc *client, _ *Account, subject, _ string, rmsg []byte) { 1999 // Ignore our own responses here (they are handled elsewhere) 2000 if tokenAt(subject, mqttJSAIdTokenPos) == as.jsa.id { 2001 return 2002 } 2003 cIDHash := tokenAt(subject, mqttJSAClientIDPos) 2004 _, msg := pc.msgParts(rmsg) 2005 if len(msg) < LEN_CR_LF { 2006 return 2007 } 2008 var par = &JSPubAckResponse{} 2009 if err := json.Unmarshal(msg, par); err != nil { 2010 return 2011 } 2012 if err := par.Error; err != nil { 2013 return 2014 } 2015 as.mu.RLock() 2016 // Note that as.domainTk includes a terminal '.', so strip to compare to PubAck.Domain. 2017 dl := len(as.domainTk) 2018 if dl > 0 { 2019 dl-- 2020 } 2021 ignore := par.Domain != as.domainTk[:dl] 2022 as.mu.RUnlock() 2023 if ignore { 2024 return 2025 } 2026 2027 as.mu.Lock() 2028 defer as.mu.Unlock() 2029 sess, ok := as.sessByHash[cIDHash] 2030 if !ok { 2031 return 2032 } 2033 // If our current session's stream sequence is higher, it means that this 2034 // update is stale, so we don't do anything here. 2035 sess.mu.Lock() 2036 ignore = par.Sequence < sess.seq 2037 sess.mu.Unlock() 2038 if ignore { 2039 return 2040 } 2041 as.removeSession(sess, false) 2042 sess.mu.Lock() 2043 if ec := sess.c; ec != nil { 2044 as.addSessToFlappers(sess.id) 2045 ec.Warnf("Closing because a remote connection has started with the same client ID: %q", sess.id) 2046 // Disassociate the client from the session so that on client close, 2047 // nothing will be done with regards to cleaning up the session, 2048 // such as deleting stream, etc.. 2049 sess.c = nil 2050 // Remove in separate go routine. 2051 go ec.closeConnection(DuplicateClientID) 2052 } 2053 sess.mu.Unlock() 2054 } 2055 2056 // Adds this client ID to the flappers map, and if needed start the timer 2057 // for map cleanup. 2058 // 2059 // Lock held on entry. 2060 func (as *mqttAccountSessionManager) addSessToFlappers(clientID string) { 2061 as.flappers[clientID] = time.Now().UnixNano() 2062 if as.flapTimer == nil { 2063 as.flapTimer = time.AfterFunc(mqttFlapCleanItvl, func() { 2064 as.mu.Lock() 2065 defer as.mu.Unlock() 2066 // In case of shutdown, this will be nil 2067 if as.flapTimer == nil { 2068 return 2069 } 2070 now := time.Now().UnixNano() 2071 for cID, tm := range as.flappers { 2072 if now-tm > int64(mqttSessJailDur) { 2073 delete(as.flappers, cID) 2074 } 2075 } 2076 as.flapTimer.Reset(mqttFlapCleanItvl) 2077 }) 2078 } 2079 } 2080 2081 // Remove this client ID from the flappers map. 2082 // 2083 // Lock held on entry. 2084 func (as *mqttAccountSessionManager) removeSessFromFlappers(clientID string) { 2085 delete(as.flappers, clientID) 2086 // Do not stop/set timer to nil here. Better leave the timer run at its 2087 // regular interval and detect that there is nothing to do. The timer 2088 // will be stopped on shutdown. 2089 } 2090 2091 // Helper to create a subscription. It updates the sid and array of subscriptions. 2092 func (as *mqttAccountSessionManager) createSubscription(subject string, cb msgHandler, sid *int64, subs *[]*subscription) error { 2093 sub, err := as.jsa.c.processSub([]byte(subject), nil, []byte(strconv.FormatInt(*sid, 10)), cb, false) 2094 if err != nil { 2095 return err 2096 } 2097 *sid++ 2098 *subs = append(*subs, sub) 2099 return nil 2100 } 2101 2102 // A timer loop to cleanup up expired cached retained messages for a given MQTT account. 2103 // The closeCh is used by the caller to be able to interrupt this routine 2104 // if the rest of the initialization fails, since the quitCh is really 2105 // only used when the server shutdown. 2106 // 2107 // No lock held on entry. 2108 func (as *mqttAccountSessionManager) cleanupRetainedMessageCache(s *Server, closeCh chan struct{}) { 2109 tt := time.NewTicker(mqttRetainedCacheTTL) 2110 defer tt.Stop() 2111 for { 2112 select { 2113 case <-tt.C: 2114 // Set a limit to the number of retained messages to scan since we 2115 // lock as for it. Since the map enumeration gives random order we 2116 // should eventually clean up everything. 2117 i, maxScan := 0, 10*1000 2118 now := time.Now() 2119 as.rmsCache.Range(func(key, value interface{}) bool { 2120 rm := value.(*mqttRetainedMsg) 2121 if now.After(rm.expiresFromCache) { 2122 as.rmsCache.Delete(key) 2123 } 2124 i++ 2125 return i < maxScan 2126 }) 2127 2128 case <-closeCh: 2129 return 2130 case <-s.quitCh: 2131 return 2132 } 2133 } 2134 } 2135 2136 // Loop to send JS API requests for a given MQTT account. 2137 // The closeCh is used by the caller to be able to interrupt this routine 2138 // if the rest of the initialization fails, since the quitCh is really 2139 // only used when the server shutdown. 2140 // 2141 // No lock held on entry. 2142 func (as *mqttAccountSessionManager) sendJSAPIrequests(s *Server, c *client, accName string, closeCh chan struct{}) { 2143 var cluster string 2144 if s.JetStreamEnabled() && !as.jsa.domainSet { 2145 // Only request the own cluster when it is clear that 2146 cluster = s.cachedClusterName() 2147 } 2148 as.mu.RLock() 2149 sendq := as.jsa.sendq 2150 quitCh := as.jsa.quitCh 2151 ci := ClientInfo{Account: accName, Cluster: cluster} 2152 as.mu.RUnlock() 2153 2154 // The account session manager does not have a suhtdown API per-se, instead, 2155 // we will cleanup things when this go routine exits after detecting that the 2156 // server is shutdown or the initialization of the account manager failed. 2157 defer func() { 2158 as.mu.Lock() 2159 if as.flapTimer != nil { 2160 as.flapTimer.Stop() 2161 as.flapTimer = nil 2162 } 2163 as.mu.Unlock() 2164 }() 2165 2166 b, _ := json.Marshal(ci) 2167 hdrStart := bytes.Buffer{} 2168 hdrStart.WriteString(hdrLine) 2169 http.Header{ClientInfoHdr: []string{string(b)}}.Write(&hdrStart) 2170 hdrStart.WriteString(CR_LF) 2171 hdrStart.WriteString(CR_LF) 2172 hdrb := hdrStart.Bytes() 2173 2174 for { 2175 select { 2176 case <-sendq.ch: 2177 pmis := sendq.pop() 2178 for _, r := range pmis { 2179 var nsize int 2180 2181 msg := r.msg 2182 // If r.hdr is set to -1, it means that there is no need for any header. 2183 if r.hdr != -1 { 2184 bb := bytes.Buffer{} 2185 if r.hdr > 0 { 2186 // This means that the header has been set by the caller and is 2187 // already part of `msg`, so simply set c.pa.hdr to the given value. 2188 c.pa.hdr = r.hdr 2189 nsize = len(msg) 2190 msg = append(msg, _CRLF_...) 2191 } else { 2192 // We need the ClientInfo header, so add it here. 2193 bb.Write(hdrb) 2194 c.pa.hdr = bb.Len() 2195 bb.Write(r.msg) 2196 nsize = bb.Len() 2197 bb.WriteString(_CRLF_) 2198 msg = bb.Bytes() 2199 } 2200 c.pa.hdb = []byte(strconv.Itoa(c.pa.hdr)) 2201 } else { 2202 c.pa.hdr = -1 2203 c.pa.hdb = nil 2204 nsize = len(msg) 2205 msg = append(msg, _CRLF_...) 2206 } 2207 2208 c.pa.subject = []byte(r.subj) 2209 c.pa.reply = []byte(r.reply) 2210 c.pa.size = nsize 2211 c.pa.szb = []byte(strconv.Itoa(nsize)) 2212 2213 c.processInboundClientMsg(msg) 2214 c.flushClients(0) 2215 } 2216 sendq.recycle(&pmis) 2217 2218 case <-closeCh: 2219 return 2220 case <-quitCh: 2221 return 2222 } 2223 } 2224 } 2225 2226 // Add/Replace this message from the retained messages map. 2227 // If a message for this topic already existed, the existing record is updated 2228 // with the provided information. 2229 // Lock not held on entry. 2230 func (as *mqttAccountSessionManager) handleRetainedMsg(key string, rf *mqttRetainedMsgRef, rm *mqttRetainedMsg, copyBytesToCache bool) { 2231 as.mu.Lock() 2232 defer as.mu.Unlock() 2233 if as.retmsgs == nil { 2234 as.retmsgs = make(map[string]*mqttRetainedMsgRef) 2235 as.sl = NewSublistWithCache() 2236 } else { 2237 // Check if we already had one retained message. If so, update the existing one. 2238 if erm, exists := as.retmsgs[key]; exists { 2239 // If the new sequence is below the floor or the existing one, 2240 // then ignore the new one. 2241 if rf.sseq <= erm.sseq || rf.sseq <= erm.floor { 2242 return 2243 } 2244 // Capture existing sequence number so we can return it as the old sequence. 2245 erm.sseq = rf.sseq 2246 // Clear the floor 2247 erm.floor = 0 2248 // If sub is nil, it means that it was removed from sublist following a 2249 // network delete. So need to add it now. 2250 if erm.sub == nil { 2251 erm.sub = &subscription{subject: []byte(key)} 2252 as.sl.Insert(erm.sub) 2253 } 2254 2255 // Update the in-memory retained message cache but only for messages 2256 // that are already in the cache, i.e. have been (recently) used. 2257 as.setCachedRetainedMsg(key, rm, true, copyBytesToCache) 2258 return 2259 } 2260 } 2261 2262 rf.sub = &subscription{subject: []byte(key)} 2263 as.retmsgs[key] = rf 2264 as.sl.Insert(rf.sub) 2265 } 2266 2267 // Removes the retained message for the given `subject` if present, and returns the 2268 // stream sequence it was stored at. It will be 0 if no retained message was removed. 2269 // If a sequence is passed and not 0, then the retained message will be removed only 2270 // if the given sequence is equal or higher to what is stored. 2271 // 2272 // No lock held on entry. 2273 func (as *mqttAccountSessionManager) handleRetainedMsgDel(subject string, seq uint64) uint64 { 2274 var seqToRemove uint64 2275 as.mu.Lock() 2276 if as.retmsgs == nil { 2277 as.retmsgs = make(map[string]*mqttRetainedMsgRef) 2278 as.sl = NewSublistWithCache() 2279 } 2280 if erm, ok := as.retmsgs[subject]; ok { 2281 if as.rmsCache != nil { 2282 as.rmsCache.Delete(subject) 2283 } 2284 if erm.sub != nil { 2285 as.sl.Remove(erm.sub) 2286 erm.sub = nil 2287 } 2288 // If processing a delete request from the network, then seq will be > 0. 2289 // If that is the case and it is greater or equal to what we have, we need 2290 // to record the floor for this subject. 2291 if seq != 0 && seq >= erm.sseq { 2292 erm.sseq = 0 2293 erm.floor = seq 2294 } else if seq == 0 { 2295 delete(as.retmsgs, subject) 2296 seqToRemove = erm.sseq 2297 } 2298 } else if seq != 0 { 2299 rf := &mqttRetainedMsgRef{floor: seq} 2300 as.retmsgs[subject] = rf 2301 } 2302 as.mu.Unlock() 2303 return seqToRemove 2304 } 2305 2306 // First check if this session's client ID is already in the "locked" map, 2307 // which if it is the case means that another client is now bound to this 2308 // session and this should return an error. 2309 // If not in the "locked" map, but the client is not bound with this session, 2310 // then same error is returned. 2311 // Finally, if all checks ok, then the session's ID is added to the "locked" map. 2312 // 2313 // No lock held on entry. 2314 func (as *mqttAccountSessionManager) lockSession(sess *mqttSession, c *client) error { 2315 as.mu.Lock() 2316 defer as.mu.Unlock() 2317 var fail bool 2318 if _, fail = as.sessLocked[sess.id]; !fail { 2319 sess.mu.Lock() 2320 fail = sess.c != c 2321 sess.mu.Unlock() 2322 } 2323 if fail { 2324 return fmt.Errorf("another session is in use with client ID %q", sess.id) 2325 } 2326 as.sessLocked[sess.id] = struct{}{} 2327 return nil 2328 } 2329 2330 // Remove the session from the "locked" map. 2331 // 2332 // No lock held on entry. 2333 func (as *mqttAccountSessionManager) unlockSession(sess *mqttSession) { 2334 as.mu.Lock() 2335 delete(as.sessLocked, sess.id) 2336 as.mu.Unlock() 2337 } 2338 2339 // Simply adds the session to the various sessions maps. 2340 // The boolean `lock` indicates if this function should acquire the lock 2341 // prior to adding to the maps. 2342 // 2343 // No lock held on entry. 2344 func (as *mqttAccountSessionManager) addSession(sess *mqttSession, lock bool) { 2345 if lock { 2346 as.mu.Lock() 2347 } 2348 as.sessions[sess.id] = sess 2349 as.sessByHash[sess.idHash] = sess 2350 if lock { 2351 as.mu.Unlock() 2352 } 2353 } 2354 2355 // Simply removes the session from the various sessions maps. 2356 // The boolean `lock` indicates if this function should acquire the lock 2357 // prior to removing from the maps. 2358 // 2359 // No lock held on entry. 2360 func (as *mqttAccountSessionManager) removeSession(sess *mqttSession, lock bool) { 2361 if lock { 2362 as.mu.Lock() 2363 } 2364 delete(as.sessions, sess.id) 2365 delete(as.sessByHash, sess.idHash) 2366 if lock { 2367 as.mu.Unlock() 2368 } 2369 } 2370 2371 // Helper to set the sub's mqtt fields and possibly serialize (pre-loaded) 2372 // retained messages. 2373 // 2374 // Session lock held on entry. Acquires the subs lock and holds it for 2375 // the duration. Non-MQTT messages coming into mqttDeliverMsgCbQoS0 will be 2376 // waiting. 2377 func (sess *mqttSession) processQOS12Sub( 2378 c *client, // subscribing client. 2379 subject, sid []byte, isReserved bool, qos byte, jsDurName string, h msgHandler, // subscription parameters. 2380 ) (*subscription, error) { 2381 return sess.processSub(c, subject, sid, isReserved, qos, jsDurName, h, false, false, nil, false, nil) 2382 } 2383 2384 func (sess *mqttSession) processSub( 2385 c *client, // subscribing client. 2386 subject, sid []byte, isReserved bool, qos byte, jsDurName string, h msgHandler, // subscription parameters. 2387 initShadow bool, // do we need to scan for shadow subscriptions? (not for QOS1+) 2388 serializeRMS bool, // do we need to serialize RMS? 2389 rms map[string]*mqttRetainedMsg, // preloaded rms (can be empty, or missing items if errors) 2390 trace bool, // trace serialized retained messages in the log? 2391 as *mqttAccountSessionManager, // needed only for rms serialization. 2392 ) (*subscription, error) { 2393 start := time.Now() 2394 defer func() { 2395 elapsed := time.Since(start) 2396 if elapsed > mqttProcessSubTooLong { 2397 c.Warnf("Took too long to process subscription for %q: %v", subject, elapsed) 2398 } 2399 }() 2400 2401 // Hold subsMu to prevent QOS0 messages callback from doing anything until 2402 // the (MQTT) sub is initialized. 2403 sess.subsMu.Lock() 2404 defer sess.subsMu.Unlock() 2405 2406 sub, err := c.processSub(subject, nil, sid, h, false) 2407 if err != nil { 2408 // c.processSub already called c.Errorf(), so no need here. 2409 return nil, err 2410 } 2411 subs := []*subscription{sub} 2412 if initShadow { 2413 subs = append(subs, sub.shadow...) 2414 } 2415 for _, ss := range subs { 2416 if ss.mqtt == nil { 2417 // reserved is set only once and once the subscription has been 2418 // created it can be considered immutable. 2419 ss.mqtt = &mqttSub{ 2420 reserved: isReserved, 2421 } 2422 } 2423 // QOS and jsDurName can be changed on an existing subscription, so 2424 // accessing it later requires a lock. 2425 ss.mqtt.qos = qos 2426 ss.mqtt.jsDur = jsDurName 2427 } 2428 2429 if len(rms) > 0 { 2430 for _, ss := range subs { 2431 as.serializeRetainedMsgsForSub(rms, sess, c, ss, trace) 2432 } 2433 } 2434 2435 return sub, nil 2436 } 2437 2438 // Process subscriptions for the given session/client. 2439 // 2440 // When `fromSubProto` is false, it means that this is invoked from the CONNECT 2441 // protocol, when restoring subscriptions that were saved for this session. 2442 // In that case, there is no need to update the session record. 2443 // 2444 // When `fromSubProto` is true, it means that this call is invoked from the 2445 // processing of the SUBSCRIBE protocol, which means that the session needs to 2446 // be updated. It also means that if a subscription on same subject with same 2447 // QoS already exist, we should not be recreating the subscription/JS durable, 2448 // since it was already done when processing the CONNECT protocol. 2449 // 2450 // Runs from the client's readLoop. 2451 // Lock not held on entry, but session is in the locked map. 2452 func (as *mqttAccountSessionManager) processSubs(sess *mqttSession, c *client, 2453 filters []*mqttFilter, fromSubProto, trace bool) ([]*subscription, error) { 2454 2455 c.mu.Lock() 2456 acc := c.acc 2457 c.mu.Unlock() 2458 2459 // Helper to determine if we need to create a separate top-level 2460 // subscription for a wildcard. 2461 fwc := func(subject string) (bool, string, string) { 2462 if !mqttNeedSubForLevelUp(subject) { 2463 return false, _EMPTY_, _EMPTY_ 2464 } 2465 // Say subject is "foo.>", remove the ".>" so that it becomes "foo" 2466 fwcsubject := subject[:len(subject)-2] 2467 // Change the sid to "foo fwc" 2468 fwcsid := fwcsubject + mqttMultiLevelSidSuffix 2469 2470 return true, fwcsubject, fwcsid 2471 } 2472 2473 rmSubjects := map[string]struct{}{} 2474 // Preload retained messages for all requested subscriptions. Also, since 2475 // it's the first iteration over the filter list, do some cleanup. 2476 for _, f := range filters { 2477 if f.qos > 2 { 2478 f.qos = 2 2479 } 2480 if c.mqtt.downgradeQoS2Sub && f.qos == 2 { 2481 c.Warnf("Downgrading subscription QoS2 to QoS1 for %q, as configured", f.filter) 2482 f.qos = 1 2483 } 2484 2485 // Do not allow subscribing to our internal subjects. 2486 // 2487 // TODO: (levb: not sure why since one can subscribe to `#` and it'll 2488 // include everything; I guess this would discourage? Otherwise another 2489 // candidate for DO NOT DELIVER prefix list). 2490 if strings.HasPrefix(f.filter, mqttSubPrefix) { 2491 f.qos = mqttSubAckFailure 2492 continue 2493 } 2494 2495 if f.qos == 2 { 2496 if err := sess.ensurePubRelConsumerSubscription(c); err != nil { 2497 c.Errorf("failed to initialize PUBREL processing: %v", err) 2498 f.qos = mqttSubAckFailure 2499 continue 2500 } 2501 } 2502 2503 // Find retained messages. 2504 if fromSubProto { 2505 addRMSubjects := func(subject string) error { 2506 sub := &subscription{ 2507 client: c, 2508 subject: []byte(subject), 2509 sid: []byte(subject), 2510 } 2511 if err := c.addShadowSubscriptions(acc, sub, false); err != nil { 2512 return err 2513 } 2514 2515 for _, sub := range append([]*subscription{sub}, sub.shadow...) { 2516 as.addRetainedSubjectsForSubject(rmSubjects, bytesToString(sub.subject)) 2517 for _, ss := range sub.shadow { 2518 as.addRetainedSubjectsForSubject(rmSubjects, bytesToString(ss.subject)) 2519 } 2520 } 2521 return nil 2522 } 2523 2524 if err := addRMSubjects(f.filter); err != nil { 2525 f.qos = mqttSubAckFailure 2526 continue 2527 } 2528 if need, subject, _ := fwc(f.filter); need { 2529 if err := addRMSubjects(subject); err != nil { 2530 f.qos = mqttSubAckFailure 2531 continue 2532 } 2533 } 2534 } 2535 } 2536 2537 serializeRMS := len(rmSubjects) > 0 2538 var rms map[string]*mqttRetainedMsg 2539 if serializeRMS { 2540 // Make the best effort to load retained messages. We will identify 2541 // errors in the next pass. 2542 rms = as.loadRetainedMessages(rmSubjects, c) 2543 } 2544 2545 // Small helper to add the consumer config to the session. 2546 addJSConsToSess := func(sid string, cc *ConsumerConfig) { 2547 if cc == nil { 2548 return 2549 } 2550 if sess.cons == nil { 2551 sess.cons = make(map[string]*ConsumerConfig) 2552 } 2553 sess.cons[sid] = cc 2554 } 2555 2556 var err error 2557 subs := make([]*subscription, 0, len(filters)) 2558 for _, f := range filters { 2559 // Skip what's already been identified as a failure. 2560 if f.qos == mqttSubAckFailure { 2561 continue 2562 } 2563 subject := f.filter 2564 bsubject := []byte(subject) 2565 sid := subject 2566 bsid := bsubject 2567 isReserved := isMQTTReservedSubscription(subject) 2568 2569 var jscons *ConsumerConfig 2570 var jssub *subscription 2571 2572 // Note that if a subscription already exists on this subject, the 2573 // existing sub is returned. Need to update the qos. 2574 var sub *subscription 2575 var err error 2576 2577 const processShadowSubs = true 2578 2579 as.mu.Lock() 2580 sess.mu.Lock() 2581 sub, err = sess.processSub(c, 2582 bsubject, bsid, isReserved, f.qos, // main subject 2583 _EMPTY_, mqttDeliverMsgCbQoS0, // no jsDur for QOS0 2584 processShadowSubs, 2585 serializeRMS, rms, trace, as) 2586 sess.mu.Unlock() 2587 as.mu.Unlock() 2588 2589 if err != nil { 2590 f.qos = mqttSubAckFailure 2591 sess.cleanupFailedSub(c, sub, jscons, jssub) 2592 continue 2593 } 2594 2595 // This will create (if not already exist) a JS consumer for 2596 // subscriptions of QoS >= 1. But if a JS consumer already exists and 2597 // the subscription for same subject is now a QoS==0, then the JS 2598 // consumer will be deleted. 2599 jscons, jssub, err = sess.processJSConsumer(c, subject, sid, f.qos, fromSubProto) 2600 if err != nil { 2601 f.qos = mqttSubAckFailure 2602 sess.cleanupFailedSub(c, sub, jscons, jssub) 2603 continue 2604 } 2605 2606 // Process the wildcard subject if needed. 2607 if need, fwcsubject, fwcsid := fwc(subject); need { 2608 var fwjscons *ConsumerConfig 2609 var fwjssub *subscription 2610 var fwcsub *subscription 2611 2612 // See note above about existing subscription. 2613 as.mu.Lock() 2614 sess.mu.Lock() 2615 fwcsub, err = sess.processSub(c, 2616 []byte(fwcsubject), []byte(fwcsid), isReserved, f.qos, // FWC (top-level wildcard) subject 2617 _EMPTY_, mqttDeliverMsgCbQoS0, // no jsDur for QOS0 2618 processShadowSubs, 2619 serializeRMS, rms, trace, as) 2620 sess.mu.Unlock() 2621 as.mu.Unlock() 2622 if err != nil { 2623 // c.processSub already called c.Errorf(), so no need here. 2624 f.qos = mqttSubAckFailure 2625 sess.cleanupFailedSub(c, sub, jscons, jssub) 2626 continue 2627 } 2628 2629 fwjscons, fwjssub, err = sess.processJSConsumer(c, fwcsubject, fwcsid, f.qos, fromSubProto) 2630 if err != nil { 2631 // c.processSub already called c.Errorf(), so no need here. 2632 f.qos = mqttSubAckFailure 2633 sess.cleanupFailedSub(c, sub, jscons, jssub) 2634 sess.cleanupFailedSub(c, fwcsub, fwjscons, fwjssub) 2635 continue 2636 } 2637 2638 subs = append(subs, fwcsub) 2639 addJSConsToSess(fwcsid, fwjscons) 2640 } 2641 2642 subs = append(subs, sub) 2643 addJSConsToSess(sid, jscons) 2644 } 2645 2646 if fromSubProto { 2647 err = sess.update(filters, true) 2648 } 2649 2650 return subs, err 2651 } 2652 2653 // Retained publish messages matching this subscription are serialized in the 2654 // subscription's `prm` mqtt writer. This buffer will be queued for outbound 2655 // after the subscription is processed and SUBACK is sent or possibly when 2656 // server processes an incoming published message matching the newly 2657 // registered subscription. 2658 // 2659 // Runs from the client's readLoop. 2660 // Account session manager lock held on entry. 2661 // Session lock held on entry. 2662 func (as *mqttAccountSessionManager) serializeRetainedMsgsForSub(rms map[string]*mqttRetainedMsg, sess *mqttSession, c *client, sub *subscription, trace bool) error { 2663 if len(as.retmsgs) == 0 || len(rms) == 0 { 2664 return nil 2665 } 2666 result := as.sl.ReverseMatch(string(sub.subject)) 2667 if len(result.psubs) == 0 { 2668 return nil 2669 } 2670 toTrace := []mqttPublish{} 2671 for _, psub := range result.psubs { 2672 2673 rm := rms[string(psub.subject)] 2674 if rm == nil { 2675 // This should not happen since we pre-load messages into rms before 2676 // calling serialize. 2677 continue 2678 } 2679 var pi uint16 2680 qos := mqttGetQoS(rm.Flags) 2681 if qos > sub.mqtt.qos { 2682 qos = sub.mqtt.qos 2683 } 2684 if c.mqtt.rejectQoS2Pub && qos == 2 { 2685 c.Warnf("Rejecting retained message with QoS2 for subscription %q, as configured", sub.subject) 2686 continue 2687 } 2688 if qos > 0 { 2689 pi = sess.trackPublishRetained() 2690 2691 // If we failed to get a PI for this message, send it as a QoS0, the 2692 // best we can do? 2693 if pi == 0 { 2694 qos = 0 2695 } 2696 } 2697 2698 // Need to use the subject for the retained message, not the `sub` subject. 2699 // We can find the published retained message in rm.sub.subject. 2700 // Set the RETAIN flag: [MQTT-3.3.1-8]. 2701 flags, headerBytes := mqttMakePublishHeader(pi, qos, false, true, []byte(rm.Topic), len(rm.Msg)) 2702 c.mu.Lock() 2703 sub.mqtt.prm = append(sub.mqtt.prm, headerBytes, rm.Msg) 2704 c.mu.Unlock() 2705 if trace { 2706 toTrace = append(toTrace, mqttPublish{ 2707 topic: []byte(rm.Topic), 2708 flags: flags, 2709 pi: pi, 2710 sz: len(rm.Msg), 2711 }) 2712 } 2713 } 2714 for _, pp := range toTrace { 2715 c.traceOutOp("PUBLISH", []byte(mqttPubTrace(&pp))) 2716 } 2717 return nil 2718 } 2719 2720 // Appends the stored message subjects for all retained message records that 2721 // match the given subscription's `subject` (which could have wildcards). 2722 // 2723 // Account session manager NOT lock held on entry. 2724 func (as *mqttAccountSessionManager) addRetainedSubjectsForSubject(list map[string]struct{}, topSubject string) bool { 2725 as.mu.RLock() 2726 if len(as.retmsgs) == 0 { 2727 as.mu.RUnlock() 2728 return false 2729 } 2730 result := as.sl.ReverseMatch(topSubject) 2731 as.mu.RUnlock() 2732 2733 added := false 2734 for _, sub := range result.psubs { 2735 subject := string(sub.subject) 2736 if _, ok := list[subject]; ok { 2737 continue 2738 } 2739 list[subject] = struct{}{} 2740 added = true 2741 } 2742 2743 return added 2744 } 2745 2746 type warner interface { 2747 Warnf(format string, v ...any) 2748 } 2749 2750 // Loads a list of retained messages given a list of stored message subjects. 2751 func (as *mqttAccountSessionManager) loadRetainedMessages(subjects map[string]struct{}, w warner) map[string]*mqttRetainedMsg { 2752 rms := make(map[string]*mqttRetainedMsg, len(subjects)) 2753 ss := []string{} 2754 for s := range subjects { 2755 if rm := as.getCachedRetainedMsg(s); rm != nil { 2756 rms[s] = rm 2757 } else { 2758 ss = append(ss, mqttRetainedMsgsStreamSubject+s) 2759 } 2760 } 2761 2762 if len(ss) == 0 { 2763 return rms 2764 } 2765 2766 results, err := as.jsa.loadLastMsgForMulti(mqttRetainedMsgsStreamName, ss) 2767 // If an error occurred, warn, but then proceed with what we got. 2768 if err != nil { 2769 w.Warnf("error loading retained messages: %v", err) 2770 } 2771 for i, result := range results { 2772 if result == nil { 2773 continue // skip requests that timed out 2774 } 2775 if result.ToError() != nil { 2776 w.Warnf("failed to load retained message for subject %q: %v", ss[i], err) 2777 continue 2778 } 2779 rm, err := mqttDecodeRetainedMessage(result.Message.Header, result.Message.Data) 2780 if err != nil { 2781 w.Warnf("failed to decode retained message for subject %q: %v", ss[i], err) 2782 continue 2783 } 2784 2785 // Add the loaded retained message to the cache, and to the results map. 2786 key := ss[i][len(mqttRetainedMsgsStreamSubject):] 2787 as.setCachedRetainedMsg(key, rm, false, false) 2788 rms[key] = rm 2789 } 2790 return rms 2791 } 2792 2793 // Composes a NATS message for a storeable mqttRetainedMsg. 2794 func mqttEncodeRetainedMessage(rm *mqttRetainedMsg) (natsMsg []byte, headerLen int) { 2795 // No need to encode the subject, we can restore it from topic. 2796 l := len(hdrLine) 2797 l += len(mqttNatsRetainedMessageTopic) + 1 + len(rm.Topic) + 2 // 1 byte for ':', 2 bytes for CRLF 2798 if rm.Origin != _EMPTY_ { 2799 l += len(mqttNatsRetainedMessageOrigin) + 1 + len(rm.Origin) + 2 // 1 byte for ':', 2 bytes for CRLF 2800 } 2801 if rm.Source != _EMPTY_ { 2802 l += len(mqttNatsRetainedMessageSource) + 1 + len(rm.Source) + 2 // 1 byte for ':', 2 bytes for CRLF 2803 } 2804 l += len(mqttNatsRetainedMessageFlags) + 1 + 2 + 2 // 1 byte for ':', 2 bytes for the flags, 2 bytes for CRLF 2805 l += 2 // 2 bytes for the extra CRLF after the header 2806 l += len(rm.Msg) 2807 2808 buf := bytes.NewBuffer(make([]byte, 0, l)) 2809 2810 buf.WriteString(hdrLine) 2811 2812 buf.WriteString(mqttNatsRetainedMessageTopic) 2813 buf.WriteByte(':') 2814 buf.WriteString(rm.Topic) 2815 buf.WriteString(_CRLF_) 2816 2817 buf.WriteString(mqttNatsRetainedMessageFlags) 2818 buf.WriteByte(':') 2819 buf.WriteString(strconv.FormatUint(uint64(rm.Flags), 16)) 2820 buf.WriteString(_CRLF_) 2821 2822 if rm.Origin != _EMPTY_ { 2823 buf.WriteString(mqttNatsRetainedMessageOrigin) 2824 buf.WriteByte(':') 2825 buf.WriteString(rm.Origin) 2826 buf.WriteString(_CRLF_) 2827 } 2828 if rm.Source != _EMPTY_ { 2829 buf.WriteString(mqttNatsRetainedMessageSource) 2830 buf.WriteByte(':') 2831 buf.WriteString(rm.Source) 2832 buf.WriteString(_CRLF_) 2833 } 2834 2835 // End of header, finalize 2836 buf.WriteString(_CRLF_) 2837 headerLen = buf.Len() 2838 buf.Write(rm.Msg) 2839 return buf.Bytes(), headerLen 2840 } 2841 2842 func mqttDecodeRetainedMessage(h, m []byte) (*mqttRetainedMsg, error) { 2843 fHeader := getHeader(mqttNatsRetainedMessageFlags, h) 2844 if len(fHeader) > 0 { 2845 flags, err := strconv.ParseUint(string(fHeader), 16, 8) 2846 if err != nil { 2847 return nil, fmt.Errorf("invalid retained message flags: %v", err) 2848 } 2849 topic := getHeader(mqttNatsRetainedMessageTopic, h) 2850 subj, _ := mqttToNATSSubjectConversion(topic, false) 2851 return &mqttRetainedMsg{ 2852 Flags: byte(flags), 2853 Subject: string(subj), 2854 Topic: string(topic), 2855 Origin: string(getHeader(mqttNatsRetainedMessageOrigin, h)), 2856 Source: string(getHeader(mqttNatsRetainedMessageSource, h)), 2857 Msg: m, 2858 }, nil 2859 } else { 2860 var rm mqttRetainedMsg 2861 if err := json.Unmarshal(m, &rm); err != nil { 2862 return nil, err 2863 } 2864 return &rm, nil 2865 } 2866 } 2867 2868 // Creates the session stream (limit msgs of 1) for this client ID if it does 2869 // not already exist. If it exists, recover the single record to rebuild the 2870 // state of the session. If there is a session record but this session is not 2871 // registered in the runtime of this server, then a request is made to the 2872 // owner to close the client associated with this session since specification 2873 // [MQTT-3.1.4-2] specifies that if the ClientId represents a Client already 2874 // connected to the Server then the Server MUST disconnect the existing client. 2875 // 2876 // Runs from the client's readLoop. 2877 // Lock not held on entry, but session is in the locked map. 2878 func (as *mqttAccountSessionManager) createOrRestoreSession(clientID string, opts *Options) (*mqttSession, bool, error) { 2879 jsa := &as.jsa 2880 formatError := func(errTxt string, err error) (*mqttSession, bool, error) { 2881 accName := jsa.c.acc.GetName() 2882 return nil, false, fmt.Errorf("%s for account %q, session %q: %v", errTxt, accName, clientID, err) 2883 } 2884 2885 hash := getHash(clientID) 2886 smsg, err := jsa.loadSessionMsg(as.domainTk, hash) 2887 if err != nil { 2888 if isErrorOtherThan(err, JSNoMessageFoundErr) { 2889 return formatError("loading session record", err) 2890 } 2891 // Message not found, so reate the session... 2892 // Create a session and indicate that this session did not exist. 2893 sess := mqttSessionCreate(jsa, clientID, hash, 0, opts) 2894 sess.domainTk = as.domainTk 2895 return sess, false, nil 2896 } 2897 // We need to recover the existing record now. 2898 ps := &mqttPersistedSession{} 2899 if err := json.Unmarshal(smsg.Data, ps); err != nil { 2900 return formatError(fmt.Sprintf("unmarshal of session record at sequence %v", smsg.Sequence), err) 2901 } 2902 2903 // Restore this session (even if we don't own it), the caller will do the right thing. 2904 sess := mqttSessionCreate(jsa, clientID, hash, smsg.Sequence, opts) 2905 sess.domainTk = as.domainTk 2906 sess.clean = ps.Clean 2907 sess.subs = ps.Subs 2908 sess.cons = ps.Cons 2909 sess.pubRelConsumer = ps.PubRel 2910 as.addSession(sess, true) 2911 return sess, true, nil 2912 } 2913 2914 // Sends a request to delete a message, but does not wait for the response. 2915 // 2916 // No lock held on entry. 2917 func (as *mqttAccountSessionManager) deleteRetainedMsg(seq uint64) { 2918 as.jsa.deleteMsg(mqttRetainedMsgsStreamName, seq, false) 2919 } 2920 2921 // Sends a message indicating that a retained message on a given subject and stream sequence 2922 // is being removed. 2923 func (as *mqttAccountSessionManager) notifyRetainedMsgDeleted(subject string, seq uint64) { 2924 req := mqttRetMsgDel{ 2925 Subject: subject, 2926 Seq: seq, 2927 } 2928 b, _ := json.Marshal(&req) 2929 jsa := &as.jsa 2930 jsa.sendq.push(&mqttJSPubMsg{ 2931 subj: jsa.rplyr + mqttJSARetainedMsgDel, 2932 msg: b, 2933 }) 2934 } 2935 2936 func (as *mqttAccountSessionManager) transferUniqueSessStreamsToMuxed(log *Server) { 2937 // Set retry to true, will be set to false on success. 2938 retry := true 2939 defer func() { 2940 if retry { 2941 next := mqttDefaultTransferRetry 2942 log.Warnf("Failed to transfer all MQTT session streams, will try again in %v", next) 2943 time.AfterFunc(next, func() { as.transferUniqueSessStreamsToMuxed(log) }) 2944 } 2945 }() 2946 2947 jsa := &as.jsa 2948 sni, err := jsa.newRequestEx(mqttJSAStreamNames, JSApiStreams, _EMPTY_, 0, nil, 5*time.Second) 2949 if err != nil { 2950 log.Errorf("Unable to transfer MQTT session streams: %v", err) 2951 return 2952 } 2953 snames := sni.(*JSApiStreamNamesResponse) 2954 if snames.Error != nil { 2955 log.Errorf("Unable to transfer MQTT session streams: %v", snames.ToError()) 2956 return 2957 } 2958 var oldMQTTSessStreams []string 2959 for _, sn := range snames.Streams { 2960 if strings.HasPrefix(sn, mqttSessionsStreamNamePrefix) { 2961 oldMQTTSessStreams = append(oldMQTTSessStreams, sn) 2962 } 2963 } 2964 ns := len(oldMQTTSessStreams) 2965 if ns == 0 { 2966 // Nothing to do 2967 retry = false 2968 return 2969 } 2970 log.Noticef("Transferring %v MQTT session streams...", ns) 2971 for _, sn := range oldMQTTSessStreams { 2972 log.Noticef(" Transferring stream %q to %q", sn, mqttSessStreamName) 2973 smsg, err := jsa.loadLastMsgFor(sn, sn) 2974 if err != nil { 2975 log.Errorf(" Unable to load session record: %v", err) 2976 return 2977 } 2978 ps := &mqttPersistedSession{} 2979 if err := json.Unmarshal(smsg.Data, ps); err != nil { 2980 log.Warnf(" Unable to unmarshal the content of this stream, may not be a legitimate MQTT session stream, skipping") 2981 continue 2982 } 2983 // Store record to MQTT session stream 2984 if _, err := jsa.storeSessionMsg(as.domainTk, getHash(ps.ID), 0, smsg.Data); err != nil { 2985 log.Errorf(" Unable to transfer the session record: %v", err) 2986 return 2987 } 2988 jsa.deleteStream(sn) 2989 } 2990 log.Noticef("Transfer of %v MQTT session streams done!", ns) 2991 retry = false 2992 } 2993 2994 func (as *mqttAccountSessionManager) transferRetainedToPerKeySubjectStream(log *Server) error { 2995 jsa := &as.jsa 2996 var processed int 2997 var transferred int 2998 2999 start := time.Now() 3000 deadline := start.Add(mqttRetainedTransferTimeout) 3001 for { 3002 // Try and look up messages on the original undivided "$MQTT.rmsgs" subject. 3003 // If nothing is returned here, we assume to have migrated all old messages. 3004 smsg, err := jsa.loadNextMsgFor(mqttRetainedMsgsStreamName, "$MQTT.rmsgs") 3005 if IsNatsErr(err, JSNoMessageFoundErr) { 3006 // We've ran out of messages to transfer, done. 3007 break 3008 } 3009 if err != nil { 3010 log.Warnf(" Unable to transfer a retained message: failed to load from '$MQTT.rmsgs': %s", err) 3011 return err 3012 } 3013 3014 // Unmarshal the message so that we can obtain the subject name. Do not 3015 // use mqttDecodeRetainedMessage() here because these messages are from 3016 // older versions, and contain the full JSON encoding in payload. 3017 var rmsg mqttRetainedMsg 3018 if err = json.Unmarshal(smsg.Data, &rmsg); err == nil { 3019 // Store the message again, this time with the new per-key subject. 3020 subject := mqttRetainedMsgsStreamSubject + rmsg.Subject 3021 if _, err = jsa.storeMsg(subject, 0, smsg.Data); err != nil { 3022 log.Errorf(" Unable to transfer the retained message with sequence %d: %v", smsg.Sequence, err) 3023 } 3024 transferred++ 3025 } else { 3026 log.Warnf(" Unable to unmarshal retained message with sequence %d, skipping", smsg.Sequence) 3027 } 3028 3029 // Delete the original message. 3030 if err := jsa.deleteMsg(mqttRetainedMsgsStreamName, smsg.Sequence, true); err != nil { 3031 log.Errorf(" Unable to clean up the retained message with sequence %d: %v", smsg.Sequence, err) 3032 return err 3033 } 3034 processed++ 3035 3036 now := time.Now() 3037 if now.After(deadline) { 3038 err := fmt.Errorf("timed out while transferring retained messages from '$MQTT.rmsgs' after %v, %d processed, %d successfully transferred", now.Sub(start), processed, transferred) 3039 log.Noticef(err.Error()) 3040 return err 3041 } 3042 } 3043 if processed > 0 { 3044 log.Noticef("Processed %d messages from '$MQTT.rmsgs', successfully transferred %d in %v", processed, transferred, time.Since(start)) 3045 } else { 3046 log.Debugf("No messages found to transfer from '$MQTT.rmsgs'") 3047 } 3048 return nil 3049 } 3050 3051 func (as *mqttAccountSessionManager) getCachedRetainedMsg(subject string) *mqttRetainedMsg { 3052 if as.rmsCache == nil { 3053 return nil 3054 } 3055 v, ok := as.rmsCache.Load(subject) 3056 if !ok { 3057 return nil 3058 } 3059 rm := v.(*mqttRetainedMsg) 3060 if rm.expiresFromCache.Before(time.Now()) { 3061 as.rmsCache.Delete(subject) 3062 return nil 3063 } 3064 return rm 3065 } 3066 3067 func (as *mqttAccountSessionManager) setCachedRetainedMsg(subject string, rm *mqttRetainedMsg, onlyReplace bool, copyBytesToCache bool) { 3068 if as.rmsCache == nil || rm == nil { 3069 return 3070 } 3071 rm.expiresFromCache = time.Now().Add(mqttRetainedCacheTTL) 3072 if onlyReplace { 3073 if _, ok := as.rmsCache.Load(subject); !ok { 3074 return 3075 } 3076 } 3077 if copyBytesToCache { 3078 rm.Msg = copyBytes(rm.Msg) 3079 } 3080 as.rmsCache.Store(subject, rm) 3081 } 3082 3083 ////////////////////////////////////////////////////////////////////////////// 3084 // 3085 // MQTT session related functions 3086 // 3087 ////////////////////////////////////////////////////////////////////////////// 3088 3089 // Returns a new mqttSession object with max ack pending set based on 3090 // option or use mqttDefaultMaxAckPending if no option set. 3091 func mqttSessionCreate(jsa *mqttJSA, id, idHash string, seq uint64, opts *Options) *mqttSession { 3092 maxp := opts.MQTT.MaxAckPending 3093 if maxp == 0 { 3094 maxp = mqttDefaultMaxAckPending 3095 } 3096 3097 return &mqttSession{ 3098 jsa: jsa, 3099 id: id, 3100 idHash: idHash, 3101 seq: seq, 3102 maxp: maxp, 3103 pubRelSubject: mqttPubRelSubjectPrefix + idHash, 3104 pubRelDeliverySubject: mqttPubRelDeliverySubjectPrefix + idHash, 3105 pubRelDeliverySubjectB: []byte(mqttPubRelDeliverySubjectPrefix + idHash), 3106 } 3107 } 3108 3109 // Persists a session. Note that if the session's current client does not match 3110 // the given client, nothing is done. 3111 // 3112 // Lock not held on entry. 3113 func (sess *mqttSession) save() error { 3114 sess.mu.Lock() 3115 ps := mqttPersistedSession{ 3116 Origin: sess.jsa.id, 3117 ID: sess.id, 3118 Clean: sess.clean, 3119 Subs: sess.subs, 3120 Cons: sess.cons, 3121 PubRel: sess.pubRelConsumer, 3122 } 3123 b, _ := json.Marshal(&ps) 3124 3125 domainTk, cidHash := sess.domainTk, sess.idHash 3126 seq := sess.seq 3127 sess.mu.Unlock() 3128 3129 var hdr int 3130 if seq != 0 { 3131 bb := bytes.Buffer{} 3132 bb.WriteString(hdrLine) 3133 bb.WriteString(JSExpectedLastSubjSeq) 3134 bb.WriteString(":") 3135 bb.WriteString(strconv.FormatInt(int64(seq), 10)) 3136 bb.WriteString(CR_LF) 3137 bb.WriteString(CR_LF) 3138 hdr = bb.Len() 3139 bb.Write(b) 3140 b = bb.Bytes() 3141 } 3142 3143 resp, err := sess.jsa.storeSessionMsg(domainTk, cidHash, hdr, b) 3144 if err != nil { 3145 return fmt.Errorf("unable to persist session %q (seq=%v): %v", ps.ID, seq, err) 3146 } 3147 sess.mu.Lock() 3148 sess.seq = resp.Sequence 3149 sess.mu.Unlock() 3150 return nil 3151 } 3152 3153 // Clear the session. 3154 // 3155 // Runs from the client's readLoop. 3156 // Lock not held on entry, but session is in the locked map. 3157 func (sess *mqttSession) clear() error { 3158 var durs []string 3159 var pubRelDur string 3160 3161 sess.mu.Lock() 3162 id := sess.id 3163 seq := sess.seq 3164 if l := len(sess.cons); l > 0 { 3165 durs = make([]string, 0, l) 3166 } 3167 for sid, cc := range sess.cons { 3168 delete(sess.cons, sid) 3169 durs = append(durs, cc.Durable) 3170 } 3171 if sess.pubRelConsumer != nil { 3172 pubRelDur = sess.pubRelConsumer.Durable 3173 } 3174 3175 sess.subs = nil 3176 sess.pendingPublish = nil 3177 sess.pendingPubRel = nil 3178 sess.cpending = nil 3179 sess.pubRelConsumer = nil 3180 sess.seq = 0 3181 sess.tmaxack = 0 3182 sess.mu.Unlock() 3183 3184 for _, dur := range durs { 3185 if _, err := sess.jsa.deleteConsumer(mqttStreamName, dur); isErrorOtherThan(err, JSConsumerNotFoundErr) { 3186 return fmt.Errorf("unable to delete consumer %q for session %q: %v", dur, sess.id, err) 3187 } 3188 } 3189 if pubRelDur != _EMPTY_ { 3190 _, err := sess.jsa.deleteConsumer(mqttOutStreamName, pubRelDur) 3191 if isErrorOtherThan(err, JSConsumerNotFoundErr) { 3192 return fmt.Errorf("unable to delete consumer %q for session %q: %v", pubRelDur, sess.id, err) 3193 } 3194 } 3195 3196 if seq > 0 { 3197 err := sess.jsa.deleteMsg(mqttSessStreamName, seq, true) 3198 // Ignore the various errors indicating that the message (or sequence) 3199 // is already deleted, can happen in a cluster. 3200 if isErrorOtherThan(err, JSSequenceNotFoundErrF) { 3201 if isErrorOtherThan(err, JSStreamMsgDeleteFailedF) || !strings.Contains(err.Error(), ErrStoreMsgNotFound.Error()) { 3202 return fmt.Errorf("unable to delete session %q record at sequence %v: %v", id, seq, err) 3203 } 3204 } 3205 } 3206 return nil 3207 } 3208 3209 // This will update the session record for this client in the account's MQTT 3210 // sessions stream if the session had any change in the subscriptions. 3211 // 3212 // Runs from the client's readLoop. 3213 // Lock not held on entry, but session is in the locked map. 3214 func (sess *mqttSession) update(filters []*mqttFilter, add bool) error { 3215 // Evaluate if we need to persist anything. 3216 var needUpdate bool 3217 for _, f := range filters { 3218 if add { 3219 if f.qos == mqttSubAckFailure { 3220 continue 3221 } 3222 if qos, ok := sess.subs[f.filter]; !ok || qos != f.qos { 3223 if sess.subs == nil { 3224 sess.subs = make(map[string]byte) 3225 } 3226 sess.subs[f.filter] = f.qos 3227 needUpdate = true 3228 } 3229 } else { 3230 if _, ok := sess.subs[f.filter]; ok { 3231 delete(sess.subs, f.filter) 3232 needUpdate = true 3233 } 3234 } 3235 } 3236 var err error 3237 if needUpdate { 3238 err = sess.save() 3239 } 3240 return err 3241 } 3242 3243 func (sess *mqttSession) bumpPI() uint16 { 3244 var avail bool 3245 next := sess.last_pi 3246 for i := 0; i < 0xFFFF; i++ { 3247 next++ 3248 if next == 0 { 3249 next = 1 3250 } 3251 3252 _, usedInPublish := sess.pendingPublish[next] 3253 _, usedInPubRel := sess.pendingPubRel[next] 3254 if !usedInPublish && !usedInPubRel { 3255 sess.last_pi = next 3256 avail = true 3257 break 3258 } 3259 } 3260 if !avail { 3261 return 0 3262 } 3263 return sess.last_pi 3264 } 3265 3266 // trackPublishRetained is invoked when a retained (QoS) message is published. 3267 // It need a new PI to be allocated, so we add it to the pendingPublish map, 3268 // with an empty value. Since cpending (not pending) is used to serialize the PI 3269 // mappings, we need to add this PI there as well. Make a unique key by using 3270 // mqttRetainedMsgsStreamName for the durable name, and PI for sseq. 3271 // 3272 // Lock held on entry 3273 func (sess *mqttSession) trackPublishRetained() uint16 { 3274 // Make sure we initialize the tracking maps. 3275 if sess.pendingPublish == nil { 3276 sess.pendingPublish = make(map[uint16]*mqttPending) 3277 } 3278 if sess.cpending == nil { 3279 sess.cpending = make(map[string]map[uint64]uint16) 3280 } 3281 3282 pi := sess.bumpPI() 3283 if pi == 0 { 3284 return 0 3285 } 3286 sess.pendingPublish[pi] = &mqttPending{} 3287 3288 return pi 3289 } 3290 3291 // trackPublish is invoked when a (QoS) PUBLISH message is to be delivered. It 3292 // detects an untracked (new) message based on its sequence extracted from its 3293 // delivery-time jsAckSubject, and adds it to the tracking maps. Returns a PI to 3294 // use for the message (new, or previously used), and whether this is a 3295 // duplicate delivery attempt. 3296 // 3297 // Lock held on entry 3298 func (sess *mqttSession) trackPublish(jsDur, jsAckSubject string) (uint16, bool) { 3299 var dup bool 3300 var pi uint16 3301 3302 if jsAckSubject == _EMPTY_ || jsDur == _EMPTY_ { 3303 return 0, false 3304 } 3305 3306 // Make sure we initialize the tracking maps. 3307 if sess.pendingPublish == nil { 3308 sess.pendingPublish = make(map[uint16]*mqttPending) 3309 } 3310 if sess.cpending == nil { 3311 sess.cpending = make(map[string]map[uint64]uint16) 3312 } 3313 3314 // Get the stream sequence and duplicate flag from the ack reply subject. 3315 sseq, _, dcount := ackReplyInfo(jsAckSubject) 3316 if dcount > 1 { 3317 dup = true 3318 } 3319 3320 var ack *mqttPending 3321 sseqToPi, ok := sess.cpending[jsDur] 3322 if !ok { 3323 sseqToPi = make(map[uint64]uint16) 3324 sess.cpending[jsDur] = sseqToPi 3325 } else { 3326 pi = sseqToPi[sseq] 3327 } 3328 3329 if pi != 0 { 3330 // There is a possible race between a PUBLISH re-delivery calling us, 3331 // and a PUBREC received already having submitting a PUBREL into JS . If 3332 // so, indicate no need for (re-)delivery by returning a PI of 0. 3333 _, usedForPubRel := sess.pendingPubRel[pi] 3334 if /*dup && */ usedForPubRel { 3335 return 0, false 3336 } 3337 3338 // We should have a pending JS ACK for this PI. 3339 ack = sess.pendingPublish[pi] 3340 } else { 3341 // sess.maxp will always have a value > 0. 3342 if len(sess.pendingPublish) >= int(sess.maxp) { 3343 // Indicate that we did not assign a packet identifier. 3344 // The caller will not send the message to the subscription 3345 // and JS will redeliver later, based on consumer's AckWait. 3346 return 0, false 3347 } 3348 3349 pi = sess.bumpPI() 3350 if pi == 0 { 3351 return 0, false 3352 } 3353 3354 sseqToPi[sseq] = pi 3355 } 3356 3357 if ack == nil { 3358 sess.pendingPublish[pi] = &mqttPending{ 3359 jsDur: jsDur, 3360 sseq: sseq, 3361 jsAckSubject: jsAckSubject, 3362 } 3363 } else { 3364 ack.jsAckSubject = jsAckSubject 3365 ack.sseq = sseq 3366 ack.jsDur = jsDur 3367 } 3368 3369 return pi, dup 3370 } 3371 3372 // Stops a PI from being tracked as a PUBLISH. It can still be in use for a 3373 // pending PUBREL. 3374 // 3375 // Lock held on entry 3376 func (sess *mqttSession) untrackPublish(pi uint16) (jsAckSubject string) { 3377 ack, ok := sess.pendingPublish[pi] 3378 if !ok { 3379 return _EMPTY_ 3380 } 3381 3382 delete(sess.pendingPublish, pi) 3383 if len(sess.pendingPublish) == 0 { 3384 sess.last_pi = 0 3385 } 3386 3387 if len(sess.cpending) != 0 && ack.jsDur != _EMPTY_ { 3388 if sseqToPi := sess.cpending[ack.jsDur]; sseqToPi != nil { 3389 delete(sseqToPi, ack.sseq) 3390 } 3391 } 3392 3393 return ack.jsAckSubject 3394 } 3395 3396 // trackPubRel is invoked in 2 cases: (a) when we receive a PUBREC and we need 3397 // to change from tracking the PI as a PUBLISH to a PUBREL; and (b) when we 3398 // attempt to deliver the PUBREL to record the JS ack subject for it. 3399 // 3400 // Lock held on entry 3401 func (sess *mqttSession) trackAsPubRel(pi uint16, jsAckSubject string) { 3402 if sess.pubRelConsumer == nil { 3403 // The cosumer MUST be set up already. 3404 return 3405 } 3406 jsDur := sess.pubRelConsumer.Durable 3407 3408 if sess.pendingPubRel == nil { 3409 sess.pendingPubRel = make(map[uint16]*mqttPending) 3410 } 3411 3412 if jsAckSubject == _EMPTY_ { 3413 sess.pendingPubRel[pi] = &mqttPending{ 3414 jsDur: jsDur, 3415 } 3416 return 3417 } 3418 3419 sseq, _, _ := ackReplyInfo(jsAckSubject) 3420 3421 if sess.cpending == nil { 3422 sess.cpending = make(map[string]map[uint64]uint16) 3423 } 3424 sseqToPi := sess.cpending[jsDur] 3425 if sseqToPi == nil { 3426 sseqToPi = make(map[uint64]uint16) 3427 sess.cpending[jsDur] = sseqToPi 3428 } 3429 sseqToPi[sseq] = pi 3430 sess.pendingPubRel[pi] = &mqttPending{ 3431 jsDur: sess.pubRelConsumer.Durable, 3432 sseq: sseq, 3433 jsAckSubject: jsAckSubject, 3434 } 3435 } 3436 3437 // Stops a PI from being tracked as a PUBREL. 3438 // 3439 // Lock held on entry 3440 func (sess *mqttSession) untrackPubRel(pi uint16) (jsAckSubject string) { 3441 ack, ok := sess.pendingPubRel[pi] 3442 if !ok { 3443 return _EMPTY_ 3444 } 3445 3446 delete(sess.pendingPubRel, pi) 3447 3448 if sess.pubRelConsumer != nil && len(sess.cpending) > 0 { 3449 if sseqToPi := sess.cpending[ack.jsDur]; sseqToPi != nil { 3450 delete(sseqToPi, ack.sseq) 3451 } 3452 } 3453 3454 return ack.jsAckSubject 3455 } 3456 3457 // Sends a consumer delete request, but does not wait for response. 3458 // 3459 // Lock not held on entry. 3460 func (sess *mqttSession) deleteConsumer(cc *ConsumerConfig) { 3461 sess.mu.Lock() 3462 sess.tmaxack -= cc.MaxAckPending 3463 sess.jsa.sendq.push(&mqttJSPubMsg{subj: sess.jsa.prefixDomain(fmt.Sprintf(JSApiConsumerDeleteT, mqttStreamName, cc.Durable))}) 3464 sess.mu.Unlock() 3465 } 3466 3467 ////////////////////////////////////////////////////////////////////////////// 3468 // 3469 // CONNECT protocol related functions 3470 // 3471 ////////////////////////////////////////////////////////////////////////////// 3472 3473 // Parse the MQTT connect protocol 3474 func (c *client) mqttParseConnect(r *mqttReader, pl int, hasMappings bool) (byte, *mqttConnectProto, error) { 3475 // Protocol name 3476 proto, err := r.readBytes("protocol name", false) 3477 if err != nil { 3478 return 0, nil, err 3479 } 3480 3481 // Spec [MQTT-3.1.2-1] 3482 if !bytes.Equal(proto, mqttProtoName) { 3483 // Check proto name against v3.1 to report better error 3484 if bytes.Equal(proto, mqttOldProtoName) { 3485 return 0, nil, fmt.Errorf("older protocol %q not supported", proto) 3486 } 3487 return 0, nil, fmt.Errorf("expected connect packet with protocol name %q, got %q", mqttProtoName, proto) 3488 } 3489 3490 // Protocol level 3491 level, err := r.readByte("protocol level") 3492 if err != nil { 3493 return 0, nil, err 3494 } 3495 // Spec [MQTT-3.1.2-2] 3496 if level != mqttProtoLevel { 3497 return mqttConnAckRCUnacceptableProtocolVersion, nil, fmt.Errorf("unacceptable protocol version of %v", level) 3498 } 3499 3500 cp := &mqttConnectProto{} 3501 // Connect flags 3502 cp.flags, err = r.readByte("flags") 3503 if err != nil { 3504 return 0, nil, err 3505 } 3506 3507 // Spec [MQTT-3.1.2-3] 3508 if cp.flags&mqttConnFlagReserved != 0 { 3509 return 0, nil, errMQTTConnFlagReserved 3510 } 3511 3512 var hasWill bool 3513 wqos := (cp.flags & mqttConnFlagWillQoS) >> 3 3514 wretain := cp.flags&mqttConnFlagWillRetain != 0 3515 // Spec [MQTT-3.1.2-11] 3516 if cp.flags&mqttConnFlagWillFlag == 0 { 3517 // Spec [MQTT-3.1.2-13] 3518 if wqos != 0 { 3519 return 0, nil, fmt.Errorf("if Will flag is set to 0, Will QoS must be 0 too, got %v", wqos) 3520 } 3521 // Spec [MQTT-3.1.2-15] 3522 if wretain { 3523 return 0, nil, errMQTTWillAndRetainFlag 3524 } 3525 } else { 3526 // Spec [MQTT-3.1.2-14] 3527 if wqos == 3 { 3528 return 0, nil, fmt.Errorf("if Will flag is set to 1, Will QoS can be 0, 1 or 2, got %v", wqos) 3529 } 3530 hasWill = true 3531 } 3532 3533 if c.mqtt.rejectQoS2Pub && hasWill && wqos == 2 { 3534 return mqttConnAckRCQoS2WillRejected, nil, fmt.Errorf("server does not accept QoS2 for Will messages") 3535 } 3536 3537 // Spec [MQTT-3.1.2-19] 3538 hasUser := cp.flags&mqttConnFlagUsernameFlag != 0 3539 // Spec [MQTT-3.1.2-21] 3540 hasPassword := cp.flags&mqttConnFlagPasswordFlag != 0 3541 // Spec [MQTT-3.1.2-22] 3542 if !hasUser && hasPassword { 3543 return 0, nil, errMQTTPasswordFlagAndNoUser 3544 } 3545 3546 // Keep alive 3547 var ka uint16 3548 ka, err = r.readUint16("keep alive") 3549 if err != nil { 3550 return 0, nil, err 3551 } 3552 // Spec [MQTT-3.1.2-24] 3553 if ka > 0 { 3554 cp.rd = time.Duration(float64(ka)*1.5) * time.Second 3555 } 3556 3557 // Payload starts here and order is mandated by: 3558 // Spec [MQTT-3.1.3-1]: client ID, will topic, will message, username, password 3559 3560 // Client ID 3561 c.mqtt.cid, err = r.readString("client ID") 3562 if err != nil { 3563 return 0, nil, err 3564 } 3565 // Spec [MQTT-3.1.3-7] 3566 if c.mqtt.cid == _EMPTY_ { 3567 if cp.flags&mqttConnFlagCleanSession == 0 { 3568 return mqttConnAckRCIdentifierRejected, nil, errMQTTCIDEmptyNeedsCleanFlag 3569 } 3570 // Spec [MQTT-3.1.3-6] 3571 c.mqtt.cid = nuid.Next() 3572 } 3573 // Spec [MQTT-3.1.3-4] and [MQTT-3.1.3-9] 3574 if !utf8.ValidString(c.mqtt.cid) { 3575 return mqttConnAckRCIdentifierRejected, nil, fmt.Errorf("invalid utf8 for client ID: %q", c.mqtt.cid) 3576 } 3577 3578 if hasWill { 3579 cp.will = &mqttWill{ 3580 qos: wqos, 3581 retain: wretain, 3582 } 3583 var topic []byte 3584 // Need to make a copy since we need to hold to this topic after the 3585 // parsing of this protocol. 3586 topic, err = r.readBytes("Will topic", true) 3587 if err != nil { 3588 return 0, nil, err 3589 } 3590 if len(topic) == 0 { 3591 return 0, nil, errMQTTEmptyWillTopic 3592 } 3593 if !utf8.Valid(topic) { 3594 return 0, nil, fmt.Errorf("invalid utf8 for Will topic %q", topic) 3595 } 3596 // Convert MQTT topic to NATS subject 3597 cp.will.subject, err = mqttTopicToNATSPubSubject(topic) 3598 if err != nil { 3599 return 0, nil, err 3600 } 3601 // Check for subject mapping. 3602 if hasMappings { 3603 // For selectMappedSubject to work, we need to have c.pa.subject set. 3604 // If there is a change, c.pa.mapped will be set after the call. 3605 c.pa.subject = cp.will.subject 3606 if changed := c.selectMappedSubject(); changed { 3607 // We need to keep track of the NATS subject/mapped in the `cp` structure. 3608 cp.will.subject = c.pa.subject 3609 cp.will.mapped = c.pa.mapped 3610 // We also now need to map the original MQTT topic to the new topic 3611 // based on the new subject. 3612 topic = natsSubjectToMQTTTopic(string(cp.will.subject)) 3613 } 3614 // Reset those now. 3615 c.pa.subject, c.pa.mapped = nil, nil 3616 } 3617 cp.will.topic = topic 3618 // Now "will" message. 3619 // Ask for a copy since we need to hold to this after parsing of this protocol. 3620 cp.will.message, err = r.readBytes("Will message", true) 3621 if err != nil { 3622 return 0, nil, err 3623 } 3624 } 3625 3626 if hasUser { 3627 c.opts.Username, err = r.readString("user name") 3628 if err != nil { 3629 return 0, nil, err 3630 } 3631 if c.opts.Username == _EMPTY_ { 3632 return mqttConnAckRCBadUserOrPassword, nil, errMQTTEmptyUsername 3633 } 3634 // Spec [MQTT-3.1.3-11] 3635 if !utf8.ValidString(c.opts.Username) { 3636 return mqttConnAckRCBadUserOrPassword, nil, fmt.Errorf("invalid utf8 for user name %q", c.opts.Username) 3637 } 3638 } 3639 3640 if hasPassword { 3641 c.opts.Password, err = r.readString("password") 3642 if err != nil { 3643 return 0, nil, err 3644 } 3645 c.opts.Token = c.opts.Password 3646 c.opts.JWT = c.opts.Password 3647 } 3648 return 0, cp, nil 3649 } 3650 3651 func (c *client) mqttConnectTrace(cp *mqttConnectProto) string { 3652 trace := fmt.Sprintf("clientID=%s", c.mqtt.cid) 3653 if cp.rd > 0 { 3654 trace += fmt.Sprintf(" keepAlive=%v", cp.rd) 3655 } 3656 if cp.will != nil { 3657 trace += fmt.Sprintf(" will=(topic=%s QoS=%v retain=%v)", 3658 cp.will.topic, cp.will.qos, cp.will.retain) 3659 } 3660 if cp.flags&mqttConnFlagCleanSession != 0 { 3661 trace += " clean" 3662 } 3663 if c.opts.Username != _EMPTY_ { 3664 trace += fmt.Sprintf(" username=%s", c.opts.Username) 3665 } 3666 if c.opts.Password != _EMPTY_ { 3667 trace += " password=****" 3668 } 3669 return trace 3670 } 3671 3672 // Process the CONNECT packet. 3673 // 3674 // For the first session on the account, an account session manager will be created, 3675 // along with the JetStream streams/consumer necessary for the working of MQTT. 3676 // 3677 // The session, identified by a client ID, will be registered, or if already existing, 3678 // will be resumed. If the session exists but is associated with an existing client, 3679 // the old client is evicted, as per the specifications. 3680 // 3681 // Due to specific locking requirements around JS API requests, we cannot hold some 3682 // locks for the entire duration of processing of some protocols, therefore, we use 3683 // a map that registers the client ID in a "locked" state. If a different client tries 3684 // to connect and the server detects that the client ID is in that map, it will try 3685 // a little bit until it is not, or fail the new client, since we can't protect 3686 // processing of protocols in the original client. This is not expected to happen often. 3687 // 3688 // Runs from the client's readLoop. 3689 // No lock held on entry. 3690 func (s *Server) mqttProcessConnect(c *client, cp *mqttConnectProto, trace bool) error { 3691 sendConnAck := func(rc byte, sessp bool) { 3692 c.mqttEnqueueConnAck(rc, sessp) 3693 if trace { 3694 c.traceOutOp("CONNACK", []byte(fmt.Sprintf("sp=%v rc=%v", sessp, rc))) 3695 } 3696 } 3697 3698 c.mu.Lock() 3699 cid := c.mqtt.cid 3700 c.clearAuthTimer() 3701 c.mu.Unlock() 3702 if !s.isClientAuthorized(c) { 3703 if trace { 3704 c.traceOutOp("CONNACK", []byte(fmt.Sprintf("sp=%v rc=%v", false, mqttConnAckRCNotAuthorized))) 3705 } 3706 c.authViolation() 3707 return ErrAuthentication 3708 } 3709 // Now that we are are authenticated, we have the client bound to the account. 3710 // Get the account's level MQTT sessions manager. If it does not exists yet, 3711 // this will create it along with the streams where sessions and messages 3712 // are stored. 3713 asm, err := s.getOrCreateMQTTAccountSessionManager(cid, c) 3714 if err != nil { 3715 return err 3716 } 3717 3718 // Most of the session state is altered only in the readLoop so does not 3719 // need locking. For things that can be access in the readLoop and in 3720 // callbacks, we will use explicit locking. 3721 // To prevent other clients to connect with the same client ID, we will 3722 // add the client ID to a "locked" map so that the connect somewhere else 3723 // is put on hold. 3724 // This keep track of how many times this client is detecting that its 3725 // client ID is in the locked map. After a short amount, the server will 3726 // fail this inbound client. 3727 locked := 0 3728 3729 CHECK: 3730 asm.mu.Lock() 3731 // Check if different applications keep trying to connect with the same 3732 // client ID at the same time. 3733 if tm, ok := asm.flappers[cid]; ok { 3734 // If the last time it tried to connect was more than 1 sec ago, 3735 // then accept and remove from flappers map. 3736 if time.Now().UnixNano()-tm > int64(mqttSessJailDur) { 3737 asm.removeSessFromFlappers(cid) 3738 } else { 3739 // Will hold this client for a second and then close it. We 3740 // do this so that if the client has a reconnect feature we 3741 // don't end-up with very rapid flapping between apps. 3742 // We need to wait in place and not schedule the connection 3743 // close because if this is a misbehaved client that does 3744 // not wait for the CONNACK and sends other protocols, the 3745 // server would not have a fully setup client and may panic. 3746 asm.mu.Unlock() 3747 select { 3748 case <-s.quitCh: 3749 case <-time.After(mqttSessJailDur): 3750 } 3751 c.closeConnection(DuplicateClientID) 3752 return ErrConnectionClosed 3753 } 3754 } 3755 // If an existing session is in the process of processing some packet, we can't 3756 // evict the old client just yet. So try again to see if the state clears, but 3757 // if it does not, then we have no choice but to fail the new client instead of 3758 // the old one. 3759 if _, ok := asm.sessLocked[cid]; ok { 3760 asm.mu.Unlock() 3761 if locked++; locked == 10 { 3762 return fmt.Errorf("other session with client ID %q is in the process of connecting", cid) 3763 } 3764 time.Sleep(100 * time.Millisecond) 3765 goto CHECK 3766 } 3767 3768 // Register this client ID the "locked" map for the duration if this function. 3769 asm.sessLocked[cid] = struct{}{} 3770 // And remove it on exit, regardless of error or not. 3771 defer func() { 3772 asm.mu.Lock() 3773 delete(asm.sessLocked, cid) 3774 asm.mu.Unlock() 3775 }() 3776 3777 // Is the client requesting a clean session or not. 3778 cleanSess := cp.flags&mqttConnFlagCleanSession != 0 3779 // Session present? Assume false, will be set to true only when applicable. 3780 sessp := false 3781 // Do we have an existing session for this client ID 3782 es, exists := asm.sessions[cid] 3783 asm.mu.Unlock() 3784 3785 // The session is not in the map, but may be on disk, so try to recover 3786 // or create the stream if not. 3787 if !exists { 3788 es, exists, err = asm.createOrRestoreSession(cid, s.getOpts()) 3789 if err != nil { 3790 return err 3791 } 3792 } 3793 if exists { 3794 // Clear the session if client wants a clean session. 3795 // Also, Spec [MQTT-3.2.2-1]: don't report session present 3796 if cleanSess || es.clean { 3797 // Spec [MQTT-3.1.2-6]: If CleanSession is set to 1, the Client and 3798 // Server MUST discard any previous Session and start a new one. 3799 // This Session lasts as long as the Network Connection. State data 3800 // associated with this Session MUST NOT be reused in any subsequent 3801 // Session. 3802 if err := es.clear(); err != nil { 3803 asm.removeSession(es, true) 3804 return err 3805 } 3806 } else { 3807 // Report to the client that the session was present 3808 sessp = true 3809 } 3810 // Spec [MQTT-3.1.4-2]. If the ClientId represents a Client already 3811 // connected to the Server then the Server MUST disconnect the existing 3812 // client. 3813 // Bind with the new client. This needs to be protected because can be 3814 // accessed outside of the readLoop. 3815 es.mu.Lock() 3816 ec := es.c 3817 es.c = c 3818 es.clean = cleanSess 3819 es.mu.Unlock() 3820 if ec != nil { 3821 // Remove "will" of existing client before closing 3822 ec.mu.Lock() 3823 ec.mqtt.cp.will = nil 3824 ec.mu.Unlock() 3825 // Add to the map of the flappers 3826 asm.mu.Lock() 3827 asm.addSessToFlappers(cid) 3828 asm.mu.Unlock() 3829 c.Warnf("Replacing old client %q since both have the same client ID %q", ec, cid) 3830 // Close old client in separate go routine 3831 go ec.closeConnection(DuplicateClientID) 3832 } 3833 } else { 3834 // Spec [MQTT-3.2.2-3]: if the Server does not have stored Session state, 3835 // it MUST set Session Present to 0 in the CONNACK packet. 3836 es.mu.Lock() 3837 es.c, es.clean = c, cleanSess 3838 es.mu.Unlock() 3839 // Now add this new session into the account sessions 3840 asm.addSession(es, true) 3841 } 3842 // We would need to save only if it did not exist previously, but we save 3843 // always in case we are running in cluster mode. This will notify other 3844 // running servers that this session is being used. 3845 if err := es.save(); err != nil { 3846 asm.removeSession(es, true) 3847 return err 3848 } 3849 c.mu.Lock() 3850 c.flags.set(connectReceived) 3851 c.mqtt.cp = cp 3852 c.mqtt.asm = asm 3853 c.mqtt.sess = es 3854 c.mu.Unlock() 3855 3856 // Spec [MQTT-3.2.0-1]: CONNACK must be the first protocol sent to the session. 3857 sendConnAck(mqttConnAckRCConnectionAccepted, sessp) 3858 3859 // Process possible saved subscriptions. 3860 if l := len(es.subs); l > 0 { 3861 filters := make([]*mqttFilter, 0, l) 3862 for subject, qos := range es.subs { 3863 filters = append(filters, &mqttFilter{filter: subject, qos: qos}) 3864 } 3865 if _, err := asm.processSubs(es, c, filters, false, trace); err != nil { 3866 return err 3867 } 3868 } 3869 return nil 3870 } 3871 3872 func (c *client) mqttEnqueueConnAck(rc byte, sessionPresent bool) { 3873 proto := [4]byte{mqttPacketConnectAck, 2, 0, rc} 3874 c.mu.Lock() 3875 // Spec [MQTT-3.2.2-4]. If return code is different from 0, then 3876 // session present flag must be set to 0. 3877 if rc == 0 { 3878 if sessionPresent { 3879 proto[2] = 1 3880 } 3881 } 3882 c.enqueueProto(proto[:]) 3883 c.mu.Unlock() 3884 } 3885 3886 func (s *Server) mqttHandleWill(c *client) { 3887 c.mu.Lock() 3888 if c.mqtt.cp == nil { 3889 c.mu.Unlock() 3890 return 3891 } 3892 will := c.mqtt.cp.will 3893 if will == nil { 3894 c.mu.Unlock() 3895 return 3896 } 3897 pp := c.mqtt.pp 3898 pp.topic = will.topic 3899 pp.subject = will.subject 3900 pp.mapped = will.mapped 3901 pp.msg = will.message 3902 pp.sz = len(will.message) 3903 pp.pi = 0 3904 pp.flags = will.qos << 1 3905 if will.retain { 3906 pp.flags |= mqttPubFlagRetain 3907 } 3908 c.mu.Unlock() 3909 s.mqttInitiateMsgDelivery(c, pp) 3910 c.flushClients(0) 3911 } 3912 3913 ////////////////////////////////////////////////////////////////////////////// 3914 // 3915 // PUBLISH protocol related functions 3916 // 3917 ////////////////////////////////////////////////////////////////////////////// 3918 3919 func (c *client) mqttParsePub(r *mqttReader, pl int, pp *mqttPublish, hasMappings bool) error { 3920 qos := mqttGetQoS(pp.flags) 3921 if qos > 2 { 3922 return fmt.Errorf("QoS=%v is invalid in MQTT", qos) 3923 } 3924 3925 if c.mqtt.rejectQoS2Pub && qos == 2 { 3926 return fmt.Errorf("QoS=2 is disabled for PUBLISH messages") 3927 } 3928 3929 // Keep track of where we are when starting to read the variable header 3930 start := r.pos 3931 3932 var err error 3933 pp.topic, err = r.readBytes("topic", false) 3934 if err != nil { 3935 return err 3936 } 3937 if len(pp.topic) == 0 { 3938 return errMQTTTopicIsEmpty 3939 } 3940 // Convert the topic to a NATS subject. This call will also check that 3941 // there is no MQTT wildcards (Spec [MQTT-3.3.2-2] and [MQTT-4.7.1-1]) 3942 // Note that this may not result in a copy if there is no conversion. 3943 // It is good because after the message is processed we won't have a 3944 // reference to the buffer and we save a copy. 3945 pp.subject, err = mqttTopicToNATSPubSubject(pp.topic) 3946 if err != nil { 3947 return err 3948 } 3949 3950 // Check for subject mapping. 3951 if hasMappings { 3952 // For selectMappedSubject to work, we need to have c.pa.subject set. 3953 // If there is a change, c.pa.mapped will be set after the call. 3954 c.pa.subject = pp.subject 3955 if changed := c.selectMappedSubject(); changed { 3956 // We need to keep track of the NATS subject/mapped in the `pp` structure. 3957 pp.subject = c.pa.subject 3958 pp.mapped = c.pa.mapped 3959 // We also now need to map the original MQTT topic to the new topic 3960 // based on the new subject. 3961 pp.topic = natsSubjectToMQTTTopic(string(pp.subject)) 3962 } 3963 // Reset those now. 3964 c.pa.subject, c.pa.mapped = nil, nil 3965 } 3966 3967 if qos > 0 { 3968 pp.pi, err = r.readUint16("packet identifier") 3969 if err != nil { 3970 return err 3971 } 3972 if pp.pi == 0 { 3973 return fmt.Errorf("with QoS=%v, packet identifier cannot be 0", qos) 3974 } 3975 } else { 3976 pp.pi = 0 3977 } 3978 3979 // The message payload will be the total packet length minus 3980 // what we have consumed for the variable header 3981 pp.sz = pl - (r.pos - start) 3982 if pp.sz > 0 { 3983 start = r.pos 3984 r.pos += pp.sz 3985 pp.msg = r.buf[start:r.pos] 3986 } else { 3987 pp.msg = nil 3988 } 3989 return nil 3990 } 3991 3992 func mqttPubTrace(pp *mqttPublish) string { 3993 dup := pp.flags&mqttPubFlagDup != 0 3994 qos := mqttGetQoS(pp.flags) 3995 retain := mqttIsRetained(pp.flags) 3996 var piStr string 3997 if pp.pi > 0 { 3998 piStr = fmt.Sprintf(" pi=%v", pp.pi) 3999 } 4000 return fmt.Sprintf("%s dup=%v QoS=%v retain=%v size=%v%s", 4001 pp.topic, dup, qos, retain, pp.sz, piStr) 4002 } 4003 4004 // Composes a NATS message from a MQTT PUBLISH packet. The message includes an 4005 // internal header containint the original packet's QoS, and for QoS2 packets 4006 // the original subject. 4007 // 4008 // Example (QoS2, subject: "foo.bar"): 4009 // 4010 // NATS/1.0\r\n 4011 // Nmqtt-Pub:2foo.bar\r\n 4012 // \r\n 4013 func mqttNewDeliverableMessage(pp *mqttPublish, encodePP bool) (natsMsg []byte, headerLen int) { 4014 size := len(hdrLine) + 4015 len(mqttNatsHeader) + 2 + 2 + // 2 for ':<qos>', and 2 for CRLF 4016 2 + // end-of-header CRLF 4017 len(pp.msg) 4018 if encodePP { 4019 size += len(mqttNatsHeaderSubject) + 1 + // +1 for ':' 4020 len(pp.subject) + 2 // 2 for CRLF 4021 4022 if len(pp.mapped) > 0 { 4023 size += len(mqttNatsHeaderMapped) + 1 + // +1 for ':' 4024 len(pp.mapped) + 2 // 2 for CRLF 4025 } 4026 } 4027 buf := bytes.NewBuffer(make([]byte, 0, size)) 4028 4029 qos := mqttGetQoS(pp.flags) 4030 4031 buf.WriteString(hdrLine) 4032 buf.WriteString(mqttNatsHeader) 4033 buf.WriteByte(':') 4034 buf.WriteByte(qos + '0') 4035 buf.WriteString(_CRLF_) 4036 4037 if encodePP { 4038 buf.WriteString(mqttNatsHeaderSubject) 4039 buf.WriteByte(':') 4040 buf.Write(pp.subject) 4041 buf.WriteString(_CRLF_) 4042 4043 if len(pp.mapped) > 0 { 4044 buf.WriteString(mqttNatsHeaderMapped) 4045 buf.WriteByte(':') 4046 buf.Write(pp.mapped) 4047 buf.WriteString(_CRLF_) 4048 } 4049 } 4050 4051 // End of header 4052 buf.WriteString(_CRLF_) 4053 4054 headerLen = buf.Len() 4055 4056 buf.Write(pp.msg) 4057 return buf.Bytes(), headerLen 4058 } 4059 4060 // Composes a NATS message for a pending PUBREL packet. The message includes an 4061 // internal header containing the PI for PUBREL/PUBCOMP. 4062 // 4063 // Example (PI:123): 4064 // 4065 // NATS/1.0\r\n 4066 // Nmqtt-PubRel:123\r\n 4067 // \r\n 4068 func mqttNewDeliverablePubRel(pi uint16) (natsMsg []byte, headerLen int) { 4069 size := len(hdrLine) + 4070 len(mqttNatsPubRelHeader) + 6 + 2 + // 6 for ':65535', and 2 for CRLF 4071 2 // end-of-header CRLF 4072 buf := bytes.NewBuffer(make([]byte, 0, size)) 4073 buf.WriteString(hdrLine) 4074 buf.WriteString(mqttNatsPubRelHeader) 4075 buf.WriteByte(':') 4076 buf.WriteString(strconv.FormatInt(int64(pi), 10)) 4077 buf.WriteString(_CRLF_) 4078 buf.WriteString(_CRLF_) 4079 return buf.Bytes(), buf.Len() 4080 } 4081 4082 // Process the PUBLISH packet. 4083 // 4084 // Runs from the client's readLoop. 4085 // No lock held on entry. 4086 func (s *Server) mqttProcessPub(c *client, pp *mqttPublish, trace bool) error { 4087 qos := mqttGetQoS(pp.flags) 4088 4089 switch qos { 4090 case 0: 4091 return s.mqttInitiateMsgDelivery(c, pp) 4092 4093 case 1: 4094 // [MQTT-4.3.2-2]. Initiate onward delivery of the Application Message, 4095 // Send PUBACK. 4096 // 4097 // The receiver is not required to complete delivery of the Application 4098 // Message before sending the PUBACK. When its original sender receives 4099 // the PUBACK packet, ownership of the Application Message is 4100 // transferred to the receiver. 4101 err := s.mqttInitiateMsgDelivery(c, pp) 4102 if err == nil { 4103 c.mqttEnqueuePubResponse(mqttPacketPubAck, pp.pi, trace) 4104 } 4105 return err 4106 4107 case 2: 4108 // [MQTT-4.3.3-2]. Method A, Store message, send PUBREC. 4109 // 4110 // The receiver is not required to complete delivery of the Application 4111 // Message before sending the PUBREC or PUBCOMP. When its original 4112 // sender receives the PUBREC packet, ownership of the Application 4113 // Message is transferred to the receiver. 4114 err := s.mqttStoreQoS2MsgOnce(c, pp) 4115 if err == nil { 4116 c.mqttEnqueuePubResponse(mqttPacketPubRec, pp.pi, trace) 4117 } 4118 return err 4119 4120 default: 4121 return fmt.Errorf("unreachable: invalid QoS in mqttProcessPub: %v", qos) 4122 } 4123 } 4124 4125 func (s *Server) mqttInitiateMsgDelivery(c *client, pp *mqttPublish) error { 4126 natsMsg, headerLen := mqttNewDeliverableMessage(pp, false) 4127 4128 // Set the client's pubarg for processing. 4129 c.pa.subject = pp.subject 4130 c.pa.mapped = pp.mapped 4131 c.pa.reply = nil 4132 c.pa.hdr = headerLen 4133 c.pa.hdb = []byte(strconv.FormatInt(int64(c.pa.hdr), 10)) 4134 c.pa.size = len(natsMsg) 4135 c.pa.szb = []byte(strconv.FormatInt(int64(c.pa.size), 10)) 4136 defer func() { 4137 c.pa.subject = nil 4138 c.pa.mapped = nil 4139 c.pa.reply = nil 4140 c.pa.hdr = -1 4141 c.pa.hdb = nil 4142 c.pa.size = 0 4143 c.pa.szb = nil 4144 }() 4145 4146 _, permIssue := c.processInboundClientMsg(natsMsg) 4147 if permIssue { 4148 return nil 4149 } 4150 4151 // If QoS 0 messages don't need to be stored, other (1 and 2) do. Store them 4152 // JetStream under "$MQTT.msgs.<delivery-subject>" 4153 if qos := mqttGetQoS(pp.flags); qos == 0 { 4154 return nil 4155 } 4156 4157 // We need to call flushClients now since this we may have called c.addToPCD 4158 // with destination clients (possibly a route). Without calling flushClients 4159 // the following call may then be stuck waiting for a reply that may never 4160 // come because the destination is not flushed (due to c.out.fsp > 0, 4161 // see addToPCD and writeLoop for details). 4162 c.flushClients(0) 4163 4164 _, err := c.mqtt.sess.jsa.storeMsg(mqttStreamSubjectPrefix+string(c.pa.subject), headerLen, natsMsg) 4165 4166 return err 4167 } 4168 4169 var mqttMaxMsgErrPattern = fmt.Sprintf("%s (%v)", ErrMaxMsgsPerSubject.Error(), JSStreamStoreFailedF) 4170 4171 func (s *Server) mqttStoreQoS2MsgOnce(c *client, pp *mqttPublish) error { 4172 // `true` means encode the MQTT PUBLISH packet in the NATS message header. 4173 natsMsg, headerLen := mqttNewDeliverableMessage(pp, true) 4174 4175 // Do not broadcast the message until it has been deduplicated and released 4176 // by the sender. Instead store this QoS2 message as 4177 // "$MQTT.qos2.<client-id>.<PI>". If the message is a duplicate, we get back 4178 // a ErrMaxMsgsPerSubject, otherwise it does not change the flow, still need 4179 // to send a PUBREC back to the client. The original subject (translated 4180 // from MQTT topic) is included in the NATS header of the stored message to 4181 // use for latter delivery. 4182 _, err := c.mqtt.sess.jsa.storeMsg(c.mqttQoS2InternalSubject(pp.pi), headerLen, natsMsg) 4183 4184 // TODO: would prefer a more robust and performant way of checking the 4185 // error, but it comes back wrapped as an API result. 4186 if err != nil && 4187 (isErrorOtherThan(err, JSStreamStoreFailedF) || err.Error() != mqttMaxMsgErrPattern) { 4188 return err 4189 } 4190 4191 return nil 4192 } 4193 4194 func (c *client) mqttQoS2InternalSubject(pi uint16) string { 4195 return mqttQoS2IncomingMsgsStreamSubjectPrefix + c.mqtt.cid + "." + strconv.FormatUint(uint64(pi), 10) 4196 } 4197 4198 // Process a PUBREL packet (QoS2, acting as Receiver). 4199 // 4200 // Runs from the client's readLoop. 4201 // No lock held on entry. 4202 func (s *Server) mqttProcessPubRel(c *client, pi uint16, trace bool) error { 4203 // Once done with the processing, send a PUBCOMP back to the client. 4204 defer c.mqttEnqueuePubResponse(mqttPacketPubComp, pi, trace) 4205 4206 // See if there is a message pending for this pi. All failures are treated 4207 // as "not found". 4208 asm := c.mqtt.asm 4209 stored, _ := asm.jsa.loadLastMsgFor(mqttQoS2IncomingMsgsStreamName, c.mqttQoS2InternalSubject(pi)) 4210 4211 if stored == nil { 4212 // No message found, nothing to do. 4213 return nil 4214 } 4215 // Best attempt to delete the message from the QoS2 stream. 4216 asm.jsa.deleteMsg(mqttQoS2IncomingMsgsStreamName, stored.Sequence, true) 4217 4218 // only MQTT QoS2 messages should be here, and they must have a subject. 4219 h := mqttParsePublishNATSHeader(stored.Header) 4220 if h == nil || h.qos != 2 || len(h.subject) == 0 { 4221 return errors.New("invalid message in QoS2 PUBREL stream") 4222 } 4223 4224 pp := &mqttPublish{ 4225 topic: natsSubjectToMQTTTopic(string(h.subject)), 4226 subject: h.subject, 4227 mapped: h.mapped, 4228 msg: stored.Data, 4229 sz: len(stored.Data), 4230 pi: pi, 4231 flags: h.qos << 1, 4232 } 4233 4234 return s.mqttInitiateMsgDelivery(c, pp) 4235 } 4236 4237 // Invoked when processing an inbound client message. If the "retain" flag is 4238 // set, the message is stored so it can be later resent to (re)starting 4239 // subscriptions that match the subject. 4240 // 4241 // Invoked from the MQTT publisher's readLoop. No client lock is held on entry. 4242 func (c *client) mqttHandlePubRetain() { 4243 pp := c.mqtt.pp 4244 if !mqttIsRetained(pp.flags) { 4245 return 4246 } 4247 key := string(pp.subject) 4248 asm := c.mqtt.asm 4249 // Spec [MQTT-3.3.1-11]. Payload of size 0 removes the retained message, 4250 // but should still be delivered as a normal message. 4251 if pp.sz == 0 { 4252 if seqToRemove := asm.handleRetainedMsgDel(key, 0); seqToRemove > 0 { 4253 asm.deleteRetainedMsg(seqToRemove) 4254 asm.notifyRetainedMsgDeleted(key, seqToRemove) 4255 } 4256 } else { 4257 // Spec [MQTT-3.3.1-5]. Store the retained message with its QoS. 4258 // 4259 // When coming from a publish protocol, `pp` is referencing a stack 4260 // variable that itself possibly references the read buffer. 4261 rm := &mqttRetainedMsg{ 4262 Origin: asm.jsa.id, 4263 Subject: key, 4264 Topic: string(pp.topic), 4265 Msg: pp.msg, // will copy these bytes later as we process rm. 4266 Flags: pp.flags, 4267 Source: c.opts.Username, 4268 } 4269 rmBytes, hdr := mqttEncodeRetainedMessage(rm) // will copy the payload bytes 4270 smr, err := asm.jsa.storeMsg(mqttRetainedMsgsStreamSubject+key, hdr, rmBytes) 4271 if err == nil { 4272 // Update the new sequence. 4273 rf := &mqttRetainedMsgRef{ 4274 sseq: smr.Sequence, 4275 } 4276 // Add/update the map. `true` to copy the payload bytes if needs to 4277 // update rmsCache. 4278 asm.handleRetainedMsg(key, rf, rm, true) 4279 } else { 4280 c.mu.Lock() 4281 acc := c.acc 4282 c.mu.Unlock() 4283 c.Errorf("unable to store retained message for account %q, subject %q: %v", 4284 acc.GetName(), key, err) 4285 } 4286 } 4287 4288 // Clear the retain flag for a normal published message. 4289 pp.flags &= ^mqttPubFlagRetain 4290 } 4291 4292 // After a config reload, it is possible that the source of a publish retained 4293 // message is no longer allowed to publish on the given topic. If that is the 4294 // case, the retained message is removed from the map and will no longer be 4295 // sent to (re)starting subscriptions. 4296 // 4297 // Server lock MUST NOT be held on entry. 4298 func (s *Server) mqttCheckPubRetainedPerms() { 4299 sm := &s.mqtt.sessmgr 4300 sm.mu.RLock() 4301 done := len(sm.sessions) == 0 4302 sm.mu.RUnlock() 4303 4304 if done { 4305 return 4306 } 4307 4308 s.mu.Lock() 4309 users := make(map[string]*User, len(s.users)) 4310 for un, u := range s.users { 4311 users[un] = u 4312 } 4313 s.mu.Unlock() 4314 4315 // First get a list of all of the sessions. 4316 sm.mu.RLock() 4317 asms := make([]*mqttAccountSessionManager, 0, len(sm.sessions)) 4318 for _, asm := range sm.sessions { 4319 asms = append(asms, asm) 4320 } 4321 sm.mu.RUnlock() 4322 4323 type retainedMsg struct { 4324 subj string 4325 rmsg *mqttRetainedMsgRef 4326 } 4327 4328 // For each session we will obtain a list of retained messages. 4329 var _rms [128]retainedMsg 4330 rms := _rms[:0] 4331 for _, asm := range asms { 4332 // Get all of the retained messages. Then we will sort them so 4333 // that they are in sequence order, which should help the file 4334 // store to not have to load out-of-order blocks so often. 4335 asm.mu.RLock() 4336 rms = rms[:0] // reuse slice 4337 for subj, rf := range asm.retmsgs { 4338 rms = append(rms, retainedMsg{ 4339 subj: subj, 4340 rmsg: rf, 4341 }) 4342 } 4343 asm.mu.RUnlock() 4344 sort.Slice(rms, func(i, j int) bool { 4345 return rms[i].rmsg.sseq < rms[j].rmsg.sseq 4346 }) 4347 4348 perms := map[string]*perm{} 4349 deletes := map[string]uint64{} 4350 for _, rf := range rms { 4351 jsm, err := asm.jsa.loadMsg(mqttRetainedMsgsStreamName, rf.rmsg.sseq) 4352 if err != nil || jsm == nil { 4353 continue 4354 } 4355 rm, err := mqttDecodeRetainedMessage(jsm.Header, jsm.Data) 4356 if err != nil { 4357 continue 4358 } 4359 if rm.Source == _EMPTY_ { 4360 continue 4361 } 4362 // Lookup source from global users. 4363 u := users[rm.Source] 4364 if u != nil { 4365 p, ok := perms[rm.Source] 4366 if !ok { 4367 p = generatePubPerms(u.Permissions) 4368 perms[rm.Source] = p 4369 } 4370 // If there is permission and no longer allowed to publish in 4371 // the subject, remove the publish retained message from the map. 4372 if p != nil && !pubAllowed(p, rf.subj) { 4373 u = nil 4374 } 4375 } 4376 4377 // Not present or permissions have changed such that the source can't 4378 // publish on that subject anymore: remove it from the map. 4379 if u == nil { 4380 asm.mu.Lock() 4381 delete(asm.retmsgs, rf.subj) 4382 asm.sl.Remove(rf.rmsg.sub) 4383 asm.mu.Unlock() 4384 deletes[rf.subj] = rf.rmsg.sseq 4385 } 4386 } 4387 4388 for subject, seq := range deletes { 4389 asm.deleteRetainedMsg(seq) 4390 asm.notifyRetainedMsgDeleted(subject, seq) 4391 } 4392 } 4393 } 4394 4395 // Helper to generate only pub permissions from a Permissions object 4396 func generatePubPerms(perms *Permissions) *perm { 4397 var p *perm 4398 if perms.Publish.Allow != nil { 4399 p = &perm{} 4400 p.allow = NewSublistWithCache() 4401 for _, pubSubject := range perms.Publish.Allow { 4402 sub := &subscription{subject: []byte(pubSubject)} 4403 p.allow.Insert(sub) 4404 } 4405 } 4406 if len(perms.Publish.Deny) > 0 { 4407 if p == nil { 4408 p = &perm{} 4409 } 4410 p.deny = NewSublistWithCache() 4411 for _, pubSubject := range perms.Publish.Deny { 4412 sub := &subscription{subject: []byte(pubSubject)} 4413 p.deny.Insert(sub) 4414 } 4415 } 4416 return p 4417 } 4418 4419 // Helper that checks if given `perms` allow to publish on the given `subject` 4420 func pubAllowed(perms *perm, subject string) bool { 4421 allowed := true 4422 if perms.allow != nil { 4423 r := perms.allow.Match(subject) 4424 allowed = len(r.psubs) != 0 4425 } 4426 // If we have a deny list and are currently allowed, check that as well. 4427 if allowed && perms.deny != nil { 4428 r := perms.deny.Match(subject) 4429 allowed = len(r.psubs) == 0 4430 } 4431 return allowed 4432 } 4433 4434 func (c *client) mqttEnqueuePubResponse(packetType byte, pi uint16, trace bool) { 4435 proto := [4]byte{packetType, 0x2, 0, 0} 4436 proto[2] = byte(pi >> 8) 4437 proto[3] = byte(pi) 4438 4439 // Bits 3,2,1 and 0 of the fixed header in the PUBREL Control Packet are 4440 // reserved and MUST be set to 0,0,1 and 0 respectively. The Server MUST treat 4441 // any other value as malformed and close the Network Connection [MQTT-3.6.1-1]. 4442 if packetType == mqttPacketPubRel { 4443 proto[0] |= 0x2 4444 } 4445 4446 c.mu.Lock() 4447 c.enqueueProto(proto[:4]) 4448 c.mu.Unlock() 4449 4450 if trace { 4451 name := "(???)" 4452 switch packetType { 4453 case mqttPacketPubAck: 4454 name = "PUBACK" 4455 case mqttPacketPubRec: 4456 name = "PUBREC" 4457 case mqttPacketPubRel: 4458 name = "PUBREL" 4459 case mqttPacketPubComp: 4460 name = "PUBCOMP" 4461 } 4462 c.traceOutOp(name, []byte(fmt.Sprintf("pi=%v", pi))) 4463 } 4464 } 4465 4466 func mqttParsePIPacket(r *mqttReader, pl int) (uint16, error) { 4467 pi, err := r.readUint16("packet identifier") 4468 if err != nil { 4469 return 0, err 4470 } 4471 if pi == 0 { 4472 return 0, errMQTTPacketIdentifierIsZero 4473 } 4474 return pi, nil 4475 } 4476 4477 // Process a PUBACK (QoS1) or a PUBREC (QoS2) packet, acting as Sender. Set 4478 // isPubRec to false to process as a PUBACK. 4479 // 4480 // Runs from the client's readLoop. No lock held on entry. 4481 func (c *client) mqttProcessPublishReceived(pi uint16, isPubRec bool) (err error) { 4482 sess := c.mqtt.sess 4483 if sess == nil { 4484 return errMQTTInvalidSession 4485 } 4486 4487 var jsAckSubject string 4488 sess.mu.Lock() 4489 // Must be the same client, and the session must have been setup for QoS2. 4490 if sess.c != c { 4491 sess.mu.Unlock() 4492 return errMQTTInvalidSession 4493 } 4494 if isPubRec { 4495 // The JS ACK subject for the PUBREL will be filled in at the delivery 4496 // attempt. 4497 sess.trackAsPubRel(pi, _EMPTY_) 4498 } 4499 jsAckSubject = sess.untrackPublish(pi) 4500 sess.mu.Unlock() 4501 4502 if isPubRec { 4503 natsMsg, headerLen := mqttNewDeliverablePubRel(pi) 4504 _, err = sess.jsa.storeMsg(sess.pubRelSubject, headerLen, natsMsg) 4505 if err != nil { 4506 // Failure to send out PUBREL will terminate the connection. 4507 return err 4508 } 4509 } 4510 4511 // Send the ack to JS to remove the pending message from the consumer. 4512 sess.jsa.sendAck(jsAckSubject) 4513 return nil 4514 } 4515 4516 func (c *client) mqttProcessPubAck(pi uint16) error { 4517 return c.mqttProcessPublishReceived(pi, false) 4518 } 4519 4520 func (c *client) mqttProcessPubRec(pi uint16) error { 4521 return c.mqttProcessPublishReceived(pi, true) 4522 } 4523 4524 // Runs from the client's readLoop. No lock held on entry. 4525 func (c *client) mqttProcessPubComp(pi uint16) { 4526 sess := c.mqtt.sess 4527 if sess == nil { 4528 return 4529 } 4530 4531 var jsAckSubject string 4532 sess.mu.Lock() 4533 if sess.c != c { 4534 sess.mu.Unlock() 4535 return 4536 } 4537 jsAckSubject = sess.untrackPubRel(pi) 4538 sess.mu.Unlock() 4539 4540 // Send the ack to JS to remove the pending message from the consumer. 4541 sess.jsa.sendAck(jsAckSubject) 4542 } 4543 4544 // Return the QoS from the given PUBLISH protocol's flags 4545 func mqttGetQoS(flags byte) byte { 4546 return flags & mqttPubFlagQoS >> 1 4547 } 4548 4549 func mqttIsRetained(flags byte) bool { 4550 return flags&mqttPubFlagRetain != 0 4551 } 4552 4553 ////////////////////////////////////////////////////////////////////////////// 4554 // 4555 // SUBSCRIBE related functions 4556 // 4557 ////////////////////////////////////////////////////////////////////////////// 4558 4559 func (c *client) mqttParseSubs(r *mqttReader, b byte, pl int) (uint16, []*mqttFilter, error) { 4560 return c.mqttParseSubsOrUnsubs(r, b, pl, true) 4561 } 4562 4563 func (c *client) mqttParseSubsOrUnsubs(r *mqttReader, b byte, pl int, sub bool) (uint16, []*mqttFilter, error) { 4564 var expectedFlag byte 4565 var action string 4566 if sub { 4567 expectedFlag = mqttSubscribeFlags 4568 } else { 4569 expectedFlag = mqttUnsubscribeFlags 4570 action = "un" 4571 } 4572 // Spec [MQTT-3.8.1-1], [MQTT-3.10.1-1] 4573 if rf := b & 0xf; rf != expectedFlag { 4574 return 0, nil, fmt.Errorf("wrong %ssubscribe reserved flags: %x", action, rf) 4575 } 4576 pi, err := r.readUint16("packet identifier") 4577 if err != nil { 4578 return 0, nil, fmt.Errorf("reading packet identifier: %v", err) 4579 } 4580 end := r.pos + (pl - 2) 4581 var filters []*mqttFilter 4582 for r.pos < end { 4583 // Don't make a copy now because, this will happen during conversion 4584 // or when processing the sub. 4585 topic, err := r.readBytes("topic filter", false) 4586 if err != nil { 4587 return 0, nil, err 4588 } 4589 if len(topic) == 0 { 4590 return 0, nil, errMQTTTopicFilterCannotBeEmpty 4591 } 4592 // Spec [MQTT-3.8.3-1], [MQTT-3.10.3-1] 4593 if !utf8.Valid(topic) { 4594 return 0, nil, fmt.Errorf("invalid utf8 for topic filter %q", topic) 4595 } 4596 var qos byte 4597 // We are going to report if we had an error during the conversion, 4598 // but we don't fail the parsing. When processing the sub, we will 4599 // have an error then, and the processing of subs code will send 4600 // the proper mqttSubAckFailure flag for this given subscription. 4601 filter, err := mqttFilterToNATSSubject(topic) 4602 if err != nil { 4603 c.Errorf("invalid topic %q: %v", topic, err) 4604 } 4605 if sub { 4606 qos, err = r.readByte("QoS") 4607 if err != nil { 4608 return 0, nil, err 4609 } 4610 // Spec [MQTT-3-8.3-4]. 4611 if qos > 2 { 4612 return 0, nil, fmt.Errorf("subscribe QoS value must be 0, 1 or 2, got %v", qos) 4613 } 4614 } 4615 f := &mqttFilter{ttopic: topic, filter: string(filter), qos: qos} 4616 filters = append(filters, f) 4617 } 4618 // Spec [MQTT-3.8.3-3], [MQTT-3.10.3-2] 4619 if len(filters) == 0 { 4620 return 0, nil, fmt.Errorf("%ssubscribe protocol must contain at least 1 topic filter", action) 4621 } 4622 return pi, filters, nil 4623 } 4624 4625 func mqttSubscribeTrace(pi uint16, filters []*mqttFilter) string { 4626 var sep string 4627 sb := &strings.Builder{} 4628 sb.WriteString("[") 4629 for i, f := range filters { 4630 sb.WriteString(sep) 4631 sb.Write(f.ttopic) 4632 sb.WriteString(" (") 4633 sb.WriteString(f.filter) 4634 sb.WriteString(") QoS=") 4635 sb.WriteString(fmt.Sprintf("%v", f.qos)) 4636 if i == 0 { 4637 sep = ", " 4638 } 4639 } 4640 sb.WriteString(fmt.Sprintf("] pi=%v", pi)) 4641 return sb.String() 4642 } 4643 4644 // For a MQTT QoS0 subscription, we create a single NATS subscription on the 4645 // actual subject, for instance "foo.bar". 4646 // 4647 // For a MQTT QoS1+ subscription, we create 2 subscriptions, one on "foo.bar" 4648 // (as for QoS0, but sub.mqtt.qos will be 1 or 2), and one on the subject 4649 // "$MQTT.sub.<uid>" which is the delivery subject of the JS durable consumer 4650 // with the filter subject "$MQTT.msgs.foo.bar". 4651 // 4652 // This callback delivers messages to the client as QoS0 messages, either 4653 // because: (a) they have been produced as MQTT QoS0 messages (and therefore 4654 // only this callback can receive them); (b) they are MQTT QoS1+ published 4655 // messages but this callback is for a subscription that is QoS0; or (c) the 4656 // published messages come from (other) NATS publishers on the subject. 4657 // 4658 // This callback must reject a message if it is known to be a QoS1+ published 4659 // message and this is the callback for a QoS1+ subscription because in that 4660 // case, it will be handled by the other callback. This avoid getting duplicate 4661 // deliveries. 4662 func mqttDeliverMsgCbQoS0(sub *subscription, pc *client, _ *Account, subject, reply string, rmsg []byte) { 4663 if pc.kind == JETSTREAM && len(reply) > 0 && strings.HasPrefix(reply, jsAckPre) { 4664 return 4665 } 4666 4667 // This is the client associated with the subscription. 4668 cc := sub.client 4669 4670 // This is immutable 4671 sess := cc.mqtt.sess 4672 4673 // Lock here, otherwise we may be called with sub.mqtt == nil. Ignore 4674 // wildcard subscriptions if this subject starts with '$', per Spec 4675 // [MQTT-4.7.2-1]. 4676 sess.subsMu.RLock() 4677 subQoS := sub.mqtt.qos 4678 ignore := mqttMustIgnoreForReservedSub(sub, subject) 4679 sess.subsMu.RUnlock() 4680 4681 if ignore { 4682 return 4683 } 4684 4685 hdr, msg := pc.msgParts(rmsg) 4686 var topic []byte 4687 if pc.isMqtt() { 4688 // This is an MQTT publisher directly connected to this server. 4689 4690 // Check the subscription's QoS. If the message was published with a 4691 // QoS>0 and the sub has the QoS>0 then the message will be delivered by 4692 // mqttDeliverMsgCbQoS12. 4693 msgQoS := mqttGetQoS(pc.mqtt.pp.flags) 4694 if subQoS > 0 && msgQoS > 0 { 4695 return 4696 } 4697 topic = pc.mqtt.pp.topic 4698 // Check for service imports where subject mapping is in play. 4699 if len(pc.pa.mapped) > 0 && len(pc.pa.psi) > 0 { 4700 topic = natsSubjectToMQTTTopic(subject) 4701 } 4702 4703 } else { 4704 // Non MQTT client, could be NATS publisher, or ROUTER, etc.. 4705 h := mqttParsePublishNATSHeader(hdr) 4706 4707 // If the message does not have the MQTT header, it is not a MQTT and 4708 // should be delivered here, at QOS0. If it does have the header, we 4709 // need to lock the session to check the sub QoS, and then ignore the 4710 // message if the Sub wants higher QOS delivery. It will be delivered by 4711 // mqttDeliverMsgCbQoS12. 4712 if subQoS > 0 && h != nil && h.qos > 0 { 4713 return 4714 } 4715 4716 // If size is more than what a MQTT client can handle, we should probably reject, 4717 // for now just truncate. 4718 if len(msg) > mqttMaxPayloadSize { 4719 msg = msg[:mqttMaxPayloadSize] 4720 } 4721 topic = natsSubjectToMQTTTopic(subject) 4722 } 4723 4724 // Message never has a packet identifier nor is marked as duplicate. 4725 pc.mqttEnqueuePublishMsgTo(cc, sub, 0, 0, false, topic, msg) 4726 } 4727 4728 // This is the callback attached to a JS durable subscription for a MQTT QoS 1+ 4729 // sub. Only JETSTREAM should be sending a message to this subject (the delivery 4730 // subject associated with the JS durable consumer), but in cluster mode, this 4731 // can be coming from a route, gw, etc... We make sure that if this is the case, 4732 // the message contains a NATS/MQTT header that indicates that this is a 4733 // published QoS1+ message. 4734 func mqttDeliverMsgCbQoS12(sub *subscription, pc *client, _ *Account, subject, reply string, rmsg []byte) { 4735 // Message on foo.bar is stored under $MQTT.msgs.foo.bar, so the subject has to be 4736 // at least as long as the stream subject prefix "$MQTT.msgs.", and after removing 4737 // the prefix, has to be at least 1 character long. 4738 if len(subject) < len(mqttStreamSubjectPrefix)+1 { 4739 return 4740 } 4741 4742 hdr, msg := pc.msgParts(rmsg) 4743 h := mqttParsePublishNATSHeader(hdr) 4744 if pc.kind != JETSTREAM && (h == nil || h.qos == 0) { 4745 // MQTT QoS 0 messages must be ignored, they will be delivered by the 4746 // other callback, the direct NATS subscription. All JETSTREAM messages 4747 // will have the header. 4748 return 4749 } 4750 4751 // This is the client associated with the subscription. 4752 cc := sub.client 4753 4754 // This is immutable 4755 sess := cc.mqtt.sess 4756 4757 // We lock to check some of the subscription's fields and if we need to keep 4758 // track of pending acks, etc. There is no need to acquire the subsMu RLock 4759 // since sess.Lock is overarching for modifying subscriptions. 4760 sess.mu.Lock() 4761 if sess.c != cc || sub.mqtt == nil { 4762 sess.mu.Unlock() 4763 return 4764 } 4765 4766 // In this callback we handle only QoS-published messages to QoS 4767 // subscriptions. Ignore if either is 0, will be delivered by the other 4768 // callback, mqttDeliverMsgCbQos1. 4769 var qos byte 4770 if h != nil { 4771 qos = h.qos 4772 } 4773 if qos > sub.mqtt.qos { 4774 qos = sub.mqtt.qos 4775 } 4776 if qos == 0 { 4777 sess.mu.Unlock() 4778 return 4779 } 4780 4781 // Check for reserved subject violation. If so, we will send the ack to 4782 // remove the message, and do nothing else. 4783 strippedSubj := string(subject[len(mqttStreamSubjectPrefix):]) 4784 if mqttMustIgnoreForReservedSub(sub, strippedSubj) { 4785 sess.mu.Unlock() 4786 sess.jsa.sendAck(reply) 4787 return 4788 } 4789 4790 pi, dup := sess.trackPublish(sub.mqtt.jsDur, reply) 4791 sess.mu.Unlock() 4792 4793 if pi == 0 { 4794 // We have reached max pending, don't send the message now. 4795 // JS will cause a redelivery and if by then the number of pending 4796 // messages has fallen below threshold, the message will be resent. 4797 return 4798 } 4799 4800 originalTopic := natsSubjectToMQTTTopic(strippedSubj) 4801 pc.mqttEnqueuePublishMsgTo(cc, sub, pi, qos, dup, originalTopic, msg) 4802 } 4803 4804 func mqttDeliverPubRelCb(sub *subscription, pc *client, _ *Account, subject, reply string, rmsg []byte) { 4805 if sub.client.mqtt == nil || sub.client.mqtt.sess == nil || reply == _EMPTY_ { 4806 return 4807 } 4808 4809 hdr, _ := pc.msgParts(rmsg) 4810 pi := mqttParsePubRelNATSHeader(hdr) 4811 if pi == 0 { 4812 return 4813 } 4814 4815 // This is the client associated with the subscription. 4816 cc := sub.client 4817 4818 // This is immutable 4819 sess := cc.mqtt.sess 4820 4821 sess.mu.Lock() 4822 if sess.c != cc || sess.pubRelConsumer == nil { 4823 sess.mu.Unlock() 4824 return 4825 } 4826 sess.trackAsPubRel(pi, reply) 4827 trace := cc.trace 4828 sess.mu.Unlock() 4829 4830 cc.mqttEnqueuePubResponse(mqttPacketPubRel, pi, trace) 4831 } 4832 4833 // The MQTT Server MUST NOT match Topic Filters starting with a wildcard 4834 // character (# or +) with Topic Names beginning with a $ character, Spec 4835 // [MQTT-4.7.2-1]. We will return true if there is a violation. 4836 // 4837 // Session or subMu lock must be held on entry to protect access to sub.mqtt. 4838 func mqttMustIgnoreForReservedSub(sub *subscription, subject string) bool { 4839 // If the subject does not start with $ nothing to do here. 4840 if !sub.mqtt.reserved || len(subject) == 0 || subject[0] != mqttReservedPre { 4841 return false 4842 } 4843 return true 4844 } 4845 4846 // Check if a sub is a reserved wildcard. E.g. '#', '*', or '*/" prefix. 4847 func isMQTTReservedSubscription(subject string) bool { 4848 if len(subject) == 1 && (subject[0] == fwc || subject[0] == pwc) { 4849 return true 4850 } 4851 // Match "*.<>" 4852 if len(subject) > 1 && (subject[0] == pwc && subject[1] == btsep) { 4853 return true 4854 } 4855 return false 4856 } 4857 4858 // Common function to mqtt delivery callbacks to serialize and send the message 4859 // to the `cc` client. 4860 func (c *client) mqttEnqueuePublishMsgTo(cc *client, sub *subscription, pi uint16, qos byte, dup bool, topic, msg []byte) { 4861 flags, headerBytes := mqttMakePublishHeader(pi, qos, dup, false, topic, len(msg)) 4862 4863 cc.mu.Lock() 4864 if sub.mqtt.prm != nil { 4865 for _, data := range sub.mqtt.prm { 4866 cc.queueOutbound(data) 4867 } 4868 sub.mqtt.prm = nil 4869 } 4870 cc.queueOutbound(headerBytes) 4871 cc.queueOutbound(msg) 4872 c.addToPCD(cc) 4873 trace := cc.trace 4874 cc.mu.Unlock() 4875 4876 if trace { 4877 pp := mqttPublish{ 4878 topic: topic, 4879 flags: flags, 4880 pi: pi, 4881 sz: len(msg), 4882 } 4883 cc.traceOutOp("PUBLISH", []byte(mqttPubTrace(&pp))) 4884 } 4885 } 4886 4887 // Serializes to the given writer the message for the given subject. 4888 func (w *mqttWriter) WritePublishHeader(pi uint16, qos byte, dup, retained bool, topic []byte, msgLen int) byte { 4889 // Compute len (will have to add packet id if message is sent as QoS>=1) 4890 pkLen := 2 + len(topic) + msgLen 4891 var flags byte 4892 4893 // Set flags for dup/retained/qos1 4894 if dup { 4895 flags |= mqttPubFlagDup 4896 } 4897 if retained { 4898 flags |= mqttPubFlagRetain 4899 } 4900 if qos > 0 { 4901 pkLen += 2 4902 flags |= qos << 1 4903 } 4904 4905 w.WriteByte(mqttPacketPub | flags) 4906 w.WriteVarInt(pkLen) 4907 w.WriteBytes(topic) 4908 if qos > 0 { 4909 w.WriteUint16(pi) 4910 } 4911 4912 return flags 4913 } 4914 4915 // Serializes to the given writer the message for the given subject. 4916 func mqttMakePublishHeader(pi uint16, qos byte, dup, retained bool, topic []byte, msgLen int) (byte, []byte) { 4917 headerBuf := newMQTTWriter(mqttInitialPubHeader + len(topic)) 4918 flags := headerBuf.WritePublishHeader(pi, qos, dup, retained, topic, msgLen) 4919 return flags, headerBuf.Bytes() 4920 } 4921 4922 // Process the SUBSCRIBE packet. 4923 // 4924 // Process the list of subscriptions and update the given filter 4925 // with the QoS that has been accepted (or failure). 4926 // 4927 // Spec [MQTT-3.8.4-3] says that if an exact same subscription is 4928 // found, it needs to be replaced with the new one (possibly updating 4929 // the qos) and that the flow of publications must not be interrupted, 4930 // which I read as the replacement cannot be a "remove then add" if there 4931 // is a chance that in between the 2 actions, published messages 4932 // would be "lost" because there would not be any matching subscription. 4933 // 4934 // Run from client's readLoop. 4935 // No lock held on entry. 4936 func (c *client) mqttProcessSubs(filters []*mqttFilter) ([]*subscription, error) { 4937 // Those things are immutable, but since processing subs is not 4938 // really in the fast path, let's get them under the client lock. 4939 c.mu.Lock() 4940 asm := c.mqtt.asm 4941 sess := c.mqtt.sess 4942 trace := c.trace 4943 c.mu.Unlock() 4944 4945 if err := asm.lockSession(sess, c); err != nil { 4946 return nil, err 4947 } 4948 defer asm.unlockSession(sess) 4949 return asm.processSubs(sess, c, filters, true, trace) 4950 } 4951 4952 // Cleanup that is performed in processSubs if there was an error. 4953 // 4954 // Runs from client's readLoop. 4955 // Lock not held on entry, but session is in the locked map. 4956 func (sess *mqttSession) cleanupFailedSub(c *client, sub *subscription, cc *ConsumerConfig, jssub *subscription) { 4957 if sub != nil { 4958 c.processUnsub(sub.sid) 4959 } 4960 if jssub != nil { 4961 c.processUnsub(jssub.sid) 4962 } 4963 if cc != nil { 4964 sess.deleteConsumer(cc) 4965 } 4966 } 4967 4968 // Make sure we are set up to deliver PUBREL messages to this QoS2-subscribed 4969 // session. 4970 func (sess *mqttSession) ensurePubRelConsumerSubscription(c *client) error { 4971 opts := c.srv.getOpts() 4972 ackWait := opts.MQTT.AckWait 4973 if ackWait == 0 { 4974 ackWait = mqttDefaultAckWait 4975 } 4976 maxAckPending := int(opts.MQTT.MaxAckPending) 4977 if maxAckPending == 0 { 4978 maxAckPending = mqttDefaultMaxAckPending 4979 } 4980 4981 sess.mu.Lock() 4982 pubRelSubscribed := sess.pubRelSubscribed 4983 pubRelSubject := sess.pubRelSubject 4984 pubRelDeliverySubjectB := sess.pubRelDeliverySubjectB 4985 pubRelDeliverySubject := sess.pubRelDeliverySubject 4986 pubRelConsumer := sess.pubRelConsumer 4987 tmaxack := sess.tmaxack 4988 idHash := sess.idHash 4989 id := sess.id 4990 sess.mu.Unlock() 4991 4992 // Subscribe before the consumer is created so we don't loose any messages. 4993 if !pubRelSubscribed { 4994 _, err := c.processSub(pubRelDeliverySubjectB, nil, pubRelDeliverySubjectB, 4995 mqttDeliverPubRelCb, false) 4996 if err != nil { 4997 c.Errorf("Unable to create subscription for JetStream consumer on %q: %v", pubRelDeliverySubject, err) 4998 return err 4999 } 5000 pubRelSubscribed = true 5001 } 5002 5003 // Create the consumer if needed. 5004 if pubRelConsumer == nil { 5005 // Check that the limit of subs' maxAckPending are not going over the limit 5006 if after := tmaxack + maxAckPending; after > mqttMaxAckTotalLimit { 5007 return fmt.Errorf("max_ack_pending for all consumers would be %v which exceeds the limit of %v", 5008 after, mqttMaxAckTotalLimit) 5009 } 5010 5011 ccr := &CreateConsumerRequest{ 5012 Stream: mqttOutStreamName, 5013 Config: ConsumerConfig{ 5014 DeliverSubject: pubRelDeliverySubject, 5015 Durable: mqttPubRelConsumerDurablePrefix + idHash, 5016 AckPolicy: AckExplicit, 5017 DeliverPolicy: DeliverNew, 5018 FilterSubject: pubRelSubject, 5019 AckWait: ackWait, 5020 MaxAckPending: maxAckPending, 5021 MemoryStorage: opts.MQTT.ConsumerMemoryStorage, 5022 }, 5023 } 5024 if opts.MQTT.ConsumerInactiveThreshold > 0 { 5025 ccr.Config.InactiveThreshold = opts.MQTT.ConsumerInactiveThreshold 5026 } 5027 if _, err := sess.jsa.createDurableConsumer(ccr); err != nil { 5028 c.Errorf("Unable to add JetStream consumer for PUBREL for client %q: err=%v", id, err) 5029 return err 5030 } 5031 pubRelConsumer = &ccr.Config 5032 tmaxack += maxAckPending 5033 } 5034 5035 sess.mu.Lock() 5036 sess.pubRelSubscribed = pubRelSubscribed 5037 sess.pubRelConsumer = pubRelConsumer 5038 sess.tmaxack = tmaxack 5039 sess.mu.Unlock() 5040 5041 return nil 5042 } 5043 5044 // When invoked with a QoS of 0, looks for an existing JS durable consumer for 5045 // the given sid and if one is found, delete the JS durable consumer and unsub 5046 // the NATS subscription on the delivery subject. 5047 // 5048 // With a QoS > 0, creates or update the existing JS durable consumer along with 5049 // its NATS subscription on a delivery subject. 5050 // 5051 // Session lock is acquired and released as needed. Session is in the locked 5052 // map. 5053 func (sess *mqttSession) processJSConsumer(c *client, subject, sid string, 5054 qos byte, fromSubProto bool) (*ConsumerConfig, *subscription, error) { 5055 5056 sess.mu.Lock() 5057 cc, exists := sess.cons[sid] 5058 tmaxack := sess.tmaxack 5059 idHash := sess.idHash 5060 sess.mu.Unlock() 5061 5062 // Check if we are already a JS consumer for this SID. 5063 if exists { 5064 // If current QoS is 0, it means that we need to delete the existing 5065 // one (that was QoS > 0) 5066 if qos == 0 { 5067 // The JS durable consumer's delivery subject is on a NUID of 5068 // the form: mqttSubPrefix + <nuid>. It is also used as the sid 5069 // for the NATS subscription, so use that for the lookup. 5070 sub := c.subs[cc.DeliverSubject] 5071 5072 sess.mu.Lock() 5073 delete(sess.cons, sid) 5074 sess.mu.Unlock() 5075 5076 sess.deleteConsumer(cc) 5077 if sub != nil { 5078 c.processUnsub(sub.sid) 5079 } 5080 return nil, nil, nil 5081 } 5082 // If this is called when processing SUBSCRIBE protocol, then if 5083 // the JS consumer already exists, we are done (it was created 5084 // during the processing of CONNECT). 5085 if fromSubProto { 5086 return nil, nil, nil 5087 } 5088 } 5089 // Here it means we don't have a JS consumer and if we are QoS 0, 5090 // we have nothing to do. 5091 if qos == 0 { 5092 return nil, nil, nil 5093 } 5094 var err error 5095 var inbox string 5096 if exists { 5097 inbox = cc.DeliverSubject 5098 } else { 5099 inbox = mqttSubPrefix + nuid.Next() 5100 opts := c.srv.getOpts() 5101 ackWait := opts.MQTT.AckWait 5102 if ackWait == 0 { 5103 ackWait = mqttDefaultAckWait 5104 } 5105 maxAckPending := int(opts.MQTT.MaxAckPending) 5106 if maxAckPending == 0 { 5107 maxAckPending = mqttDefaultMaxAckPending 5108 } 5109 5110 // Check that the limit of subs' maxAckPending are not going over the limit 5111 if after := tmaxack + maxAckPending; after > mqttMaxAckTotalLimit { 5112 return nil, nil, fmt.Errorf("max_ack_pending for all consumers would be %v which exceeds the limit of %v", 5113 after, mqttMaxAckTotalLimit) 5114 } 5115 5116 durName := idHash + "_" + nuid.Next() 5117 ccr := &CreateConsumerRequest{ 5118 Stream: mqttStreamName, 5119 Config: ConsumerConfig{ 5120 DeliverSubject: inbox, 5121 Durable: durName, 5122 AckPolicy: AckExplicit, 5123 DeliverPolicy: DeliverNew, 5124 FilterSubject: mqttStreamSubjectPrefix + subject, 5125 AckWait: ackWait, 5126 MaxAckPending: maxAckPending, 5127 MemoryStorage: opts.MQTT.ConsumerMemoryStorage, 5128 }, 5129 } 5130 if opts.MQTT.ConsumerInactiveThreshold > 0 { 5131 ccr.Config.InactiveThreshold = opts.MQTT.ConsumerInactiveThreshold 5132 } 5133 if _, err := sess.jsa.createDurableConsumer(ccr); err != nil { 5134 c.Errorf("Unable to add JetStream consumer for subscription on %q: err=%v", subject, err) 5135 return nil, nil, err 5136 } 5137 cc = &ccr.Config 5138 tmaxack += maxAckPending 5139 } 5140 5141 // This is an internal subscription on subject like "$MQTT.sub.<nuid>" that is setup 5142 // for the JS durable's deliver subject. 5143 sess.mu.Lock() 5144 sess.tmaxack = tmaxack 5145 sub, err := sess.processQOS12Sub(c, []byte(inbox), []byte(inbox), 5146 isMQTTReservedSubscription(subject), qos, cc.Durable, mqttDeliverMsgCbQoS12) 5147 sess.mu.Unlock() 5148 5149 if err != nil { 5150 sess.deleteConsumer(cc) 5151 c.Errorf("Unable to create subscription for JetStream consumer on %q: %v", subject, err) 5152 return nil, nil, err 5153 } 5154 return cc, sub, nil 5155 } 5156 5157 // Queues the published retained messages for each subscription and signals 5158 // the writeLoop. 5159 func (c *client) mqttSendRetainedMsgsToNewSubs(subs []*subscription) { 5160 c.mu.Lock() 5161 for _, sub := range subs { 5162 if sub.mqtt != nil && sub.mqtt.prm != nil { 5163 for _, data := range sub.mqtt.prm { 5164 c.queueOutbound(data) 5165 } 5166 sub.mqtt.prm = nil 5167 } 5168 } 5169 c.flushSignal() 5170 c.mu.Unlock() 5171 } 5172 5173 func (c *client) mqttEnqueueSubAck(pi uint16, filters []*mqttFilter) { 5174 w := newMQTTWriter(7 + len(filters)) 5175 w.WriteByte(mqttPacketSubAck) 5176 // packet length is 2 (for packet identifier) and 1 byte per filter. 5177 w.WriteVarInt(2 + len(filters)) 5178 w.WriteUint16(pi) 5179 for _, f := range filters { 5180 w.WriteByte(f.qos) 5181 } 5182 c.mu.Lock() 5183 c.enqueueProto(w.Bytes()) 5184 c.mu.Unlock() 5185 } 5186 5187 ////////////////////////////////////////////////////////////////////////////// 5188 // 5189 // UNSUBSCRIBE related functions 5190 // 5191 ////////////////////////////////////////////////////////////////////////////// 5192 5193 func (c *client) mqttParseUnsubs(r *mqttReader, b byte, pl int) (uint16, []*mqttFilter, error) { 5194 return c.mqttParseSubsOrUnsubs(r, b, pl, false) 5195 } 5196 5197 // Process the UNSUBSCRIBE packet. 5198 // 5199 // Given the list of topics, this is going to unsubscribe the low level NATS subscriptions 5200 // and delete the JS durable consumers when applicable. 5201 // 5202 // Runs from the client's readLoop. 5203 // No lock held on entry. 5204 func (c *client) mqttProcessUnsubs(filters []*mqttFilter) error { 5205 // Those things are immutable, but since processing unsubs is not 5206 // really in the fast path, let's get them under the client lock. 5207 c.mu.Lock() 5208 asm := c.mqtt.asm 5209 sess := c.mqtt.sess 5210 c.mu.Unlock() 5211 5212 if err := asm.lockSession(sess, c); err != nil { 5213 return err 5214 } 5215 defer asm.unlockSession(sess) 5216 5217 removeJSCons := func(sid string) { 5218 cc, ok := sess.cons[sid] 5219 if ok { 5220 delete(sess.cons, sid) 5221 sess.deleteConsumer(cc) 5222 // Need lock here since these are accessed by callbacks 5223 sess.mu.Lock() 5224 if seqPis, ok := sess.cpending[cc.Durable]; ok { 5225 delete(sess.cpending, cc.Durable) 5226 for _, pi := range seqPis { 5227 delete(sess.pendingPublish, pi) 5228 } 5229 if len(sess.pendingPublish) == 0 { 5230 sess.last_pi = 0 5231 } 5232 } 5233 sess.mu.Unlock() 5234 } 5235 } 5236 for _, f := range filters { 5237 sid := f.filter 5238 // Remove JS Consumer if one exists for this sid 5239 removeJSCons(sid) 5240 if err := c.processUnsub([]byte(sid)); err != nil { 5241 c.Errorf("error unsubscribing from %q: %v", sid, err) 5242 } 5243 if mqttNeedSubForLevelUp(sid) { 5244 subject := sid[:len(sid)-2] 5245 sid = subject + mqttMultiLevelSidSuffix 5246 removeJSCons(sid) 5247 if err := c.processUnsub([]byte(sid)); err != nil { 5248 c.Errorf("error unsubscribing from %q: %v", subject, err) 5249 } 5250 } 5251 } 5252 return sess.update(filters, false) 5253 } 5254 5255 func (c *client) mqttEnqueueUnsubAck(pi uint16) { 5256 w := newMQTTWriter(4) 5257 w.WriteByte(mqttPacketUnsubAck) 5258 w.WriteVarInt(2) 5259 w.WriteUint16(pi) 5260 c.mu.Lock() 5261 c.enqueueProto(w.Bytes()) 5262 c.mu.Unlock() 5263 } 5264 5265 func mqttUnsubscribeTrace(pi uint16, filters []*mqttFilter) string { 5266 var sep string 5267 sb := strings.Builder{} 5268 sb.WriteString("[") 5269 for i, f := range filters { 5270 sb.WriteString(sep) 5271 sb.Write(f.ttopic) 5272 sb.WriteString(" (") 5273 sb.WriteString(f.filter) 5274 sb.WriteString(")") 5275 if i == 0 { 5276 sep = ", " 5277 } 5278 } 5279 sb.WriteString(fmt.Sprintf("] pi=%v", pi)) 5280 return sb.String() 5281 } 5282 5283 ////////////////////////////////////////////////////////////////////////////// 5284 // 5285 // PINGREQ/PINGRESP related functions 5286 // 5287 ////////////////////////////////////////////////////////////////////////////// 5288 5289 func (c *client) mqttEnqueuePingResp() { 5290 c.mu.Lock() 5291 c.enqueueProto(mqttPingResponse) 5292 c.mu.Unlock() 5293 } 5294 5295 ////////////////////////////////////////////////////////////////////////////// 5296 // 5297 // Trace functions 5298 // 5299 ////////////////////////////////////////////////////////////////////////////// 5300 5301 func errOrTrace(err error, trace string) []byte { 5302 if err != nil { 5303 return []byte(err.Error()) 5304 } 5305 return []byte(trace) 5306 } 5307 5308 ////////////////////////////////////////////////////////////////////////////// 5309 // 5310 // Subject/Topic conversion functions 5311 // 5312 ////////////////////////////////////////////////////////////////////////////// 5313 5314 // Converts an MQTT Topic Name to a NATS Subject (used by PUBLISH) 5315 // See mqttToNATSSubjectConversion() for details. 5316 func mqttTopicToNATSPubSubject(mt []byte) ([]byte, error) { 5317 return mqttToNATSSubjectConversion(mt, false) 5318 } 5319 5320 // Converts an MQTT Topic Filter to a NATS Subject (used by SUBSCRIBE) 5321 // See mqttToNATSSubjectConversion() for details. 5322 func mqttFilterToNATSSubject(filter []byte) ([]byte, error) { 5323 return mqttToNATSSubjectConversion(filter, true) 5324 } 5325 5326 // Converts an MQTT Topic Name or Filter to a NATS Subject. 5327 // In MQTT: 5328 // - a Topic Name does not have wildcard (PUBLISH uses only topic names). 5329 // - a Topic Filter can include wildcards (SUBSCRIBE uses those). 5330 // - '+' and '#' are wildcard characters (single and multiple levels respectively) 5331 // - '/' is the topic level separator. 5332 // 5333 // Conversion that occurs: 5334 // - '/' is replaced with '/.' if it is the first character in mt 5335 // - '/' is replaced with './' if the last or next character in mt is '/' 5336 // For instance, foo//bar would become foo./.bar 5337 // - '/' is replaced with '.' for all other conditions (foo/bar -> foo.bar) 5338 // - '.' is replaced with '//'. 5339 // - ' ' cause an error to be returned. 5340 // 5341 // If there is no need to convert anything (say "foo" remains "foo"), then 5342 // the no memory is allocated and the returned slice is the original `mt`. 5343 func mqttToNATSSubjectConversion(mt []byte, wcOk bool) ([]byte, error) { 5344 var cp bool 5345 var j int 5346 res := mt 5347 5348 makeCopy := func(i int) { 5349 cp = true 5350 res = make([]byte, 0, len(mt)+10) 5351 if i > 0 { 5352 res = append(res, mt[:i]...) 5353 } 5354 } 5355 5356 end := len(mt) - 1 5357 for i := 0; i < len(mt); i++ { 5358 switch mt[i] { 5359 case mqttTopicLevelSep: 5360 if i == 0 || res[j-1] == btsep { 5361 if !cp { 5362 makeCopy(0) 5363 } 5364 res = append(res, mqttTopicLevelSep, btsep) 5365 j++ 5366 } else if i == end || mt[i+1] == mqttTopicLevelSep { 5367 if !cp { 5368 makeCopy(i) 5369 } 5370 res = append(res, btsep, mqttTopicLevelSep) 5371 j++ 5372 } else { 5373 if !cp { 5374 makeCopy(i) 5375 } 5376 res = append(res, btsep) 5377 } 5378 case ' ': 5379 // As of now, we cannot support ' ' in the MQTT topic/filter. 5380 return nil, errMQTTUnsupportedCharacters 5381 case btsep: 5382 if !cp { 5383 makeCopy(i) 5384 } 5385 res = append(res, mqttTopicLevelSep, mqttTopicLevelSep) 5386 j++ 5387 case mqttSingleLevelWC, mqttMultiLevelWC: 5388 if !wcOk { 5389 // Spec [MQTT-3.3.2-2] and [MQTT-4.7.1-1] 5390 // The wildcard characters can be used in Topic Filters, but MUST NOT be used within a Topic Name 5391 return nil, fmt.Errorf("wildcards not allowed in publish's topic: %q", mt) 5392 } 5393 if !cp { 5394 makeCopy(i) 5395 } 5396 if mt[i] == mqttSingleLevelWC { 5397 res = append(res, pwc) 5398 } else { 5399 res = append(res, fwc) 5400 } 5401 default: 5402 if cp { 5403 res = append(res, mt[i]) 5404 } 5405 } 5406 j++ 5407 } 5408 if cp && res[j-1] == btsep { 5409 res = append(res, mqttTopicLevelSep) 5410 j++ 5411 } 5412 return res[:j], nil 5413 } 5414 5415 // Converts a NATS subject to MQTT topic. This is for publish 5416 // messages only, so there is no checking for wildcards. 5417 // Rules are reversed of mqttToNATSSubjectConversion. 5418 func natsSubjectToMQTTTopic(subject string) []byte { 5419 topic := []byte(subject) 5420 end := len(subject) - 1 5421 var j int 5422 for i := 0; i < len(subject); i++ { 5423 switch subject[i] { 5424 case mqttTopicLevelSep: 5425 if i < end { 5426 switch c := subject[i+1]; c { 5427 case btsep, mqttTopicLevelSep: 5428 if c == btsep { 5429 topic[j] = mqttTopicLevelSep 5430 } else { 5431 topic[j] = btsep 5432 } 5433 j++ 5434 i++ 5435 default: 5436 } 5437 } 5438 case btsep: 5439 topic[j] = mqttTopicLevelSep 5440 j++ 5441 default: 5442 topic[j] = subject[i] 5443 j++ 5444 } 5445 } 5446 return topic[:j] 5447 } 5448 5449 // Returns true if the subject has more than 1 token and ends with ".>" 5450 func mqttNeedSubForLevelUp(subject string) bool { 5451 if len(subject) < 3 { 5452 return false 5453 } 5454 end := len(subject) 5455 if subject[end-2] == '.' && subject[end-1] == fwc { 5456 return true 5457 } 5458 return false 5459 } 5460 5461 ////////////////////////////////////////////////////////////////////////////// 5462 // 5463 // MQTT Reader functions 5464 // 5465 ////////////////////////////////////////////////////////////////////////////// 5466 5467 func (r *mqttReader) reset(buf []byte) { 5468 if l := len(r.pbuf); l > 0 { 5469 tmp := make([]byte, l+len(buf)) 5470 copy(tmp, r.pbuf) 5471 copy(tmp[l:], buf) 5472 buf = tmp 5473 r.pbuf = nil 5474 } 5475 r.buf = buf 5476 r.pos = 0 5477 r.pstart = 0 5478 } 5479 5480 func (r *mqttReader) hasMore() bool { 5481 return r.pos != len(r.buf) 5482 } 5483 5484 func (r *mqttReader) readByte(field string) (byte, error) { 5485 if r.pos == len(r.buf) { 5486 return 0, fmt.Errorf("error reading %s: %v", field, io.EOF) 5487 } 5488 b := r.buf[r.pos] 5489 r.pos++ 5490 return b, nil 5491 } 5492 5493 func (r *mqttReader) readPacketLen() (int, bool, error) { 5494 return r.readPacketLenWithCheck(true) 5495 } 5496 5497 func (r *mqttReader) readPacketLenWithCheck(check bool) (int, bool, error) { 5498 m := 1 5499 v := 0 5500 for { 5501 var b byte 5502 if r.pos != len(r.buf) { 5503 b = r.buf[r.pos] 5504 r.pos++ 5505 } else { 5506 break 5507 } 5508 v += int(b&0x7f) * m 5509 if (b & 0x80) == 0 { 5510 if check && r.pos+v > len(r.buf) { 5511 break 5512 } 5513 return v, true, nil 5514 } 5515 m *= 0x80 5516 if m > 0x200000 { 5517 return 0, false, errMQTTMalformedVarInt 5518 } 5519 } 5520 r.pbuf = make([]byte, len(r.buf)-r.pstart) 5521 copy(r.pbuf, r.buf[r.pstart:]) 5522 return 0, false, nil 5523 } 5524 5525 func (r *mqttReader) readString(field string) (string, error) { 5526 var s string 5527 bs, err := r.readBytes(field, false) 5528 if err == nil { 5529 s = string(bs) 5530 } 5531 return s, err 5532 } 5533 5534 func (r *mqttReader) readBytes(field string, cp bool) ([]byte, error) { 5535 luint, err := r.readUint16(field) 5536 if err != nil { 5537 return nil, err 5538 } 5539 l := int(luint) 5540 if l == 0 { 5541 return nil, nil 5542 } 5543 start := r.pos 5544 if start+l > len(r.buf) { 5545 return nil, fmt.Errorf("error reading %s: %v", field, io.ErrUnexpectedEOF) 5546 } 5547 r.pos += l 5548 b := r.buf[start:r.pos] 5549 if cp { 5550 b = copyBytes(b) 5551 } 5552 return b, nil 5553 } 5554 5555 func (r *mqttReader) readUint16(field string) (uint16, error) { 5556 if len(r.buf)-r.pos < 2 { 5557 return 0, fmt.Errorf("error reading %s: %v", field, io.ErrUnexpectedEOF) 5558 } 5559 start := r.pos 5560 r.pos += 2 5561 return binary.BigEndian.Uint16(r.buf[start:r.pos]), nil 5562 } 5563 5564 ////////////////////////////////////////////////////////////////////////////// 5565 // 5566 // MQTT Writer functions 5567 // 5568 ////////////////////////////////////////////////////////////////////////////// 5569 5570 func (w *mqttWriter) WriteUint16(i uint16) { 5571 w.WriteByte(byte(i >> 8)) 5572 w.WriteByte(byte(i)) 5573 } 5574 5575 func (w *mqttWriter) WriteString(s string) { 5576 w.WriteBytes([]byte(s)) 5577 } 5578 5579 func (w *mqttWriter) WriteBytes(bs []byte) { 5580 w.WriteUint16(uint16(len(bs))) 5581 w.Write(bs) 5582 } 5583 5584 func (w *mqttWriter) WriteVarInt(value int) { 5585 for { 5586 b := byte(value & 0x7f) 5587 value >>= 7 5588 if value > 0 { 5589 b |= 0x80 5590 } 5591 w.WriteByte(b) 5592 if value == 0 { 5593 break 5594 } 5595 } 5596 } 5597 5598 func newMQTTWriter(cap int) *mqttWriter { 5599 w := &mqttWriter{} 5600 w.Grow(cap) 5601 return w 5602 }