anchor.diff:            '';
            };
           connectTo = mkOption {
  -          type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
  +          type = types.attrsOf (types.attrsOf types.str);
             default = { };
             example = {
               "192.168.1.1:27313" = {
  -              hostname = "homer.hype";
  -              password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
  +              user      = "foobar";
  +              password  = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
                 publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
               };
             };
  
positive.code:       };
      };
  
      networking.extraHosts = cjdnsExtraHosts;
  
      assertions = [
        { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null );
          message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";
  
negative.code:         type = types.str;
          description = "Public key at the opposite end of the tunnel.";
        };
      };
    };
  
    # check for the required attributes, otherwise
    # permit attributes not undefined here
    checkPeers = x:
      x // {
        connectTo = mapAttrs
          (name: value:
            if !hasAttr "publicKey" value then abort "cjdns peer ${name} missing a publicKey" else
            if !hasAttr "password"  value then abort "cjdns peer ${name} missing a password"  else
            value
          )
        x.connectTo;
      };
  
    # would be nice to  merge 'cfg' with a //,
    # but the json nesting is wacky.
  