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  }