diff options
Diffstat (limited to 'nixos/tests/cjdns.nix')
-rw-r--r-- | nixos/tests/cjdns.nix | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix new file mode 100644 index 000000000000..7bb3863c683f --- /dev/null +++ b/nixos/tests/cjdns.nix @@ -0,0 +1,123 @@ +let + carolKey = "2d2a338b46f8e4a8c462f0c385b481292a05f678e19a2b82755258cf0f0af7e2"; + carolPubKey = "n932l3pjvmhtxxcdrqq2qpw5zc58f01vvjx01h4dtd1bb0nnu2h0.k"; + carolPassword = "678287829ce4c67bc8b227e56d94422ee1b85fa11618157b2f591de6c6322b52"; + carolIp4 = "192.168.0.9"; + + basicConfig = + { config, pkgs, ... }: + { services.cjdns.enable = true; + + # Turning off DHCP isn't very realistic but makes + # the sequence of address assignment less stochastic. + networking.useDHCP = false; + + networking.interfaces.eth1.prefixLength = 24; + # CJDNS output is incompatible with the XML log. + systemd.services.cjdns.serviceConfig.StandardOutput = "null"; + #networking.firewall.enable = true; + networking.firewall.allowPing = true; + #networking.firewall.rejectPackets = true; + }; + +in + +import ./make-test.nix { + name = "cjdns"; + + nodes = rec + { # Alice finds peers over over ETHInterface. + alice = + { config, ... }: + { imports = [ basicConfig ]; + + services.cjdns.ETHInterface.bind = "eth1"; + + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + networking.firewall.allowedTCPPorts = [ 80 ]; + }; + + # Bob explicitly connects to Carol over UDPInterface. + bob = + { config, lib, nodes, ... }: + + let carolIp4 = lib.mkForce nodes.carol.config.networking.interfaces.eth1; in + + { imports = [ basicConfig ]; + + networking.interfaces.eth1.ipAddress = "192.168.0.2"; + + services.cjdns = + { UDPInterface = + { bind = "0.0.0.0:1024"; + connectTo."192.168.0.1:1024}" = + { hostname = "carol.hype"; + password = carolPassword; + publicKey = carolPubKey; + }; + }; + }; + }; + + # Carol listens on ETHInterface and UDPInterface, + # but knows neither Alice or Bob. + carol = + { config, lib, nodes, ... }: + let + carolIp4 = (lib.mkForce nodes.carol.config.networking.interfaces.eth1); + in + { imports = [ basicConfig ]; + + environment.etc."cjdns.keys".text = '' + CJDNS_PRIVATE_KEY=${carolKey} + CJDNS_ADMIN_PASSWORD=FOOBAR + ''; + + networking.interfaces.eth1.ipAddress = "192.168.0.1"; + + services.cjdns = + { authorizedPasswords = [ carolPassword ]; + ETHInterface.bind = "eth1"; + UDPInterface.bind = "192.168.0.1:1024"; + }; + networking.firewall.allowedUDPPorts = [ 1024 ]; + }; + + }; + + testScript = + '' + startAll; + + $alice->waitForUnit("cjdns.service"); + $bob->waitForUnit("cjdns.service"); + $carol->waitForUnit("cjdns.service"); + + sub cjdnsIp { + my ($machine) = @_; + my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev tun0"))[3]; + $machine->log("has ip $ip"); + return $ip; + } + + my $aliceIp6 = cjdnsIp $alice; + my $bobIp6 = cjdnsIp $bob; + my $carolIp6 = cjdnsIp $carol; + + # ping a few times each to let the routing table establish itself + + $alice->succeed("ping6 -c 4 $carolIp6"); + $bob->succeed("ping6 -c 4 carol.hype"); + + $carol->succeed("ping6 -c 4 $aliceIp6"); + $carol->succeed("ping6 -c 4 $bobIp6"); + + $alice->succeed("ping6 -c 4 $bobIp6"); + $bob->succeed("ping6 -c 4 $aliceIp6"); + + $alice->waitForUnit("httpd.service"); + + $bob->succeed("curl --fail -g http://[$aliceIp6]"); + ''; +} |