bifrost

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 25, 2022 License: Apache-2.0

README

Bifrost

Introduction

Bifrost is a peer-to-peer communications engine with pluggable transports:

  • Cross-platform: supports web browsers, servers, desktop, mobile, ...
  • Efficient: multiplex many simultaneous streams over a single Link.
  • Encryption: identify, authenticate, and encrypt each Link between peers.
  • Flexible: use multiple transports, protocols, simultaneously.
  • Meshing: supports multi-hop routing to a desired target peer w/ circuits.
  • PubSub: publish/subscribe channels with pluggable implementations.
  • Robust: uses Quic for reliable connections over lossy transports.

Bifrost provides ControllerBus controllers and directives to manage links between peers, transports, routing, and other higher-level processes. It has extensive and flexible configuration. Connections are created on-demand.

Overview

Bifrost is designed around the following core concepts:

  • Peer: a routable process or device with a keypair.
  • Transport: protocol or hardware for communication Link between two Peer.
  • Link: a connection between two peers over a Transport.
  • Stream: channel of data between two Peer with a protocol type.
  • PubSub: at-least-once delivery of messages to named topics.
  • Route: a multi-hop path through the network between two Peer.
  • Circuit: a type of Link which implements a multi-hop connection.

Integrates and interoperates with other networking, pubsub, RPC libraries like libp2p, noise, drpc, and nats.

In practice, this makes it easy to mix-and-match communications hardware and software in a configurable and reproducible way, often hot-loading support for new functionality without requiring a restart of the entire process.

The network simulator, testbed, and in-proc transport can be used to write end-to-end tests as Go unit tests. The mock transports use identical code to the real transports, and appear the same to the application code.

EntityGraph exposes the internal state representation of Bifrost to visualizers and instrumentation via a graph-based inter-connected entity model.

A Link is a packet stream between two Peer. Links are created by Transports, which are associated with a local private keypair.

Transports are responsible for handshaking their identity and providing stream multiplexing, encryption, and ordering. The Bifrost codebase contains common implementations for packet-based and stream-based transports, based primarily on the quic-go implementation of the Quic UDP protocol.

The Transport controller creates a HandleStream directive with the protocol and peer info. The appropriate controller for the protocol responds to the directive and handles the incoming stream. This decouples the communication from the app.

PubSub

A PubSub is a controller that supports topic-based at-least-once message delivery to a network of interested peers.

Nats is also supported as PubSub protocol. There is also a simpler "floodsub" implementation, and support for libp2p pubsub algorithms.

Examples

Bifrost can be used as either a Go library or a command-line / daemon.

GO111MODULE=on go install -v github.com/aperturerobotics/bifrost/cmd/bifrost

Access help by adding the "-h" tag or running "bifrost help."

As a basic example, launch the daemon:

bifrost daemon --write-config --hold-open-links --pubsub floodsub --api-listen :5110 --udp-listen :5112

YAML Configuration

An example of a ConfigSet in YAML format for the daemon: bifrost_daemon.yaml:

# Start a UDP listener on port 5112.
my-udp:
  config:
    listenAddr: :5112
  id: bifrost/udp/1
  revision: 1

# Use the floodsub driver for PubSub.
pubsub:
  config: {}
  id: bifrost/floodsub/1
  revision: 1

Client CLI

Most Bifrost functionality is exposed on the client CLI and GRPC API:

  • Mount a peer by loading a private key into the daemon.
  • Forward incoming streams with a protocol ID to a multiaddress
  • Proxy incoming connections to a listener to a remote peer
  • Open a stream with a remote peer and a given protocol ID
  • Accept a stream for a local peer with a given protocol ID

The client CLI has the following help output:

bifrost client command [command options] [arguments...]

COMMANDS:
   local-peers           returns local peer info
   identify              Private key will be loaded with a peer controller
   subscribe             Subscribe to a pubsub channel with a private key or mounted peer and publish base64 w/ newline delim from stdin.
   forward               Protocol ID will be forwarded to the target multiaddress
   accept                Single incoming stream with Protocol ID will be accepted
   dial                  Single outgoing stream with Protocol ID will be dialed
   listen                Listen on the multiaddress and forward the connection to a remote stream.
   controller-bus, cbus  ControllerBus system sub-commands.

With the above operations, all stream handling and interaction with the network is exposed to the API and command line. Some examples:

  # Note: you can edit bifrost_daemon.yaml to change settings.
  # Once the daemon configuration exists, you can now just run:
  bifrost daemon

  # While the command is executing, the private key will be attached.
  bifrost client identify --peer-priv priv-key.pem

  # While the command is executing, a forwarding controller will be running.
  # Protocol ID will be forwarded to the target multiaddress
  # Handles HandleMountedStream directives by contacting the target.
  # HTTP can be easily proxied through an encrypted stream this way.
  bifrost client forward \
    --peer-id <agent-id> \
    --protocol-id /x/myproto \
    --target /ip4/127.0.0.1/tcp/8000

  # While the command is executing, a proxying controller will be running.
  # Protocol ID will be proxied from the listen multiaddress to the target peer.
  # Calls OpenStream to build a stream from <source-peer-id> to <target-peer-id>.
  # HTTP can be easily proxied through an encrypted stream this way.
  bifrost client listen \
    --peer-id <target-peer-id> \
    --from-peer-id <source-peer-id> \
    --protocol-id /x/myproto \
    --listen /ip4/127.0.0.1/tcp/8001

  # Wait for a stream to be opened to the mounted peer with the protocol ID /x/myproto
  # Standard output is the incoming data stream, standard input is the outgoing data stream.
  # Standard error is used for logging.
  bifrost client accept \
    --local-peer-id <peer-id> \
    --protocol-id /x/myproto 

  # Establish a stream.
  # Standard output is the incoming data stream, standard input is the outgoing data stream.
  # Standard error is used for logging.
  bifrost client dial \
    --peer-id <target-peer-id> \
    --local-peer-id <local-peer-id> \
    --protocol-id /x/myproto

Support

Bifrost is built & supported by Aperture Robotics, LLC.

Please open a GitHub issue with any questions / issues.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL