~ubuntu-branches/ubuntu/saucy/postfix/saucy

« back to all changes in this revision

Viewing changes to src/postscreen/postscreen_dict.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2011-02-22 11:20:43 UTC
  • mfrom: (1.1.27 upstream)
  • Revision ID: james.westby@ubuntu.com-20110222112043-c34ht219w3ybrilr
Tags: 2.8.0-2
* a little more lintian cleanup
* Fix missing format strings in smtp-sink.c

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
117
int     psc_addr_match_list_match(ADDR_MATCH_LIST *addr_list,
 
118
                                          const char *addr_str)
 
119
{
 
120
    const char *myname = "psc_addr_match_list_match";
 
121
    int     result;
 
122
    static double latency_ms;
 
123
 
 
124
    PSC_GET_TIME_BEFORE_LOOKUP;
 
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
 
 
138
    PSC_GET_TIME_BEFORE_LOOKUP;
 
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
 
 
151
    PSC_GET_TIME_BEFORE_LOOKUP;
 
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
 
 
164
    PSC_GET_TIME_BEFORE_LOOKUP;
 
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
 
 
178
    PSC_GET_TIME_BEFORE_LOOKUP;
 
179
    result = maps_find(maps, key, flags);
 
180
    PSC_CHECK_TIME_AFTER_LOOKUP(maps->title, "lookup", latency_ms);
 
181
    return (result);
 
182
}