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