get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/gateway_test.go (about) 1 // Copyright 2018-2019 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package test 15 16 import ( 17 "bufio" 18 "bytes" 19 "crypto/tls" 20 "encoding/json" 21 "fmt" 22 "net" 23 "net/url" 24 "regexp" 25 "testing" 26 "time" 27 28 "get.pme.sh/pnats/server" 29 "github.com/nats-io/nats.go" 30 ) 31 32 func testDefaultOptionsForGateway(name string) *server.Options { 33 o := DefaultTestOptions 34 o.Port = -1 35 o.Cluster.Name = name 36 o.Gateway.Name = name 37 o.Gateway.Host = "127.0.0.1" 38 o.Gateway.Port = -1 39 return &o 40 } 41 42 func runGatewayServer(o *server.Options) *server.Server { 43 s := RunServer(o) 44 return s 45 } 46 47 func createGatewayConn(t testing.TB, host string, port int) net.Conn { 48 t.Helper() 49 return createClientConn(t, host, port) 50 } 51 52 func setupGatewayConn(t testing.TB, c net.Conn, org, dst string) (sendFun, expectFun) { 53 t.Helper() 54 dstInfo := checkInfoMsg(t, c) 55 if dstInfo.Gateway != dst { 56 t.Fatalf("Expected to connect to %q, got %q", dst, dstInfo.Gateway) 57 } 58 cs := fmt.Sprintf("CONNECT {\"verbose\":%v,\"pedantic\":%v,\"tls_required\":%v,\"gateway\":%q}\r\n", 59 false, false, false, org) 60 sendProto(t, c, cs) 61 sendProto(t, c, fmt.Sprintf("INFO {\"gateway\":%q}\r\n", org)) 62 return sendCommand(t, c), expectCommand(t, c) 63 } 64 65 func expectNumberOfProtos(t *testing.T, expFn expectFun, proto *regexp.Regexp, expected int, ignore ...*regexp.Regexp) { 66 t.Helper() 67 buf := []byte(nil) 68 for count := 0; count != expected; { 69 buf = append(buf, expFn(anyRe)...) 70 for _, skip := range ignore { 71 buf = skip.ReplaceAll(buf, []byte(``)) 72 } 73 count += len(proto.FindAllSubmatch(buf, -1)) 74 if count > expected { 75 t.Fatalf("Expected %v matches, got %v", expected, count) 76 } 77 buf = proto.ReplaceAll(buf, []byte(``)) 78 } 79 if len(buf) != 0 { 80 t.Fatalf("did not consume everything, left with: %q", buf) 81 } 82 } 83 84 func TestGatewayAccountInterest(t *testing.T) { 85 server.GatewayDoNotForceInterestOnlyMode(true) 86 defer server.GatewayDoNotForceInterestOnlyMode(false) 87 88 ob := testDefaultOptionsForGateway("B") 89 sb := runGatewayServer(ob) 90 defer sb.Shutdown() 91 92 gA := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 93 defer gA.Close() 94 95 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 96 gASend("PING\r\n") 97 gAExpect(pongRe) 98 99 // Sending a bunch of messages. On the first, "B" will send an A- 100 // protocol. 101 for i := 0; i < 100; i++ { 102 gASend("RMSG $foo foo 2\r\nok\r\n") 103 } 104 // We expect single A- followed by PONG. If "B" was sending more 105 // this expect call would fail. 106 gAExpect(aunsubRe) 107 gASend("PING\r\n") 108 gAExpect(pongRe) 109 110 // Start gateway C that connects to B 111 gC := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 112 defer gC.Close() 113 114 gCSend, gCExpect := setupGatewayConn(t, gC, "C", "B") 115 gCSend("PING\r\n") 116 gCExpect(pongRe) 117 // Send more messages, C should get A-, but A should not (already 118 // got it). 119 for i := 0; i < 100; i++ { 120 gCSend("RMSG $foo foo 2\r\nok\r\n") 121 } 122 gCExpect(aunsubRe) 123 gCSend("PING\r\n") 124 gCExpect(pongRe) 125 expectNothing(t, gA) 126 127 // Restart one of the gateway, and resend a message, verify 128 // that it receives A- (things get cleared on reconnect) 129 gC.Close() 130 gC = createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 131 defer gC.Close() 132 133 gCSend, gCExpect = setupGatewayConn(t, gC, "C", "B") 134 gCSend("PING\r\n") 135 gCExpect(pongRe) 136 gCSend("RMSG $foo foo 2\r\nok\r\n") 137 gCExpect(aunsubRe) 138 gCSend("PING\r\n") 139 gCExpect(pongRe) 140 expectNothing(t, gA) 141 142 // Close again and re-create, but this time don't send anything. 143 gC.Close() 144 gC = createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 145 defer gC.Close() 146 147 gCSend, gCExpect = setupGatewayConn(t, gC, "C", "B") 148 gCSend("PING\r\n") 149 gCExpect(pongRe) 150 151 // Now register the $foo account on B and create a subscription, 152 // A should receive an A+ because B knows that it previously sent 153 // an A-, but since it did not send one to C, C should not receive 154 // the A+. 155 client := createClientConn(t, ob.Host, ob.Port) 156 defer client.Close() 157 clientSend, clientExpect := setupConnWithAccount(t, sb, client, "$foo") 158 clientSend("SUB not.used 1234567\r\nPING\r\n") 159 clientExpect(pongRe) 160 gAExpect(asubRe) 161 expectNothing(t, gC) 162 } 163 164 func TestGatewaySubjectInterest(t *testing.T) { 165 server.GatewayDoNotForceInterestOnlyMode(true) 166 defer server.GatewayDoNotForceInterestOnlyMode(false) 167 168 ob := testDefaultOptionsForGateway("B") 169 fooAcc := server.NewAccount("$foo") 170 ob.Accounts = []*server.Account{fooAcc} 171 ob.Users = []*server.User{{Username: "ivan", Password: "password", Account: fooAcc}} 172 sb := runGatewayServer(ob) 173 defer sb.Shutdown() 174 175 // Create a client on B 176 client := createClientConn(t, ob.Host, ob.Port) 177 defer client.Close() 178 clientSend, clientExpect := setupConnWithUserPass(t, client, "ivan", "password") 179 // Since we want to test RS+/-, we need to have at 180 // least a subscription on B so that sending from A does 181 // not result in A- 182 clientSend("SUB not.used 1234567\r\nPING\r\n") 183 clientExpect(pongRe) 184 185 gA := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 186 defer gA.Close() 187 188 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 189 gASend("PING\r\n") 190 gAExpect(pongRe) 191 192 for i := 0; i < 100; i++ { 193 gASend("RMSG $foo foo 2\r\nok\r\n") 194 } 195 // We expect single RS- followed by PONG. If "B" was sending more 196 // this expect call would fail. 197 gAExpect(runsubRe) 198 gASend("PING\r\n") 199 gAExpect(pongRe) 200 201 // Start gateway C that connects to B 202 gC := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 203 defer gC.Close() 204 205 gCSend, gCExpect := setupGatewayConn(t, gC, "C", "B") 206 gCSend("PING\r\n") 207 gCExpect(pongRe) 208 // Send more messages, C should get RS-, but A should not (already 209 // got it). 210 for i := 0; i < 100; i++ { 211 gCSend("RMSG $foo foo 2\r\nok\r\n") 212 } 213 gCExpect(runsubRe) 214 gCSend("PING\r\n") 215 gCExpect(pongRe) 216 expectNothing(t, gA) 217 218 // Restart one of the gateway, and resend a message, verify 219 // that it receives RS- (things get cleared on reconnect) 220 gC.Close() 221 gC = createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 222 defer gC.Close() 223 224 gCSend, gCExpect = setupGatewayConn(t, gC, "C", "B") 225 gCSend("PING\r\n") 226 gCExpect(pongRe) 227 gCSend("RMSG $foo foo 2\r\nok\r\n") 228 gCExpect(runsubRe) 229 gCSend("PING\r\n") 230 gCExpect(pongRe) 231 expectNothing(t, gA) 232 233 // Close again and re-create, but this time don't send anything. 234 gC.Close() 235 gC = createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 236 defer gC.Close() 237 238 gCSend, gCExpect = setupGatewayConn(t, gC, "C", "B") 239 gCSend("PING\r\n") 240 gCExpect(pongRe) 241 242 // Now register a subscription on foo for account $foo on B. 243 // A should receive a RS+ because B knows that it previously 244 // sent a RS-, but since it did not send one to C, C should 245 // not receive the RS+. 246 clientSend("SUB foo 1\r\nSUB foo 2\r\n") 247 // Also subscribe to subject that was not used before, 248 // so there should be no RS+ for this one. 249 clientSend("SUB bar 3\r\nPING\r\n") 250 clientExpect(pongRe) 251 252 gAExpect(rsubRe) 253 expectNothing(t, gC) 254 // Check that we get only one protocol 255 expectNothing(t, gA) 256 257 // Unsubscribe the 2 subs on foo, expect to receive nothing. 258 clientSend("UNSUB 1\r\nUNSUB 2\r\nPING\r\n") 259 clientExpect(pongRe) 260 261 expectNothing(t, gC) 262 expectNothing(t, gA) 263 264 gC.Close() 265 266 // Send on foo, should get an RS- 267 gASend("RMSG $foo foo 2\r\nok\r\n") 268 gAExpect(runsubRe) 269 // Subscribe on foo, should get an RS+ that removes the no-interest 270 clientSend("SUB foo 4\r\nPING\r\n") 271 clientExpect(pongRe) 272 gAExpect(rsubRe) 273 // Send on bar, message should be received. 274 gASend("RMSG $foo bar 2\r\nok\r\n") 275 clientExpect(msgRe) 276 // Unsub foo and bar 277 clientSend("UNSUB 3\r\nUNSUB 4\r\nPING\r\n") 278 clientExpect(pongRe) 279 expectNothing(t, gA) 280 // Send on both foo and bar expect RS- 281 gASend("RMSG $foo foo 2\r\nok\r\n") 282 gAExpect(runsubRe) 283 gASend("RMSG $foo bar 2\r\nok\r\n") 284 gAExpect(runsubRe) 285 // Now have client create sub on "*", this should cause RS+ on * 286 // The remote will have cleared its no-interest on foo and bar 287 // and this receiving side is supposed to be doing the same. 288 clientSend("SUB * 5\r\nPING\r\n") 289 clientExpect(pongRe) 290 buf := gAExpect(rsubRe) 291 if !bytes.Contains(buf, []byte("$foo *")) { 292 t.Fatalf("Expected RS+ on %q, got %q", "*", buf) 293 } 294 // Check that the remote has cleared by sending from the client 295 // on foo and bar 296 clientSend("PUB foo 2\r\nok\r\n") 297 clientExpect(msgRe) 298 clientSend("PUB bar 2\r\nok\r\n") 299 clientExpect(msgRe) 300 // Check that A can send too and does not receive an RS- 301 gASend("RMSG $foo foo 2\r\nok\r\n") 302 expectNothing(t, gA) 303 clientExpect(msgRe) 304 gASend("RMSG $foo bar 2\r\nok\r\n") 305 expectNothing(t, gA) 306 clientExpect(msgRe) 307 } 308 309 func TestGatewayQueue(t *testing.T) { 310 server.GatewayDoNotForceInterestOnlyMode(true) 311 defer server.GatewayDoNotForceInterestOnlyMode(false) 312 313 ob := testDefaultOptionsForGateway("B") 314 fooAcc := server.NewAccount("$foo") 315 ob.Accounts = []*server.Account{fooAcc} 316 ob.Users = []*server.User{{Username: "ivan", Password: "password", Account: fooAcc}} 317 sb := runGatewayServer(ob) 318 defer sb.Shutdown() 319 320 gA := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 321 defer gA.Close() 322 323 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 324 gASend("PING\r\n") 325 gAExpect(pongRe) 326 327 client := createClientConn(t, ob.Host, ob.Port) 328 defer client.Close() 329 clientSend, clientExpect := setupConnWithUserPass(t, client, "ivan", "password") 330 331 // Create one queue sub on foo.* for group bar. 332 clientSend("SUB foo.* bar 1\r\nPING\r\n") 333 clientExpect(pongRe) 334 // Expect RS+ 335 gAExpect(rsubRe) 336 // Add another queue sub on same group 337 clientSend("SUB foo.* bar 2\r\nPING\r\n") 338 clientExpect(pongRe) 339 // Should not receive another RS+ for that one 340 expectNothing(t, gA) 341 // However, if subject is different, we can expect to receive another RS+ 342 clientSend("SUB foo.> bar 3\r\nPING\r\n") 343 clientExpect(pongRe) 344 gAExpect(rsubRe) 345 346 // Unsub one of the foo.* qsub, no RS- should be received 347 clientSend("UNSUB 1\r\nPING\r\n") 348 clientExpect(pongRe) 349 expectNothing(t, gA) 350 // Remove the other one, now we should get the RS- 351 clientSend("UNSUB 2\r\nPING\r\n") 352 clientExpect(pongRe) 353 gAExpect(runsubRe) 354 // Remove last one 355 clientSend("UNSUB 3\r\nPING\r\n") 356 clientExpect(pongRe) 357 gAExpect(runsubRe) 358 359 // Create some queues and check that interest is sent 360 // when GW reconnects. 361 clientSend("SUB foo bar 4\r\n") 362 gAExpect(rsubRe) 363 clientSend("SUB foo baz 5\r\n") 364 gAExpect(rsubRe) 365 clientSend("SUB foo bat 6\r\n") 366 gAExpect(rsubRe) 367 // There is already one on foo/bar, so nothing sent 368 clientSend("SUB foo bar 7\r\n") 369 expectNothing(t, gA) 370 // Add regular sub that should not cause RS+ 371 clientSend("SUB foo 8\r\n") 372 expectNothing(t, gA) 373 374 // Recreate gA 375 gA.Close() 376 gA = createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 377 defer gA.Close() 378 gASend, gAExpect = setupGatewayConn(t, gA, "A", "B") 379 // A should receive 3 RS+ 380 expectNumberOfProtos(t, gAExpect, rsubRe, 3) 381 // Nothing more 382 expectNothing(t, gA) 383 gASend("PING\r\n") 384 gAExpect(pongRe) 385 386 // Have A send a message on subject that has no sub 387 gASend("RMSG $foo new.subject 2\r\nok\r\n") 388 gAExpect(runsubRe) 389 // Now create a queue sub and check that we do not receive 390 // an RS+ without the queue name. 391 clientSend("SUB new.* queue 9\r\nPING\r\n") 392 clientExpect(pongRe) 393 buf := gAExpect(rsubRe) 394 if !bytes.Contains(buf, []byte("new.* queue")) { 395 t.Fatalf("Should have receives RS+ for new.* for queue, did not: %v", buf) 396 } 397 // Check for no other RS+. A should still keep an RS- for plain 398 // sub on new.subject 399 expectNothing(t, gA) 400 // Send message, expected to be received by client 401 gASend("RMSG $foo new.subject | queue 2\r\nok\r\n") 402 clientExpect(msgRe) 403 // Unsubscribe the queue sub 404 clientSend("UNSUB 9\r\nPING\r\n") 405 clientExpect(pongRe) 406 // A should receive RS- for this queue sub 407 buf = gAExpect(runsubRe) 408 if !bytes.Contains(buf, []byte("new.* queue")) { 409 t.Fatalf("Should have receives RS- for new.* for queue, did not: %v", buf) 410 } 411 expectNothing(t, gA) 412 } 413 414 func TestGatewaySendAllSubs(t *testing.T) { 415 server.GatewayDoNotForceInterestOnlyMode(true) 416 defer server.GatewayDoNotForceInterestOnlyMode(false) 417 418 ob := testDefaultOptionsForGateway("B") 419 sb := runGatewayServer(ob) 420 defer sb.Shutdown() 421 422 // Create a client on B 423 client := createClientConn(t, ob.Host, ob.Port) 424 defer client.Close() 425 clientSend, clientExpect := setupConn(t, client) 426 // Since we want to test RS+/-, we need to have at 427 // least a subscription on B so that sending from A does 428 // not result in A- 429 clientSend("SUB not.used 1234567\r\nPING\r\n") 430 clientExpect(pongRe) 431 432 gA := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 433 defer gA.Close() 434 435 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 436 gASend("PING\r\n") 437 gAExpect(pongRe) 438 439 // Bombard B with messages on different subjects. 440 // TODO(ik): Adapt if/when we change the conditions for the 441 // switch. 442 for i := 0; i < 1010; i++ { 443 gASend(fmt.Sprintf("RMSG $G foo.%d 2\r\nok\r\n", i)) 444 if i < 1000 { 445 gAExpect(runsubRe) 446 } 447 } 448 // Expect an INFO + RS+ $G not.used + INFO 449 buf := bufio.NewReader(gA) 450 for i := 0; i < 3; i++ { 451 line, _, err := buf.ReadLine() 452 if err != nil { 453 t.Fatalf("Error reading: %v", err) 454 } 455 switch i { 456 case 0: 457 case 2: 458 if !bytes.HasPrefix(line, []byte("INFO {")) { 459 t.Fatalf("Expected INFO, got: %s", line) 460 } 461 case 1: 462 if !bytes.HasPrefix(line, []byte("RS+ ")) { 463 t.Fatalf("Expected RS+, got: %s", line) 464 } 465 } 466 } 467 // After this point, any new sub or unsub on B should be 468 // sent to A. 469 clientSend("SUB foo 1\r\n") 470 gAExpect(rsubRe) 471 clientSend("UNSUB 1\r\n") 472 gAExpect(runsubRe) 473 } 474 475 func TestGatewayNoPanicOnBadProtocol(t *testing.T) { 476 ob := testDefaultOptionsForGateway("B") 477 sb := runGatewayServer(ob) 478 defer sb.Shutdown() 479 480 for _, test := range []struct { 481 name string 482 proto string 483 }{ 484 {"sub", "SUB > 1\r\n"}, 485 {"unsub", "UNSUB 1\r\n"}, 486 {"rsub", "RS+ $foo foo 2\r\n"}, 487 {"runsub", "RS- $foo foo 2\r\n"}, 488 {"pub", "PUB foo 2\r\nok\r\n"}, 489 {"msg", "MSG foo 2\r\nok\r\n"}, 490 {"rmsg", "RMSG $foo foo 2\r\nok\r\n"}, 491 {"anything", "xxxx\r\n"}, 492 } { 493 t.Run(test.name, func(t *testing.T) { 494 // Create raw tcp connection to gateway port 495 client := createClientConn(t, ob.Gateway.Host, ob.Gateway.Port) 496 defer client.Close() 497 clientSend := sendCommand(t, client) 498 clientSend(test.proto) 499 }) 500 } 501 502 // Server should not have crashed. 503 client := createClientConn(t, ob.Host, ob.Port) 504 defer client.Close() 505 clientSend, clientExpect := setupConn(t, client) 506 clientSend("PING\r\n") 507 clientExpect(pongRe) 508 } 509 510 func TestGatewayNoAccUnsubAfterQSub(t *testing.T) { 511 server.GatewayDoNotForceInterestOnlyMode(true) 512 defer server.GatewayDoNotForceInterestOnlyMode(false) 513 514 ob := testDefaultOptionsForGateway("B") 515 sb := runGatewayServer(ob) 516 defer sb.Shutdown() 517 518 gA := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 519 defer gA.Close() 520 521 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 522 gASend("PING\r\n") 523 gAExpect(pongRe) 524 525 // Simulate a client connecting to A and publishing a message 526 // so we get an A- from B since there is no interest. 527 gASend("RMSG $G foo 2\r\nok\r\n") 528 gAExpect(runsubRe) 529 530 // Now create client on B and create queue sub. 531 client := createClientConn(t, ob.Host, ob.Port) 532 defer client.Close() 533 clientSend, clientExpect := setupConn(t, client) 534 535 clientSend("SUB bar queue 1\r\nPING\r\n") 536 clientExpect(pongRe) 537 538 // A should receive an RS+ for this queue sub. 539 gAExpect(rsubRe) 540 541 // On B, create a plain sub now. We should get nothing. 542 clientSend("SUB baz 2\r\nPING\r\n") 543 clientExpect(pongRe) 544 545 expectNothing(t, gA) 546 } 547 548 func TestGatewayErrorOnRSentFromOutbound(t *testing.T) { 549 server.GatewayDoNotForceInterestOnlyMode(true) 550 defer server.GatewayDoNotForceInterestOnlyMode(false) 551 552 ob := testDefaultOptionsForGateway("B") 553 sb := runGatewayServer(ob) 554 defer sb.Shutdown() 555 556 for _, test := range []struct { 557 name string 558 proto string 559 }{ 560 {"RS+", "RS+"}, 561 {"RS-", "RS-"}, 562 } { 563 t.Run(test.name, func(t *testing.T) { 564 gA := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 565 defer gA.Close() 566 567 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 568 gASend("PING\r\n") 569 gAExpect(pongRe) 570 571 gASend(fmt.Sprintf("%s foo bar\r\n", test.proto)) 572 expectDisconnect(t, gA) 573 }) 574 } 575 } 576 577 func TestGatewaySystemConnectionAllowedToPublishOnGWPrefix(t *testing.T) { 578 sc := createSuperCluster(t, 2, 2) 579 defer sc.shutdown() 580 581 o := sc.clusters[1].opts[1] 582 url := fmt.Sprintf("nats://sys:pass@%s:%d", o.Host, o.Port) 583 nc, err := nats.Connect(url) 584 if err != nil { 585 t.Fatalf("Error on connect: %v", err) 586 } 587 defer nc.Close() 588 589 reply := nats.NewInbox() 590 sub, err := nc.SubscribeSync(reply) 591 if err != nil { 592 t.Fatalf("Error on subscribe: %v", err) 593 } 594 if err := nc.PublishRequest("$SYS.REQ.SERVER.PING", reply, nil); err != nil { 595 t.Fatalf("Failed to send request: %v", err) 596 } 597 for i := 0; i < 4; i++ { 598 if _, err := sub.NextMsg(time.Second); err != nil { 599 t.Fatalf("Expected to get a response, got %v", err) 600 } 601 } 602 } 603 604 func TestGatewayTLSMixedIPAndDNS(t *testing.T) { 605 server.SetGatewaysSolicitDelay(5 * time.Millisecond) 606 defer server.ResetGatewaysSolicitDelay() 607 608 // Run this test extra times to make sure not flaky since it 609 // on solicit time. 610 for i := 0; i < 10; i++ { 611 t.Run("", func(t *testing.T) { 612 confA1 := createConfFile(t, []byte(` 613 listen: 127.0.0.1:-1 614 server_name: A1 615 gateway { 616 name: "A" 617 listen: "127.0.0.1:-1" 618 tls { 619 cert_file: "./configs/certs/server-iponly.pem" 620 key_file: "./configs/certs/server-key-iponly.pem" 621 ca_file: "./configs/certs/ca.pem" 622 timeout: 2 623 } 624 } 625 cluster { 626 listen: "127.0.0.1:-1" 627 }`)) 628 srvA1, optsA1 := RunServerWithConfig(confA1) 629 defer srvA1.Shutdown() 630 631 confA2Template := ` 632 listen: 127.0.0.1:-1 633 server_name: A2 634 gateway { 635 name: "A" 636 listen: "localhost:-1" 637 tls { 638 cert_file: "./configs/certs/server-cert.pem" 639 key_file: "./configs/certs/server-key.pem" 640 ca_file: "./configs/certs/ca.pem" 641 timeout: 2 642 } 643 } 644 cluster { 645 listen: "127.0.0.1:-1" 646 routes [ 647 "nats://%s:%d" 648 ] 649 }` 650 confA2 := createConfFile(t, []byte(fmt.Sprintf(confA2Template, 651 optsA1.Cluster.Host, optsA1.Cluster.Port))) 652 srvA2, optsA2 := RunServerWithConfig(confA2) 653 defer srvA2.Shutdown() 654 655 checkClusterFormed(t, srvA1, srvA2) 656 657 // Create a GW connection to cluster "A". Don't use the helper since we need verification etc. 658 o := DefaultTestOptions 659 o.Port = -1 660 o.ServerName = "B1" 661 o.Gateway.Name = "B" 662 o.Gateway.Host = "127.0.0.1" 663 o.Gateway.Port = -1 664 665 tc := &server.TLSConfigOpts{} 666 tc.CertFile = "./configs/certs/server-cert.pem" 667 tc.KeyFile = "./configs/certs/server-key.pem" 668 tc.CaFile = "./configs/certs/ca.pem" 669 tc.Timeout = 2.0 670 tlsConfig, err := server.GenTLSConfig(tc) 671 if err != nil { 672 t.Fatalf("Error generating TLS config: %v", err) 673 } 674 tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert 675 tlsConfig.RootCAs = tlsConfig.ClientCAs 676 677 o.Gateway.TLSConfig = tlsConfig.Clone() 678 679 rurl, _ := url.Parse(fmt.Sprintf("nats://%s:%d", optsA2.Gateway.Host, optsA2.Gateway.Port)) 680 remote := &server.RemoteGatewayOpts{Name: "A", URLs: []*url.URL{rurl}} 681 remote.TLSConfig = tlsConfig.Clone() 682 o.Gateway.Gateways = []*server.RemoteGatewayOpts{remote} 683 684 srvB := RunServer(&o) 685 defer srvB.Shutdown() 686 687 waitForOutboundGateways(t, srvB, 1, 10*time.Second) 688 waitForOutboundGateways(t, srvA1, 1, 10*time.Second) 689 waitForOutboundGateways(t, srvA2, 1, 10*time.Second) 690 691 // Now kill off srvA2 and force serverB to connect to srvA1. 692 srvA2.Shutdown() 693 694 // Make sure this works. 695 waitForOutboundGateways(t, srvB, 1, 30*time.Second) 696 }) 697 } 698 } 699 700 func TestGatewayAdvertiseInCluster(t *testing.T) { 701 server.GatewayDoNotForceInterestOnlyMode(true) 702 defer server.GatewayDoNotForceInterestOnlyMode(false) 703 704 ob1 := testDefaultOptionsForGateway("B") 705 ob1.Cluster.Name = "B" 706 ob1.Cluster.Host = "127.0.0.1" 707 ob1.Cluster.Port = -1 708 sb1 := runGatewayServer(ob1) 709 defer sb1.Shutdown() 710 711 gA := createGatewayConn(t, ob1.Gateway.Host, ob1.Gateway.Port) 712 defer gA.Close() 713 714 gASend, gAExpect := setupGatewayConn(t, gA, "A", "B") 715 gASend("PING\r\n") 716 gAExpect(pongRe) 717 718 ob2 := testDefaultOptionsForGateway("B") 719 ob2.Cluster.Name = "B" 720 ob2.Cluster.Host = "127.0.0.1" 721 ob2.Cluster.Port = -1 722 ob2.Routes = server.RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", ob1.Cluster.Port)) 723 ob2.Gateway.Advertise = "srvB:7222" 724 sb2 := runGatewayServer(ob2) 725 defer sb2.Shutdown() 726 727 checkClusterFormed(t, sb1, sb2) 728 729 buf := gAExpect(infoRe) 730 si := &server.Info{} 731 json.Unmarshal(buf[5:], si) 732 var ok bool 733 for _, u := range si.GatewayURLs { 734 if u == "srvB:7222" { 735 ok = true 736 break 737 } 738 } 739 if !ok { 740 t.Fatalf("Url srvB:7222 was not found: %q", si.GatewayURLs) 741 } 742 743 ob3 := testDefaultOptionsForGateway("B") 744 ob3.Cluster.Name = "B" 745 ob3.Cluster.Host = "127.0.0.1" 746 ob3.Cluster.Port = -1 747 ob3.Routes = server.RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", ob1.Cluster.Port)) 748 ob3.Gateway.Advertise = "srvB:7222" 749 sb3 := runGatewayServer(ob3) 750 defer sb3.Shutdown() 751 752 checkClusterFormed(t, sb1, sb2, sb3) 753 754 // Since it is the save srvB:7222 url, we should not get an update. 755 expectNothing(t, gA) 756 757 // Now shutdown sb2 and make sure that we are not getting an update 758 // with srvB:7222 missing. 759 sb2.Shutdown() 760 expectNothing(t, gA) 761 } 762 763 func TestGatewayAuthTimeout(t *testing.T) { 764 for _, test := range []struct { 765 name string 766 setAuth bool // 767 wait time.Duration 768 }{ 769 {"auth not explicitly set", false, 2500 * time.Millisecond}, 770 {"auth set", true, 500 * time.Millisecond}, 771 } { 772 t.Run(test.name, func(t *testing.T) { 773 ob := testDefaultOptionsForGateway("B") 774 if test.setAuth { 775 ob.Gateway.AuthTimeout = 0.25 776 } 777 sb := RunServer(ob) 778 defer sb.Shutdown() 779 780 sa := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 781 defer sa.Close() 782 783 gAExpect := expectCommand(t, sa) 784 785 dstInfo := checkInfoMsg(t, sa) 786 if dstInfo.Gateway != "B" { 787 t.Fatalf("Expected to connect to %q, got %q", "B", dstInfo.Gateway) 788 } 789 790 // Don't send our CONNECT and we should be disconnected due to auth timeout. 791 time.Sleep(test.wait) 792 gAExpect(errRe) 793 expectDisconnect(t, sa) 794 }) 795 } 796 } 797 798 func TestGatewayFirstPingGoesAfterConnect(t *testing.T) { 799 server.GatewayDoNotForceInterestOnlyMode(true) 800 defer server.GatewayDoNotForceInterestOnlyMode(false) 801 802 ob := testDefaultOptionsForGateway("B") 803 // For this test, we want the first ping to NOT be disabled. 804 ob.DisableShortFirstPing = false 805 // Also, for this test increase auth_timeout so that it does not disconnect 806 // while checking... 807 ob.Gateway.AuthTimeout = 10.0 808 sb := RunServer(ob) 809 defer sb.Shutdown() 810 811 sa := createGatewayConn(t, ob.Gateway.Host, ob.Gateway.Port) 812 defer sa.Close() 813 814 gASend, gAExpect := sendCommand(t, sa), expectCommand(t, sa) 815 dstInfo := checkInfoMsg(t, sa) 816 if dstInfo.Gateway != "B" { 817 t.Fatalf("Expected to connect to %q, got %q", "B", dstInfo.Gateway) 818 } 819 820 // Wait and we should not be receiving a PING from server B until we send 821 // a CONNECT. We need to wait for more than the initial PING, so cannot 822 // use expectNothing() helper here. 823 buf := make([]byte, 256) 824 sa.SetReadDeadline(time.Now().Add(2 * time.Second)) 825 if n, err := sa.Read(buf); err == nil { 826 t.Fatalf("Expected nothing, got %s", buf[:n]) 827 } 828 829 // Now send connect and INFO 830 cs := fmt.Sprintf("CONNECT {\"verbose\":%v,\"pedantic\":%v,\"tls_required\":%v,\"gateway\":%q}\r\n", 831 false, false, false, "A") 832 gASend(cs) 833 gASend(fmt.Sprintf("INFO {\"gateway\":%q}\r\n", "A")) 834 835 // We should get the first PING 836 gAExpect(pingRe) 837 }