static void multi_server_accept_pass(int unused_event, char *context) { int listen_fd = CAST_CHAR_PTR_TO_INT(context); int time_left = -1; int fd; /* * Be prepared for accept() to fail because some other process already * got the connection (the number of processes competing for clients is * kept small, so this is not a "thundering herd" problem). If the * accept() succeeds, be sure to disable non-blocking I/O, in order to * minimize confusion. */ if (client_count == 0 && var_idle_limit > 0) time_left = event_cancel_timer(multi_server_timeout, (char *) 0); if (multi_server_pre_accept) multi_server_pre_accept(multi_server_name, multi_server_argv); fd = PASS_ACCEPT(listen_fd); if (multi_server_lock != 0 && myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0) msg_fatal("select unlock: %m"); if (fd < 0) { if (errno != EAGAIN) msg_error("accept connection: %m"); if (time_left >= 0) event_request_timer(multi_server_timeout, (char *) 0, time_left); return; } multi_server_wakeup(fd); }
PSC_STATE *psc_new_session_state(VSTREAM *stream, const char *client_addr, const char *client_port, const char *server_addr, const char *server_port) { PSC_STATE *state; HTABLE_INFO *ht; state = (PSC_STATE *) mymalloc(sizeof(*state)); PSC_INIT_TESTS(state); if ((state->smtp_client_stream = stream) != 0) psc_check_queue_length++; state->smtp_server_fd = (-1); state->smtp_client_addr = mystrdup(client_addr); state->smtp_client_port = mystrdup(client_port); state->smtp_server_addr = mystrdup(server_addr); state->smtp_server_port = mystrdup(server_port); state->send_buf = vstring_alloc(100); state->test_name = "TEST NAME HERE"; state->dnsbl_reply = 0; state->final_reply = "421 4.3.2 Service currently unavailable\r\n"; state->rcpt_reply = "450 4.3.2 Service currently unavailable\r\n"; state->command_count = 0; state->protocol = MAIL_PROTO_SMTP; state->helo_name = 0; state->sender = 0; state->cmd_buffer = 0; state->read_state = 0; state->ehlo_discard_mask = 0; /* XXX Should be ~0 */ state->expand_buf = 0; state->where = PSC_SMTPD_CMD_CONNECT; /* * Update the stress level. */ if (psc_stress == 0 && psc_check_queue_length >= psc_hiwat_check_queue_length) { psc_stress = 1; msg_info("entering STRESS mode with %d connections", psc_check_queue_length); } /* * Update the per-client session count. */ if ((ht = htable_locate(psc_client_concurrency, client_addr)) == 0) ht = htable_enter(psc_client_concurrency, client_addr, (char *) 0); ht->value += 1; state->client_concurrency = CAST_CHAR_PTR_TO_INT(ht->value); return (state); }
static void trigger_server_accept_pass(int unused_event, char *context) { const char *myname = "trigger_server_accept_pass"; int listen_fd = CAST_CHAR_PTR_TO_INT(context); int time_left = 0; int fd; if (msg_verbose) msg_info("%s: trigger arrived", myname); /* * Read a message from a socket. Be prepared for accept() to fail because * some other process already got the connection. The socket is * non-blocking so we won't get stuck when multiple processes wake up. * Don't get stuck when the client connects but sends no data. Restart * the idle timer if this was a false alarm. */ if (var_idle_limit > 0) time_left = event_cancel_timer(trigger_server_timeout, (char *) 0); if (trigger_server_pre_accept) trigger_server_pre_accept(trigger_server_name, trigger_server_argv); fd = pass_accept(listen_fd); if (trigger_server_lock != 0 && myflock(vstream_fileno(trigger_server_lock), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0) msg_fatal("select unlock: %m"); if (fd < 0) { if (errno != EAGAIN) msg_error("accept connection: %m"); if (time_left >= 0) event_request_timer(trigger_server_timeout, (char *) 0, time_left); return; } close_on_exec(fd, CLOSE_ON_EXEC); if (read_wait(fd, 10) == 0) trigger_server_wakeup(fd); else if (time_left >= 0) event_request_timer(trigger_server_timeout, (char *) 0, time_left); close(fd); }
static void trigger_server_accept_fifo(int unused_event, char *context) { const char *myname = "trigger_server_accept_fifo"; int listen_fd = CAST_CHAR_PTR_TO_INT(context); if (trigger_server_lock != 0 && myflock(vstream_fileno(trigger_server_lock), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0) msg_fatal("select unlock: %m"); if (msg_verbose) msg_info("%s: trigger arrived", myname); /* * Read whatever the other side wrote into the FIFO. The FIFO read end is * non-blocking so we won't get stuck when multiple processes wake up. */ if (trigger_server_pre_accept) trigger_server_pre_accept(trigger_server_name, trigger_server_argv); trigger_server_wakeup(listen_fd); }