Make sure we use correct MSG prefix when mixing between leafnodes and routes.

Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
Derek Collison
2019-05-01 15:08:20 -07:00
parent 628c373299
commit 1d736ccc61
4 changed files with 77 additions and 1 deletions

View File

@@ -2567,6 +2567,8 @@ sendToRoutesOrLeafs:
kind := rt.sub.client.kind
mh := c.msgb[:msgHeadProtoLen]
if kind == ROUTER {
// Router (and Gateway) nodes are RMSG. Set here since leafnodes may rewrite.
mh[0] = 'R'
mh = append(mh, acc.Name...)
mh = append(mh, ' ')
} else {

View File

@@ -40,7 +40,7 @@ var (
const (
// VERSION is the current version for the server.
VERSION = "2.0.0-RC8"
VERSION = "2.0.0-RC9"
// PROTO is the currently supported protocol.
// 0 was the original

View File

@@ -503,6 +503,12 @@ func (s *Server) createLeafNode(conn net.Conn, remote *leafNodeCfg) *client {
url := c.leaf.remote.getCurrentURL()
host, _, _ := net.SplitHostPort(url.Host)
// We need to check if this host is an IP. If so, we probably
// had this advertised to us an should use the configured host
// name for the TLS server name.
if net.ParseIP(host) != nil {
host, _, _ = net.SplitHostPort(c.leaf.remote.RemoteLeafOpts.URL.Host)
}
tlsConfig.ServerName = host
c.nc = tls.Client(c.nc, tlsConfig)

View File

@@ -1831,3 +1831,71 @@ func TestLeafNodeSwitchGatewayToInterestModeOnly(t *testing.T) {
leafSend("PING\r\n")
leafExpect(pongRe)
}
// The MSG proto for routes and gateways is RMSG, and we have an
// optimization that a scratch buffer has RMSG and when doing a
// client we just start at scratch[1]. For leaf nodes its LMSG and we
// rewrite scratch[0], but never reset it which causes protocol
// errors when used with routes or gateways after use to send
// to a leafnode.
// We will create a server with a leafnode connection and a route
// and a gateway connection.
// route connections to simulate.
func TestLeafNodeResetsMSGProto(t *testing.T) {
opts := testDefaultOptionsForLeafNodes()
opts.Cluster.Host = opts.Host
opts.Cluster.Port = -1
opts.Gateway.Name = "lproto"
opts.Gateway.Host = opts.Host
opts.Gateway.Port = -1
opts.Accounts = []*server.Account{server.NewAccount("$SYS")}
opts.SystemAccount = "$SYS"
s := RunServer(opts)
defer s.Shutdown()
lc := createLeafConn(t, opts.LeafNode.Host, opts.LeafNode.Port)
defer lc.Close()
leafSend, leafExpect := setupConn(t, lc)
gw := createGatewayConn(t, opts.Gateway.Host, opts.Gateway.Port)
defer gw.Close()
gwSend, gwExpect := setupGatewayConn(t, gw, "A", "lproto")
gwSend("PING\r\n")
gwExpect(pongRe)
// Now setup interest in the leaf node for 'foo'.
leafSend("LS+ foo\r\nPING\r\n")
leafExpect(pongRe)
// Send msg from the gateway.
gwSend("RMSG $G foo 2\r\nok\r\nPING\r\n")
gwExpect(pongRe)
leafExpect(lmsgRe)
// At this point the gw inside our main server's scratch buffer is LMSG. When we do
// same with a connected route with interest it should fail.
rc := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
defer rc.Close()
checkInfoMsg(t, rc)
routeSend, routeExpect := setupRouteEx(t, rc, opts, "RC")
routeSend("RS+ $G foo\r\nPING\r\n")
routeExpect(pongRe)
// This is for the route interest we just created.
leafExpect(lsubRe)
// Send msg from the gateway.
gwSend("RMSG $G foo 2\r\nok\r\nPING\r\n")
gwExpect(pongRe)
leafExpect(lmsgRe)
// Now make sure we get it on route. This will fail with the proto bug.
routeExpect(rmsgRe)
}