Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Also known as "The Gossip Refactor", the CONN (Connections Over Numerous Networks) plugin replaces the old gossip
plugin, covering all its use cases. CONN has these responsibilities:
~/.ssb/conn.json
)Prerequisites:
secret-stack@^6.2.0
npm install --save ssb-conn
Add this plugin to ssb-server like this:
var createSsbServer = require('ssb-server')
.use(require('ssb-onion'))
.use(require('ssb-unix-socket'))
.use(require('ssb-no-auth'))
.use(require('ssb-plugins'))
.use(require('ssb-master'))
+ .use(require('ssb-conn'))
.use(require('ssb-replicate'))
.use(require('ssb-friends'))
// ...
Now you should be able to access the muxrpc APIs under ssb.conn
and ssb.gossip
, see next section.
Under ssb.conn.*
you can call any of these APIs in your local peer.
API | Type | Description |
---|---|---|
remember(addr, data?) | sync | Stores (in cold storage) connection information about a new peer, known by its multiserver address addr and additional optional data (as an object). |
forget(addr) | sync | Removes (from cold storage) connection information about a peer known by its multiserver address addr . |
dbPeers() | sync | Returns an Iterable of ConnDB entries known at the moment. Does not reactively update once the database is written to. |
connect(addr, data?) | async | Connects to a peer known by its multiserver address addr , and stores additional optional data (as an object) during its connection lifespan. |
disconnect(addr) | async | Disconnects a peer known by its multiserver address addr . |
peers() | source | A pull-stream that emits an array of all ConnHub entries whenever any connection updates (i.e. changes it state: connecting, disconnecting, connected, etc). |
stage(addr, data?) | sync | Registers a suggested connection to a new peer, known by its multiserver address addr and additional optional data (as an object). |
unstage(addr) | sync | Unregisters a suggested connection the peer known by its multiserver address addr . |
stagedPeers() | source | A pull-stream that emits an array of all ConnStaging entries whenever any staging status updates (upon stage() or unstage()). |
start() | sync | Triggers the start of the connection scheduler in CONN. |
stop() | sync | Stops the CONN scheduler if it is currently active. |
ping() | duplex | A duplex pull-stream for periodically pinging with peers, fully compatible with ssb.gossip.ping . |
db() | sync | Returns the instance of ConnDB currently in use. |
hub() | sync | Returns the instance of ConnHub currently in use. |
staging() | sync | Returns the instance of ConnStaging currently in use. |
query() | sync | Returns the instance of ConnQuery currently in use. |
An "entry" is a (tuple) array of form:
[addr, data]
where:
addr
is a multiserver address (a string that follows some rules)data
is an object with additional information about the peer (fields marked 🔷 are important and often used, fields marked 🔹 come from CONN, fields marked 🔸 are ad-hoc and added by various other modules, and fields suffixed with ?
are not always present):🔷 key: string
: the peer's public key / feedId
🔷 state?: 'connecting' | 'connected' | 'disconnecting'
: (only from peers()
) the peer's current connection status
🔷 type?: string
: what type of peer this is; it can be any string, but often is either 'lan'
, 'bt'
, 'pub'
, 'room'
, 'room-endpoint'
, 'dht'
🔹 inferredType?: 'bt' | 'lan' | 'dht' | 'internet' | 'tunnel'
: (only from peers()
) when there is no type
field, e.g. when a new and unknown peer initiates a client connection with us (as a server), then ConnHub makes a guess what type it is
🔹 birth?: number
: Unix timestamp for when this peer was added to ConnDB
🔹 stateChange?: number
: Unix timestamp for the last time the field state
was changed; this is stored in ConnDB
🔹 hubBirth?: number
: Unix timestamp for when this peer was added to ConnHub
🔹 hubUpdated?: number
: Unix timestamp for when this data object was last updated in ConnHub
🔹 stagingBirth?: number
: Unix timestamp for when this peer was added to ConnStaging
🔹 stagingUpdated?: number
: Unix timestamp for when this data object was last updated in ConnStaging
🔹 autoconnect?: boolean
: indicates whether this peer should be considered for connection in the scheduler
🔹 failure?: number
: typically in ConnDB, this is the number of connection errors since the last successful connection
🔹 duration?: object
: typically in ConnDB, this is a statistics object to measure the duration of connection with this peer
🔹 ping?: object
: typically in ConnDB, this is statistics object of various ping health measurements
🔹 pool?: 'db' | 'hub' | 'staging'
: this only appears in ConnQuery APIs, and indicates from which pool (ConnDB or ConnHub or ConnStaging) was this peer picked
🔸 name?: string
: a nickname for this peer, when there isn't an ssb-about name
🔸 room?: string
: (only if type = 'room-endpoint'
) the public key of the room server where this peer is in
🔸 onlineCount?: number
: (only if type = 'room'
) the number of room endpoints currently connected to this room
The following gossip plugin APIs are available once you install CONN, but these will emit deprecation warnings and might behave slightly different than the old gossip plugin:
API | Type |
---|---|
ssb.gossip.peers() | sync |
ssb.gossip.get(p) | sync |
ssb.gossip.connect(p) | async |
ssb.gossip.disconnect(p) | async |
ssb.gossip.changes() | source |
ssb.gossip.add(p, source) | sync |
ssb.gossip.remove(p) | sync |
ssb.gossip.ping() | duplex |
ssb.gossip.reconnect() | sync |
ssb.gossip.enable() | sync |
ssb.gossip.disable() | sync |
If you want to use the new CONN infrastructure but preserve the same gossip behavior as before, use ssb-legacy-conn
which tries to mirror the gossip plugin, even its log messages.
Under the hood, CONN is based on three "pools" of peers:
ConnDB contains metadata on stable servers and peers that have been successfully connectable. ConnHub is the central API that allows us to issue new connections and disconnections, as well as to track the currently active connections. ConnStaging is an in-memory ephemeral storage of new possible connections that the user might want to approve or disapprove.
Then, ConnQuery has access to those three pools, and provides utilities to query, filter, and sort connections across all those pools.
ConnScheduler is an opinionated (⚠️) plugin that utilizes ConnQuery to select peers to connect to, then schedules connections to happen via ConnHub, as well as schedules disconnections if necessary. Being opinionated, CONN provides an easy way of replacing the default scheduler with your own scheduler, see instructions below.
There is also a Gossip Compatibility plugin, implementing all the legacy APIs, so that other SSB plugins that call these APIs will continue to function as normal.
When you install the ssb-plugin, it will actually setup three plugins:
[conn, connScheduler, gossip]
The default scheduler is roughly the same as the legacy ssb-gossip plugin, with some opinions removed and others added. The scheduler has two parts: discovery setup on startup, and periodic connections/disconnections.
Discovery setup:
remember
themstage
themPeriodic connections/disconnections:
In none of the cases above shall we connect to a peer that we block. In addition to the above, the following actions happen automatically every (approximately) 1 second:
autoconnect=false
Other events:
To experiment with your own opinions for establishing connections, you can make your own ConnScheduler, which is just a typical SSB plugin. You can write in the traditional style (like other SSB plugins), or with OOP decorators. The example below uses OOP decorators.
Here is the basic shape of the scheduler:
import {plugin, muxrpc} from 'secret-stack-decorators';
@plugin('1.0.0')
module.exports = class ConnScheduler {
constructor(ssb, config) {
// basic setup here
this.ssb = ssb;
}
@muxrpc('sync')
public start = () => {
// this is called when the scheduler should begin scheduling connections
// You have access to CONN core here:
const query = this.ssb.conn.query();
this.ssb.conn.stage(addr);
this.ssb.conn.disconnect(addr);
// ...
}
@muxrpc('sync')
public stop = () => {
// this is called when the scheduler should cancel its jobs
}
}
Note that the name of the plugin must be exactly ConnScheduler
(or connScheduler
) and it must have the methods start() and stop(), because the CONN core will try to use your scheduler under those names. The rest of the contents of the ConnScheduler class are up to you, you can use private methods, etc.
When you're done building your scheduler, you can export it together with CONN core and the gossip compatibility plugin like this:
var CONN = require('ssb-conn/core')
var Gossip = require('ssb-conn/compat')
var ConnScheduler = require('./my-scheduler')
module.exports = [CONN, ConnScheduler, Gossip]
That array is a valid secret-stack plugin which you can .use()
in ssb-server.
The legacy gossip plugin is one of the oldest parts of the SSB stack in Node.js, and it contained several old opinions. It wasn't designed with multiserver in mind, so it made a lot of assumptions that peers have host
/port
fields. Nowadays with Bluetooth and other unusual modes of connectivity, that assumption breaks down often.
The gossip plugin also did not have the concept of "staging", which is useful for ephemeral connections (LAN or Bluetooth) in spaces that may have many strangers. So the gossip plugin tended to connect as soon as possible to any peer discovered.
Also, since the gossip plugin was a monolith, it had all these concerns (cold persistence, in-memory tracking of current connections, ephemeral peers, scheduling, old and new style addresses) squashed into one file, making it hard and brittle to change the code.
The objectives with CONN were to:
[address, dataObject]
MIT
FAQs
SSB plugin for establishing and managing peer connections
The npm package ssb-conn receives a total of 69 weekly downloads. As such, ssb-conn popularity was classified as not popular.
We found that ssb-conn demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.