1/*++ 2/* NAME 3/* smtpd_resolve 3 4/* SUMMARY 5/* caching resolve client 6/* SYNOPSIS 7/* #include <smtpd_resolve.h> 8/* 9/* void smtpd_resolve_init(cache_size) 10/* int cache_size; 11/* 12/* const RESOLVE_REPLY *smtpd_resolve_addr(addr) 13/* const char *addr; 14/* DESCRIPTION 15/* This module maintains a resolve client cache that persists 16/* across SMTP sessions (not process life times). Addresses 17/* are always resolved in local rewriting context. 18/* 19/* smtpd_resolve_init() initializes the cache and must 20/* called once before the cache can be used. 21/* 22/* smtpd_resolve_addr() resolves one address or returns 23/* a known result from cache. 24/* 25/* Arguments: 26/* .IP cache_size 27/* The requested cache size. 28/* .IP addr 29/* The address to resolve. 30/* DIAGNOSTICS 31/* All errors are fatal. 32/* BUGS 33/* The recipient address is always case folded to lowercase. 34/* Changing this requires great care, since the address is used 35/* for policy lookups. 36/* LICENSE 37/* .ad 38/* .fi 39/* The Secure Mailer license must be distributed with this software. 40/* AUTHOR(S) 41/* Wietse Venema 42/* IBM T.J. Watson Research 43/* P.O. Box 704 44/* Yorktown Heights, NY 10598, USA 45/*--*/ 46 47/* System library. */ 48 49#include <sys_defs.h> 50 51/* Utility library. */ 52 53#include <msg.h> 54#include <mymalloc.h> 55#include <vstring.h> 56#include <ctable.h> 57#include <stringops.h> 58 59/* Global library. */ 60 61#include <rewrite_clnt.h> 62#include <resolve_clnt.h> 63#include <mail_proto.h> 64 65/* Application-specific. */ 66 67#include <smtpd_resolve.h> 68 69static CTABLE *smtpd_resolve_cache; 70 71#define STR(x) vstring_str(x) 72 73/* resolve_pagein - page in an address resolver result */ 74 75static void *resolve_pagein(const char *addr, void *unused_context) 76{ 77 static VSTRING *query; 78 RESOLVE_REPLY *reply; 79 80 /* 81 * Initialize on the fly. 82 */ 83 if (query == 0) 84 query = vstring_alloc(10); 85 86 /* 87 * Initialize. 88 */ 89 reply = (RESOLVE_REPLY *) mymalloc(sizeof(*reply)); 90 resolve_clnt_init(reply); 91 92 /* 93 * Resolve the address. 94 */ 95 rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, addr, query); 96 resolve_clnt_query(STR(query), reply); 97 lowercase(STR(reply->recipient)); /* XXX */ 98 99 /* 100 * Save the result. 101 */ 102 return ((void *) reply); 103} 104 105/* resolve_pageout - page out an address resolver result */ 106 107static void resolve_pageout(void *data, void *unused_context) 108{ 109 RESOLVE_REPLY *reply = (RESOLVE_REPLY *) data; 110 111 resolve_clnt_free(reply); 112 myfree((void *) reply); 113} 114 115/* smtpd_resolve_init - set up global cache */ 116 117void smtpd_resolve_init(int cache_size) 118{ 119 120 /* 121 * Sanity check. 122 */ 123 if (smtpd_resolve_cache) 124 msg_panic("smtpd_resolve_init: multiple initialization"); 125 126 /* 127 * Initialize the resolved address cache. Note: the cache persists across 128 * SMTP sessions so we cannot make it dependent on session state. 129 */ 130 smtpd_resolve_cache = ctable_create(cache_size, resolve_pagein, 131 resolve_pageout, (void *) 0); 132} 133 134/* smtpd_resolve_addr - resolve cached addres */ 135 136const RESOLVE_REPLY *smtpd_resolve_addr(const char *addr) 137{ 138 139 /* 140 * Sanity check. 141 */ 142 if (smtpd_resolve_cache == 0) 143 msg_panic("smtpd_resolve_addr: missing initialization"); 144 145 /* 146 * Reply from the read-through cache. 147 */ 148 return (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, addr); 149} 150