libspf2
1.2.10
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of either: 00004 * 00005 * a) The GNU Lesser General Public License as published by the Free 00006 * Software Foundation; either version 2.1, or (at your option) any 00007 * later version, 00008 * 00009 * OR 00010 * 00011 * b) The two-clause BSD license. 00012 * 00013 * These licenses can be found with the distribution in the file LICENSES 00014 */ 00015 00016 #include "spf_sys_config.h" 00017 00018 #ifdef STDC_HEADERS 00019 # include <stdio.h> /* stdin / stdout */ 00020 # include <stdlib.h> /* malloc / free */ 00021 #endif 00022 00023 00024 #ifdef HAVE_STRING_H 00025 # include <string.h> /* strstr / strdup */ 00026 #else 00027 # ifdef HAVE_STRINGS_H 00028 # include <strings.h> /* strstr / strdup */ 00029 # endif 00030 #endif 00031 00032 #ifdef HAVE_MEMORY_H 00033 #include <memory.h> 00034 #endif 00035 #if TIME_WITH_SYS_TIME 00036 # include <sys/time.h> 00037 # include <time.h> 00038 #else 00039 # if HAVE_SYS_TIME_H 00040 # include <sys/time.h> 00041 # else 00042 # include <time.h> 00043 # endif 00044 #endif 00045 00046 #ifdef HAVE_NETDB_H 00047 # include <netdb.h> 00048 #endif 00049 00050 #ifdef HAVE_PTHREAD_H 00051 # include <pthread.h> 00052 #endif 00053 00054 #include "spf.h" 00055 #include "spf_dns.h" 00056 #include "spf_internal.h" 00057 #include "spf_dns_internal.h" 00058 #include "spf_dns_cache.h" 00059 00060 00082 typedef 00083 struct _SPF_dns_cache_bucket_t { 00084 struct _SPF_dns_cache_bucket_t *next; 00085 SPF_dns_rr_t *rr; 00086 } SPF_dns_cache_bucket_t; 00087 00088 typedef struct 00089 { 00090 SPF_dns_cache_bucket_t **cache; 00091 int cache_size; 00092 pthread_mutex_t cache_lock; 00093 00094 int hash_mask; 00095 int max_hash_len; 00096 00097 #if 0 00098 int hit; 00099 int miss; 00100 #endif 00101 00102 time_t min_ttl; 00103 time_t err_ttl; 00104 time_t txt_ttl; 00105 time_t rdns_ttl; 00106 00107 int conserve_cache; 00108 00109 00110 } SPF_dns_cache_config_t; 00111 00112 00113 static inline SPF_dns_cache_config_t *SPF_voidp2spfhook( void *hook ) 00114 { return (SPF_dns_cache_config_t *)hook; } 00115 static inline void *SPF_spfhook2voidp( SPF_dns_cache_config_t *spfhook ) 00116 { return (void *)spfhook; } 00117 00118 00119 /* 00120 ** calculate CRC-32 stuff. 00121 */ 00122 00123 /* 00124 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or 00125 * code or tables extracted from it, as desired without restriction. 00126 * 00127 * First, the polynomial itself and its table of feedback terms. The 00128 * polynomial is 00129 * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 00130 * 00131 * Note that we take it "backwards" and put the highest-order term in 00132 * the lowest-order bit. The X^32 term is "implied"; the LSB is the 00133 * X^31 term, etc. The X^0 term (usually shown as "+1") results in 00134 * the MSB being 1 00135 * 00136 * Note that the usual hardware shift register implementation, which 00137 * is what we're using (we're merely optimizing it by doing eight-bit 00138 * chunks at a time) shifts bits into the lowest-order term. In our 00139 * implementation, that means shifting towards the right. Why do we 00140 * do it this way? Because the calculated CRC must be transmitted in 00141 * order from highest-order term to lowest-order term. UARTs transmit 00142 * characters in order from LSB to MSB. By storing the CRC this way 00143 * we hand it to the UART in the order low-byte to high-byte; the UART 00144 * sends each low-bit to hight-bit; and the result is transmission bit 00145 * by bit from highest- to lowest-order term without requiring any bit 00146 * shuffling on our part. Reception works similarly 00147 * 00148 * The feedback terms table consists of 256, 32-bit entries. Notes 00149 * 00150 * The table can be generated at runtime if desired; code to do so 00151 * is shown later. It might not be obvious, but the feedback 00152 * terms simply represent the results of eight shift/xor opera 00153 * tions for all combinations of data and CRC register values 00154 * 00155 * The values must be right-shifted by eight bits by the "updcrc 00156 * logic; the shift must be unsigned (bring in zeroes). On some 00157 * hardware you could probably optimize the shift in assembler by 00158 * using byte-swap instructions 00159 * polynomial $edb88320 00160 */ 00161 00162 const unsigned int crc_32_tab[256] = { 00163 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 00164 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 00165 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 00166 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 00167 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 00168 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 00169 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 00170 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 00171 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 00172 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 00173 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 00174 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 00175 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 00176 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 00177 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 00178 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 00179 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 00180 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 00181 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 00182 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 00183 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 00184 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 00185 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 00186 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 00187 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 00188 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 00189 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 00190 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 00191 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 00192 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 00193 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 00194 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 00195 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 00196 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 00197 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 00198 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 00199 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 00200 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 00201 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 00202 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 00203 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 00204 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 00205 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 00206 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 00207 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 00208 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 00209 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 00210 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 00211 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 00212 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 00213 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 00214 0x2d02ef8dL 00215 }; 00216 00217 static inline int 00218 crc32str(unsigned int accum, const char *str, int max_hash_len) 00219 { 00220 for( ; *str != '\0' && max_hash_len > 0; str++ ) { 00221 if ( *str == '.' ) 00222 continue; 00223 00224 accum = crc_32_tab[ (unsigned char)accum ^ (unsigned char)*str ] 00225 ^ (unsigned char)(accum >> 8); 00226 00227 max_hash_len--; 00228 } 00229 00230 00231 return accum; 00232 } 00233 00234 // #define hash(h,s,a) (crc32str(a,s,h->max_hash_len) & (h->hash_mask)) 00235 #define hash(h,s,a) crc32str(a,s,h->max_hash_len) 00236 00237 /* This must be called with the lock held. */ 00238 static SPF_dns_cache_bucket_t * 00239 SPF_dns_cache_bucket_find(SPF_dns_cache_config_t *spfhook, 00240 const char *domain, ns_type rr_type, int idx) 00241 { 00242 SPF_dns_cache_bucket_t *bucket; 00243 SPF_dns_cache_bucket_t *prev; 00244 SPF_dns_rr_t *rr; 00245 time_t now; 00246 00247 bucket = spfhook->cache[idx]; 00248 prev = NULL; 00249 time(&now); 00250 00251 while (bucket != NULL) { 00252 rr = bucket->rr; 00253 00254 if (rr->utc_ttl < now) { 00255 /* Unlink the bucket. */ 00256 if (prev != NULL) 00257 prev->next = bucket->next; 00258 else 00259 spfhook->cache[idx] = bucket->next; 00260 /* Free the bucket. */ 00261 if (bucket->rr) 00262 SPF_dns_rr_free(bucket->rr); 00263 free(bucket); 00264 /* Set iterator back one step. */ 00265 bucket = prev; /* Might be NULL */ 00266 } 00267 else if (rr->rr_type != rr_type) { 00268 /* Types differ */ 00269 } 00270 else if (strcmp(rr->domain, domain) != 0) { 00271 /* Domains differ */ 00272 } 00273 else { 00274 /* Move the bucket to the top of the chain. */ 00275 if (prev != NULL) { 00276 prev->next = bucket->next; 00277 bucket->next = spfhook->cache[idx]; 00278 spfhook->cache[idx] = bucket; 00279 } 00280 return bucket; 00281 } 00282 00283 prev = bucket; /* Might be NULL */ 00284 if (bucket == NULL) /* After an unlink */ 00285 bucket = spfhook->cache[idx]; 00286 else 00287 bucket = bucket->next; 00288 } 00289 00290 return NULL; 00291 } 00292 00293 /* This must be called with the lock held. */ 00294 static SPF_errcode_t 00295 SPF_dns_cache_bucket_add(SPF_dns_cache_config_t *spfhook, 00296 SPF_dns_rr_t *rr, int idx) 00297 { 00298 SPF_dns_cache_bucket_t *bucket; 00299 00300 bucket = (SPF_dns_cache_bucket_t *) 00301 malloc(sizeof(SPF_dns_cache_bucket_t)); 00302 if (! bucket) 00303 return SPF_E_NO_MEMORY; 00304 bucket->next = spfhook->cache[idx]; 00305 spfhook->cache[idx] = bucket; 00306 bucket->rr = rr; 00307 return SPF_E_SUCCESS; 00308 } 00309 00310 00314 static SPF_errcode_t 00315 SPF_dns_cache_rr_fixup(SPF_dns_cache_config_t *spfhook, 00316 SPF_dns_rr_t *cached_rr, 00317 const char *domain, ns_type rr_type) 00318 { 00319 char *p; 00320 00321 /* make sure the RR has enough data to be useful for caching */ 00322 if (cached_rr->rr_type == ns_t_any) 00323 cached_rr->rr_type = rr_type; 00324 00325 /* XXX I'm still not sure about this bit. */ 00326 if (cached_rr->domain == NULL || cached_rr->domain[0] != '\0') { 00327 char *new_domain; 00328 size_t new_len = strlen(domain) + 1; 00329 00330 if (cached_rr->domain_buf_len < new_len) { 00331 new_domain = realloc(cached_rr->domain, new_len); 00332 if (new_domain == NULL) 00333 return SPF_E_NO_MEMORY; 00334 cached_rr->domain = new_domain; 00335 cached_rr->domain_buf_len = new_len; 00336 } 00337 strcpy(cached_rr->domain, domain); 00338 } 00339 00340 /* set up the ttl values */ 00341 if ( cached_rr->ttl < spfhook->min_ttl ) 00342 cached_rr->ttl = spfhook->min_ttl; 00343 00344 if ( cached_rr->ttl < spfhook->txt_ttl 00345 && cached_rr->rr_type == ns_t_txt ) 00346 cached_rr->ttl = spfhook->txt_ttl; 00347 00348 if ( cached_rr->ttl < spfhook->err_ttl 00349 && cached_rr->herrno != NETDB_SUCCESS ) 00350 cached_rr->ttl = spfhook->err_ttl; 00351 00352 if ( cached_rr->ttl < spfhook->rdns_ttl ) { 00353 p = strstr( cached_rr->domain, ".arpa" ); 00354 if ( p && p[ sizeof( ".arpa" )-1 ] == '\0' ) 00355 cached_rr->ttl = spfhook->rdns_ttl; 00356 } 00357 00358 cached_rr->utc_ttl = cached_rr->ttl + time(NULL); 00359 00360 return SPF_E_SUCCESS; 00361 } 00362 00363 00367 static SPF_dns_rr_t * 00368 SPF_dns_cache_lookup(SPF_dns_server_t *spf_dns_server, 00369 const char *domain, ns_type rr_type, int should_cache) 00370 { 00371 SPF_dns_cache_config_t *spfhook; 00372 SPF_dns_cache_bucket_t *bucket; 00373 SPF_dns_rr_t *cached_rr; 00374 SPF_dns_rr_t *rr; 00375 int idx; 00376 00377 spfhook = SPF_voidp2spfhook(spf_dns_server->hook); 00378 00379 /* max_hash_len and cache_size are constant, so this be done 00380 * outside the lock. */ 00381 idx = hash(spfhook, domain, 0 /* spfhook->hash_mask+rr_type */); 00382 idx &= (spfhook->cache_size - 1); 00383 00384 pthread_mutex_lock(&(spfhook->cache_lock)); 00385 00386 bucket = SPF_dns_cache_bucket_find(spfhook, domain, rr_type, idx); 00387 if (bucket != NULL) { 00388 if (bucket->rr != NULL) { 00389 if (SPF_dns_rr_dup(&rr, bucket->rr) == SPF_E_SUCCESS) { 00390 pthread_mutex_unlock(&(spfhook->cache_lock)); 00391 return rr; 00392 } 00393 else if (rr != NULL) { 00394 SPF_dns_rr_free(rr); /* Within the lock. :-( */ 00395 } 00396 } 00397 } 00398 00399 /* Make sure we don't hang onto this outside the lock. 00400 * idx is presumably safe. */ 00401 bucket = NULL; 00402 00403 pthread_mutex_unlock(&(spfhook->cache_lock)); 00404 00405 if (!spf_dns_server->layer_below) 00406 return SPF_dns_rr_new_nxdomain(spf_dns_server, domain); 00407 00408 rr = SPF_dns_lookup( spf_dns_server->layer_below, 00409 domain, rr_type, should_cache ); 00410 if (spfhook->conserve_cache && !should_cache) 00411 return rr; 00412 00413 pthread_mutex_lock(&(spfhook->cache_lock)); 00414 00415 if (SPF_dns_rr_dup(&cached_rr, rr) == SPF_E_SUCCESS) { 00416 if (SPF_dns_cache_rr_fixup(spfhook, cached_rr, domain, rr_type) == SPF_E_SUCCESS){ 00417 if (SPF_dns_cache_bucket_add(spfhook, cached_rr, idx) == SPF_E_SUCCESS) { 00418 pthread_mutex_unlock(&(spfhook->cache_lock)); 00419 return rr; 00420 } 00421 } 00422 } 00423 00424 pthread_mutex_unlock(&(spfhook->cache_lock)); 00425 00426 if (cached_rr) 00427 SPF_dns_rr_free(cached_rr); 00428 00429 return rr; 00430 00431 } 00432 00433 00434 static void 00435 SPF_dns_cache_free( SPF_dns_server_t *spf_dns_server ) 00436 { 00437 SPF_dns_cache_config_t *spfhook; 00438 SPF_dns_cache_bucket_t *bucket; 00439 SPF_dns_cache_bucket_t *prev; 00440 int i; 00441 00442 SPF_ASSERT_NOTNULL(spf_dns_server); 00443 00444 spfhook = SPF_voidp2spfhook( spf_dns_server->hook ); 00445 if ( spfhook ) { 00446 pthread_mutex_lock(&(spfhook->cache_lock)); 00447 00448 if (spfhook->cache) { 00449 for( i = 0; i < spfhook->cache_size; i++ ) { 00450 bucket = spfhook->cache[i]; 00451 while (bucket != NULL) { 00452 prev = bucket; 00453 bucket = bucket->next; 00454 00455 /* Free the bucket. */ 00456 if (prev->rr) 00457 SPF_dns_rr_free(prev->rr); 00458 free(prev); 00459 } 00460 } 00461 free(spfhook->cache); 00462 spfhook->cache = NULL; 00463 } 00464 00465 pthread_mutex_unlock(&(spfhook->cache_lock)); 00466 00467 /* 00468 * There is a risk that something might grab the mutex 00469 * here and try to look things up and try to resolve 00470 * stuff from a mashed cache it might happen but that's 00471 * what you get for trying to simultaneously free and 00472 * use a resource destroy will then return EBUSY but 00473 * it'll probably segfault so there ain't much to be 00474 * done really. 00475 */ 00476 pthread_mutex_destroy(&(spfhook->cache_lock)); 00477 00478 free(spfhook); 00479 } 00480 00481 free(spf_dns_server); 00482 } 00483 00484 00485 00486 SPF_dns_server_t * 00487 SPF_dns_cache_new(SPF_dns_server_t *layer_below, 00488 const char *name, int debug, int cache_bits) 00489 { 00490 SPF_dns_server_t *spf_dns_server; 00491 SPF_dns_cache_config_t *spfhook; 00492 00493 SPF_ASSERT_NOTNULL(layer_below); 00494 00495 if ( cache_bits < 1 || cache_bits > 16 ) 00496 SPF_error( "cache bits out of range (1..16)." ); 00497 00498 00499 spf_dns_server = malloc(sizeof(SPF_dns_server_t)); 00500 if (spf_dns_server == NULL) 00501 return NULL; 00502 memset(spf_dns_server, 0, sizeof(SPF_dns_server_t)); 00503 00504 spf_dns_server->hook = malloc(sizeof(SPF_dns_cache_config_t)); 00505 if (spf_dns_server->hook == NULL) { 00506 free(spf_dns_server); 00507 return NULL; 00508 } 00509 memset(spf_dns_server->hook, 0, sizeof(SPF_dns_cache_config_t)); 00510 00511 if (name == NULL) 00512 name = "cache"; 00513 00514 spf_dns_server->destroy = SPF_dns_cache_free; 00515 spf_dns_server->lookup = SPF_dns_cache_lookup; 00516 spf_dns_server->get_spf = NULL; 00517 spf_dns_server->get_exp = NULL; 00518 spf_dns_server->add_cache = NULL; 00519 spf_dns_server->layer_below = layer_below; 00520 spf_dns_server->name = name; 00521 spf_dns_server->debug = debug; 00522 00523 spfhook = SPF_voidp2spfhook( spf_dns_server->hook ); 00524 00525 spfhook->cache_size = 1 << cache_bits; 00526 spfhook->hash_mask = spfhook->cache_size - 1; 00527 spfhook->max_hash_len = cache_bits > 4 ? cache_bits * 2 : 8; 00528 00529 spfhook->cache = calloc(spfhook->cache_size, 00530 sizeof(*spfhook->cache)); 00531 00532 #if 0 00533 spfhook->hit = 0; 00534 spfhook->miss = 0; 00535 #endif 00536 00537 spfhook->min_ttl = 30; 00538 spfhook->err_ttl = 30*60; 00539 spfhook->txt_ttl = 30*60; 00540 spfhook->rdns_ttl = 30*60; 00541 spfhook->conserve_cache = cache_bits < 12; 00542 00543 if (spfhook->cache == NULL) { 00544 free(spfhook); 00545 free(spf_dns_server); 00546 return NULL; 00547 } 00548 00549 pthread_mutex_init(&(spfhook->cache_lock),NULL); 00550 00551 return spf_dns_server; 00552 } 00553 00554 void 00555 SPF_dns_cache_set_ttl( SPF_dns_server_t *spf_dns_server, 00556 time_t min_ttl, time_t err_ttl, 00557 time_t txt_ttl, time_t rdns_ttl ) 00558 { 00559 SPF_dns_cache_config_t *spfhook; 00560 00561 SPF_ASSERT_NOTNULL(spf_dns_server); 00562 00563 spfhook = SPF_voidp2spfhook( spf_dns_server->hook ); 00564 00565 if (spfhook != NULL) { 00566 pthread_mutex_lock(&(spfhook->cache_lock)); 00567 spfhook->min_ttl = min_ttl; 00568 spfhook->err_ttl = err_ttl; 00569 spfhook->txt_ttl = txt_ttl; 00570 spfhook->rdns_ttl = rdns_ttl; 00571 pthread_mutex_unlock(&(spfhook->cache_lock)); 00572 } 00573 } 00574 00575 00576 void 00577 SPF_dns_set_conserve_cache( SPF_dns_server_t *spf_dns_server, 00578 int conserve_cache ) 00579 { 00580 SPF_dns_cache_config_t *spfhook; 00581 00582 SPF_ASSERT_NOTNULL(spf_dns_server); 00583 00584 spfhook = SPF_voidp2spfhook( spf_dns_server->hook ); 00585 /* This is a boolean and it doesn't matter if it 00586 * changes suddenly, thus no lock. */ 00587 if (spfhook != NULL) 00588 spfhook->conserve_cache = conserve_cache; 00589 }