diff options
Diffstat (limited to 'src/mhd')
| -rw-r--r-- | src/mhd/Makefile.am | 3 | ||||
| -rw-r--r-- | src/mhd/mhd_config.c | 47 | ||||
| -rw-r--r-- | src/mhd/mhd_run.c | 174 | 
3 files changed, 223 insertions, 1 deletions
diff --git a/src/mhd/Makefile.am b/src/mhd/Makefile.am index 059c275c..f7f052d5 100644 --- a/src/mhd/Makefile.am +++ b/src/mhd/Makefile.am @@ -13,7 +13,8 @@ libtalermhd_la_SOURCES = \    mhd_config.c \    mhd_legal.c \    mhd_parsing.c \ -  mhd_responses.c +  mhd_responses.c \ +  mhd_run.c  libtalermhd_la_LDFLAGS = \    -version-info 0:0:0 \    -no-undefined diff --git a/src/mhd/mhd_config.c b/src/mhd/mhd_config.c index a619bba1..d6e1a25c 100644 --- a/src/mhd/mhd_config.c +++ b/src/mhd/mhd_config.c @@ -322,6 +322,53 @@ TALER_MHD_bind (const struct GNUNET_CONFIGURATION_Handle *cfg,    char *bind_to;    struct GNUNET_NETWORK_Handle *nh; +  /* try systemd passing first */ +  { +    const char *listen_pid; +    const char *listen_fds; + +    /* check for systemd-style FD passing */ +    listen_pid = getenv ("LISTEN_PID"); +    listen_fds = getenv ("LISTEN_FDS"); +    if ( (NULL != listen_pid) && +         (NULL != listen_fds) && +         (getpid () == strtol (listen_pid, +                               NULL, +                               10)) && +         (1 == strtoul (listen_fds, +                        NULL, +                        10)) ) +    { +      int fh; +      int flags; + +      fh = 3; +      flags = fcntl (fh, +                     F_GETFD); +      if ( (-1 == flags) && +           (EBADF == errno) ) +      { +        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                    "Bad listen socket passed, ignored\n"); +        fh = -1; +      } +      flags |= FD_CLOEXEC; +      if ( (-1 != fh) && +           (0 != fcntl (fh, +                        F_SETFD, +                        flags)) ) +        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, +                             "fcntl"); +      if (-1 != fh) +      { +        GNUNET_log (GNUNET_ERROR_TYPE_INFO, +                    "Successfully obtained listen socket from hypervisor\n"); +        return fh; +      } +    } +  } + +  /* now try configuration file */    *port = 0;    {      char *serve_unixpath; diff --git a/src/mhd/mhd_run.c b/src/mhd/mhd_run.c new file mode 100644 index 00000000..8a3c369b --- /dev/null +++ b/src/mhd/mhd_run.c @@ -0,0 +1,174 @@ +/* +  This file is part of TALER +  Copyright (C) 2019-2021 Taler Systems SA + +  TALER is free software; you can redistribute it and/or modify it under the +  terms of the GNU Affero General Public License as published by the Free Software +  Foundation; either version 3, or (at your option) any later version. + +  TALER is distributed in the hope that it will be useful, but WITHOUT ANY +  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details. + +  You should have received a copy of the GNU Affero General Public License along with +  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file mhd_run.c + * @brief API for running an MHD daemon with the + *        GNUnet scheduler + * @author Christian Grothoff + */ +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_json_lib.h> +#include <jansson.h> +#include <microhttpd.h> +#include "taler_util.h" +#include "taler_mhd_lib.h" + + +/** + * Set if we should immediately #MHD_run again. + */ +static int triggered; + +/** + * Task running the HTTP server. + */ +static struct GNUNET_SCHEDULER_Task *mhd_task; + +/** + * The MHD daemon we are running. + */ +static struct MHD_Daemon *mhd; + + +/** + * Function that queries MHD's select sets and + * starts the task waiting for them. + */ +static struct GNUNET_SCHEDULER_Task * +prepare_daemon (void); + + +/** + * Call MHD to process pending requests and then go back + * and schedule the next run. + * + * @param cls NULL + */ +static void +run_daemon (void *cls) +{ +  mhd_task = NULL; +  do { +    triggered = 0; +    GNUNET_assert (MHD_YES == +                   MHD_run (mhd)); +  } while (0 != triggered); +  mhd_task = prepare_daemon (); +} + + +/** + * Function that queries MHD's select sets and starts the task waiting for + * them. + * + * @return task handle for the MHD task. + */ +static struct GNUNET_SCHEDULER_Task * +prepare_daemon (void) +{ +  struct GNUNET_SCHEDULER_Task *ret; +  fd_set rs; +  fd_set ws; +  fd_set es; +  struct GNUNET_NETWORK_FDSet *wrs; +  struct GNUNET_NETWORK_FDSet *wws; +  int max; +  MHD_UNSIGNED_LONG_LONG timeout; +  int haveto; +  struct GNUNET_TIME_Relative tv; + +  FD_ZERO (&rs); +  FD_ZERO (&ws); +  FD_ZERO (&es); +  wrs = GNUNET_NETWORK_fdset_create (); +  wws = GNUNET_NETWORK_fdset_create (); +  max = -1; +  GNUNET_assert (MHD_YES == +                 MHD_get_fdset (mhd, +                                &rs, +                                &ws, +                                &es, +                                &max)); +  haveto = MHD_get_timeout (mhd, +                            &timeout); +  if (haveto == MHD_YES) +    tv = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, +                                        timeout); +  else +    tv = GNUNET_TIME_UNIT_FOREVER_REL; +  GNUNET_NETWORK_fdset_copy_native (wrs, +                                    &rs, +                                    max + 1); +  GNUNET_NETWORK_fdset_copy_native (wws, +                                    &ws, +                                    max + 1); +  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, +              "Adding run_daemon select task\n"); +  ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, +                                     tv, +                                     wrs, +                                     wws, +                                     &run_daemon, +                                     NULL); +  GNUNET_NETWORK_fdset_destroy (wrs); +  GNUNET_NETWORK_fdset_destroy (wws); +  return ret; +} + + +void +TALER_MHD_daemon_start (struct MHD_Daemon *daemon) +{ +  GNUNET_assert (NULL == mhd); +  mhd = daemon; +  mhd_task = prepare_daemon (); +} + + +struct MHD_Daemon * +TALER_MHD_daemon_stop (void) +{ +  struct MHD_Daemon *ret; + +  if (NULL != mhd_task) +  { +    GNUNET_SCHEDULER_cancel (mhd_task); +    mhd_task = NULL; +  } +  ret = mhd; +  mhd = NULL; +  return ret; +} + + +void +TALER_MHD_daemon_trigger (void) +{ +  if (NULL != mhd_task) +  { +    GNUNET_SCHEDULER_cancel (mhd_task); +    mhd_task = NULL; +    run_daemon (NULL); +  } +  else +  { +    triggered = 1; +  } +} + + +/* end of mhd_run.c */  | 
