12ee382b6Ssthen /* 22ee382b6Ssthen * cachedb/cachedb.h - cache from a database external to the program module 32ee382b6Ssthen * 42ee382b6Ssthen * Copyright (c) 2016, NLnet Labs. All rights reserved. 52ee382b6Ssthen * 62ee382b6Ssthen * This software is open source. 72ee382b6Ssthen * 82ee382b6Ssthen * Redistribution and use in source and binary forms, with or without 92ee382b6Ssthen * modification, are permitted provided that the following conditions 102ee382b6Ssthen * are met: 112ee382b6Ssthen * 122ee382b6Ssthen * Redistributions of source code must retain the above copyright notice, 132ee382b6Ssthen * this list of conditions and the following disclaimer. 142ee382b6Ssthen * 152ee382b6Ssthen * Redistributions in binary form must reproduce the above copyright notice, 162ee382b6Ssthen * this list of conditions and the following disclaimer in the documentation 172ee382b6Ssthen * and/or other materials provided with the distribution. 182ee382b6Ssthen * 192ee382b6Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 202ee382b6Ssthen * be used to endorse or promote products derived from this software without 212ee382b6Ssthen * specific prior written permission. 222ee382b6Ssthen * 232ee382b6Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 242ee382b6Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 252ee382b6Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 262ee382b6Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 272ee382b6Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 282ee382b6Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 292ee382b6Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 302ee382b6Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 312ee382b6Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 322ee382b6Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 332ee382b6Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 342ee382b6Ssthen */ 352ee382b6Ssthen 362ee382b6Ssthen /** 372ee382b6Ssthen * \file 382ee382b6Ssthen * 392ee382b6Ssthen * This file contains a module that uses an external database to cache 402ee382b6Ssthen * dns responses. 412ee382b6Ssthen */ 422ee382b6Ssthen #include "util/module.h" 432ee382b6Ssthen struct cachedb_backend; 442bdc0ed1Ssthen struct module_stack; 452ee382b6Ssthen 462ee382b6Ssthen /** 472ee382b6Ssthen * The global variable environment contents for the cachedb 482ee382b6Ssthen * Shared between threads, this represents long term information. 492ee382b6Ssthen * Like database connections. 502ee382b6Ssthen */ 512ee382b6Ssthen struct cachedb_env { 522ee382b6Ssthen /** true is cachedb is enabled, the backend is turned on */ 532ee382b6Ssthen int enabled; 542ee382b6Ssthen 552ee382b6Ssthen /** the backend routines */ 562ee382b6Ssthen struct cachedb_backend* backend; 572ee382b6Ssthen 582ee382b6Ssthen /** backend specific data here */ 592ee382b6Ssthen void* backend_data; 602ee382b6Ssthen }; 612ee382b6Ssthen 622ee382b6Ssthen /** 632ee382b6Ssthen * Per query state for the cachedb module. 642ee382b6Ssthen */ 652ee382b6Ssthen struct cachedb_qstate { 662ee382b6Ssthen int todo; 672ee382b6Ssthen }; 682ee382b6Ssthen 692ee382b6Ssthen /** 702ee382b6Ssthen * Backend call routines 712ee382b6Ssthen */ 722ee382b6Ssthen struct cachedb_backend { 732ee382b6Ssthen /** backend name */ 742ee382b6Ssthen const char* name; 752ee382b6Ssthen 762ee382b6Ssthen /** Init(env, cachedb_env): false on setup failure */ 772ee382b6Ssthen int (*init)(struct module_env*, struct cachedb_env*); 782ee382b6Ssthen 792ee382b6Ssthen /** Deinit - close db for program exit */ 802ee382b6Ssthen void (*deinit)(struct module_env*, struct cachedb_env*); 812ee382b6Ssthen 822ee382b6Ssthen /** Lookup (env, cachedb_env, key, result_buffer): true if found */ 832ee382b6Ssthen int (*lookup)(struct module_env*, struct cachedb_env*, char*, 842ee382b6Ssthen struct sldns_buffer*); 852ee382b6Ssthen 862ee382b6Ssthen /** Store (env, cachedb_env, key, data, data_len) */ 872ee382b6Ssthen void (*store)(struct module_env*, struct cachedb_env*, char*, 88a3167c07Ssthen uint8_t*, size_t, time_t); 892ee382b6Ssthen }; 902ee382b6Ssthen 9120237c55Ssthen #define CACHEDB_HASHSIZE 256 /* bit hash */ 9220237c55Ssthen 932ee382b6Ssthen /** Init the cachedb module */ 942ee382b6Ssthen int cachedb_init(struct module_env* env, int id); 952ee382b6Ssthen /** Deinit the cachedb module */ 962ee382b6Ssthen void cachedb_deinit(struct module_env* env, int id); 972ee382b6Ssthen /** Operate on an event on a query (in qstate). */ 982ee382b6Ssthen void cachedb_operate(struct module_qstate* qstate, enum module_ev event, 992ee382b6Ssthen int id, struct outbound_entry* outbound); 1002ee382b6Ssthen /** Subordinate query done, inform this super request of its conclusion */ 1012ee382b6Ssthen void cachedb_inform_super(struct module_qstate* qstate, int id, 1022ee382b6Ssthen struct module_qstate* super); 1032ee382b6Ssthen /** clear the cachedb query-specific contents out of qstate */ 1042ee382b6Ssthen void cachedb_clear(struct module_qstate* qstate, int id); 1052ee382b6Ssthen /** return memory estimate for cachedb module */ 1062ee382b6Ssthen size_t cachedb_get_mem(struct module_env* env, int id); 1072ee382b6Ssthen 1082ee382b6Ssthen /** 1092ee382b6Ssthen * Get the function block with pointers to the cachedb functions 1102ee382b6Ssthen * @return the function block for "cachedb". 1112ee382b6Ssthen */ 1122ee382b6Ssthen struct module_func_block* cachedb_get_funcblock(void); 1132ee382b6Ssthen 1142bdc0ed1Ssthen /** 1152bdc0ed1Ssthen * See if the cachedb is enabled. 1162bdc0ed1Ssthen * @param mods: module stack. It finds the cachedb module environment. 1172bdc0ed1Ssthen * @param env: module environment. 1182bdc0ed1Ssthen * @return true if exists and enabled. 1192bdc0ed1Ssthen */ 1202bdc0ed1Ssthen int cachedb_is_enabled(struct module_stack* mods, struct module_env* env); 1212bdc0ed1Ssthen 1222bdc0ed1Ssthen /** 1232bdc0ed1Ssthen * Remove a message from the global cache. Because edns subnet has a more 1242bdc0ed1Ssthen * specific entry, and if not removed when everything expires, the global 1252bdc0ed1Ssthen * entry is used, instead of a fresh lookup of the edns subnet entry. 1262bdc0ed1Ssthen * @param qstate: query state. 1272bdc0ed1Ssthen */ 1282bdc0ed1Ssthen void cachedb_msg_remove(struct module_qstate* qstate); 129*98bc733bSsthen 130*98bc733bSsthen /** 131*98bc733bSsthen * Remove message from the cachedb cache, by query info. 132*98bc733bSsthen * @param env: module environment to look up cachedb state. 133*98bc733bSsthen * @param qinfo: the message to remove. 134*98bc733bSsthen */ 135*98bc733bSsthen void cachedb_msg_remove_qinfo(struct module_env* env, 136*98bc733bSsthen struct query_info* qinfo); 137