Introducing NDNts, Named Data Networking libraries for the Modern Web

I'm creating a new Named Data Networking (NDN) client library, NDNts. The initial NPM release, v0.0.20191223-beta.1, was uploaded yesterday. This article explains why I'm doing this, and why you should consider using my library.

Motivation

I've been developing Named Data Networking (NDN) for several years. Although my specialty is in the forwarding plane, I occasionally build NDN applications, such as a home surveillance camera. A common ingredient of every NDN application is some sort of client libraries, which provides APIs that allow the application to encode/decode NDN packets and communicate over NDN networks in accordance with the NDN protocol. One of these client libraries is the NDN Common Client Libraries (NDN-CCL), which provide a consistent API across several programming languages.

I adopted ndn-js, the JavaScript variant of NDN-CCL, in several projects, and was unhappy about it:

  • The API feels like Java, not JavaScript.
  • Callbacks everywhere, leading to callback hell.
  • The library inserts over 50 symbols to the browser's global scope, causing name conflicts.
  • All features are bundled into a single file that weighs over 500KB.
  • There's no unit testing for the most part, let alone continuous integration.

ESP8266 Call Button

It's NDN Community Meeting again and this time I'm officially presenting HomeCam at the demo session. I'm the sole presenter of this project. Normally, I have to stay at my table to show my project to the audience. However, I don't want to miss the chance of seeing what others have been doing. To solve this dilemma, I come up with an idea: a call button.

I put a big button on my table. It is labelled as: if I'm not here, press the button to send an Interest. Then, I wear a battery powered light ring on my body. Whenever someone presses the button, it lights up for 15 seconds.

me wearing a light ring at NDNcomm demo session

How It Works

Both the button and the light ring are based on ESP8266. The light ring unit acts as WiFi access point and NDN producer. The button unit acts as WiFi station and NDN consumer. When the button is pressed, the consumer transmits a signed Interest, and the producer turns on the light for 15 seconds after verifying the signature. Since the light ring unit is battery-powered, it enters deep sleep mode if there's no connected WiFi client.

Ubuntu 16.04 NFD Development Machine

I shared how I setup my NFD development machine in 2017. Back then, NFD's minimum system requirement is Ubuntu 14.04 so my virtual machine is 14.04 as well. In May 2018, ndn-cxx started requiring Ubuntu 16.04, so it's time for a rebuild.

Vagrantfile for NFD Development in Ubuntu 16.04

Here's my new Vagrantfile:

$vmname = "devbox"
$sshhostport = 2222

$deps = <<SCRIPT
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get dist-upgrade -yq
apt-get install -yq git build-essential gdb valgrind libssl-dev libsqlite3-dev libboost-all-dev pkg-config libpcap-dev doxygen graphviz python-sphinx python-pip
pip install sphinxcontrib-doxylink sphinxcontrib-googleanalytics
SCRIPT

Vagrant.configure(2) do |config|
  config.vm.box = "bento/ubuntu-16.04"
  config.vm.network :forwarded_port, guest: 22, host: $sshhostport, id: "ssh"
  config.vm.provider "virtualbox" do |vb|
    vb.name = $vmname
    vb.memory = 6144
    vb.cpus = 8
  end
  config.vm.provision "deps", type: "shell", inline: $deps
  config.vm.provision "hostname", type: "shell", inline: "echo " + $vmname + " > /etc/hostname; hostname " + $vmname
  config.vm.provision "sshpvtkey", type: "file", source: "~/.ssh/id_rsa", destination: ".ssh/id_rsa"
  config.vm.provision "sshpubkey", type: "file", source: "~/.ssh/id_rsa.pub", destination: ".ssh/id_rsa.pub"
  config.vm.provision "sshauth", type: "shell", inline: "cd .ssh; cat id_rsa.pub >> authorized_keys"
  config.vm.provision "gitconfig", type: "file", source: "~/.gitconfig", destination: ".gitconfig"
end

Differences from 2017

NFD on Windows 10 WSL

The NDN Forwarding Daemon (NFD) connects every Ubuntu and Mac OS machine to the Named Data Networking (NDN) testbed network. While it's awesome to get your NFD connected from a Linux server or a Macbook, 82.56% of the desktop users running Windows are out of luck. Compiling NFD for Windows is possible, but the amount of patches needed is astonishing.

Then the good news came: Microsoft announced Windows Subsystem for Linux (WSL), which lets developers run Linux environments directly on Windows, unmodified, without the overhead of a virtual machine. Ubuntu is the first Linux distribution supported by WSL. This means, we can now run NFD natively on Windows!

How to Install NFD on WSL

This section outlines how to install NDN Forwarding Daemon (NFD) on Windows Subsystem for Linux (WSL). As of this writing, I have Windows 10 version 1709 (Fall Creators Update), and the latest NFD release is version 0.6.1.

The steps to install NFD on Windows are:

Tunnel Ethernet Traffic Over NDN

Named Data Networking (NDN) is a common network protocol for all applications and network environment. NDN's network layer protocol runs on top of a best-effort packet delivery service, which includes physical channels such as Ethernet wires, and logical connections such as UDP or TCP tunnels over the existing Internet. Using this underlying connectivity, NDN provides a content retrieval service, which allows applications to fetch uniquely named "Data packets" each carrying a piece of data. The "data" could be practically anything: text file chunks, video frames, temperature sensor readings ... they are all data. Likewise, a packet in a lower layer network protocol, such as an Ethernet frame, is also a piece of data. Therefore, it should be possible to encapsulate Ethernet traffic into NDN Data packets, and establish a Virtual Private Network (VPN) through NDN communication. This post describes the architecture of a proof-of-concept Ethernet-over-NDN tunneling program, and shows a simple performance benchmark over the real world Internet.

The Program

tap-tunnel creates an Ethernet tunnel between two nodes using NDN communication. Each node runs an instance of tap-tunnel. This program collects packets sent into a TAP interface, and turn them into NDN packets. It then gains NDN connectivity by connecting to the local NDN Forwarding Daemon (NFD). The diagram below shows the overall architecture:

IP app                                              IP app
  |                                                    |
IP stack    tap-tunnel              tap-tunnel    IP stack
  |         /        \              /        \         |
TAP interface       NFD            NFD       TAP interface
                     |              |
                    UDP            UDP
                     |              |
                    global NDN testbed

tap-tunnel requires existing NDN reachability between the two nodes. Each node must have a globally routable NDN prefix, so that a tap-tunnel instance can send an Interest to the other instance. This reachability can be established with auto prefix propagation.

How I Setup my NFD Development Machine

I'm the lead developer of NDN Forwarding Daemon (NFD). In this article, I want to share how my development machine is setup.

Everything in Virtual Machines

I do all NFD development work in virtual machines. There are many benefits in using VMs: I can have a clean operating system, I can test out different OS versions if necessary, and I can work on a different change on another VM when "my code's compiling".

My VM was setup using Vagrant, using the following Vagrantfile:

$vmname = "devbox"
$sshhostport = 2222

$deps = <<SCRIPT
apt-get update
apt-get dist-upgrade -y -qq
apt-get install -y -qq build-essential doxygen gdb git graphviz libboost-all-dev libcrypto++-dev libpcap-dev libsqlite3-dev libssl-dev pkg-config python-pip python-sphinx valgrind
pip install sphinxcontrib-doxylink sphinxcontrib-googleanalytics
SCRIPT

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network :forwarded_port, guest: 22, host: $sshhostport, id: "ssh"
  config.vm.provider "virtualbox" do |vb|
    vb.name = $vmname
    vb.memory = 4096
    vb.cpus = 4
  end
  config.vm.provision "deps", type: "shell", inline: $deps
  config.vm.provision "hostname", type: "shell", inline: "echo " + $vmname + " > /etc/hostname; hostname " + $vmname
  config.vm.provision "sshpvtkey", type: "file", source: "~/.ssh/id_rsa", destination: ".ssh/id_rsa"
  config.vm.provision "sshpubkey", type: "file", source: "~/.ssh/id_rsa.pub", destination: ".ssh/id_rsa.pub"
  config.vm.provision "sshauth", type: "shell", inline: "cd .ssh; cat id_rsa.pub >> authorized_keys"
  config.vm.provision "gitconfig", type: "file", source: "~/.gitconfig", destination: ".gitconfig"
end

How I Put a Temperature Sensor on the NDN Testbed

The frontpage of my recently renovated website shows a room temperature reading of my apartment. This is not your average IoT project, but a showcase of how an IoT device can communicate directly over Named Data Networking (NDN). This article explains where does this temperature reading come from, how is it turned into NDN Data packets, how the sensor appears on the NDN testbed, and how the temperature reading shows up on the website.

room temperature display on yoursunny.com frontpage

Sensor Hardware

If you have been reading my posts, you may have guessed that the temperature reading comes from an ESP8266. Of course! It is actually my very first ESP8266, which I received from Losant IoT Inc. It comes with a TMP36 analog temperature sensor, and has been reporting my room temperature to Losant platform since May 2016.

Losant Builder Kit with all the additions

How HomeCam Registers NDN Prefixes?

HomeCam, a browser-based home surveillance camera, is one of my major side projects during the past few years. My last post gave an overview on the overall architecture and various components of HomeCam. I mentioned that HomeCam delivers pictures via Named Data Networking (NDN), which provides better scalability because the camera only needs to serve each picture once even if there are multiple viewers, and the network takes care of the distribution.

Both HomeCam viewers and cameras connect to the global NDN testbed network via WebSockets. A viewer sends Interests to the network to request a picture from a specific camera identified by part of the Interest name. The network forwards the Interests to the named camera, and the camera responds with Data packets that contain the picture. But how does the network know where the camera is?

The camera must register its prefix onto the NDN testbed network.

For a regular end host running the NDN Forwarding Daemon (NFD), you may let the world reach your NFD via auto prefix propagation. This procedure involves sending a prefix registration command to the network, which causes the router to add a route toward the end host. A requirement is that the prefix registration command must be signed by a key trusted by the network.

HomeCam camera is a browser-based application that directly connects to a testbed router, and there is no NFD running locally to do auto prefix propagation for us. However, HomeCam can still have a route added toward the camera by sending a prefix registration command.

How HomeCam Works?

HomeCam, a browser-based home surveillance camera, is one of my major side projects during the past few years. HomeCam allows you to capture pictures via the webcam on a laptop or smartphone, and view real-time images from a different device. No specialized hardware or software installation is needed: HomeCam works directly in a web browser. This article gives an overview of the web technologies that enable HomeCam.

If you have not used HomeCam, try it today!

Functionality Review and General Workflow

The HomeCam web app can operate in either viewer or camera mode. To enter either mode, the user is required to specify a "camera name", which serves as an identifier. Each camera should have a distinct camera name. Any number of viewers can be active at the same time, and they will retrieve real-time pictures from the camera with the same camera name.

Under the hood, this works in three steps:

ndnping Jewelry on ESP8266

I was wearing a unique piece of jewelry at NDN community meeting, Mar 2017: a pair of ESP8266 units that communicate with each other over the NDN testbed. They are ugly, but it is a nice way to demonstrate my creation in a Named Data Networking community meeting.

Two Witty Cloud boards are tied to my wrists, and powered by a USB powerbank in my pocket. One of them runs a ndnping client, and the other runs a ndnping server. The client sends Interests to a router in Arizona, the Interests (under a multicast prefix) are flooded through the testbed, and reach the server which is connected to a router in Memphis.

Arduino Code

Library: esp8266ndn