Network2

From OLPC
Jump to navigation Jump to search

This page proposes a rough design for networking for a highly collaborative world, based on Scott's Network Principles.

Design

Protocols

We take IPv6 and DNS as the basis of our system and rely heavily the Linux Documentation Project's IPv6 documentation.

A couple of key facts and expectations inform the rest of this design, like:

  • hosts will have multiple interfaces,
  • interfaces will have multiple addresses,
  • DNS queries (used via getaddrinfo()) will return multiple results
  • these results will be sorted in a sane order, and
  • hosts will choose routes for packets based on how specifically the routes match the destination and on any QoS information available to the routing node.

(NB: these expectations suggest that SCTP (wikipedia, man page) may be particularly appropriate for new software being tailored for our environment.)

(NB: you should definitely start asking your ISPs to provide IPv6 routers. After all -- if none of their customers ask, then what incentive will they ever have to upgrade?)

Client IPv6 Configuration

Your job is to be an IPv6 node. Consequently, when you bring up your interfaces,

  1. You might discover an IPv6 router advertising on one of your links.
    • (See sysctl net.ipv6.conf.all.accept_ra and related variables.)
  2. You might try out dhcp6c.
  3. You might have some kind of IPv4 connectivity. If so, connect to the Internet or to other internetworks of your choice.
    • (miredo and openvpn seem particularly easy to configure and hence to experiment with...)
  4. Use dnshash to add guessable link-local addresses to all your links.

Server IPv6 Configuration

Your job is to be an IPv6 router and a DNS server. One of several situations might obtain:

  1. You might discover an IPv6 router advertising one or more IPv6 prefixes on your outbound link(s).
  2. You might have some kind of IPv4 connectivity. If so, connect to the Internet or to other internetworks of your choice.
  3. You might be under a tree. If so, generate a Unique Local Address prefix.
  4. (Use dnshash to add guessable link-local addresses to all your links?)

When done, use radvd or dhcp6d to share addresses.

Server DNS Configuration

One of the server's most important jobs is to get itself on appropriate internetworks so that it can dynamically map stable (DNS) names to unstable names (IPv6 addresses) for itself and its clients.

Unfortunately, the most reliable and secure means of updating these mappings is likely to be bespoke -- RFC 2136 is not widely implemented and specifies no concrete security protocol while DNSSEC seems immature at present.

Consequently, I propose the following strawman update protocol -- exchange an RFC-2136 UPDATE packet and response over your favorite authenticated RPC protocol with the nameserver.

(My favorite protocol for this sort of thing is currently "json-over-SSH-to-python-and-make", but variations (ucspi-ssl, 9p, etc.) make me smile.)

(Other possibilities: maybe DNSSEC isn't so hard? Maybe DNSCurve will be usable?)

Client DNS Configuration

Clients which have been registered with one or more servers need to update those servers when their addresses change using the protcol described above.


Analysis

Bandwidth Usage

Several important numbers that we need to predict and to measure:

tx == transmit, rx == receive, btx == broadcast

btx/tx/rx - ICMPv6+IPv6+phys           - router discovery (RD)
btx/rx    - ICMPv6+IPv6+phys           - duplicate address detection (DAD)
tx/rx     - ICMPv6+IPv6+phys           - NS neighbor discovery (ND)
tx/rx     - UDP+IPv6+phys              - DNS query
tx/rx     - JSON+SSH+TCP+IPv6+phys     - DNS update

where "phys" describes the equations' dependence on the "physical" layer's 
frame overhead and MTU

Debugging Techniques

Start recording a typescript so that we can see what you did.

TESTDIR=`pwd`/testing
mkdir -p $TESTDIR && cd TESTDIR
script
ulimit -c unlimited

Check that you've got the right DNS name for the person you want to talk to.

NAME=the.right.person
echo $NAME > peer

Dump your addresses, routes, and perhaps your open connections.

hostname --fqdn | tee host
ip addr show | tee addrs
ip route show | tee ipv4_routes
ip -6 route show | tee ipv6_routes
netstat -anp | tee conns

If you have wireless devices,

iwconfig | tee iwconfig
iwlist scan | tee iwlist_scan

Fire up tcpdump:

tcpdump -w packets -s0 &

Resolve that name to addresses. Check that the addresses seem sane.

dnshash_lookup $NAME | tee peer_addrs_dnshash
dig $NAME | tee peer_addrs_dig

Route to the addresses:

ping6 -I $IFACE $ADDR | tee ping
traceroute6 $ADDR | tee traceroute
tracepath6 $ADDR | tee tracepath

Connect to the address:

nc6 $ADDR $PORT
# echo "SSH-2.0-Hi" | nc6 $ADDR 22
# printf "GET / HTTP/1.0\r\n\r\n" | nc6 $ADDR 80
# ssh $ADDR
# curl -I http://$ADDR/
# ...

Conduct a bandwidth test:

iperf -c -V $ADDR

Collect logs from your application and send them to developers:

kill -SIGINT %1
cd ..
tar c $TESTDIR | lzma -c > logs.tar.lzma

Self-Test Algorithm

Client Design Considerations

Client Implementation Techniques

Future Work

  • Per-host networks and per-app IPs and names.
  • Sample code.