From 4a1c1785d17d1d992447e3cce7a32a50622c2306 Mon Sep 17 00:00:00 2001 From: SJ Date: Sun, 30 Oct 2016 22:53:49 +0100 Subject: [PATCH] user can sepcify the max connections piler-smtp can handle Change-Id: Id92d625d354838558a63dfdd668143168bb7ebee Signed-off-by: SJ --- etc/example.conf | 8 +++++++- src/cfg.c | 1 + src/cfg.h | 1 + src/piler-smtp.c | 28 ++++++++++++++++++---------- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/etc/example.conf b/etc/example.conf index ab6c44cd..655baafb 100644 --- a/etc/example.conf +++ b/etc/example.conf @@ -35,7 +35,13 @@ default_retention_days=2557 encrypt_messages=1 ; number of worker processes, ie. the number of simultaneous smtp connections to piler. -number_of_worker_processes=10 +; This value should be the number of cpus + 1, ie. 2 for a single cpu host +number_of_worker_processes=2 + +; max. number of parallel connections piler-smtp can handle. +; Important! If you want to change this value, then you must first +; stop piler-smtp, change the value, then start piler-smtp. +max_connections=256 ; number of processed emails per each piler process max_requests_per_child=1000 diff --git a/src/cfg.c b/src/cfg.c index 3dc1a7b7..634b515e 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -80,6 +80,7 @@ struct _parse_rule config_parse_rules[] = { "listen_addr", "string", (void*) string_parser, offsetof(struct __config, listen_addr), "0.0.0.0", MAXVAL-1}, { "listen_port", "integer", (void*) int_parser, offsetof(struct __config, listen_port), "25", sizeof(int)}, { "locale", "string", (void*) string_parser, offsetof(struct __config, locale), "", MAXVAL-1}, + { "max_connections", "integer", (void*) int_parser, offsetof(struct __config, max_connections), "256", sizeof(int)}, { "max_requests_per_child", "integer", (void*) int_parser, offsetof(struct __config, max_requests_per_child), "1000", sizeof(int)}, { "memcached_servers", "string", (void*) string_parser, offsetof(struct __config, memcached_servers), "127.0.0.1", MAXVAL-1}, { "memcached_to_db_interval", "integer", (void*) int_parser, offsetof(struct __config, memcached_to_db_interval), "900", sizeof(int)}, diff --git a/src/cfg.h b/src/cfg.h index bd1a3e66..18dc2190 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -35,6 +35,7 @@ struct __config { char memcached_servers[MAXVAL]; int memcached_ttl; + int max_connections; int number_of_worker_processes; int max_requests_per_child; diff --git a/src/piler-smtp.c b/src/piler-smtp.c index 11e5d9b9..4e38127e 100644 --- a/src/piler-smtp.c +++ b/src/piler-smtp.c @@ -26,12 +26,11 @@ #include #define PROGNAME "piler-smtp" -#define POLL_SIZE 256 extern char *optarg; extern int optind; -struct pollfd poll_set[POLL_SIZE]; +struct pollfd *poll_set=NULL; int timeout = 20; // checking for timeout this often [sec] int numfds = 0; int listenerfd = -1; @@ -39,7 +38,7 @@ int listenerfd = -1; char *configfile = CONFIG_FILE; struct __config cfg; struct passwd *pwd; -struct smtp_session *session, *sessions[POLL_SIZE]; +struct smtp_session *session, **sessions=NULL; void handle_data(struct smtp_session *session, char *readbuf, int readlen){ @@ -130,10 +129,8 @@ void init_smtp_session(struct smtp_session *session, int fd_index, int sd){ void free_smtp_session(struct smtp_session *session){ if(session){ - //printf("freeing session\n"); if(session->use_ssl == 1){ - //printf("shutdown ssl\n"); SSL_shutdown(session->ssl); SSL_free(session->ssl); } @@ -156,6 +153,9 @@ void p_clean_exit(){ free_smtp_session(sessions[i]); } + if(sessions) free(sessions); + if(poll_set) free(poll_set); + syslog(LOG_PRIORITY, "%s has been terminated", PROGNAME); //unlink(cfg.pidfile); @@ -180,7 +180,6 @@ void tear_down_client(int n){ syslog(LOG_PRIORITY, "disconnected from %s", sessions[n]->remote_host); - // new code free_smtp_session(sessions[n]); sessions[n] = NULL; @@ -286,7 +285,7 @@ void start_new_session(int socket, struct sockaddr_storage client_address, int f char smtp_banner[SMALLBUFSIZE], remote_host[INET6_ADDRSTRLEN]; // Uh-oh! We have enough connections to serve already - if(numfds >= POLL_SIZE){ + if(numfds >= cfg.max_connections){ inet_ntop(client_address.ss_family, get_in_addr((struct sockaddr*)&client_address), remote_host, sizeof(remote_host)); syslog(LOG_PRIORITY, "too many connections (%d), cannot accept %s", numfds, remote_host); send(socket, SMTP_RESP_421_ERR_ALL_PORTS_ARE_BUSY, strlen(SMTP_RESP_421_ERR_ALL_PORTS_ARE_BUSY), 0); @@ -384,11 +383,12 @@ int main(int argc, char **argv){ (void) openlog(PROGNAME, LOG_PID, LOG_MAIL); - memset(sessions, '\0', sizeof(sessions)); - memset(poll_set, '\0', sizeof(poll_set)); - initialise_configuration(); + // The max_connections variable mustn't be affected by a reload! + if(cfg.max_connections < 10) cfg.max_connections = 10; + if(cfg.max_connections > 10000) cfg.max_connections = 10000; + listenerfd = create_listener_socket(cfg.listen_addr, cfg.listen_port); if(listenerfd == -1){ syslog(LOG_PRIORITY, "create_listener_socket() error"); @@ -397,12 +397,20 @@ int main(int argc, char **argv){ if(drop_privileges(pwd)) fatal(ERR_SETUID); + set_signal_handler(SIGINT, p_clean_exit); set_signal_handler(SIGTERM, p_clean_exit); set_signal_handler(SIGALRM, check_for_client_timeout); set_signal_handler(SIGHUP, initialise_configuration); alarm(timeout); + // calloc() initialitizes the allocated memory + + sessions = calloc(cfg.max_connections, sizeof(struct smtp_session)); + poll_set = calloc(cfg.max_connections, sizeof(struct pollfd)); + + if(!sessions || !poll_set) fatal("calloc() error"); + poll_set[0].fd = listenerfd; poll_set[0].events = POLLIN; numfds = 1;