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