| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  | let | 
					
						
							|  |  |  |   carolKey = "2d2a338b46f8e4a8c462f0c385b481292a05f678e19a2b82755258cf0f0af7e2"; | 
					
						
							|  |  |  |   carolPubKey = "n932l3pjvmhtxxcdrqq2qpw5zc58f01vvjx01h4dtd1bb0nnu2h0.k"; | 
					
						
							|  |  |  |   carolPassword = "678287829ce4c67bc8b227e56d94422ee1b85fa11618157b2f591de6c6322b52"; | 
					
						
							|  |  |  |   carolIp4 = "192.168.0.9"; | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |   basicConfig = | 
					
						
							|  |  |  |     { config, pkgs, ... }: | 
					
						
							|  |  |  |     { services.cjdns.enable = true; | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |       # Turning off DHCP isn't very realistic but makes | 
					
						
							|  |  |  |       # the sequence of address assignment less stochastic. | 
					
						
							|  |  |  |       networking.useDHCP = false; | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |       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, ... }: | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |         let carolIp4 = lib.mkForce nodes.carol.config.networking.interfaces.eth1; in | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |           { imports = [ basicConfig ]; | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |           networking.interfaces.eth1.ipAddress = "192.168.0.2"; | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |           services.cjdns = | 
					
						
							|  |  |  |             { UDPInterface = | 
					
						
							|  |  |  |                 { bind = "0.0.0.0:1024"; | 
					
						
							|  |  |  |                   connectTo."192.168.0.1:1024}" = | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  |                     { password = carolPassword; | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |                       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"; | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |           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 | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |       $alice->succeed("ping6 -c 4 $carolIp6"); | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  |       $bob->succeed("ping6 -c 4 $carolIp6"); | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       $carol->succeed("ping6 -c 4 $aliceIp6"); | 
					
						
							|  |  |  |       $carol->succeed("ping6 -c 4 $bobIp6"); | 
					
						
							| 
									
										
										
										
											2015-03-21 10:13:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 15:15:48 -04:00
										 |  |  |       $alice->succeed("ping6 -c 4 $bobIp6"); | 
					
						
							|  |  |  |       $bob->succeed("ping6 -c 4 $aliceIp6"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $alice->waitForUnit("httpd.service"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $bob->succeed("curl --fail -g http://[$aliceIp6]"); | 
					
						
							|  |  |  |     '';
 | 
					
						
							|  |  |  | } |