コード例 #1
0
int     main(int unused_argc, char **argv)
{
    HTABLE *table = htable_create(1);

    msg_vstream_init(argv[0], VSTREAM_ERR);
    msg_verbose = 1;
    htable_enter(table, "foo-name", mystrdup("foo-value"));
    htable_enter(table, "bar-name", mystrdup("bar-value"));
    attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
		     ATTR_TYPE_INT, ATTR_NAME_INT, 4711,
		     ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
		     ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
	       ATTR_TYPE_DATA, ATTR_NAME_DATA, strlen("whoopee"), "whoopee",
		     ATTR_TYPE_HASH, table,
		     ATTR_TYPE_END);
    attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
		     ATTR_TYPE_INT, ATTR_NAME_INT, 4711,
		     ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
		     ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
	       ATTR_TYPE_DATA, ATTR_NAME_DATA, strlen("whoopee"), "whoopee",
		     ATTR_TYPE_END);
    if (vstream_fflush(VSTREAM_OUT) != 0)
	msg_fatal("write error: %m");

    htable_free(table, myfree);
    return (0);
}
コード例 #2
0
ファイル: anvil.c プロジェクト: ajinkya93/netbsd-src
static void anvil_remote_disconnect(VSTREAM *client_stream, const char *ident)
{
    ANVIL_REMOTE *anvil_remote;
    ANVIL_LOCAL *anvil_local;
    const char *myname = "anvil_remote_disconnect";

    if (msg_verbose)
	msg_info("%s fd=%d stream=0x%lx ident=%s",
		 myname, vstream_fileno(client_stream),
		 (unsigned long) client_stream, ident);

    /*
     * Update local and remote info if this remote connection is listed for
     * this local server.
     */
    if ((anvil_local = (ANVIL_LOCAL *) vstream_context(client_stream)) != 0
	&& (anvil_remote =
	    (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) != 0
	&& ANVIL_LOCAL_REMOTE_LINKED(anvil_local, anvil_remote)) {
	ANVIL_REMOTE_DROP_ONE(anvil_remote);
	ANVIL_LOCAL_DROP_ONE(anvil_local, anvil_remote);
    }
    if (msg_verbose)
	msg_info("%s: anvil_local 0x%lx",
		 myname, (unsigned long) anvil_local);

    /*
     * Respond to the local server.
     */
    attr_print_plain(client_stream, ATTR_FLAG_NONE,
		     ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_OK,
		     ATTR_TYPE_END);
}
コード例 #3
0
ファイル: anvil.c プロジェクト: ajinkya93/netbsd-src
static void anvil_remote_newtls_stat(VSTREAM *client_stream, const char *ident)
{
    ANVIL_REMOTE *anvil_remote;
    int     rate;

    /*
     * Be prepared for "postfix reload" after "connect".
     */
    if ((anvil_remote =
	 (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) == 0) {
	rate = 0;
    }

    /*
     * Do not report stale information.
     */
    else {
	if (anvil_remote->start != 0
	    && anvil_remote->start + var_anvil_time_unit < event_time())
	    ANVIL_REMOTE_RSET_RATE(anvil_remote, 0);
	rate = anvil_remote->ntls;
    }

    /*
     * Respond to local server.
     */
    attr_print_plain(client_stream, ATTR_FLAG_NONE,
		     ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_OK,
		     ATTR_TYPE_INT, ANVIL_ATTR_RATE, rate,
		     ATTR_TYPE_END);
}
コード例 #4
0
ファイル: anvil.c プロジェクト: ajinkya93/netbsd-src
static void anvil_remote_newtls(VSTREAM *client_stream, const char *ident)
{
    ANVIL_REMOTE *anvil_remote;

    /*
     * Be prepared for "postfix reload" after "connect".
     */
    if ((anvil_remote =
	 (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) == 0)
	anvil_remote = anvil_remote_conn_update(client_stream, ident);

    /*
     * Update newtls rate and respond to local server.
     */
    ANVIL_REMOTE_INCR_NTLS(anvil_remote);
    attr_print_plain(client_stream, ATTR_FLAG_NONE,
		     ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_OK,
		     ATTR_TYPE_INT, ANVIL_ATTR_RATE, anvil_remote->ntls,
		     ATTR_TYPE_END);

    /*
     * Update peak statistics.
     */
    if (anvil_remote->ntls > max_ntls_rate.value)
	ANVIL_MAX_UPDATE(max_ntls_rate, anvil_remote->ntls, anvil_remote->ident);
}
コード例 #5
0
ファイル: anvil.c プロジェクト: ajinkya93/netbsd-src
static void anvil_remote_connect(VSTREAM *client_stream, const char *ident)
{
    ANVIL_REMOTE *anvil_remote;

    /*
     * Update or instantiate connection info.
     */
    anvil_remote = anvil_remote_conn_update(client_stream, ident);

    /*
     * Respond to the local server.
     */
    attr_print_plain(client_stream, ATTR_FLAG_NONE,
		     ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_OK,
		     ATTR_TYPE_INT, ANVIL_ATTR_COUNT, anvil_remote->count,
		     ATTR_TYPE_INT, ANVIL_ATTR_RATE, anvil_remote->rate,
		     ATTR_TYPE_END);

    /*
     * Update peak statistics.
     */
    if (anvil_remote->rate > max_conn_rate.value)
	ANVIL_MAX_UPDATE(max_conn_rate, anvil_remote->rate, anvil_remote->ident);
    if (anvil_remote->count > max_conn_count.value)
	ANVIL_MAX_UPDATE(max_conn_count, anvil_remote->count, anvil_remote->ident);
}
コード例 #6
0
ファイル: anvil.c プロジェクト: ajinkya93/netbsd-src
static void anvil_remote_lookup(VSTREAM *client_stream, const char *ident)
{
    ANVIL_REMOTE *anvil_remote;
    const char *myname = "anvil_remote_lookup";

    if (msg_verbose)
	msg_info("%s fd=%d stream=0x%lx ident=%s",
		 myname, vstream_fileno(client_stream),
		 (unsigned long) client_stream, ident);

    /*
     * Look up remote client information.
     */
    if ((anvil_remote =
	 (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) == 0) {
	attr_print_plain(client_stream, ATTR_FLAG_NONE,
			 ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_OK,
			 ATTR_TYPE_INT, ANVIL_ATTR_COUNT, 0,
			 ATTR_TYPE_INT, ANVIL_ATTR_RATE, 0,
			 ATTR_TYPE_INT, ANVIL_ATTR_MAIL, 0,
			 ATTR_TYPE_INT, ANVIL_ATTR_RCPT, 0,
			 ATTR_TYPE_INT, ANVIL_ATTR_NTLS, 0,
			 ATTR_TYPE_END);
    } else {

	/*
	 * Do not report stale information.
	 */
	if (anvil_remote->start != 0
	    && anvil_remote->start + var_anvil_time_unit < event_time())
	    ANVIL_REMOTE_RSET_RATE(anvil_remote, 0);
	attr_print_plain(client_stream, ATTR_FLAG_NONE,
			 ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_OK,
		       ATTR_TYPE_INT, ANVIL_ATTR_COUNT, anvil_remote->count,
			 ATTR_TYPE_INT, ANVIL_ATTR_RATE, anvil_remote->rate,
			 ATTR_TYPE_INT, ANVIL_ATTR_MAIL, anvil_remote->mail,
			 ATTR_TYPE_INT, ANVIL_ATTR_RCPT, anvil_remote->rcpt,
			 ATTR_TYPE_INT, ANVIL_ATTR_NTLS, anvil_remote->ntls,
			 ATTR_TYPE_END);
    }
}
コード例 #7
0
ファイル: anvil.c プロジェクト: ajinkya93/netbsd-src
static void anvil_service(VSTREAM *client_stream, char *unused_service, char **argv)
{
    static VSTRING *request;
    static VSTRING *ident;
    static const ANVIL_REQ_TABLE request_table[] = {
	ANVIL_REQ_CONN, anvil_remote_connect,
	ANVIL_REQ_MAIL, anvil_remote_mail,
	ANVIL_REQ_RCPT, anvil_remote_rcpt,
	ANVIL_REQ_NTLS, anvil_remote_newtls,
	ANVIL_REQ_DISC, anvil_remote_disconnect,
	ANVIL_REQ_NTLS_STAT, anvil_remote_newtls_stat,
	ANVIL_REQ_LOOKUP, anvil_remote_lookup,
	0, 0,
    };
    const ANVIL_REQ_TABLE *rp;

    /*
     * Sanity check. This service takes no command-line arguments.
     */
    if (argv[0])
	msg_fatal("unexpected command-line argument: %s", argv[0]);

    /*
     * Initialize.
     */
    if (request == 0) {
	request = vstring_alloc(10);
	ident = vstring_alloc(10);
    }

    /*
     * This routine runs whenever a client connects to the socket dedicated
     * to the client connection rate management service. All
     * connection-management stuff is handled by the common code in
     * multi_server.c.
     */
    if (msg_verbose)
	msg_info("--- start request ---");
    if (attr_scan_plain(client_stream,
			ATTR_FLAG_MISSING | ATTR_FLAG_STRICT,
			ATTR_TYPE_STR, ANVIL_ATTR_REQ, request,
			ATTR_TYPE_STR, ANVIL_ATTR_IDENT, ident,
			ATTR_TYPE_END) == 2) {
	for (rp = request_table; /* see below */ ; rp++) {
	    if (rp->name == 0) {
		msg_warn("unrecognized request: \"%s\", ignored", STR(request));
		attr_print_plain(client_stream, ATTR_FLAG_NONE,
			  ATTR_TYPE_INT, ANVIL_ATTR_STATUS, ANVIL_STAT_FAIL,
				 ATTR_TYPE_END);
		break;
	    }
	    if (STREQ(rp->name, STR(request))) {
		rp->action(client_stream, STR(ident));
		break;
	    }
	}
	vstream_fflush(client_stream);
    } else {
	/* Note: invokes anvil_service_done() */
	multi_server_disconnect(client_stream);
    }
    if (msg_verbose)
	msg_info("--- end request ---");
}
コード例 #8
0
ファイル: smtp_session.c プロジェクト: tmtm/postfix
int     smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
			               VSTRING *endp_prop)
{
    SMTP_ITERATOR *iter = session->iterator;
    VSTREAM *mp;
    int     fd;

    /*
     * Encode the delivery request next-hop to endpoint binding properties:
     * whether or not this server is best MX host for the delivery request
     * next-hop or fall-back logical destination (this information is needed
     * for loop handling in smtp_proto()).
     * 
     * TODO: save SASL username and password information so that we can
     * correctly save a reused authenticated connection.
     * 
     * These memory writes should never fail.
     */
    if ((mp = vstream_memopen(dest_prop, O_WRONLY)) == 0
	|| attr_print_plain(mp, ATTR_FLAG_NONE,
			    SEND_ATTR_STR(SESS_ATTR_DEST, STR(iter->dest)),
			    SEND_ATTR_STR(SESS_ATTR_HOST, STR(iter->host)),
			    SEND_ATTR_STR(SESS_ATTR_ADDR, STR(iter->addr)),
			    SEND_ATTR_INT(SESS_ATTR_DEST_FEATURES,
			 session->features & SMTP_FEATURE_DESTINATION_MASK),
			    ATTR_TYPE_END) != 0
	|| vstream_fclose(mp) != 0)
	msg_fatal("smtp_session_passivate: can't save dest properties: %m");

    /*
     * Encode the physical endpoint properties: all the session properties
     * except for "session from cache", "best MX", or "RSET failure". Plus
     * the TLS level, reuse count, and connection expiration time.
     * 
     * XXX Should also record how many non-delivering mail transactions there
     * were during this session, and perhaps other statistics, so that we
     * don't reuse a session too much.
     * 
     * TODO: passivate SASL username and password information so that we can
     * correctly save a reused authenticated connection.
     * 
     * These memory writes should never fail.
     */
    if ((mp = vstream_memopen(endp_prop, O_WRONLY)) == 0
	|| attr_print_plain(mp, ATTR_FLAG_NONE,
#ifdef USE_TLS
			    SEND_ATTR_INT(SESS_ATTR_TLS_LEVEL,
					  session->state->tls->level),
#endif
			    SEND_ATTR_INT(SESS_ATTR_REUSE_COUNT,
					  session->reuse_count),
			    SEND_ATTR_INT(SESS_ATTR_ENDP_FEATURES,
			    session->features & SMTP_FEATURE_ENDPOINT_MASK),
			    SEND_ATTR_LONG(SESS_ATTR_EXPIRE_TIME,
					   (long) session->expire_time),
			    ATTR_TYPE_END) != 0

    /*
     * Append the passivated TLS context. These memory writes should never
     * fail.
     */
#ifdef USE_TLS
	|| (session->tls_context
	    && attr_print_plain(mp, ATTR_FLAG_NONE,
				SEND_ATTR_FUNC(tls_proxy_context_print,
					     (void *) session->tls_context),
				ATTR_TYPE_END) != 0)
#endif
	|| vstream_fclose(mp) != 0)
	msg_fatal("smtp_session_passivate: cannot save TLS context: %m");

    /*
     * Salvage the underlying file descriptor, and destroy the session
     * object.
     */
    fd = vstream_fileno(session->stream);
    vstream_fdclose(session->stream);
    session->stream = 0;
    smtp_session_free(session);

    return (fd);
}