get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/mqtt_test.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 //go:build !skip_mqtt_tests 15 // +build !skip_mqtt_tests 16 17 package server 18 19 import ( 20 "bufio" 21 "bytes" 22 "crypto/tls" 23 "encoding/json" 24 "errors" 25 "fmt" 26 "io" 27 "math/rand" 28 "net" 29 "os" 30 "reflect" 31 "strings" 32 "sync" 33 "testing" 34 "time" 35 36 "github.com/nats-io/jwt/v2" 37 "github.com/nats-io/nats.go" 38 "github.com/nats-io/nkeys" 39 "github.com/nats-io/nuid" 40 ) 41 42 var testMQTTTimeout = 10 * time.Second 43 44 var jsClusterTemplWithLeafAndMQTT = ` 45 listen: 127.0.0.1:-1 46 server_name: %s 47 jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'} 48 49 {{leaf}} 50 51 cluster { 52 name: %s 53 listen: 127.0.0.1:%d 54 routes = [%s] 55 } 56 57 mqtt { 58 listen: 127.0.0.1:-1 59 } 60 61 # For access to system account. 62 accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } } 63 ` 64 65 type mqttWrapAsWs struct { 66 net.Conn 67 t testing.TB 68 br *bufio.Reader 69 tmp []byte 70 } 71 72 func (c *mqttWrapAsWs) Write(p []byte) (int, error) { 73 proto := testWSCreateClientMsg(wsBinaryMessage, 1, true, false, p) 74 return c.Conn.Write(proto) 75 } 76 77 func (c *mqttWrapAsWs) Read(p []byte) (int, error) { 78 for { 79 if n := len(c.tmp); n > 0 { 80 if len(p) < n { 81 n = len(p) 82 } 83 copy(p, c.tmp[:n]) 84 c.tmp = c.tmp[n:] 85 return n, nil 86 } 87 c.tmp = testWSReadFrame(c.t, c.br) 88 } 89 } 90 91 func testMQTTReadPacket(t testing.TB, r *mqttReader) (byte, int) { 92 t.Helper() 93 94 var b byte 95 var pl int 96 var err error 97 98 rd := r.reader 99 100 fill := func() []byte { 101 t.Helper() 102 var buf [512]byte 103 104 n, err := rd.Read(buf[:]) 105 if err != nil { 106 t.Fatalf("Error reading data: %v", err) 107 } 108 return copyBytes(buf[:n]) 109 } 110 111 rd.SetReadDeadline(time.Now().Add(testMQTTTimeout)) 112 for { 113 r.pstart = r.pos 114 if !r.hasMore() { 115 r.reset(fill()) 116 continue 117 } 118 b, err = r.readByte("packet type") 119 if err != nil { 120 t.Fatalf("Error reading packet: %v", err) 121 } 122 var complete bool 123 pl, complete, err = r.readPacketLen() 124 if err != nil { 125 t.Fatalf("Error reading packet: %v", err) 126 } 127 if !complete { 128 r.reset(fill()) 129 continue 130 } 131 break 132 } 133 rd.SetReadDeadline(time.Time{}) 134 return b, pl 135 } 136 137 func testMQTTReadPIPacket(expectedType byte, t testing.TB, r *mqttReader, expectedPI uint16) { 138 t.Helper() 139 b, _ := testMQTTReadPacket(t, r) 140 if pt := b & mqttPacketMask; pt != expectedType { 141 t.Fatalf("Expected packet %x, got %x", expectedType, pt) 142 } 143 rpi, err := r.readUint16("packet identifier") 144 if err != nil || rpi != expectedPI { 145 t.Fatalf("Expected PI %v got: %v, err=%v", expectedPI, rpi, err) 146 } 147 } 148 149 func TestMQTTReader(t *testing.T) { 150 r := &mqttReader{} 151 r.reset([]byte{0, 2, 'a', 'b'}) 152 bs, err := r.readBytes("", false) 153 if err != nil { 154 t.Fatal(err) 155 } 156 sbs := string(bs) 157 if sbs != "ab" { 158 t.Fatalf(`expected "ab", got %q`, sbs) 159 } 160 161 r.reset([]byte{0, 2, 'a', 'b'}) 162 bs, err = r.readBytes("", true) 163 if err != nil { 164 t.Fatal(err) 165 } 166 bs[0], bs[1] = 'c', 'd' 167 if bytes.Equal(bs, r.buf[2:]) { 168 t.Fatal("readBytes should have returned a copy") 169 } 170 171 r.reset([]byte{'a', 'b'}) 172 if b, err := r.readByte(""); err != nil || b != 'a' { 173 t.Fatalf("Error reading byte: b=%v err=%v", b, err) 174 } 175 if !r.hasMore() { 176 t.Fatal("expected to have more, did not") 177 } 178 if b, err := r.readByte(""); err != nil || b != 'b' { 179 t.Fatalf("Error reading byte: b=%v err=%v", b, err) 180 } 181 if r.hasMore() { 182 t.Fatal("expected to not have more") 183 } 184 if _, err := r.readByte("test"); err == nil || !strings.Contains(err.Error(), "error reading test") { 185 t.Fatalf("unexpected error: %v", err) 186 } 187 188 r.reset([]byte{0, 2, 'a', 'b'}) 189 if s, err := r.readString(""); err != nil || s != "ab" { 190 t.Fatalf("Error reading string: s=%q err=%v", s, err) 191 } 192 193 r.reset([]byte{10}) 194 if _, err := r.readUint16("uint16"); err == nil || !strings.Contains(err.Error(), "error reading uint16") { 195 t.Fatalf("unexpected error: %v", err) 196 } 197 198 r.reset([]byte{0x82, 0xff, 0x3}) 199 l, _, err := r.readPacketLenWithCheck(false) 200 if err != nil { 201 t.Fatal("error getting packet len") 202 } 203 if l != 0xff82 { 204 t.Fatalf("expected length 0xff82 got 0x%x", l) 205 } 206 r.reset([]byte{0xff, 0xff, 0xff, 0xff, 0xff}) 207 if _, _, err := r.readPacketLenWithCheck(false); err == nil || !strings.Contains(err.Error(), "malformed") { 208 t.Fatalf("unexpected error: %v", err) 209 } 210 211 r.reset([]byte{0, 2, 'a', 'b', mqttPacketPub, 0x82, 0xff, 0x3}) 212 r.readString("") 213 for i := 0; i < 2; i++ { 214 r.pstart = r.pos 215 b, err := r.readByte("") 216 if err != nil { 217 t.Fatalf("Error reading byte: %v", err) 218 } 219 if pt := b & mqttPacketMask; pt != mqttPacketPub { 220 t.Fatalf("Unexpected byte: %v", b) 221 } 222 pl, complete, err := r.readPacketLen() 223 if err != nil { 224 t.Fatalf("Unexpected error: %v", err) 225 } 226 if complete { 227 t.Fatal("Expected to be incomplete") 228 } 229 if pl != 0 { 230 t.Fatalf("Expected pl to be 0, got %v", pl) 231 } 232 if i > 0 { 233 break 234 } 235 if !bytes.Equal(r.pbuf, []byte{mqttPacketPub, 0x82, 0xff, 0x3}) { 236 t.Fatalf("Invalid recorded partial: %v", r.pbuf) 237 } 238 r.reset([]byte{'a', 'b', 'c'}) 239 if !bytes.Equal(r.buf, []byte{mqttPacketPub, 0x82, 0xff, 0x3, 'a', 'b', 'c'}) { 240 t.Fatalf("Invalid buffer: %v", r.buf) 241 } 242 if r.pbuf != nil { 243 t.Fatalf("Partial buffer should have been reset, got %v", r.pbuf) 244 } 245 if r.pos != 0 { 246 t.Fatalf("Pos should have been reset, got %v", r.pos) 247 } 248 if r.pstart != 0 { 249 t.Fatalf("Pstart should have been reset, got %v", r.pstart) 250 } 251 } 252 // On second pass, the pbuf should have been extended with 'abc' 253 if !bytes.Equal(r.pbuf, []byte{mqttPacketPub, 0x82, 0xff, 0x3, 'a', 'b', 'c'}) { 254 t.Fatalf("Invalid recorded partial: %v", r.pbuf) 255 } 256 } 257 258 func TestMQTTWriter(t *testing.T) { 259 w := newMQTTWriter(0) 260 w.WriteUint16(1234) 261 262 r := &mqttReader{} 263 r.reset(w.Bytes()) 264 if v, err := r.readUint16(""); err != nil || v != 1234 { 265 t.Fatalf("unexpected value: v=%v err=%v", v, err) 266 } 267 268 w.Reset() 269 w.WriteString("test") 270 r.reset(w.Bytes()) 271 if len(r.buf) != 6 { 272 t.Fatalf("Expected 2 bytes size before string, got %v", r.buf) 273 } 274 275 w.Reset() 276 w.WriteBytes([]byte("test")) 277 r.reset(w.Bytes()) 278 if len(r.buf) != 6 { 279 t.Fatalf("Expected 2 bytes size before bytes, got %v", r.buf) 280 } 281 282 ints := []int{ 283 0, 1, 127, 128, 16383, 16384, 2097151, 2097152, 268435455, 284 } 285 lens := []int{ 286 1, 1, 1, 2, 2, 3, 3, 4, 4, 287 } 288 289 tl := 0 290 w.Reset() 291 for i, v := range ints { 292 w.WriteVarInt(v) 293 tl += lens[i] 294 if tl != w.Len() { 295 t.Fatalf("expected len %d, got %d", tl, w.Len()) 296 } 297 } 298 299 r.reset(w.Bytes()) 300 for _, v := range ints { 301 x, _, _ := r.readPacketLenWithCheck(false) 302 if v != x { 303 t.Fatalf("expected %d, got %d", v, x) 304 } 305 } 306 } 307 308 func testMQTTDefaultOptions() *Options { 309 o := DefaultOptions() 310 o.ServerName = nuid.Next() 311 o.Cluster.Port = 0 312 o.Gateway.Name = "" 313 o.Gateway.Port = 0 314 o.LeafNode.Port = 0 315 o.Websocket.Port = 0 316 o.MQTT.Host = "127.0.0.1" 317 o.MQTT.Port = -1 318 o.JetStream = true 319 return o 320 } 321 322 func testMQTTRunServer(t testing.TB, o *Options) *Server { 323 t.Helper() 324 o.NoLog = false 325 if o.StoreDir == _EMPTY_ { 326 o.StoreDir = t.TempDir() 327 } 328 s, err := NewServer(o) 329 if err != nil { 330 t.Fatalf("Error creating server: %v", err) 331 } 332 l := &DummyLogger{} 333 s.SetLogger(l, true, true) 334 s.Start() 335 if err := s.readyForConnections(3 * time.Second); err != nil { 336 testMQTTShutdownServer(s) 337 t.Fatal(err) 338 } 339 return s 340 } 341 342 func testMQTTShutdownRestartedServer(s **Server) { 343 srv := *s 344 testMQTTShutdownServer(srv) 345 *s = nil 346 } 347 348 func testMQTTShutdownServer(s *Server) { 349 if c := s.JetStreamConfig(); c != nil { 350 dir := strings.TrimSuffix(c.StoreDir, JetStreamStoreDir) 351 defer os.RemoveAll(dir) 352 } 353 s.Shutdown() 354 } 355 356 func testMQTTDefaultTLSOptions(t *testing.T, verify bool) *Options { 357 t.Helper() 358 o := testMQTTDefaultOptions() 359 tc := &TLSConfigOpts{ 360 CertFile: "../test/configs/certs/server-cert.pem", 361 KeyFile: "../test/configs/certs/server-key.pem", 362 CaFile: "../test/configs/certs/ca.pem", 363 Verify: verify, 364 } 365 var err error 366 o.MQTT.TLSConfig, err = GenTLSConfig(tc) 367 o.MQTT.TLSTimeout = 2.0 368 if err != nil { 369 t.Fatalf("Error creating tls config: %v", err) 370 } 371 return o 372 } 373 374 func TestMQTTServerNameRequired(t *testing.T) { 375 conf := createConfFile(t, []byte(` 376 cluster { 377 port: -1 378 } 379 mqtt { 380 port: -1 381 } 382 `)) 383 o, err := ProcessConfigFile(conf) 384 if err != nil { 385 t.Fatalf("Error processing config file: %v", err) 386 } 387 if _, err := NewServer(o); err == nil || err.Error() != errMQTTServerNameMustBeSet.Error() { 388 t.Fatalf("Expected error about requiring server name to be set, got %v", err) 389 } 390 391 conf = createConfFile(t, []byte(` 392 mqtt { 393 port: -1 394 } 395 `)) 396 o, err = ProcessConfigFile(conf) 397 if err != nil { 398 t.Fatalf("Error processing config file: %v", err) 399 } 400 if _, err := NewServer(o); err == nil || err.Error() != errMQTTStandaloneNeedsJetStream.Error() { 401 t.Fatalf(`Expected errMQTTStandaloneNeedsJetStream ("next in line"), got %v`, err) 402 } 403 } 404 405 func TestMQTTStandaloneRequiresJetStream(t *testing.T) { 406 conf := createConfFile(t, []byte(` 407 server_name: mqtt 408 mqtt { 409 port: -1 410 tls { 411 cert_file: "./configs/certs/server.pem" 412 key_file: "./configs/certs/key.pem" 413 } 414 } 415 `)) 416 o, err := ProcessConfigFile(conf) 417 if err != nil { 418 t.Fatalf("Error processing config file: %v", err) 419 } 420 if _, err := NewServer(o); err == nil || err.Error() != errMQTTStandaloneNeedsJetStream.Error() { 421 t.Fatalf("Expected error about requiring JetStream in standalone mode, got %v", err) 422 } 423 } 424 425 func TestMQTTConfig(t *testing.T) { 426 conf := createConfFile(t, []byte(fmt.Sprintf(` 427 jetstream { 428 store_dir = %q 429 } 430 server_name: mqtt 431 mqtt { 432 port: -1 433 tls { 434 cert_file: "./configs/certs/server.pem" 435 key_file: "./configs/certs/key.pem" 436 } 437 } 438 `, t.TempDir()))) 439 s, o := RunServerWithConfig(conf) 440 defer testMQTTShutdownServer(s) 441 if o.MQTT.TLSConfig == nil { 442 t.Fatal("expected TLS config to be set") 443 } 444 } 445 446 func TestMQTTValidateOptions(t *testing.T) { 447 nmqtto := DefaultOptions() 448 mqtto := testMQTTDefaultOptions() 449 for _, test := range []struct { 450 name string 451 getOpts func() *Options 452 err error 453 }{ 454 {"mqtt disabled", func() *Options { return nmqtto.Clone() }, nil}, 455 {"mqtt username not allowed if users specified", func() *Options { 456 o := mqtto.Clone() 457 o.Users = []*User{{Username: "abc", Password: "pwd"}} 458 o.MQTT.Username = "b" 459 o.MQTT.Password = "pwd" 460 return o 461 }, errMQTTUserMixWithUsersNKeys}, 462 {"mqtt token not allowed if users specified", func() *Options { 463 o := mqtto.Clone() 464 o.Nkeys = []*NkeyUser{{Nkey: "abc"}} 465 o.MQTT.Token = "mytoken" 466 return o 467 }, errMQTTTokenMixWIthUsersNKeys}, 468 {"ack wait should be >=0", func() *Options { 469 o := mqtto.Clone() 470 o.MQTT.AckWait = -10 * time.Second 471 return o 472 }, errMQTTAckWaitMustBePositive}, 473 } { 474 t.Run(test.name, func(t *testing.T) { 475 err := validateMQTTOptions(test.getOpts()) 476 if test.err == nil && err != nil { 477 t.Fatalf("Unexpected error: %v", err) 478 } else if test.err != nil && (err == nil || err.Error() != test.err.Error()) { 479 t.Fatalf("Expected error to contain %q, got %v", test.err, err) 480 } 481 }) 482 } 483 } 484 485 func TestMQTTParseOptions(t *testing.T) { 486 for _, test := range []struct { 487 name string 488 content string 489 checkOpt func(*MQTTOpts) error 490 err string 491 }{ 492 // Negative tests 493 {"bad type", "mqtt: []", nil, "to be a map"}, 494 {"bad listen", "mqtt: { listen: [] }", nil, "port or host:port"}, 495 {"bad port", `mqtt: { port: "abc" }`, nil, "not int64"}, 496 {"bad host", `mqtt: { host: 123 }`, nil, "not string"}, 497 {"bad tls", `mqtt: { tls: 123 }`, nil, "not map[string]interface {}"}, 498 {"unknown field", `mqtt: { this_does_not_exist: 123 }`, nil, "unknown"}, 499 {"ack wait", `mqtt: {ack_wait: abc}`, nil, "invalid duration"}, 500 {"max ack pending", `mqtt: {max_ack_pending: abc}`, nil, "not int64"}, 501 {"max ack pending too high", `mqtt: {max_ack_pending: 12345678}`, nil, "invalid value"}, 502 // Positive tests 503 {"tls gen fails", ` 504 mqtt { 505 tls { 506 cert_file: "./configs/certs/server.pem" 507 } 508 }`, nil, "missing 'key_file'"}, 509 {"listen port only", `mqtt { listen: 1234 }`, func(o *MQTTOpts) error { 510 if o.Port != 1234 { 511 return fmt.Errorf("expected 1234, got %v", o.Port) 512 } 513 return nil 514 }, ""}, 515 {"listen host and port", `mqtt { listen: "localhost:1234" }`, func(o *MQTTOpts) error { 516 if o.Host != "localhost" || o.Port != 1234 { 517 return fmt.Errorf("expected localhost:1234, got %v:%v", o.Host, o.Port) 518 } 519 return nil 520 }, ""}, 521 {"host", `mqtt { host: "localhost" }`, func(o *MQTTOpts) error { 522 if o.Host != "localhost" { 523 return fmt.Errorf("expected localhost, got %v", o.Host) 524 } 525 return nil 526 }, ""}, 527 {"port", `mqtt { port: 1234 }`, func(o *MQTTOpts) error { 528 if o.Port != 1234 { 529 return fmt.Errorf("expected 1234, got %v", o.Port) 530 } 531 return nil 532 }, ""}, 533 {"tls config", 534 ` 535 mqtt { 536 tls { 537 cert_file: "./configs/certs/server.pem" 538 key_file: "./configs/certs/key.pem" 539 } 540 } 541 `, func(o *MQTTOpts) error { 542 if o.TLSConfig == nil { 543 return fmt.Errorf("TLSConfig should have been set") 544 } 545 return nil 546 }, ""}, 547 {"no auth user", 548 ` 549 mqtt { 550 no_auth_user: "noauthuser" 551 } 552 `, func(o *MQTTOpts) error { 553 if o.NoAuthUser != "noauthuser" { 554 return fmt.Errorf("Invalid NoAuthUser value: %q", o.NoAuthUser) 555 } 556 return nil 557 }, ""}, 558 {"auth block", 559 ` 560 mqtt { 561 authorization { 562 user: "mqttuser" 563 password: "pwd" 564 token: "token" 565 timeout: 2.0 566 } 567 } 568 `, func(o *MQTTOpts) error { 569 if o.Username != "mqttuser" || o.Password != "pwd" || o.Token != "token" || o.AuthTimeout != 2.0 { 570 return fmt.Errorf("Invalid auth block: %+v", o) 571 } 572 return nil 573 }, ""}, 574 {"auth timeout as int", 575 ` 576 mqtt { 577 authorization { 578 timeout: 2 579 } 580 } 581 `, func(o *MQTTOpts) error { 582 if o.AuthTimeout != 2.0 { 583 return fmt.Errorf("Invalid auth timeout: %v", o.AuthTimeout) 584 } 585 return nil 586 }, ""}, 587 {"ack wait", 588 ` 589 mqtt { 590 ack_wait: "10s" 591 } 592 `, func(o *MQTTOpts) error { 593 if o.AckWait != 10*time.Second { 594 return fmt.Errorf("Invalid ack wait: %v", o.AckWait) 595 } 596 return nil 597 }, ""}, 598 {"max ack pending", 599 ` 600 mqtt { 601 max_ack_pending: 123 602 } 603 `, func(o *MQTTOpts) error { 604 if o.MaxAckPending != 123 { 605 return fmt.Errorf("Invalid max ack pending: %v", o.MaxAckPending) 606 } 607 return nil 608 }, ""}, 609 {"reject_qos2_publish", 610 ` 611 mqtt { 612 reject_qos2_publish: true 613 } 614 `, func(o *MQTTOpts) error { 615 if !o.rejectQoS2Pub { 616 return fmt.Errorf("Invalid: expected rejectQoS2Pub to be set") 617 } 618 return nil 619 }, ""}, 620 {"downgrade_qos2_subscribe", 621 ` 622 mqtt { 623 downgrade_qos2_subscribe: true 624 } 625 `, func(o *MQTTOpts) error { 626 if !o.downgradeQoS2Sub { 627 return fmt.Errorf("Invalid: expected downgradeQoS2Sub to be set") 628 } 629 return nil 630 }, ""}, 631 } { 632 t.Run(test.name, func(t *testing.T) { 633 conf := createConfFile(t, []byte(test.content)) 634 o, err := ProcessConfigFile(conf) 635 if test.err != _EMPTY_ { 636 if err == nil || !strings.Contains(err.Error(), test.err) { 637 t.Fatalf("For content: %q, expected error about %q, got %v", test.content, test.err, err) 638 } 639 return 640 } else if err != nil { 641 t.Fatalf("Unexpected error for content %q: %v", test.content, err) 642 } 643 if err := test.checkOpt(&o.MQTT); err != nil { 644 t.Fatalf("Incorrect option for content %q: %v", test.content, err.Error()) 645 } 646 }) 647 } 648 } 649 650 func TestMQTTStart(t *testing.T) { 651 o := testMQTTDefaultOptions() 652 s := testMQTTRunServer(t, o) 653 defer testMQTTShutdownServer(s) 654 655 nc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port)) 656 if err != nil { 657 t.Fatalf("Unable to create tcp connection to mqtt port: %v", err) 658 } 659 nc.Close() 660 661 // Check failure to start due to port in use 662 o2 := testMQTTDefaultOptions() 663 o2.MQTT.Port = o.MQTT.Port 664 s2, err := NewServer(o2) 665 if err != nil { 666 t.Fatalf("Error creating server: %v", err) 667 } 668 defer s2.Shutdown() 669 l := &captureFatalLogger{fatalCh: make(chan string, 1)} 670 s2.SetLogger(l, false, false) 671 672 wg := sync.WaitGroup{} 673 wg.Add(1) 674 go func() { 675 s2.Start() 676 wg.Done() 677 }() 678 679 select { 680 case e := <-l.fatalCh: 681 if !strings.Contains(e, "Unable to listen for MQTT connections") { 682 t.Fatalf("Unexpected error: %q", e) 683 } 684 case <-time.After(time.Second): 685 t.Fatal("Should have gotten a fatal error") 686 } 687 } 688 689 func TestMQTTTLS(t *testing.T) { 690 o := testMQTTDefaultTLSOptions(t, false) 691 s := testMQTTRunServer(t, o) 692 defer testMQTTShutdownServer(s) 693 694 c, _, err := testMQTTConnectRetryWithError(t, &mqttConnInfo{tls: true}, o.MQTT.Host, o.MQTT.Port, 0) 695 if err != nil { 696 t.Fatal(err) 697 } 698 c.Close() 699 c = nil 700 testMQTTShutdownServer(s) 701 702 // Force client cert verification 703 o = testMQTTDefaultTLSOptions(t, true) 704 s = testMQTTRunServer(t, o) 705 defer testMQTTShutdownServer(s) 706 707 c, _, err = testMQTTConnectRetryWithError(t, &mqttConnInfo{tls: true}, o.MQTT.Host, o.MQTT.Port, 0) 708 if err == nil || c != nil { 709 if c != nil { 710 c.Close() 711 } 712 t.Fatal("Handshake expected to fail since client did not provide cert") 713 } 714 715 // Add client cert. 716 tc := &TLSConfigOpts{ 717 CertFile: "../test/configs/certs/client-cert.pem", 718 KeyFile: "../test/configs/certs/client-key.pem", 719 } 720 tlsc, err := GenTLSConfig(tc) 721 if err != nil { 722 t.Fatalf("Error generating tls config: %v", err) 723 } 724 tlsc.InsecureSkipVerify = true 725 c, _, err = testMQTTConnectRetryWithError(t, &mqttConnInfo{ 726 tls: true, 727 tlsc: tlsc, 728 }, o.MQTT.Host, o.MQTT.Port, 0) 729 if err != nil { 730 t.Fatal(err) 731 } 732 c.Close() 733 c = nil 734 testMQTTShutdownServer(s) 735 736 // Lower TLS timeout so low that we should fail 737 o.MQTT.TLSTimeout = 0.001 738 s = testMQTTRunServer(t, o) 739 defer testMQTTShutdownServer(s) 740 741 nc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port)) 742 if err != nil { 743 t.Fatalf("Unable to create tcp connection to mqtt port: %v", err) 744 } 745 defer nc.Close() 746 time.Sleep(100 * time.Millisecond) 747 tlsConn := tls.Client(nc, tlsc) 748 tlsConn.SetDeadline(time.Now().Add(time.Second)) 749 if err := tlsConn.Handshake(); err == nil { 750 t.Fatal("Expected failure, did not get one") 751 } 752 } 753 754 type mqttConnInfo struct { 755 clientID string 756 cleanSess bool 757 keepAlive uint16 758 will *mqttWill 759 user string 760 pass string 761 ws bool 762 tls bool 763 tlsc *tls.Config 764 } 765 766 func testMQTTGetClient(t testing.TB, s *Server, clientID string) *client { 767 t.Helper() 768 var mc *client 769 s.mu.Lock() 770 for _, c := range s.clients { 771 c.mu.Lock() 772 if c.isMqtt() && c.mqtt.cid == clientID { 773 mc = c 774 } 775 c.mu.Unlock() 776 if mc != nil { 777 break 778 } 779 } 780 s.mu.Unlock() 781 if mc == nil { 782 t.Fatalf("Did not find client %q", clientID) 783 } 784 return mc 785 } 786 787 func testMQTTRead(c net.Conn) ([]byte, error) { 788 var buf [512]byte 789 // Make sure that test does not block 790 c.SetReadDeadline(time.Now().Add(testMQTTTimeout)) 791 n, err := c.Read(buf[:]) 792 if err != nil { 793 return nil, err 794 } 795 c.SetReadDeadline(time.Time{}) 796 return copyBytes(buf[:n]), nil 797 } 798 799 func testMQTTWrite(c net.Conn, buf []byte) (int, error) { 800 c.SetWriteDeadline(time.Now().Add(testMQTTTimeout)) 801 n, err := c.Write(buf) 802 c.SetWriteDeadline(time.Time{}) 803 return n, err 804 } 805 806 func testMQTTConnect(t testing.TB, ci *mqttConnInfo, host string, port int) (net.Conn, *mqttReader) { 807 t.Helper() 808 return testMQTTConnectRetry(t, ci, host, port, 0) 809 } 810 811 func testMQTTConnectRetry(t testing.TB, ci *mqttConnInfo, host string, port int, retryCount int) (net.Conn, *mqttReader) { 812 t.Helper() 813 c, r, err := testMQTTConnectRetryWithError(t, ci, host, port, retryCount) 814 if err != nil { 815 t.Fatal(err) 816 } 817 return c, r 818 } 819 820 func testMQTTConnectRetryWithError(t testing.TB, ci *mqttConnInfo, host string, port int, retryCount int) (net.Conn, *mqttReader, error) { 821 retry := func(c net.Conn) bool { 822 if c != nil { 823 c.Close() 824 } 825 if retryCount == 0 { 826 return false 827 } 828 time.Sleep(time.Second) 829 retryCount-- 830 return true 831 } 832 833 addr := fmt.Sprintf("%s:%d", host, port) 834 var c net.Conn 835 var err error 836 RETRY: 837 if ci.ws { 838 var br *bufio.Reader 839 c, br, _, err = testNewWSClientWithError(t, testWSClientOptions{ 840 host: host, 841 port: port, 842 noTLS: !ci.tls, 843 path: mqttWSPath, 844 }) 845 if err == nil { 846 c = &mqttWrapAsWs{Conn: c, t: t, br: br} 847 } 848 } else { 849 c, err = net.Dial("tcp", addr) 850 if err == nil && ci.tls { 851 tc := ci.tlsc 852 if tc == nil { 853 tc = &tls.Config{InsecureSkipVerify: true} 854 } 855 c = tls.Client(c, tc) 856 c.SetDeadline(time.Now().Add(time.Second)) 857 err = c.(*tls.Conn).Handshake() 858 c.SetDeadline(time.Time{}) 859 } 860 } 861 if err != nil { 862 if retry(c) { 863 goto RETRY 864 } 865 return nil, nil, fmt.Errorf("Error creating mqtt connection: %v", err) 866 } 867 868 proto := mqttCreateConnectProto(ci) 869 if _, err := testMQTTWrite(c, proto); err != nil { 870 if retry(c) { 871 goto RETRY 872 } 873 return nil, nil, fmt.Errorf("Error writing connect: %v", err) 874 } 875 876 buf, err := testMQTTRead(c) 877 if err != nil { 878 if retry(c) { 879 goto RETRY 880 } 881 return nil, nil, fmt.Errorf("Error reading: %v", err) 882 } 883 mr := &mqttReader{reader: c} 884 mr.reset(buf) 885 886 return c, mr, nil 887 } 888 889 func mqttCreateConnectProto(ci *mqttConnInfo) []byte { 890 flags := byte(0) 891 if ci.cleanSess { 892 flags |= mqttConnFlagCleanSession 893 } 894 if ci.will != nil { 895 flags |= mqttConnFlagWillFlag | (ci.will.qos << 3) 896 if ci.will.retain { 897 flags |= mqttConnFlagWillRetain 898 } 899 } 900 if ci.user != _EMPTY_ { 901 flags |= mqttConnFlagUsernameFlag 902 } 903 if ci.pass != _EMPTY_ { 904 flags |= mqttConnFlagPasswordFlag 905 } 906 907 pkLen := 2 + len(mqttProtoName) + 908 1 + // proto level 909 1 + // flags 910 2 + // keepAlive 911 2 + len(ci.clientID) 912 913 if ci.will != nil { 914 pkLen += 2 + len(ci.will.topic) 915 pkLen += 2 + len(ci.will.message) 916 } 917 if ci.user != _EMPTY_ { 918 pkLen += 2 + len(ci.user) 919 } 920 if ci.pass != _EMPTY_ { 921 pkLen += 2 + len(ci.pass) 922 } 923 924 w := newMQTTWriter(0) 925 w.WriteByte(mqttPacketConnect) 926 w.WriteVarInt(pkLen) 927 w.WriteString(string(mqttProtoName)) 928 w.WriteByte(0x4) 929 w.WriteByte(flags) 930 w.WriteUint16(ci.keepAlive) 931 w.WriteString(ci.clientID) 932 if ci.will != nil { 933 w.WriteBytes(ci.will.topic) 934 w.WriteBytes(ci.will.message) 935 } 936 if ci.user != _EMPTY_ { 937 w.WriteString(ci.user) 938 } 939 if ci.pass != _EMPTY_ { 940 w.WriteBytes([]byte(ci.pass)) 941 } 942 return w.Bytes() 943 } 944 945 func testMQTTCheckConnAck(t testing.TB, r *mqttReader, rc byte, sessionPresent bool) { 946 t.Helper() 947 b, pl := testMQTTReadPacket(t, r) 948 pt := b & mqttPacketMask 949 if pt != mqttPacketConnectAck { 950 t.Fatalf("Expected ConnAck (%x), got %x", mqttPacketConnectAck, pt) 951 } 952 if pl != 2 { 953 t.Fatalf("ConnAck packet length should be 2, got %v", pl) 954 } 955 caf, err := r.readByte("connack flags") 956 if err != nil { 957 t.Fatalf("Error reading packet length: %v", err) 958 } 959 if caf&0xfe != 0 { 960 t.Fatalf("ConnAck flag bits 7-1 should all be 0, got %x", caf>>1) 961 } 962 if sp := caf == 1; sp != sessionPresent { 963 t.Fatalf("Expected session present flag=%v got %v", sessionPresent, sp) 964 } 965 carc, err := r.readByte("connack return code") 966 if err != nil { 967 t.Fatalf("Error reading returned code: %v", err) 968 } 969 if carc != rc { 970 t.Fatalf("Expected return code to be %v, got %v", rc, carc) 971 } 972 } 973 974 func testMQTTCheckPubAck(t testing.TB, r *mqttReader, packetType byte) { 975 t.Helper() 976 b, pl := testMQTTReadPacket(t, r) 977 pt := b & mqttPacketMask 978 if pt != packetType { 979 t.Fatalf("Expected %x, got %x", packetType, pt) 980 } 981 r.pos += pl 982 } 983 984 func TestMQTTRequiresJSEnabled(t *testing.T) { 985 o := testMQTTDefaultOptions() 986 acc := NewAccount("mqtt") 987 o.Accounts = []*Account{acc} 988 o.Users = []*User{{Username: "mqtt", Account: acc}} 989 s := testMQTTRunServer(t, o) 990 defer testMQTTShutdownServer(s) 991 992 addr := fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port) 993 c, err := net.Dial("tcp", addr) 994 if err != nil { 995 t.Fatalf("Error creating mqtt connection: %v", err) 996 } 997 defer c.Close() 998 999 proto := mqttCreateConnectProto(&mqttConnInfo{cleanSess: true, user: "mqtt"}) 1000 if _, err := testMQTTWrite(c, proto); err != nil { 1001 t.Fatalf("Error writing connect: %v", err) 1002 } 1003 if _, err := testMQTTRead(c); err == nil { 1004 t.Fatal("Expected failure, did not get one") 1005 } 1006 } 1007 1008 func testMQTTEnableJSForAccount(t *testing.T, s *Server, accName string) { 1009 t.Helper() 1010 acc, err := s.LookupAccount(accName) 1011 if err != nil { 1012 t.Fatalf("Error looking up account: %v", err) 1013 } 1014 limits := map[string]JetStreamAccountLimits{ 1015 _EMPTY_: { 1016 MaxConsumers: -1, 1017 MaxStreams: -1, 1018 MaxMemory: 1024 * 1024, 1019 MaxStore: 1024 * 1024, 1020 }, 1021 } 1022 if err := acc.EnableJetStream(limits); err != nil { 1023 t.Fatalf("Error enabling JS: %v", err) 1024 } 1025 } 1026 1027 func TestMQTTTLSVerifyAndMap(t *testing.T) { 1028 accName := "MyAccount" 1029 acc := NewAccount(accName) 1030 certUserName := "CN=example.com,OU=NATS.io" 1031 users := []*User{{Username: certUserName, Account: acc}} 1032 1033 for _, test := range []struct { 1034 name string 1035 filtering bool 1036 provideCert bool 1037 }{ 1038 {"no filtering, client provides cert", false, true}, 1039 {"no filtering, client does not provide cert", false, false}, 1040 {"filtering, client provides cert", true, true}, 1041 {"filtering, client does not provide cert", true, false}, 1042 } { 1043 t.Run(test.name, func(t *testing.T) { 1044 o := testMQTTDefaultOptions() 1045 o.Host = "localhost" 1046 o.Accounts = []*Account{acc} 1047 o.Users = users 1048 if test.filtering { 1049 o.Users[0].AllowedConnectionTypes = testCreateAllowedConnectionTypes([]string{jwt.ConnectionTypeStandard, jwt.ConnectionTypeMqtt}) 1050 } 1051 tc := &TLSConfigOpts{ 1052 CertFile: "../test/configs/certs/tlsauth/server.pem", 1053 KeyFile: "../test/configs/certs/tlsauth/server-key.pem", 1054 CaFile: "../test/configs/certs/tlsauth/ca.pem", 1055 Verify: true, 1056 } 1057 tlsc, err := GenTLSConfig(tc) 1058 if err != nil { 1059 t.Fatalf("Error creating tls config: %v", err) 1060 } 1061 o.MQTT.TLSConfig = tlsc 1062 o.MQTT.TLSTimeout = 2.0 1063 o.MQTT.TLSMap = true 1064 s := testMQTTRunServer(t, o) 1065 defer testMQTTShutdownServer(s) 1066 1067 testMQTTEnableJSForAccount(t, s, accName) 1068 1069 tlscc := &tls.Config{} 1070 if test.provideCert { 1071 tc := &TLSConfigOpts{ 1072 CertFile: "../test/configs/certs/tlsauth/client.pem", 1073 KeyFile: "../test/configs/certs/tlsauth/client-key.pem", 1074 } 1075 var err error 1076 tlscc, err = GenTLSConfig(tc) 1077 if err != nil { 1078 t.Fatalf("Error generating tls config: %v", err) 1079 } 1080 } 1081 tlscc.InsecureSkipVerify = true 1082 if test.provideCert { 1083 tlscc.MinVersion = tls.VersionTLS13 1084 } 1085 mc, r, err := testMQTTConnectRetryWithError(t, &mqttConnInfo{ 1086 cleanSess: true, 1087 tls: true, 1088 tlsc: tlscc, 1089 }, o.MQTT.Host, o.MQTT.Port, 0) 1090 if !test.provideCert { 1091 if err == nil { 1092 t.Fatal("Expected error, did not get one") 1093 } else if !strings.Contains(err.Error(), "bad certificate") && !strings.Contains(err.Error(), "certificate required") { 1094 t.Fatalf("Unexpected error: %v", err) 1095 } 1096 return 1097 } 1098 if err != nil { 1099 t.Fatalf("Error reading: %v", err) 1100 } 1101 defer mc.Close() 1102 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1103 1104 var c *client 1105 s.mu.Lock() 1106 for _, sc := range s.clients { 1107 sc.mu.Lock() 1108 if sc.isMqtt() { 1109 c = sc 1110 } 1111 sc.mu.Unlock() 1112 if c != nil { 1113 break 1114 } 1115 } 1116 s.mu.Unlock() 1117 if c == nil { 1118 t.Fatal("Client not found") 1119 } 1120 1121 var uname string 1122 var accname string 1123 c.mu.Lock() 1124 uname = c.opts.Username 1125 if c.acc != nil { 1126 accname = c.acc.GetName() 1127 } 1128 c.mu.Unlock() 1129 if uname != certUserName { 1130 t.Fatalf("Expected username %q, got %q", certUserName, uname) 1131 } 1132 if accname != accName { 1133 t.Fatalf("Expected account %q, got %v", accName, accname) 1134 } 1135 }) 1136 } 1137 } 1138 1139 func TestMQTTBasicAuth(t *testing.T) { 1140 for _, test := range []struct { 1141 name string 1142 opts func() *Options 1143 user string 1144 pass string 1145 rc byte 1146 }{ 1147 { 1148 "top level auth, no override, wrong u/p", 1149 func() *Options { 1150 o := testMQTTDefaultOptions() 1151 o.Username = "normal" 1152 o.Password = "client" 1153 return o 1154 }, 1155 "mqtt", "client", mqttConnAckRCNotAuthorized, 1156 }, 1157 { 1158 "top level auth, no override, correct u/p", 1159 func() *Options { 1160 o := testMQTTDefaultOptions() 1161 o.Username = "normal" 1162 o.Password = "client" 1163 return o 1164 }, 1165 "normal", "client", mqttConnAckRCConnectionAccepted, 1166 }, 1167 { 1168 "no top level auth, mqtt auth, wrong u/p", 1169 func() *Options { 1170 o := testMQTTDefaultOptions() 1171 o.MQTT.Username = "mqtt" 1172 o.MQTT.Password = "client" 1173 return o 1174 }, 1175 "normal", "client", mqttConnAckRCNotAuthorized, 1176 }, 1177 { 1178 "no top level auth, mqtt auth, correct u/p", 1179 func() *Options { 1180 o := testMQTTDefaultOptions() 1181 o.MQTT.Username = "mqtt" 1182 o.MQTT.Password = "client" 1183 return o 1184 }, 1185 "mqtt", "client", mqttConnAckRCConnectionAccepted, 1186 }, 1187 { 1188 "top level auth, mqtt override, wrong u/p", 1189 func() *Options { 1190 o := testMQTTDefaultOptions() 1191 o.Username = "normal" 1192 o.Password = "client" 1193 o.MQTT.Username = "mqtt" 1194 o.MQTT.Password = "client" 1195 return o 1196 }, 1197 "normal", "client", mqttConnAckRCNotAuthorized, 1198 }, 1199 { 1200 "top level auth, mqtt override, correct u/p", 1201 func() *Options { 1202 o := testMQTTDefaultOptions() 1203 o.Username = "normal" 1204 o.Password = "client" 1205 o.MQTT.Username = "mqtt" 1206 o.MQTT.Password = "client" 1207 return o 1208 }, 1209 "mqtt", "client", mqttConnAckRCConnectionAccepted, 1210 }, 1211 } { 1212 t.Run(test.name, func(t *testing.T) { 1213 o := test.opts() 1214 s := testMQTTRunServer(t, o) 1215 defer testMQTTShutdownServer(s) 1216 1217 ci := &mqttConnInfo{ 1218 cleanSess: true, 1219 user: test.user, 1220 pass: test.pass, 1221 } 1222 mc, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 1223 defer mc.Close() 1224 testMQTTCheckConnAck(t, r, test.rc, false) 1225 }) 1226 } 1227 } 1228 1229 func TestMQTTAuthTimeout(t *testing.T) { 1230 for _, test := range []struct { 1231 name string 1232 at float64 1233 mat float64 1234 ok bool 1235 }{ 1236 {"use top-level auth timeout", 0.5, 0.0, true}, 1237 {"use mqtt auth timeout", 0.5, 0.05, false}, 1238 } { 1239 t.Run(test.name, func(t *testing.T) { 1240 o := testMQTTDefaultOptions() 1241 o.AuthTimeout = test.at 1242 o.MQTT.Username = "mqtt" 1243 o.MQTT.Password = "client" 1244 o.MQTT.AuthTimeout = test.mat 1245 s := testMQTTRunServer(t, o) 1246 defer testMQTTShutdownServer(s) 1247 1248 mc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port)) 1249 if err != nil { 1250 t.Fatalf("Error connecting: %v", err) 1251 } 1252 defer mc.Close() 1253 1254 time.Sleep(100 * time.Millisecond) 1255 1256 ci := &mqttConnInfo{ 1257 cleanSess: true, 1258 user: "mqtt", 1259 pass: "client", 1260 } 1261 proto := mqttCreateConnectProto(ci) 1262 if _, err := testMQTTWrite(mc, proto); err != nil { 1263 if test.ok { 1264 t.Fatalf("Error sending connect: %v", err) 1265 } 1266 // else it is ok since we got disconnected due to auth timeout 1267 return 1268 } 1269 buf, err := testMQTTRead(mc) 1270 if err != nil { 1271 if test.ok { 1272 t.Fatalf("Error reading: %v", err) 1273 } 1274 // else it is ok since we got disconnected due to auth timeout 1275 return 1276 } 1277 r := &mqttReader{reader: mc} 1278 r.reset(buf) 1279 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1280 1281 time.Sleep(500 * time.Millisecond) 1282 testMQTTPublish(t, mc, r, 1, false, false, "foo", 1, []byte("msg")) 1283 }) 1284 } 1285 } 1286 1287 func TestMQTTTokenAuth(t *testing.T) { 1288 for _, test := range []struct { 1289 name string 1290 opts func() *Options 1291 token string 1292 rc byte 1293 }{ 1294 { 1295 "top level auth, no override, wrong token", 1296 func() *Options { 1297 o := testMQTTDefaultOptions() 1298 o.Authorization = "goodtoken" 1299 return o 1300 }, 1301 "badtoken", mqttConnAckRCNotAuthorized, 1302 }, 1303 { 1304 "top level auth, no override, correct token", 1305 func() *Options { 1306 o := testMQTTDefaultOptions() 1307 o.Authorization = "goodtoken" 1308 return o 1309 }, 1310 "goodtoken", mqttConnAckRCConnectionAccepted, 1311 }, 1312 { 1313 "no top level auth, mqtt auth, wrong token", 1314 func() *Options { 1315 o := testMQTTDefaultOptions() 1316 o.MQTT.Token = "goodtoken" 1317 return o 1318 }, 1319 "badtoken", mqttConnAckRCNotAuthorized, 1320 }, 1321 { 1322 "no top level auth, mqtt auth, correct token", 1323 func() *Options { 1324 o := testMQTTDefaultOptions() 1325 o.MQTT.Token = "goodtoken" 1326 return o 1327 }, 1328 "goodtoken", mqttConnAckRCConnectionAccepted, 1329 }, 1330 { 1331 "top level auth, mqtt override, wrong token", 1332 func() *Options { 1333 o := testMQTTDefaultOptions() 1334 o.Authorization = "clienttoken" 1335 o.MQTT.Token = "mqtttoken" 1336 return o 1337 }, 1338 "clienttoken", mqttConnAckRCNotAuthorized, 1339 }, 1340 { 1341 "top level auth, mqtt override, correct token", 1342 func() *Options { 1343 o := testMQTTDefaultOptions() 1344 o.Authorization = "clienttoken" 1345 o.MQTT.Token = "mqtttoken" 1346 return o 1347 }, 1348 "mqtttoken", mqttConnAckRCConnectionAccepted, 1349 }, 1350 } { 1351 t.Run(test.name, func(t *testing.T) { 1352 o := test.opts() 1353 s := testMQTTRunServer(t, o) 1354 defer testMQTTShutdownServer(s) 1355 1356 ci := &mqttConnInfo{ 1357 cleanSess: true, 1358 user: "ignore_use_token", 1359 pass: test.token, 1360 } 1361 mc, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 1362 defer mc.Close() 1363 testMQTTCheckConnAck(t, r, test.rc, false) 1364 }) 1365 } 1366 } 1367 1368 func TestMQTTJWTWithAllowedConnectionTypes(t *testing.T) { 1369 o := testMQTTDefaultOptions() 1370 // Create System Account 1371 syskp, _ := nkeys.CreateAccount() 1372 syspub, _ := syskp.PublicKey() 1373 sysAc := jwt.NewAccountClaims(syspub) 1374 sysjwt, err := sysAc.Encode(oKp) 1375 if err != nil { 1376 t.Fatalf("Error generating account JWT: %v", err) 1377 } 1378 // Create memory resolver and store system account 1379 mr := &MemAccResolver{} 1380 mr.Store(syspub, sysjwt) 1381 if err != nil { 1382 t.Fatalf("Error saving system account JWT to memory resolver: %v", err) 1383 } 1384 // Add system account and memory resolver to server options 1385 o.SystemAccount = syspub 1386 o.AccountResolver = mr 1387 setupAddTrusted(o) 1388 1389 s := testMQTTRunServer(t, o) 1390 defer testMQTTShutdownServer(s) 1391 1392 for _, test := range []struct { 1393 name string 1394 connectionTypes []string 1395 rc byte 1396 }{ 1397 {"not allowed", []string{jwt.ConnectionTypeStandard}, mqttConnAckRCNotAuthorized}, 1398 {"allowed", []string{jwt.ConnectionTypeStandard, strings.ToLower(jwt.ConnectionTypeMqtt)}, mqttConnAckRCConnectionAccepted}, 1399 {"allowed with unknown", []string{jwt.ConnectionTypeMqtt, "SomeNewType"}, mqttConnAckRCConnectionAccepted}, 1400 {"not allowed with unknown", []string{"SomeNewType"}, mqttConnAckRCNotAuthorized}, 1401 } { 1402 t.Run(test.name, func(t *testing.T) { 1403 1404 nuc := newJWTTestUserClaims() 1405 nuc.AllowedConnectionTypes = test.connectionTypes 1406 nuc.BearerToken = true 1407 1408 okp, _ := nkeys.FromSeed(oSeed) 1409 1410 akp, _ := nkeys.CreateAccount() 1411 apub, _ := akp.PublicKey() 1412 nac := jwt.NewAccountClaims(apub) 1413 // Enable Jetstream on account with lax limitations 1414 nac.Limits.JetStreamLimits.Consumer = -1 1415 nac.Limits.JetStreamLimits.Streams = -1 1416 nac.Limits.JetStreamLimits.MemoryStorage = 1024 * 1024 1417 nac.Limits.JetStreamLimits.DiskStorage = 1024 * 1024 1418 ajwt, err := nac.Encode(okp) 1419 if err != nil { 1420 t.Fatalf("Error generating account JWT: %v", err) 1421 } 1422 1423 nkp, _ := nkeys.CreateUser() 1424 pub, _ := nkp.PublicKey() 1425 nuc.Subject = pub 1426 jwt, err := nuc.Encode(akp) 1427 if err != nil { 1428 t.Fatalf("Error generating user JWT: %v", err) 1429 } 1430 1431 addAccountToMemResolver(s, apub, ajwt) 1432 1433 ci := &mqttConnInfo{ 1434 cleanSess: true, 1435 user: "ignore_use_token", 1436 pass: jwt, 1437 } 1438 1439 mc, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 1440 defer mc.Close() 1441 testMQTTCheckConnAck(t, r, test.rc, false) 1442 }) 1443 } 1444 } 1445 1446 func TestMQTTUsersAuth(t *testing.T) { 1447 users := []*User{{Username: "user", Password: "pwd"}} 1448 for _, test := range []struct { 1449 name string 1450 opts func() *Options 1451 user string 1452 pass string 1453 rc byte 1454 }{ 1455 { 1456 "no filtering, wrong user", 1457 func() *Options { 1458 o := testMQTTDefaultOptions() 1459 o.Users = users 1460 return o 1461 }, 1462 "wronguser", "pwd", mqttConnAckRCNotAuthorized, 1463 }, 1464 { 1465 "no filtering, correct user", 1466 func() *Options { 1467 o := testMQTTDefaultOptions() 1468 o.Users = users 1469 return o 1470 }, 1471 "user", "pwd", mqttConnAckRCConnectionAccepted, 1472 }, 1473 { 1474 "filtering, user not allowed", 1475 func() *Options { 1476 o := testMQTTDefaultOptions() 1477 o.Users = users 1478 // Only allowed for regular clients 1479 o.Users[0].AllowedConnectionTypes = testCreateAllowedConnectionTypes([]string{jwt.ConnectionTypeStandard}) 1480 return o 1481 }, 1482 "user", "pwd", mqttConnAckRCNotAuthorized, 1483 }, 1484 { 1485 "filtering, user allowed", 1486 func() *Options { 1487 o := testMQTTDefaultOptions() 1488 o.Users = users 1489 o.Users[0].AllowedConnectionTypes = testCreateAllowedConnectionTypes([]string{jwt.ConnectionTypeStandard, jwt.ConnectionTypeMqtt}) 1490 return o 1491 }, 1492 "user", "pwd", mqttConnAckRCConnectionAccepted, 1493 }, 1494 { 1495 "filtering, wrong password", 1496 func() *Options { 1497 o := testMQTTDefaultOptions() 1498 o.Users = users 1499 o.Users[0].AllowedConnectionTypes = testCreateAllowedConnectionTypes([]string{jwt.ConnectionTypeStandard, jwt.ConnectionTypeMqtt}) 1500 return o 1501 }, 1502 "user", "badpassword", mqttConnAckRCNotAuthorized, 1503 }, 1504 } { 1505 t.Run(test.name, func(t *testing.T) { 1506 o := test.opts() 1507 s := testMQTTRunServer(t, o) 1508 defer testMQTTShutdownServer(s) 1509 1510 ci := &mqttConnInfo{ 1511 cleanSess: true, 1512 user: test.user, 1513 pass: test.pass, 1514 } 1515 mc, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 1516 defer mc.Close() 1517 testMQTTCheckConnAck(t, r, test.rc, false) 1518 }) 1519 } 1520 } 1521 1522 func TestMQTTNoAuthUserValidation(t *testing.T) { 1523 o := testMQTTDefaultOptions() 1524 o.Users = []*User{{Username: "user", Password: "pwd"}} 1525 // Should fail because it is not part of o.Users. 1526 o.MQTT.NoAuthUser = "notfound" 1527 if _, err := NewServer(o); err == nil || !strings.Contains(err.Error(), "not present as user") { 1528 t.Fatalf("Expected error saying not present as user, got %v", err) 1529 } 1530 1531 // Set a valid no auth user for global options, but still should fail because 1532 // of o.MQTT.NoAuthUser 1533 o.NoAuthUser = "user" 1534 o.MQTT.NoAuthUser = "notfound" 1535 if _, err := NewServer(o); err == nil || !strings.Contains(err.Error(), "not present as user") { 1536 t.Fatalf("Expected error saying not present as user, got %v", err) 1537 } 1538 } 1539 1540 func TestMQTTNoAuthUser(t *testing.T) { 1541 for _, test := range []struct { 1542 name string 1543 override bool 1544 useAuth bool 1545 expectedUser string 1546 expectedAcc string 1547 }{ 1548 {"no override, no user provided", false, false, "noauth", "normal"}, 1549 {"no override, user povided", false, true, "user", "normal"}, 1550 {"override, no user provided", true, false, "mqttnoauth", "mqtt"}, 1551 {"override, user provided", true, true, "mqttuser", "mqtt"}, 1552 } { 1553 t.Run(test.name, func(t *testing.T) { 1554 o := testMQTTDefaultOptions() 1555 normalAcc := NewAccount("normal") 1556 mqttAcc := NewAccount("mqtt") 1557 o.Accounts = []*Account{normalAcc, mqttAcc} 1558 o.Users = []*User{ 1559 {Username: "noauth", Password: "pwd", Account: normalAcc}, 1560 {Username: "user", Password: "pwd", Account: normalAcc}, 1561 {Username: "mqttnoauth", Password: "pwd", Account: mqttAcc}, 1562 {Username: "mqttuser", Password: "pwd", Account: mqttAcc}, 1563 } 1564 o.NoAuthUser = "noauth" 1565 if test.override { 1566 o.MQTT.NoAuthUser = "mqttnoauth" 1567 } 1568 s := testMQTTRunServer(t, o) 1569 defer testMQTTShutdownServer(s) 1570 1571 testMQTTEnableJSForAccount(t, s, "normal") 1572 testMQTTEnableJSForAccount(t, s, "mqtt") 1573 1574 ci := &mqttConnInfo{clientID: "mqtt", cleanSess: true} 1575 if test.useAuth { 1576 ci.user = test.expectedUser 1577 ci.pass = "pwd" 1578 } 1579 mc, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 1580 defer mc.Close() 1581 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1582 1583 c := testMQTTGetClient(t, s, "mqtt") 1584 c.mu.Lock() 1585 uname := c.opts.Username 1586 aname := c.acc.GetName() 1587 c.mu.Unlock() 1588 if uname != test.expectedUser { 1589 t.Fatalf("Expected selected user to be %q, got %q", test.expectedUser, uname) 1590 } 1591 if aname != test.expectedAcc { 1592 t.Fatalf("Expected selected account to be %q, got %q", test.expectedAcc, aname) 1593 } 1594 }) 1595 } 1596 } 1597 1598 func TestMQTTConnectNotFirstPacket(t *testing.T) { 1599 o := testMQTTDefaultOptions() 1600 s := testMQTTRunServer(t, o) 1601 defer testMQTTShutdownServer(s) 1602 1603 l := &captureErrorLogger{errCh: make(chan string, 10)} 1604 s.SetLogger(l, false, false) 1605 1606 c, err := net.Dial("tcp", fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port)) 1607 if err != nil { 1608 t.Fatalf("Error on dial: %v", err) 1609 } 1610 defer c.Close() 1611 1612 testMQTTSendPublishPacket(t, c, 0, false, false, "foo", 0, []byte("hello")) 1613 testMQTTExpectDisconnect(t, c) 1614 1615 select { 1616 case err := <-l.errCh: 1617 if !strings.Contains(err, "should be a CONNECT") { 1618 t.Fatalf("Expected error about first packet being a CONNECT, got %v", err) 1619 } 1620 case <-time.After(time.Second): 1621 t.Fatal("Did not log any error") 1622 } 1623 } 1624 1625 func TestMQTTSecondConnect(t *testing.T) { 1626 o := testMQTTDefaultOptions() 1627 s := testMQTTRunServer(t, o) 1628 defer testMQTTShutdownServer(s) 1629 1630 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 1631 defer mc.Close() 1632 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1633 1634 proto := mqttCreateConnectProto(&mqttConnInfo{cleanSess: true}) 1635 if _, err := testMQTTWrite(mc, proto); err != nil { 1636 t.Fatalf("Error writing connect: %v", err) 1637 } 1638 testMQTTExpectDisconnect(t, mc) 1639 } 1640 1641 func TestMQTTParseConnect(t *testing.T) { 1642 for _, test := range []struct { 1643 name string 1644 proto []byte 1645 pl int 1646 err string 1647 }{ 1648 {"packet in buffer error", []byte{0}, 10, io.ErrUnexpectedEOF.Error()}, 1649 {"bad proto name", []byte{0, 4, 'B', 'A', 'D'}, 5, "protocol name"}, 1650 {"invalid proto name", []byte{0, 3, 'B', 'A', 'D'}, 5, "expected connect packet with protocol name"}, 1651 {"old proto not supported", []byte{0, 6, 'M', 'Q', 'I', 's', 'd', 'p'}, 8, "older protocol"}, 1652 {"error on protocol level", []byte{0, 4, 'M', 'Q', 'T', 'T'}, 6, "protocol level"}, 1653 {"unacceptable protocol version", []byte{0, 4, 'M', 'Q', 'T', 'T', 10}, 7, "unacceptable protocol version"}, 1654 {"error on flags", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel}, 7, "flags"}, 1655 {"reserved flag", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 1}, 8, errMQTTConnFlagReserved.Error()}, 1656 {"will qos without will flag", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 1 << 3}, 8, "if Will flag is set to 0, Will QoS must be 0 too"}, 1657 {"will retain without will flag", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 1 << 5}, 8, errMQTTWillAndRetainFlag.Error()}, 1658 {"will qos", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 3<<3 | 1<<2}, 8, "if Will flag is set to 1, Will QoS can be 0, 1 or 2"}, 1659 {"no user but password", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagPasswordFlag}, 8, errMQTTPasswordFlagAndNoUser.Error()}, 1660 {"missing keep alive", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 0}, 8, "keep alive"}, 1661 {"missing client ID", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 0, 0, 1}, 10, "client ID"}, 1662 {"empty client ID", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 0, 0, 1, 0, 0}, 12, errMQTTCIDEmptyNeedsCleanFlag.Error()}, 1663 {"invalid utf8 client ID", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, 0, 0, 1, 0, 1, 241}, 13, "invalid utf8 for client ID"}, 1664 {"missing will topic", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagWillFlag | mqttConnFlagCleanSession, 0, 0, 0, 0}, 12, "Will topic"}, 1665 {"empty will topic", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagWillFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 0}, 14, errMQTTEmptyWillTopic.Error()}, 1666 {"invalid utf8 will topic", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagWillFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 1, 241}, 15, "invalid utf8 for Will topic"}, 1667 {"invalid wildcard will topic", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagWillFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 1, '#'}, 15, "wildcards not allowed"}, 1668 {"error on will message", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagWillFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 1, 'a', 0, 3}, 17, "Will message"}, 1669 {"error on username", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagUsernameFlag | mqttConnFlagCleanSession, 0, 0, 0, 0}, 12, "user name"}, 1670 {"empty username", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagUsernameFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 0}, 14, errMQTTEmptyUsername.Error()}, 1671 {"invalid utf8 username", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagUsernameFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 1, 241}, 15, "invalid utf8 for user name"}, 1672 {"error on password", []byte{0, 4, 'M', 'Q', 'T', 'T', mqttProtoLevel, mqttConnFlagUsernameFlag | mqttConnFlagPasswordFlag | mqttConnFlagCleanSession, 0, 0, 0, 0, 0, 1, 'a'}, 15, "password"}, 1673 } { 1674 t.Run(test.name, func(t *testing.T) { 1675 r := &mqttReader{} 1676 r.reset(test.proto) 1677 mqtt := &mqtt{r: r} 1678 c := &client{mqtt: mqtt} 1679 if _, _, err := c.mqttParseConnect(r, test.pl, false); err == nil || !strings.Contains(err.Error(), test.err) { 1680 t.Fatalf("Expected error %q, got %v", test.err, err) 1681 } 1682 }) 1683 } 1684 } 1685 1686 func TestMQTTConnectFailsOnParse(t *testing.T) { 1687 o := testMQTTDefaultOptions() 1688 s := testMQTTRunServer(t, o) 1689 defer testMQTTShutdownServer(s) 1690 1691 addr := fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port) 1692 c, err := net.Dial("tcp", addr) 1693 if err != nil { 1694 t.Fatalf("Error creating mqtt connection: %v", err) 1695 } 1696 1697 pkLen := 2 + len(mqttProtoName) + 1698 1 + // proto level 1699 1 + // flags 1700 2 + // keepAlive 1701 2 + len("mqtt") 1702 1703 w := newMQTTWriter(0) 1704 w.WriteByte(mqttPacketConnect) 1705 w.WriteVarInt(pkLen) 1706 w.WriteString(string(mqttProtoName)) 1707 w.WriteByte(0x7) 1708 w.WriteByte(mqttConnFlagCleanSession) 1709 w.WriteUint16(0) 1710 w.WriteString("mqtt") 1711 c.Write(w.Bytes()) 1712 1713 buf, err := testMQTTRead(c) 1714 if err != nil { 1715 t.Fatalf("Error reading: %v", err) 1716 } 1717 r := &mqttReader{reader: c} 1718 r.reset(buf) 1719 testMQTTCheckConnAck(t, r, mqttConnAckRCUnacceptableProtocolVersion, false) 1720 } 1721 1722 func TestMQTTConnKeepAlive(t *testing.T) { 1723 o := testMQTTDefaultOptions() 1724 s := testMQTTRunServer(t, o) 1725 defer testMQTTShutdownServer(s) 1726 1727 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true, keepAlive: 1}, o.MQTT.Host, o.MQTT.Port) 1728 defer mc.Close() 1729 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1730 1731 testMQTTPublish(t, mc, r, 0, false, false, "foo", 0, []byte("msg")) 1732 1733 time.Sleep(2 * time.Second) 1734 testMQTTExpectDisconnect(t, mc) 1735 } 1736 1737 func TestMQTTDontSetPinger(t *testing.T) { 1738 o := testMQTTDefaultOptions() 1739 o.PingInterval = 15 * time.Millisecond 1740 s := testMQTTRunServer(t, o) 1741 defer testMQTTShutdownServer(s) 1742 1743 mc, r := testMQTTConnect(t, &mqttConnInfo{clientID: "mqtt", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 1744 defer mc.Close() 1745 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1746 1747 c := testMQTTGetClient(t, s, "mqtt") 1748 c.mu.Lock() 1749 timerSet := c.ping.tmr != nil 1750 c.mu.Unlock() 1751 if timerSet { 1752 t.Fatalf("Ping timer should not be set for MQTT clients") 1753 } 1754 1755 // Wait a bit and expect nothing (and connection should still be valid) 1756 testMQTTExpectNothing(t, r) 1757 testMQTTPublish(t, mc, r, 0, false, false, "foo", 0, []byte("msg")) 1758 } 1759 1760 func TestMQTTTopicAndSubjectConversion(t *testing.T) { 1761 for _, test := range []struct { 1762 name string 1763 mqttTopic string 1764 natsSubject string 1765 err string 1766 }{ 1767 {"/", "/", "/./", ""}, 1768 {"//", "//", "/././", ""}, 1769 {"///", "///", "/./././", ""}, 1770 {"////", "////", "/././././", ""}, 1771 {"foo", "foo", "foo", ""}, 1772 {"/foo", "/foo", "/.foo", ""}, 1773 {"//foo", "//foo", "/./.foo", ""}, 1774 {"///foo", "///foo", "/././.foo", ""}, 1775 {"///foo/", "///foo/", "/././.foo./", ""}, 1776 {"///foo//", "///foo//", "/././.foo././", ""}, 1777 {"///foo///", "///foo///", "/././.foo./././", ""}, 1778 {"//.foo.//", "//.foo.//", "/././/foo//././", ""}, 1779 {"foo/bar", "foo/bar", "foo.bar", ""}, 1780 {"/foo/bar", "/foo/bar", "/.foo.bar", ""}, 1781 {"/foo/bar/", "/foo/bar/", "/.foo.bar./", ""}, 1782 {"foo/bar/baz", "foo/bar/baz", "foo.bar.baz", ""}, 1783 {"/foo/bar/baz", "/foo/bar/baz", "/.foo.bar.baz", ""}, 1784 {"/foo/bar/baz/", "/foo/bar/baz/", "/.foo.bar.baz./", ""}, 1785 {"bar", "bar/", "bar./", ""}, 1786 {"bar//", "bar//", "bar././", ""}, 1787 {"bar///", "bar///", "bar./././", ""}, 1788 {"foo//bar", "foo//bar", "foo./.bar", ""}, 1789 {"foo///bar", "foo///bar", "foo././.bar", ""}, 1790 {"foo////bar", "foo////bar", "foo./././.bar", ""}, 1791 {".", ".", "//", ""}, 1792 {"..", "..", "////", ""}, 1793 {"...", "...", "//////", ""}, 1794 {"./", "./", "//./", ""}, 1795 {".//.", ".//.", "//././/", ""}, 1796 {"././.", "././.", "//.//.//", ""}, 1797 {"././/.", "././/.", "//.//././/", ""}, 1798 {".foo", ".foo", "//foo", ""}, 1799 {"foo.", "foo.", "foo//", ""}, 1800 {".foo.", ".foo.", "//foo//", ""}, 1801 {"foo../bar/", "foo../bar/", "foo////.bar./", ""}, 1802 {"foo../bar/.", "foo../bar/.", "foo////.bar.//", ""}, 1803 {"/foo/", "/foo/", "/.foo./", ""}, 1804 {"./foo/.", "./foo/.", "//.foo.//", ""}, 1805 {"foo.bar/baz", "foo.bar/baz", "foo//bar.baz", ""}, 1806 // These should produce errors 1807 {"foo/+", "foo/+", "", "wildcards not allowed in publish"}, 1808 {"foo/#", "foo/#", "", "wildcards not allowed in publish"}, 1809 {"foo bar", "foo bar", "", "not supported"}, 1810 } { 1811 t.Run(test.name, func(t *testing.T) { 1812 res, err := mqttTopicToNATSPubSubject([]byte(test.mqttTopic)) 1813 if test.err != _EMPTY_ { 1814 if err == nil || !strings.Contains(err.Error(), test.err) { 1815 t.Fatalf("Expected error %q, got %v", test.err, err) 1816 } 1817 return 1818 } 1819 toNATS := string(res) 1820 if toNATS != test.natsSubject { 1821 t.Fatalf("Expected subject %q got %q", test.natsSubject, toNATS) 1822 } 1823 1824 res = natsSubjectToMQTTTopic(string(res)) 1825 backToMQTT := string(res) 1826 if backToMQTT != test.mqttTopic { 1827 t.Fatalf("Expected topic %q got %q (NATS conversion was %q)", test.mqttTopic, backToMQTT, toNATS) 1828 } 1829 }) 1830 } 1831 } 1832 1833 func TestMQTTFilterConversion(t *testing.T) { 1834 // Similar to TopicConversion test except that wildcards are OK here. 1835 // So testing only those. 1836 for _, test := range []struct { 1837 name string 1838 mqttTopic string 1839 natsSubject string 1840 }{ 1841 {"single level wildcard", "+", "*"}, 1842 {"single level wildcard", "/+", "/.*"}, 1843 {"single level wildcard", "+/", "*./"}, 1844 {"single level wildcard", "/+/", "/.*./"}, 1845 {"single level wildcard", "foo/+", "foo.*"}, 1846 {"single level wildcard", "foo/+/", "foo.*./"}, 1847 {"single level wildcard", "foo/+/bar", "foo.*.bar"}, 1848 {"single level wildcard", "foo/+/+", "foo.*.*"}, 1849 {"single level wildcard", "foo/+/+/", "foo.*.*./"}, 1850 {"single level wildcard", "foo/+/+/bar", "foo.*.*.bar"}, 1851 {"single level wildcard", "foo//+", "foo./.*"}, 1852 {"single level wildcard", "foo//+/", "foo./.*./"}, 1853 {"single level wildcard", "foo//+//", "foo./.*././"}, 1854 {"single level wildcard", "foo//+//bar", "foo./.*./.bar"}, 1855 {"single level wildcard", "foo///+///bar", "foo././.*././.bar"}, 1856 {"single level wildcard", "foo.bar///+///baz", "foo//bar././.*././.baz"}, 1857 1858 {"multi level wildcard", "#", ">"}, 1859 {"multi level wildcard", "/#", "/.>"}, 1860 {"multi level wildcard", "/foo/#", "/.foo.>"}, 1861 {"multi level wildcard", "foo/#", "foo.>"}, 1862 {"multi level wildcard", "foo//#", "foo./.>"}, 1863 {"multi level wildcard", "foo///#", "foo././.>"}, 1864 {"multi level wildcard", "foo/bar/#", "foo.bar.>"}, 1865 {"multi level wildcard", "foo/bar.baz/#", "foo.bar//baz.>"}, 1866 } { 1867 t.Run(test.name, func(t *testing.T) { 1868 res, err := mqttFilterToNATSSubject([]byte(test.mqttTopic)) 1869 if err != nil { 1870 t.Fatalf("Error: %v", err) 1871 } 1872 if string(res) != test.natsSubject { 1873 t.Fatalf("Expected subject %q got %q", test.natsSubject, res) 1874 } 1875 }) 1876 } 1877 } 1878 1879 func TestMQTTParseSub(t *testing.T) { 1880 for _, test := range []struct { 1881 name string 1882 proto []byte 1883 b byte 1884 pl int 1885 err string 1886 }{ 1887 {"reserved flag", nil, 3, 0, "wrong subscribe reserved flags"}, 1888 {"ensure packet loaded", []byte{1, 2}, mqttSubscribeFlags, 10, io.ErrUnexpectedEOF.Error()}, 1889 {"error reading packet id", []byte{1}, mqttSubscribeFlags, 1, "reading packet identifier"}, 1890 {"missing filters", []byte{0, 1}, mqttSubscribeFlags, 2, "subscribe protocol must contain at least 1 topic filter"}, 1891 {"error reading topic", []byte{0, 1, 0, 2, 'a'}, mqttSubscribeFlags, 5, "topic filter"}, 1892 {"empty topic", []byte{0, 1, 0, 0}, mqttSubscribeFlags, 4, errMQTTTopicFilterCannotBeEmpty.Error()}, 1893 {"invalid utf8 topic", []byte{0, 1, 0, 1, 241}, mqttSubscribeFlags, 5, "invalid utf8 for topic filter"}, 1894 {"missing qos", []byte{0, 1, 0, 1, 'a'}, mqttSubscribeFlags, 5, "QoS"}, 1895 {"invalid qos", []byte{0, 1, 0, 1, 'a', 3}, mqttSubscribeFlags, 6, "subscribe QoS value must be 0, 1 or 2"}, 1896 } { 1897 t.Run(test.name, func(t *testing.T) { 1898 r := &mqttReader{} 1899 r.reset(test.proto) 1900 mqtt := &mqtt{r: r} 1901 c := &client{mqtt: mqtt} 1902 if _, _, err := c.mqttParseSubsOrUnsubs(r, test.b, test.pl, true); err == nil || !strings.Contains(err.Error(), test.err) { 1903 t.Fatalf("Expected error %q, got %v", test.err, err) 1904 } 1905 }) 1906 } 1907 } 1908 1909 func testMQTTSub(t testing.TB, pi uint16, c net.Conn, r *mqttReader, filters []*mqttFilter, expected []byte) { 1910 t.Helper() 1911 w := newMQTTWriter(0) 1912 pkLen := 2 // for pi 1913 for i := 0; i < len(filters); i++ { 1914 f := filters[i] 1915 pkLen += 2 + len(f.filter) + 1 1916 } 1917 w.WriteByte(mqttPacketSub | mqttSubscribeFlags) 1918 w.WriteVarInt(pkLen) 1919 w.WriteUint16(pi) 1920 for i := 0; i < len(filters); i++ { 1921 f := filters[i] 1922 w.WriteBytes([]byte(f.filter)) 1923 w.WriteByte(f.qos) 1924 } 1925 if _, err := testMQTTWrite(c, w.Bytes()); err != nil { 1926 t.Fatalf("Error writing SUBSCRIBE protocol: %v", err) 1927 } 1928 b, pl := testMQTTReadPacket(t, r) 1929 if pt := b & mqttPacketMask; pt != mqttPacketSubAck { 1930 t.Fatalf("Expected SUBACK packet %x, got %x", mqttPacketSubAck, pt) 1931 } 1932 rpi, err := r.readUint16("packet identifier") 1933 if err != nil || rpi != pi { 1934 t.Fatalf("Error with packet identifier expected=%v got: %v err=%v", pi, rpi, err) 1935 } 1936 for i, rem := 0, pl-2; rem > 0; rem-- { 1937 qos, err := r.readByte("filter qos") 1938 if err != nil { 1939 t.Fatal(err) 1940 } 1941 if expected != nil && qos != expected[i] { 1942 t.Fatalf("For topic filter %q expected qos of %v, got %v", 1943 filters[i].filter, expected[i], qos) 1944 } 1945 i++ 1946 } 1947 } 1948 1949 func TestMQTTSubAck(t *testing.T) { 1950 o := testMQTTDefaultOptions() 1951 s := testMQTTRunServer(t, o) 1952 defer testMQTTShutdownServer(s) 1953 1954 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 1955 defer mc.Close() 1956 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1957 1958 subs := []*mqttFilter{ 1959 {filter: "foo", qos: 0}, 1960 {filter: "bar", qos: 1}, 1961 {filter: "baz", qos: 2}, 1962 {filter: "foo/#/bar", qos: 0}, // Invalid sub, so we should receive a result of mqttSubAckFailure 1963 } 1964 expected := []byte{ 1965 0, 1966 1, 1967 2, 1968 mqttSubAckFailure, 1969 } 1970 testMQTTSub(t, 1, mc, r, subs, expected) 1971 } 1972 1973 func TestMQTTQoS2SubDowngrade(t *testing.T) { 1974 o := testMQTTDefaultOptions() 1975 o.MQTT.downgradeQoS2Sub = true 1976 s := testMQTTRunServer(t, o) 1977 defer testMQTTShutdownServer(s) 1978 1979 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 1980 defer mc.Close() 1981 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 1982 1983 subs := []*mqttFilter{ 1984 {filter: "bar", qos: 1}, 1985 {filter: "baz", qos: 2}, 1986 } 1987 expected := []byte{ 1988 1, 1989 1, 1990 } 1991 testMQTTSub(t, 1, mc, r, subs, expected) 1992 } 1993 1994 func testMQTTFlush(t testing.TB, c net.Conn, bw *bufio.Writer, r *mqttReader) { 1995 t.Helper() 1996 w := newMQTTWriter(0) 1997 w.WriteByte(mqttPacketPing) 1998 w.WriteByte(0) 1999 if bw != nil { 2000 bw.Write(w.Bytes()) 2001 bw.Flush() 2002 } else { 2003 c.Write(w.Bytes()) 2004 } 2005 ab, l := testMQTTReadPacket(t, r) 2006 if pt := ab & mqttPacketMask; pt != mqttPacketPingResp { 2007 t.Fatalf("Expected ping response got %x", pt) 2008 } 2009 if l != 0 { 2010 t.Fatalf("Expected PINGRESP length to be 0, got %v", l) 2011 } 2012 } 2013 2014 func testMQTTExpectNothing(t testing.TB, r *mqttReader) { 2015 t.Helper() 2016 var buf [128]byte 2017 r.reader.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 2018 if n, err := r.reader.Read(buf[:]); err == nil { 2019 t.Fatalf("Expected nothing, got %v", buf[:n]) 2020 } 2021 r.reader.SetReadDeadline(time.Time{}) 2022 } 2023 2024 func testMQTTCheckPubMsg(t testing.TB, c net.Conn, r *mqttReader, topic string, expectedFlags byte, payload []byte) uint16 { 2025 t.Helper() 2026 pi := testMQTTCheckPubMsgNoAck(t, c, r, topic, expectedFlags, payload) 2027 if pi == 0 { 2028 return 0 2029 } 2030 qos := mqttGetQoS(expectedFlags) 2031 switch qos { 2032 case 1: 2033 testMQTTSendPIPacket(mqttPacketPubAck, t, c, pi) 2034 case 2: 2035 testMQTTSendPIPacket(mqttPacketPubRec, t, c, pi) 2036 } 2037 return pi 2038 } 2039 2040 func testMQTTCheckPubMsgNoAck(t testing.TB, c net.Conn, r *mqttReader, topic string, expectedFlags byte, payload []byte) uint16 { 2041 t.Helper() 2042 pflags, pi := testMQTTGetPubMsg(t, c, r, topic, payload) 2043 if pflags != expectedFlags { 2044 t.Fatalf("Expected flags to be %x, got %x", expectedFlags, pflags) 2045 } 2046 return pi 2047 } 2048 2049 func testMQTTGetPubMsg(t testing.TB, c net.Conn, r *mqttReader, topic string, payload []byte) (byte, uint16) { 2050 t.Helper() 2051 flags, pi, _ := testMQTTGetPubMsgEx(t, c, r, topic, payload) 2052 return flags, pi 2053 } 2054 2055 func testMQTTGetPubMsgEx(t testing.TB, _ net.Conn, r *mqttReader, topic string, payload []byte) (byte, uint16, string) { 2056 t.Helper() 2057 b, pl := testMQTTReadPacket(t, r) 2058 if pt := b & mqttPacketMask; pt != mqttPacketPub { 2059 t.Fatalf("Expected PUBLISH packet %x, got %x", mqttPacketPub, pt) 2060 } 2061 return testMQTTGetPubMsgExEx(t, nil, r, b, pl, topic, payload) 2062 } 2063 2064 func testMQTTGetPubMsgExEx(t testing.TB, _ net.Conn, r *mqttReader, b byte, pl int, topic string, payload []byte) (byte, uint16, string) { 2065 t.Helper() 2066 pflags := b & mqttPacketFlagMask 2067 qos := (pflags & mqttPubFlagQoS) >> 1 2068 start := r.pos 2069 ptopic, err := r.readString("topic name") 2070 if err != nil { 2071 t.Fatal(err) 2072 } 2073 if topic != _EMPTY_ && ptopic != topic { 2074 t.Fatalf("Expected topic %q, got %q", topic, ptopic) 2075 } 2076 var pi uint16 2077 if qos > 0 { 2078 pi, err = r.readUint16("packet identifier") 2079 if err != nil { 2080 t.Fatal(err) 2081 } 2082 } 2083 msgLen := pl - (r.pos - start) 2084 if r.pos+msgLen > len(r.buf) { 2085 t.Fatalf("computed message length goes beyond buffer: ml=%v pos=%v lenBuf=%v", 2086 msgLen, r.pos, len(r.buf)) 2087 } 2088 ppayload := r.buf[r.pos : r.pos+msgLen] 2089 if payload != nil && !bytes.Equal(payload, ppayload) { 2090 t.Fatalf("Expected payload %q, got %q", payload, ppayload) 2091 } 2092 r.pos += msgLen 2093 return pflags, pi, ptopic 2094 } 2095 2096 func testMQTTReadPubPacket(t testing.TB, r *mqttReader) (flags byte, pi uint16, topic string, payload []byte) { 2097 t.Helper() 2098 b, pl := testMQTTReadPacket(t, r) 2099 if pt := b & mqttPacketMask; pt != mqttPacketPub { 2100 t.Fatalf("Expected PUBLISH packet %x, got %x", mqttPacketPub, pt) 2101 } 2102 flags = b & mqttPacketFlagMask 2103 start := r.pos 2104 topic, err := r.readString("topic name") 2105 if err != nil { 2106 t.Fatal(err) 2107 } 2108 qos := (flags & mqttPubFlagQoS) >> 1 2109 if qos > 0 { 2110 pi, err = r.readUint16("packet identifier") 2111 if err != nil { 2112 t.Fatal(err) 2113 } 2114 } 2115 msgLen := pl - (r.pos - start) 2116 if r.pos+msgLen > len(r.buf) { 2117 t.Fatalf("computed message length goes beyond buffer: ml=%v pos=%v lenBuf=%v", 2118 msgLen, r.pos, len(r.buf)) 2119 } 2120 payload = r.buf[r.pos : r.pos+msgLen] 2121 r.pos += msgLen 2122 return flags, pi, topic, payload 2123 } 2124 2125 func testMQTTSendPIPacket(packetType byte, t testing.TB, c net.Conn, pi uint16) { 2126 t.Helper() 2127 w := newMQTTWriter(0) 2128 w.WriteByte(packetType) 2129 w.WriteVarInt(2) 2130 w.WriteUint16(pi) 2131 if _, err := testMQTTWrite(c, w.Bytes()); err != nil { 2132 t.Fatalf("Error writing packet type %v: %v", packetType, err) 2133 } 2134 } 2135 2136 func testMQTTWritePublishPacket(t testing.TB, w *mqttWriter, qos byte, dup, retain bool, topic string, pi uint16, payload []byte) { 2137 t.Helper() 2138 w.WritePublishHeader(pi, qos, dup, retain, []byte(topic), len(payload)) 2139 if _, err := w.Write(payload); err != nil { 2140 t.Fatalf("Error writing PUBLISH proto: %v", err) 2141 } 2142 } 2143 2144 func testMQTTSendPublishPacket(t testing.TB, c net.Conn, qos byte, dup, retain bool, topic string, pi uint16, payload []byte) { 2145 t.Helper() 2146 c.SetWriteDeadline(time.Now().Add(testMQTTTimeout)) 2147 _, header := mqttMakePublishHeader(pi, qos, dup, retain, []byte(topic), len(payload)) 2148 if _, err := c.Write(header); err != nil { 2149 t.Fatalf("Error writing PUBLISH header: %v", err) 2150 } 2151 if _, err := c.Write(payload); err != nil { 2152 t.Fatalf("Error writing PUBLISH payload: %v", err) 2153 } 2154 c.SetWriteDeadline(time.Time{}) 2155 } 2156 2157 func testMQTTPublish(t testing.TB, c net.Conn, r *mqttReader, qos byte, dup, retain bool, topic string, pi uint16, payload []byte) { 2158 t.Helper() 2159 testMQTTSendPublishPacket(t, c, qos, dup, retain, topic, pi, payload) 2160 switch qos { 2161 case 1: 2162 b, _ := testMQTTReadPacket(t, r) 2163 if pt := b & mqttPacketMask; pt != mqttPacketPubAck { 2164 t.Fatalf("Expected PUBACK packet %x, got %x", mqttPacketPubAck, pt) 2165 } 2166 rpi, err := r.readUint16("packet identifier") 2167 if err != nil || rpi != pi { 2168 t.Fatalf("Error with packet identifier expected=%v got: %v err=%v", pi, rpi, err) 2169 } 2170 2171 case 2: 2172 b, _ := testMQTTReadPacket(t, r) 2173 if pt := b & mqttPacketMask; pt != mqttPacketPubRec { 2174 t.Fatalf("Expected PUBREC packet %x, got %x", mqttPacketPubRec, pt) 2175 } 2176 rpi, err := r.readUint16("packet identifier") 2177 if err != nil || rpi != pi { 2178 t.Fatalf("Error with packet identifier expected=%v got: %v err=%v", pi, rpi, err) 2179 } 2180 2181 testMQTTSendPIPacket(mqttPacketPubRel, t, c, pi) 2182 2183 b, _ = testMQTTReadPacket(t, r) 2184 if pt := b & mqttPacketMask; pt != mqttPacketPubComp { 2185 t.Fatalf("Expected PUBCOMP packet %x, got %x", mqttPacketPubComp, pt) 2186 } 2187 rpi, err = r.readUint16("packet identifier") 2188 if err != nil || rpi != pi { 2189 t.Fatalf("Error with packet identifier expected=%v got: %v err=%v", pi, rpi, err) 2190 } 2191 2192 testMQTTFlush(t, c, nil, r) 2193 } 2194 } 2195 2196 func TestMQTTParsePub(t *testing.T) { 2197 for _, test := range []struct { 2198 name string 2199 flags byte 2200 proto []byte 2201 pl int 2202 err string 2203 }{ 2204 {"qos not supported", (3 << 1), nil, 0, "QoS=3 is invalid in MQTT"}, 2205 {"packet in buffer error", 0, nil, 10, io.ErrUnexpectedEOF.Error()}, 2206 {"error on topic", 0, []byte{0, 3, 'f', 'o'}, 4, "topic"}, 2207 {"empty topic", 0, []byte{0, 0}, 2, errMQTTTopicIsEmpty.Error()}, 2208 {"wildcards topic", 0, []byte{0, 1, '#'}, 3, "wildcards not allowed"}, 2209 {"error on packet identifier", mqttPubQos1, []byte{0, 3, 'f', 'o', 'o'}, 5, "packet identifier"}, 2210 {"invalid packet identifier", mqttPubQos1, []byte{0, 3, 'f', 'o', 'o', 0, 0}, 7, errMQTTPacketIdentifierIsZero.Error()}, 2211 } { 2212 t.Run(test.name, func(t *testing.T) { 2213 r := &mqttReader{} 2214 r.reset(test.proto) 2215 mqtt := &mqtt{r: r} 2216 c := &client{mqtt: mqtt} 2217 pp := &mqttPublish{flags: test.flags} 2218 if err := c.mqttParsePub(r, test.pl, pp, false); err == nil || !strings.Contains(err.Error(), test.err) { 2219 t.Fatalf("Expected error %q, got %v", test.err, err) 2220 } 2221 }) 2222 } 2223 } 2224 2225 func TestMQTTParsePIMsg(t *testing.T) { 2226 for _, test := range []struct { 2227 name string 2228 proto []byte 2229 pl int 2230 err string 2231 }{ 2232 {"packet in buffer error", nil, 10, io.ErrUnexpectedEOF.Error()}, 2233 {"error reading packet identifier", []byte{0}, 1, "packet identifier"}, 2234 {"invalid packet identifier", []byte{0, 0}, 2, errMQTTPacketIdentifierIsZero.Error()}, 2235 } { 2236 t.Run(test.name, func(t *testing.T) { 2237 r := &mqttReader{} 2238 r.reset(test.proto) 2239 if _, err := mqttParsePIPacket(r, test.pl); err == nil || !strings.Contains(err.Error(), test.err) { 2240 t.Fatalf("Expected error %q, got %v", test.err, err) 2241 } 2242 }) 2243 } 2244 } 2245 2246 func TestMQTTPublish(t *testing.T) { 2247 o := testMQTTDefaultOptions() 2248 s := testMQTTRunServer(t, o) 2249 defer testMQTTShutdownServer(s) 2250 2251 nc := natsConnect(t, s.ClientURL()) 2252 defer nc.Close() 2253 2254 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2255 defer mcp.Close() 2256 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2257 2258 testMQTTPublish(t, mcp, mpr, 0, false, false, "foo", 0, []byte("msg")) 2259 testMQTTPublish(t, mcp, mpr, 1, false, false, "foo", 1, []byte("msg")) 2260 testMQTTPublish(t, mcp, mpr, 2, false, false, "foo", 2, []byte("msg")) 2261 } 2262 2263 func TestMQTTQoS2PubReject(t *testing.T) { 2264 o := testMQTTDefaultOptions() 2265 o.MQTT.rejectQoS2Pub = true 2266 s := testMQTTRunServer(t, o) 2267 defer testMQTTShutdownServer(s) 2268 2269 nc := natsConnect(t, s.ClientURL()) 2270 defer nc.Close() 2271 2272 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2273 defer mcp.Close() 2274 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2275 2276 testMQTTPublish(t, mcp, mpr, 1, false, false, "foo", 1, []byte("msg")) 2277 2278 testMQTTSendPublishPacket(t, mcp, 2, false, false, "foo", 2, []byte("msg")) 2279 testMQTTExpectDisconnect(t, mcp) 2280 } 2281 2282 func TestMQTTSub(t *testing.T) { 2283 o := testMQTTDefaultOptions() 2284 s := testMQTTRunServer(t, o) 2285 defer testMQTTShutdownServer(s) 2286 2287 nc := natsConnect(t, s.ClientURL()) 2288 defer nc.Close() 2289 2290 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2291 defer mcp.Close() 2292 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2293 2294 for _, test := range []struct { 2295 name string 2296 mqttSubTopic string 2297 natsPubSubject string 2298 mqttPubTopic string 2299 ok bool 2300 }{ 2301 {"1 level match", "foo", "foo", "foo", true}, 2302 {"1 level no match", "foo", "bar", "bar", false}, 2303 {"2 levels match", "foo/bar", "foo.bar", "foo/bar", true}, 2304 {"2 levels no match", "foo/bar", "foo.baz", "foo/baz", false}, 2305 {"3 levels match", "/foo/bar", "/.foo.bar", "/foo/bar", true}, 2306 {"3 levels no match", "/foo/bar", "/.foo.baz", "/foo/baz", false}, 2307 2308 {"single level wc", "foo/+", "foo.bar.baz", "foo/bar/baz", false}, 2309 {"single level wc", "foo/+", "foo.bar./", "foo/bar/", false}, 2310 {"single level wc", "foo/+", "foo.bar", "foo/bar", true}, 2311 {"single level wc", "foo/+", "foo./", "foo/", true}, 2312 {"single level wc", "foo/+", "foo", "foo", false}, 2313 {"single level wc", "foo/+", "/.foo", "/foo", false}, 2314 2315 {"multiple level wc", "foo/#", "foo.bar.baz./", "foo/bar/baz/", true}, 2316 {"multiple level wc", "foo/#", "foo.bar.baz", "foo/bar/baz", true}, 2317 {"multiple level wc", "foo/#", "foo.bar./", "foo/bar/", true}, 2318 {"multiple level wc", "foo/#", "foo.bar", "foo/bar", true}, 2319 {"multiple level wc", "foo/#", "foo./", "foo/", true}, 2320 {"multiple level wc", "foo/#", "foo", "foo", true}, 2321 {"multiple level wc", "foo/#", "/.foo", "/foo", false}, 2322 } { 2323 t.Run(test.name, func(t *testing.T) { 2324 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2325 defer mc.Close() 2326 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2327 2328 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: test.mqttSubTopic, qos: 0}}, []byte{0}) 2329 testMQTTFlush(t, mc, nil, r) 2330 2331 natsPub(t, nc, test.natsPubSubject, []byte("msg")) 2332 if test.ok { 2333 testMQTTCheckPubMsg(t, mc, r, test.mqttPubTopic, 0, []byte("msg")) 2334 } else { 2335 testMQTTExpectNothing(t, r) 2336 } 2337 2338 testMQTTPublish(t, mcp, mpr, 0, false, false, test.mqttPubTopic, 0, []byte("msg")) 2339 if test.ok { 2340 testMQTTCheckPubMsg(t, mc, r, test.mqttPubTopic, 0, []byte("msg")) 2341 } else { 2342 testMQTTExpectNothing(t, r) 2343 } 2344 }) 2345 } 2346 } 2347 2348 func TestMQTTSubQoS2(t *testing.T) { 2349 o := testMQTTDefaultOptions() 2350 s := testMQTTRunServer(t, o) 2351 defer testMQTTShutdownServer(s) 2352 2353 nc := natsConnect(t, s.ClientURL()) 2354 defer nc.Close() 2355 2356 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2357 defer mcp.Close() 2358 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2359 2360 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2361 defer mc.Close() 2362 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2363 2364 topic := "foo/bar/baz" 2365 mqttTopic0 := "foo/#" 2366 mqttTopic1 := "foo/bar/#" 2367 mqttTopic2 := topic 2368 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: mqttTopic0, qos: 0}}, []byte{0}) 2369 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: mqttTopic1, qos: 1}}, []byte{1}) 2370 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: mqttTopic2, qos: 2}}, []byte{2}) 2371 testMQTTFlush(t, mc, nil, r) 2372 2373 for pubQoS, expectedCounts := range map[byte]map[byte]int{ 2374 0: {0: 3}, 2375 1: {0: 1, 1: 2}, 2376 2: {0: 1, 1: 1, 2: 1}, 2377 } { 2378 t.Run(fmt.Sprintf("pubQoS %v", pubQoS), func(t *testing.T) { 2379 pubPI := uint16(456) 2380 2381 testMQTTPublish(t, mcp, mpr, pubQoS, false, false, topic, pubPI, []byte("msg")) 2382 2383 qosCounts := map[byte]int{} 2384 delivered := map[uint16]byte{} 2385 2386 // We have 3 subscriptions, each should receive the message, with the 2387 // QoS that maybe "trimmed" to that of the subscription. 2388 for i := 0; i < 3; i++ { 2389 flags, pi := testMQTTGetPubMsg(t, mc, r, topic, []byte("msg")) 2390 delivered[pi] = flags 2391 qosCounts[mqttGetQoS(flags)]++ 2392 } 2393 2394 for pi, flags := range delivered { 2395 switch mqttGetQoS(flags) { 2396 case 1: 2397 testMQTTSendPIPacket(mqttPacketPubAck, t, mc, pi) 2398 2399 case 2: 2400 testMQTTSendPIPacket(mqttPacketPubRec, t, mc, pi) 2401 testMQTTReadPIPacket(mqttPacketPubRel, t, r, pi) 2402 testMQTTSendPIPacket(mqttPacketPubComp, t, mc, pi) 2403 } 2404 } 2405 2406 if !reflect.DeepEqual(qosCounts, expectedCounts) { 2407 t.Fatalf("Expected QoS %#v, got %#v", expectedCounts, qosCounts) 2408 } 2409 }) 2410 } 2411 } 2412 2413 func TestMQTTSubQoS1(t *testing.T) { 2414 o := testMQTTDefaultOptions() 2415 s := testMQTTRunServer(t, o) 2416 defer testMQTTShutdownServer(s) 2417 2418 nc := natsConnect(t, s.ClientURL()) 2419 defer nc.Close() 2420 2421 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2422 defer mcp.Close() 2423 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2424 2425 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2426 defer mc.Close() 2427 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2428 2429 mqttTopic := "foo/bar" 2430 2431 // Subscribe with QoS 1 2432 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 2433 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: mqttTopic, qos: 1}}, []byte{1}) 2434 testMQTTFlush(t, mc, nil, r) 2435 2436 // Publish from NATS, which means QoS 0 2437 natsPub(t, nc, "foo.bar", []byte("NATS")) 2438 // Will receive as QoS 0 2439 testMQTTCheckPubMsg(t, mc, r, mqttTopic, 0, []byte("NATS")) 2440 testMQTTCheckPubMsg(t, mc, r, mqttTopic, 0, []byte("NATS")) 2441 2442 // Publish from MQTT with QoS 0 2443 testMQTTPublish(t, mcp, mpr, 0, false, false, mqttTopic, 0, []byte("msg")) 2444 // Will receive as QoS 0 2445 testMQTTCheckPubMsg(t, mc, r, mqttTopic, 0, []byte("msg")) 2446 testMQTTCheckPubMsg(t, mc, r, mqttTopic, 0, []byte("msg")) 2447 2448 // Publish from MQTT with QoS 1 2449 testMQTTPublish(t, mcp, mpr, 1, false, false, mqttTopic, 1, []byte("msg")) 2450 pflags1, pi1 := testMQTTGetPubMsg(t, mc, r, mqttTopic, []byte("msg")) 2451 if pflags1 != 0x2 { 2452 t.Fatalf("Expected flags to be 0x2, got %v", pflags1) 2453 } 2454 pflags2, pi2 := testMQTTGetPubMsg(t, mc, r, mqttTopic, []byte("msg")) 2455 if pflags2 != 0x2 { 2456 t.Fatalf("Expected flags to be 0x2, got %v", pflags2) 2457 } 2458 if pi1 == pi2 { 2459 t.Fatalf("packet identifier for message 1: %v should be different from message 2", pi1) 2460 } 2461 testMQTTSendPIPacket(mqttPacketPubAck, t, mc, pi1) 2462 testMQTTSendPIPacket(mqttPacketPubAck, t, mc, pi2) 2463 } 2464 2465 func getSubQoS(sub *subscription) int { 2466 if sub.mqtt != nil { 2467 return int(sub.mqtt.qos) 2468 } 2469 return -1 2470 } 2471 2472 func TestMQTTSubDups(t *testing.T) { 2473 o := testMQTTDefaultOptions() 2474 s := testMQTTRunServer(t, o) 2475 defer testMQTTShutdownServer(s) 2476 2477 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2478 defer mcp.Close() 2479 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2480 2481 mc, r := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", user: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2482 defer mc.Close() 2483 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2484 2485 // Test with single SUBSCRIBE protocol but multiple filters 2486 filters := []*mqttFilter{ 2487 {filter: "foo", qos: 1}, 2488 {filter: "foo", qos: 0}, 2489 } 2490 testMQTTSub(t, 1, mc, r, filters, []byte{1, 0}) 2491 testMQTTFlush(t, mc, nil, r) 2492 2493 // And also with separate SUBSCRIBE protocols 2494 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "bar", qos: 0}}, []byte{0}) 2495 // Ask for QoS 1 but server will downgrade to 1 2496 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 2497 testMQTTFlush(t, mc, nil, r) 2498 2499 // Publish and test msg received only once 2500 testMQTTPublish(t, mcp, r, 0, false, false, "foo", 0, []byte("msg")) 2501 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg")) 2502 testMQTTExpectNothing(t, r) 2503 2504 testMQTTPublish(t, mcp, r, 0, false, false, "bar", 0, []byte("msg")) 2505 testMQTTCheckPubMsg(t, mc, r, "bar", 0, []byte("msg")) 2506 testMQTTExpectNothing(t, r) 2507 2508 // Check that the QoS for subscriptions have been updated to the latest received filter 2509 var err error 2510 subc := testMQTTGetClient(t, s, "sub") 2511 subc.mu.Lock() 2512 if subc.opts.Username != "sub" { 2513 err = fmt.Errorf("wrong user name") 2514 } 2515 if err == nil { 2516 if sub := subc.subs["foo"]; sub == nil || getSubQoS(sub) != 0 { 2517 err = fmt.Errorf("subscription foo QoS should be 0, got %v", getSubQoS(sub)) 2518 } 2519 } 2520 if err == nil { 2521 if sub := subc.subs["bar"]; sub == nil || getSubQoS(sub) != 1 { 2522 err = fmt.Errorf("subscription bar QoS should be 1, got %v", getSubQoS(sub)) 2523 } 2524 } 2525 subc.mu.Unlock() 2526 if err != nil { 2527 t.Fatal(err) 2528 } 2529 2530 // Now subscribe on "foo/#" which means that a PUBLISH on "foo" will be received 2531 // by this subscription and also the one on "foo". 2532 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 2533 testMQTTFlush(t, mc, nil, r) 2534 2535 // Publish and test msg received twice 2536 testMQTTPublish(t, mcp, r, 0, false, false, "foo", 0, []byte("msg")) 2537 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg")) 2538 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg")) 2539 2540 checkWCSub := func(expectedQoS int) { 2541 t.Helper() 2542 2543 subc.mu.Lock() 2544 defer subc.mu.Unlock() 2545 2546 // When invoked with expectedQoS==1, we have the following subs: 2547 // foo (QoS-0), bar (QoS-1), foo.> (QoS-1) 2548 // which means (since QoS-1 have a JS consumer + sub for delivery 2549 // and foo.> causes a "foo fwc") that we should have the following 2550 // number of NATS subs: foo (1), bar (2), foo.> (2) and "foo fwc" (2), 2551 // so total=7. 2552 // When invoked with expectedQoS==0, it means that we have replaced 2553 // foo/# QoS-1 to QoS-0, so we should have 2 less NATS subs, 2554 // so total=5 2555 expected := 7 2556 if expectedQoS == 0 { 2557 expected = 5 2558 } 2559 if lenmap := len(subc.subs); lenmap != expected { 2560 t.Fatalf("Subs map should have %v entries, got %v", expected, lenmap) 2561 } 2562 if sub, ok := subc.subs["foo.>"]; !ok { 2563 t.Fatal("Expected sub foo.> to be present but was not") 2564 } else if getSubQoS(sub) != expectedQoS { 2565 t.Fatalf("Expected sub foo.> QoS to be %v, got %v", expectedQoS, getSubQoS(sub)) 2566 } 2567 if sub, ok := subc.subs["foo fwc"]; !ok { 2568 t.Fatal("Expected sub foo fwc to be present but was not") 2569 } else if getSubQoS(sub) != expectedQoS { 2570 t.Fatalf("Expected sub foo fwc QoS to be %v, got %v", expectedQoS, getSubQoS(sub)) 2571 } 2572 // Make sure existing sub on "foo" qos was not changed. 2573 if sub, ok := subc.subs["foo"]; !ok { 2574 t.Fatal("Expected sub foo to be present but was not") 2575 } else if getSubQoS(sub) != 0 { 2576 t.Fatalf("Expected sub foo QoS to be 0, got %v", getSubQoS(sub)) 2577 } 2578 } 2579 checkWCSub(1) 2580 2581 // Sub again on same subject with lower QoS 2582 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/#", qos: 0}}, []byte{0}) 2583 testMQTTFlush(t, mc, nil, r) 2584 2585 // Publish and test msg received twice 2586 testMQTTPublish(t, mcp, r, 0, false, false, "foo", 0, []byte("msg")) 2587 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg")) 2588 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg")) 2589 checkWCSub(0) 2590 } 2591 2592 func TestMQTTSubWithSpaces(t *testing.T) { 2593 o := testMQTTDefaultOptions() 2594 s := testMQTTRunServer(t, o) 2595 defer testMQTTShutdownServer(s) 2596 2597 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2598 defer mcp.Close() 2599 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2600 2601 mc, r := testMQTTConnect(t, &mqttConnInfo{user: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2602 defer mc.Close() 2603 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2604 2605 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo bar", qos: 0}}, []byte{mqttSubAckFailure}) 2606 } 2607 2608 func TestMQTTSubCaseSensitive(t *testing.T) { 2609 o := testMQTTDefaultOptions() 2610 s := testMQTTRunServer(t, o) 2611 defer testMQTTShutdownServer(s) 2612 2613 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2614 defer mcp.Close() 2615 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 2616 2617 mc, r := testMQTTConnect(t, &mqttConnInfo{user: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2618 defer mc.Close() 2619 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2620 2621 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "Foo/Bar", qos: 0}}, []byte{0}) 2622 testMQTTFlush(t, mc, nil, r) 2623 2624 testMQTTPublish(t, mcp, r, 0, false, false, "Foo/Bar", 0, []byte("msg")) 2625 testMQTTCheckPubMsg(t, mc, r, "Foo/Bar", 0, []byte("msg")) 2626 2627 testMQTTPublish(t, mcp, r, 0, false, false, "foo/bar", 0, []byte("msg")) 2628 testMQTTExpectNothing(t, r) 2629 2630 nc := natsConnect(t, s.ClientURL()) 2631 defer nc.Close() 2632 2633 natsPub(t, nc, "Foo.Bar", []byte("nats")) 2634 testMQTTCheckPubMsg(t, mc, r, "Foo/Bar", 0, []byte("nats")) 2635 2636 natsPub(t, nc, "foo.bar", []byte("nats")) 2637 testMQTTExpectNothing(t, r) 2638 } 2639 2640 func TestMQTTPubSubMatrix(t *testing.T) { 2641 for _, test := range []struct { 2642 name string 2643 natsPub bool 2644 mqttPub bool 2645 mqttPubQoS byte 2646 natsSub bool 2647 mqttSubQoS0 bool 2648 mqttSubQoS1 bool 2649 }{ 2650 {"NATS to MQTT sub QoS-0", true, false, 0, false, true, false}, 2651 {"NATS to MQTT sub QoS-1", true, false, 0, false, false, true}, 2652 {"NATS to MQTT sub QoS-0 and QoS-1", true, false, 0, false, true, true}, 2653 2654 {"MQTT QoS-0 to NATS sub", false, true, 0, true, false, false}, 2655 {"MQTT QoS-0 to MQTT sub QoS-0", false, true, 0, false, true, false}, 2656 {"MQTT QoS-0 to MQTT sub QoS-1", false, true, 0, false, false, true}, 2657 {"MQTT QoS-0 to NATS sub and MQTT sub QoS-0", false, true, 0, true, true, false}, 2658 {"MQTT QoS-0 to NATS sub and MQTT sub QoS-1", false, true, 0, true, false, true}, 2659 {"MQTT QoS-0 to all subs", false, true, 0, true, true, true}, 2660 2661 {"MQTT QoS-1 to NATS sub", false, true, 1, true, false, false}, 2662 {"MQTT QoS-1 to MQTT sub QoS-0", false, true, 1, false, true, false}, 2663 {"MQTT QoS-1 to MQTT sub QoS-1", false, true, 1, false, false, true}, 2664 {"MQTT QoS-1 to NATS sub and MQTT sub QoS-0", false, true, 1, true, true, false}, 2665 {"MQTT QoS-1 to NATS sub and MQTT sub QoS-1", false, true, 1, true, false, true}, 2666 {"MQTT QoS-1 to all subs", false, true, 1, true, true, true}, 2667 } { 2668 t.Run(test.name, func(t *testing.T) { 2669 o := testMQTTDefaultOptions() 2670 s := testMQTTRunServer(t, o) 2671 defer testMQTTShutdownServer(s) 2672 2673 nc := natsConnect(t, s.ClientURL()) 2674 defer nc.Close() 2675 2676 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2677 defer mc.Close() 2678 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2679 2680 mc1, r1 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2681 defer mc1.Close() 2682 testMQTTCheckConnAck(t, r1, mqttConnAckRCConnectionAccepted, false) 2683 2684 mc2, r2 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2685 defer mc2.Close() 2686 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 2687 2688 // First setup subscriptions based on test options. 2689 var ns *nats.Subscription 2690 if test.natsSub { 2691 ns = natsSubSync(t, nc, "foo") 2692 } 2693 if test.mqttSubQoS0 { 2694 testMQTTSub(t, 1, mc1, r1, []*mqttFilter{{filter: "foo", qos: 0}}, []byte{0}) 2695 testMQTTFlush(t, mc1, nil, r1) 2696 } 2697 if test.mqttSubQoS1 { 2698 testMQTTSub(t, 1, mc2, r2, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 2699 testMQTTFlush(t, mc2, nil, r2) 2700 } 2701 2702 // Just as a barrier 2703 natsFlush(t, nc) 2704 2705 // Now publish 2706 if test.natsPub { 2707 natsPubReq(t, nc, "foo", "", []byte("msg")) 2708 } else { 2709 testMQTTPublish(t, mc, r, test.mqttPubQoS, false, false, "foo", 1, []byte("msg")) 2710 } 2711 2712 // Check message received 2713 if test.natsSub { 2714 natsNexMsg(t, ns, time.Second) 2715 // Make sure no other is received 2716 if msg, err := ns.NextMsg(50 * time.Millisecond); err == nil { 2717 t.Fatalf("Should not have gotten a second message, got %v", msg) 2718 } 2719 } 2720 if test.mqttSubQoS0 { 2721 testMQTTCheckPubMsg(t, mc1, r1, "foo", 0, []byte("msg")) 2722 testMQTTExpectNothing(t, r1) 2723 } 2724 if test.mqttSubQoS1 { 2725 var expectedFlag byte 2726 if test.mqttPubQoS > 0 { 2727 expectedFlag = test.mqttPubQoS << 1 2728 } 2729 testMQTTCheckPubMsg(t, mc2, r2, "foo", expectedFlag, []byte("msg")) 2730 testMQTTExpectNothing(t, r2) 2731 } 2732 }) 2733 } 2734 } 2735 2736 func TestMQTTPreventSubWithMQTTSubPrefix(t *testing.T) { 2737 o := testMQTTDefaultOptions() 2738 s := testMQTTRunServer(t, o) 2739 defer testMQTTShutdownServer(s) 2740 2741 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2742 defer mc.Close() 2743 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2744 testMQTTSub(t, 1, mc, r, 2745 []*mqttFilter{{filter: strings.ReplaceAll(mqttSubPrefix, ".", "/") + "foo/bar", qos: 1}}, 2746 []byte{mqttSubAckFailure}) 2747 } 2748 2749 func TestMQTTSubWithNATSStream(t *testing.T) { 2750 o := testMQTTDefaultOptions() 2751 s := testMQTTRunServer(t, o) 2752 defer testMQTTShutdownServer(s) 2753 2754 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2755 defer mc.Close() 2756 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2757 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/bar", qos: 1}}, []byte{1}) 2758 testMQTTFlush(t, mc, nil, r) 2759 2760 mcp, rp := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2761 defer mcp.Close() 2762 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 2763 testMQTTFlush(t, mcp, nil, rp) 2764 2765 nc := natsConnect(t, s.ClientURL()) 2766 defer nc.Close() 2767 2768 sc := &StreamConfig{ 2769 Name: "test", 2770 Storage: FileStorage, 2771 Retention: InterestPolicy, 2772 Subjects: []string{"foo.>"}, 2773 } 2774 mset, err := s.GlobalAccount().addStream(sc) 2775 if err != nil { 2776 t.Fatalf("Unable to create stream: %v", err) 2777 } 2778 2779 sub := natsSubSync(t, nc, "bar") 2780 cc := &ConsumerConfig{ 2781 Durable: "dur", 2782 AckPolicy: AckExplicit, 2783 DeliverSubject: "bar", 2784 } 2785 if _, err := mset.addConsumer(cc); err != nil { 2786 t.Fatalf("Unable to add consumer: %v", err) 2787 } 2788 2789 // Now send message from NATS 2790 resp, err := nc.Request("foo.bar", []byte("nats"), time.Second) 2791 if err != nil { 2792 t.Fatalf("Error publishing: %v", err) 2793 } 2794 ar := &ApiResponse{} 2795 if err := json.Unmarshal(resp.Data, ar); err != nil || ar.Error != nil { 2796 t.Fatalf("Unexpected response: err=%v resp=%+v", err, ar.Error) 2797 } 2798 2799 // Check that message is received by both 2800 checkRecv := func(content string, flags byte) { 2801 t.Helper() 2802 if msg := natsNexMsg(t, sub, time.Second); string(msg.Data) != content { 2803 t.Fatalf("Expected %q, got %q", content, msg.Data) 2804 } 2805 testMQTTCheckPubMsg(t, mc, r, "foo/bar", flags, []byte(content)) 2806 } 2807 checkRecv("nats", 0) 2808 2809 // Send from MQTT as a QoS0 2810 testMQTTPublish(t, mcp, rp, 0, false, false, "foo/bar", 0, []byte("qos0")) 2811 checkRecv("qos0", 0) 2812 2813 // Send from MQTT as a QoS1 2814 testMQTTPublish(t, mcp, rp, 1, false, false, "foo/bar", 1, []byte("qos1")) 2815 checkRecv("qos1", mqttPubQos1) 2816 } 2817 2818 func TestMQTTTrackPendingOverrun(t *testing.T) { 2819 sess := mqttSession{} 2820 2821 sess.last_pi = 0xFFFF 2822 pi := sess.trackPublishRetained() 2823 if pi != 1 { 2824 t.Fatalf("Expected 1, got %v", pi) 2825 } 2826 2827 p := &mqttPending{} 2828 for i := 1; i <= 0xFFFF; i++ { 2829 sess.pendingPublish[uint16(i)] = p 2830 } 2831 pi, _ = sess.trackPublish("test", "test") 2832 if pi != 0 { 2833 t.Fatalf("Expected 0, got %v", pi) 2834 } 2835 2836 delete(sess.pendingPublish, 1234) 2837 pi = sess.trackPublishRetained() 2838 if pi != 1234 { 2839 t.Fatalf("Expected 1234, got %v", pi) 2840 } 2841 } 2842 2843 func TestMQTTSubRestart(t *testing.T) { 2844 o := testMQTTDefaultOptions() 2845 s := testMQTTRunServer(t, o) 2846 defer testMQTTShutdownServer(s) 2847 2848 nc := natsConnect(t, s.ClientURL()) 2849 defer nc.Close() 2850 2851 mc, r := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, o.MQTT.Host, o.MQTT.Port) 2852 defer mc.Close() 2853 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2854 2855 // Start an MQTT subscription QoS=1 on "foo" 2856 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 2857 testMQTTFlush(t, mc, nil, r) 2858 2859 // Now start a NATS subscription on ">" (anything that would match the JS consumer delivery subject) 2860 natsSubSync(t, nc, ">") 2861 natsFlush(t, nc) 2862 2863 // Restart the MQTT client 2864 testMQTTDisconnect(t, mc, nil) 2865 2866 mc, r = testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, o.MQTT.Host, o.MQTT.Port) 2867 defer mc.Close() 2868 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 2869 2870 // Restart an MQTT subscription QoS=1 on "foo" 2871 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 2872 testMQTTFlush(t, mc, nil, r) 2873 2874 pc, pr := testMQTTConnect(t, &mqttConnInfo{clientID: "pub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2875 defer pc.Close() 2876 testMQTTCheckConnAck(t, pr, mqttConnAckRCConnectionAccepted, false) 2877 2878 // Publish a message QoS1 2879 testMQTTPublish(t, pc, pr, 1, false, false, "foo", 1, []byte("msg1")) 2880 // Make sure we receive it 2881 testMQTTCheckPubMsg(t, mc, r, "foo", mqttPubQos1, []byte("msg1")) 2882 2883 // Now "restart" the subscription but as a Qos0 2884 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo", qos: 0}}, []byte{0}) 2885 testMQTTFlush(t, mc, nil, r) 2886 2887 // Publish a message QoS 2888 testMQTTPublish(t, pc, pr, 1, false, false, "foo", 1, []byte("msg2")) 2889 // Make sure we receive but as a QoS0 2890 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg2")) 2891 } 2892 2893 func testMQTTGetClusterTemplaceNoLeaf() string { 2894 return strings.Replace(jsClusterTemplWithLeafAndMQTT, "{{leaf}}", "", 1) 2895 } 2896 2897 func TestMQTTSubPropagation(t *testing.T) { 2898 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", 2) 2899 defer cl.shutdown() 2900 2901 o := cl.opts[0] 2902 s2 := cl.servers[1] 2903 nc := natsConnect(t, s2.ClientURL()) 2904 defer nc.Close() 2905 2906 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2907 defer mc.Close() 2908 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2909 2910 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/#", qos: 0}}, []byte{0}) 2911 testMQTTFlush(t, mc, nil, r) 2912 2913 // Because in MQTT foo/# means foo.> but also foo, check that this is propagated 2914 checkSubInterest(t, s2, globalAccountName, "foo", time.Second) 2915 2916 // Publish on foo.bar, foo./ and foo and we should receive them 2917 natsPub(t, nc, "foo.bar", []byte("hello")) 2918 testMQTTCheckPubMsg(t, mc, r, "foo/bar", 0, []byte("hello")) 2919 2920 natsPub(t, nc, "foo./", []byte("from")) 2921 testMQTTCheckPubMsg(t, mc, r, "foo/", 0, []byte("from")) 2922 2923 natsPub(t, nc, "foo", []byte("NATS")) 2924 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("NATS")) 2925 } 2926 2927 func TestMQTTCluster(t *testing.T) { 2928 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", 2) 2929 defer cl.shutdown() 2930 2931 for _, topTest := range []struct { 2932 name string 2933 restart bool 2934 }{ 2935 {"first_start", true}, 2936 {"restart", false}, 2937 } { 2938 t.Run(topTest.name, func(t *testing.T) { 2939 for _, test := range []struct { 2940 name string 2941 subQos byte 2942 }{ 2943 {"qos_0", 0}, 2944 {"qos_1", 1}, 2945 } { 2946 t.Run(test.name, func(t *testing.T) { 2947 clientID := nuid.Next() 2948 2949 o := cl.opts[0] 2950 mc, r := testMQTTConnectRetry(t, &mqttConnInfo{clientID: clientID, cleanSess: false}, o.MQTT.Host, o.MQTT.Port, 5) 2951 defer mc.Close() 2952 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 2953 2954 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/#", qos: test.subQos}}, []byte{test.subQos}) 2955 testMQTTFlush(t, mc, nil, r) 2956 2957 check := func(mc net.Conn, r *mqttReader, o *Options, s *Server) { 2958 t.Helper() 2959 2960 nc := natsConnect(t, s.ClientURL()) 2961 defer nc.Close() 2962 2963 natsPub(t, nc, "foo.bar", []byte("fromNats")) 2964 testMQTTCheckPubMsg(t, mc, r, "foo/bar", 0, []byte("fromNats")) 2965 2966 mpc, pr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 2967 defer mpc.Close() 2968 testMQTTCheckConnAck(t, pr, mqttConnAckRCConnectionAccepted, false) 2969 2970 testMQTTPublish(t, mpc, pr, 0, false, false, "foo/baz", 0, []byte("mqtt_qos0")) 2971 testMQTTCheckPubMsg(t, mc, r, "foo/baz", 0, []byte("mqtt_qos0")) 2972 2973 testMQTTPublish(t, mpc, pr, 1, false, false, "foo/bat", 1, []byte("mqtt_qos1")) 2974 expectedQoS := byte(0) 2975 if test.subQos == 1 { 2976 expectedQoS = mqttPubQos1 2977 } 2978 testMQTTCheckPubMsg(t, mc, r, "foo/bat", expectedQoS, []byte("mqtt_qos1")) 2979 testMQTTDisconnect(t, mpc, nil) 2980 } 2981 check(mc, r, cl.opts[0], cl.servers[0]) 2982 check(mc, r, cl.opts[1], cl.servers[1]) 2983 2984 // Start the same subscription from the other server. It should disconnect 2985 // the one connected in the first server. 2986 o = cl.opts[1] 2987 2988 mc2, r2 := testMQTTConnect(t, &mqttConnInfo{clientID: clientID, cleanSess: false}, o.MQTT.Host, o.MQTT.Port) 2989 defer mc2.Close() 2990 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, true) 2991 2992 // Expect first connection to be closed. 2993 testMQTTExpectDisconnect(t, mc) 2994 2995 // Now re-run the checks 2996 check(mc2, r2, cl.opts[0], cl.servers[0]) 2997 check(mc2, r2, cl.opts[1], cl.servers[1]) 2998 2999 // Disconnect our sub and restart with clean session then disconnect again to clear the state. 3000 testMQTTDisconnect(t, mc2, nil) 3001 mc2, r2 = testMQTTConnect(t, &mqttConnInfo{clientID: clientID, cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3002 defer mc2.Close() 3003 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 3004 testMQTTFlush(t, mc2, nil, r2) 3005 testMQTTDisconnect(t, mc2, nil) 3006 3007 // Remove the session from the flappers so we can restart the test 3008 // without failure and have to wait for 1sec before being able to reconnect. 3009 s := cl.servers[0] 3010 sm := &s.mqtt.sessmgr 3011 sm.mu.Lock() 3012 asm := sm.sessions[globalAccountName] 3013 sm.mu.Unlock() 3014 if asm != nil { 3015 asm.mu.Lock() 3016 delete(asm.flappers, clientID) 3017 asm.mu.Unlock() 3018 } 3019 }) 3020 } 3021 if !t.Failed() && topTest.restart { 3022 cl.stopAll() 3023 cl.restartAll() 3024 3025 streams := []string{mqttStreamName, mqttRetainedMsgsStreamName, mqttSessStreamName} 3026 for _, sn := range streams { 3027 cl.waitOnStreamLeader(globalAccountName, sn) 3028 } 3029 3030 mset, err := cl.randomServer().GlobalAccount().lookupStream(mqttRetainedMsgsStreamName) 3031 if err != nil { 3032 t.Fatalf("Expected to find a stream for %q", mqttRetainedMsgsStreamName) 3033 } 3034 3035 rmConsumerNames := []string{} 3036 mset.mu.RLock() 3037 for _, o := range mset.consumers { 3038 rmConsumerNames = append(rmConsumerNames, o.name) 3039 } 3040 mset.mu.RUnlock() 3041 3042 for _, consumerName := range rmConsumerNames { 3043 cl.waitOnConsumerLeader(globalAccountName, mqttRetainedMsgsStreamName, consumerName) 3044 } 3045 } 3046 }) 3047 } 3048 } 3049 3050 func testMQTTConnectDisconnect(t *testing.T, o *Options, clientID string, clean bool, found bool) { 3051 t.Helper() 3052 mc, r := testMQTTConnect(t, &mqttConnInfo{clientID: clientID, cleanSess: clean}, o.MQTT.Host, o.MQTT.Port) 3053 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, found) 3054 testMQTTDisconnectEx(t, mc, nil, false) 3055 mc.Close() 3056 } 3057 3058 func TestMQTTClusterConnectDisconnectClean(t *testing.T) { 3059 nServers := 3 3060 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", nServers) 3061 defer cl.shutdown() 3062 3063 clientID := nuid.Next() 3064 3065 // test runs a connect/disconnect against a random server in the cluster, as 3066 // specified. 3067 N := 100 3068 for n := 0; n < N; n++ { 3069 testMQTTConnectDisconnect(t, cl.opts[rand.Intn(nServers)], clientID, true, false) 3070 } 3071 } 3072 3073 func TestMQTTClusterConnectDisconnectPersist(t *testing.T) { 3074 nServers := 3 3075 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", nServers) 3076 defer cl.shutdown() 3077 3078 clientID := nuid.Next() 3079 3080 // test runs a connect/disconnect against a random server in the cluster, as 3081 // specified. 3082 N := 20 3083 for n := 0; n < N; n++ { 3084 // First clean sessions on all servers 3085 for i := 0; i < nServers; i++ { 3086 testMQTTConnectDisconnect(t, cl.opts[i], clientID, true, false) 3087 } 3088 3089 testMQTTConnectDisconnect(t, cl.opts[0], clientID, false, false) 3090 testMQTTConnectDisconnect(t, cl.opts[1], clientID, false, true) 3091 testMQTTConnectDisconnect(t, cl.opts[2], clientID, false, true) 3092 testMQTTConnectDisconnect(t, cl.opts[0], clientID, false, true) 3093 } 3094 } 3095 3096 func TestMQTTClusterRetainedMsg(t *testing.T) { 3097 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", 2) 3098 defer cl.shutdown() 3099 3100 srv1Opts := cl.opts[0] 3101 srv2Opts := cl.opts[1] 3102 3103 // Connect subscription on server 1. 3104 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, srv1Opts.MQTT.Host, srv1Opts.MQTT.Port, 5) 3105 defer mc.Close() 3106 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3107 3108 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 3109 testMQTTFlush(t, mc, nil, rc) 3110 3111 // Create a publisher from server 2. 3112 mp, rp := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, srv2Opts.MQTT.Host, srv2Opts.MQTT.Port) 3113 defer mp.Close() 3114 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 3115 3116 // Send retained message. 3117 testMQTTPublish(t, mp, rp, 1, false, true, "foo/bar", 1, []byte("retained")) 3118 // Check it is received. 3119 testMQTTCheckPubMsg(t, mc, rc, "foo/bar", mqttPubQos1, []byte("retained")) 3120 3121 // Start a new subscription on server 1 and make sure we receive the retained message 3122 mc2, rc2 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, srv1Opts.MQTT.Host, srv1Opts.MQTT.Port) 3123 defer mc2.Close() 3124 testMQTTCheckConnAck(t, rc2, mqttConnAckRCConnectionAccepted, false) 3125 testMQTTSub(t, 1, mc2, rc2, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 3126 testMQTTCheckPubMsg(t, mc2, rc2, "foo/bar", mqttPubQos1|mqttPubFlagRetain, []byte("retained")) 3127 testMQTTDisconnect(t, mc2, nil) 3128 3129 // Send an empty retained message which should remove it from storage, but still be delivered. 3130 testMQTTPublish(t, mp, rp, 1, false, true, "foo/bar", 1, []byte("")) 3131 testMQTTCheckPubMsg(t, mc, rc, "foo/bar", mqttPubQos1, []byte("")) 3132 3133 // Now shutdown the consumer connection 3134 testMQTTDisconnect(t, mc, nil) 3135 mc.Close() 3136 3137 // Reconnect to server where the retained message was published (server 2) 3138 mc, rc = testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, srv2Opts.MQTT.Host, srv2Opts.MQTT.Port) 3139 defer mc.Close() 3140 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, true) 3141 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 3142 // The retained message should not be delivered. 3143 testMQTTExpectNothing(t, rc) 3144 // Now disconnect and reconnect back to first server 3145 testMQTTDisconnect(t, mc, nil) 3146 mc.Close() 3147 3148 // Now reconnect to the server 1, which is not where the messages were published, and check 3149 // that we don't receive the message. 3150 mc, rc = testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, srv1Opts.MQTT.Host, srv1Opts.MQTT.Port) 3151 defer mc.Close() 3152 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, true) 3153 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 3154 testMQTTExpectNothing(t, rc) 3155 testMQTTDisconnect(t, mc, nil) 3156 mc.Close() 3157 3158 // Will now test network deletes 3159 3160 // Create a subscription on server 1 and server 2 3161 mc, rc = testMQTTConnect(t, &mqttConnInfo{clientID: "sub_one", cleanSess: false}, srv1Opts.MQTT.Host, srv1Opts.MQTT.Port) 3162 defer mc.Close() 3163 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3164 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 3165 testMQTTFlush(t, mc, nil, rc) 3166 3167 mc2, rc2 = testMQTTConnect(t, &mqttConnInfo{clientID: "sub_two", cleanSess: false}, srv2Opts.MQTT.Host, srv2Opts.MQTT.Port) 3168 defer mc2.Close() 3169 testMQTTCheckConnAck(t, rc2, mqttConnAckRCConnectionAccepted, false) 3170 testMQTTSub(t, 1, mc2, rc2, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 3171 testMQTTFlush(t, mc2, nil, rc2) 3172 3173 // Publish 1 retained message (producer is connected to server 2) 3174 testMQTTPublish(t, mp, rp, 1, false, true, "bar", 1, []byte("msg1")) 3175 3176 // Make sure messages are received by both 3177 testMQTTCheckPubMsg(t, mc, rc, "bar", mqttPubQos1, []byte("msg1")) 3178 testMQTTCheckPubMsg(t, mc2, rc2, "bar", mqttPubQos1, []byte("msg1")) 3179 3180 // Now send an empty retained message that should delete it. For the one on server 1, 3181 // this will be a network delete. 3182 testMQTTPublish(t, mp, rp, 1, false, true, "bar", 1, []byte("")) 3183 testMQTTCheckPubMsg(t, mc, rc, "bar", mqttPubQos1, []byte("")) 3184 testMQTTCheckPubMsg(t, mc2, rc2, "bar", mqttPubQos1, []byte("")) 3185 3186 // Now send a new retained message 3187 testMQTTPublish(t, mp, rp, 1, false, true, "bar", 1, []byte("msg2")) 3188 3189 // Again, verify that they all receive it. 3190 testMQTTCheckPubMsg(t, mc, rc, "bar", mqttPubQos1, []byte("msg2")) 3191 testMQTTCheckPubMsg(t, mc2, rc2, "bar", mqttPubQos1, []byte("msg2")) 3192 3193 // But now, restart the consumer that was in the server that processed the 3194 // original network delete. 3195 testMQTTDisconnect(t, mc, nil) 3196 mc.Close() 3197 3198 mc, rc = testMQTTConnect(t, &mqttConnInfo{clientID: "sub_one", cleanSess: false}, srv1Opts.MQTT.Host, srv1Opts.MQTT.Port) 3199 defer mc.Close() 3200 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, true) 3201 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 3202 // Expect the message to be delivered as retained 3203 testMQTTCheckPubMsg(t, mc, rc, "bar", mqttPubQos1|mqttPubFlagRetain, []byte("msg2")) 3204 } 3205 3206 func TestMQTTRetainedMsgNetworkUpdates(t *testing.T) { 3207 o := testMQTTDefaultOptions() 3208 s := testMQTTRunServer(t, o) 3209 defer testMQTTShutdownServer(s) 3210 3211 mc, rc := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3212 defer mc.Close() 3213 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3214 3215 c := testMQTTGetClient(t, s, "sub") 3216 asm := c.mqtt.asm 3217 3218 // For this test, we are going to simulate updates arriving in a 3219 // mixed order and verify that we have the expected outcome. 3220 check := func(t *testing.T, subject string, present bool, current, floor uint64) { 3221 t.Helper() 3222 asm.mu.RLock() 3223 defer asm.mu.RUnlock() 3224 erm, ok := asm.retmsgs[subject] 3225 if present && !ok { 3226 t.Fatalf("Subject %q not present", subject) 3227 } else if !present && ok { 3228 t.Fatalf("Subject %q should not be present", subject) 3229 } else if !present { 3230 return 3231 } 3232 if floor != erm.floor { 3233 t.Fatalf("Expected floor to be %v, got %v", floor, erm.floor) 3234 } 3235 if erm.sseq != current { 3236 t.Fatalf("Expected current sequence to be %v, got %v", current, erm.sseq) 3237 } 3238 } 3239 3240 type action struct { 3241 add bool 3242 seq uint64 3243 } 3244 for _, test := range []struct { 3245 subject string 3246 order []action 3247 seq uint64 3248 floor uint64 3249 }{ 3250 {"foo.1", []action{{true, 1}, {true, 2}, {true, 3}}, 3, 0}, 3251 {"foo.2", []action{{true, 3}, {true, 1}, {true, 2}}, 3, 0}, 3252 {"foo.3", []action{{true, 1}, {false, 1}, {true, 2}}, 2, 0}, 3253 {"foo.4", []action{{false, 2}, {true, 1}, {true, 3}, {true, 2}}, 3, 0}, 3254 {"foo.5", []action{{false, 2}, {true, 1}, {true, 2}}, 0, 2}, 3255 {"foo.6", []action{{true, 1}, {true, 2}, {false, 2}}, 0, 2}, 3256 } { 3257 t.Run(test.subject, func(t *testing.T) { 3258 for _, a := range test.order { 3259 if a.add { 3260 rf := &mqttRetainedMsgRef{sseq: a.seq} 3261 asm.handleRetainedMsg(test.subject, rf, nil, false) 3262 } else { 3263 asm.handleRetainedMsgDel(test.subject, a.seq) 3264 } 3265 } 3266 check(t, test.subject, true, test.seq, test.floor) 3267 }) 3268 } 3269 3270 for _, subject := range []string{"foo.5", "foo.6"} { 3271 t.Run("clear_"+subject, func(t *testing.T) { 3272 // Now add a new message, which should clear the floor. 3273 rf := &mqttRetainedMsgRef{sseq: 3} 3274 asm.handleRetainedMsg(subject, rf, nil, false) 3275 check(t, subject, true, 3, 0) 3276 // Now do a non network delete and make sure it is gone. 3277 asm.handleRetainedMsgDel(subject, 0) 3278 check(t, subject, false, 0, 0) 3279 }) 3280 } 3281 } 3282 3283 func TestMQTTRetainedMsgDel(t *testing.T) { 3284 o := testMQTTDefaultOptions() 3285 s := testMQTTRunServer(t, o) 3286 defer testMQTTShutdownServer(s) 3287 mc, _ := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3288 defer mc.Close() 3289 3290 c := testMQTTGetClient(t, s, "sub") 3291 asm := c.mqtt.asm 3292 var i uint64 3293 for i = 0; i < 3; i++ { 3294 rf := &mqttRetainedMsgRef{sseq: i} 3295 asm.handleRetainedMsg("subject", rf, nil, false) 3296 } 3297 asm.handleRetainedMsgDel("subject", 2) 3298 if asm.sl.count > 0 { 3299 t.Fatalf("all retained messages subs should be removed, but %d still present", asm.sl.count) 3300 } 3301 } 3302 3303 func TestMQTTRetainedMsgMigration(t *testing.T) { 3304 o := testMQTTDefaultOptions() 3305 s := testMQTTRunServer(t, o) 3306 defer testMQTTShutdownServer(s) 3307 3308 nc, js := jsClientConnect(t, s) 3309 defer nc.Close() 3310 3311 // Create the retained messages stream to listen on the old subject first. 3312 // The server will correct this when the migration takes place. 3313 _, err := js.AddStream(&nats.StreamConfig{ 3314 Name: mqttRetainedMsgsStreamName, 3315 Subjects: []string{`$MQTT.rmsgs`}, 3316 Storage: nats.FileStorage, 3317 Retention: nats.LimitsPolicy, 3318 Replicas: 1, 3319 }) 3320 require_NoError(t, err) 3321 3322 // Publish some retained messages on the old "$MQTT.rmsgs" subject. 3323 const N = 100 3324 for i := 0; i < N; i++ { 3325 msg := fmt.Sprintf( 3326 `{"origin":"b5IQZNtG","subject":"test%d","topic":"test%d","msg":"YmFy","flags":1}`, i, i, 3327 ) 3328 _, err := js.Publish(`$MQTT.rmsgs`, []byte(msg)) 3329 require_NoError(t, err) 3330 } 3331 3332 // Check that the old subject looks right. 3333 si, err := js.StreamInfo(mqttRetainedMsgsStreamName, &nats.StreamInfoRequest{ 3334 SubjectsFilter: `$MQTT.>`, 3335 }) 3336 require_NoError(t, err) 3337 if si.State.NumSubjects != 1 { 3338 t.Fatalf("expected 1 subject, got %d", si.State.NumSubjects) 3339 } 3340 if n := si.State.Subjects[`$MQTT.rmsgs`]; n != N { 3341 t.Fatalf("expected to find %d messages on the original subject but found %d", N, n) 3342 } 3343 3344 // Create an MQTT client, this will cause a migration to take place. 3345 mc, rc := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3346 defer mc.Close() 3347 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3348 3349 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "+", qos: 0}}, []byte{0}) 3350 topics := map[string]struct{}{} 3351 for i := 0; i < N; i++ { 3352 _, _, topic := testMQTTGetPubMsgEx(t, mc, rc, _EMPTY_, []byte("bar")) 3353 topics[topic] = struct{}{} 3354 } 3355 if len(topics) != N { 3356 t.Fatalf("Unexpected topics: %v", topics) 3357 } 3358 3359 // Now look at the stream, there should be N messages on the new 3360 // divided subjects and none on the old undivided subject. 3361 si, err = js.StreamInfo(mqttRetainedMsgsStreamName, &nats.StreamInfoRequest{ 3362 SubjectsFilter: `$MQTT.>`, 3363 }) 3364 require_NoError(t, err) 3365 if si.State.NumSubjects != N { 3366 t.Fatalf("expected %d subjects, got %d", N, si.State.NumSubjects) 3367 } 3368 if n := si.State.Subjects[`$MQTT.rmsgs`]; n > 0 { 3369 t.Fatalf("expected to find no messages on the original subject but found %d", n) 3370 } 3371 3372 // Check that the message counts look right. There should be one 3373 // retained message per key. 3374 for i := 0; i < N; i++ { 3375 expected := fmt.Sprintf(`$MQTT.rmsgs.test%d`, i) 3376 n, ok := si.State.Subjects[expected] 3377 if !ok { 3378 t.Fatalf("expected to find %q but didn't", expected) 3379 } 3380 if n != 1 { 3381 t.Fatalf("expected %q to have 1 message but had %d", expected, n) 3382 } 3383 } 3384 } 3385 3386 func TestMQTTClusterReplicasCount(t *testing.T) { 3387 for _, test := range []struct { 3388 size int 3389 replicas int 3390 }{ 3391 {1, 1}, 3392 {2, 2}, 3393 {3, 3}, 3394 {5, 3}, 3395 } { 3396 t.Run(fmt.Sprintf("size %v", test.size), func(t *testing.T) { 3397 var s *Server 3398 var o *Options 3399 if test.size == 1 { 3400 o = testMQTTDefaultOptions() 3401 s = testMQTTRunServer(t, o) 3402 defer testMQTTShutdownServer(s) 3403 } else { 3404 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", test.size) 3405 defer cl.shutdown() 3406 o = cl.opts[0] 3407 s = cl.randomServer() 3408 } 3409 3410 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, o.MQTT.Host, o.MQTT.Port, 5) 3411 defer mc.Close() 3412 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3413 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 3414 testMQTTFlush(t, mc, nil, rc) 3415 3416 nc := natsConnect(t, s.ClientURL()) 3417 defer nc.Close() 3418 3419 // Check the replicas of all MQTT streams 3420 js, err := nc.JetStream() 3421 if err != nil { 3422 t.Fatalf("Error getting js: %v", err) 3423 } 3424 for _, sname := range []string{ 3425 mqttStreamName, 3426 mqttRetainedMsgsStreamName, 3427 mqttSessStreamName, 3428 } { 3429 t.Run(sname, func(t *testing.T) { 3430 si, err := js.StreamInfo(sname) 3431 if err != nil { 3432 t.Fatalf("Error getting stream info: %v", err) 3433 } 3434 if si.Config.Replicas != test.replicas { 3435 t.Fatalf("Expected %v replicas, got %v", test.replicas, si.Config.Replicas) 3436 } 3437 }) 3438 } 3439 }) 3440 } 3441 } 3442 3443 func TestMQTTClusterCanCreateSessionWithOnServerDown(t *testing.T) { 3444 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", 3) 3445 defer cl.shutdown() 3446 o := cl.opts[0] 3447 3448 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 3449 defer mc.Close() 3450 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3451 mc.Close() 3452 3453 // Shutdown one of the server. 3454 sd := cl.servers[1].StoreDir() 3455 defer os.RemoveAll(strings.TrimSuffix(sd, JetStreamStoreDir)) 3456 cl.servers[1].Shutdown() 3457 3458 // Make sure there is a meta leader 3459 cl.waitOnPeerCount(2) 3460 cl.waitOnLeader() 3461 3462 // Now try to create a new session. Since we use a single stream now for all sessions, 3463 // this should succeed. 3464 o = cl.opts[2] 3465 // We may still get failures because of some JS APIs may timeout while things 3466 // settle, so try again for a certain amount of times. 3467 mc, rc = testMQTTConnectRetry(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 3468 defer mc.Close() 3469 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3470 } 3471 3472 func TestMQTTClusterPlacement(t *testing.T) { 3473 sc := createJetStreamSuperCluster(t, 3, 2) 3474 defer sc.shutdown() 3475 3476 c := sc.randomCluster() 3477 lnc := c.createLeafNodesWithTemplateAndStartPort(jsClusterTemplWithLeafAndMQTT, "SPOKE", 3, 22111) 3478 defer lnc.shutdown() 3479 3480 sc.waitOnPeerCount(9) 3481 sc.waitOnLeader() 3482 3483 for i := 0; i < 10; i++ { 3484 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{cleanSess: true}, lnc.opts[i%3].MQTT.Host, lnc.opts[i%3].MQTT.Port, 5) 3485 defer mc.Close() 3486 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3487 } 3488 3489 // Now check that MQTT assets have been created in the LEAF node's side, not the Hub. 3490 nc := natsConnect(t, lnc.servers[0].ClientURL()) 3491 defer nc.Close() 3492 js, err := nc.JetStream() 3493 if err != nil { 3494 t.Fatalf("Unable to get JetStream: %v", err) 3495 } 3496 count := 0 3497 for si := range js.StreamsInfo() { 3498 if si.Cluster == nil || si.Cluster.Name != "SPOKE" { 3499 t.Fatalf("Expected asset %q to be placed on spoke cluster, was placed on %+v", si.Config.Name, si.Cluster) 3500 } 3501 for _, repl := range si.Cluster.Replicas { 3502 if !strings.HasPrefix(repl.Name, "SPOKE-") { 3503 t.Fatalf("Replica on the wrong cluster: %+v", repl) 3504 } 3505 } 3506 if si.State.Consumers > 0 { 3507 for ci := range js.ConsumersInfo(si.Config.Name) { 3508 if ci.Cluster == nil || ci.Cluster.Name != "SPOKE" { 3509 t.Fatalf("Expected asset %q to be placed on spoke cluster, was placed on %+v", ci.Name, si.Cluster) 3510 } 3511 for _, repl := range ci.Cluster.Replicas { 3512 if !strings.HasPrefix(repl.Name, "SPOKE-") { 3513 t.Fatalf("Replica on the wrong cluster: %+v", repl) 3514 } 3515 } 3516 } 3517 } 3518 count++ 3519 } 3520 if count == 0 { 3521 t.Fatal("No stream found!") 3522 } 3523 } 3524 3525 func TestMQTTLeafnodeWithoutJSToClusterWithJSNoSharedSysAcc(t *testing.T) { 3526 test := func(t *testing.T, resolution int) { 3527 getClusterOpts := func(name string, i int) *Options { 3528 o := testMQTTDefaultOptions() 3529 o.ServerName = name 3530 o.Cluster.Name = "hub" 3531 // first two test cases rely on domain not being set in hub 3532 if resolution > 1 { 3533 o.JetStreamDomain = "DOMAIN" 3534 } 3535 o.Cluster.Host = "127.0.0.1" 3536 o.Cluster.Port = 2790 + i 3537 o.Routes = RoutesFromStr("nats://127.0.0.1:2791,nats://127.0.0.1:2792,nats://127.0.0.1:2793") 3538 o.LeafNode.Host = "127.0.0.1" 3539 o.LeafNode.Port = -1 3540 return o 3541 } 3542 o1 := getClusterOpts("S1", 1) 3543 s1 := testMQTTRunServer(t, o1) 3544 defer testMQTTShutdownServer(s1) 3545 3546 o2 := getClusterOpts("S2", 2) 3547 s2 := testMQTTRunServer(t, o2) 3548 defer testMQTTShutdownServer(s2) 3549 3550 o3 := getClusterOpts("S3", 3) 3551 s3 := testMQTTRunServer(t, o3) 3552 defer testMQTTShutdownServer(s3) 3553 3554 cluster := []*Server{s1, s2, s3} 3555 checkClusterFormed(t, cluster...) 3556 checkFor(t, 10*time.Second, 50*time.Millisecond, func() error { 3557 for _, s := range cluster { 3558 if s.JetStreamIsLeader() { 3559 // Need to wait for usage updates now to propagate to meta leader. 3560 if len(s.JetStreamClusterPeers()) == len(cluster) { 3561 time.Sleep(100 * time.Millisecond) 3562 return nil 3563 } 3564 } 3565 } 3566 return fmt.Errorf("no leader yet") 3567 }) 3568 3569 // Now define a leafnode that has mqtt enabled, but no JS. This should still work. 3570 lno := testMQTTDefaultOptions() 3571 // Make sure jetstream is not explicitly defined here. 3572 lno.JetStream = false 3573 switch resolution { 3574 case 0: 3575 // turn off jetstream in $G by adding another account and set mqtt domain option and set account default 3576 lno.Accounts = append(lno.Accounts, NewAccount("unused-account")) 3577 fallthrough 3578 case 1: 3579 lno.JsAccDefaultDomain = map[string]string{"$G": ""} 3580 case 2: 3581 lno.JsAccDefaultDomain = map[string]string{"$G": o1.JetStreamDomain} 3582 case 3: 3583 // turn off jetstream in $G by adding another account and set mqtt domain option 3584 lno.Accounts = append(lno.Accounts, NewAccount("unused-account")) 3585 fallthrough 3586 case 4: 3587 // actual solution 3588 lno.MQTT.JsDomain = o1.JetStreamDomain 3589 case 5: 3590 // set per account overwrite and disable js in $G 3591 lno.Accounts = append(lno.Accounts, NewAccount("unused-account")) 3592 lno.JsAccDefaultDomain = map[string]string{ 3593 "$G": o1.JetStreamDomain, 3594 } 3595 } 3596 // Whenever an account was added to disable JS in $G, enable it in the server 3597 if len(lno.Accounts) > 0 { 3598 lno.JetStream = true 3599 lno.JetStreamDomain = "OTHER" 3600 lno.StoreDir = t.TempDir() 3601 } 3602 3603 // Use RoutesFromStr() to make an array of urls 3604 urls := RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d,nats://127.0.0.1:%d,nats://127.0.0.1:%d", 3605 o1.LeafNode.Port, o2.LeafNode.Port, o3.LeafNode.Port)) 3606 lno.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: urls}} 3607 3608 ln := RunServer(lno) 3609 defer testMQTTShutdownServer(ln) 3610 3611 checkLeafNodeConnected(t, ln) 3612 3613 // Now connect to leafnode and subscribe 3614 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub", cleanSess: true}, lno.MQTT.Host, lno.MQTT.Port, 5) 3615 defer mc.Close() 3616 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 3617 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 3618 testMQTTFlush(t, mc, nil, rc) 3619 3620 connectAndPublish := func(o *Options) { 3621 mp, rp := testMQTTConnectRetry(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 3622 defer mp.Close() 3623 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 3624 3625 testMQTTPublish(t, mp, rp, 1, false, false, "foo", 1, []byte("msg")) 3626 } 3627 // Connect a publisher from leafnode and publish, verify message is received. 3628 connectAndPublish(lno) 3629 testMQTTCheckPubMsg(t, mc, rc, "foo", mqttPubQos1, []byte("msg")) 3630 3631 // Connect from one server in the cluster check it works from there too. 3632 connectAndPublish(o3) 3633 testMQTTCheckPubMsg(t, mc, rc, "foo", mqttPubQos1, []byte("msg")) 3634 3635 // Connect from a server in the hub and subscribe 3636 mc2, rc2 := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub2", cleanSess: true}, o2.MQTT.Host, o2.MQTT.Port, 5) 3637 defer mc2.Close() 3638 testMQTTCheckConnAck(t, rc2, mqttConnAckRCConnectionAccepted, false) 3639 testMQTTSub(t, 1, mc2, rc2, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 3640 testMQTTFlush(t, mc2, nil, rc2) 3641 3642 // Connect a publisher from leafnode and publish, verify message is received. 3643 connectAndPublish(lno) 3644 testMQTTCheckPubMsg(t, mc2, rc2, "foo", mqttPubQos1, []byte("msg")) 3645 3646 // Connect from one server in the cluster check it works from there too. 3647 connectAndPublish(o1) 3648 testMQTTCheckPubMsg(t, mc2, rc2, "foo", mqttPubQos1, []byte("msg")) 3649 } 3650 t.Run("backwards-compatibility-default-js-enabled-in-leaf", func(t *testing.T) { 3651 test(t, 0) // test with JsAccDefaultDomain set to default (pointing at hub) but jetstream enabled in leaf node too 3652 }) 3653 t.Run("backwards-compatibility-default-js-disabled-in-leaf", func(t *testing.T) { 3654 // test with JsAccDefaultDomain set. Checks if it works with backwards compatibility code for empty domain 3655 test(t, 1) 3656 }) 3657 t.Run("backwards-compatibility-domain-js-disabled-in-leaf", func(t *testing.T) { 3658 // test with JsAccDefaultDomain set. Checks if it works with backwards compatibility code for domain set 3659 test(t, 2) // test with domain set in mqtt client 3660 }) 3661 t.Run("mqtt-explicit-js-enabled-in-leaf", func(t *testing.T) { 3662 test(t, 3) // test with domain set in mqtt client (pointing at hub) but jetstream enabled in leaf node too 3663 }) 3664 t.Run("mqtt-explicit-js-disabled-in-leaf", func(t *testing.T) { 3665 test(t, 4) // test with domain set in mqtt client 3666 }) 3667 t.Run("backwards-compatibility-domain-js-enabled-in-leaf", func(t *testing.T) { 3668 test(t, 5) // test with JsAccDefaultDomain set to domain (pointing at hub) but jetstream enabled in leaf node too 3669 }) 3670 } 3671 3672 func TestMQTTImportExport(t *testing.T) { 3673 conf := createConfFile(t, []byte(fmt.Sprintf(` 3674 listen: "127.0.0.1:-1" 3675 server_name: "mqtt" 3676 jetstream { 3677 store_dir = %q 3678 } 3679 accounts { 3680 org { 3681 jetstream: enabled 3682 users: [{user: org, password: pwd}] 3683 imports = [{stream: {account: "device", subject: "foo"}, prefix: "org"}] 3684 } 3685 device { 3686 users: [{user: device, password: pwd}] 3687 exports = [{stream: "foo"}] 3688 } 3689 } 3690 mqtt { 3691 listen: "127.0.0.1:-1" 3692 } 3693 no_auth_user: device 3694 `, t.TempDir()))) 3695 defer os.Remove(conf) 3696 3697 s, o := RunServerWithConfig(conf) 3698 defer s.Shutdown() 3699 3700 mc1, rc1 := testMQTTConnect(t, &mqttConnInfo{clientID: "sub1", user: "org", pass: "pwd", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3701 defer mc1.Close() 3702 testMQTTCheckConnAck(t, rc1, mqttConnAckRCConnectionAccepted, false) 3703 testMQTTSub(t, 1, mc1, rc1, []*mqttFilter{{filter: "org/foo", qos: 0}}, []byte{0}) 3704 testMQTTFlush(t, mc1, nil, rc1) 3705 3706 mc2, rc2 := testMQTTConnect(t, &mqttConnInfo{clientID: "sub2", user: "org", pass: "pwd", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3707 defer mc2.Close() 3708 testMQTTCheckConnAck(t, rc2, mqttConnAckRCConnectionAccepted, false) 3709 testMQTTSub(t, 1, mc2, rc2, []*mqttFilter{{filter: "org/foo", qos: 1}}, []byte{1}) 3710 testMQTTFlush(t, mc2, nil, rc2) 3711 3712 nc := natsConnect(t, s.ClientURL()) 3713 defer nc.Close() 3714 natsPub(t, nc, "foo", []byte("msg")) 3715 3716 // Verify message is received on receiver side. 3717 testMQTTCheckPubMsg(t, mc1, rc1, "org/foo", 0, []byte("msg")) 3718 testMQTTCheckPubMsg(t, mc2, rc2, "org/foo", 0, []byte("msg")) 3719 } 3720 3721 func TestMQTTSessionMovingDomains(t *testing.T) { 3722 tmpl := strings.Replace(jsClusterTemplWithLeafAndMQTT, "{{leaf}}", `leafnodes { listen: 127.0.0.1:-1 }`, 1) 3723 tmpl = strings.Replace(tmpl, "store_dir:", "domain: HUB, store_dir:", 1) 3724 c := createJetStreamCluster(t, tmpl, "HUB", _EMPTY_, 3, 22020, true) 3725 defer c.shutdown() 3726 c.waitOnLeader() 3727 3728 tmpl = strings.Replace(jsClusterTemplWithLeafAndMQTT, "store_dir:", "domain: SPOKE, store_dir:", 1) 3729 lnc := c.createLeafNodesWithTemplateAndStartPort(tmpl, "SPOKE", 3, 22111) 3730 defer lnc.shutdown() 3731 lnc.waitOnPeerCount(3) 3732 3733 connectSubAndDisconnect := func(host string, port int, present bool) { 3734 t.Helper() 3735 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, host, port, 5) 3736 defer mc.Close() 3737 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, present) 3738 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 3739 testMQTTFlush(t, mc, nil, rc) 3740 testMQTTDisconnect(t, mc, nil) 3741 } 3742 3743 // Create a session on the HUB. Make sure we don't use "clean" session so that 3744 // it is not removed when the client connection closes. 3745 for i := 0; i < 7; i++ { 3746 var present bool 3747 if i > 0 { 3748 present = true 3749 } 3750 connectSubAndDisconnect(c.opts[0].MQTT.Host, c.opts[0].MQTT.Port, present) 3751 } 3752 3753 // Now move to the SPOKE cluster, this is a brand new session there, so should not be present. 3754 connectSubAndDisconnect(lnc.opts[1].MQTT.Host, lnc.opts[1].MQTT.Port, false) 3755 3756 // Move back to HUB cluster. Make it interesting by connecting to a different 3757 // server in that cluster. This should work, and present flag should be true. 3758 connectSubAndDisconnect(c.opts[2].MQTT.Host, c.opts[2].MQTT.Port, true) 3759 } 3760 3761 type remoteConnSameClientIDLogger struct { 3762 DummyLogger 3763 warn chan string 3764 } 3765 3766 func (l *remoteConnSameClientIDLogger) Warnf(format string, args ...interface{}) { 3767 msg := fmt.Sprintf(format, args...) 3768 if strings.Contains(msg, "remote connection has started with the same client ID") { 3769 l.warn <- msg 3770 } 3771 } 3772 3773 func TestMQTTSessionsDifferentDomains(t *testing.T) { 3774 tmpl := strings.Replace(jsClusterTemplWithLeafAndMQTT, "{{leaf}}", `leafnodes { listen: 127.0.0.1:-1 }`, 1) 3775 c := createJetStreamCluster(t, tmpl, "HUB", _EMPTY_, 3, 22020, true) 3776 defer c.shutdown() 3777 c.waitOnLeader() 3778 3779 tmpl = strings.Replace(jsClusterTemplWithLeafAndMQTT, "store_dir:", "domain: LEAF1, store_dir:", 1) 3780 lnc1 := c.createLeafNodesWithTemplateAndStartPort(tmpl, "LEAF1", 2, 22111) 3781 defer lnc1.shutdown() 3782 lnc1.waitOnPeerCount(2) 3783 3784 l := &remoteConnSameClientIDLogger{warn: make(chan string, 10)} 3785 lnc1.servers[0].SetLogger(l, false, false) 3786 3787 tmpl = strings.Replace(jsClusterTemplWithLeafAndMQTT, "store_dir:", "domain: LEAF2, store_dir:", 1) 3788 lnc2 := c.createLeafNodesWithTemplateAndStartPort(tmpl, "LEAF2", 2, 23111) 3789 defer lnc2.shutdown() 3790 lnc2.waitOnPeerCount(2) 3791 3792 o := &(lnc1.opts[0].MQTT) 3793 mc1, rc1 := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, o.Host, o.Port, 5) 3794 defer mc1.Close() 3795 testMQTTCheckConnAck(t, rc1, mqttConnAckRCConnectionAccepted, false) 3796 testMQTTSub(t, 1, mc1, rc1, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 3797 testMQTTFlush(t, mc1, nil, rc1) 3798 3799 o = &(lnc2.opts[0].MQTT) 3800 connectSubAndDisconnect := func(host string, port int, present bool) { 3801 t.Helper() 3802 mc, rc := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, host, port, 5) 3803 defer mc.Close() 3804 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, present) 3805 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 3806 testMQTTFlush(t, mc, nil, rc) 3807 testMQTTDisconnect(t, mc, nil) 3808 } 3809 3810 for i := 0; i < 2; i++ { 3811 connectSubAndDisconnect(o.Host, o.Port, i > 0) 3812 } 3813 3814 select { 3815 case w := <-l.warn: 3816 t.Fatalf("Got a warning: %v", w) 3817 case <-time.After(500 * time.Millisecond): 3818 // OK 3819 } 3820 } 3821 3822 func TestMQTTParseUnsub(t *testing.T) { 3823 for _, test := range []struct { 3824 name string 3825 proto []byte 3826 b byte 3827 pl int 3828 err string 3829 }{ 3830 {"reserved flag", nil, 3, 0, "wrong unsubscribe reserved flags"}, 3831 {"ensure packet loaded", []byte{1, 2}, mqttUnsubscribeFlags, 10, io.ErrUnexpectedEOF.Error()}, 3832 {"error reading packet id", []byte{1}, mqttUnsubscribeFlags, 1, "reading packet identifier"}, 3833 {"missing filters", []byte{0, 1}, mqttUnsubscribeFlags, 2, "subscribe protocol must contain at least 1 topic filter"}, 3834 {"error reading topic", []byte{0, 1, 0, 2, 'a'}, mqttUnsubscribeFlags, 5, "topic filter"}, 3835 {"empty topic", []byte{0, 1, 0, 0}, mqttUnsubscribeFlags, 4, errMQTTTopicFilterCannotBeEmpty.Error()}, 3836 {"invalid utf8 topic", []byte{0, 1, 0, 1, 241}, mqttUnsubscribeFlags, 5, "invalid utf8 for topic filter"}, 3837 } { 3838 t.Run(test.name, func(t *testing.T) { 3839 r := &mqttReader{} 3840 r.reset(test.proto) 3841 mqtt := &mqtt{r: r} 3842 c := &client{mqtt: mqtt} 3843 if _, _, err := c.mqttParseSubsOrUnsubs(r, test.b, test.pl, false); err == nil || !strings.Contains(err.Error(), test.err) { 3844 t.Fatalf("Expected error %q, got %v", test.err, err) 3845 } 3846 }) 3847 } 3848 } 3849 3850 func testMQTTUnsub(t *testing.T, pi uint16, c net.Conn, r *mqttReader, filters []*mqttFilter) { 3851 t.Helper() 3852 w := newMQTTWriter(0) 3853 pkLen := 2 // for pi 3854 for i := 0; i < len(filters); i++ { 3855 f := filters[i] 3856 pkLen += 2 + len(f.filter) 3857 } 3858 w.WriteByte(mqttPacketUnsub | mqttUnsubscribeFlags) 3859 w.WriteVarInt(pkLen) 3860 w.WriteUint16(pi) 3861 for i := 0; i < len(filters); i++ { 3862 f := filters[i] 3863 w.WriteBytes([]byte(f.filter)) 3864 } 3865 if _, err := testMQTTWrite(c, w.Bytes()); err != nil { 3866 t.Fatalf("Error writing UNSUBSCRIBE protocol: %v", err) 3867 } 3868 b, _ := testMQTTReadPacket(t, r) 3869 if pt := b & mqttPacketMask; pt != mqttPacketUnsubAck { 3870 t.Fatalf("Expected UNSUBACK packet %x, got %x", mqttPacketUnsubAck, pt) 3871 } 3872 rpi, err := r.readUint16("packet identifier") 3873 if err != nil || rpi != pi { 3874 t.Fatalf("Error with packet identifier expected=%v got: %v err=%v", pi, rpi, err) 3875 } 3876 } 3877 3878 func TestMQTTUnsub(t *testing.T) { 3879 o := testMQTTDefaultOptions() 3880 s := testMQTTRunServer(t, o) 3881 defer testMQTTShutdownServer(s) 3882 3883 mcp, mpr := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3884 defer mcp.Close() 3885 testMQTTCheckConnAck(t, mpr, mqttConnAckRCConnectionAccepted, false) 3886 3887 mc, r := testMQTTConnect(t, &mqttConnInfo{user: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3888 defer mc.Close() 3889 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 3890 3891 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo", qos: 0}}, []byte{0}) 3892 testMQTTFlush(t, mc, nil, r) 3893 3894 // Publish and test msg received 3895 testMQTTPublish(t, mcp, r, 0, false, false, "foo", 0, []byte("msg")) 3896 testMQTTCheckPubMsg(t, mc, r, "foo", 0, []byte("msg")) 3897 3898 // Unsubscribe 3899 testMQTTUnsub(t, 1, mc, r, []*mqttFilter{{filter: "foo"}}) 3900 3901 // Publish and test msg not received 3902 testMQTTPublish(t, mcp, r, 0, false, false, "foo", 0, []byte("msg")) 3903 testMQTTExpectNothing(t, r) 3904 3905 // Use of wildcards subs 3906 filters := []*mqttFilter{ 3907 {filter: "foo/bar", qos: 0}, 3908 {filter: "foo/#", qos: 0}, 3909 } 3910 testMQTTSub(t, 1, mc, r, filters, []byte{0, 0}) 3911 testMQTTFlush(t, mc, nil, r) 3912 3913 // Publish and check that message received twice 3914 testMQTTPublish(t, mcp, r, 0, false, false, "foo/bar", 0, []byte("msg")) 3915 testMQTTCheckPubMsg(t, mc, r, "foo/bar", 0, []byte("msg")) 3916 testMQTTCheckPubMsg(t, mc, r, "foo/bar", 0, []byte("msg")) 3917 3918 // Unsub the wildcard one 3919 testMQTTUnsub(t, 1, mc, r, []*mqttFilter{{filter: "foo/#"}}) 3920 // Publish and check that message received once 3921 testMQTTPublish(t, mcp, r, 0, false, false, "foo/bar", 0, []byte("msg")) 3922 testMQTTCheckPubMsg(t, mc, r, "foo/bar", 0, []byte("msg")) 3923 testMQTTExpectNothing(t, r) 3924 3925 // Unsub last 3926 testMQTTUnsub(t, 1, mc, r, []*mqttFilter{{filter: "foo/bar"}}) 3927 // Publish and test msg not received 3928 testMQTTPublish(t, mcp, r, 0, false, false, "foo/bar", 0, []byte("msg")) 3929 testMQTTExpectNothing(t, r) 3930 } 3931 3932 func testMQTTExpectDisconnect(t testing.TB, c net.Conn) { 3933 t.Helper() 3934 if buf, err := testMQTTRead(c); err == nil { 3935 t.Fatalf("Expected connection to be disconnected, got %s", buf) 3936 } 3937 } 3938 3939 func TestMQTTPublishTopicErrors(t *testing.T) { 3940 o := testMQTTDefaultOptions() 3941 s := testMQTTRunServer(t, o) 3942 defer testMQTTShutdownServer(s) 3943 3944 for _, test := range []struct { 3945 name string 3946 topic string 3947 }{ 3948 {"empty", ""}, 3949 {"with single level wildcard", "foo/+"}, 3950 {"with multiple level wildcard", "foo/#"}, 3951 } { 3952 t.Run(test.name, func(t *testing.T) { 3953 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 3954 defer mc.Close() 3955 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 3956 3957 testMQTTPublish(t, mc, r, 0, false, false, test.topic, 0, []byte("msg")) 3958 testMQTTExpectDisconnect(t, mc) 3959 }) 3960 } 3961 } 3962 3963 func testMQTTDisconnect(t testing.TB, c net.Conn, bw *bufio.Writer) { 3964 t.Helper() 3965 testMQTTDisconnectEx(t, c, bw, true) 3966 } 3967 3968 func testMQTTDisconnectEx(t testing.TB, c net.Conn, bw *bufio.Writer, wait bool) { 3969 t.Helper() 3970 w := newMQTTWriter(0) 3971 w.WriteByte(mqttPacketDisconnect) 3972 w.WriteByte(0) 3973 if bw != nil { 3974 bw.Write(w.Bytes()) 3975 bw.Flush() 3976 } else { 3977 c.Write(w.Bytes()) 3978 } 3979 if wait { 3980 testMQTTExpectDisconnect(t, c) 3981 } 3982 } 3983 3984 func TestMQTTWill(t *testing.T) { 3985 o := testMQTTDefaultOptions() 3986 s := testMQTTRunServer(t, o) 3987 defer testMQTTShutdownServer(s) 3988 3989 nc := natsConnect(t, s.ClientURL()) 3990 defer nc.Close() 3991 3992 sub := natsSubSync(t, nc, "will.topic") 3993 natsFlush(t, nc) 3994 3995 willMsg := []byte("bye") 3996 3997 for _, test := range []struct { 3998 name string 3999 willExpected bool 4000 willQoS byte 4001 }{ 4002 {"will qos 0", true, 0}, 4003 {"will qos 1", true, 1}, 4004 {"will qos 2", true, 2}, 4005 {"proper disconnect no will", false, 0}, 4006 } { 4007 t.Run(test.name, func(t *testing.T) { 4008 mcs, rs := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4009 defer mcs.Close() 4010 testMQTTCheckConnAck(t, rs, mqttConnAckRCConnectionAccepted, false) 4011 4012 testMQTTSub(t, 1, mcs, rs, []*mqttFilter{{filter: "will/#", qos: 2}}, []byte{2}) 4013 testMQTTFlush(t, mcs, nil, rs) 4014 4015 mc, r := testMQTTConnect(t, 4016 &mqttConnInfo{ 4017 cleanSess: true, 4018 will: &mqttWill{ 4019 topic: []byte("will/topic"), 4020 message: willMsg, 4021 qos: test.willQoS, 4022 }, 4023 }, o.MQTT.Host, o.MQTT.Port) 4024 defer mc.Close() 4025 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4026 4027 if test.willExpected { 4028 mc.Close() 4029 testMQTTCheckPubMsg(t, mcs, rs, "will/topic", test.willQoS<<1, willMsg) 4030 wm := natsNexMsg(t, sub, time.Second) 4031 if !bytes.Equal(wm.Data, willMsg) { 4032 t.Fatalf("Expected will message to be %q, got %q", willMsg, wm.Data) 4033 } 4034 } else { 4035 testMQTTDisconnect(t, mc, nil) 4036 testMQTTExpectNothing(t, rs) 4037 if wm, err := sub.NextMsg(100 * time.Millisecond); err == nil { 4038 t.Fatalf("Should not have receive a message, got subj=%q data=%q", 4039 wm.Subject, wm.Data) 4040 } 4041 } 4042 }) 4043 } 4044 } 4045 4046 func TestMQTTQoS2WillReject(t *testing.T) { 4047 o := testMQTTDefaultOptions() 4048 o.MQTT.rejectQoS2Pub = true 4049 s := testMQTTRunServer(t, o) 4050 defer testMQTTShutdownServer(s) 4051 4052 mcs, rs := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4053 defer mcs.Close() 4054 testMQTTCheckConnAck(t, rs, mqttConnAckRCConnectionAccepted, false) 4055 4056 testMQTTSub(t, 1, mcs, rs, []*mqttFilter{{filter: "will/#", qos: 2}}, []byte{2}) 4057 testMQTTFlush(t, mcs, nil, rs) 4058 4059 mc, r := testMQTTConnect(t, 4060 &mqttConnInfo{ 4061 cleanSess: true, 4062 will: &mqttWill{ 4063 topic: []byte("will/topic"), 4064 message: []byte("bye"), 4065 qos: 2, 4066 }, 4067 }, o.MQTT.Host, o.MQTT.Port) 4068 defer mc.Close() 4069 testMQTTCheckConnAck(t, r, mqttConnAckRCQoS2WillRejected, false) 4070 } 4071 4072 func TestMQTTWillRetain(t *testing.T) { 4073 for _, test := range []struct { 4074 name string 4075 pubQoS byte 4076 subQoS byte 4077 }{ 4078 {"pub QoS0 sub QoS0", 0, 0}, 4079 {"pub QoS0 sub QoS1", 0, 1}, 4080 {"pub QoS1 sub QoS0", 1, 0}, 4081 {"pub QoS1 sub QoS1", 1, 1}, 4082 } { 4083 t.Run(test.name, func(t *testing.T) { 4084 o := testMQTTDefaultOptions() 4085 s := testMQTTRunServer(t, o) 4086 defer testMQTTShutdownServer(s) 4087 4088 mces, res := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4089 defer mces.Close() 4090 testMQTTCheckConnAck(t, res, mqttConnAckRCConnectionAccepted, false) 4091 testMQTTSub(t, 1, mces, res, []*mqttFilter{{filter: "will/#", qos: test.subQoS}}, []byte{test.subQoS}) 4092 4093 willTopic := []byte("will/topic") 4094 willMsg := []byte("bye") 4095 4096 mc, r := testMQTTConnect(t, 4097 &mqttConnInfo{ 4098 cleanSess: true, 4099 will: &mqttWill{ 4100 topic: willTopic, 4101 message: willMsg, 4102 qos: test.pubQoS, 4103 retain: true, 4104 }, 4105 }, o.MQTT.Host, o.MQTT.Port) 4106 defer mc.Close() 4107 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4108 4109 // Disconnect the client 4110 mc.Close() 4111 4112 // Wait for the server to process the connection close, which will 4113 // cause the "will" message to be published (and retained). 4114 checkClientsCount(t, s, 1) 4115 4116 // Create subscription on will topic and expect will message. 4117 mcs, rs := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4118 defer mcs.Close() 4119 testMQTTCheckConnAck(t, rs, mqttConnAckRCConnectionAccepted, false) 4120 4121 testMQTTSub(t, 1, mcs, rs, []*mqttFilter{{filter: "will/#", qos: test.subQoS}}, []byte{test.subQoS}) 4122 pflags, _ := testMQTTGetPubMsg(t, mcs, rs, "will/topic", willMsg) 4123 if !mqttIsRetained(pflags) { 4124 t.Fatalf("expected retain flag to be set, it was not: %v", pflags) 4125 } 4126 // Expected QoS will be the lesser of the pub/sub QoS. 4127 expectedQoS := test.pubQoS 4128 if test.subQoS == 0 { 4129 expectedQoS = 0 4130 } 4131 if qos := mqttGetQoS(pflags); qos != expectedQoS { 4132 t.Fatalf("expected qos to be %v, got %v", expectedQoS, qos) 4133 } 4134 4135 // The existing subscription (prior to sending the will) should receive 4136 // the will but the retain flag should not be set. 4137 pflags, _ = testMQTTGetPubMsg(t, mces, res, "will/topic", willMsg) 4138 if mqttIsRetained(pflags) { 4139 t.Fatalf("expected retain flag to not be set, it was: %v", pflags) 4140 } 4141 // Expected QoS will be the lesser of the pub/sub QoS. 4142 if qos := mqttGetQoS(pflags); qos != expectedQoS { 4143 t.Fatalf("expected qos to be %v, got %v", expectedQoS, qos) 4144 } 4145 }) 4146 } 4147 } 4148 4149 func TestMQTTWillRetainPermViolation(t *testing.T) { 4150 template := ` 4151 port: -1 4152 jetstream { 4153 store_dir = %q 4154 } 4155 server_name: mqtt 4156 authorization { 4157 mqtt_perms = { 4158 publish = ["%s"] 4159 subscribe = ["foo", "bar", "$MQTT.sub.>"] 4160 } 4161 users = [ 4162 {user: mqtt, password: pass, permissions: $mqtt_perms} 4163 ] 4164 } 4165 mqtt { 4166 port: -1 4167 } 4168 ` 4169 tdir := t.TempDir() 4170 conf := createConfFile(t, []byte(fmt.Sprintf(template, tdir, "foo"))) 4171 4172 s, o := RunServerWithConfig(conf) 4173 defer testMQTTShutdownServer(s) 4174 4175 ci := &mqttConnInfo{ 4176 cleanSess: true, 4177 user: "mqtt", 4178 pass: "pass", 4179 } 4180 4181 // We create first a connection with the Will topic that the publisher 4182 // is allowed to publish to. 4183 ci.will = &mqttWill{ 4184 topic: []byte("foo"), 4185 message: []byte("bye"), 4186 qos: 1, 4187 retain: true, 4188 } 4189 mc, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4190 defer mc.Close() 4191 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4192 4193 // Disconnect, which will cause the Will to be sent with retain flag. 4194 mc.Close() 4195 4196 // Wait for the server to process the connection close, which will 4197 // cause the "will" message to be published (and retained). 4198 checkClientsCount(t, s, 0) 4199 4200 // Create a subscription on the Will subject and we should receive it. 4201 ci.will = nil 4202 mcs, rs := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4203 defer mcs.Close() 4204 testMQTTCheckConnAck(t, rs, mqttConnAckRCConnectionAccepted, false) 4205 4206 testMQTTSub(t, 1, mcs, rs, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4207 pflags, _ := testMQTTGetPubMsg(t, mcs, rs, "foo", []byte("bye")) 4208 if !mqttIsRetained(pflags) { 4209 t.Fatalf("expected retain flag to be set, it was not: %v", pflags) 4210 } 4211 if qos := mqttGetQoS(pflags); qos != 1 { 4212 t.Fatalf("expected qos to be 1, got %v", qos) 4213 } 4214 testMQTTDisconnect(t, mcs, nil) 4215 4216 // Now create another connection with a Will that client is not allowed to publish to. 4217 ci.will = &mqttWill{ 4218 topic: []byte("bar"), 4219 message: []byte("bye"), 4220 qos: 1, 4221 retain: true, 4222 } 4223 mc, r = testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4224 defer mc.Close() 4225 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4226 4227 // Disconnect, to cause Will to be produced, but in that case should not be stored 4228 // since user not allowed to publish on "bar". 4229 mc.Close() 4230 4231 // Wait for the server to process the connection close, which will 4232 // cause the "will" message to be published (and retained). 4233 checkClientsCount(t, s, 0) 4234 4235 // Create sub on "bar" which user is allowed to subscribe to. 4236 ci.will = nil 4237 mcs, rs = testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4238 defer mcs.Close() 4239 testMQTTCheckConnAck(t, rs, mqttConnAckRCConnectionAccepted, false) 4240 4241 testMQTTSub(t, 1, mcs, rs, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 4242 // No Will should be published since it should not have been stored in the first place. 4243 testMQTTExpectNothing(t, rs) 4244 testMQTTDisconnect(t, mcs, nil) 4245 4246 // Now remove permission to publish on "foo" and check that a new subscription 4247 // on "foo" is now not getting the will message because the original user no 4248 // longer has permission to do so. 4249 reloadUpdateConfig(t, s, conf, fmt.Sprintf(template, tdir, "baz")) 4250 4251 mcs, rs = testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4252 defer mcs.Close() 4253 testMQTTCheckConnAck(t, rs, mqttConnAckRCConnectionAccepted, false) 4254 4255 testMQTTSub(t, 1, mcs, rs, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4256 testMQTTExpectNothing(t, rs) 4257 testMQTTDisconnect(t, mcs, nil) 4258 } 4259 4260 func TestMQTTPublishRetain(t *testing.T) { 4261 o := testMQTTDefaultOptions() 4262 s := testMQTTRunServer(t, o) 4263 defer testMQTTShutdownServer(s) 4264 4265 buf := strings.Builder{} 4266 for i := 0; i < 128; i++ { // 128Kb 4267 for j := 0; j < 64; j++ { // 16 * 64 = 1Kb 4268 buf.Write([]byte("0123456789abcdef")) 4269 } 4270 } 4271 large := buf.String() 4272 4273 for _, test := range []struct { 4274 name string 4275 retained bool 4276 sentValue string 4277 expectedValue string 4278 subGetsIt bool 4279 }{ 4280 {"publish large retained", true, large, large, true}, 4281 {"publish retained", true, "retained", "retained", true}, 4282 {"publish not retained", false, "not retained", "retained", true}, 4283 {"remove retained", true, "", "", false}, 4284 } { 4285 t.Run(test.name, func(t *testing.T) { 4286 mc1, rs1 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4287 defer mc1.Close() 4288 testMQTTCheckConnAck(t, rs1, mqttConnAckRCConnectionAccepted, false) 4289 testMQTTPublish(t, mc1, rs1, 0, false, test.retained, "foo", 0, []byte(test.sentValue)) 4290 testMQTTFlush(t, mc1, nil, rs1) 4291 4292 mc2, rs2 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4293 defer mc2.Close() 4294 testMQTTCheckConnAck(t, rs2, mqttConnAckRCConnectionAccepted, false) 4295 4296 testMQTTSub(t, 1, mc2, rs2, []*mqttFilter{{filter: "foo/#", qos: 1}}, []byte{1}) 4297 4298 if test.subGetsIt { 4299 pflags, _ := testMQTTGetPubMsg(t, mc2, rs2, "foo", []byte(test.expectedValue)) 4300 if !mqttIsRetained(pflags) { 4301 t.Fatalf("retain flag should have been set, it was not: flags=%v", pflags) 4302 } 4303 } else { 4304 testMQTTExpectNothing(t, rs2) 4305 } 4306 4307 testMQTTDisconnect(t, mc1, nil) 4308 testMQTTDisconnect(t, mc2, nil) 4309 }) 4310 } 4311 } 4312 4313 func TestMQTTQoS2RetainedReject(t *testing.T) { 4314 // Start the server with QOS2 enabled, and submit retained messages with QoS 4315 // 1 and 2. 4316 o := testMQTTDefaultOptions() 4317 s := testMQTTRunServer(t, o) 4318 mc1, rs1 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4319 testMQTTCheckConnAck(t, rs1, mqttConnAckRCConnectionAccepted, false) 4320 testMQTTPublish(t, mc1, rs1, 2, false, true, "foo", 1, []byte("qos2 failed")) 4321 testMQTTPublish(t, mc1, rs1, 1, false, true, "bar", 2, []byte("qos1 retained")) 4322 testMQTTFlush(t, mc1, nil, rs1) 4323 testMQTTDisconnect(t, mc1, nil) 4324 mc1.Close() 4325 s.Shutdown() 4326 4327 // Restart the server with QOS2 disabled; we should be using the same 4328 // JetStream store, so the retained message should still be there. 4329 o.MQTT.rejectQoS2Pub = true 4330 s = testMQTTRunServer(t, o) 4331 defer testMQTTShutdownServer(s) 4332 4333 mc2, rs2 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4334 defer mc2.Close() 4335 testMQTTCheckConnAck(t, rs2, mqttConnAckRCConnectionAccepted, false) 4336 4337 testMQTTSub(t, 1, mc2, rs2, []*mqttFilter{{filter: "bar/#", qos: 2}}, []byte{2}) 4338 pflags, _ := testMQTTGetPubMsg(t, mc2, rs2, "bar", []byte("qos1 retained")) 4339 if !mqttIsRetained(pflags) { 4340 t.Fatalf("retain flag should have been set, it was not: flags=%v", pflags) 4341 } 4342 4343 testMQTTSub(t, 1, mc2, rs2, []*mqttFilter{{filter: "foo/#", qos: 2}}, []byte{2}) 4344 testMQTTExpectNothing(t, rs2) 4345 testMQTTDisconnect(t, mc2, nil) 4346 } 4347 4348 func TestMQTTRetainFlag(t *testing.T) { 4349 o := testMQTTDefaultOptions() 4350 s := testMQTTRunServer(t, o) 4351 defer testMQTTShutdownServer(s) 4352 4353 mc1, rs1 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4354 defer mc1.Close() 4355 testMQTTCheckConnAck(t, rs1, mqttConnAckRCConnectionAccepted, false) 4356 testMQTTPublish(t, mc1, rs1, 0, false, true, "foo/0", 0, []byte("flag set")) 4357 testMQTTPublish(t, mc1, rs1, 0, false, true, "foo/1", 0, []byte("flag set")) 4358 testMQTTFlush(t, mc1, nil, rs1) 4359 4360 mc2, rs2 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 4361 defer mc2.Close() 4362 testMQTTCheckConnAck(t, rs2, mqttConnAckRCConnectionAccepted, false) 4363 4364 testMQTTSub(t, 1, mc2, rs2, []*mqttFilter{{filter: "foo/0", qos: 0}}, []byte{0}) 4365 pflags, _ := testMQTTGetPubMsg(t, mc2, rs2, "foo/0", []byte("flag set")) 4366 if !mqttIsRetained(pflags) { 4367 t.Fatalf("retain flag should have been set, it was not: flags=%v", pflags) 4368 } 4369 4370 testMQTTSub(t, 1, mc2, rs2, []*mqttFilter{{filter: "foo/1", qos: 1}}, []byte{1}) 4371 pflags, _ = testMQTTGetPubMsg(t, mc2, rs2, "foo/1", []byte("flag set")) 4372 if !mqttIsRetained(pflags) { 4373 t.Fatalf("retain flag should have been set, it was not: flags=%v", pflags) 4374 } 4375 4376 // For existing subscriptions, RETAIN flag should not be set: [MQTT-3.3.1-9]. 4377 testMQTTPublish(t, mc1, rs1, 0, false, true, "foo/0", 0, []byte("flag not set")) 4378 testMQTTFlush(t, mc1, nil, rs1) 4379 4380 pflags, _ = testMQTTGetPubMsg(t, mc2, rs2, "foo/0", []byte("flag not set")) 4381 if mqttIsRetained(pflags) { 4382 t.Fatalf("retain flag should not have been set, it was: flags=%v", pflags) 4383 } 4384 4385 testMQTTPublish(t, mc1, rs1, 0, false, true, "foo/1", 0, []byte("flag not set")) 4386 testMQTTFlush(t, mc1, nil, rs1) 4387 4388 pflags, _ = testMQTTGetPubMsg(t, mc2, rs2, "foo/1", []byte("flag not set")) 4389 if mqttIsRetained(pflags) { 4390 t.Fatalf("retain flag should not have been set, it was: flags=%v", pflags) 4391 } 4392 } 4393 4394 func TestMQTTPublishRetainPermViolation(t *testing.T) { 4395 o := testMQTTDefaultOptions() 4396 o.Users = []*User{ 4397 { 4398 Username: "mqtt", 4399 Password: "pass", 4400 Permissions: &Permissions{ 4401 Publish: &SubjectPermission{Allow: []string{"foo"}}, 4402 Subscribe: &SubjectPermission{Allow: []string{"bar", "$MQTT.sub.>"}}, 4403 }, 4404 }, 4405 } 4406 s := testMQTTRunServer(t, o) 4407 defer testMQTTShutdownServer(s) 4408 4409 ci := &mqttConnInfo{ 4410 cleanSess: true, 4411 user: "mqtt", 4412 pass: "pass", 4413 } 4414 4415 mc1, rs1 := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4416 defer mc1.Close() 4417 testMQTTCheckConnAck(t, rs1, mqttConnAckRCConnectionAccepted, false) 4418 testMQTTPublish(t, mc1, rs1, 0, false, true, "bar", 0, []byte("retained")) 4419 testMQTTFlush(t, mc1, nil, rs1) 4420 4421 mc2, rs2 := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4422 defer mc2.Close() 4423 testMQTTCheckConnAck(t, rs2, mqttConnAckRCConnectionAccepted, false) 4424 4425 testMQTTSub(t, 1, mc2, rs2, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 4426 testMQTTExpectNothing(t, rs2) 4427 4428 testMQTTDisconnect(t, mc1, nil) 4429 testMQTTDisconnect(t, mc2, nil) 4430 } 4431 4432 func TestMQTTPublishViolation(t *testing.T) { 4433 o := testMQTTDefaultOptions() 4434 o.Users = []*User{ 4435 { 4436 Username: "mqtt", 4437 Password: "pass", 4438 Permissions: &Permissions{ 4439 Publish: &SubjectPermission{Allow: []string{"foo.bar"}}, 4440 Subscribe: &SubjectPermission{Allow: []string{"foo.*", "$MQTT.sub.>"}}, 4441 }, 4442 }, 4443 } 4444 s := testMQTTRunServer(t, o) 4445 defer testMQTTShutdownServer(s) 4446 4447 ci := &mqttConnInfo{ 4448 user: "mqtt", 4449 pass: "pass", 4450 } 4451 ci.clientID = "sub" 4452 mc, rc := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4453 defer mc.Close() 4454 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, false) 4455 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo/+", qos: 1}}, []byte{1}) 4456 testMQTTFlush(t, mc, nil, rc) 4457 4458 ci.clientID = "pub" 4459 ci.cleanSess = true 4460 mp, rp := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4461 defer mp.Close() 4462 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 4463 4464 // These should be received since publisher has the right to publish on foo.bar 4465 testMQTTPublish(t, mp, rp, 0, false, false, "foo/bar", 0, []byte("msg1")) 4466 testMQTTCheckPubMsg(t, mc, rc, "foo/bar", 0, []byte("msg1")) 4467 testMQTTPublish(t, mp, rp, 1, false, false, "foo/bar", 1, []byte("msg2")) 4468 testMQTTCheckPubMsg(t, mc, rc, "foo/bar", mqttPubQos1, []byte("msg2")) 4469 4470 // But these should not be cause pub has no permission to publish on foo.baz 4471 testMQTTPublish(t, mp, rp, 0, false, false, "foo/baz", 0, []byte("msg3")) 4472 testMQTTExpectNothing(t, rc) 4473 testMQTTPublish(t, mp, rp, 1, false, false, "foo/baz", 1, []byte("msg4")) 4474 testMQTTExpectNothing(t, rc) 4475 4476 // Disconnect publisher 4477 testMQTTDisconnect(t, mp, nil) 4478 mp.Close() 4479 // Disconnect subscriber and restart it to make sure that it does not receive msg3/msg4 4480 testMQTTDisconnect(t, mc, nil) 4481 mc.Close() 4482 4483 ci.cleanSess = false 4484 ci.clientID = "sub" 4485 mc, rc = testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4486 defer mc.Close() 4487 testMQTTCheckConnAck(t, rc, mqttConnAckRCConnectionAccepted, true) 4488 testMQTTSub(t, 1, mc, rc, []*mqttFilter{{filter: "foo/+", qos: 1}}, []byte{1}) 4489 testMQTTExpectNothing(t, rc) 4490 } 4491 4492 func TestMQTTCleanSession(t *testing.T) { 4493 o := testMQTTDefaultOptions() 4494 s := testMQTTRunServer(t, o) 4495 defer testMQTTShutdownServer(s) 4496 4497 ci := &mqttConnInfo{ 4498 clientID: "me", 4499 cleanSess: false, 4500 } 4501 c, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4502 defer c.Close() 4503 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4504 testMQTTDisconnect(t, c, nil) 4505 4506 c, r = testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4507 defer c.Close() 4508 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4509 testMQTTDisconnect(t, c, nil) 4510 4511 ci.cleanSess = true 4512 c, r = testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4513 defer c.Close() 4514 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4515 testMQTTDisconnect(t, c, nil) 4516 } 4517 4518 func TestMQTTDuplicateClientID(t *testing.T) { 4519 o := testMQTTDefaultOptions() 4520 s := testMQTTRunServer(t, o) 4521 defer testMQTTShutdownServer(s) 4522 4523 ci := &mqttConnInfo{ 4524 clientID: "me", 4525 cleanSess: false, 4526 } 4527 c1, r1 := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4528 defer c1.Close() 4529 testMQTTCheckConnAck(t, r1, mqttConnAckRCConnectionAccepted, false) 4530 4531 c2, r2 := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4532 defer c2.Close() 4533 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, true) 4534 4535 // The old client should be disconnected. 4536 testMQTTExpectDisconnect(t, c1) 4537 } 4538 4539 func TestMQTTPersistedSession(t *testing.T) { 4540 o := testMQTTDefaultOptions() 4541 s := testMQTTRunServer(t, o) 4542 defer testMQTTShutdownRestartedServer(&s) 4543 4544 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 4545 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 4546 4547 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4548 defer c.Close() 4549 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4550 4551 testMQTTSub(t, 1, c, r, 4552 []*mqttFilter{ 4553 {filter: "foo/#", qos: 1}, 4554 {filter: "bar", qos: 1}, 4555 {filter: "baz", qos: 0}, 4556 }, 4557 []byte{1, 1, 0}) 4558 testMQTTFlush(t, c, nil, r) 4559 4560 // Shutdown server, close connection and restart server. It should 4561 // have restored the session and consumers. 4562 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 4563 s.Shutdown() 4564 c.Close() 4565 4566 o.Port = -1 4567 o.MQTT.Port = -1 4568 o.StoreDir = dir 4569 s = testMQTTRunServer(t, o) 4570 // There is already the defer for shutdown at top of function 4571 4572 // Create a publisher that will send qos1 so we verify that messages 4573 // are stored for the persisted sessions. 4574 c, r = testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 4575 defer c.Close() 4576 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4577 4578 testMQTTPublish(t, c, r, 1, false, false, "foo/bar", 1, []byte("msg0")) 4579 testMQTTFlush(t, c, nil, r) 4580 testMQTTDisconnect(t, c, nil) 4581 c.Close() 4582 4583 // Recreate session 4584 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4585 defer c.Close() 4586 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4587 4588 // Since consumers have been recovered, messages should be received 4589 // (MQTT does not need client to recreate consumers for a recovered 4590 // session) 4591 4592 // Check that qos1 publish message is received. 4593 testMQTTCheckPubMsg(t, c, r, "foo/bar", mqttPubQos1, []byte("msg0")) 4594 4595 // Flush to prevent publishes to be done too soon since we are 4596 // receiving the CONNACK before the subscriptions are restored. 4597 testMQTTFlush(t, c, nil, r) 4598 4599 // Now publish some messages to all subscriptions. 4600 nc := natsConnect(t, s.ClientURL()) 4601 defer nc.Close() 4602 4603 natsPub(t, nc, "foo.bar", []byte("msg1")) 4604 testMQTTCheckPubMsg(t, c, r, "foo/bar", 0, []byte("msg1")) 4605 4606 natsPub(t, nc, "foo", []byte("msg2")) 4607 testMQTTCheckPubMsg(t, c, r, "foo", 0, []byte("msg2")) 4608 4609 natsPub(t, nc, "bar", []byte("msg3")) 4610 testMQTTCheckPubMsg(t, c, r, "bar", 0, []byte("msg3")) 4611 4612 natsPub(t, nc, "baz", []byte("msg4")) 4613 testMQTTCheckPubMsg(t, c, r, "baz", 0, []byte("msg4")) 4614 4615 // Now unsub "bar" and verify that message published on this topic 4616 // is not received. 4617 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "bar"}}) 4618 natsPub(t, nc, "bar", []byte("msg5")) 4619 testMQTTExpectNothing(t, r) 4620 4621 nc.Close() 4622 s.Shutdown() 4623 c.Close() 4624 4625 o.Port = -1 4626 o.MQTT.Port = -1 4627 o.StoreDir = dir 4628 s = testMQTTRunServer(t, o) 4629 // There is already the defer for shutdown at top of function 4630 4631 // Recreate a client 4632 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4633 defer c.Close() 4634 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4635 4636 nc = natsConnect(t, s.ClientURL()) 4637 defer nc.Close() 4638 4639 natsPub(t, nc, "foo.bar", []byte("msg6")) 4640 testMQTTCheckPubMsg(t, c, r, "foo/bar", 0, []byte("msg6")) 4641 4642 natsPub(t, nc, "foo", []byte("msg7")) 4643 testMQTTCheckPubMsg(t, c, r, "foo", 0, []byte("msg7")) 4644 4645 // Make sure that we did not recover bar. 4646 natsPub(t, nc, "bar", []byte("msg8")) 4647 testMQTTExpectNothing(t, r) 4648 4649 natsPub(t, nc, "baz", []byte("msg9")) 4650 testMQTTCheckPubMsg(t, c, r, "baz", 0, []byte("msg9")) 4651 4652 // Have the sub client send a subscription downgrading the qos1 subscription. 4653 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo/#", qos: 0}}, []byte{0}) 4654 testMQTTFlush(t, c, nil, r) 4655 4656 nc.Close() 4657 s.Shutdown() 4658 c.Close() 4659 4660 o.Port = -1 4661 o.MQTT.Port = -1 4662 o.StoreDir = dir 4663 s = testMQTTRunServer(t, o) 4664 // There is already the defer for shutdown at top of function 4665 4666 // Recreate the sub client 4667 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4668 defer c.Close() 4669 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4670 4671 // Publish as a qos1 4672 c2, r2 := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 4673 defer c2.Close() 4674 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 4675 testMQTTPublish(t, c2, r2, 1, false, false, "foo/bar", 1, []byte("msg10")) 4676 4677 // Verify that it is received as qos0 which is the qos of the subscription. 4678 testMQTTCheckPubMsg(t, c, r, "foo/bar", 0, []byte("msg10")) 4679 4680 testMQTTDisconnect(t, c, nil) 4681 c.Close() 4682 testMQTTDisconnect(t, c2, nil) 4683 c2.Close() 4684 4685 // Finally, recreate the sub with clean session and ensure that all is gone 4686 cisub.cleanSess = true 4687 for i := 0; i < 2; i++ { 4688 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4689 defer c.Close() 4690 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4691 4692 nc = natsConnect(t, s.ClientURL()) 4693 defer nc.Close() 4694 4695 natsPub(t, nc, "foo.bar", []byte("msg11")) 4696 testMQTTExpectNothing(t, r) 4697 4698 natsPub(t, nc, "foo", []byte("msg12")) 4699 testMQTTExpectNothing(t, r) 4700 4701 // Make sure that we did not recover bar. 4702 natsPub(t, nc, "bar", []byte("msg13")) 4703 testMQTTExpectNothing(t, r) 4704 4705 natsPub(t, nc, "baz", []byte("msg14")) 4706 testMQTTExpectNothing(t, r) 4707 4708 testMQTTDisconnect(t, c, nil) 4709 c.Close() 4710 nc.Close() 4711 4712 s.Shutdown() 4713 o.Port = -1 4714 o.MQTT.Port = -1 4715 o.StoreDir = dir 4716 s = testMQTTRunServer(t, o) 4717 // There is already the defer for shutdown at top of function 4718 } 4719 } 4720 4721 func TestMQTTRecoverSessionAndAddNewSub(t *testing.T) { 4722 o := testMQTTDefaultOptions() 4723 s := testMQTTRunServer(t, o) 4724 defer testMQTTShutdownRestartedServer(&s) 4725 4726 cisub := &mqttConnInfo{clientID: "sub1", cleanSess: false} 4727 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4728 defer c.Close() 4729 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4730 testMQTTDisconnect(t, c, nil) 4731 c.Close() 4732 4733 // Shutdown server, close connection and restart server. It should 4734 // have restored the session and consumers. 4735 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 4736 s.Shutdown() 4737 c.Close() 4738 4739 o.Port = -1 4740 o.MQTT.Port = -1 4741 o.StoreDir = dir 4742 s = testMQTTRunServer(t, o) 4743 // No need for defer since it is done top of function 4744 4745 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 4746 defer c.Close() 4747 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4748 // Now add sub and make sure it does not crash 4749 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4750 testMQTTFlush(t, c, nil, r) 4751 4752 // Now repeat with a new client but without server restart. 4753 cisub2 := &mqttConnInfo{clientID: "sub2", cleanSess: false} 4754 c2, r2 := testMQTTConnect(t, cisub2, o.MQTT.Host, o.MQTT.Port) 4755 defer c2.Close() 4756 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 4757 testMQTTDisconnect(t, c2, nil) 4758 c2.Close() 4759 4760 c2, r2 = testMQTTConnect(t, cisub2, o.MQTT.Host, o.MQTT.Port) 4761 defer c2.Close() 4762 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, true) 4763 testMQTTSub(t, 1, c2, r2, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 4764 testMQTTFlush(t, c2, nil, r2) 4765 } 4766 4767 func TestMQTTRecoverSessionWithSubAndClientResendSub(t *testing.T) { 4768 o := testMQTTDefaultOptions() 4769 s := testMQTTRunServer(t, o) 4770 defer testMQTTShutdownRestartedServer(&s) 4771 4772 cisub1 := &mqttConnInfo{clientID: "sub1", cleanSess: false} 4773 c, r := testMQTTConnect(t, cisub1, o.MQTT.Host, o.MQTT.Port) 4774 defer c.Close() 4775 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4776 4777 // Have a client send a SUBSCRIBE protocol for foo, QoS1 4778 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4779 testMQTTDisconnect(t, c, nil) 4780 c.Close() 4781 4782 // Restart the server now. 4783 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 4784 s.Shutdown() 4785 4786 o.Port = -1 4787 o.MQTT.Port = -1 4788 o.StoreDir = dir 4789 s = testMQTTRunServer(t, o) 4790 // No need for defer since it is done top of function 4791 4792 // Now restart the client. Since the client was created with cleanSess==false, 4793 // the server will have recorded the subscriptions for this client. 4794 c, r = testMQTTConnect(t, cisub1, o.MQTT.Host, o.MQTT.Port) 4795 defer c.Close() 4796 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4797 // At this point, the server has recreated the subscription on foo, QoS1. 4798 4799 // For applications that restart, it is possible (likely) that they 4800 // will resend their SUBSCRIBE protocols, so do so now: 4801 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4802 testMQTTFlush(t, c, nil, r) 4803 4804 checkNumSub := func(clientID string) { 4805 t.Helper() 4806 4807 // Find the MQTT client... 4808 mc := testMQTTGetClient(t, s, clientID) 4809 4810 // Check how many NATS subscriptions are registered. 4811 var fooSub int 4812 var otherSub int 4813 mc.mu.Lock() 4814 for _, sub := range mc.subs { 4815 switch string(sub.subject) { 4816 case "foo": 4817 fooSub++ 4818 default: 4819 otherSub++ 4820 } 4821 } 4822 mc.mu.Unlock() 4823 4824 // We should have 2 subscriptions, one on "foo", and one for the JS durable 4825 // consumer's delivery subject. 4826 if fooSub != 1 { 4827 t.Fatalf("Expected 1 sub on 'foo', got %v", fooSub) 4828 } 4829 if otherSub != 1 { 4830 t.Fatalf("Expected 1 subscription for JS durable, got %v", otherSub) 4831 } 4832 } 4833 checkNumSub("sub1") 4834 4835 c.Close() 4836 4837 // Now same but without the server restart in-between. 4838 cisub2 := &mqttConnInfo{clientID: "sub2", cleanSess: false} 4839 c, r = testMQTTConnect(t, cisub2, o.MQTT.Host, o.MQTT.Port) 4840 defer c.Close() 4841 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4842 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4843 testMQTTDisconnect(t, c, nil) 4844 c.Close() 4845 // Restart client 4846 c, r = testMQTTConnect(t, cisub2, o.MQTT.Host, o.MQTT.Port) 4847 defer c.Close() 4848 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 4849 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 4850 testMQTTFlush(t, c, nil, r) 4851 // Check client subs 4852 checkNumSub("sub2") 4853 } 4854 4855 func TestMQTTFlappingSession(t *testing.T) { 4856 mqttSessJailDur = 250 * time.Millisecond 4857 mqttFlapCleanItvl = 350 * time.Millisecond 4858 defer func() { 4859 mqttSessJailDur = mqttSessFlappingJailDur 4860 mqttFlapCleanItvl = mqttSessFlappingCleanupInterval 4861 }() 4862 4863 o := testMQTTDefaultOptions() 4864 s := testMQTTRunServer(t, o) 4865 defer testMQTTShutdownServer(s) 4866 4867 ci := &mqttConnInfo{clientID: "flapper", cleanSess: false} 4868 c, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4869 defer c.Close() 4870 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4871 4872 // Let's get a handle on the asm to check things later. 4873 cli := testMQTTGetClient(t, s, "flapper") 4874 asm := cli.mqtt.asm 4875 4876 // Start a new connection with the same clientID, which should replace 4877 // the old one and put it in the flappers map. 4878 c2, r2 := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4879 defer c2.Close() 4880 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, true) 4881 4882 // Should be disconnected... 4883 testMQTTExpectDisconnect(t, c) 4884 4885 // Now try to reconnect "c" and we should fail. We have to do this manually, 4886 // since we expect it to fail. 4887 addr := fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port) 4888 c, err := net.Dial("tcp", addr) 4889 if err != nil { 4890 t.Fatalf("Error creating mqtt connection: %v", err) 4891 } 4892 defer c.Close() 4893 proto := mqttCreateConnectProto(ci) 4894 if _, err := testMQTTWrite(c, proto); err != nil { 4895 t.Fatalf("Error writing protocols: %v", err) 4896 } 4897 // Misbehave and send a SUB protocol without waiting for the CONNACK 4898 w := newMQTTWriter(0) 4899 pkLen := 2 // for pi 4900 // Topic "foo" 4901 pkLen += 2 + 3 + 1 4902 w.WriteByte(mqttPacketSub | mqttSubscribeFlags) 4903 w.WriteVarInt(pkLen) 4904 w.WriteUint16(1) 4905 w.WriteBytes([]byte("foo")) 4906 w.WriteByte(1) 4907 if _, err := testMQTTWrite(c, w.Bytes()); err != nil { 4908 t.Fatalf("Error writing protocols: %v", err) 4909 } 4910 // Now read the CONNACK and we should have been disconnected. 4911 if _, err := testMQTTRead(c); err == nil { 4912 t.Fatal("Expected connection to fail") 4913 } 4914 4915 // This should be in the flappers map, but after 250ms should be cleared. 4916 for i := 0; i < 2; i++ { 4917 asm.mu.RLock() 4918 _, present := asm.flappers["flapper"] 4919 asm.mu.RUnlock() 4920 if i == 0 { 4921 if !present { 4922 t.Fatal("Did not find the client ID in the flappers map") 4923 } 4924 // Wait for more than the cleanup interval 4925 time.Sleep(mqttFlapCleanItvl + 100*time.Millisecond) 4926 } else if present { 4927 t.Fatal("The client ID should have been cleared from the map") 4928 } 4929 } 4930 } 4931 4932 func TestMQTTLockedSession(t *testing.T) { 4933 o := testMQTTDefaultOptions() 4934 s := testMQTTRunServer(t, o) 4935 defer testMQTTShutdownServer(s) 4936 4937 subClientID := "sub" 4938 ci := &mqttConnInfo{clientID: subClientID, cleanSess: false} 4939 c, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4940 defer c.Close() 4941 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 4942 4943 sm := &s.mqtt.sessmgr 4944 sm.mu.Lock() 4945 asm := sm.sessions[globalAccountName] 4946 sm.mu.Unlock() 4947 if asm == nil { 4948 t.Fatalf("account session manager not found") 4949 } 4950 4951 // It is possible, however unlikely, to have received CONNACK while 4952 // mqttProcessConnect is still running, and the session remains locked. Wait 4953 // for it to finish. 4954 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 4955 asm.mu.RLock() 4956 defer asm.mu.RUnlock() 4957 if _, stillLocked := asm.sessLocked[subClientID]; stillLocked { 4958 return fmt.Errorf("session still locked") 4959 } 4960 return nil 4961 }) 4962 4963 // Get the session for "sub" 4964 cli := testMQTTGetClient(t, s, subClientID) 4965 sess := cli.mqtt.sess 4966 4967 // Pretend that the session above is locked. 4968 if err := asm.lockSession(sess, cli); err != nil { 4969 t.Fatalf("Unable to lock session: %v", err) 4970 } 4971 defer asm.unlockSession(sess) 4972 4973 // Now try to connect another client that wants to use "sub". 4974 // We can't use testMQTTConnect() because it is going to fail. 4975 addr := fmt.Sprintf("%s:%d", o.MQTT.Host, o.MQTT.Port) 4976 c2, err := net.Dial("tcp", addr) 4977 if err != nil { 4978 t.Fatalf("Error creating mqtt connection: %v", err) 4979 } 4980 defer c2.Close() 4981 proto := mqttCreateConnectProto(ci) 4982 if _, err := testMQTTWrite(c2, proto); err != nil { 4983 t.Fatalf("Error writing connect: %v", err) 4984 } 4985 if _, err := testMQTTRead(c2); err == nil { 4986 t.Fatal("Expected connection to fail") 4987 } 4988 4989 // Now try again, but this time release the session while waiting 4990 // to connect and it should succeed. 4991 time.AfterFunc(250*time.Millisecond, func() { asm.unlockSession(sess) }) 4992 c3, r3 := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 4993 defer c3.Close() 4994 testMQTTCheckConnAck(t, r3, mqttConnAckRCConnectionAccepted, true) 4995 } 4996 4997 func TestMQTTPersistRetainedMsg(t *testing.T) { 4998 o := testMQTTDefaultOptions() 4999 s := testMQTTRunServer(t, o) 5000 defer testMQTTShutdownRestartedServer(&s) 5001 5002 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 5003 5004 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5005 c, r := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5006 defer c.Close() 5007 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5008 5009 testMQTTPublish(t, c, r, 1, false, true, "moo/foo", 1, []byte("foo1")) 5010 testMQTTPublish(t, c, r, 1, false, true, "moo/foo", 1, []byte("foo2")) 5011 testMQTTPublish(t, c, r, 1, false, true, "moo/bar", 1, []byte("bar1")) 5012 testMQTTPublish(t, c, r, 0, false, true, "moo/baz", 1, []byte("baz1")) 5013 // Remove bar 5014 testMQTTPublish(t, c, r, 1, false, true, "moo/bar", 1, nil) 5015 testMQTTFlush(t, c, nil, r) 5016 testMQTTDisconnect(t, c, nil) 5017 c.Close() 5018 5019 s.Shutdown() 5020 5021 o.Port = -1 5022 o.MQTT.Port = -1 5023 o.StoreDir = dir 5024 s = testMQTTRunServer(t, o) 5025 5026 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5027 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5028 defer c.Close() 5029 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5030 5031 t.Run("many subs one topic", func(t *testing.T) { 5032 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "moo/foo", qos: 1}}, []byte{1}) 5033 testMQTTCheckPubMsg(t, c, r, "moo/foo", mqttPubFlagRetain|mqttPubQos1, []byte("foo2")) 5034 5035 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "moo/baz", qos: 1}}, []byte{1}) 5036 testMQTTCheckPubMsg(t, c, r, "moo/baz", mqttPubFlagRetain, []byte("baz1")) 5037 5038 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "moo/bar", qos: 1}}, []byte{1}) 5039 testMQTTExpectNothing(t, r) 5040 }) 5041 5042 runSingleSubscribe := func(filters []*mqttFilter) func(t *testing.T) { 5043 return func(t *testing.T) { 5044 testMQTTSub(t, 1, c, r, filters, nil) 5045 5046 for i := 0; i < 2; i++ { 5047 flags, pi, topic, payload := testMQTTReadPubPacket(t, r) 5048 if (flags & mqttPubFlagRetain) == 0 { 5049 t.Fatalf("Expected flags to have retain set, got %v", flags) 5050 } 5051 if (flags & mqttPubFlagDup) != 0 { 5052 t.Fatalf("Expected flags to not have Dup set, got %v", flags) 5053 } 5054 var expQOS byte 5055 var expPayload []byte 5056 switch topic { 5057 case "moo/foo": 5058 expQOS = mqttPubQos1 5059 expPayload = []byte("foo2") 5060 testMQTTSendPIPacket(mqttPacketPubAck, t, c, pi) 5061 case "moo/baz": 5062 expQOS = 0 5063 expPayload = []byte("baz1") 5064 default: 5065 t.Fatalf("Unexpected topic: %v", topic) 5066 } 5067 if (flags & mqttPubFlagQoS) != expQOS { 5068 t.Fatalf("Expected flags to have QOS %x set, got %x", expQOS, flags) 5069 } 5070 if string(payload) != string(expPayload) { 5071 t.Fatalf("Expected payload to be %q, got %v", expPayload, string(payload)) 5072 } 5073 } 5074 testMQTTExpectNothing(t, r) 5075 } 5076 } 5077 5078 t.Run("one sub many topics", runSingleSubscribe([]*mqttFilter{ 5079 {filter: "moo/foo", qos: 1}, 5080 {filter: "moo/baz", qos: 1}, 5081 {filter: "moo/bar", qos: 1}, 5082 })) 5083 5084 t.Run("one sub wildcard plus", runSingleSubscribe([]*mqttFilter{ 5085 {filter: "moo/+", qos: 1}, 5086 })) 5087 5088 t.Run("one sub wildcard hash", runSingleSubscribe([]*mqttFilter{ 5089 {filter: "moo/#", qos: 1}, 5090 })) 5091 5092 testMQTTDisconnect(t, c, nil) 5093 c.Close() 5094 } 5095 5096 func TestMQTTRetainedMsgCleanup(t *testing.T) { 5097 mqttRetainedCacheTTL = 250 * time.Millisecond 5098 defer func() { mqttRetainedCacheTTL = mqttDefaultRetainedCacheTTL }() 5099 5100 o := testMQTTDefaultOptions() 5101 s := testMQTTRunServer(t, o) 5102 defer testMQTTShutdownServer(s) 5103 5104 ci := &mqttConnInfo{clientID: "cache", cleanSess: true} 5105 c, r := testMQTTConnect(t, ci, o.MQTT.Host, o.MQTT.Port) 5106 defer c.Close() 5107 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5108 5109 // Send a retained message. 5110 testMQTTPublish(t, c, r, 1, false, true, "foo", 1, []byte("msg")) 5111 testMQTTFlush(t, c, nil, r) 5112 5113 // Start a subscription. 5114 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5115 testMQTTCheckPubMsg(t, c, r, "foo", mqttPubQos1|mqttPubFlagRetain, []byte("msg")) 5116 5117 time.Sleep(2 * mqttRetainedCacheTTL) 5118 5119 // Make sure not in cache anymore 5120 cli := testMQTTGetClient(t, s, "cache") 5121 asm := cli.mqtt.asm 5122 if v, ok := asm.rmsCache.Load("foo"); ok { 5123 t.Fatalf("Should not be in cache, got %+v", v) 5124 } 5125 } 5126 5127 func TestMQTTConnAckFirstPacket(t *testing.T) { 5128 o := testMQTTDefaultOptions() 5129 o.NoLog, o.Debug, o.Trace = true, false, false 5130 s := RunServer(o) 5131 defer testMQTTShutdownServer(s) 5132 5133 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5134 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5135 defer c.Close() 5136 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5137 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 0}}, []byte{0}) 5138 testMQTTDisconnect(t, c, nil) 5139 c.Close() 5140 5141 nc := natsConnect(t, s.ClientURL()) 5142 defer nc.Close() 5143 5144 wg := sync.WaitGroup{} 5145 wg.Add(1) 5146 ch := make(chan struct{}, 1) 5147 ready := make(chan struct{}) 5148 go func() { 5149 defer wg.Done() 5150 5151 close(ready) 5152 for { 5153 nc.Publish("foo", []byte("msg")) 5154 select { 5155 case <-ch: 5156 return 5157 default: 5158 } 5159 } 5160 }() 5161 5162 <-ready 5163 for i := 0; i < 100; i++ { 5164 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5165 defer c.Close() 5166 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 5167 w := newMQTTWriter(0) 5168 w.WriteByte(mqttPacketDisconnect) 5169 w.WriteByte(0) 5170 c.Write(w.Bytes()) 5171 // Wait to be disconnected, we can't use testMQTTDisconnect() because 5172 // it would fail because we may still receive some NATS messages. 5173 var b [10]byte 5174 for { 5175 if _, err := c.Read(b[:]); err != nil { 5176 break 5177 } 5178 } 5179 c.Close() 5180 } 5181 close(ch) 5182 wg.Wait() 5183 } 5184 5185 func TestMQTTRedeliveryAckWait(t *testing.T) { 5186 o := testMQTTDefaultOptions() 5187 o.MQTT.AckWait = 250 * time.Millisecond 5188 s := testMQTTRunServer(t, o) 5189 defer testMQTTShutdownServer(s) 5190 5191 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5192 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5193 defer c.Close() 5194 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5195 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5196 5197 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5198 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5199 defer cp.Close() 5200 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5201 5202 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("foo1")) 5203 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 2, []byte("foo2")) 5204 testMQTTDisconnect(t, cp, nil) 5205 cp.Close() 5206 5207 for i := 0; i < 2; i++ { 5208 flags := mqttPubQos1 5209 if i > 0 { 5210 flags |= mqttPubFlagDup 5211 } 5212 pi1 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", flags, []byte("foo1")) 5213 pi2 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", flags, []byte("foo2")) 5214 5215 if pi1 != 1 || pi2 != 2 { 5216 t.Fatalf("Unexpected pi values: %v, %v", pi1, pi2) 5217 } 5218 } 5219 // Ack first message 5220 testMQTTSendPIPacket(mqttPacketPubAck, t, c, 1) 5221 // Redelivery should only be for second message now 5222 for i := 0; i < 2; i++ { 5223 flags := mqttPubQos1 | mqttPubFlagDup 5224 pi := testMQTTCheckPubMsgNoAck(t, c, r, "foo", flags, []byte("foo2")) 5225 if pi != 2 { 5226 t.Fatalf("Unexpected pi to be 2, got %v", pi) 5227 } 5228 } 5229 5230 // Restart client, should receive second message with pi==2 5231 c.Close() 5232 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5233 defer c.Close() 5234 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 5235 // Check that message is received with proper pi 5236 pi := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1|mqttPubFlagDup, []byte("foo2")) 5237 if pi != 2 { 5238 t.Fatalf("Unexpected pi to be 2, got %v", pi) 5239 } 5240 // Now ack second message 5241 testMQTTSendPIPacket(mqttPacketPubAck, t, c, 2) 5242 // Flush to make sure it is processed before checking client's maps 5243 testMQTTFlush(t, c, nil, r) 5244 5245 // Look for the sub client 5246 mc := testMQTTGetClient(t, s, "sub") 5247 mc.mu.Lock() 5248 sess := mc.mqtt.sess 5249 sess.mu.Lock() 5250 lpi := len(sess.pendingPublish) 5251 var lsseq int 5252 for _, sseqToPi := range sess.cpending { 5253 lsseq += len(sseqToPi) 5254 } 5255 sess.mu.Unlock() 5256 mc.mu.Unlock() 5257 if lpi != 0 || lsseq != 0 { 5258 t.Fatalf("Maps should be empty, got %v, %v", lpi, lsseq) 5259 } 5260 } 5261 5262 // - [MQTT-3.10.4-3] If a Server deletes a Subscription It MUST complete the 5263 // delivery of any QoS 1 or QoS 2 messages which it has started to send to the 5264 // Client. 5265 // 5266 // Test flow: 5267 // - Subscribe to foo, publish 3 QoS2 messages. 5268 // - After one is PUBCOMP-ed, and one is PUBREC-ed, Unsubscribe. 5269 // - See that the remaining 2 are fully delivered. 5270 func TestMQTTQoS2InflightMsgsDeliveredAfterUnsubscribe(t *testing.T) { 5271 // This test has proven flaky on Travis, so skip for now. Line 4926, the 3rd 5272 // testMQTTCheckPubMsgNoAck sometimes returns `data1`, instead of `data3` 5273 // that we are expecting. It must be a retry since we did not acknowledge 5274 // `data1` until later. 5275 t.Skip() 5276 5277 o := testMQTTDefaultOptions() 5278 o.MQTT.AckWait = 10 * time.Millisecond 5279 s := testMQTTRunServer(t, o) 5280 defer testMQTTShutdownServer(s) 5281 5282 var qos2 byte = 2 5283 cisub := &mqttConnInfo{clientID: "sub", cleanSess: true} 5284 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5285 defer c.Close() 5286 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5287 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: qos2}}, []byte{qos2}) 5288 5289 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5290 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5291 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5292 5293 // send 3 messages 5294 testMQTTPublish(t, cp, rp, qos2, false, false, "foo", 441, []byte("data1")) 5295 testMQTTPublish(t, cp, rp, qos2, false, false, "foo", 442, []byte("data2")) 5296 testMQTTPublish(t, cp, rp, qos2, false, false, "foo", 443, []byte("data3")) 5297 5298 testMQTTDisconnect(t, cp, nil) 5299 cp.Close() 5300 5301 subPI1 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data1")) 5302 subPI2 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data2")) 5303 // subPI3 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data3")) 5304 _ = testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data3")) 5305 5306 // fully receive first message 5307 testMQTTSendPIPacket(mqttPacketPubRec, t, c, subPI1) 5308 testMQTTReadPIPacket(mqttPacketPubRel, t, r, subPI1) 5309 testMQTTSendPIPacket(mqttPacketPubComp, t, c, subPI1) 5310 5311 // Do not PUBCOMP the 2nd message yet. 5312 testMQTTSendPIPacket(mqttPacketPubRec, t, c, subPI2) 5313 testMQTTReadPIPacket(mqttPacketPubRel, t, r, subPI2) 5314 5315 // Unsubscribe 5316 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: qos2}}) 5317 5318 // We expect that PI2 and PI3 will continue to be delivered, from their 5319 // respective states. 5320 gotPI2PubRel := false 5321 5322 // TODO: Currently, we do not get the unacknowledged PUBLISH re-delivered 5323 // after an UNSUBSCRIBE. Ongoing discussion if we should/must. 5324 // gotPI3Publish := false 5325 // gotPI3PubRel := false 5326 for !gotPI2PubRel /* || !gotPI3Publish || !gotPI3PubRel */ { 5327 b, _ /* len */ := testMQTTReadPacket(t, r) 5328 switch b & mqttPacketMask { 5329 case mqttPacketPubRel: 5330 pi, err := r.readUint16("packet identifier") 5331 if err != nil { 5332 t.Fatalf("got unexpected error: %v", err) 5333 } 5334 switch pi { 5335 case subPI2: 5336 testMQTTSendPIPacket(mqttPacketPubComp, t, c, pi) 5337 gotPI2PubRel = true 5338 // case subPI3: 5339 // testMQTTSendPIPacket(mqttPacketPubComp, t, c, pi) 5340 // gotPI3PubRel = true 5341 default: 5342 t.Fatalf("Expected PI %v got: %v", subPI2, pi) 5343 } 5344 5345 // case mqttPacketPub: 5346 // _, pi, _ := testMQTTGetPubMsgExEx(t, c, r, b, len, "foo", []byte("data3")) 5347 // if pi != subPI3 { 5348 // t.Fatalf("Expected PI %v got: %v", subPI3, pi) 5349 // } 5350 // gotPI3Publish = true 5351 // testMQTTSendPIPacket(mqttPacketPubRec, t, c, subPI3) 5352 5353 default: 5354 t.Fatalf("Unexpected packet type: %v", b&mqttPacketMask) 5355 } 5356 } 5357 5358 testMQTTExpectNothing(t, r) 5359 } 5360 5361 func TestMQTTQoS2RejectPublishDuplicates(t *testing.T) { 5362 o := testMQTTDefaultOptions() 5363 s := testMQTTRunServer(t, o) 5364 defer testMQTTShutdownServer(s) 5365 5366 var qos2 byte = 2 5367 cisub := &mqttConnInfo{clientID: "sub", cleanSess: true} 5368 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5369 defer c.Close() 5370 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5371 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: qos2}}, []byte{qos2}) 5372 5373 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5374 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5375 defer cp.Close() 5376 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5377 5378 // Publish 3 different with same PI before we get any PUBREC back, then 5379 // complete the PUBREL/PUBCOMP flow as needed. Only one message (first 5380 // payload) should be delivered. PUBRECs, 5381 var pubPI uint16 = 444 5382 testMQTTSendPublishPacket(t, cp, qos2, false, false, "foo", pubPI, []byte("data1")) 5383 testMQTTSendPublishPacket(t, cp, qos2, true, false, "foo", pubPI, []byte("data2")) 5384 testMQTTSendPublishPacket(t, cp, qos2, false, false, "foo", pubPI, []byte("data3")) 5385 5386 for i := 0; i < 3; i++ { 5387 // [MQTT-4.3.3-1] The receiver 5388 // 5389 // - MUST respond with a PUBREC containing the Packet Identifier from 5390 // the incoming PUBLISH Packet, having accepted ownership of the 5391 // Application Message. 5392 // 5393 // - Until it has received the corresponding PUBREL packet, the Receiver 5394 // MUST acknowledge any subsequent PUBLISH packet with the same Packet 5395 // Identifier by sending a PUBREC. It MUST NOT cause duplicate messages 5396 // to be delivered to any onward recipients in this case. 5397 testMQTTReadPIPacket(mqttPacketPubRec, t, rp, pubPI) 5398 } 5399 for i := 0; i < 3; i++ { 5400 testMQTTSendPIPacket(mqttPacketPubRel, t, cp, pubPI) 5401 } 5402 for i := 0; i < 3; i++ { 5403 // [MQTT-4.3.3-1] MUST respond to a PUBREL packet by sending a PUBCOMP 5404 // packet containing the same Packet Identifier as the PUBREL. 5405 testMQTTReadPIPacket(mqttPacketPubComp, t, rp, pubPI) 5406 } 5407 5408 // [MQTT-4.3.3-1] After it has sent a PUBCOMP, the receiver MUST treat any 5409 // subsequent PUBLISH packet that contains that Packet Identifier as being a 5410 // new publication. 5411 // 5412 // Publish another message, identical to the first one. Since the server 5413 // already sent us a PUBCOMP, it will deliver this message, for a total of 2 5414 // delivered. 5415 testMQTTPublish(t, cp, rp, qos2, false, false, "foo", pubPI, []byte("data5")) 5416 5417 testMQTTDisconnect(t, cp, nil) 5418 cp.Close() 5419 5420 // Verify we got a total of 2 messages. 5421 subPI1 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data1")) 5422 subPI2 := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data5")) 5423 for _, pi := range []uint16{subPI1, subPI2} { 5424 testMQTTSendPIPacket(mqttPacketPubRec, t, c, pi) 5425 testMQTTReadPIPacket(mqttPacketPubRel, t, r, pi) 5426 testMQTTSendPIPacket(mqttPacketPubComp, t, c, pi) 5427 } 5428 testMQTTExpectNothing(t, r) 5429 } 5430 5431 func TestMQTTQoS2RetriesPublish(t *testing.T) { 5432 o := testMQTTDefaultOptions() 5433 o.MQTT.AckWait = 100 * time.Millisecond 5434 s := testMQTTRunServer(t, o) 5435 defer testMQTTShutdownServer(s) 5436 5437 var qos2 byte = 2 5438 cisub := &mqttConnInfo{clientID: "sub", cleanSess: true} 5439 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5440 defer c.Close() 5441 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5442 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: qos2}}, []byte{qos2}) 5443 5444 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5445 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5446 defer cp.Close() 5447 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5448 5449 // Publish a message and close the pub connection. 5450 var pubPI uint16 = 444 5451 testMQTTPublish(t, cp, rp, qos2, false, false, "foo", pubPI, []byte("data1")) 5452 testMQTTDisconnect(t, cp, nil) 5453 cp.Close() 5454 5455 // See that we got the message delivered to the sub, but don't PUBREC it 5456 // yet. 5457 subPI := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data1")) 5458 5459 // See that the message is redelivered again 2 times, with the DUP on, before we PUBREC it. 5460 for i := 0; i < 2; i++ { 5461 expectedFlags := mqttPubQoS2 | mqttPubFlagDup 5462 pi := testMQTTCheckPubMsgNoAck(t, c, r, "foo", expectedFlags, []byte("data1")) 5463 if pi != subPI { 5464 t.Fatalf("Expected pi to be %v, got %v", subPI, pi) 5465 } 5466 } 5467 5468 // Finish the exchange and make sure there are no more attempts. 5469 testMQTTSendPIPacket(mqttPacketPubRec, t, c, subPI) 5470 testMQTTReadPIPacket(mqttPacketPubRel, t, r, subPI) 5471 testMQTTSendPIPacket(mqttPacketPubComp, t, c, subPI) 5472 testMQTTExpectNothing(t, r) 5473 } 5474 5475 func TestMQTTQoS2RetriesPubRel(t *testing.T) { 5476 o := testMQTTDefaultOptions() 5477 o.MQTT.AckWait = 50 * time.Millisecond 5478 s := testMQTTRunServer(t, o) 5479 defer testMQTTShutdownServer(s) 5480 5481 var qos2 byte = 2 5482 cisub := &mqttConnInfo{clientID: "sub", cleanSess: true} 5483 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5484 defer c.Close() 5485 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5486 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: qos2}}, []byte{qos2}) 5487 5488 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5489 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5490 defer cp.Close() 5491 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5492 5493 // Publish a message and close the pub connection. 5494 var pubPI uint16 = 444 5495 testMQTTPublish(t, cp, rp, qos2, false, false, "foo", pubPI, []byte("data1")) 5496 testMQTTDisconnect(t, cp, nil) 5497 cp.Close() 5498 5499 // See that we got the message delivered to the sub, PUBREC it and expect a 5500 // PUBREL from the server. 5501 subPI := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQoS2, []byte("data1")) 5502 testMQTTSendPIPacket(mqttPacketPubRec, t, c, subPI) 5503 5504 // See that we get PUBREL redelivered several times, there's no DUP flag to 5505 // check. 5506 testMQTTReadPIPacket(mqttPacketPubRel, t, r, subPI) 5507 testMQTTReadPIPacket(mqttPacketPubRel, t, r, subPI) 5508 testMQTTReadPIPacket(mqttPacketPubRel, t, r, subPI) 5509 5510 // Finish the exchange and make sure there are no more attempts. 5511 testMQTTSendPIPacket(mqttPacketPubComp, t, c, subPI) 5512 testMQTTExpectNothing(t, r) 5513 } 5514 5515 func TestMQTTAckWaitConfigChange(t *testing.T) { 5516 o := testMQTTDefaultOptions() 5517 o.MQTT.AckWait = 250 * time.Millisecond 5518 s := testMQTTRunServer(t, o) 5519 defer testMQTTShutdownRestartedServer(&s) 5520 5521 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 5522 5523 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5524 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5525 defer c.Close() 5526 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5527 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5528 5529 sendMsg := func(topic, payload string) { 5530 t.Helper() 5531 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5532 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5533 defer cp.Close() 5534 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5535 5536 testMQTTPublish(t, cp, rp, 1, false, false, topic, 1, []byte(payload)) 5537 testMQTTDisconnect(t, cp, nil) 5538 cp.Close() 5539 } 5540 sendMsg("foo", "msg1") 5541 5542 for i := 0; i < 2; i++ { 5543 flags := mqttPubQos1 5544 if i > 0 { 5545 flags |= mqttPubFlagDup 5546 } 5547 testMQTTCheckPubMsgNoAck(t, c, r, "foo", flags, []byte("msg1")) 5548 } 5549 5550 // Restart the server with a different AckWait option value. 5551 // Verify that MQTT sub restart succeeds. It will keep the 5552 // original value. 5553 c.Close() 5554 s.Shutdown() 5555 5556 o.Port = -1 5557 o.MQTT.Port = -1 5558 o.MQTT.AckWait = 10 * time.Millisecond 5559 o.StoreDir = dir 5560 s = testMQTTRunServer(t, o) 5561 // There is already the defer for shutdown at top of function 5562 5563 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5564 defer c.Close() 5565 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 5566 testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1|mqttPubFlagDup, []byte("msg1")) 5567 start := time.Now() 5568 testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1|mqttPubFlagDup, []byte("msg1")) 5569 if dur := time.Since(start); dur < 200*time.Millisecond { 5570 t.Fatalf("AckWait seem to have changed for existing subscription: %v", dur) 5571 } 5572 5573 // Create new subscription 5574 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 5575 sendMsg("bar", "msg2") 5576 testMQTTCheckPubMsgNoAck(t, c, r, "bar", mqttPubQos1, []byte("msg2")) 5577 start = time.Now() 5578 testMQTTCheckPubMsgNoAck(t, c, r, "bar", mqttPubQos1|mqttPubFlagDup, []byte("msg2")) 5579 if dur := time.Since(start); dur > 50*time.Millisecond { 5580 t.Fatalf("AckWait new value not used by new sub: %v", dur) 5581 } 5582 c.Close() 5583 } 5584 5585 func TestMQTTUnsubscribeWithPendingAcks(t *testing.T) { 5586 o := testMQTTDefaultOptions() 5587 o.MQTT.AckWait = 250 * time.Millisecond 5588 s := testMQTTRunServer(t, o) 5589 defer testMQTTShutdownServer(s) 5590 5591 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5592 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5593 defer c.Close() 5594 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5595 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5596 5597 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5598 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5599 defer cp.Close() 5600 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5601 5602 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg")) 5603 testMQTTDisconnect(t, cp, nil) 5604 cp.Close() 5605 5606 for i := 0; i < 2; i++ { 5607 flags := mqttPubQos1 5608 if i > 0 { 5609 flags |= mqttPubFlagDup 5610 } 5611 testMQTTCheckPubMsgNoAck(t, c, r, "foo", flags, []byte("msg")) 5612 } 5613 5614 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "foo"}}) 5615 testMQTTFlush(t, c, nil, r) 5616 5617 mc := testMQTTGetClient(t, s, "sub") 5618 mc.mu.Lock() 5619 sess := mc.mqtt.sess 5620 sess.mu.Lock() 5621 pal := len(sess.pendingPublish) 5622 sess.mu.Unlock() 5623 mc.mu.Unlock() 5624 if pal != 0 { 5625 t.Fatalf("Expected pending ack map to be empty, got %v", pal) 5626 } 5627 } 5628 5629 func TestMQTTMaxAckPending(t *testing.T) { 5630 o := testMQTTDefaultOptions() 5631 o.MQTT.MaxAckPending = 1 5632 s := testMQTTRunServer(t, o) 5633 defer testMQTTShutdownRestartedServer(&s) 5634 5635 nc, js := jsClientConnect(t, s) 5636 defer nc.Close() 5637 5638 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 5639 5640 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5641 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5642 defer c.Close() 5643 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5644 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5645 5646 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5647 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5648 defer cp.Close() 5649 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5650 5651 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg1")) 5652 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg2")) 5653 5654 pi := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1, []byte("msg1")) 5655 // Check that we don't receive the second one due to max ack pending 5656 testMQTTExpectNothing(t, r) 5657 5658 // Now ack first message 5659 testMQTTSendPIPacket(mqttPacketPubAck, t, c, pi) 5660 // Now we should receive message 2 5661 testMQTTCheckPubMsg(t, c, r, "foo", mqttPubQos1, []byte("msg2")) 5662 testMQTTDisconnect(t, c, nil) 5663 5664 // Give a chance to the server to "close" the consumer 5665 checkFor(t, 2*time.Second, 15*time.Millisecond, func() error { 5666 for ci := range js.ConsumersInfo("$MQTT_msgs") { 5667 if ci.PushBound { 5668 return fmt.Errorf("Consumer still connected") 5669 } 5670 } 5671 return nil 5672 }) 5673 5674 // Send 2 messages while sub is offline 5675 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg3")) 5676 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg4")) 5677 5678 // Restart consumer 5679 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5680 defer c.Close() 5681 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 5682 5683 // Should receive only message 3 5684 pi = testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1, []byte("msg3")) 5685 testMQTTExpectNothing(t, r) 5686 5687 // Ack and get the next 5688 testMQTTSendPIPacket(mqttPacketPubAck, t, c, pi) 5689 testMQTTCheckPubMsg(t, c, r, "foo", mqttPubQos1, []byte("msg4")) 5690 5691 // Make sure this message gets ack'ed 5692 mcli := testMQTTGetClient(t, s, cisub.clientID) 5693 checkFor(t, time.Second, 15*time.Millisecond, func() error { 5694 mcli.mu.Lock() 5695 sess := mcli.mqtt.sess 5696 sess.mu.Lock() 5697 np := len(sess.pendingPublish) 5698 sess.mu.Unlock() 5699 mcli.mu.Unlock() 5700 if np != 0 { 5701 return fmt.Errorf("Still %v pending messages", np) 5702 } 5703 return nil 5704 }) 5705 5706 // Check that change to config does not prevent restart of sub. 5707 cp.Close() 5708 c.Close() 5709 s.Shutdown() 5710 5711 o.Port = -1 5712 o.MQTT.Port = -1 5713 o.MQTT.MaxAckPending = 2 5714 o.StoreDir = dir 5715 s = testMQTTRunServer(t, o) 5716 // There is already the defer for shutdown at top of function 5717 5718 cp, rp = testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5719 defer cp.Close() 5720 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5721 5722 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg5")) 5723 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg6")) 5724 5725 // Restart consumer 5726 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5727 defer c.Close() 5728 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, true) 5729 5730 // Should receive only message 5 5731 pi = testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1, []byte("msg5")) 5732 testMQTTExpectNothing(t, r) 5733 5734 // Ack and get the next 5735 testMQTTSendPIPacket(mqttPacketPubAck, t, c, pi) 5736 testMQTTCheckPubMsg(t, c, r, "foo", mqttPubQos1, []byte("msg6")) 5737 } 5738 5739 func TestMQTTMaxAckPendingForMultipleSubs(t *testing.T) { 5740 o := testMQTTDefaultOptions() 5741 o.MQTT.AckWait = time.Second 5742 o.MQTT.MaxAckPending = 1 5743 s := testMQTTRunServer(t, o) 5744 defer testMQTTShutdownServer(s) 5745 5746 cisub := &mqttConnInfo{clientID: "sub", cleanSess: true} 5747 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5748 defer c.Close() 5749 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5750 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5751 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 5752 5753 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5754 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5755 defer cp.Close() 5756 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5757 5758 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg1")) 5759 pi := testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1, []byte("msg1")) 5760 5761 // Now send a second message but on topic bar 5762 testMQTTPublish(t, cp, rp, 1, false, false, "bar", 1, []byte("msg2")) 5763 5764 // JS allows us to limit per consumer, but we apply the limit to the 5765 // session, so although JS will attempt to delivery this message, 5766 // the MQTT code will suppress it. 5767 testMQTTExpectNothing(t, r) 5768 5769 // Ack the first message. 5770 testMQTTSendPIPacket(mqttPacketPubAck, t, c, pi) 5771 5772 // Now we should get the second message 5773 testMQTTCheckPubMsg(t, c, r, "bar", mqttPubQos1|mqttPubFlagDup, []byte("msg2")) 5774 } 5775 5776 func TestMQTTMaxAckPendingOverLimit(t *testing.T) { 5777 o := testMQTTDefaultOptions() 5778 o.MQTT.MaxAckPending = 20000 5779 s := testMQTTRunServer(t, o) 5780 defer testMQTTShutdownServer(s) 5781 5782 checkTMax := func(sess *mqttSession, expected int) { 5783 t.Helper() 5784 sess.mu.Lock() 5785 tmax := sess.tmaxack 5786 sess.mu.Unlock() 5787 if tmax != expected { 5788 t.Fatalf("Expected current tmax to be %v, got %v", expected, tmax) 5789 } 5790 } 5791 5792 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5793 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5794 defer c.Close() 5795 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5796 5797 mc := testMQTTGetClient(t, s, "sub") 5798 mc.mu.Lock() 5799 sess := mc.mqtt.sess 5800 mc.mu.Unlock() 5801 5802 // After this one, total would be 20000 5803 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5804 checkTMax(sess, 20000) 5805 // This one will count for 2, so total will be 60000 5806 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bar/#", qos: 1}}, []byte{1}) 5807 checkTMax(sess, 60000) 5808 5809 // This should fail 5810 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{mqttSubAckFailure}) 5811 checkTMax(sess, 60000) 5812 5813 // Remove the one with wildcard 5814 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "bar/#"}}) 5815 checkTMax(sess, 20000) 5816 5817 // Now we could add 2 more without wildcards 5818 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 5819 checkTMax(sess, 40000) 5820 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "baz", qos: 1}}, []byte{1}) 5821 checkTMax(sess, 60000) 5822 5823 // Again, this one should fail 5824 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bat", qos: 1}}, []byte{mqttSubAckFailure}) 5825 checkTMax(sess, 60000) 5826 5827 // Now remove all and check that we are at 0 5828 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "foo"}}) 5829 checkTMax(sess, 40000) 5830 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "bar"}}) 5831 checkTMax(sess, 20000) 5832 testMQTTUnsub(t, 1, c, r, []*mqttFilter{{filter: "baz"}}) 5833 checkTMax(sess, 0) 5834 } 5835 5836 func TestMQTTConfigReload(t *testing.T) { 5837 template := ` 5838 jetstream: true 5839 server_name: mqtt 5840 mqtt { 5841 port: -1 5842 ack_wait: %s 5843 max_ack_pending: %s 5844 } 5845 ` 5846 conf := createConfFile(t, []byte(fmt.Sprintf(template, `"5s"`, `10000`))) 5847 5848 s, o := RunServerWithConfig(conf) 5849 defer testMQTTShutdownServer(s) 5850 5851 if val := o.MQTT.AckWait; val != 5*time.Second { 5852 t.Fatalf("Invalid ackwait: %v", val) 5853 } 5854 if val := o.MQTT.MaxAckPending; val != 10000 { 5855 t.Fatalf("Invalid ackwait: %v", val) 5856 } 5857 5858 changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(template, `"250ms"`, `1`))) 5859 if err := s.Reload(); err != nil { 5860 t.Fatalf("Error on reload: %v", err) 5861 } 5862 5863 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5864 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5865 defer c.Close() 5866 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5867 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5868 5869 cipub := &mqttConnInfo{clientID: "pub", cleanSess: true} 5870 cp, rp := testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5871 defer cp.Close() 5872 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5873 5874 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg1")) 5875 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg2")) 5876 5877 testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1, []byte("msg1")) 5878 start := time.Now() 5879 testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1|mqttPubFlagDup, []byte("msg1")) 5880 if dur := time.Since(start); dur > 500*time.Millisecond { 5881 t.Fatalf("AckWait not applied? dur=%v", dur) 5882 } 5883 c.Close() 5884 cp.Close() 5885 testMQTTShutdownServer(s) 5886 5887 changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(template, `"30s"`, `1`))) 5888 s, o = RunServerWithConfig(conf) 5889 defer testMQTTShutdownServer(s) 5890 5891 cisub.cleanSess = true 5892 c, r = testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5893 defer c.Close() 5894 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5895 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 5896 5897 cipub = &mqttConnInfo{clientID: "pub", cleanSess: true} 5898 cp, rp = testMQTTConnect(t, cipub, o.MQTT.Host, o.MQTT.Port) 5899 defer cp.Close() 5900 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 5901 5902 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg1")) 5903 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg2")) 5904 5905 testMQTTCheckPubMsgNoAck(t, c, r, "foo", mqttPubQos1, []byte("msg1")) 5906 testMQTTExpectNothing(t, r) 5907 5908 // Increase the max ack pending 5909 changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(template, `"30s"`, `10`))) 5910 // Reload now 5911 if err := s.Reload(); err != nil { 5912 t.Fatalf("Error on reload: %v", err) 5913 } 5914 5915 // Reload will have effect only on new subscriptions. 5916 // Create a new subscription, and we should not be able to get the 2 messages. 5917 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 5918 5919 testMQTTPublish(t, cp, rp, 1, false, false, "bar", 1, []byte("msg3")) 5920 testMQTTPublish(t, cp, rp, 1, false, false, "bar", 1, []byte("msg4")) 5921 5922 testMQTTCheckPubMsg(t, c, r, "bar", mqttPubQos1, []byte("msg3")) 5923 testMQTTCheckPubMsg(t, c, r, "bar", mqttPubQos1, []byte("msg4")) 5924 } 5925 5926 func TestMQTTStreamInfoReturnsNonEmptySubject(t *testing.T) { 5927 o := testMQTTDefaultOptions() 5928 s := testMQTTRunServer(t, o) 5929 defer testMQTTShutdownServer(s) 5930 5931 cisub := &mqttConnInfo{clientID: "sub", cleanSess: false} 5932 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 5933 defer c.Close() 5934 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 5935 5936 nc := natsConnect(t, s.ClientURL()) 5937 defer nc.Close() 5938 5939 // Check that we can query all MQTT streams. MQTT streams are 5940 // created without subject filter, however, if we return them like this, 5941 // the 'nats' utility will fail to display them due to some xml validation. 5942 for _, sname := range []string{ 5943 mqttStreamName, 5944 mqttRetainedMsgsStreamName, 5945 } { 5946 t.Run(sname, func(t *testing.T) { 5947 resp, err := nc.Request(fmt.Sprintf(JSApiStreamInfoT, sname), nil, time.Second) 5948 if err != nil { 5949 t.Fatalf("Unexpected error: %v", err) 5950 } 5951 var bResp JSApiStreamInfoResponse 5952 if err = json.Unmarshal(resp.Data, &bResp); err != nil { 5953 t.Fatalf("Unexpected error: %v", err) 5954 } 5955 if len(bResp.Config.Subjects) == 0 { 5956 t.Fatalf("No subject returned, which will cause nats tooling to fail: %+v", bResp.Config) 5957 } 5958 }) 5959 } 5960 } 5961 5962 func TestMQTTWebsocketToMQTTPort(t *testing.T) { 5963 conf := createConfFile(t, []byte(fmt.Sprintf(` 5964 listen: "127.0.0.1:-1" 5965 http: "127.0.0.1:-1" 5966 server_name: "mqtt" 5967 jetstream { 5968 store_dir = %q 5969 } 5970 mqtt { 5971 listen: "127.0.0.1:-1" 5972 } 5973 websocket { 5974 listen: "127.0.0.1:-1" 5975 no_tls: true 5976 } 5977 `, t.TempDir()))) 5978 s, o := RunServerWithConfig(conf) 5979 defer testMQTTShutdownServer(s) 5980 5981 l := &captureErrorLogger{errCh: make(chan string, 10)} 5982 s.SetLogger(l, false, false) 5983 5984 ci := &mqttConnInfo{cleanSess: true, ws: true} 5985 if _, _, err := testMQTTConnectRetryWithError(t, ci, o.MQTT.Host, o.MQTT.Port, 0); err == nil { 5986 t.Fatal("Expected error during connect") 5987 } 5988 select { 5989 case e := <-l.errCh: 5990 if !strings.Contains(e, errMQTTNotWebsocketPort.Error()) { 5991 t.Fatalf("Unexpected error: %v", e) 5992 } 5993 case <-time.After(time.Second): 5994 t.Fatal("No error regarding wrong port") 5995 } 5996 } 5997 5998 func TestMQTTWebsocket(t *testing.T) { 5999 tdir := t.TempDir() 6000 template := ` 6001 listen: "127.0.0.1:-1" 6002 http: "127.0.0.1:-1" 6003 server_name: "mqtt" 6004 jetstream { 6005 store_dir = %q 6006 } 6007 accounts { 6008 MQTT { 6009 jetstream: enabled 6010 users [ 6011 {user: "mqtt", pass: "pwd", connection_types: ["%s"%s]} 6012 ] 6013 } 6014 } 6015 mqtt { 6016 listen: "127.0.0.1:-1" 6017 } 6018 websocket { 6019 listen: "127.0.0.1:-1" 6020 no_tls: true 6021 } 6022 ` 6023 s, o, conf := runReloadServerWithContent(t, []byte(fmt.Sprintf(template, tdir, jwt.ConnectionTypeMqtt, ""))) 6024 defer testMQTTShutdownServer(s) 6025 6026 cisub := &mqttConnInfo{clientID: "sub", user: "mqtt", pass: "pwd", ws: true} 6027 c, r := testMQTTConnect(t, cisub, o.Websocket.Host, o.Websocket.Port) 6028 defer c.Close() 6029 testMQTTCheckConnAck(t, r, mqttConnAckRCNotAuthorized, false) 6030 c.Close() 6031 6032 ws := fmt.Sprintf(`, "%s"`, jwt.ConnectionTypeMqttWS) 6033 reloadUpdateConfig(t, s, conf, fmt.Sprintf(template, tdir, jwt.ConnectionTypeMqtt, ws)) 6034 6035 cisub = &mqttConnInfo{clientID: "sub", user: "mqtt", pass: "pwd", ws: true} 6036 c, r = testMQTTConnect(t, cisub, o.Websocket.Host, o.Websocket.Port) 6037 defer c.Close() 6038 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6039 6040 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 6041 testMQTTFlush(t, c, nil, r) 6042 6043 cipub := &mqttConnInfo{clientID: "pub", user: "mqtt", pass: "pwd", ws: true} 6044 cp, rp := testMQTTConnect(t, cipub, o.Websocket.Host, o.Websocket.Port) 6045 defer cp.Close() 6046 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 6047 6048 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg1")) 6049 testMQTTCheckPubMsg(t, c, r, "foo", mqttPubQos1, []byte("msg1")) 6050 } 6051 6052 type chunkWriteConn struct { 6053 net.Conn 6054 } 6055 6056 func (cwc *chunkWriteConn) Write(p []byte) (int, error) { 6057 max := len(p) 6058 cs := rand.Intn(max) + 1 6059 if cs < max { 6060 if pn, perr := cwc.Conn.Write(p[:cs]); perr != nil { 6061 return pn, perr 6062 } 6063 time.Sleep(10 * time.Millisecond) 6064 if pn, perr := cwc.Conn.Write(p[cs:]); perr != nil { 6065 return pn, perr 6066 } 6067 return len(p), nil 6068 } 6069 return cwc.Conn.Write(p) 6070 } 6071 6072 func TestMQTTPartial(t *testing.T) { 6073 conf := createConfFile(t, []byte(fmt.Sprintf(` 6074 listen: "127.0.0.1:-1" 6075 http: "127.0.0.1:-1" 6076 server_name: "mqtt" 6077 jetstream { 6078 store_dir = %q 6079 } 6080 mqtt { 6081 listen: "127.0.0.1:-1" 6082 } 6083 websocket { 6084 listen: "127.0.0.1:-1" 6085 no_tls: true 6086 } 6087 `, t.TempDir()))) 6088 s, o := RunServerWithConfig(conf) 6089 defer testMQTTShutdownServer(s) 6090 6091 for _, test := range []struct { 6092 name string 6093 ws bool 6094 }{ 6095 {"standard", false}, 6096 {"websocket", true}, 6097 } { 6098 t.Run(test.name, func(t *testing.T) { 6099 ci := &mqttConnInfo{cleanSess: true, ws: test.ws} 6100 host, port := o.MQTT.Host, o.MQTT.Port 6101 if test.ws { 6102 host, port = o.Websocket.Host, o.Websocket.Port 6103 } 6104 c, r := testMQTTConnect(t, ci, host, port) 6105 defer c.Close() 6106 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6107 c = &chunkWriteConn{Conn: c} 6108 6109 cp, rp := testMQTTConnect(t, ci, host, port) 6110 defer cp.Close() 6111 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 6112 cp = &chunkWriteConn{Conn: cp} 6113 6114 subj := nuid.Next() 6115 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: subj, qos: 1}}, []byte{1}) 6116 testMQTTFlush(t, c, nil, r) 6117 for i := 0; i < 10; i++ { 6118 testMQTTPublish(t, cp, rp, 1, false, false, subj, 1, []byte("msg")) 6119 testMQTTCheckPubMsg(t, c, r, subj, mqttPubQos1, []byte("msg")) 6120 } 6121 }) 6122 } 6123 } 6124 6125 func TestMQTTWebsocketTLS(t *testing.T) { 6126 conf := createConfFile(t, []byte(fmt.Sprintf(` 6127 listen: "127.0.0.1:-1" 6128 http: "127.0.0.1:-1" 6129 server_name: "mqtt" 6130 jetstream { 6131 store_dir = %q 6132 } 6133 mqtt { 6134 listen: "127.0.0.1:-1" 6135 } 6136 websocket { 6137 listen: "127.0.0.1:-1" 6138 tls { 6139 cert_file: '../test/configs/certs/server-cert.pem' 6140 key_file: '../test/configs/certs/server-key.pem' 6141 ca_file: '../test/configs/certs/ca.pem' 6142 } 6143 } 6144 `, t.TempDir()))) 6145 s, o := RunServerWithConfig(conf) 6146 defer testMQTTShutdownServer(s) 6147 6148 c, r := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", ws: true, tls: true}, o.Websocket.Host, o.Websocket.Port) 6149 defer c.Close() 6150 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6151 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 6152 testMQTTFlush(t, c, nil, r) 6153 6154 cp, rp := testMQTTConnect(t, &mqttConnInfo{clientID: "pub", ws: true, tls: true}, o.Websocket.Host, o.Websocket.Port) 6155 defer cp.Close() 6156 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 6157 6158 testMQTTPublish(t, cp, rp, 1, false, false, "foo", 1, []byte("msg1")) 6159 testMQTTCheckPubMsg(t, c, r, "foo", mqttPubQos1, []byte("msg1")) 6160 } 6161 6162 func TestMQTTTransferSessionStreamsToMuxed(t *testing.T) { 6163 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", 3) 6164 defer cl.shutdown() 6165 6166 nc, js := jsClientConnect(t, cl.randomServer()) 6167 defer nc.Close() 6168 6169 // Create 2 streams that start with "$MQTT_sess_" to check for transfer to new 6170 // mux'ed unique "$MQTT_sess" stream. One of this stream will not contain a 6171 // proper session record, and we will check that the stream does not get deleted. 6172 sessStreamName1 := mqttSessionsStreamNamePrefix + getHash("sub") 6173 if _, err := js.AddStream(&nats.StreamConfig{ 6174 Name: sessStreamName1, 6175 Subjects: []string{sessStreamName1}, 6176 Replicas: 3, 6177 MaxMsgs: 1, 6178 }); err != nil { 6179 t.Fatalf("Unable to add stream: %v", err) 6180 } 6181 // Then add the session record 6182 ps := mqttPersistedSession{ 6183 ID: "sub", 6184 Subs: map[string]byte{"foo": 1}, 6185 Cons: map[string]*ConsumerConfig{"foo": { 6186 Durable: "d6INCtp3_cK39H5WHEtOSU7sLy2oQv3", 6187 DeliverSubject: "$MQTT.sub.cK39H5WHEtOSU7sLy2oQrR", 6188 DeliverPolicy: DeliverNew, 6189 AckPolicy: AckExplicit, 6190 FilterSubject: "$MQTT.msgs.foo", 6191 MaxAckPending: 1024, 6192 }}, 6193 } 6194 b, _ := json.Marshal(&ps) 6195 if _, err := js.Publish(sessStreamName1, b); err != nil { 6196 t.Fatalf("Error on publish: %v", err) 6197 } 6198 6199 // Create the stream that has "$MQTT_sess_" prefix, but that is not really a MQTT session stream 6200 sessStreamName2 := mqttSessionsStreamNamePrefix + "ivan" 6201 if _, err := js.AddStream(&nats.StreamConfig{ 6202 Name: sessStreamName2, 6203 Subjects: []string{sessStreamName2}, 6204 Replicas: 3, 6205 MaxMsgs: 1, 6206 }); err != nil { 6207 t.Fatalf("Unable to add stream: %v", err) 6208 } 6209 if _, err := js.Publish(sessStreamName2, []byte("some content")); err != nil { 6210 t.Fatalf("Error on publish: %v", err) 6211 } 6212 6213 cl.waitOnStreamLeader(globalAccountName, sessStreamName1) 6214 cl.waitOnStreamLeader(globalAccountName, sessStreamName2) 6215 6216 // Now create a real MQTT connection 6217 o := cl.opts[0] 6218 sc, sr := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub"}, o.MQTT.Host, o.MQTT.Port, 10) 6219 defer sc.Close() 6220 testMQTTCheckConnAck(t, sr, mqttConnAckRCConnectionAccepted, true) 6221 6222 // Check that old session stream is gone, but the non session stream is still present. 6223 var gotIt = false 6224 for info := range js.StreamsInfo() { 6225 if strings.HasPrefix(info.Config.Name, mqttSessionsStreamNamePrefix) { 6226 if strings.HasSuffix(info.Config.Name, "_ivan") { 6227 gotIt = true 6228 } else { 6229 t.Fatalf("The stream %q should have been deleted", info.Config.Name) 6230 } 6231 } 6232 } 6233 if !gotIt { 6234 t.Fatalf("The stream %q should not have been deleted", mqttSessionsStreamNamePrefix+"ivan") 6235 } 6236 6237 // We want to check that the record was properly transferred. 6238 rmsg, err := js.GetMsg(mqttSessStreamName, 2) 6239 if err != nil { 6240 t.Fatalf("Unable to get session message: %v", err) 6241 } 6242 ps2 := &mqttPersistedSession{} 6243 if err := json.Unmarshal(rmsg.Data, ps2); err != nil { 6244 t.Fatalf("Error unpacking session record: %v", err) 6245 } 6246 if ps2.ID != "sub" { 6247 t.Fatalf("Unexpected session record, %+v vs %+v", ps2, ps) 6248 } 6249 if qos, ok := ps2.Subs["foo"]; !ok || qos != 1 { 6250 t.Fatalf("Unexpected session record, %+v vs %+v", ps2, ps) 6251 } 6252 if cons, ok := ps2.Cons["foo"]; !ok || !reflect.DeepEqual(cons, ps.Cons["foo"]) { 6253 t.Fatalf("Unexpected session record, %+v vs %+v", ps2, ps) 6254 } 6255 6256 // Make sure we don't attempt to transfer again by creating a subscription 6257 // on the "stream names" API, which is used to get the list of streams to transfer 6258 sub := natsSubSync(t, nc, JSApiStreams) 6259 6260 // Make sure to connect an MQTT client from a different node so that this node 6261 // gets a connection for the account for the first time and tries to create 6262 // all MQTT streams, etc.. 6263 o = cl.opts[1] 6264 sc, sr = testMQTTConnectRetry(t, &mqttConnInfo{clientID: "sub2"}, o.MQTT.Host, o.MQTT.Port, 10) 6265 defer sc.Close() 6266 testMQTTCheckConnAck(t, sr, mqttConnAckRCConnectionAccepted, false) 6267 6268 if _, err := sub.NextMsg(200 * time.Millisecond); err == nil { 6269 t.Fatal("Looks like attempt to transfer was done again") 6270 } 6271 } 6272 6273 func TestMQTTConnectAndDisconnectEvent(t *testing.T) { 6274 conf := createConfFile(t, []byte(fmt.Sprintf(` 6275 listen: "127.0.0.1:-1" 6276 http: "127.0.0.1:-1" 6277 server_name: "mqtt" 6278 jetstream { 6279 store_dir = %q 6280 } 6281 accounts { 6282 MQTT { 6283 jetstream: enabled 6284 users: [{user: "mqtt", password: "pwd"}] 6285 } 6286 SYS { 6287 users: [{user: "sys", password: "pwd"}] 6288 } 6289 } 6290 mqtt { 6291 listen: "127.0.0.1:-1" 6292 } 6293 system_account: "SYS" 6294 `, t.TempDir()))) 6295 defer os.Remove(conf) 6296 s, o := RunServerWithConfig(conf) 6297 defer testMQTTShutdownServer(s) 6298 6299 nc := natsConnect(t, s.ClientURL(), nats.UserInfo("sys", "pwd")) 6300 defer nc.Close() 6301 6302 accConn := natsSubSync(t, nc, fmt.Sprintf(connectEventSubj, "MQTT")) 6303 accDisc := natsSubSync(t, nc, fmt.Sprintf(disconnectEventSubj, "MQTT")) 6304 accAuth := natsSubSync(t, nc, fmt.Sprintf(authErrorEventSubj, s.ID())) 6305 natsFlush(t, nc) 6306 6307 checkConnEvent := func(data []byte, expected string) { 6308 t.Helper() 6309 var ce ConnectEventMsg 6310 json.Unmarshal(data, &ce) 6311 if ce.Client.MQTTClient != expected { 6312 t.Fatalf("Expected client ID %q, got this connect event: %+v", expected, ce) 6313 } 6314 } 6315 checkDiscEvent := func(data []byte, expected string) { 6316 t.Helper() 6317 var de DisconnectEventMsg 6318 json.Unmarshal(data, &de) 6319 if de.Client.MQTTClient != expected { 6320 t.Fatalf("Expected client ID %q, got this disconnect event: %+v", expected, de) 6321 } 6322 } 6323 6324 c1, r1 := testMQTTConnect(t, &mqttConnInfo{user: "mqtt", pass: "pwd", clientID: "conn1", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 6325 defer c1.Close() 6326 testMQTTCheckConnAck(t, r1, mqttConnAckRCConnectionAccepted, false) 6327 6328 cm := natsNexMsg(t, accConn, time.Second) 6329 checkConnEvent(cm.Data, "conn1") 6330 6331 c2, r2 := testMQTTConnect(t, &mqttConnInfo{user: "mqtt", pass: "pwd", clientID: "conn2", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 6332 defer c2.Close() 6333 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 6334 6335 cm = natsNexMsg(t, accConn, time.Second) 6336 checkConnEvent(cm.Data, "conn2") 6337 6338 c3, r3 := testMQTTConnect(t, &mqttConnInfo{user: "mqtt", pass: "pwd", clientID: "conn3", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 6339 defer c3.Close() 6340 testMQTTCheckConnAck(t, r3, mqttConnAckRCConnectionAccepted, false) 6341 6342 cm = natsNexMsg(t, accConn, time.Second) 6343 checkConnEvent(cm.Data, "conn3") 6344 6345 testMQTTDisconnect(t, c3, nil) 6346 cm = natsNexMsg(t, accDisc, time.Second) 6347 checkDiscEvent(cm.Data, "conn3") 6348 6349 // Now try a bad auth 6350 c4, r4 := testMQTTConnect(t, &mqttConnInfo{clientID: "conn4", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 6351 defer c4.Close() 6352 testMQTTCheckConnAck(t, r4, mqttConnAckRCNotAuthorized, false) 6353 // This will generate an auth error, which is a disconnect event 6354 cm = natsNexMsg(t, accAuth, time.Second) 6355 checkDiscEvent(cm.Data, "conn4") 6356 6357 url := fmt.Sprintf("http://127.0.0.1:%d/", s.MonitorAddr().Port) 6358 for mode := 0; mode < 2; mode++ { 6359 c := pollConz(t, s, mode, url+"connz", nil) 6360 if c.Conns == nil || len(c.Conns) != 3 { 6361 t.Fatalf("Expected 3 connections in array, got %v", len(c.Conns)) 6362 } 6363 6364 // Check that client ID is present 6365 for _, conn := range c.Conns { 6366 if conn.Type == clientTypeStringMap[MQTT] && conn.MQTTClient == _EMPTY_ { 6367 t.Fatalf("Expected a client ID to be set, got %+v", conn) 6368 } 6369 } 6370 6371 // Check that we can select based on client ID: 6372 c = pollConz(t, s, mode, url+"connz?mqtt_client=conn2", &ConnzOptions{MQTTClient: "conn2"}) 6373 if c.Conns == nil || len(c.Conns) != 1 { 6374 t.Fatalf("Expected 1 connection in array, got %v", len(c.Conns)) 6375 } 6376 if c.Conns[0].MQTTClient != "conn2" { 6377 t.Fatalf("Unexpected client ID: %+v", c.Conns[0]) 6378 } 6379 6380 // Check that we have the closed ones 6381 c = pollConz(t, s, mode, url+"connz?state=closed", &ConnzOptions{State: ConnClosed}) 6382 if c.Conns == nil || len(c.Conns) != 2 { 6383 t.Fatalf("Expected 2 connections in array, got %v", len(c.Conns)) 6384 } 6385 for _, conn := range c.Conns { 6386 if conn.MQTTClient == _EMPTY_ { 6387 t.Fatalf("Expected a client ID, got %+v", conn) 6388 } 6389 } 6390 6391 // Check that we can select with client ID for closed state 6392 c = pollConz(t, s, mode, url+"connz?state=closed&mqtt_client=conn3", &ConnzOptions{State: ConnClosed, MQTTClient: "conn3"}) 6393 if c.Conns == nil || len(c.Conns) != 1 { 6394 t.Fatalf("Expected 1 connection in array, got %v", len(c.Conns)) 6395 } 6396 if c.Conns[0].MQTTClient != "conn3" { 6397 t.Fatalf("Unexpected client ID: %+v", c.Conns[0]) 6398 } 6399 // Check that we can select with client ID for closed state (but in this case not found) 6400 c = pollConz(t, s, mode, url+"connz?state=closed&mqtt_client=conn5", &ConnzOptions{State: ConnClosed, MQTTClient: "conn5"}) 6401 if len(c.Conns) != 0 { 6402 t.Fatalf("Expected 0 connection in array, got %v", len(c.Conns)) 6403 } 6404 } 6405 6406 reply := nc.NewRespInbox() 6407 replySub := natsSubSync(t, nc, reply) 6408 6409 // Test system events now 6410 for _, test := range []struct { 6411 opt interface{} 6412 cid string 6413 }{ 6414 {&ConnzOptions{MQTTClient: "conn1"}, "conn1"}, 6415 {&ConnzOptions{MQTTClient: "conn3", State: ConnClosed}, "conn3"}, 6416 {&ConnzOptions{MQTTClient: "conn4", State: ConnClosed}, "conn4"}, 6417 {&ConnzOptions{MQTTClient: "conn5"}, _EMPTY_}, 6418 {json.RawMessage(`{"mqtt_client":"conn1"}`), "conn1"}, 6419 {json.RawMessage(fmt.Sprintf(`{"mqtt_client":"conn3", "state":%v}`, ConnClosed)), "conn3"}, 6420 {json.RawMessage(fmt.Sprintf(`{"mqtt_client":"conn4", "state":%v}`, ConnClosed)), "conn4"}, 6421 {json.RawMessage(`{"mqtt_client":"conn5"}`), _EMPTY_}, 6422 } { 6423 t.Run("sys connz", func(t *testing.T) { 6424 b, _ := json.Marshal(test.opt) 6425 6426 // set a header to make sure request parsing knows to ignore them 6427 nc.PublishMsg(&nats.Msg{ 6428 Subject: fmt.Sprintf("%s.CONNZ", serverStatsPingReqSubj), 6429 Reply: reply, 6430 Data: b, 6431 }) 6432 6433 msg := natsNexMsg(t, replySub, time.Second) 6434 var response ServerAPIResponse 6435 if err := json.Unmarshal(msg.Data, &response); err != nil { 6436 t.Fatalf("Error unmarshalling response json: %v", err) 6437 } 6438 tmp, _ := json.Marshal(response.Data) 6439 cz := &Connz{} 6440 if err := json.Unmarshal(tmp, cz); err != nil { 6441 t.Fatalf("Error unmarshalling connz: %v", err) 6442 } 6443 if test.cid == _EMPTY_ { 6444 if len(cz.Conns) != 0 { 6445 t.Fatalf("Expected no connections, got %v", len(cz.Conns)) 6446 } 6447 return 6448 } 6449 if len(cz.Conns) != 1 { 6450 t.Fatalf("Expected single connection, got %v", len(cz.Conns)) 6451 } 6452 conn := cz.Conns[0] 6453 if conn.MQTTClient != test.cid { 6454 t.Fatalf("Expected client ID %q, got %q", test.cid, conn.MQTTClient) 6455 } 6456 }) 6457 } 6458 } 6459 6460 func TestMQTTClientIDInLogStatements(t *testing.T) { 6461 o := testMQTTDefaultOptions() 6462 s := testMQTTRunServer(t, o) 6463 defer testMQTTShutdownServer(s) 6464 6465 l := &captureDebugLogger{dbgCh: make(chan string, 10)} 6466 s.SetLogger(l, true, false) 6467 6468 cisub := &mqttConnInfo{clientID: "my_client_id", cleanSess: false} 6469 c, r := testMQTTConnect(t, cisub, o.MQTT.Host, o.MQTT.Port) 6470 defer c.Close() 6471 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6472 testMQTTDisconnect(t, c, nil) 6473 c.Close() 6474 6475 tm := time.NewTimer(2 * time.Second) 6476 var connected bool 6477 var disconnected bool 6478 for { 6479 select { 6480 case dl := <-l.dbgCh: 6481 if strings.Contains(dl, "my_client_id") { 6482 if strings.Contains(dl, "Client connected") { 6483 connected = true 6484 } else if strings.Contains(dl, "Client connection closed") { 6485 disconnected = true 6486 } 6487 if connected && disconnected { 6488 // OK! 6489 return 6490 } 6491 } 6492 case <-tm.C: 6493 t.Fatal("Did not get the debug statements or client_id in them") 6494 } 6495 } 6496 } 6497 6498 func TestMQTTStreamReplicasOverride(t *testing.T) { 6499 conf := ` 6500 listen: 127.0.0.1:-1 6501 server_name: %s 6502 jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'} 6503 6504 cluster { 6505 name: %s 6506 listen: 127.0.0.1:%d 6507 routes = [%s] 6508 } 6509 6510 mqtt { 6511 listen: 127.0.0.1:-1 6512 stream_replicas: 3 6513 } 6514 6515 # For access to system account. 6516 accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } } 6517 ` 6518 cl := createJetStreamClusterWithTemplate(t, conf, "MQTT", 3) 6519 defer cl.shutdown() 6520 6521 connectAndCheck := func(restarted bool) { 6522 t.Helper() 6523 6524 o := cl.opts[0] 6525 mc, r := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: false}, o.MQTT.Host, o.MQTT.Port, 5) 6526 defer mc.Close() 6527 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, restarted) 6528 6529 nc, js := jsClientConnect(t, cl.servers[2]) 6530 defer nc.Close() 6531 6532 streams := []string{mqttStreamName, mqttRetainedMsgsStreamName, mqttSessStreamName} 6533 for _, sn := range streams { 6534 si, err := js.StreamInfo(sn) 6535 require_NoError(t, err) 6536 if n := len(si.Cluster.Replicas); n != 2 { 6537 t.Fatalf("Expected stream %q to have 2 replicas, got %v", sn, n) 6538 } 6539 } 6540 } 6541 connectAndCheck(false) 6542 6543 cl.stopAll() 6544 for _, o := range cl.opts { 6545 o.MQTT.StreamReplicas = 2 6546 } 6547 cl.restartAllSamePorts() 6548 cl.waitOnStreamLeader(globalAccountName, mqttStreamName) 6549 cl.waitOnStreamLeader(globalAccountName, mqttRetainedMsgsStreamName) 6550 cl.waitOnStreamLeader(globalAccountName, mqttSessStreamName) 6551 6552 l := &captureWarnLogger{warn: make(chan string, 10)} 6553 cl.servers[0].SetLogger(l, false, false) 6554 6555 connectAndCheck(true) 6556 6557 select { 6558 case w := <-l.warn: 6559 if !strings.Contains(w, "current is 3 but configuration is 2") { 6560 t.Fatalf("Unexpected warning: %q", w) 6561 } 6562 case <-time.After(2 * time.Second): 6563 t.Fatal("Should have warned against replicas mismatch") 6564 } 6565 } 6566 6567 func TestMQTTStreamReplicasConfigReload(t *testing.T) { 6568 tdir := t.TempDir() 6569 tmpl := ` 6570 jetstream { 6571 store_dir = %q 6572 } 6573 server_name: mqtt 6574 mqtt { 6575 port: -1 6576 stream_replicas: %v 6577 } 6578 ` 6579 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, tdir, 3))) 6580 s, o := RunServerWithConfig(conf) 6581 defer testMQTTShutdownServer(s) 6582 6583 l := &captureErrorLogger{errCh: make(chan string, 10)} 6584 s.SetLogger(l, false, false) 6585 6586 _, _, err := testMQTTConnectRetryWithError(t, &mqttConnInfo{clientID: "mqtt", cleanSess: false}, o.MQTT.Host, o.MQTT.Port, 0) 6587 if err == nil { 6588 t.Fatal("Expected to fail, did not") 6589 } 6590 6591 select { 6592 case e := <-l.errCh: 6593 if !strings.Contains(e, NewJSStreamReplicasNotSupportedError().Description) { 6594 t.Fatalf("Expected error regarding replicas, got %v", e) 6595 } 6596 case <-time.After(2 * time.Second): 6597 t.Fatalf("Did not get the error regarding replicas count") 6598 } 6599 6600 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, tdir, 1)) 6601 6602 mc, r := testMQTTConnect(t, &mqttConnInfo{clientID: "mqtt", cleanSess: false}, o.MQTT.Host, o.MQTT.Port) 6603 defer mc.Close() 6604 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6605 } 6606 6607 func TestMQTTStreamReplicasInsufficientResources(t *testing.T) { 6608 conf := ` 6609 listen: 127.0.0.1:-1 6610 server_name: %s 6611 jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'} 6612 6613 cluster { 6614 name: %s 6615 listen: 127.0.0.1:%d 6616 routes = [%s] 6617 } 6618 6619 mqtt { 6620 listen: 127.0.0.1:-1 6621 stream_replicas: 5 6622 } 6623 6624 # For access to system account. 6625 accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } } 6626 ` 6627 cl := createJetStreamClusterWithTemplate(t, conf, "MQTT", 3) 6628 defer cl.shutdown() 6629 6630 l := &captureErrorLogger{errCh: make(chan string, 10)} 6631 for _, s := range cl.servers { 6632 s.SetLogger(l, false, false) 6633 } 6634 6635 o := cl.opts[1] 6636 _, _, err := testMQTTConnectRetryWithError(t, &mqttConnInfo{clientID: "mqtt", cleanSess: false}, o.MQTT.Host, o.MQTT.Port, 0) 6637 if err == nil { 6638 t.Fatal("Expected to fail, did not") 6639 } 6640 6641 select { 6642 case e := <-l.errCh: 6643 if !strings.Contains(e, fmt.Sprintf("%d", NewJSClusterNoPeersError(errors.New("")).ErrCode)) { 6644 t.Fatalf("Expected error regarding no peers error, got %v", e) 6645 } 6646 case <-time.After(2 * time.Second): 6647 t.Fatalf("Did not get the error regarding replicas count") 6648 } 6649 } 6650 6651 func TestMQTTConsumerReplicasValidate(t *testing.T) { 6652 o := testMQTTDefaultOptions() 6653 for _, test := range []struct { 6654 name string 6655 sr int 6656 cr int 6657 err bool 6658 }{ 6659 {"stream replicas neg", -1, 3, false}, 6660 {"stream replicas 0", 0, 3, false}, 6661 {"consumer replicas neg", 0, -1, false}, 6662 {"consumer replicas 0", -1, 0, false}, 6663 {"consumer replicas too high", 1, 2, true}, 6664 } { 6665 t.Run(test.name, func(t *testing.T) { 6666 o.MQTT.StreamReplicas = test.sr 6667 o.MQTT.ConsumerReplicas = test.cr 6668 err := validateMQTTOptions(o) 6669 if test.err { 6670 if err == nil { 6671 t.Fatal("Expected error, did not get one") 6672 } 6673 if !strings.Contains(err.Error(), "cannot be higher") { 6674 t.Fatalf("Unexpected error: %v", err) 6675 } 6676 // OK 6677 return 6678 } else if err != nil { 6679 t.Fatalf("Unexpected error: %v", err) 6680 } 6681 }) 6682 } 6683 } 6684 6685 // This was ill-advised since the messages stream is currently interest policy. 6686 // Interest policy streams require consumers match the replica count. 6687 // Will leave her for now to make sure we do not override. 6688 func TestMQTTConsumerReplicasOverride(t *testing.T) { 6689 conf := ` 6690 listen: 127.0.0.1:-1 6691 server_name: %s 6692 jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'} 6693 6694 cluster { 6695 name: %s 6696 listen: 127.0.0.1:%d 6697 routes = [%s] 6698 } 6699 6700 mqtt { 6701 listen: 127.0.0.1:-1 6702 stream_replicas: 5 6703 consumer_replicas: 1 6704 consumer_memory_storage: true 6705 } 6706 6707 # For access to system account. 6708 accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } } 6709 ` 6710 cl := createJetStreamClusterWithTemplate(t, conf, "MQTT", 5) 6711 defer cl.shutdown() 6712 6713 connectAndCheck := func(subject string, restarted bool) { 6714 t.Helper() 6715 6716 o := cl.opts[0] 6717 mc, r := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: false}, o.MQTT.Host, o.MQTT.Port, 5) 6718 defer mc.Close() 6719 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, restarted) 6720 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: subject, qos: 1}}, []byte{1}) 6721 6722 nc, js := jsClientConnect(t, cl.servers[2]) 6723 defer nc.Close() 6724 6725 for ci := range js.ConsumersInfo(mqttStreamName) { 6726 if ci.Config.FilterSubject == mqttStreamSubjectPrefix+subject { 6727 if rf := len(ci.Cluster.Replicas) + 1; rf != 5 { 6728 t.Fatalf("Expected consumer to be R5, got: %d", rf) 6729 } 6730 } 6731 } 6732 } 6733 connectAndCheck("foo", false) 6734 6735 cl.stopAll() 6736 for _, o := range cl.opts { 6737 o.MQTT.ConsumerReplicas = 2 6738 o.MQTT.ConsumerMemoryStorage = false 6739 } 6740 cl.restartAllSamePorts() 6741 cl.waitOnStreamLeader(globalAccountName, mqttStreamName) 6742 cl.waitOnStreamLeader(globalAccountName, mqttRetainedMsgsStreamName) 6743 cl.waitOnStreamLeader(globalAccountName, mqttSessStreamName) 6744 6745 connectAndCheck("bar", true) 6746 } 6747 6748 func TestMQTTConsumerMemStorageReload(t *testing.T) { 6749 tdir := t.TempDir() 6750 tmpl := ` 6751 jetstream { 6752 store_dir = %q 6753 } 6754 server_name: mqtt 6755 mqtt { 6756 port: -1 6757 consumer_memory_storage: %s 6758 } 6759 ` 6760 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, tdir, "false"))) 6761 s, o := RunServerWithConfig(conf) 6762 defer testMQTTShutdownServer(s) 6763 6764 l := &captureErrorLogger{errCh: make(chan string, 10)} 6765 s.SetLogger(l, false, false) 6766 6767 c, r := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: false}, o.MQTT.Host, o.MQTT.Port) 6768 defer c.Close() 6769 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6770 6771 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, tdir, "true")) 6772 6773 testMQTTSub(t, 1, c, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 6774 6775 mset, err := s.GlobalAccount().lookupStream(mqttStreamName) 6776 if err != nil { 6777 t.Fatalf("Error looking up stream: %v", err) 6778 } 6779 var cons *consumer 6780 mset.mu.RLock() 6781 for _, c := range mset.consumers { 6782 cons = c 6783 break 6784 } 6785 mset.mu.RUnlock() 6786 cons.mu.RLock() 6787 st := cons.store.Type() 6788 cons.mu.RUnlock() 6789 if st != MemoryStorage { 6790 t.Fatalf("Expected storage %v, got %v", MemoryStorage, st) 6791 } 6792 } 6793 6794 type unableToDeleteConsLogger struct { 6795 DummyLogger 6796 errCh chan string 6797 } 6798 6799 func (l *unableToDeleteConsLogger) Errorf(format string, args ...interface{}) { 6800 msg := fmt.Sprintf(format, args...) 6801 if strings.Contains(msg, "unable to delete consumer") { 6802 l.errCh <- msg 6803 } 6804 } 6805 6806 func TestMQTTSessionNotDeletedOnDeleteConsumerError(t *testing.T) { 6807 org := mqttJSAPITimeout 6808 mqttJSAPITimeout = 1000 * time.Millisecond 6809 defer func() { mqttJSAPITimeout = org }() 6810 6811 cl := createJetStreamClusterWithTemplate(t, testMQTTGetClusterTemplaceNoLeaf(), "MQTT", 2) 6812 defer cl.shutdown() 6813 6814 o := cl.opts[0] 6815 s1 := cl.servers[0] 6816 // Plug error logger to s1 6817 l := &unableToDeleteConsLogger{errCh: make(chan string, 10)} 6818 s1.SetLogger(l, false, false) 6819 6820 nc, js := jsClientConnect(t, s1) 6821 defer nc.Close() 6822 6823 mc, r := testMQTTConnectRetry(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 6824 defer mc.Close() 6825 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6826 6827 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 6828 testMQTTFlush(t, mc, nil, r) 6829 6830 // Now shutdown server 2, we should lose quorum 6831 cl.servers[1].Shutdown() 6832 6833 // Close the MQTT client: 6834 testMQTTDisconnect(t, mc, nil) 6835 6836 // We should have reported that there was an error deleting the consumer 6837 select { 6838 case <-l.errCh: 6839 // OK 6840 case <-time.After(time.Second): 6841 t.Fatal("Server did not report any error") 6842 } 6843 6844 // Now restart the server 2 so that we can check that the session is still persisted. 6845 cl.restartAllSamePorts() 6846 cl.waitOnStreamLeader(globalAccountName, mqttSessStreamName) 6847 6848 si, err := js.StreamInfo(mqttSessStreamName) 6849 require_NoError(t, err) 6850 require_True(t, si.State.Msgs == 1) 6851 } 6852 6853 // Test for auto-cleanup of consumers. 6854 func TestMQTTConsumerInactiveThreshold(t *testing.T) { 6855 tdir := t.TempDir() 6856 tmpl := ` 6857 listen: 127.0.0.1:-1 6858 server_name: mqtt 6859 jetstream { 6860 store_dir = %q 6861 } 6862 6863 mqtt { 6864 listen: 127.0.0.1:-1 6865 consumer_inactive_threshold: %q 6866 } 6867 6868 # For access to system account. 6869 accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } } 6870 ` 6871 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, tdir, "0.2s"))) 6872 s, o := RunServerWithConfig(conf) 6873 defer testMQTTShutdownServer(s) 6874 6875 mc, r := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 6876 defer mc.Close() 6877 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6878 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 6879 6880 nc, js := jsClientConnect(t, s) 6881 defer nc.Close() 6882 6883 ci := <-js.ConsumersInfo("$MQTT_msgs") 6884 6885 // Make sure we clean up this consumer. 6886 mc.Close() 6887 checkFor(t, 2*time.Second, 50*time.Millisecond, func() error { 6888 _, err := js.ConsumerInfo(ci.Stream, ci.Name) 6889 if err == nil { 6890 return fmt.Errorf("Consumer still present") 6891 } 6892 return nil 6893 }) 6894 6895 // Check reload. 6896 // We will not redo existing consumers however. 6897 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, tdir, "22s")) 6898 if opts := s.getOpts(); opts.MQTT.ConsumerInactiveThreshold != 22*time.Second { 6899 t.Fatalf("Expected reloaded value of %v but got %v", 22*time.Second, opts.MQTT.ConsumerInactiveThreshold) 6900 } 6901 } 6902 6903 func TestMQTTSubjectMapping(t *testing.T) { 6904 conf := createConfFile(t, []byte(fmt.Sprintf(` 6905 listen: 127.0.0.1:-1 6906 server_name: mqtt 6907 jetstream { 6908 store_dir = %q 6909 } 6910 6911 mappings = { 6912 foo0: bar0 6913 foo1: bar1 6914 } 6915 6916 mqtt { 6917 listen: 127.0.0.1:-1 6918 } 6919 `, t.TempDir()))) 6920 s, o := RunServerWithConfig(conf) 6921 defer testMQTTShutdownServer(s) 6922 6923 nc, js := jsClientConnect(t, s) 6924 defer nc.Close() 6925 6926 for _, qos := range []byte{0, 1} { 6927 t.Run(fmt.Sprintf("qos%d", qos), func(t *testing.T) { 6928 mc, r := testMQTTConnect(t, &mqttConnInfo{clientID: "sub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 6929 defer mc.Close() 6930 6931 bar := fmt.Sprintf("bar%v", qos) 6932 foo := fmt.Sprintf("foo%v", qos) 6933 6934 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 6935 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: bar, qos: qos}}, []byte{qos}) 6936 testMQTTFlush(t, mc, nil, r) 6937 6938 mcp, rp := testMQTTConnect(t, &mqttConnInfo{clientID: "pub", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 6939 defer mcp.Close() 6940 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 6941 6942 natsPub(t, nc, foo, []byte("msg0")) 6943 testMQTTCheckPubMsgNoAck(t, mc, r, bar, 0, []byte("msg0")) 6944 6945 testMQTTPublish(t, mcp, rp, 0, false, false, foo, 0, []byte("msg1")) 6946 testMQTTCheckPubMsgNoAck(t, mc, r, bar, 0, []byte("msg1")) 6947 6948 testMQTTPublish(t, mcp, rp, 0, false, true, foo, 0, []byte("msg1_retained")) 6949 testMQTTCheckPubMsgNoAck(t, mc, r, bar, 0, []byte("msg1_retained")) 6950 6951 testMQTTPublish(t, mcp, rp, 1, false, false, foo, 1, []byte("msg2")) 6952 // For the receiving side, the expected QoS is based on the subscription's QoS, 6953 // not the publisher. 6954 expected := byte(0) 6955 if qos == 1 { 6956 expected = mqttPubQos1 6957 } 6958 testMQTTCheckPubMsgNoAck(t, mc, r, bar, expected, []byte("msg2")) 6959 6960 testMQTTPublish(t, mcp, rp, 1, false, true, foo, 1, []byte("msg2_retained")) 6961 testMQTTCheckPubMsgNoAck(t, mc, r, bar, expected, []byte("msg2_retained")) 6962 6963 testMQTTDisconnect(t, mcp, nil) 6964 6965 // Try the with the "will" with QoS0 first 6966 mcp, rp = testMQTTConnect(t, &mqttConnInfo{ 6967 clientID: "pub", 6968 cleanSess: true, 6969 will: &mqttWill{topic: []byte(foo), qos: 0, message: []byte("willmsg1")}}, 6970 o.MQTT.Host, o.MQTT.Port) 6971 defer mcp.Close() 6972 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 6973 testMQTTFlush(t, mcp, nil, rp) 6974 6975 // Close the connection without proper disconnect for will to be sent 6976 mcp.Close() 6977 testMQTTCheckPubMsgNoAck(t, mc, r, bar, 0, []byte("willmsg1")) 6978 6979 // Try the with the "will" with QoS1 now 6980 mcp, rp = testMQTTConnect(t, &mqttConnInfo{ 6981 clientID: "pub", 6982 cleanSess: true, 6983 will: &mqttWill{topic: []byte(foo), qos: 1, message: []byte("willmsg2")}}, 6984 o.MQTT.Host, o.MQTT.Port) 6985 defer mcp.Close() 6986 testMQTTCheckConnAck(t, rp, mqttConnAckRCConnectionAccepted, false) 6987 testMQTTFlush(t, mcp, nil, rp) 6988 6989 // Close the connection without proper disconnect for will to be sent 6990 mcp.Close() 6991 testMQTTCheckPubMsgNoAck(t, mc, r, bar, expected, []byte("willmsg2")) 6992 6993 si, err := js.StreamInfo("$MQTT_msgs") 6994 require_NoError(t, err) 6995 if qos == 0 { 6996 require_True(t, si.State.Msgs == 0) 6997 require_True(t, si.State.NumSubjects == 0) 6998 } else { 6999 // Number of QoS1 messages: 1 regular, 1 retained, 1 from will. 7000 require_True(t, si.State.Msgs == 3) 7001 require_True(t, si.State.NumSubjects == 1) 7002 } 7003 testMQTTDisconnect(t, mc, nil) 7004 }) 7005 } 7006 } 7007 7008 func TestMQTTSubjectMappingWithImportExport(t *testing.T) { 7009 conf := createConfFile(t, []byte(fmt.Sprintf(` 7010 listen: 127.0.0.1:-1 7011 server_name: mqtt 7012 jetstream { 7013 store_dir = %q 7014 } 7015 7016 accounts { 7017 A { 7018 users = [{user: "a", password: "pwd"}] 7019 mappings = { 7020 bar: foo 7021 } 7022 exports = [{service: "bar"}] 7023 jetstream: enabled 7024 } 7025 B { 7026 users = [{user: "b", password: "pwd"}] 7027 mappings = { 7028 foo: bar 7029 } 7030 imports = [{service: {account: "A", subject: "bar"}}] 7031 jetstream: enabled 7032 } 7033 $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } 7034 } 7035 7036 mqtt { 7037 listen: 127.0.0.1:-1 7038 } 7039 `, t.TempDir()))) 7040 s, o := RunServerWithConfig(conf) 7041 defer testMQTTShutdownServer(s) 7042 7043 c1, r1 := testMQTTConnect(t, &mqttConnInfo{user: "a", pass: "pwd", clientID: "a1", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7044 defer c1.Close() 7045 testMQTTCheckConnAck(t, r1, mqttConnAckRCConnectionAccepted, false) 7046 testMQTTSub(t, 1, c1, r1, []*mqttFilter{{filter: "foo", qos: 0}}, []byte{0}) 7047 testMQTTFlush(t, c1, nil, r1) 7048 7049 c2, r2 := testMQTTConnect(t, &mqttConnInfo{user: "a", pass: "pwd", clientID: "a2", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7050 defer c2.Close() 7051 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 7052 testMQTTSub(t, 1, c2, r2, []*mqttFilter{{filter: "foo", qos: 1}}, []byte{1}) 7053 testMQTTFlush(t, c2, nil, r2) 7054 7055 c3, r3 := testMQTTConnect(t, &mqttConnInfo{user: "a", pass: "pwd", clientID: "a3", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7056 defer c3.Close() 7057 testMQTTCheckConnAck(t, r3, mqttConnAckRCConnectionAccepted, false) 7058 testMQTTSub(t, 1, c3, r3, []*mqttFilter{{filter: "bar", qos: 0}}, []byte{0}) 7059 testMQTTFlush(t, c3, nil, r3) 7060 7061 c4, r4 := testMQTTConnect(t, &mqttConnInfo{user: "a", pass: "pwd", clientID: "a4", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7062 defer c4.Close() 7063 testMQTTCheckConnAck(t, r4, mqttConnAckRCConnectionAccepted, false) 7064 testMQTTSub(t, 1, c4, r4, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 7065 testMQTTFlush(t, c4, nil, r4) 7066 7067 bc, br := testMQTTConnect(t, &mqttConnInfo{user: "b", pass: "pwd", clientID: "b0", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7068 defer bc.Close() 7069 testMQTTCheckConnAck(t, br, mqttConnAckRCConnectionAccepted, false) 7070 7071 bc1, br1 := testMQTTConnect(t, &mqttConnInfo{user: "b", pass: "pwd", clientID: "b1", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7072 defer bc1.Close() 7073 testMQTTCheckConnAck(t, br1, mqttConnAckRCConnectionAccepted, false) 7074 testMQTTSub(t, 1, bc1, br1, []*mqttFilter{{filter: "foo", qos: 0}}, []byte{0}) 7075 testMQTTFlush(t, bc1, nil, br1) 7076 7077 bc2, br2 := testMQTTConnect(t, &mqttConnInfo{user: "b", pass: "pwd", clientID: "b2", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7078 defer bc2.Close() 7079 testMQTTCheckConnAck(t, br2, mqttConnAckRCConnectionAccepted, false) 7080 testMQTTSub(t, 1, bc2, br2, []*mqttFilter{{filter: "b", qos: 1}}, []byte{1}) 7081 testMQTTFlush(t, bc2, nil, br2) 7082 7083 bc3, br3 := testMQTTConnect(t, &mqttConnInfo{user: "b", pass: "pwd", clientID: "b3", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7084 defer bc3.Close() 7085 testMQTTCheckConnAck(t, br3, mqttConnAckRCConnectionAccepted, false) 7086 testMQTTSub(t, 1, bc3, br3, []*mqttFilter{{filter: "bar", qos: 0}}, []byte{0}) 7087 testMQTTFlush(t, bc3, nil, br3) 7088 7089 bc4, br4 := testMQTTConnect(t, &mqttConnInfo{user: "b", pass: "pwd", clientID: "b4", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7090 defer bc4.Close() 7091 testMQTTCheckConnAck(t, br4, mqttConnAckRCConnectionAccepted, false) 7092 testMQTTSub(t, 1, bc4, br4, []*mqttFilter{{filter: "bar", qos: 1}}, []byte{1}) 7093 testMQTTFlush(t, bc4, nil, br4) 7094 7095 nc := natsConnect(t, fmt.Sprintf("nats://b:pwd@%s:%d", o.Host, o.Port)) 7096 defer nc.Close() 7097 7098 natsPub(t, nc, "foo", []byte("msg0")) 7099 testMQTTCheckPubMsgNoAck(t, c1, r1, "foo", 0, []byte("msg0")) 7100 testMQTTCheckPubMsgNoAck(t, c2, r2, "foo", 0, []byte("msg0")) 7101 testMQTTExpectNothing(t, r3) 7102 testMQTTExpectNothing(t, r4) 7103 testMQTTExpectNothing(t, br1) 7104 testMQTTExpectNothing(t, br2) 7105 testMQTTCheckPubMsgNoAck(t, bc3, br3, "bar", 0, []byte("msg0")) 7106 testMQTTCheckPubMsgNoAck(t, bc4, br4, "bar", 0, []byte("msg0")) 7107 7108 testMQTTPublish(t, bc, br, 0, false, false, "foo", 0, []byte("msg1")) 7109 testMQTTCheckPubMsgNoAck(t, c1, r1, "foo", 0, []byte("msg1")) 7110 testMQTTCheckPubMsgNoAck(t, c2, r2, "foo", 0, []byte("msg1")) 7111 testMQTTExpectNothing(t, r3) 7112 testMQTTExpectNothing(t, r4) 7113 testMQTTExpectNothing(t, br1) 7114 testMQTTExpectNothing(t, br2) 7115 testMQTTCheckPubMsgNoAck(t, bc3, br3, "bar", 0, []byte("msg1")) 7116 testMQTTCheckPubMsgNoAck(t, bc4, br4, "bar", 0, []byte("msg1")) 7117 7118 testMQTTPublish(t, bc, br, 1, false, false, "foo", 1, []byte("msg2")) 7119 testMQTTCheckPubMsgNoAck(t, c1, r1, "foo", 0, []byte("msg2")) 7120 testMQTTCheckPubMsgNoAck(t, c2, r2, "foo", mqttPubQos1, []byte("msg2")) 7121 testMQTTExpectNothing(t, r3) 7122 testMQTTExpectNothing(t, r4) 7123 testMQTTExpectNothing(t, br1) 7124 testMQTTExpectNothing(t, br2) 7125 testMQTTCheckPubMsgNoAck(t, bc3, br3, "bar", 0, []byte("msg2")) 7126 testMQTTCheckPubMsgNoAck(t, bc4, br4, "bar", mqttPubQos1, []byte("msg2")) 7127 7128 // Connection nc is for account B 7129 check := func(nc *nats.Conn, subj string) { 7130 t.Helper() 7131 req, err := json.Marshal(&JSApiStreamInfoRequest{SubjectsFilter: ">"}) 7132 require_NoError(t, err) 7133 resp, err := nc.Request(fmt.Sprintf(JSApiStreamInfoT, "$MQTT_msgs"), req, time.Second) 7134 require_NoError(t, err) 7135 var si StreamInfo 7136 err = json.Unmarshal(resp.Data, &si) 7137 require_NoError(t, err) 7138 require_True(t, si.State.Msgs == 1) 7139 require_True(t, si.State.NumSubjects == 1) 7140 require_True(t, si.State.Subjects[subj] == 1) 7141 } 7142 // Currently, nc is for account B 7143 check(nc, "$MQTT.msgs.bar") 7144 7145 nc.Close() 7146 nc = natsConnect(t, fmt.Sprintf("nats://a:pwd@%s:%d", o.Host, o.Port)) 7147 defer nc.Close() 7148 check(nc, "$MQTT.msgs.foo") 7149 } 7150 7151 func TestMQTTSubRetainedRace(t *testing.T) { 7152 o := testMQTTDefaultOptions() 7153 s := testMQTTRunServer(t, o) 7154 defer testMQTTShutdownServer(s) 7155 7156 useCases := []struct { 7157 name string 7158 f func(t *testing.T, o *Options, subTopic, pubTopic string, QOS byte) 7159 }{ 7160 {"new top level", testMQTTNewSubRetainedRace}, 7161 {"existing top level", testMQTTNewSubWithExistingTopLevelRetainedRace}, 7162 } 7163 pubTopic := "/bar" 7164 subTopics := []string{"#", "/bar", "/+", "/#"} 7165 QOS := []byte{0, 1, 2} 7166 for _, tc := range useCases { 7167 t.Run(tc.name, func(t *testing.T) { 7168 for _, subTopic := range subTopics { 7169 t.Run(subTopic, func(t *testing.T) { 7170 for _, qos := range QOS { 7171 t.Run(fmt.Sprintf("QOS%d", qos), func(t *testing.T) { 7172 tc.f(t, o, subTopic, pubTopic, qos) 7173 }) 7174 } 7175 }) 7176 } 7177 }) 7178 } 7179 } 7180 7181 func testMQTTNewSubRetainedRace(t *testing.T, o *Options, subTopic, pubTopic string, QOS byte) { 7182 expectedFlags := (QOS << 1) | mqttPubFlagRetain 7183 payload := []byte("testmsg") 7184 7185 pubID := nuid.Next() 7186 pubc, pubr := testMQTTConnectRetry(t, &mqttConnInfo{clientID: pubID, cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 3) 7187 testMQTTCheckConnAck(t, pubr, mqttConnAckRCConnectionAccepted, false) 7188 defer testMQTTDisconnectEx(t, pubc, nil, true) 7189 defer pubc.Close() 7190 testMQTTPublish(t, pubc, pubr, QOS, false, true, pubTopic, 1, payload) 7191 7192 subID := nuid.Next() 7193 subc, subr := testMQTTConnect(t, &mqttConnInfo{clientID: subID, cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7194 testMQTTCheckConnAck(t, subr, mqttConnAckRCConnectionAccepted, false) 7195 testMQTTSub(t, 1, subc, subr, []*mqttFilter{{filter: subTopic, qos: QOS}}, []byte{QOS}) 7196 7197 testMQTTCheckPubMsg(t, subc, subr, pubTopic, expectedFlags, payload) 7198 if QOS == 2 { 7199 testMQTTCheckPubAck(t, subr, mqttPacketPubRel) 7200 testMQTTSendPIPacket(mqttPacketPubComp, t, subc, 1) 7201 } 7202 7203 testMQTTDisconnectEx(t, subc, nil, true) 7204 subc.Close() 7205 } 7206 7207 func testMQTTNewSubWithExistingTopLevelRetainedRace(t *testing.T, o *Options, subTopic, pubTopic string, QOS byte) { 7208 expectedFlags := (QOS << 1) | mqttPubFlagRetain 7209 payload := []byte("testmsg") 7210 7211 pubID := nuid.Next() 7212 pubc, pubr := testMQTTConnectRetry(t, &mqttConnInfo{clientID: pubID, cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 3) 7213 testMQTTCheckConnAck(t, pubr, mqttConnAckRCConnectionAccepted, false) 7214 defer testMQTTDisconnectEx(t, pubc, nil, true) 7215 defer pubc.Close() 7216 7217 subID := nuid.Next() 7218 subc, subr := testMQTTConnect(t, &mqttConnInfo{clientID: subID, cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7219 testMQTTCheckConnAck(t, subr, mqttConnAckRCConnectionAccepted, false) 7220 7221 // Clear retained messages from the prior run, and sleep a little to 7222 // ensure the change is propagated. 7223 testMQTTPublish(t, pubc, pubr, 0, false, true, pubTopic, 1, nil) 7224 time.Sleep(1 * time.Millisecond) 7225 7226 // Subscribe to `#` first, make sure we can get get the retained message 7227 // there. It's a QOS0 sub, so expect a QOS0 message. 7228 testMQTTSub(t, 1, subc, subr, []*mqttFilter{{filter: `#`, qos: 0}}, []byte{0}) 7229 testMQTTExpectNothing(t, subr) 7230 7231 // Publish the retained message with QOS2, see that the `#` subscriber gets it. 7232 testMQTTPublish(t, pubc, pubr, 2, false, true, pubTopic, 1, payload) 7233 testMQTTCheckPubMsg(t, subc, subr, pubTopic, 0, payload) 7234 testMQTTExpectNothing(t, subr) 7235 7236 // Now subscribe to the topic we want to test. We should get the retained 7237 // message there. 7238 testMQTTSub(t, 1, subc, subr, []*mqttFilter{{filter: subTopic, qos: QOS}}, []byte{QOS}) 7239 testMQTTCheckPubMsg(t, subc, subr, pubTopic, expectedFlags, payload) 7240 if QOS == 2 { 7241 testMQTTCheckPubAck(t, subr, mqttPacketPubRel) 7242 testMQTTSendPIPacket(mqttPacketPubComp, t, subc, 1) 7243 } 7244 7245 testMQTTDisconnectEx(t, subc, nil, true) 7246 subc.Close() 7247 } 7248 7249 // Issue https://github.com/nats-io/nats-server/issues/3924 7250 // The MQTT Server MUST NOT match Topic Filters starting with a wildcard character (# or +), 7251 // with Topic Names beginning with a $ character [MQTT-4.7.2-1] 7252 func TestMQTTSubjectWildcardStart(t *testing.T) { 7253 conf := createConfFile(t, []byte(fmt.Sprintf(` 7254 listen: 127.0.0.1:-1 7255 server_name: mqtt 7256 jetstream { 7257 store_dir = %q 7258 } 7259 mqtt { 7260 listen: 127.0.0.1:-1 7261 } 7262 `, t.TempDir()))) 7263 s, o := RunServerWithConfig(conf) 7264 defer testMQTTShutdownServer(s) 7265 7266 nc := natsConnect(t, s.ClientURL()) 7267 defer nc.Close() 7268 7269 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7270 defer mc.Close() 7271 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 7272 7273 mc1, r1 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7274 defer mc1.Close() 7275 testMQTTCheckConnAck(t, r1, mqttConnAckRCConnectionAccepted, false) 7276 7277 mc2, r2 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7278 defer mc2.Close() 7279 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 7280 7281 mc3, r3 := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7282 defer mc3.Close() 7283 testMQTTCheckConnAck(t, r3, mqttConnAckRCConnectionAccepted, false) 7284 7285 // These will fail already with the bug due to messages already being queue up before the subAck. 7286 testMQTTSub(t, 1, mc1, r1, []*mqttFilter{{filter: "*", qos: 0}}, []byte{0}) 7287 testMQTTFlush(t, mc1, nil, r1) 7288 7289 testMQTTSub(t, 1, mc2, r2, []*mqttFilter{{filter: "#", qos: 1}}, []byte{1}) 7290 testMQTTFlush(t, mc2, nil, r2) 7291 7292 testMQTTSub(t, 1, mc3, r3, []*mqttFilter{{filter: "*/foo", qos: 1}}, []byte{1}) 7293 testMQTTFlush(t, mc2, nil, r2) 7294 7295 // Just as a barrier 7296 natsFlush(t, nc) 7297 7298 // Now publish 7299 7300 // NATS Publish 7301 msg := []byte("HELLO WORLD") 7302 natsPubReq(t, nc, "foo", _EMPTY_, msg) 7303 7304 // Check messages received 7305 testMQTTCheckPubMsg(t, mc1, r1, "foo", 0, msg) 7306 testMQTTExpectNothing(t, r1) 7307 7308 testMQTTCheckPubMsg(t, mc2, r2, "foo", 0, msg) 7309 testMQTTExpectNothing(t, r2) 7310 7311 testMQTTExpectNothing(t, r3) 7312 7313 // Anything that starts with $ is reserved against wildcard subjects like above. 7314 natsPubReq(t, nc, "$JS.foo", _EMPTY_, msg) 7315 testMQTTExpectNothing(t, r1) 7316 testMQTTExpectNothing(t, r2) 7317 testMQTTExpectNothing(t, r3) 7318 7319 // Now do MQTT QoS-0 7320 testMQTTPublish(t, mc, r, 0, false, false, "foo", 0, msg) 7321 7322 testMQTTCheckPubMsg(t, mc1, r1, "foo", 0, msg) 7323 testMQTTExpectNothing(t, r1) 7324 7325 testMQTTCheckPubMsg(t, mc2, r2, "foo", 0, msg) 7326 testMQTTExpectNothing(t, r2) 7327 7328 testMQTTExpectNothing(t, r3) 7329 7330 testMQTTPublish(t, mc, r, 0, false, false, "$JS/foo", 1, msg) 7331 7332 testMQTTExpectNothing(t, r1) 7333 testMQTTExpectNothing(t, r2) 7334 testMQTTExpectNothing(t, r3) 7335 7336 // Now do MQTT QoS-1 7337 msg = []byte("HELLO WORLD - RETAINED") 7338 testMQTTPublish(t, mc, r, 1, false, false, "$JS/foo", 4, msg) 7339 7340 testMQTTExpectNothing(t, r1) 7341 testMQTTExpectNothing(t, r2) 7342 testMQTTExpectNothing(t, r3) 7343 7344 testMQTTPublish(t, mc, r, 1, false, false, "foo", 2, msg) 7345 7346 testMQTTCheckPubMsg(t, mc1, r1, "foo", 0, msg) 7347 testMQTTExpectNothing(t, r1) 7348 7349 testMQTTCheckPubMsg(t, mc2, r2, "foo", 2, msg) 7350 testMQTTExpectNothing(t, r2) 7351 7352 testMQTTExpectNothing(t, r3) 7353 7354 testMQTTPublish(t, mc, r, 1, false, false, "foo/foo", 3, msg) 7355 7356 testMQTTExpectNothing(t, r1) 7357 7358 testMQTTCheckPubMsg(t, mc2, r2, "foo/foo", 2, msg) 7359 testMQTTExpectNothing(t, r2) 7360 7361 testMQTTCheckPubMsg(t, mc3, r3, "foo/foo", 2, msg) 7362 testMQTTExpectNothing(t, r3) 7363 7364 // Make sure we did not retain the messages prefixed with $. 7365 nc, js := jsClientConnect(t, s) 7366 defer nc.Close() 7367 7368 si, err := js.StreamInfo(mqttStreamName) 7369 require_NoError(t, err) 7370 7371 require_True(t, si.State.Msgs == 0) 7372 } 7373 7374 func TestMQTTTopicWithDot(t *testing.T) { 7375 o := testMQTTDefaultOptions() 7376 s := testMQTTRunServer(t, o) 7377 defer testMQTTShutdownServer(s) 7378 7379 nc := natsConnect(t, s.ClientURL(), nats.UserInfo("mqtt", "pwd")) 7380 defer nc.Close() 7381 7382 sub := natsSubSync(t, nc, "*.*") 7383 7384 c1, r1 := testMQTTConnect(t, &mqttConnInfo{user: "mqtt", pass: "pwd", clientID: "conn1", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7385 defer c1.Close() 7386 testMQTTCheckConnAck(t, r1, mqttConnAckRCConnectionAccepted, false) 7387 testMQTTSub(t, 1, c1, r1, []*mqttFilter{{filter: "spBv1.0/plant1", qos: 0}}, []byte{0}) 7388 testMQTTSub(t, 1, c1, r1, []*mqttFilter{{filter: "spBv1.0/plant2", qos: 1}}, []byte{1}) 7389 7390 c2, r2 := testMQTTConnect(t, &mqttConnInfo{user: "mqtt", pass: "pwd", clientID: "conn2", cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7391 defer c2.Close() 7392 testMQTTCheckConnAck(t, r2, mqttConnAckRCConnectionAccepted, false) 7393 7394 testMQTTPublish(t, c2, r2, 0, false, false, "spBv1.0/plant1", 0, []byte("msg1")) 7395 testMQTTCheckPubMsg(t, c1, r1, "spBv1.0/plant1", 0, []byte("msg1")) 7396 msg := natsNexMsg(t, sub, time.Second) 7397 require_Equal(t, msg.Subject, "spBv1//0.plant1") 7398 7399 testMQTTPublish(t, c2, r2, 1, false, false, "spBv1.0/plant2", 1, []byte("msg2")) 7400 testMQTTCheckPubMsg(t, c1, r1, "spBv1.0/plant2", mqttPubQos1, []byte("msg2")) 7401 msg = natsNexMsg(t, sub, time.Second) 7402 require_Equal(t, msg.Subject, "spBv1//0.plant2") 7403 7404 natsPub(t, nc, "spBv1//0.plant1", []byte("msg3")) 7405 testMQTTCheckPubMsg(t, c1, r1, "spBv1.0/plant1", 0, []byte("msg3")) 7406 msg = natsNexMsg(t, sub, time.Second) 7407 require_Equal(t, msg.Subject, "spBv1//0.plant1") 7408 7409 natsPub(t, nc, "spBv1//0.plant2", []byte("msg4")) 7410 testMQTTCheckPubMsg(t, c1, r1, "spBv1.0/plant2", 0, []byte("msg4")) 7411 msg = natsNexMsg(t, sub, time.Second) 7412 require_Equal(t, msg.Subject, "spBv1//0.plant2") 7413 } 7414 7415 // Issue https://github.com/nats-io/nats-server/issues/4291 7416 func TestMQTTJetStreamRepublishAndQoS0Subscribers(t *testing.T) { 7417 conf := createConfFile(t, []byte(fmt.Sprintf(` 7418 listen: 127.0.0.1:-1 7419 server_name: mqtt 7420 jetstream { 7421 store_dir = %q 7422 } 7423 mqtt { 7424 listen: 127.0.0.1:-1 7425 } 7426 `, t.TempDir()))) 7427 s, o := RunServerWithConfig(conf) 7428 defer testMQTTShutdownServer(s) 7429 7430 nc, js := jsClientConnect(t, s) 7431 defer nc.Close() 7432 7433 // Setup stream with republish on it. 7434 _, err := js.AddStream(&nats.StreamConfig{ 7435 Name: "TEST", 7436 Subjects: []string{"foo"}, 7437 RePublish: &nats.RePublish{ 7438 Source: "foo", 7439 Destination: "mqtt.foo", 7440 }, 7441 }) 7442 require_NoError(t, err) 7443 7444 // Create QoS0 subscriber to catch re-publishes. 7445 mc, r := testMQTTConnect(t, &mqttConnInfo{cleanSess: true}, o.MQTT.Host, o.MQTT.Port) 7446 defer mc.Close() 7447 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 7448 7449 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "mqtt/foo", qos: 0}}, []byte{0}) 7450 testMQTTFlush(t, mc, nil, r) 7451 7452 msg := []byte("HELLO WORLD") 7453 _, err = js.Publish("foo", msg) 7454 require_NoError(t, err) 7455 7456 testMQTTCheckPubMsg(t, mc, r, "mqtt/foo", 0, msg) 7457 testMQTTExpectNothing(t, r) 7458 } 7459 7460 // Test for auto-cleanup of consumers. 7461 func TestMQTTDecodeRetainedMessage(t *testing.T) { 7462 tdir := t.TempDir() 7463 tmpl := ` 7464 listen: 127.0.0.1:-1 7465 server_name: mqtt 7466 jetstream { 7467 store_dir = %q 7468 } 7469 7470 mqtt { 7471 listen: 127.0.0.1:-1 7472 consumer_inactive_threshold: %q 7473 } 7474 7475 # For access to system account. 7476 accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } } 7477 ` 7478 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, tdir, "0.2s"))) 7479 s, o := RunServerWithConfig(conf) 7480 defer testMQTTShutdownServer(s) 7481 7482 // Connect and publish a retained message, this will be in the "newer" form, 7483 // with the metadata in the header. 7484 mc, r := testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 7485 defer mc.Close() 7486 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 7487 testMQTTPublish(t, mc, r, 0, false, true, "foo/1", 0, []byte("msg1")) 7488 mc.Close() 7489 7490 // Store a "legacy", JSON-encoded payload directly into the stream. 7491 nc, js := jsClientConnect(t, s) 7492 defer nc.Close() 7493 7494 rm := mqttRetainedMsg{ 7495 Origin: "test", 7496 Subject: "foo.2", 7497 Topic: "foo/2", 7498 Flags: mqttPubFlagRetain, 7499 Msg: []byte("msg2"), 7500 } 7501 jsonData, _ := json.Marshal(rm) 7502 _, err := js.PublishMsg(&nats.Msg{ 7503 Subject: mqttRetainedMsgsStreamSubject + rm.Subject, 7504 Data: jsonData, 7505 }) 7506 if err != nil { 7507 t.Fatalf("Error publishing retained message to JS directly: %v", err) 7508 } 7509 7510 // Restart the server to see that it picks up both retained messages on restart. 7511 s.Shutdown() 7512 s = RunServer(o) 7513 defer testMQTTShutdownServer(s) 7514 7515 // Connect again, subscribe, and check that we get both messages. 7516 mc, r = testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 7517 defer mc.Close() 7518 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 7519 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/+", qos: 0}}, []byte{0}) 7520 for i := 0; i < 2; i++ { 7521 b, pl := testMQTTReadPacket(t, r) 7522 if pt := b & mqttPacketMask; pt != mqttPacketPub { 7523 t.Fatalf("Expected PUBLISH packet %x, got %x", mqttPacketPub, pt) 7524 } 7525 _, _, topic := testMQTTGetPubMsgExEx(t, mc, r, mqttPubFlagRetain, pl, "", nil) 7526 if string(topic) != "foo/1" && string(topic) != "foo/2" { 7527 t.Fatalf("Expected foo/1 or foo/2, got %q", topic) 7528 } 7529 } 7530 testMQTTExpectNothing(t, r) 7531 mc.Close() 7532 7533 // Clear both retained messages. 7534 mc, r = testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 7535 defer mc.Close() 7536 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 7537 testMQTTPublish(t, mc, r, 0, false, true, "foo/1", 0, []byte{}) 7538 testMQTTPublish(t, mc, r, 0, false, true, "foo/2", 0, []byte{}) 7539 mc.Close() 7540 7541 // Connect again, subscribe, and check that we get nothing. 7542 mc, r = testMQTTConnectRetry(t, &mqttConnInfo{clientID: "test", cleanSess: true}, o.MQTT.Host, o.MQTT.Port, 5) 7543 defer mc.Close() 7544 testMQTTCheckConnAck(t, r, mqttConnAckRCConnectionAccepted, false) 7545 testMQTTSub(t, 1, mc, r, []*mqttFilter{{filter: "foo/+", qos: 0}}, []byte{0}) 7546 testMQTTExpectNothing(t, r) 7547 } 7548 7549 ////////////////////////////////////////////////////////////////////////// 7550 // 7551 // Benchmarks 7552 // 7553 ////////////////////////////////////////////////////////////////////////// 7554 7555 const ( 7556 mqttPubSubj = "a" 7557 mqttBenchBufLen = 32768 7558 ) 7559 7560 func mqttBenchPubQoS0(b *testing.B, subject, payload string, numSubs int) { 7561 b.StopTimer() 7562 b.ReportAllocs() 7563 o := testMQTTDefaultOptions() 7564 s := RunServer(o) 7565 defer testMQTTShutdownServer(s) 7566 7567 ci := &mqttConnInfo{clientID: "pub", cleanSess: true} 7568 c, br := testMQTTConnect(b, ci, o.MQTT.Host, o.MQTT.Port) 7569 testMQTTCheckConnAck(b, br, mqttConnAckRCConnectionAccepted, false) 7570 w := newMQTTWriter(0) 7571 testMQTTWritePublishPacket(b, w, 0, false, false, subject, 0, []byte(payload)) 7572 sendOp := w.Bytes() 7573 7574 dch := make(chan error, 1) 7575 totalSize := int64(len(sendOp)) 7576 cdch := 0 7577 7578 createSub := func(i int) { 7579 ci := &mqttConnInfo{clientID: fmt.Sprintf("sub%d", i), cleanSess: true} 7580 cs, brs := testMQTTConnect(b, ci, o.MQTT.Host, o.MQTT.Port) 7581 testMQTTCheckConnAck(b, brs, mqttConnAckRCConnectionAccepted, false) 7582 7583 testMQTTSub(b, 1, cs, brs, []*mqttFilter{{filter: subject, qos: 0}}, []byte{0}) 7584 testMQTTFlush(b, cs, nil, brs) 7585 7586 w := newMQTTWriter(0) 7587 varHeaderAndPayload := 2 + len(subject) + len(payload) 7588 w.WriteVarInt(varHeaderAndPayload) 7589 size := 1 + w.Len() + varHeaderAndPayload 7590 totalSize += int64(size) 7591 7592 go func() { 7593 mqttBenchConsumeMsgQoS0(cs, int64(b.N)*int64(size), dch) 7594 cs.Close() 7595 }() 7596 } 7597 for i := 0; i < numSubs; i++ { 7598 createSub(i + 1) 7599 cdch++ 7600 } 7601 7602 bw := bufio.NewWriterSize(c, mqttBenchBufLen) 7603 b.SetBytes(totalSize) 7604 b.StartTimer() 7605 for i := 0; i < b.N; i++ { 7606 bw.Write(sendOp) 7607 } 7608 testMQTTFlush(b, c, bw, br) 7609 for i := 0; i < cdch; i++ { 7610 if e := <-dch; e != nil { 7611 b.Fatal(e.Error()) 7612 } 7613 } 7614 b.StopTimer() 7615 c.Close() 7616 s.Shutdown() 7617 } 7618 7619 func mqttBenchConsumeMsgQoS0(c net.Conn, total int64, dch chan<- error) { 7620 var buf [mqttBenchBufLen]byte 7621 var err error 7622 var n int 7623 for size := int64(0); size < total; { 7624 n, err = c.Read(buf[:]) 7625 if err != nil { 7626 break 7627 } 7628 size += int64(n) 7629 } 7630 dch <- err 7631 } 7632 7633 func mqttBenchPubQoS1(b *testing.B, subject, payload string, numSubs int) { 7634 b.StopTimer() 7635 o := testMQTTDefaultOptions() 7636 o.MQTT.MaxAckPending = 0xFFFF 7637 s := RunServer(o) 7638 defer testMQTTShutdownServer(s) 7639 7640 ci := &mqttConnInfo{cleanSess: true} 7641 c, br := testMQTTConnect(b, ci, o.MQTT.Host, o.MQTT.Port) 7642 testMQTTCheckConnAck(b, br, mqttConnAckRCConnectionAccepted, false) 7643 7644 w := newMQTTWriter(0) 7645 testMQTTWritePublishPacket(b, w, 1, false, false, subject, 1, []byte(payload)) 7646 // For reported bytes we will count the PUBLISH + PUBACK (4 bytes) 7647 totalSize := int64(w.Len() + 4) 7648 w.Reset() 7649 7650 pi := uint16(1) 7651 maxpi := uint16(60000) 7652 ppich := make(chan error, 10) 7653 dch := make(chan error, 1+numSubs) 7654 cdch := 1 7655 // Start go routine to consume PUBACK for published QoS 1 messages. 7656 go mqttBenchConsumePubAck(c, b.N, dch, ppich) 7657 7658 createSub := func(i int) { 7659 ci := &mqttConnInfo{clientID: fmt.Sprintf("sub%d", i), cleanSess: true} 7660 cs, brs := testMQTTConnect(b, ci, o.MQTT.Host, o.MQTT.Port) 7661 testMQTTCheckConnAck(b, brs, mqttConnAckRCConnectionAccepted, false) 7662 7663 testMQTTSub(b, 1, cs, brs, []*mqttFilter{{filter: subject, qos: 1}}, []byte{1}) 7664 testMQTTFlush(b, cs, nil, brs) 7665 7666 w := newMQTTWriter(0) 7667 varHeaderAndPayload := 2 + len(subject) + 2 + len(payload) 7668 w.WriteVarInt(varHeaderAndPayload) 7669 size := 1 + w.Len() + varHeaderAndPayload 7670 // Add to the bytes reported the size of message sent to subscriber + PUBACK (4 bytes) 7671 totalSize += int64(size + 4) 7672 7673 go func() { 7674 mqttBenchConsumeMsgQos1(cs, b.N, size, dch) 7675 cs.Close() 7676 }() 7677 } 7678 for i := 0; i < numSubs; i++ { 7679 createSub(i + 1) 7680 cdch++ 7681 } 7682 7683 flush := func() { 7684 b.Helper() 7685 if _, err := c.Write(w.Bytes()); err != nil { 7686 b.Fatalf("Error on write: %v", err) 7687 } 7688 w.Reset() 7689 } 7690 7691 b.SetBytes(totalSize) 7692 b.StartTimer() 7693 for i := 0; i < b.N; i++ { 7694 if pi <= maxpi { 7695 testMQTTWritePublishPacket(b, w, 1, false, false, subject, pi, []byte(payload)) 7696 pi++ 7697 if w.Len() >= mqttBenchBufLen { 7698 flush() 7699 } 7700 } else { 7701 if w.Len() > 0 { 7702 flush() 7703 } 7704 if pi > 60000 { 7705 pi = 1 7706 maxpi = 0 7707 } 7708 if e := <-ppich; e != nil { 7709 b.Fatal(e.Error()) 7710 } 7711 maxpi += 10000 7712 i-- 7713 } 7714 } 7715 if w.Len() > 0 { 7716 flush() 7717 } 7718 for i := 0; i < cdch; i++ { 7719 if e := <-dch; e != nil { 7720 b.Fatal(e.Error()) 7721 } 7722 } 7723 b.StopTimer() 7724 c.Close() 7725 s.Shutdown() 7726 } 7727 7728 func mqttBenchConsumeMsgQos1(c net.Conn, total, size int, dch chan<- error) { 7729 var buf [mqttBenchBufLen]byte 7730 pubAck := [4]byte{mqttPacketPubAck, 0x2, 0, 0} 7731 var err error 7732 var n int 7733 var pi uint16 7734 var prev int 7735 for i := 0; i < total; { 7736 n, err = c.Read(buf[:]) 7737 if err != nil { 7738 break 7739 } 7740 n += prev 7741 for ; n >= size; n -= size { 7742 i++ 7743 pi++ 7744 pubAck[2] = byte(pi >> 8) 7745 pubAck[3] = byte(pi) 7746 if _, err = c.Write(pubAck[:4]); err != nil { 7747 dch <- err 7748 return 7749 } 7750 if pi == 60000 { 7751 pi = 0 7752 } 7753 } 7754 prev = n 7755 } 7756 dch <- err 7757 } 7758 7759 func mqttBenchConsumePubAck(c net.Conn, total int, dch, ppich chan<- error) { 7760 var buf [mqttBenchBufLen]byte 7761 var err error 7762 var n int 7763 var pi uint16 7764 var prev int 7765 for i := 0; i < total; { 7766 n, err = c.Read(buf[:]) 7767 if err != nil { 7768 break 7769 } 7770 n += prev 7771 for ; n >= 4; n -= 4 { 7772 i++ 7773 pi++ 7774 if pi%10000 == 0 { 7775 ppich <- nil 7776 } 7777 if pi == 60001 { 7778 pi = 0 7779 } 7780 } 7781 prev = n 7782 } 7783 ppich <- err 7784 dch <- err 7785 } 7786 7787 func BenchmarkMQTT_QoS0_Pub_______0b_Payload(b *testing.B) { 7788 mqttBenchPubQoS0(b, mqttPubSubj, "", 0) 7789 } 7790 7791 func BenchmarkMQTT_QoS0_Pub_______8b_Payload(b *testing.B) { 7792 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(8), 0) 7793 } 7794 7795 func BenchmarkMQTT_QoS0_Pub______32b_Payload(b *testing.B) { 7796 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(32), 0) 7797 } 7798 7799 func BenchmarkMQTT_QoS0_Pub_____128b_Payload(b *testing.B) { 7800 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(128), 0) 7801 } 7802 7803 func BenchmarkMQTT_QoS0_Pub_____256b_Payload(b *testing.B) { 7804 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(256), 0) 7805 } 7806 7807 func BenchmarkMQTT_QoS0_Pub_______1K_Payload(b *testing.B) { 7808 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(1024), 0) 7809 } 7810 7811 func BenchmarkMQTT_QoS0_PubSub1___0b_Payload(b *testing.B) { 7812 mqttBenchPubQoS0(b, mqttPubSubj, "", 1) 7813 } 7814 7815 func BenchmarkMQTT_QoS0_PubSub1___8b_Payload(b *testing.B) { 7816 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(8), 1) 7817 } 7818 7819 func BenchmarkMQTT_QoS0_PubSub1__32b_Payload(b *testing.B) { 7820 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(32), 1) 7821 } 7822 7823 func BenchmarkMQTT_QoS0_PubSub1_128b_Payload(b *testing.B) { 7824 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(128), 1) 7825 } 7826 7827 func BenchmarkMQTT_QoS0_PubSub1_256b_Payload(b *testing.B) { 7828 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(256), 1) 7829 } 7830 7831 func BenchmarkMQTT_QoS0_PubSub1___1K_Payload(b *testing.B) { 7832 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(1024), 1) 7833 } 7834 7835 func BenchmarkMQTT_QoS0_PubSub2___0b_Payload(b *testing.B) { 7836 mqttBenchPubQoS0(b, mqttPubSubj, "", 2) 7837 } 7838 7839 func BenchmarkMQTT_QoS0_PubSub2___8b_Payload(b *testing.B) { 7840 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(8), 2) 7841 } 7842 7843 func BenchmarkMQTT_QoS0_PubSub2__32b_Payload(b *testing.B) { 7844 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(32), 2) 7845 } 7846 7847 func BenchmarkMQTT_QoS0_PubSub2_128b_Payload(b *testing.B) { 7848 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(128), 2) 7849 } 7850 7851 func BenchmarkMQTT_QoS0_PubSub2_256b_Payload(b *testing.B) { 7852 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(256), 2) 7853 } 7854 7855 func BenchmarkMQTT_QoS0_PubSub2___1K_Payload(b *testing.B) { 7856 mqttBenchPubQoS0(b, mqttPubSubj, sizedString(1024), 2) 7857 } 7858 7859 func BenchmarkMQTT_QoS1_Pub_______0b_Payload(b *testing.B) { 7860 mqttBenchPubQoS1(b, mqttPubSubj, "", 0) 7861 } 7862 7863 func BenchmarkMQTT_QoS1_Pub_______8b_Payload(b *testing.B) { 7864 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(8), 0) 7865 } 7866 7867 func BenchmarkMQTT_QoS1_Pub______32b_Payload(b *testing.B) { 7868 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(32), 0) 7869 } 7870 7871 func BenchmarkMQTT_QoS1_Pub_____128b_Payload(b *testing.B) { 7872 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(128), 0) 7873 } 7874 7875 func BenchmarkMQTT_QoS1_Pub_____256b_Payload(b *testing.B) { 7876 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(256), 0) 7877 } 7878 7879 func BenchmarkMQTT_QoS1_Pub_______1K_Payload(b *testing.B) { 7880 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(1024), 0) 7881 } 7882 7883 func BenchmarkMQTT_QoS1_PubSub1___0b_Payload(b *testing.B) { 7884 mqttBenchPubQoS1(b, mqttPubSubj, "", 1) 7885 } 7886 7887 func BenchmarkMQTT_QoS1_PubSub1___8b_Payload(b *testing.B) { 7888 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(8), 1) 7889 } 7890 7891 func BenchmarkMQTT_QoS1_PubSub1__32b_Payload(b *testing.B) { 7892 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(32), 1) 7893 } 7894 7895 func BenchmarkMQTT_QoS1_PubSub1_128b_Payload(b *testing.B) { 7896 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(128), 1) 7897 } 7898 7899 func BenchmarkMQTT_QoS1_PubSub1_256b_Payload(b *testing.B) { 7900 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(256), 1) 7901 } 7902 7903 func BenchmarkMQTT_QoS1_PubSub1___1K_Payload(b *testing.B) { 7904 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(1024), 1) 7905 } 7906 7907 func BenchmarkMQTT_QoS1_PubSub2___0b_Payload(b *testing.B) { 7908 mqttBenchPubQoS1(b, mqttPubSubj, "", 2) 7909 } 7910 7911 func BenchmarkMQTT_QoS1_PubSub2___8b_Payload(b *testing.B) { 7912 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(8), 2) 7913 } 7914 7915 func BenchmarkMQTT_QoS1_PubSub2__32b_Payload(b *testing.B) { 7916 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(32), 2) 7917 } 7918 7919 func BenchmarkMQTT_QoS1_PubSub2_128b_Payload(b *testing.B) { 7920 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(128), 2) 7921 } 7922 7923 func BenchmarkMQTT_QoS1_PubSub2_256b_Payload(b *testing.B) { 7924 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(256), 2) 7925 } 7926 7927 func BenchmarkMQTT_QoS1_PubSub2___1K_Payload(b *testing.B) { 7928 mqttBenchPubQoS1(b, mqttPubSubj, sizedString(1024), 2) 7929 }