Postfix3.3.1
postscreen_dict.c
[詳解]
1 /*++
2 /* NAME
3 /* postscreen_dict 3
4 /* SUMMARY
5 /* postscreen table access wrappers
6 /* SYNOPSIS
7 /* #include <postscreen.h>
8 /*
9 /* int psc_addr_match_list_match(match_list, client_addr)
10 /* ADDR_MATCH_LIST *match_list;
11 /* const char *client_addr;
12 /*
13 /* const char *psc_cache_lookup(DICT_CACHE *cache, const char *key)
14 /* DICT_CACHE *cache;
15 /* const char *key;
16 /*
17 /* void psc_cache_update(cache, key, value)
18 /* DICT_CACHE *cache;
19 /* const char *key;
20 /* const char *value;
21 /*
22 /* void psc_dict_get(dict, key)
23 /* DICT *dict;
24 /* const char *key;
25 /*
26 /* void psc_maps_find(maps, key, flags)
27 /* MAPS *maps;
28 /* const char *key;
29 /* int flags;
30 /* DESCRIPTION
31 /* This module implements wrappers around time-critical table
32 /* access functions. The functions log a warning when table
33 /* access takes a non-trivial amount of time.
34 /*
35 /* psc_addr_match_list_match() is a wrapper around
36 /* addr_match_list_match().
37 /*
38 /* psc_cache_lookup() and psc_cache_update() are wrappers around
39 /* the corresponding dict_cache() methods.
40 /*
41 /* psc_dict_get() and psc_maps_find() are wrappers around
42 /* dict_get() and maps_find(), respectively.
43 /* LICENSE
44 /* .ad
45 /* .fi
46 /* The Secure Mailer license must be distributed with this software.
47 /* AUTHOR(S)
48 /* Wietse Venema
49 /* IBM T.J. Watson Research
50 /* P.O. Box 704
51 /* Yorktown Heights, NY 10598, USA
52 /*--*/
53 
54 /* System library. */
55 
56 #include <sys_defs.h>
57 
58 /* Utility library. */
59 
60 #include <msg.h>
61 #include <dict.h>
62 
63 /* Global library. */
64 
65 #include <maps.h>
66 
67 /* Application-specific. */
68 
69 #include <postscreen.h>
70 
71  /*
72  * Monitor time-critical operations.
73  *
74  * XXX Averaging support was added during a stable release candidate, so it
75  * provides only the absolute minimum necessary. A complete implementation
76  * should maintain separate statistics for each table, and it should not
77  * complain when the access latency is less than the time between accesses.
78  */
79 #define PSC_GET_TIME_BEFORE_LOOKUP { \
80  struct timeval _before, _after; \
81  DELTA_TIME _delta; \
82  double _new_delta_ms; \
83  GETTIMEOFDAY(&_before);
84 
85 #define PSC_DELTA_MS(d) ((d).dt_sec * 1000.0 + (d).dt_usec / 1000.0)
86 
87 #define PSC_AVERAGE(new, old) (0.1 * (new) + 0.9 * (old))
88 
89 #ifndef PSC_THRESHOLD_MS
90 #define PSC_THRESHOLD_MS 100 /* nag if latency > 100ms */
91 #endif
92 
93 #ifndef PSC_WARN_LOCKOUT_S
94 #define PSC_WARN_LOCKOUT_S 60 /* don't nag for 60s */
95 #endif
96 
97  /*
98  * Shared warning lock, so that we don't spam the logfile when the system
99  * becomes slow.
100  */
101 static time_t psc_last_warn = 0;
102 
103 #define PSC_CHECK_TIME_AFTER_LOOKUP(table, action, average) \
104  GETTIMEOFDAY(&_after); \
105  PSC_CALC_DELTA(_delta, _after, _before); \
106  _new_delta_ms = PSC_DELTA_MS(_delta); \
107  if ((average = PSC_AVERAGE(_new_delta_ms, average)) > PSC_THRESHOLD_MS \
108  && psc_last_warn < _after.tv_sec - PSC_WARN_LOCKOUT_S) { \
109  msg_warn("%s: %s %s average delay is %.0f ms", \
110  myname, (table), (action), average); \
111  psc_last_warn = _after.tv_sec; \
112  } \
113 }
114 
115 /* psc_addr_match_list_match - time-critical address list lookup */
116 
118  const char *addr_str)
119 {
120  const char *myname = "psc_addr_match_list_match";
121  int result;
122  static double latency_ms;
123 
125  result = addr_match_list_match(addr_list, addr_str);
126  PSC_CHECK_TIME_AFTER_LOOKUP("address list", "lookup", latency_ms);
127  return (result);
128 }
129 
130 /* psc_cache_lookup - time-critical cache lookup */
131 
132 const char *psc_cache_lookup(DICT_CACHE *cache, const char *key)
133 {
134  const char *myname = "psc_cache_lookup";
135  const char *result;
136  static double latency_ms;
137 
139  result = dict_cache_lookup(cache, key);
140  PSC_CHECK_TIME_AFTER_LOOKUP(dict_cache_name(cache), "lookup", latency_ms);
141  return (result);
142 }
143 
144 /* psc_cache_update - time-critical cache update */
145 
146 void psc_cache_update(DICT_CACHE *cache, const char *key, const char *value)
147 {
148  const char *myname = "psc_cache_update";
149  static double latency_ms;
150 
152  dict_cache_update(cache, key, value);
153  PSC_CHECK_TIME_AFTER_LOOKUP(dict_cache_name(cache), "update", latency_ms);
154 }
155 
156 /* psc_dict_get - time-critical table lookup */
157 
158 const char *psc_dict_get(DICT *dict, const char *key)
159 {
160  const char *myname = "psc_dict_get";
161  const char *result;
162  static double latency_ms;
163 
165  result = dict_get(dict, key);
166  PSC_CHECK_TIME_AFTER_LOOKUP(dict->name, "lookup", latency_ms);
167  return (result);
168 }
169 
170 /* psc_maps_find - time-critical table lookup */
171 
172 const char *psc_maps_find(MAPS *maps, const char *key, int flags)
173 {
174  const char *myname = "psc_maps_find";
175  const char *result;
176  static double latency_ms;
177 
179  result = maps_find(maps, key, flags);
180  PSC_CHECK_TIME_AFTER_LOOKUP(maps->title, "lookup", latency_ms);
181  return (result);
182 }
const char * psc_maps_find(MAPS *maps, const char *key, int flags)
#define PSC_CHECK_TIME_AFTER_LOOKUP(table, action, average)
#define addr_match_list_match(l, a)
const char * dict_cache_lookup(DICT_CACHE *cp, const char *cache_key)
Definition: dict_cache.c:269
char * name
Definition: dict.h:80
Definition: maps.h:22
#define PSC_GET_TIME_BEFORE_LOOKUP
void psc_cache_update(DICT_CACHE *cache, const char *key, const char *value)
Definition: dict.h:78
#define ADDR_MATCH_LIST
#define dict_get(dp, key)
Definition: dict.h:236
char * title
Definition: maps.h:23
const char * dict_cache_name(DICT_CACHE *cp)
Definition: dict_cache.c:674
const char * psc_dict_get(DICT *dict, const char *key)
int psc_addr_match_list_match(ADDR_MATCH_LIST *addr_list, const char *addr_str)
const char * psc_cache_lookup(DICT_CACHE *cache, const char *key)
int dict_cache_update(DICT_CACHE *cp, const char *cache_key, const char *cache_val)
Definition: dict_cache.c:301
const char * maps_find(MAPS *maps, const char *name, int flags)
Definition: maps.c:162