Bondy Connect
Skip to content

Bridge Relay Configuration Reference ​

A bridge relay (Bondy Edge) connects one Bondy node, as a client, to a remote Bondy router, sharing a subset of procedures and topics between the two over a dedicated connection — distinct from cluster peer connections, which join nodes into the same cluster. Each bridge is named ($name) and configured independently; a node can run several bridges to several remote routers at once.

Enabling a bridge ​

bridge.$name :: on|off
Default = offSince v1.0.0-rc.1

Enables or disables the named bridge.

bridge.$name.endpoint :: string
Default = '127.0.0.1:18092'Since v1.0.0-rc.1

The host:port of the remote Bondy router's bridge relay listener (see Accepting bridges below for the listener side).

bridge.$name.transport :: tcp|tls
Default = tcpSince v1.0.0-rc.1

The transport for the connection to the remote router.

TLS ​

bridge.$name.tls.certfile :: path
Default = '/client/keycert.pem'Since v1.0.0-rc.1

Client certificate for the bridge connection, when bridge.$name.transport = tls.

bridge.$name.tls.keyfile :: path
Default = '/client/key.pem'Since v1.0.0-rc.1

Client private key for the bridge connection.

bridge.$name.tls.cacertfile :: path
Default = '/client/cacert.pem'Since v1.0.0-rc.1

CA certificate used to verify the remote router, when bridge.$name.tls.verify = verify_peer.

bridge.$name.tls.verify :: verify_peer|verify_none
Default = verify_noneSince v1.0.0-rc.1

Whether the bridge verifies the remote router's certificate against bridge.$name.tls.cacertfile.

bridge.$name.tls.hostname_verification :: wildcard|none
Default = wildcardSince v1.0.0-rc.1

Whether hostname verification accepts a wildcard certificate matching bridge.$name.endpoint's host.

bridge.$name.tls.versions :: string
Default = 1.3Since v1.0.0-rc.1

Comma-separated TLS protocol versions: 1.2, 1.3 or both.

Connection behaviour ​

bridge.$name.parallelism :: integer
Default = 1Since v1.0.0-rc.1

Number of TCP connections to open to the remote router for this bridge.

bridge.$name.connect_timeout :: duration_time_units
Default = 5sSince v1.0.0-rc.1

How long to wait for the initial connection to the remote router before giving up.

bridge.$name.network_timeout :: duration_time_units
Default = 30sSince v1.0.0-rc.1

Drops the connection once the bridge has been waiting this long for the local network to come back up, checked by counting the host's non-loopback IPv4 interfaces. Set to infinity to disable — useful for local development with no real network connection, where this check would otherwise fire spuriously.

bridge.$name.idle_timeout :: duration_time_units
Default = 24hSince v1.0.0-rc.1

Drops the connection once it has carried no message, in either direction, for this long. PING and PONG messages do not count. The bridge client logs "Shutting down client due to inactivity." with reason idle_timeout, and its supervisor starts a new client. Set to infinity to keep a silent connection open.

When this value is not longer than bridge.$name.ping.idle_timeout, the connection is dropped this long after it becomes idle, so ping.idle_timeout plus this value after the last message.

bridge.$name.hibernate :: never|idle|always
Default = idleSince v1.0.0-rc.1

Controls when the bridge connection process hibernates to reclaim memory: idle hibernates after a period of inactivity, always after every message, never disables it.

bridge.$name.max_frame_size :: integer|infinity
Default = 4194304Since v1.0.0-rc.1

The largest frame, in bytes, the bridge is meant to accept. The value is a positive integer or infinity. The default, 4194304 (4 MiB), matches the frame limits of Bondy's other carriers.

0 is rejected. Use infinity for no limit.

Not enforced in this release

Bondy validates and stores this value, but the bridge connection does not apply it. The connection reads length-prefixed frames with no size limit taken from this key.

Keepalive ​

bridge.$name.ping :: on|off
Default = onSince v1.0.0-rc.1

Whether the edge probes a silent connection with PING control messages. This affects client (edge) initiated pings only; the remote router's pings are always answered regardless.

bridge.$name.ping.idle_timeout :: duration_time_units
Default = 20sSince v1.0.0-rc.1

How long the connection may carry no message before it becomes idle. An idle connection is probed with PING when bridge.$name.ping is on. It is dropped at bridge.$name.idle_timeout, whether ping is on or off.

bridge.$name.ping.timeout :: duration_time_units
Default = 10sSince v1.0.0-rc.1

How long a probe waits for its answer before counting as a failed attempt.

bridge.$name.ping.max_attempts :: integer
Default = 3Since v1.0.0-rc.1

How many unanswered probes mean a dead connection. After this many, the bridge client closes the connection and stops. Its supervisor then starts a new client, which dials again with a fresh retry budget. The supervisor restarts the client whether or not bridge.$name.reconnect is on.

Reconnection ​

bridge.$name.reconnect :: on|off
Default = onSince v1.0.0-rc.1

Whether the bridge retries after a failed attempt, waiting the next backoff delay each time. A failed attempt is a connect error such as econnrefused, timeout or ehostunreach, a connection lost before a session opens, or a session the remote router refuses with an ABORT. The bridge retries an ABORT whatever its reason, such as a realm not yet provisioned on the remote router or a key it does not know, so the bridge connects once the remote router accepts it. Any other connect error stops the bridge. With off, the first failed attempt stops it. A stopped bridge reports stopped in bondy.router.bridge.status and stays stopped until bondy.router.bridge.start starts it again.

bridge.$name.reconnect.max_retries :: integer
Default = 100Since v1.0.0-rc.1

The retry budget: the number of failed attempts after which the bridge client exits. The budget has no time limit. Its supervisor then starts a new client, which dials again with a fresh budget.

These events count against the budget:

  • A connection attempt that fails with timeout, econnrefused, econnreset, ehostdown, enotconn, etimedout, enetdown, ehostunreach or enetunreach. Any other connect error stops the client at once.
  • A connection that is lost before a session opens on it.

When a connection that had an open session is lost, the client closes the socket and dials again at once, with a fresh budget. When the budget is spent, or when bridge.$name.reconnect is off, the client stops. Each bridge client is a permanent child of its supervisor, so the supervisor starts a new client with a new connection and a new budget. When its clients restart more than 20 times within 60 seconds, the supervisor itself stops, together with every bridge client on the node.

bridge.$name.reconnect.backoff.type :: jitter|normal
Default = jitterSince v1.0.0-rc.1

Backoff strategy between reconnection attempts: jitter randomises the delay to avoid many bridges reconnecting in lockstep, normal doesn't.

bridge.$name.reconnect.backoff.min :: duration_time_units
Default = 5sSince v1.0.0-rc.1

Initial (and minimum) delay between reconnection attempts.

bridge.$name.reconnect.backoff.max :: duration_time_units
Default = 60sSince v1.0.0-rc.1

Maximum delay between reconnection attempts, once backoff has grown.

Realm mapping ​

Each bridge shares one or more realms with the remote router; $id names one such mapping within the bridge.

bridge.$name.realm.$id.uri :: string
Default = N/ASince v1.0.0-rc.1

The realm URI, matching on both this node and the remote router.

bridge.$name.realm.$id.authid :: string
Default = N/ASince v1.0.0-rc.1

The identity the bridge authenticates as on the remote router for this realm, using cryptosign — see below for where the signing itself happens.

Delegated signing ​

The bridge never holds the realm's private key directly (except for local testing — see the warning below). Instead, signing a cryptosign challenge is delegated to one of:

bridge.$name.realm.$id.cryptosign.pubkey :: string
Default = N/ASince v1.0.0-rc.1

The public key the remote router verifies the challenge signature against.

bridge.$name.realm.$id.cryptosign.procedure :: string
Default = N/ASince v1.0.0-rc.1

Not implemented. A bridge configured with this key fails to start. Use cryptosign.exec or cryptosign.privkey_env_var.

bridge.$name.realm.$id.cryptosign.exec :: string
Default = N/ASince v1.0.0-rc.1

An external executable that performs the signing. Bondy runs it directly, never through a shell, with two arguments: the public key and the raw challenge bytes. It sends the program's standard output, unchanged, as the signature, and the remote router decodes that signature as hexadecimal, so the program has to print the hex-encoded Ed25519 signature and nothing else. The program has to answer within 10 seconds. Bondy also runs it once when the bridge starts, to check that it works.

bridge.$name.realm.$id.cryptosign.privkey_env_var :: string
Default = N/ASince v1.0.0-rc.1

Name of an environment variable holding the hex-encoded Ed25519 private key (the 32-byte seed). Bondy reads the variable when the bridge starts and signs with that key; the bridge fails to start if the variable is unset.

bridge.$name.realm.$id.cryptosign.privkey :: string
Default = N/ASince v1.0.0-rc.1

Testing only

Embeds the hex-encoded private key directly in bondy.conf. This exists for local testing only — use cryptosign.privkey_env_var or cryptosign.exec for anything else, so the private key never has to live in a configuration file.

Sharing procedures and topics ​

bridge.$name.realm.$id.procedure.$pid :: string
Default = N/ASince v1.0.0-rc.1

The value is a match spec: <uri> <match-type> <direction>, where <match-type> is exact, prefix, or wildcard, and <direction> is in, out (the default), or both.

Accepted but not enforced

Bondy validates this key, but the running bridge does not filter procedure sharing by it. The bridge proxies every local registration on the realm to the remote router, whatever this key says and whether or not it is set. Do not rely on it to keep a procedure off the remote router.

bridge.$name.realm.$id.topic.$tid :: string
Default = N/ASince v1.0.0-rc.1

Shares a topic URI pattern between the two routers for this realm, using the same match-spec syntax as above. out subscribes locally and forwards matching events to the remote router, so remote subscribers can receive them; in would do the reverse (subscribing on the remote so local subscribers receive its events).

direction: in has no effect

Only out has an effect. The schema accepts in, and the in half of both, but the bridge logs a warning and does not subscribe on the remote router's side.

Forwarding guarantees ​

These two keys apply to every bridge on the node. They mirror the cluster's router.forward.* keys.

bridge.forward.ack :: on|off
Default = offSince v1.0.0-rc.15

Meant to request acknowledged delivery for messages forwarded over bridges. Bondy accepts and stores this value, but no part of Bondy reads it in this release, so it has no effect.

bridge.forward.retransmission :: on|off
Default = offSince v1.0.0-rc.15

Meant to control retransmission of unacknowledged bridge messages. Accepted and stored, not read: it has no effect in this release.

Accepting bridges ​

The other side of a bridge relay — the socket that accepts inbound connections from edge nodes bridging to this one — is an ordinary listener whose protocol is bridge_relay:

listeners.bridge.transport = tcp
listeners.bridge.protocol  = bridge_relay
listeners.bridge.port      = 18092

The port is the one a bridging node points its own bridge.$name.endpoint at. All the listener-level settings apply — bind address, acceptor pool, connection limits, ping.*, TLS material for a tls transport — plus one key only this protocol reads: listeners.$name.auth_timeout, how long a connected peer router has to authenticate before the connection is dropped (5s if unset). A bridge-relay listener is not available over uds, and declaring services on one is an error — it serves one protocol by definition.

Deprecated bridge.listener.tcp.* renamed tolisteners.bridge_relay_tcp.*since v1.0.0
Deprecated bridge.listener.tls.* renamed tolisteners.bridge_relay_tls.*since v1.0.0

The removed bridge.listener.{tcp,tls}.* keys are no longer read; a file still setting them starts no bridge-relay listener at all. See Migrating from the pre-1.0 keys.

See also ​