Skip to content

Commit ed56b57

Browse files
wyfooteffahi
andauthored
feat: avoid duplicate autoconnection attempt (#1742)
* feat: avoid duplicate autoconnection attempt Gossip autoconnection could result in two nodes attempting to connect to each other concurrently. To fix this issue, only one node initiate the connection now. The selection criteria is arbitrary but deterministic, currently the greater zid of both. * refactor: extract autoconnect node selection in a dedicated function * refactor: add a configuration option for autoconnection * revert: revert JSON config formatting * fix: lint * feat: add an "always" autoconnection strategy * docs: document DEFAULT_CONFIG.json5 * Update DEFAULT_CONFIG.json5 Co-authored-by: Oussama Teffahi <[email protected]> * feat: make strategy dependent on the connected node * Update DEFAULT_CONFIG.json5 Co-authored-by: Oussama Teffahi <[email protected]> * Update DEFAULT_CONFIG.json5 Co-authored-by: Oussama Teffahi <[email protected]> * fix: remove dead code * feat: introduce target-dependent value * fix: lint * fix: remove dead code * fix: remove debug code --------- Co-authored-by: Oussama Teffahi <[email protected]>
1 parent 69f810d commit ed56b57

File tree

16 files changed

+539
-112
lines changed

16 files changed

+539
-112
lines changed

Cargo.lock

Lines changed: 104 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,44 @@
1414
[workspace]
1515
resolver = "2"
1616
members = [
17-
"commons/zenoh-buffers",
18-
"commons/zenoh-codec",
19-
"commons/zenoh-collections",
20-
"commons/zenoh-config",
21-
"commons/zenoh-core",
22-
"commons/zenoh-crypto",
23-
"commons/zenoh-keyexpr",
24-
"commons/zenoh-macros",
25-
"commons/zenoh-protocol",
26-
"commons/zenoh-result",
27-
"commons/zenoh-shm",
28-
"commons/zenoh-sync",
29-
"commons/zenoh-task",
30-
"commons/zenoh-util",
31-
"commons/zenoh-runtime",
32-
"examples",
33-
"io/zenoh-link",
34-
"io/zenoh-link-commons",
35-
"io/zenoh-links/zenoh-link-quic/",
36-
"io/zenoh-links/zenoh-link-serial",
37-
"io/zenoh-links/zenoh-link-tcp/",
38-
"io/zenoh-links/zenoh-link-tls/",
39-
"io/zenoh-links/zenoh-link-udp/",
40-
"io/zenoh-links/zenoh-link-unixsock_stream/",
41-
"io/zenoh-links/zenoh-link-ws/",
42-
"io/zenoh-links/zenoh-link-unixpipe/",
43-
"io/zenoh-links/zenoh-link-vsock/",
44-
"io/zenoh-transport",
45-
"plugins/zenoh-backend-example",
46-
"plugins/zenoh-plugin-example",
47-
"plugins/zenoh-backend-traits",
48-
"plugins/zenoh-plugin-rest",
49-
"plugins/zenoh-plugin-storage-manager",
50-
"plugins/zenoh-plugin-trait",
51-
"zenoh",
52-
"zenoh-ext",
53-
"zenoh-ext/examples",
54-
"zenohd",
17+
"commons/zenoh-buffers",
18+
"commons/zenoh-codec",
19+
"commons/zenoh-collections",
20+
"commons/zenoh-config",
21+
"commons/zenoh-core",
22+
"commons/zenoh-crypto",
23+
"commons/zenoh-keyexpr",
24+
"commons/zenoh-macros",
25+
"commons/zenoh-protocol",
26+
"commons/zenoh-result",
27+
"commons/zenoh-shm",
28+
"commons/zenoh-sync",
29+
"commons/zenoh-task",
30+
"commons/zenoh-util",
31+
"commons/zenoh-runtime",
32+
"examples",
33+
"io/zenoh-link",
34+
"io/zenoh-link-commons",
35+
"io/zenoh-links/zenoh-link-quic/",
36+
"io/zenoh-links/zenoh-link-serial",
37+
"io/zenoh-links/zenoh-link-tcp/",
38+
"io/zenoh-links/zenoh-link-tls/",
39+
"io/zenoh-links/zenoh-link-udp/",
40+
"io/zenoh-links/zenoh-link-unixsock_stream/",
41+
"io/zenoh-links/zenoh-link-ws/",
42+
"io/zenoh-links/zenoh-link-unixpipe/",
43+
"io/zenoh-links/zenoh-link-vsock/",
44+
"io/zenoh-transport",
45+
"plugins/zenoh-backend-example",
46+
"plugins/zenoh-plugin-example",
47+
"plugins/zenoh-backend-traits",
48+
"plugins/zenoh-plugin-rest",
49+
"plugins/zenoh-plugin-storage-manager",
50+
"plugins/zenoh-plugin-trait",
51+
"zenoh",
52+
"zenoh-ext",
53+
"zenoh-ext/examples",
54+
"zenohd",
5555
]
5656
exclude = ["ci/nostd-check", "ci/valgrind-check"]
5757

@@ -61,11 +61,11 @@ version = "1.2.1"
6161
repository = "https://github.com/eclipse-zenoh/zenoh"
6262
homepage = "http://zenoh.io"
6363
authors = [
64-
"kydos <[email protected]>",
65-
"Julien Enoch <[email protected]>",
66-
"Olivier Hécart <[email protected]>",
67-
"Luca Cominardi <[email protected]>",
68-
"Pierre Avital <[email protected]>",
64+
"kydos <[email protected]>",
65+
"Julien Enoch <[email protected]>",
66+
"Olivier Hécart <[email protected]>",
67+
"Luca Cominardi <[email protected]>",
68+
"Pierre Avital <[email protected]>",
6969
]
7070
edition = "2021"
7171
license = "EPL-2.0 OR Apache-2.0"
@@ -144,9 +144,9 @@ ringbuffer-spsc = "0.1.9"
144144
rsa = "0.9"
145145
rustc_version = "0.4.1"
146146
rustls = { version = "0.23.13", default-features = false, features = [
147-
"logging",
148-
"tls12",
149-
"ring",
147+
"logging",
148+
"tls12",
149+
"ring",
150150
] }
151151
rustls-native-certs = "0.8.0"
152152
rustls-pemfile = "2.1.3"
@@ -155,9 +155,10 @@ rustls-pki-types = "1.8.0"
155155
schemars = { version = "0.8.21", features = ["either"] }
156156
secrecy = { version = "0.8.0", features = ["serde", "alloc"] }
157157
serde = { version = "1.0.210", default-features = false, features = [
158-
"derive",
158+
"derive",
159159
] } # Default features are disabled due to usage in no_std crates
160160
serde_json = "1.0.128"
161+
serde_with = "3.12.0"
161162
serde_yaml = "0.9.34"
162163
static_init = "1.0.3"
163164
stabby = "36.1.1"
@@ -182,7 +183,7 @@ unzip-n = "0.1.2"
182183
url = "2.5.2"
183184
urlencoding = "2.1.3"
184185
uuid = { version = "1.10.0", default-features = false, features = [
185-
"v4",
186+
"v4",
186187
] } # Default features are disabled due to usage in no_std crates
187188
validated_struct = "2.1.0"
188189
vec_map = "0.8.2"

DEFAULT_CONFIG.json5

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@
138138
/// or different values for router, peer or client mode (e.g. autoconnect: { router: [], peer: ["router", "peer"] }).
139139
/// Each value is a list of: "peer", "router" and/or "client".
140140
autoconnect: { router: [], peer: ["router", "peer"], client: ["router"] },
141+
/// Strategy for autoconnection, mainly to avoid nodes connecting to each other redundantly.
142+
/// Possible options are:
143+
/// - "always": always attempt to autoconnect, may result in redundant connection which will then be closed.
144+
/// - "greater-zid": attempt to connect to another node only if its own zid is greater than the other's.
145+
/// If both nodes use this strategy, only one will attempt the connection.
146+
/// This strategy may not be suited if one of the nodes is not reachable by the other one, for example
147+
/// because of a private IP.
148+
/// Accepts a single value (e.g. autoconnect: "always") which applies whatever node would be auto-connected to,
149+
/// or different values for router and/or peer depending on the type of node detected
150+
/// (e.g. autoconnect_strategy : { "to-router": "always", "to-peer": "greater-zid" }),
151+
/// or different values for router or peer mode
152+
/// (e.g. autoconnect_strategy : { peer: { "to-router": "always", "to-peer": "greater-zid" } }).
153+
autoconnect_strategy: { peer: { "to-router": "always", "to-peer": "always" } },
141154
/// Whether or not to listen for scout messages on UDP multicast and reply to them.
142155
listen: true,
143156
},
@@ -161,6 +174,19 @@
161174
/// or different values for router or peer mode (e.g. autoconnect: { router: [], peer: ["router", "peer"] }).
162175
/// Each value is a list of: "peer" and/or "router".
163176
autoconnect: { router: [], peer: ["router", "peer"] },
177+
/// Strategy for autoconnection, mainly to avoid nodes connecting to each other redundantly.
178+
/// Possible options are:
179+
/// - "always": always attempt to autoconnect, may result in redundant connection which will then be closed.
180+
/// - "greater-zid": attempt to connect to another node only if its own zid is greater than the other's.
181+
/// If both nodes use this strategy, only one will attempt the connection.
182+
/// This strategy may not be suited if one of the nodes is not reachable by the other one, for example
183+
/// because of a private IP.
184+
/// Accepts a single value (e.g. autoconnect: "always") which applies whatever node would be auto-connected to,
185+
/// or different values for router and/or peer depending on the type of node detected
186+
/// (e.g. autoconnect_strategy : { "to-router": "always", "to-peer": "greater-zid" }),
187+
/// or different values for router or peer mode
188+
/// (e.g. autoconnect_strategy : { peer: { "to-router": "always", "to-peer": "greater-zid" } }).
189+
autoconnect_strategy: { peer: { "to-router": "always", "to-peer": "always" } },
164190
},
165191
},
166192

commons/zenoh-config/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ json5 = { workspace = true }
3434
num_cpus = { workspace = true }
3535
serde = { workspace = true, features = ["default"] }
3636
serde_json = { workspace = true }
37+
serde_with = { workspace = true }
3738
serde_yaml = { workspace = true }
3839
validated_struct = { workspace = true, features = ["json5", "json_get"] }
3940
zenoh-core = { workspace = true }

0 commit comments

Comments
 (0)