ssbc / multiserver

A single interface that can work with multiple protocols, and multiple transforms of those protocols (eg, security layer)
MIT License
104 stars 28 forks source link

scopes #19

Closed dominictarr closed 5 years ago

dominictarr commented 6 years ago

first some context, (maybe this can become documentation?)

multiserver is designed around plugins. there are two types of plugins, transports and transforms. Then transports make a connection to something, and transforms change something about it, such as encrypting and authenticating it, or compressing it. so far, we've just used the shs transform plugin to encrypt everything.

multiserver gives you a convienent handle to run multiple servers, with multiple protocol versions at the same time. that's why it's called multiserver. So, you can have multiple servers. We started to add that, but then we realized we needed something more: scopes. servers are useful for lots of things, but sometimes you don't want everyone to connect to them (we care about privacy, and would rather someone connect via tor, but local clients can use net), and other times, you know that someone can't connect to them anyway, so we want to avoid telling them about it. (we are running our server on a laptop on wifi, without a stable ip address. so we don't want to advertise our address publically, but maybe we do for another multiserver that is running on cjdns or tor etc)

Each transport plugin now takes a scope option, which is a string: the name of that scope. when a plugin is created, the plugin is passed the scope it will have. eg, Net({host: ..., port: ..., scope: 'public'}) plugins also have a scope() method, which just returns the scope it was configured with, or defaults to. so Plugin({scope: X}).scope() === X

When you call multiserver.stringify(scope) it then returns an address for that scope. If scope is "private" then public plugins are allowed.

Okay I think I understand all that now. but why isn't my websocket server attaching? hmm...

dominictarr commented 6 years ago

Okay, I figured it out, I had to read all the code, but I figured it out. it's mostly in secret handshake.

To add a new transport you pass a function to sbot.multiserver.transport(function create (config) { return MultiServerPlugin(config) })

This tripped my up because I didn't realize the signature for create had changed since the earlier PR i made.

Also, now plugins are fully driven by the configuration - it's not enough to just enable the plugin, you must also configure the protocol.

dominictarr commented 6 years ago

my local config now looks like this:

    "incoming": {
      "unix": [{ "scope": "local", "transform": "noauth" }],
      "ws": [{"scope": "local", "port": 8989, "transform": "shs"}]
    }

hmm, but why doesn't noauth show if I do sbot getAddress local? aha, that plugin doesn't actually handle configuration consistently:

https://github.com/ssbc/scuttlebot/blob/master/index.js#L200-L202

It takes the full sbot config, not the configuration for the noauth plugin... and secondly, there is a quirk that it doesn't return a connection string unless it's server configuration option is enabled: https://github.com/ssbc/multiserver/blob/master/plugins/unix-socket.js#L83 Although, it still creates a server, even if it doesn't have the server option set, it just doesn't expose the noauth connection string.

dominictarr commented 6 years ago

Oh, and also... I realized that my websocket server, which I thought was coming from ssb-ws plugin wasn't actually coming from there at all.

Actually the signature of create is now multiserver.transport({name: <proto>, create: function (config) { ... }) I fixed that and then commented out the ws built into scuttlebot/index.js and now it's working as I expected.

Some of these problems were just me not understanding how it worked now, but others are actual bugs.

The configuration thing works well for being able to create special cases, such as the noauth transform, which operates strictly on unix sockets, but is not applied to ws, for instance. but I worry that it's much harder to override arrays (since position in the array becomes significant)...

Maybe the solution is scope first? "incoming": {"local": {"ws": {...}, "unix": {...}} but I'm gonna leave that as a discussion for now and focus on clarifying how the current system works. removing inconsistencies, writing tests, etc.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.