Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / scache_single.c
blob6dea1bfdc4d5cb9cfc6e885713d361eac37be8c5
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* scache_single 3
6 /* SUMMARY
7 /* single-item session cache
8 /* SYNOPSIS
9 /* #include <scache.h>
10 /* DESCRIPTION
11 /* SCACHE *scache_single_create()
12 /* DESCRIPTION
13 /* This module implements an in-memory, single-session cache.
15 /* scache_single_create() creates a session cache instance
16 /* that stores a single session.
17 /* DIAGNOSTICS
18 /* Fatal error: memory allocation problem;
19 /* panic: internal consistency failure.
20 /* SEE ALSO
21 /* scache(3), generic session cache API
22 /* LICENSE
23 /* .ad
24 /* .fi
25 /* The Secure Mailer license must be distributed with this software.
26 /* AUTHOR(S)
27 /* Wietse Venema
28 /* IBM T.J. Watson Research
29 /* P.O. Box 704
30 /* Yorktown Heights, NY 10598, USA
31 /*--*/
33 /* System library. */
35 #include <sys_defs.h>
36 #include <unistd.h>
37 #include <string.h>
39 /* Utility library. */
41 #include <msg.h>
42 #include <vstring.h>
43 #include <mymalloc.h>
44 #include <events.h>
46 /*#define msg_verbose 1*/
48 /* Global library. */
50 #include <scache.h>
52 /* Application-specific. */
55 * Data structure for one saved connection. It is left up to the application
56 * to serialize attributes upon passivation, and to de-serialize them upon
57 * re-activation.
59 typedef struct {
60 VSTRING *endp_label; /* physical endpoint name */
61 VSTRING *endp_prop; /* endpoint properties, serialized */
62 int fd; /* the session */
63 } SCACHE_SINGLE_ENDP;
66 * Data structure for a logical name to physical endpoint binding. It is
67 * left up to the application to serialize attributes upon passivation, and
68 * to de-serialize then upon re-activation.
70 typedef struct {
71 VSTRING *dest_label; /* logical destination name */
72 VSTRING *dest_prop; /* binding properties, serialized */
73 VSTRING *endp_label; /* physical endpoint name */
74 } SCACHE_SINGLE_DEST;
77 * SCACHE_SINGLE is a derived type from the SCACHE super-class.
79 typedef struct {
80 SCACHE scache[1]; /* super-class */
81 SCACHE_SINGLE_ENDP endp; /* one cached session */
82 SCACHE_SINGLE_DEST dest; /* one cached binding */
83 } SCACHE_SINGLE;
85 static void scache_single_expire_endp(int, char *);
86 static void scache_single_expire_dest(int, char *);
88 #define SCACHE_SINGLE_ENDP_BUSY(sp) (VSTRING_LEN(sp->endp.endp_label) > 0)
89 #define SCACHE_SINGLE_DEST_BUSY(sp) (VSTRING_LEN(sp->dest.dest_label) > 0)
91 #define STR(x) vstring_str(x)
93 /* scache_single_free_endp - discard endpoint */
95 static void scache_single_free_endp(SCACHE_SINGLE *sp)
97 const char *myname = "scache_single_free_endp";
99 if (msg_verbose)
100 msg_info("%s: %s", myname, STR(sp->endp.endp_label));
102 event_cancel_timer(scache_single_expire_endp, (char *) sp);
103 if (sp->endp.fd >= 0 && close(sp->endp.fd) < 0)
104 msg_warn("close session endpoint %s: %m", STR(sp->endp.endp_label));
105 VSTRING_RESET(sp->endp.endp_label);
106 VSTRING_TERMINATE(sp->endp.endp_label);
107 VSTRING_RESET(sp->endp.endp_prop);
108 VSTRING_TERMINATE(sp->endp.endp_prop);
109 sp->endp.fd = -1;
112 /* scache_single_expire_endp - discard expired session */
114 static void scache_single_expire_endp(int unused_event, char *context)
116 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) context;
118 scache_single_free_endp(sp);
121 /* scache_single_save_endp - save endpoint */
123 static void scache_single_save_endp(SCACHE *scache, int endp_ttl,
124 const char *endp_label,
125 const char *endp_prop, int fd)
127 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
128 const char *myname = "scache_single_save_endp";
130 if (endp_ttl <= 0)
131 msg_panic("%s: bad endp_ttl: %d", myname, endp_ttl);
133 if (SCACHE_SINGLE_ENDP_BUSY(sp))
134 scache_single_free_endp(sp); /* dump the cached fd */
136 vstring_strcpy(sp->endp.endp_label, endp_label);
137 vstring_strcpy(sp->endp.endp_prop, endp_prop);
138 sp->endp.fd = fd;
139 event_request_timer(scache_single_expire_endp, (char *) sp, endp_ttl);
141 if (msg_verbose)
142 msg_info("%s: %s fd=%d", myname, endp_label, fd);
145 /* scache_single_find_endp - look up cached session */
147 static int scache_single_find_endp(SCACHE *scache, const char *endp_label,
148 VSTRING *endp_prop)
150 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
151 const char *myname = "scache_single_find_endp";
152 int fd;
154 if (!SCACHE_SINGLE_ENDP_BUSY(sp)) {
155 if (msg_verbose)
156 msg_info("%s: no endpoint cache: %s", myname, endp_label);
157 return (-1);
159 if (strcmp(STR(sp->endp.endp_label), endp_label) == 0) {
160 vstring_strcpy(endp_prop, STR(sp->endp.endp_prop));
161 fd = sp->endp.fd;
162 sp->endp.fd = -1;
163 scache_single_free_endp(sp);
164 if (msg_verbose)
165 msg_info("%s: found: %s fd=%d", myname, endp_label, fd);
166 return (fd);
168 if (msg_verbose)
169 msg_info("%s: not found: %s", myname, endp_label);
170 return (-1);
173 /* scache_single_free_dest - discard destination/endpoint association */
175 static void scache_single_free_dest(SCACHE_SINGLE *sp)
177 const char *myname = "scache_single_free_dest";
179 if (msg_verbose)
180 msg_info("%s: %s -> %s", myname, STR(sp->dest.dest_label),
181 STR(sp->dest.endp_label));
183 event_cancel_timer(scache_single_expire_dest, (char *) sp);
184 VSTRING_RESET(sp->dest.dest_label);
185 VSTRING_TERMINATE(sp->dest.dest_label);
186 VSTRING_RESET(sp->dest.dest_prop);
187 VSTRING_TERMINATE(sp->dest.dest_prop);
188 VSTRING_RESET(sp->dest.endp_label);
189 VSTRING_TERMINATE(sp->dest.endp_label);
192 /* scache_single_expire_dest - discard expired destination/endpoint binding */
194 static void scache_single_expire_dest(int unused_event, char *context)
196 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) context;
198 scache_single_free_dest(sp);
201 /* scache_single_save_dest - create destination/endpoint association */
203 static void scache_single_save_dest(SCACHE *scache, int dest_ttl,
204 const char *dest_label,
205 const char *dest_prop,
206 const char *endp_label)
208 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
209 const char *myname = "scache_single_save_dest";
210 int refresh;
212 if (dest_ttl <= 0)
213 msg_panic("%s: bad dest_ttl: %d", myname, dest_ttl);
216 * Optimize: reset timer only, if nothing has changed.
218 refresh =
219 (SCACHE_SINGLE_DEST_BUSY(sp)
220 && strcmp(STR(sp->dest.dest_label), dest_label) == 0
221 && strcmp(STR(sp->dest.dest_prop), dest_prop) == 0
222 && strcmp(STR(sp->dest.endp_label), endp_label) == 0);
224 if (refresh == 0) {
225 vstring_strcpy(sp->dest.dest_label, dest_label);
226 vstring_strcpy(sp->dest.dest_prop, dest_prop);
227 vstring_strcpy(sp->dest.endp_label, endp_label);
229 event_request_timer(scache_single_expire_dest, (char *) sp, dest_ttl);
231 if (msg_verbose)
232 msg_info("%s: %s -> %s%s", myname, dest_label, endp_label,
233 refresh ? " (refreshed)" : "");
236 /* scache_single_find_dest - look up cached session */
238 static int scache_single_find_dest(SCACHE *scache, const char *dest_label,
239 VSTRING *dest_prop, VSTRING *endp_prop)
241 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
242 const char *myname = "scache_single_find_dest";
243 int fd;
245 if (!SCACHE_SINGLE_DEST_BUSY(sp)) {
246 if (msg_verbose)
247 msg_info("%s: no destination cache: %s", myname, dest_label);
248 return (-1);
250 if (strcmp(STR(sp->dest.dest_label), dest_label) == 0) {
251 if (msg_verbose)
252 msg_info("%s: found: %s", myname, dest_label);
253 if ((fd = scache_single_find_endp(scache, STR(sp->dest.endp_label), endp_prop)) >= 0) {
254 vstring_strcpy(dest_prop, STR(sp->dest.dest_prop));
255 return (fd);
258 if (msg_verbose)
259 msg_info("%s: not found: %s", myname, dest_label);
260 return (-1);
263 /* scache_single_size - size of single-element cache :-) */
265 static void scache_single_size(SCACHE *scache, SCACHE_SIZE *size)
267 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
269 size->dest_count = (!SCACHE_SINGLE_DEST_BUSY(sp) ? 0 : 1);
270 size->endp_count = (!SCACHE_SINGLE_ENDP_BUSY(sp) ? 0 : 1);
271 size->sess_count = (sp->endp.fd < 0 ? 0 : 1);
274 /* scache_single_free - destroy single-element cache object */
276 static void scache_single_free(SCACHE *scache)
278 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
280 vstring_free(sp->endp.endp_label);
281 vstring_free(sp->endp.endp_prop);
282 if (sp->endp.fd >= 0)
283 close(sp->endp.fd);
285 vstring_free(sp->dest.dest_label);
286 vstring_free(sp->dest.dest_prop);
287 vstring_free(sp->dest.endp_label);
289 myfree((char *) sp);
292 /* scache_single_create - initialize */
294 SCACHE *scache_single_create(void)
296 SCACHE_SINGLE *sp = (SCACHE_SINGLE *) mymalloc(sizeof(*sp));
298 sp->scache->save_endp = scache_single_save_endp;
299 sp->scache->find_endp = scache_single_find_endp;
300 sp->scache->save_dest = scache_single_save_dest;
301 sp->scache->find_dest = scache_single_find_dest;
302 sp->scache->size = scache_single_size;
303 sp->scache->free = scache_single_free;
305 sp->endp.endp_label = vstring_alloc(10);
306 sp->endp.endp_prop = vstring_alloc(10);
307 sp->endp.fd = -1;
309 sp->dest.dest_label = vstring_alloc(10);
310 sp->dest.dest_prop = vstring_alloc(10);
311 sp->dest.endp_label = vstring_alloc(10);
313 return (sp->scache);