Skip to content

Commit

Permalink
user can sepcify the max connections piler-smtp can handle
Browse files Browse the repository at this point in the history
Change-Id: Id92d625d354838558a63dfdd668143168bb7ebee
Signed-off-by: SJ <sj@acts.hu>
  • Loading branch information
jsuto committed Oct 30, 2016
1 parent 49348fd commit 4a1c178
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
8 changes: 7 additions & 1 deletion etc/example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)},
Expand Down
1 change: 1 addition & 0 deletions src/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
28 changes: 18 additions & 10 deletions src/piler-smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,19 @@
#include <piler.h>

#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;

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){
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand All @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand All @@ -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;
Expand Down

0 comments on commit 4a1c178

Please sign in to comment.