aboutsummaryrefslogtreecommitdiff
path: root/src/lib/daemon_options.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/daemon_options.c')
-rw-r--r--src/lib/daemon_options.c713
1 files changed, 713 insertions, 0 deletions
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c
new file mode 100644
index 00000000..576779e3
--- /dev/null
+++ b/src/lib/daemon_options.c
@@ -0,0 +1,713 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file lib/daemon_options.c
22 * @brief boring functions to manipulate daemon options
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Set logging method. Specify NULL to disable logging entirely. By
30 * default (if this option is not given), we log error messages to
31 * stderr.
32 *
33 * @param daemon which instance to setup logging for
34 * @param logger function to invoke
35 * @param logger_cls closure for @a logger
36 */
37void
38MHD_daemon_set_logger (struct MHD_Daemon *daemon,
39 MHD_LoggingCallback logger,
40 void *logger_cls)
41{
42 daemon->logger = logger;
43 daemon->logger_cls = logger_cls;
44}
45
46
47/**
48 * Suppress use of "Date" header as this system has no RTC.
49 *
50 * @param daemon which instance to disable clock for.
51 */
52void
53MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon)
54{
55 daemon->suppress_date = true;
56}
57
58
59/**
60 * Disable use of inter-thread communication channel.
61 * #MHD_daemon_disable_itc() can be used with
62 * #MHD_daemon_thread_internal() to perform some additional
63 * optimizations (in particular, not creating a pipe for IPC
64 * signalling). If it is used, certain functions like
65 * #MHD_daemon_quiesce() or #MHD_connection_add() or
66 * #MHD_action_suspend() cannot be used anymore.
67 * #MHD_daemon_disable_itc() is not beneficial on platforms where
68 * select()/poll()/other signal shutdown() of a listen socket.
69 *
70 * You should only use this function if you are sure you do
71 * satisfy all of its requirements and need a generally minor
72 * boost in performance.
73 *
74 * @param daemon which instance to disable itc for
75 */
76void
77MHD_daemon_disable_itc (struct MHD_Daemon *daemon)
78{
79 daemon->disable_itc = true;
80}
81
82
83/**
84 * Enable `turbo`. Disables certain calls to `shutdown()`,
85 * enables aggressive non-blocking optimistic reads and
86 * other potentially unsafe optimizations.
87 * Most effects only happen with #MHD_ELS_EPOLL.
88 *
89 * @param daemon which instance to enable turbo for
90 */
91void
92MHD_daemon_enable_turbo (struct MHD_Daemon *daemon)
93{
94 daemon->enable_turbo = true;
95}
96
97
98/**
99 * Disable #MHD_action_suspend() functionality.
100 *
101 * You should only use this function if you are sure you do
102 * satisfy all of its requirements and need a generally minor
103 * boost in performance.
104 *
105 * @param daemon which instance to disable suspend for
106 */
107void
108MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon)
109{
110 daemon->disallow_suspend_resume = true;
111}
112
113
114/**
115 * You need to set this option if you want to disable use of HTTP "Upgrade".
116 * "Upgrade" may require usage of additional internal resources,
117 * which we can avoid providing if they will not be used.
118 *
119 * You should only use this function if you are sure you do
120 * satisfy all of its requirements and need a generally minor
121 * boost in performance.
122 *
123 * @param daemon which instance to enable suspend/resume for
124 */
125void
126MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
127{
128 daemon->disallow_upgrade;
129}
130
131
132/**
133 * Configure TCP_FASTOPEN option, including setting a
134 * custom @a queue_length.
135 *
136 * Note that having a larger queue size can cause resource exhaustion
137 * attack as the TCP stack has to now allocate resources for the SYN
138 * packet along with its DATA.
139 *
140 * @param daemon which instance to configure TCP_FASTOPEN for
141 * @param fom under which conditions should we use TCP_FASTOPEN?
142 * @param queue_length queue length to use, default is 50 if this
143 * option is never given.
144 * @return #MHD_YES upon success, #MHD_NO if #MHD_FOM_REQUIRE was
145 * given, but TCP_FASTOPEN is not available on the platform
146 */
147enum MHD_Bool
148MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
149 enum MHD_FastOpenMethod fom,
150 unsigned int queue_length)
151{
152 daemon->fast_open_method = fom;
153 daemon->fast_open_queue_length = queue_length;
154 switch (fom)
155 {
156 case MHD_FOM_DISABLE:
157 return MHD_YES;
158 case MHD_FOM_AUTO:
159 return MHD_YES;
160 case MHD_FOM_REQUIRE:
161#ifdef TCP_FASTOPEN
162 return MHD_YES;
163#else
164 return MHD_NO;
165#endif
166 }
167}
168
169
170/**
171 * Bind to the given TCP port and address family.
172 *
173 * Ineffective in conjunction with #MHD_daemon_listen_socket().
174 * Ineffective in conjunction with #MHD_daemon_bind_sa().
175 *
176 * If neither this option nor the other two mentioned above
177 * is specified, MHD will simply not listen on any socket!
178 *
179 * @param daemon which instance to configure the TCP port for
180 * @param af address family to use
181 * @param port port to use, 0 to bind to a random (free) port
182 */
183void
184MHD_daemon_bind_port (struct MHD_Daemon *daemon,
185 enum MHD_AddressFamily af,
186 uint16_t port)
187{
188 daemon->listen_af = af;
189 daemon->listen_port = port;
190}
191
192
193/**
194 * Bind to the given socket address.
195 * Ineffective in conjunction with #MHD_daemon_listen_socket().
196 *
197 * @param daemon which instance to configure the binding address for
198 * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
199 * or even a UNIX domain socket (AF_UNIX)
200 * @param sa_len number of bytes in @a sa
201 */
202void
203MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
204 const struct sockaddr *sa,
205 size_t sa_len)
206{
207 daemon->sa_given = true;
208 memcpy (&daemon->listen_sa,
209 sa,
210 sa_len);
211 daemon->listen_sa_len = sa_len;
212}
213
214
215/**
216 * Use the given backlog for the listen() call.
217 * Ineffective in conjunction with #MHD_daemon_listen_socket().
218 *
219 * @param daemon which instance to configure the backlog for
220 * @param listen_backlog backlog to use
221 */
222void
223MHD_daemon_listen_backlog (struct MHD_Daemon *daemon,
224 int listen_backlog)
225{
226 daemon->listen_backlog = listen_backlog;
227}
228
229
230/**
231 * If present true, allow reusing address:port socket (by using
232 * SO_REUSEPORT on most platform, or platform-specific ways). If
233 * present and set to false, disallow reusing address:port socket
234 * (does nothing on most plaform, but uses SO_EXCLUSIVEADDRUSE on
235 * Windows).
236 * Ineffective in conjunction with #MHD_daemon_listen_socket().
237 *
238 * @param daemon daemon to configure address reuse for
239 */
240void
241MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon)
242{
243 daemon->allow_address_reuse = true;
244}
245
246
247/**
248 * Accept connections from the given socket. Socket
249 * must be a TCP or UNIX domain (stream) socket.
250 *
251 * Unless -1 is given, this disables other listen options, including
252 * #MHD_daemon_bind_sa(), #MHD_daemon_bind_port(),
253 * #MHD_daemon_listen_queue() and
254 * #MHD_daemon_listen_allow_address_reuse().
255 *
256 * @param daemon daemon to set listen socket for
257 * @param listen_socket listen socket to use,
258 * MHD_INVALID_SOCKET value will cause this call to be
259 * ignored (other binding options may still be effective)
260 */
261void
262MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
263 MHD_socket listen_socket)
264{
265 daemon->listen_socket = listen_socket;
266}
267
268
269/**
270 * Force use of a particular event loop system call.
271 *
272 * @param daemon daemon to set event loop style for
273 * @param els event loop syscall to use
274 * @return #MHD_NO on failure, #MHD_YES on success
275 */
276enum MHD_Bool
277MHD_daemon_event_loop (struct MHD_Daemon *daemon,
278 enum MHD_EventLoopSyscall els)
279{
280 switch (els)
281 {
282 case MHD_ELS_AUTO:
283 break; /* should always be OK */
284 case MHD_ELS_SELECT:
285 break; /* should always be OK */
286 case MHD_ELS_POLL:
287#ifdef HAVE_POLL
288 break;
289#else
290 return MHD_NO; /* not supported */
291#endif
292 case MHD_ELS_EPOLL:
293#ifdef EPOLL_SUPPORT
294 break;
295#else
296 return MHD_NO; /* not supported */
297#endif
298 default:
299 return MHD_NO; /* not supported (presumably future ABI extension) */
300 }
301 daemon->event_loop_syscall = els;
302 return MHD_YES;
303}
304
305
306/**
307 * Set how strictly MHD will enforce the HTTP protocol.
308 *
309 * @param daemon daemon to configure strictness for
310 * @param sl how strict should we be
311 */
312void
313MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
314 enum MHD_ProtocolStrictLevel sl)
315{
316 daemon->protocol_strict_level = sl;
317}
318
319
320/**
321 * Enable and configure TLS.
322 *
323 * @param daemon which instance should be configured
324 * @param tls_backend which TLS backend should be used,
325 * currently only "gnutls" is supported. You can
326 * also specify NULL for best-available (which is the default).
327 * @param ciphers which ciphers should be used by TLS, default is
328 * "NORMAL"
329 * @return status code, #MHD_SC_OK upon success
330 * #MHD_TLS_BACKEND_UNSUPPORTED if the @a backend is unknown
331 * #MHD_TLS_DISABLED if this build of MHD does not support TLS
332 * #MHD_TLS_CIPHERS_INVALID if the given @a ciphers are not supported
333 * by this backend
334 */
335enum MHD_StatusCode
336MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
337 const char *tls_backend,
338 const char *ciphers)
339{
340#ifndef HTTPS_SUPPORT
341 return MHD_TLS_DISABLED;
342#else
343 char filename[1024];
344 int res;
345 MHD_TLS_PluginInit init;
346
347 /* todo: .dll on W32? */
348 res = MHD_snprintf (filename,
349 sizeof (filename),
350 "%s/libmicrohttpd_tls_%s.so",
351 MHD_PLUGIN_INSTALL_PREFIX,
352 tls_backend);
353 if (0 >= res)
354 return MHD_BACKEND_UNSUPPORTED; /* string too long? */
355 if (NULL ==
356 (daemon->tls_backend_lib = dlopen (filename,
357 RTLD_NOW | RTLD_LOCAL)))
358 return MHD_BACKEND_UNSUPPORTED; /* plugin not found */
359 if (NULL == (init = dlsym (daemon->tls_backend_lib,
360 "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR)))
361
362 {
363 dlclose (daemon->tls_backend_lib);
364 daemon->tls_backend_lib = NULL;
365 return MHD_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
366 }
367 if (NULL == (daemon->tls_backend = init (ciphers)))
368 {
369 dlclose (daemon->tls_backend_lib);
370 daemon->tls_backend_lib = NULL;
371 return MHD_CIPHERS_INVALID; /* possibly wrong version installed */
372 }
373 return MHD_SC_OK;
374#endif
375}
376
377
378/**
379 * Provide TLS key and certificate data in-memory.
380 *
381 * @param daemon which instance should be configured
382 * @param mem_key private key (key.pem) to be used by the
383 * HTTPS daemon. Must be the actual data in-memory, not a filename.
384 * @param mem_cert certificate (cert.pem) to be used by the
385 * HTTPS daemon. Must be the actual data in-memory, not a filename.
386 * @param pass passphrase phrase to decrypt 'key.pem', NULL
387 * if @param mem_key is in cleartext already
388 * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED
389 * if the TLS backend is not yet setup.
390 */
391enum MHD_StatusCode
392MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
393 const char *mem_key,
394 const char *mem_cert,
395 const char *pass)
396{
397 struct MHD_TLS_Plugin *plugin;
398
399 if (NULL == (plugin = daemon->tls_backend))
400 return MHD_TLS_BACKEND_UNINITIALIZED;
401 return plugin->init_kcp (plugin->cls,
402 mem_key,
403 mem_cert,
404 pass);
405}
406
407
408/**
409 * Configure DH parameters (dh.pem) to use for the TLS key
410 * exchange.
411 *
412 * @param daemon daemon to configure tls for
413 * @param dh parameters to use
414 * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED
415 * if the TLS backend is not yet setup.
416 */
417enum MHD_StatusCode
418MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
419 const char *dh)
420{
421 struct MHD_TLS_Plugin *plugin;
422
423 if (NULL == (plugin = daemon->tls_backend))
424 return MHD_TLS_BACKEND_UNINITIALIZED;
425 return plugin->init_dhparams (plugin->cls,
426 dh);
427}
428
429
430/**
431 * Memory pointer for the certificate (ca.pem) to be used by the
432 * HTTPS daemon for client authentification.
433 *
434 * @param daemon daemon to configure tls for
435 * @param mem_trust memory pointer to the certificate
436 * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED
437 * if the TLS backend is not yet setup.
438 */
439enum MHD_StatusCode
440MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
441 const char *mem_trust)
442{
443 struct MHD_TLS_Plugin *plugin;
444
445 if (NULL == (plugin = daemon->tls_backend))
446 return MHD_TLS_BACKEND_UNINITIALIZED;
447 return plugin->init_mem_trust (plugin->cls,
448 mem_trust);
449}
450
451
452/**
453 * Configure daemon credentials type for GnuTLS.
454 *
455 * @param gnutls_credentials must be a value of
456 * type `gnutls_credentials_type_t`
457 * @return #MHD_SC_OK upon success; TODO: define failure modes
458 */
459enum MHD_StatusCode
460MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
461 int gnutls_credentials)
462{
463 struct MHD_TLS_Plugin *plugin;
464
465 if (NULL == (plugin = daemon->tls_backend))
466 return MHD_TLS_BACKEND_UNINITIALIZED;
467 return MHD_TLS_BACKEND_OPERATION_UNSUPPORTED;
468}
469
470
471/**
472 * Provide TLS key and certificate data via callback.
473 *
474 * Use a callback to determine which X.509 certificate should be used
475 * for a given HTTPS connection. This option provides an alternative
476 * to #MHD_daemon_tls_key_and_cert_from_memory(). You must use this
477 * version if multiple domains are to be hosted at the same IP address
478 * using TLS's Server Name Indication (SNI) extension. In this case,
479 * the callback is expected to select the correct certificate based on
480 * the SNI information provided. The callback is expected to access
481 * the SNI data using `gnutls_server_name_get()`. Using this option
482 * requires GnuTLS 3.0 or higher.
483 *
484 * @param daemon daemon to configure callback for
485 * @param cb must be of type `gnutls_certificate_retrieve_function2 *`.
486 */
487void
488MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
489 void *cb)
490{
491 struct MHD_TLS_Plugin *plugin;
492
493 if (NULL == (plugin = daemon->tls_backend))
494 return MHD_TLS_BACKEND_UNINITIALIZED;
495 return MHD_TLS_BACKEND_OPERATION_UNSUPPORTED;
496}
497
498
499/**
500 * Specify threading model to use.
501 *
502 * @param daemon daemon to configure
503 * @param tm model to use (positive values indicate the
504 * number of worker threads to be used)
505 */
506void
507MHD_daemon_threading_model (struct MHD_Daemon *daemon,
508 enum MHD_ThreadingModel tm)
509{
510 daemon->threading_model = tm;
511}
512
513
514/**
515 * Set a policy callback that accepts/rejects connections
516 * based on the client's IP address. This function will be called
517 * before a connection object is created.
518 *
519 * @param daemon daemon to set policy for
520 * @param apc function to call to check the policy
521 * @param apc_cls closure for @a apc
522 */
523void
524MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
525 MHD_AcceptPolicyCallback apc,
526 void *apc_cls)
527{
528 daemon->accept_policy_cb = apc;
529 daemon->accept_policy_cb_cls = apc_cls;
530}
531
532
533/**
534 * Register a callback to be called first for every request
535 * (before any parsing of the header). Makes it easy to
536 * log the full URL.
537 *
538 * @param daemon daemon for which to set the logger
539 * @param cb function to call
540 * @param cb_cls closure for @a cb
541 */
542void
543MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
544 MHD_EarlyUriLogCallback cb,
545 void *cb_cls)
546{
547 daemon->early_uri_logger_cb = cb;
548 daemon->early_uri_logger_cb_cls = cb_cls;
549}
550
551
552/**
553 * Register a function that should be called whenever a connection is
554 * started or closed.
555 *
556 * @param daemon daemon to set callback for
557 * @param ncc function to call to check the policy
558 * @param ncc_cls closure for @a apc
559 */
560void
561MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
562 MHD_NotifyConnectionCallback ncc,
563 void *ncc_cls)
564{
565 daemon->notify_connection_cb = ncc;
566 daemon->notify_connection_cb_cls = ncc_cls;
567}
568
569
570/**
571 * Maximum memory size per connection.
572 * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT).
573 * Values above 128k are unlikely to result in much benefit, as half
574 * of the memory will be typically used for IO, and TCP buffers are
575 * unlikely to support window sizes above 64k on most systems.
576 *
577 * @param daemon daemon to configure
578 * @param memory_limit_b connection memory limit to use in bytes
579 * @param memory_increment_b increment to use when growing the read buffer, must be smaller than @a memory_limit_b
580 */
581void
582MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
583 size_t memory_limit_b,
584 size_t memory_increment_b)
585{
586 if (memory_increment_b >= memory_limit_b)
587 MHD_PANIC ("sane memory increment must be below memory limit");
588 daemon->connection_memory_limit_b = memory_limit_b;
589 daemon->connection_memory_increment_b = memory_increment_b;
590}
591
592
593/**
594 * Desired size of the stack for threads created by MHD. Use 0 for
595 * system default. Only useful if the selected threading model
596 * is not #MHD_TM_EXTERNAL_EVENT_LOOP.
597 *
598 * @param daemon daemon to configure
599 * @param stack_limit_b stack size to use in bytes
600 */
601void
602MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
603 size_t stack_limit_b)
604{
605 daemon->thread_stack_limit_b = stack_limit_b;
606}
607
608
609/**
610 * Set maximum number of concurrent connections to accept. If not
611 * given, MHD will not enforce any limits (modulo running into
612 * OS limits). Values of 0 mean no limit.
613 *
614 * @param daemon daemon to configure
615 * @param global_connection_limit maximum number of (concurrent)
616 connections
617 * @param ip_connection_limit limit on the number of (concurrent)
618 * connections made to the server from the same IP address.
619 * Can be used to prevent one IP from taking over all of
620 * the allowed connections. If the same IP tries to
621 * establish more than the specified number of
622 * connections, they will be immediately rejected.
623 */
624void
625MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
626 unsigned int global_connection_limit,
627 unsigned int ip_connection_limit)
628{
629 daemon->global_connection_limit = global_connection_limit;
630 daemon->ip_connection_limit = ip_connection_limit;
631}
632
633
634/**
635 * After how many seconds of inactivity should a
636 * connection automatically be timed out?
637 * Use zero for no timeout, which is also the (unsafe!) default.
638 *
639 * @param daemon daemon to configure
640 * @param timeout_s number of seconds of timeout to use
641 */
642void
643MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
644 unsigned int timeout_s)
645{
646 daemon->connection_default_timeout_s = timeout_s;
647}
648
649
650/**
651 * Specify a function that should be called for unescaping escape
652 * sequences in URIs and URI arguments. Note that this function
653 * will NOT be used by the `struct MHD_PostProcessor`. If this
654 * option is not specified, the default method will be used which
655 * decodes escape sequences of the form "%HH".
656 *
657 * @param daemon daemon to configure
658 * @param unescape_cb function to use, NULL for default
659 * @param unescape_cb_cls closure for @a unescape_cb
660 */
661void
662MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
663 MHD_UnescapeCallback unescape_cb,
664 void *unescape_cb_cls)
665{
666 daemon->unescape_cb = unescape_cb;
667 daemon->unescape_cb_cls = unescape_cb_cls;
668}
669
670
671/**
672 * Set random values to be used by the Digest Auth module. Note that
673 * the application must ensure that @a buf remains allocated and
674 * unmodified while the deamon is running.
675 *
676 * @param daemon daemon to configure
677 * @param buf_size number of bytes in @a buf
678 * @param buf entropy buffer
679 */
680void
681MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
682 size_t buf_size,
683 const void *buf)
684{
685#if ENABLE_DAUTH
686 daemon->digest_auth_random_buf = buf;
687 daemon->digest_auth_random_buf_size = buf_size;
688#else
689 MHD_PANIC ("digest authentication not supported by this build");
690#endif
691}
692
693
694/**
695 * Length of the internal array holding the map of the nonce and
696 * the nonce counter.
697 *
698 * @param daemon daemon to configure
699 * @param nc_length desired array length
700 */
701void
702MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
703 size_t nc_length)
704{
705#if ENABLE_DAUTH
706 daemon->digest_nc_length = nc_length;
707#else
708 MHD_PANIC ("digest authentication not supported by this build");
709#endif
710}
711
712
713/* end of daemon_options.c */