Commit Graph

198 Commits

Author SHA1 Message Date
Derek Collison
c5b98f5c79 Make server shutdown an atomic and check inside unsubscribe to avoid unnecessary work.
Signed-off-by: Derek Collison <derek@nats.io>
2023-09-26 17:53:58 -07:00
Ivan Kozlovic
579ee3b828 [FIXED] LeafNode: TLS Handshake when remote does not have a tls{} block
If a leafnode remote configuration does not have a tls{} block but
connect to a hub that requires TLS, the handshake between the two
servers will fail. A simple workaround is to add in the remote
configuration an empty tls{} block.

This issue was introduced in v2.10.0 due to some refactoring in
order to support compression.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-09-19 19:50:50 -06:00
Derek Collison
49c30b6d2f Merge branch 'main' into dev
Signed-off-by: Derek Collison <derek@nats.io>
2023-08-31 15:52:00 -07:00
Ivan Kozlovic
9a9e84ea5c Fix leaf connection missing LS+ sometimes
Signed-off-by: Waldemar Quevedo <wally@nats.io>
2023-08-31 10:06:02 -07:00
Waldemar Quevedo
740e5ddc37 Add some jitter to leafnode remotes reconnect
Signed-off-by: Waldemar Quevedo <wally@nats.io>
2023-08-15 07:36:37 -07:00
Derek Collison
11e5e049cf Merge branch 'main' into dev 2023-07-11 14:36:10 -07:00
Derek Collison
353d543c16 When a queue subscriber was updated multiple times over a leafnode connection we added in more shadow subscriptions which could become zombies when the connection went away.
In a case where a leafnode server had multiple queue subscribers on the same queue group, the hub server would add in multiple shadow subs. These subs would not be properly cleaned up and could lead to stale connections being associated with them.

Signed-off-by: Derek Collison <derek@nats.io>
2023-07-10 21:03:47 -07:00
Ivan Kozlovic
afb5086f17 [CHANGED] LeafNode: remotes from same server binding to same hub account
Previously, the server would reject a second remote leafnode connection
from the same server if it was binding to the same account on the hub
even if the remote was using different local accounts.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-06-20 18:44:52 -06:00
Ivan Kozlovic
7ff0ea449a Fixed issues with leafnode compression negotiation
When a server would send an asynchronous INFO to a remote server
it would incorrectly contain compression information that could
cause issues with one side thinking that the connection should
be compressed while the other side was not.

It also caused the authentication timer to be incorrectly set
which would cause a disconnect.

Signed-off-by: Ivan Kozlovic <ijkozlovic@gmail.com>
2023-06-09 13:20:44 -06:00
Derek Collison
f342f6a758 Merge branch 'main' into dev 2023-06-05 14:13:18 -07:00
Artem Seleznev
27a8b96ee3 different panic fixes
Signed-off-by: Artem Seleznev <seleznyov.artyom@gmail.com>
2023-06-02 13:19:22 +03:00
Ivan Kozlovic
86a319a50e [FIXED] LeafNode: data race during validation and create leafnode
The issue really was that the test was sharing remote options. The
way options are used is not ideal since we reference the user provided
options (but it is relied upon now in many tests and possibly users
setups). The other side of the issue was that when no local account
is specified in a "remote" specification, we set it to the global
account, but that was done when creating the leafnode object (when
soliciting), which in the case of the test could race with the
second server doing the validation.

In this PR we move the setting to global account during the validation,
but also fixed the tests to not share the remote options configuration
slice between the two servers.

Resolves #4191

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-05-24 17:52:54 -06:00
Ivan Kozlovic
ab281cc7e6 Updates based on PR feedback
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-05-16 10:18:11 -06:00
Ivan Kozlovic
67498af2dc [ADDED] LeafNode: Support for s2 compression
This is similar to PR #4115 but for LeafNodes.
Compression mode can be set on both side (the accept and in remotes).
```
leafnodes {
   port: 7422
   compression: s2_best
   remotes [
       {
         url: "nats://host2:74222"
         compression: s2_better
       }
   ]
}
```
Possible modes are similar than for routes (described in PR #4115),
except that when not defined we default to `s2_auto`.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-05-15 17:42:39 -06:00
Derek Collison
4175e4ee9c Merge branch 'main' into dev 2023-05-06 09:55:34 -07:00
Derek Collison
80db7a22ab Optimizations for large single hub account leafnode fleets.
Added a leafnode lock to allow better traversal without copying of large leafnodes in a single hub account.

Signed-off-by: Derek Collison <derek@nats.io>
2023-05-05 13:14:49 -07:00
Ivan Kozlovic
840c264f45 Cleanup use of s.opts and fixed some lock (deadlock/inversion) issues
One should not access s.opts directly but instead use s.getOpts().
Also, server lock needs to be released when performing an account
lookup (since this may result in server lock being acquired).
A function was calling s.LookupAccount under the client lock, which
technically creates a lock inversion situation.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-05-03 14:09:02 -06:00
Ivan Kozlovic
0a02f2121c [ADDED] LeafNode: TLSHandhsakeFirst option
A new field in `tls{}` blocks force the server to do TLS handshake
before sending the INFO protocol.
```
leafnodes {
   port: 7422
   tls {
      cert_file: ...
      ...
      handshake_first: true
   }
   remotes [
       {
         url: tls://host:7423
         tls {
            ...
            handshake_first: true
         }
       }
   ]
}
```
Note that if `handshake_first` is set in the "accept" side, the
first `tls{}` block in the example above, a server trying to
create a LeafNode connection to this server would need to have
`handshake_first` set to true inside the `tls{}` block of
the corresponding remote.

Configuration reload of leafnodes is generally not supported,
but TLS certificates can be reloaded and the support for this
new field was also added.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-05-01 16:41:51 -06:00
Derek Collison
e158c46884 Merge branch 'main' into dev 2023-04-30 17:37:47 -07:00
Derek Collison
c15cc0054a When a fleet of leafnodes are isolated (not routed but using same cluster) we could do better at optimizing how we update the other leafnodes.
Signed-off-by: Derek Collison <derek@nats.io>
2023-04-30 17:08:16 -07:00
Ivan Kozlovic
bd1b7b8d55 Cleanup use of s.opts and fixed some lock (deadlock/inversion) issues
One should not access s.opts directly but instead use s.getOpts().
Also, server lock needs to be released when performing an account
lookup (since this may result in server lock being acquired).
A function was calling s.LookupAccount under the client lock, which
technically creates a lock inversion situation.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-04-03 09:32:28 -06:00
Ivan Kozlovic
105237cba8 [ADDED] Multiple routes and ability to have per-account routes
New configuration fields:
```
cluster {
   ...
   pool_size: 5
   accounts: ["A", "B"]
}
```

The configuration `pool_size` in the example above means that this
server will create 5 routes to a remote server, assuming that that
server has the same `pool_size` setting.

Accounts (which are not part of the `accounts[]` configuration)
are assigned a specific route in this pool, and this will be the
same route on all servers in the cluster.

Accounts that are defined in the `accounts` field will each have
a dedicated route connection. This will allow suppression of the
account name in some of the route protocols, reducing bytes transmitted
which may increase performance.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2023-04-03 09:32:25 -06:00
Derek Collison
6507a913b3 Merge branch 'main' into dev 2023-03-01 05:05:41 -08:00
Jeremy Saenz
26f241cb62 Updated LEAFZ names to use remoteServer name/id and added is_spoke 2023-02-28 18:09:24 -08:00
Derek Collison
7bd7cda021 Merge branch 'main' into dev 2023-02-28 15:17:24 -08:00
Jeremy Saenz
9d4a603aaf Update LEAFZ to include leafnode server/connection name 2023-02-28 14:20:18 -08:00
Neil Twigg
3b29ce470d Tweak logic for sending leaf node subscription updates 2023-01-12 17:32:46 +00:00
Derek Collison
e21f77ece0 Merge branch 'main' into dev 2023-01-05 10:32:38 -08:00
Derek Collison
ad53d455f8 When migrating leaders off a server when the leafnode is not connected, also ensure leaders can not return until reconnected.
Signed-off-by: Derek Collison <derek@nats.io>
2023-01-05 08:02:50 -08:00
Ivan Kozlovic
2250f10093 Merge branch 'main' into dev 2022-11-03 13:01:35 -06:00
Ivan Kozlovic
91c84c03c2 [FIXED] LeafNode: possible duplicate messages in complex setup
This is specific to setup described [here](https://github.com/nats-io/nats-server/issues/3191#issuecomment-1296974382)
and does not require JetStream to be reproduced. The added test
reproduces the above setup but without JetStream enabled in
the accounts.

Each cluster has a leafnode for a given account to the other
cluster. The accounts import/export a subject. When a consumer
is connected to cluster "B" and the producer is on cluster "A"
there was a duplicate message. Due to shadow subscription caused
by the import/export rules, an additional subscription was
sent across the leafnode.

Resolves #3191

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-11-03 12:34:01 -06:00
Ivan Kozlovic
346770973c Merge branch 'main' into dev
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-10-27 17:16:05 -06:00
Derek Collison
9c5ae6baef Existing subs would be sent to leafnodes even though pub perms should disallow.
If the LS+ gets through we debug that it was denied, but also fixed it so that does not happen.

Signed-off-by: Derek Collison <derek@nats.io>
2022-10-27 12:31:57 -07:00
Ivan Kozlovic
a32a78d890 [CHANGED] Reduced default logging for JetStream setup over a leafnode
Changed logging from [INF] to [DBG]

Signed-off-by: Derek Collison derek@nats.io
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-10-17 10:44:21 -06:00
Ivan Kozlovic
d90854a45f Merge pull request #3341 from nats-io/go_1_19
Move to Go 1.19, remote io/util, fix data race and a flapper
2022-08-05 12:49:06 -06:00
Ivan Kozlovic
3c9a7cc6e5 Move to Go 1.19, remote io/util, fix data race and a flapper
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-08-05 09:55:37 -06:00
Ivan Kozlovic
7baf7bd887 [ADDED] LeafNode: Support for a SignatureHandler in remote config
This would allow in embedded use-cases where the user does not
have the ability to use a credentials file. Instead, a signature
callback is specified and invoked by the server sends the CONNECT
protocol. The user is responsible to provide the JWT and sign the
nonce.

Resolves #3331

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-08-04 16:59:09 -06:00
Ivan Kozlovic
d84d9f8288 Use specific boolean for a leaf test instead of using leafNodeEnabled
A test TestJetStreamClusterLeafNodeSPOFMigrateLeaders was added at
some point that needed the remotes to stop (re)connecting. It made
use of existing leafNodeEnabled that was used for GW/Leaf interest
propagation races to disable the reconnect, but that may not be
the best approach since it could affect users embedding servers
and adding leafnodes "dynamically".

So this PR introduced a specific boolean specific for that test.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-08-04 10:00:11 -06:00
Derek Collison
28ccaa4371 Direct get across a leafnode using cross domain mappings to a queue subscriber did not work.
The interest moved across the leafnode would be for the mapping, and not the actual qsub.
So when received if we did detect that we are mapped and do not have a queue filter present make sure to ignore.
This will allow queue subscriber processing on the local server that received the message from the leafnode.

Signed-off-by: Derek Collison <derek@nats.io>
2022-08-03 20:21:28 -07:00
Derek Collison
c14fda51e7 Direct access to JetStream resources would be affected if across a leafnode that was down.
This allows a solciting leafnode config to ask that any JetStream cluster assets that are a current leader have the leader stepdown.

Signed-off-by: Derek Collison <derek@nats.io>
2022-07-05 12:35:09 -07:00
Derek Collison
e6479dafd2 Close leafnode connection when same cluster name detected
Signed-off-by: Derek Collison <derek@nats.io>
2022-06-30 15:34:22 -07:00
Ivan Kozlovic
b5c9583ee2 Reject configuration with value below 2.8.0
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-04-07 12:49:34 -06:00
Ivan Kozlovic
7fa2676353 Fixed comment typos and some rewording
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-04-07 09:22:51 -06:00
Ivan Kozlovic
9e6f965913 [ADDED] LeafNode min_version new option
If set, a server configured to accept leafnode connections will
reject a remote server whose version is below that value. Note
that servers prior to v2.8.0 are not sending their version
in the CONNECT protocol, which means that anything below 2.8.0
would be rejected.

Configuration example:
```
leafnodes {
    port: 7422
    min_version: 2.8.0
}
```
The option is a string and can have the "v" prefix:
```
min_version: "v2.9.1"
```
Note that although suffix such as `-beta` would be accepted,
only the major, minor and update are used for the version comparison.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-04-06 18:40:33 -06:00
Matthias Hanel
9a2da9ed8c Adding denies $KV.>/$OBJ.> along leaf connections on differing domain (#2916)
* Adding denies $KV.>/$OBJ.> along leaf connections on differing domain

Signed-off-by: Matthias Hanel <mh@synadia.com>
2022-03-09 13:17:59 -05:00
Ivan Kozlovic
85b3f8a7fd Gateways: data race when setting first ping timer
This was introduced when fixing #2881. The call to setFirstPingTimer
needed to be done under the client's lock.

Moved setFirstPingTimer from a server receiver to a client receiver.
The only reason it was a server receiver is because we need the
server options, but c.srv is always set when invoking this function,
so we will get the server from c.srv in that function now.

Related to #2881

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-03-04 19:55:07 -07:00
Ivan Kozlovic
1e53d81cb3 [FIXED] LeafNode: queue sub interest not properly sent to new LN
In complex situations, queue members count across various servers
may not be properly accounted for when sent to a new leafnode
connection.

The new test TestLeafNodeQueueGroupWithLateLNJoin has a drawing
of such setup, when after LN1 joined, and then queue members
were removed with 1 left, LN1 was told that there was no
more interest, so message published to LN1 would not reach
the remaining queue sub connected to LN2.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
2022-03-04 17:03:06 -07:00
Matthias Hanel
3e8b66286d Js leaf deny (#2693)
Along a leaf node connection, unless the system account is shared AND the JetStream domain name is identical, the default JetStream traffic (without a domain set) will be denied.

As a consequence, all clients that wants to access a domain that is not the one in the server they are connected to, a domain name must be specified.
Affected from this change are setups where: a leaf node had no local JetStream OR the server the leaf node connected to had no local JetStream. 
One of the two accounts that are connected via a leaf node remote, must have no JetStream enabled.
The side that does not have JetStream enabled, will loose JetStream access and it's clients must set `nats.Domain` manually.

For workarounds on how to restore the old behavior, look at:
https://github.com/nats-io/nats-server/pull/2693#issuecomment-996212582

New config values added:
`default_js_domain` is a mapping from account to domain, settable when JetStream is not enabled in an account.
`extension_hint` are hints for non clustered server to start in clustered mode (and be usable to extend)
`js_domain` is a way to set the JetStream domain to use for mqtt.

Signed-off-by: Matthias Hanel <mh@synadia.com>
2021-12-16 16:53:20 -05:00
Matthias Hanel
581dfb27d0 hitting an account limit left an outgoing leaf node conn in bad state (#2715)
since no error was traced or the connection closed, subscriptions where
not forwarded

Signed-off-by: Matthias Hanel <mh@synadia.com>
2021-11-30 17:48:07 -05:00
Phil Pennock
fc6df0fbbc Redact URLs before logging or returning in error (#2643)
* Redact URLs before logging or returning in error

This does not affect strings which failed to parse, and in such a scenario
there's a mix of "which evil" to accept; we can't sanely find what should be
redacted in those cases, so we leave them alone for debugging.

The JWT library returns some errors for Operator URLs, but it rejects URLs
which contain userinfo, so there can't be passwords in those and they're safe.

Fixes #2597

* Test the URL redaction auxiliary functions

* End-to-end tests for secrets in debug/trace

Create internal/testhelper and move DummyLogger there, so it can be used from
the test/ sub-dir too.

Let DummyLogger optionally accumulate all log messages, not just retain the
last-seen message.

Confirm no passwords logged by TestLeafNodeBasicAuthFailover.

Change TestNoPasswordsFromConnectTrace to check all trace messages, not just the
most recent.

Validate existing trace redaction in TestRouteToSelf.

* Test for password in solicited route reconnect debug
2021-10-27 12:44:59 -04:00