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