This page permanently redirects to gemini://gemini.complete.org/nncp-concepts/.

NNCP Concepts

This page describes some basic concepts of NNCP[1].

=> 1: /nncp/

What NNCP can do

NNCP is a versatile communications layer; think of it as an Asynchronous Communication[2] version of ssh. See my NNCP[3] page for ideas and links. NNCP can effectively route over anything from AWS instances to USB sticks and CD-Rs, and supports file transport and remote execution.

=> 2: /asynchronous-communication/ | 3: /nncp/

Everything in NNCP is protected by end-to-end encryption and good security.

A key property of an NNCP network is that the two endpoints of communication need not be online simultaneously.

Basic Concepts of Packets

NNCP works with "packets". A packet is something that carries data. It is stored as a file in a queue on disk in your local NNCP instance. A packet can be an arbitrary size; from just a few bytes to multiple TB.

So, the NNCP commands are concerned with:

NNCP operations

I will go into the details of how packets are processed in a bit, but first I need to give you some background on the big picture of the concepts these packets provide. After that, I'll explain how these concepts map to the three categories of commands I outlined above.

The basic operations within NNCP are file transmission and remote command execution.

File transmission

With file transmission, you can either send a file to a remote node (using nncp-file[4]) or request a remote node send a file to you (nncp-freq[5]). For instance:

=> 4: https://nncp.mirrors.quux.org/nncp_002dfile.html | 5: https://nncp.mirrors.quux.org/nncp_002dfreq.html

This command creates a packet, encrypted to remotenode, using `/bin/bash` as the content.  It adds some metadata specifying that the file should be named `bash2` on the remote end.  It writes this packet as a file in the local queue bound for transmission to remotenode.

The remotenode's configuration specifies whether this node is allowed to send it files, and if so, where to put them.

To request a file from the remote node:

This command creates a (very small) packet, encrypted to remotenode, saying "Hey, send me README.txt". remotenode checks to see if the request is authorized, and if so, what directory to find the file in. If it finds one, it does something very similar to the nncp-file command above, generating a reply packet that is basically a file transmission.

Remote execution

Let's say that on node bob, I authorized node alice to run a command I call "tarextract", defined like this:

If you think this has a parallel to ssh's `authorized_keys`, you're absolutely right.

Now on alice, I can say this:

So what does nncp-exec[6] do? It reads stdin and encrypts it to node bob. It adds metadata, saying it's requesting the "tarextract" command, and adding two arguments to it (the -C /var/local/backups). It writes this all into a packet file in the transmission queue for bob.

=> 6: https://nncp.mirrors.quux.org/nncp_002dexec.html

When bob processes the packet, it spins up /usr/bin/tar -xpf - -C /var/local/backups, piping to it the data that had originally been piped to nncp-exec.

Email can be sent over NNCP; for instance, to use tools originating in the UUCP[7] days and which still work today, one might pipe an email message to nncp-exec mailserver rmail foo@example.com. The NNCP manual has details on how to set this up.

=> 7: /uucp/

The commands

Now let's talk about the NNCP commands and how they relate to the operations we've identified so far.

Commands to create packets

We've already covered the three main commands to create packets: nncp-file, nncp-freq, and nncp-exec. All of these commands take some sort of input -- a file, a command to run, or just the name of a file to request -- and create a packet, encrypted with the destination's public key, which they write into the outgoing queue for the destination's node. (Except for when we route via an intermediary; more on that below.)

Commands to transport packets

Now, there are three main ways to transport packets between NNCP nodes:

=> 8: /syncthing/

Let's take a look at these in more detail.

NNCP over a mountable filesystem

Since NNCP packets are fundamentally just files, these files can be transported to the remote over anything that can store... well, files. nncp-xfer[9] does just that. You can specify a destination node, and it will extract packets destined for that node from the NNCP queue, and copy (or move) them to the target path. It makes a simple directory structure on the target path.

=> 9: https://nncp.mirrors.quux.org/nncp_002dxfer.html

Then, at the remote, you run nncp-xfer in receive mode. It does just the opposite; scans the target path for packets meant for it, and moves those into the incoming queue for later processing.

Since the directory tree is very basic, it can be just about anything. A USB stick is common, or a shared folder with Syncthing or Dropbox, or a mounted S3 folder -- whatever you like.

You can, of course, use the same filesystem to both send and receive packets from a given node.

Over a tar-like stream

Sometimes it is handy to be able to pipe a stream to somewhere. The target might be a tape drive, a process that burns the stream to a DVD+R, an ssh pipe to a remote, or all sorts of other things you can pipe stuff to in Unix.

That's what nncp-bundle[10] does. Conceptually, it's very similar to nncp-xfer; it's just that the interchange format is a stream (or single file) instead of a directory tree populated with files. nncp-bundle in transmission mode generates a stream for a remote, filled with all the packets in the transmission queue for that node. In receive mode, it receives a stream, and copies any packets meant for the local node into its incoming queue.

=> 10: https://nncp.mirrors.quux.org/nncp_002dbundle.html

Over the network

Most people will probably have a transmission over the network at some point. Although all NNCP nodes are peers, in TCP, you need someone to be the server and someone to be a client. So, the server is nncp-daemon and the client is nncp-call or nncp-caller.

Why two clients? Both do conceptually the same thing, and speak the same protocol. The difference is that nncp-call is designed to be run as a standalone command ("connect to the server for node foo RIGHT NOW"), while nncp-caller is designed to be a long-running service, that either maintains long-lasting connections to the remote nncp-daemon, or periodically establishes connections to it, or both. Functionally they are the same.

The network communication with NNCP is quite versatile. It is bidirectional, can send packets in an order given by their user-defined prioritization, can resume interrupted transfers, and can even auto-detect peers on the local network. It is also, of course, encrypted and authenticated.

More fun with transports

My page at Tunneling NNCP over other transports[11] shows some more advanced ways to integrate these fundamental commands with things like ssh, Syncthing[12], and tor.

=> 11: /tunneling-nncp-over-other-transports/ | 12: /syncthing/

Commands to process packets

So far, I've talked a lot about queues. The commands that create packets (nncp-file, freq, and exec) put the packets in an outbound queue. There is also an inbound queue. The commands to transport packets exchange data from those queues. That leaves us with one more piece: how do we handle packets in the inbound queue?

That's the job of nncp-toss[13]. It literally processes packets from incoming queues. It verifies their integrity, decrypts them, and handles them as needed: running commands for packets generated by nncp-exec, depositing files sent by nncp-file, answering requests from nncp-freq, and also routing packets on to their destination (more on that below).

=> 13: https://nncp.mirrors.quux.org/nncp_002dtoss.html

nncp-toss can be run as a standalone command, from a cron job, or as a daemon with the -cycle parameter.

There is also a command nncp-stat that shows you the status of all your queues, incoming and outgoing.

Next Steps

Take a look at my other NNCP[14] resources, particularly Getting Started with NNCP[15].

=> 14: /nncp/ | 15: /getting-started-with-nncp/

Advanced Routing

You can skip this section for now; it covers some more advanced topics.

Thus far, I have made an assumption: that when you send a packet from node alice to node bob, alice and bob are "directly" connected. That is, they can speak to each other, or you can move a USB stick between them, or some such scenario.

Now imagine this scenario: you have three nodes. Alice can communicate with bob, and bob can communicate with charlie, but alice and charlie have no way of communicating directly. Wouldn't it be nice to use bob as an intermediary between alice and charlie? In fact, with NNCP, you can do just that!

For instance, on alice you could say:

Proxy Information
Original URL
gemini://gemini.complete.org/nncp-concepts
Status Code
Success (20)
Meta
text/gemini; charset=utf-8; lang=en; size=16490
Capsule Response Time
976.841711 milliseconds
Gemini-to-HTML Time
2.519111 milliseconds

This content has been proxied by September (ba2dc).