What is Ratnet?

Ratnet is a library that allows applications to communicate using an onion-routed and flood-routed message bus. All communications are encrypted end-to-end by the library itself.

Ratnet is completely modular, meaning that the interactions of all significant components of the system are defined with interfaces, and are therefore interchangeable. Network transports, cryptosystems, connection policies, and the ratnet nodes themselves can all be customized and swapped around dynamically.

The Ratnet library provides two working implementations for each of these interfaces:

It's also easy to implement your own replacement for any or all of these components. Multiple transport modules can be used at once, and different cryptosystems can be used for the Onion-routing and for the content encryption, if desired.

Ratnet provides input and output channels for your application to send and receive binary messages in clear text, making it very easy to interact with.

What's a Connection Policy?

You caught me, I made that term up. In ratnet, Transports are responsible for physically making and receiving connections and that's it. Nodes are basically message queues with some key management and special knowledge about when to encrypt things (and the Cryptosystem is the method they would use to do that). But none of those things actually starts a connection and moves the data around. That is the responsibility of the Connection Policy. Think of it as a script that controls a Node and any number of different Transports.

We provide two very simple connection policies:

  1. Server - This just opens up a port and listens on it.
  2. Polling - After a delay, this will connect to every Peer and exchange messages.

In real-world usage, you're very likely to want to implement your own version of Polling (via the Policy interface), so you can tune retry logic and so on. We will be doing a lot more development and experimentation with new policies in the future.

Examples

Fully Working Demo App

Hushcom is a fully working demo app that implements IRC-like chat functionality with a client and a server.

The hushcom client application is a good reference for how to set up a client using the Poll connection policy.

The hushcomd server application is a good reference for how to set up a server using the Server connection policy.

Making a Node

Make a QL-Database-Backed Node, which saves states to disk:

    // QLDB Node Mode
    node := qldb.New(new(ecc.KeyPair), new(ecc.KeyPair))
    node.BootstrapDB(dbFile)

Or, make a RAM-Only Node, which won't write anything to the disk:

    // RamNode Mode:
    node := ram.New(new(ecc.KeyPair), new(ecc.KeyPair))

The KeyPairs passed in as arguments are just used to determine which cryptosystem should be used for the Onion-Routing (first argument) and for the Content Encryption (second argument).

Setup Transports and Policies

    transportPublic := https.New("cert.pem", "key.pem", node, true)
    transportAdmin := https.New("cert.pem", "key.pem", node, true)
    node.SetPolicy(
        policy.NewServer(transportPublic, listenPublic, false),
        policy.NewServer(transportAdmin, listenAdmin, true))

    log.Println("Public Server starting: ", listenPublic)
    log.Println("Control Server starting: ", listenAdmin)

    node.Start()

Handle messages coming from the network

    go func() {
        for {
            msg := <-node.Out()
            if err := HandleMsg(msg); err != nil {
                log.Println(err.Error())
            }
        }
    }()

Send messages to the network

Blocking Send:

    message := api.Msg{Name: "destname1", IsChan: false}
    message.Content = bytes.NewBufferString(testMessage1)
    node.In() <- message

Non-Blocking Send:

        select {
        case node.Out() <- message:
            //fmt.Println("sent message", msg)
        default:
            //fmt.Println("no message sent")
        }   

Additional Documentation

Related Projects

Authors and Contributors