7 # include <sys/socket.h>
19 #include "dnscrypt_proxy.h"
25 #include "windows_service.h"
27 # include "plugin_options.h"
30 static struct option getopt_long_options
[] = {
31 { "local-address", 1, NULL
, 'a' },
33 { "daemonize", 0, NULL
, 'd' },
35 { "edns-payload-size", 1, NULL
, 'e' },
36 { "help", 0, NULL
, 'h' },
37 { "provider-key", 1, NULL
, 'k' },
39 { "logfile", 1, NULL
, 'l' },
41 { "loglevel", 1, NULL
, 'm' },
42 { "max-active-requests", 1, NULL
, 'n' },
44 { "pidfile", 1, NULL
, 'p' },
46 { "plugin", 1, NULL
, 'X' },
47 { "resolver-address", 1, NULL
, 'r' },
48 { "user", 1, NULL
, 'u' },
49 { "provider-name", 1, NULL
, 'N' },
50 { "tcp-only", 0, NULL
, 'T' },
51 { "version", 0, NULL
, 'V' },
53 { "install", 0, NULL
, WIN_OPTION_INSTALL
},
54 { "reinstall", 0, NULL
, WIN_OPTION_REINSTALL
},
55 { "uninstall", 0, NULL
, WIN_OPTION_UNINSTALL
},
60 static const char *getopt_options
= "a:de:hk:l:m:n:p:r:u:N:TVX";
62 static const char *getopt_options
= "a:e:hk:m:n:r:u:N:TVX";
65 #ifndef DEFAULT_CONNECTIONS_COUNT_MAX
66 # define DEFAULT_CONNECTIONS_COUNT_MAX 250U
69 #ifndef DEFAULT_PROVIDER_PUBLICKEY
70 # define DEFAULT_PROVIDER_PUBLICKEY \
71 "B735:1140:206F:225D:3E2B:D822:D7FD:691E:" \
72 "A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79"
74 #ifndef DEFAULT_PROVIDER_NAME
75 # define DEFAULT_PROVIDER_NAME "2.dnscrypt-cert.opendns.com."
77 #ifndef DEFAULT_RESOLVER_IP
78 # define DEFAULT_RESOLVER_IP "208.67.220.220:443"
90 const struct option
*options
= getopt_long_options
;
95 if (options
->val
< 256) {
96 printf(" -%c\t--%s%s\n", options
->val
, options
->name
,
97 options
->has_arg
? "=..." : "");
99 printf(" \t--%s%s\n", options
->name
,
100 options
->has_arg
? "=..." : "");
103 } while (options
->name
!= NULL
);
104 puts("\nPlease consult the dnscrypt-proxy(8) man page for details.\n");
108 void options_init_with_default(AppContext
* const app_context
,
109 ProxyContext
* const proxy_context
)
111 assert(proxy_context
->event_loop
== NULL
);
112 proxy_context
->app_context
= app_context
;
113 proxy_context
->connections_count
= 0U;
114 proxy_context
->connections_count_max
= DEFAULT_CONNECTIONS_COUNT_MAX
;
115 proxy_context
->edns_payload_size
= (size_t) DNS_DEFAULT_EDNS_PAYLOAD_SIZE
;
116 proxy_context
->local_ip
= "127.0.0.1:53";
117 proxy_context
->log_fd
= -1;
118 proxy_context
->log_file
= NULL
;
119 proxy_context
->pid_file
= NULL
;
120 proxy_context
->provider_name
= DEFAULT_PROVIDER_NAME
;
121 proxy_context
->provider_publickey_s
= DEFAULT_PROVIDER_PUBLICKEY
;
122 proxy_context
->resolver_ip
= DEFAULT_RESOLVER_IP
;
124 proxy_context
->user_id
= (uid_t
) 0;
125 proxy_context
->user_group
= (uid_t
) 0;
127 proxy_context
->user_dir
= NULL
;
128 proxy_context
->daemonize
= 0;
129 proxy_context
->tcp_only
= 0;
133 options_apply(ProxyContext
* const proxy_context
)
135 if (proxy_context
->resolver_ip
== NULL
) {
139 if (proxy_context
->provider_name
== NULL
||
140 *proxy_context
->provider_name
== 0) {
141 logger_noformat(proxy_context
, LOG_ERR
, "Provider name required");
144 if (proxy_context
->provider_publickey_s
== NULL
) {
145 logger_noformat(proxy_context
, LOG_ERR
, "Provider key required");
148 if (dnscrypt_fingerprint_to_key(proxy_context
->provider_publickey_s
,
149 proxy_context
->provider_publickey
) != 0) {
150 logger_noformat(proxy_context
, LOG_ERR
, "Invalid provider key");
153 if (proxy_context
->daemonize
) {
157 if (proxy_context
->pid_file
!= NULL
&&
158 pid_file_create(proxy_context
->pid_file
,
159 proxy_context
->user_id
!= (uid_t
) 0) != 0) {
160 logger_error(proxy_context
, "Unable to create pid file");
163 if (proxy_context
->log_file
!= NULL
&&
164 (proxy_context
->log_fd
= open(proxy_context
->log_file
,
165 O_WRONLY
| O_APPEND
| O_CREAT
,
166 (mode_t
) 0600)) == -1) {
167 logger_error(proxy_context
, "Unable to open log file");
170 if (proxy_context
->log_fd
== -1 && proxy_context
->daemonize
) {
171 logger_open_syslog(proxy_context
);
177 options_parse(AppContext
* const app_context
,
178 ProxyContext
* const proxy_context
, int argc
, char *argv
[])
181 int option_index
= 0;
183 options_init_with_default(app_context
, proxy_context
);
184 while ((opt_flag
= getopt_long(argc
, argv
,
185 getopt_options
, getopt_long_options
,
186 &option_index
)) != -1) {
189 proxy_context
->local_ip
= optarg
;
192 proxy_context
->daemonize
= 1;
196 const unsigned long edns_payload_size
= strtoul(optarg
, &endptr
, 10);
198 if (*optarg
== 0 || *endptr
!= 0 ||
199 edns_payload_size
> DNS_MAX_PACKET_SIZE_UDP_RECV
) {
200 logger(proxy_context
, LOG_ERR
,
201 "Invalid EDNS payload size: [%s]", optarg
);
204 if (edns_payload_size
<= DNS_MAX_PACKET_SIZE_UDP_SEND
) {
205 proxy_context
->edns_payload_size
= (size_t) 0U;
207 proxy_context
->edns_payload_size
= (size_t) edns_payload_size
;
215 proxy_context
->provider_publickey_s
= optarg
;
218 proxy_context
->log_file
= optarg
;
222 const long max_log_level
= strtol(optarg
, &endptr
, 10);
224 if (*optarg
== 0 || *endptr
!= 0 || max_log_level
< 0) {
225 logger(proxy_context
, LOG_ERR
,
226 "Invalid max log level: [%s]", optarg
);
229 proxy_context
->max_log_level
= max_log_level
;
234 const unsigned long connections_count_max
=
235 strtoul(optarg
, &endptr
, 10);
237 if (*optarg
== 0 || *endptr
!= 0 ||
238 connections_count_max
<= 0U ||
239 connections_count_max
> UINT_MAX
) {
240 logger(proxy_context
, LOG_ERR
,
241 "Invalid max number of active request: [%s]", optarg
);
244 proxy_context
->connections_count_max
=
245 (unsigned int) connections_count_max
;
249 proxy_context
->pid_file
= optarg
;
252 proxy_context
->resolver_ip
= optarg
;
256 const struct passwd
* const pw
= getpwnam(optarg
);
258 logger(proxy_context
, LOG_ERR
, "Unknown user: [%s]", optarg
);
261 proxy_context
->user_id
= pw
->pw_uid
;
262 proxy_context
->user_group
= pw
->pw_gid
;
263 proxy_context
->user_dir
= strdup(pw
->pw_dir
);
268 proxy_context
->provider_name
= optarg
;
271 proxy_context
->tcp_only
= 1;
278 logger_noformat(proxy_context
, LOG_ERR
,
279 "Support for plugins hasn't been compiled in");
282 if (plugin_options_parse_str
283 (proxy_context
->app_context
->dcps_context
, optarg
) != 0) {
284 logger_noformat(proxy_context
, LOG_ERR
,
285 "Error while parsing plugin options");
291 case WIN_OPTION_INSTALL
:
292 case WIN_OPTION_UNINSTALL
:
293 if (windows_service_option(opt_flag
, argc
,
294 (const char **) argv
) != 0) {
305 if (options_apply(proxy_context
) != 0) {
312 options_free(ProxyContext
* const proxy_context
)
314 free(proxy_context
->user_dir
);
315 proxy_context
->user_dir
= NULL
;