示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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);
}
示例#4
0
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);
}