1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.gnunet;
8
9 homeDir = "/var/lib/gnunet";
10
11 configFile = with cfg; pkgs.writeText "gnunetd.conf"
12 ''
13 [PATHS]
14 SERVICEHOME = ${homeDir}
15
16 [ats]
17 WAN_QUOTA_IN = ${toString load.maxNetDownBandwidth} b
18 WAN_QUOTA_OUT = ${toString load.maxNetUpBandwidth} b
19
20 [datastore]
21 QUOTA = ${toString fileSharing.quota} MB
22
23 [transport-udp]
24 PORT = ${toString udp.port}
25 ADVERTISED_PORT = ${toString udp.port}
26
27 [transport-tcp]
28 PORT = ${toString tcp.port}
29 ADVERTISED_PORT = ${toString tcp.port}
30
31 ${extraOptions}
32 '';
33
34in
35
36{
37
38 ###### interface
39
40 options = {
41
42 services.gnunet = {
43
44 enable = mkOption {
45 type = types.bool;
46 default = false;
47 description = ''
48 Whether to run the GNUnet daemon. GNUnet is GNU's anonymous
49 peer-to-peer communication and file sharing framework.
50 '';
51 };
52
53 fileSharing = {
54 quota = mkOption {
55 type = types.int;
56 default = 1024;
57 description = ''
58 Maximum file system usage (in MiB) for file sharing.
59 '';
60 };
61 };
62
63 udp = {
64 port = mkOption {
65 type = types.port;
66 default = 2086; # assigned by IANA
67 description = ''
68 The UDP port for use by GNUnet.
69 '';
70 };
71 };
72
73 tcp = {
74 port = mkOption {
75 type = types.port;
76 default = 2086; # assigned by IANA
77 description = ''
78 The TCP port for use by GNUnet.
79 '';
80 };
81 };
82
83 load = {
84 maxNetDownBandwidth = mkOption {
85 type = types.int;
86 default = 50000;
87 description = ''
88 Maximum bandwidth usage (in bits per second) for GNUnet
89 when downloading data.
90 '';
91 };
92
93 maxNetUpBandwidth = mkOption {
94 type = types.int;
95 default = 50000;
96 description = ''
97 Maximum bandwidth usage (in bits per second) for GNUnet
98 when downloading data.
99 '';
100 };
101
102 hardNetUpBandwidth = mkOption {
103 type = types.int;
104 default = 0;
105 description = ''
106 Hard bandwidth limit (in bits per second) when uploading
107 data.
108 '';
109 };
110 };
111
112 package = mkOption {
113 type = types.package;
114 default = pkgs.gnunet;
115 defaultText = "pkgs.gnunet";
116 description = "Overridable attribute of the gnunet package to use.";
117 example = literalExample "pkgs.gnunet_git";
118 };
119
120 extraOptions = mkOption {
121 type = types.lines;
122 default = "";
123 description = ''
124 Additional options that will be copied verbatim in `gnunet.conf'.
125 See `gnunet.conf(5)' for details.
126 '';
127 };
128 };
129
130 };
131
132
133 ###### implementation
134
135 config = mkIf config.services.gnunet.enable {
136
137 users.users.gnunet = {
138 group = "gnunet";
139 description = "GNUnet User";
140 home = homeDir;
141 createHome = true;
142 uid = config.ids.uids.gnunet;
143 };
144
145 users.groups.gnunet.gid = config.ids.gids.gnunet;
146
147 # The user tools that talk to `gnunetd' should come from the same source,
148 # so install them globally.
149 environment.systemPackages = [ cfg.package ];
150
151 systemd.services.gnunet = {
152 description = "GNUnet";
153 after = [ "network.target" ];
154 wantedBy = [ "multi-user.target" ];
155 path = [ cfg.package pkgs.miniupnpc ];
156 environment.TMPDIR = "/tmp";
157 serviceConfig.PrivateTmp = true;
158 serviceConfig.ExecStart = "${cfg.package}/lib/gnunet/libexec/gnunet-service-arm -c ${configFile}";
159 serviceConfig.User = "gnunet";
160 serviceConfig.UMask = "0007";
161 serviceConfig.WorkingDirectory = homeDir;
162 };
163
164 };
165
166}