~ubuntu-branches/ubuntu/utopic/dovecot/utopic-proposed

« back to all changes in this revision

Viewing changes to src/lib-master/master-service-settings-cache.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (4.1.35 sid)
  • Revision ID: package-import@ubuntu.com-20140108093549-i72o93pux8p0dlaf
Tags: 1:2.2.9-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2010-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "lib.h"
4
4
#include "hash.h"
38
38
        /* separate list for entries whose parser=global_parser */
39
39
        struct settings_entry *oldest_global, *newest_global;
40
40
        /* local_name, local_ip => struct settings_entry */
41
 
        struct hash_table *local_name_hash;
42
 
        struct hash_table *local_ip_hash;
 
41
        HASH_TABLE(char *, struct settings_entry *) local_name_hash;
 
42
        HASH_TABLE(struct ip_addr *, struct settings_entry *) local_ip_hash;
43
43
 
44
44
        /* Initial size for new settings entry pools */
45
45
        size_t approx_entry_pool_size;
59
59
        struct master_service_settings_cache *cache;
60
60
        pool_t pool;
61
61
 
62
 
        pool = pool_alloconly_create("master service settings cache", 1024*32);
 
62
        pool = pool_alloconly_create(MEMPOOL_GROWING"master service settings cache",
 
63
                                     1024*12);
63
64
        cache = p_new(pool, struct master_service_settings_cache, 1);
64
65
        cache->pool = pool;
65
66
        cache->service = service;
82
83
        }
83
84
        for (entry = cache->oldest; entry != NULL; entry = next) {
84
85
                next = entry->next;
 
86
                i_assert(entry->parser != cache->global_parser);
85
87
                settings_parser_deinit(&entry->parser);
86
88
                pool_unref(&entry->pool);
87
89
        }
88
 
        if (cache->local_name_hash != NULL)
 
90
        if (hash_table_is_created(cache->local_name_hash))
89
91
                hash_table_destroy(&cache->local_name_hash);
90
 
        if (cache->local_ip_hash != NULL)
 
92
        if (hash_table_is_created(cache->local_ip_hash))
91
93
                hash_table_destroy(&cache->local_ip_hash);
92
94
        if (cache->global_parser != NULL)
93
95
                settings_parser_deinit(&cache->global_parser);
134
136
           don't even try to use local_ip (even though we have it), because
135
137
           there may be different settings specifically for local_name */
136
138
        if (input->local_name != NULL) {
137
 
                if (cache->local_name_hash != NULL) {
 
139
                if (hash_table_is_created(cache->local_name_hash)) {
138
140
                        entry = hash_table_lookup(cache->local_name_hash,
139
141
                                                  input->local_name);
140
142
                }
141
 
        } else if (cache->local_ip_hash != NULL &&
 
143
        } else if (hash_table_is_created(cache->local_ip_hash) &&
142
144
                   input->local_ip.family != 0) {
143
145
                entry = hash_table_lookup(cache->local_ip_hash,
144
146
                                          &input->local_ip);
145
147
        }
146
148
 
147
149
        if (entry != NULL) {
 
150
                if (entry->parser != cache->global_parser) {
 
151
                        DLLIST2_REMOVE(&cache->oldest, &cache->newest, entry);
 
152
                        DLLIST2_APPEND(&cache->oldest, &cache->newest, entry);
 
153
                }
148
154
                *parser_r = entry->parser;
149
155
                return TRUE;
150
156
        }
166
172
        settings_parser_deinit(&entry->parser);
167
173
}
168
174
 
169
 
static void cache_add(struct master_service_settings_cache *cache,
170
 
                      const struct master_service_settings_input *input,
171
 
                      const struct master_service_settings_output *output,
172
 
                      struct setting_parser_context *parser)
 
175
static struct setting_parser_context *
 
176
cache_add(struct master_service_settings_cache *cache,
 
177
          const struct master_service_settings_input *input,
 
178
          const struct master_service_settings_output *output,
 
179
          struct setting_parser_context *parser)
173
180
{
174
181
        struct settings_entry *entry;
175
182
        pool_t pool;
185
192
        }
186
193
        if (cache->service_uses_remote) {
187
194
                /* for now we don't try to handle caching remote IPs */
188
 
                return;
 
195
                return parser;
189
196
        }
190
197
 
191
198
        if (input->local_name == NULL && input->local_ip.family == 0)
192
 
                return;
 
199
                return parser;
193
200
 
194
201
        if (!output->used_local) {
195
202
                /* use global settings, but add local_ip/host to hash tables
196
203
                   so we'll find them */
197
204
                pool = pool_alloconly_create("settings global entry", 256);
198
 
                entry = p_new(pool, struct settings_entry, 1);
199
205
        } else if (cache->cache_malloc_size >= cache->max_cache_size) {
200
206
                /* free the oldest and reuse its pool */
201
 
                entry = cache->oldest;
202
 
                pool = entry->pool;
203
 
                setting_entry_detach(cache, entry);
204
 
                p_clear(pool);
 
207
                pool = cache->oldest->pool;
 
208
                setting_entry_detach(cache, cache->oldest);
 
209
                p_clear(pool); /* note: frees also entry */
205
210
        } else {
206
211
                pool_size = cache->approx_entry_pool_size != 0 ?
207
212
                        cache->approx_entry_pool_size :
208
213
                        CACHE_INITIAL_ENTRY_POOL_SIZE;
209
214
                pool = pool_alloconly_create("settings entry", pool_size);
210
 
                entry = p_new(pool, struct settings_entry, 1);
211
215
        }
 
216
        entry = p_new(pool, struct settings_entry, 1);
212
217
        entry->pool = pool;
213
218
        entry_local_name = p_strdup(pool, input->local_name);
214
219
        entry->local_name = entry_local_name;
215
220
        entry->local_ip = input->local_ip;
216
221
        if (!output->used_local) {
217
222
                entry->parser = cache->global_parser;
218
 
                DLLIST2_PREPEND(&cache->oldest_global, &cache->newest_global,
219
 
                                entry);
 
223
                DLLIST2_APPEND(&cache->oldest_global, &cache->newest_global,
 
224
                               entry);
220
225
        } else {
221
226
                entry->parser = settings_parser_dup(parser, entry->pool);
222
 
                DLLIST2_PREPEND(&cache->oldest, &cache->newest, entry);
 
227
                DLLIST2_APPEND(&cache->oldest, &cache->newest, entry);
223
228
 
224
229
                pool_size = pool_alloconly_get_total_used_size(pool);
225
230
                if (pool_size > cache->approx_entry_pool_size) {
230
235
        cache->cache_malloc_size += pool_alloconly_get_total_alloc_size(pool);
231
236
 
232
237
        if (input->local_name != NULL) {
233
 
                if (cache->local_name_hash == NULL) {
234
 
                        cache->local_name_hash =
235
 
                                hash_table_create(default_pool, cache->pool, 0,
236
 
                                                  str_hash,
237
 
                                                  (hash_cmp_callback_t *)strcmp);
 
238
                if (!hash_table_is_created(cache->local_name_hash)) {
 
239
                        hash_table_create(&cache->local_name_hash,
 
240
                                          cache->pool, 0, str_hash, strcmp);
238
241
                }
239
242
                hash_table_insert(cache->local_name_hash,
240
243
                                  entry_local_name, entry);
241
244
        }
242
245
        if (input->local_ip.family != 0) {
243
 
                if (cache->local_ip_hash == NULL) {
244
 
                        cache->local_ip_hash =
245
 
                                hash_table_create(default_pool, cache->pool, 0,
246
 
                                                  (hash_callback_t *)net_ip_hash,
247
 
                                                  (hash_cmp_callback_t *)net_ip_cmp);
 
246
                if (!hash_table_is_created(cache->local_ip_hash)) {
 
247
                        hash_table_create(&cache->local_ip_hash, cache->pool, 0,
 
248
                                          net_ip_hash, net_ip_cmp);
248
249
                }
249
250
                hash_table_insert(cache->local_ip_hash,
250
251
                                  &entry->local_ip, entry);
251
252
        }
 
253
        return entry->parser;
252
254
}
253
255
 
254
256
int master_service_settings_cache_read(struct master_service_settings_cache *cache,
294
296
                return -1;
295
297
        }
296
298
 
297
 
        cache_add(cache, &new_input, &output, cache->service->set_parser);
298
 
        *parser_r = cache->service->set_parser;
 
299
        *parser_r = cache_add(cache, &new_input, &output,
 
300
                              cache->service->set_parser);
299
301
        return 0;
300
302
}