#ifndef MASTER_SERVICE_H
#define MASTER_SERVICE_H
#include "net.h"
#include <unistd.h> /* for getopt() opt* variables */
#include <stdio.h> /* for getopt() opt* variables in Solaris */
enum master_service_flags {
/* this process is currently running standalone without a master */
/* Log to configured log file instead of stderr. By default when
_FLAG_STANDALONE is set, logging is done to stderr. */
/* Service is going to do multiple configuration lookups,
keep the connection to config service open. Also opens the config
socket before dropping privileges. */
/* Don't read settings, but use whatever is in environment */
/* Use MASTER_LOGIN_NOTIFY_FD to track login overflow state */
/* If master sends SIGINT, don't die even if we don't have clients */
/* Show number of connections in process title
(only if verbose_proctitle setting is enabled) */
/* SSL settings are always looked up when we have ssl listeners.
This flag enables looking up SSL settings even without ssl
listeners (i.e. the service does STARTTLS). */
/* Don't initialize SSL context automatically. */
/* Don't create a data stack frame between master_service_init() and
master_service_init_finish(). By default this is done to make sure
initialization doesn't unnecessarily use up memory in data stack. */
/* This process supports sending statistics to the stats process.
Connect to it at startup. */
};
struct master_service_connection_proxy {
/* only set if ssl is TRUE */
const char *hostname;
const char *cert_common_name;
const unsigned char *alpn;
unsigned int alpn_size;
};
struct master_service_connection {
/* fd of the new connection. */
int fd;
/* fd of the socket listener. Same as fd for a FIFO. */
int listen_fd;
/* listener name as in configuration file, or "" if unnamed. */
const char *name;
by the haproxy protocol. */
/* filled if connection is proxied */
/* This is a connection proxied wit HAproxy (or similar) */
/* This is a FIFO fd. Only a single "connection" is ever received from
a FIFO after the first writer sends something to it. */
/* Perform immediate SSL handshake for this connection. Currently this
needs to be performed explicitly by each service. */
/* Internal: master_service_client_connection_accept() has been
called for this connection. */
};
typedef void
extern struct master_service *master_service;
const char *master_service_getopt_string(void);
/* Start service initialization. */
struct master_service *
/* Call getopt() and handle internal parameters. Return values are the same as
getopt()'s. */
/* Returns TRUE if str is a valid getopt_str. Currently this only checks for
duplicate args so they aren't accidentally added. */
bool master_getopt_str_is_valid(const char *str);
/* Parser command line option. Returns TRUE if processed. */
/* Finish service initialization. The caller should drop privileges
before calling this. This also notifies the master that the service was
successfully started and there shouldn't be any service throttling even if
it crashes afterwards, so this should be called after all of the
initialization code is finished. */
/* import_environment is a space-separated list of environment keys or
key=values. The key=values are immediately added to the environment.
All the keys are added to DOVECOT_PRESERVE_ENVS environment so they're
preserved by master_service_env_clean(). */
void master_service_import_environment(const char *import_environment);
/* Clean environment from everything except the ones listed in
DOVECOT_PRESERVE_ENVS environment. */
void master_service_env_clean(void);
/* Initialize logging. Only the first call changes the actual logging
functions. The following calls change the log prefix. */
const char *prefix);
/* Initialize stats client (if it's not already initialized). This is called
automatically if MASTER_SERVICE_FLAG_SEND_STATS is enabled. If
silent_notfound_errors is set, connect() errors aren't logged if they're
happening because the stats service isn't running. */
bool silent_notfound_errors);
/* If set, die immediately when connection to master is lost.
Normally all existing clients are handled first. */
bool set);
/* Call the given when master connection dies and die_with_master is TRUE.
The callback is expected to shut down the service somewhat soon or it's
done forcibly. If NULL, the service is stopped immediately. */
void (*callback)(void));
/* "idle callback" is called when master thinks we're idling and asks us to
die. We'll do it only if the idle callback returns TRUE. This callback isn't
even called if the master service code knows that we're handling clients. */
bool (*callback)(void));
/* Call the given callback when there are no available connections and master
has indicated that it can't create any more processes to handle requests.
The callback could decide to kill one of the existing connections. */
void (*callback)(void));
/* Set maximum number of clients we can handle. Default is given by master. */
unsigned int client_limit);
/* Returns the maximum number of clients we can handle. */
/* Returns how many processes of this type can be created before reaching the
limit. */
/* Returns service { process_min_avail } */
/* Returns the service's idle_kill timeout in seconds. Normally master handles
sending the kill request when the process has no clients, but some services
with permanent client connections may need to handle this themselves. */
/* Set maximum number of client connections we will handle before shutting
down. */
unsigned int count);
/* Returns the number of client connections we will handle before shutting
down. The value is decreased only after connection has been closed. */
/* Return the number of listener sockets. */
/* Returns the name of the listener socket, or "" if none is specified. */
int listen_fd);
/* Returns configuration file path. */
/* Returns PACKAGE_VERSION or NULL if version_ignore=yes. This function is
useful mostly as parameter to module_dir_load(). */
/* Returns name of the service, as given in name parameter to _init(). */
/* Start the service. Blocks until finished */
ATTR_NULL(2);
/* Stop a running service. */
/* Stop once we're done serving existing new connections, but don't accept
any new ones. */
/* Returns TRUE if our master process is already stopped. This process may or
may not be dying itself. Returns FALSE always if the process was started
standalone. */
/* Send command to anvil process, if we have fd to it. */
/* Call to accept the client connection. Otherwise the connection is closed. */
/* Used to create "extra client connections" outside the common accept()
method. */
/* Call whenever a client connection is destroyed. */
/* Deinitialize the service. */
/* Returns TRUE if line contains compatible service name and major version.
The line is expected to be in format:
VERSION <tab> service_name <tab> major version <tab> minor version */
unsigned major_version);
/* Same as version_string_verify(), but return the minor version. */
unsigned major_version,
unsigned int *minor_version_r);
/* Returns TRUE if ssl module has been loaded */
#endif