Example #1
0
int     verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
{
    VSTREAM *stream;
    int     request_status;
    int     count = 0;

    /*
     * Do client-server plumbing.
     */
    if (vrfy_clnt == 0)
	verify_clnt_init();

    /*
     * Request status for this address.
     */
    for (;;) {
	stream = clnt_stream_access(vrfy_clnt);
	errno = 0;
	count += 1;
	if (attr_print(stream, ATTR_FLAG_NONE,
		       ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY,
		       ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
		       ATTR_TYPE_END) != 0
	    || vstream_fflush(stream)
	    || attr_scan(stream, ATTR_FLAG_MISSING,
			 ATTR_TYPE_INT, MAIL_ATTR_STATUS, &request_status,
			 ATTR_TYPE_INT, MAIL_ATTR_ADDR_STATUS, addr_status,
			 ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
			 ATTR_TYPE_END) != 3) {
	    if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
		msg_warn("problem talking to service %s: %m",
			 var_verify_service);
	} else {
	    break;
	}
	sleep(1);
	clnt_stream_recover(vrfy_clnt);
    }
    return (request_status);
}
Example #2
0
int     verify_clnt_update(const char *addr, int addr_status, const char *why)
{
    VSTREAM *stream;
    int     request_status;

    /*
     * Do client-server plumbing.
     */
    if (vrfy_clnt == 0)
	verify_clnt_init();

    /*
     * Send status for this address. Supply a default status if the address
     * verification service is unavailable.
     */
    for (;;) {
	stream = clnt_stream_access(vrfy_clnt);
	errno = 0;
	if (attr_print(stream, ATTR_FLAG_NONE,
		       ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_UPDATE,
		       ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
		       ATTR_TYPE_INT, MAIL_ATTR_ADDR_STATUS, addr_status,
		       ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
		       ATTR_TYPE_END) != 0
	    || attr_scan(stream, ATTR_FLAG_MISSING,
			 ATTR_TYPE_INT, MAIL_ATTR_STATUS, &request_status,
			 ATTR_TYPE_END) != 1) {
	    if (msg_verbose || (errno != EPIPE && errno != ENOENT))
		msg_warn("problem talking to service %s: %m",
			 var_verify_service);
	} else {
	    break;
	}
	sleep(1);
	clnt_stream_recover(vrfy_clnt);
    }
    return (request_status);
}
Example #3
0
VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
{
    VSTREAM *stream;
    int     server_flags;
    int     count = 0;

    /*
     * One-entry cache.
     */
    if (last_addr == 0) {
	last_rule = vstring_alloc(10);
	last_addr = vstring_alloc(100);
	last_result = vstring_alloc(100);
    }

    /*
     * Sanity check. An address must be in externalized form. The result must
     * not clobber the input, because we may have to retransmit the query.
     */
#define STR vstring_str

    if (*addr == 0)
	addr = "";
    if (addr == STR(result))
	msg_panic("rewrite_clnt: result clobbers input");

    /*
     * Peek at the cache.
     */
    if (time((time_t *) 0) < last_expire
	&& strcmp(addr, STR(last_addr)) == 0
	&& strcmp(rule, STR(last_rule)) == 0) {
	vstring_strcpy(result, STR(last_result));
	if (msg_verbose)
	    msg_info("rewrite_clnt: cached: %s: %s -> %s",
		     rule, addr, vstring_str(result));
	return (result);
    }

    /*
     * Keep trying until we get a complete response. The rewrite service is
     * CPU bound and making the client asynchronous would just complicate the
     * code.
     */
    if (rewrite_clnt_stream == 0)
	rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
						 var_rewrite_service,
						 var_ipc_idle_limit,
						 var_ipc_ttl_limit);

    for (;;) {
	stream = clnt_stream_access(rewrite_clnt_stream);
	errno = 0;
	count += 1;
	if (attr_print(stream, ATTR_FLAG_NONE,
		       ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
		       ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
		       ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
		       ATTR_TYPE_END) != 0
	    || vstream_fflush(stream)
	    || attr_scan(stream, ATTR_FLAG_STRICT,
			 ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &server_flags,
			 ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
			 ATTR_TYPE_END) != 2) {
	    if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
		msg_warn("problem talking to service %s: %m",
			 var_rewrite_service);
	} else {
	    if (msg_verbose)
		msg_info("rewrite_clnt: %s: %s -> %s",
			 rule, addr, vstring_str(result));
	    /* Server-requested disconnect. */
	    if (server_flags != 0)
		clnt_stream_recover(rewrite_clnt_stream);
	    break;
	}
	sleep(1);				/* XXX make configurable */
	clnt_stream_recover(rewrite_clnt_stream);
    }

    /*
     * Update the cache.
     */
    vstring_strcpy(last_rule, rule);
    vstring_strcpy(last_addr, addr);
    vstring_strcpy(last_result, STR(result));
    last_expire = time((time_t *) 0) + 30;	/* XXX make configurable */

    return (result);
}