diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2012-07-04 14:24:26 +0000 | 
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2012-07-04 14:24:26 +0000 | 
| commit | afb79913ce00d885b8b43f7478e1e054edadb567 (patch) | |
| tree | b9037afac70edd3c6342318cedbbadc648b799ca /pythonmod/pythonmod_utils.c | |
Notes
Diffstat (limited to 'pythonmod/pythonmod_utils.c')
| -rw-r--r-- | pythonmod/pythonmod_utils.c | 177 | 
1 files changed, 177 insertions, 0 deletions
diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c new file mode 100644 index 000000000000..b25acd3a8904 --- /dev/null +++ b/pythonmod/pythonmod_utils.c @@ -0,0 +1,177 @@ +/* + * pythonmod_utils.c: utilities used by wrapper + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + *                     Marek Vavrusa  (xvavru00 AT stud.fit.vutbr.cz) + * + * This software is open source. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + *  + *    * Redistributions of source code must retain the above copyright notice, + *      this list of conditions and the following disclaimer. + *  + *    * Redistributions in binary form must reproduce the above copyright notice, + *      this list of conditions and the following disclaimer in the documentation + *      and/or other materials provided with the distribution. + *  + *    * Neither the name of the organization nor the names of its + *      contributors may be used to endorse or promote products derived from this + *      software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/** + * \file + * Utility functions for the python module that perform stores and loads and + * conversions. + */ +#include "config.h" +#include "util/module.h" +#include "util/netevent.h" +#include "util/net_help.h" +#include "services/cache/dns.h" +#include "services/cache/rrset.h" +#include "util/data/msgparse.h" +#include "util/data/msgreply.h" +#include "util/storage/slabhash.h" +#include "util/regional.h" + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE +#include <Python.h> + +/* Store the reply_info and query_info pair in message cache (qstate->msg_cache) */ +int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral) +{ +    if (!msgrep)  +       return 0; + +    if (msgrep->authoritative) /*authoritative answer can't be stored in cache*/ +    { +       PyErr_SetString(PyExc_ValueError, "Authoritative answer can't be stored"); +       return 0; +    } + +    return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,  +	qstate->prefetch_leeway, 0, NULL); +} + +/*  Invalidate the message associated with query_info stored in message cache */ +void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo) +{  +    hashvalue_t h; +    struct lruhash_entry* e; +    struct reply_info *r; +    size_t i, j; + +    h = query_info_hash(qinfo); +    if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0)))  +    { +	r = (struct reply_info*)(e->data); +	if (r)  +	{ +	   r->ttl = 0; +	   if(rrset_array_lock(r->ref, r->rrset_count, *qstate->env->now)) { +		   for(i=0; i< r->rrset_count; i++)  +		   { +		       struct packed_rrset_data* data =  +		       	(struct packed_rrset_data*) r->ref[i].key->entry.data; +		       if(i>0 && r->ref[i].key == r->ref[i-1].key) +			   continue; +	       +		       data->ttl = r->ttl; +		       for(j=0; j<data->count + data->rrsig_count; j++) +			   data->rr_ttl[j] = r->ttl; +		   } +		   rrset_array_unlock(r->ref, r->rrset_count); +	   } +	} +	lock_rw_unlock(&e->lock); +    } else { +	log_info("invalidateQueryInCache: qinfo is not in cache"); +    } +} + +/* Create response according to the ldns packet content */ +int createResponse(struct module_qstate* qstate, ldns_buffer* pkt) +{ +    struct msg_parse* prs; +    struct edns_data edns; +     +    /* parse message */ +    prs = (struct msg_parse*) regional_alloc(qstate->env->scratch, sizeof(struct msg_parse)); +    if (!prs) { +	log_err("storeResponse: out of memory on incoming message"); +	return 0; +    } + +    memset(prs, 0, sizeof(*prs)); +    memset(&edns, 0, sizeof(edns)); + +    ldns_buffer_set_position(pkt, 0); +    if (parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) { +	verbose(VERB_ALGO, "storeResponse: parse error on reply packet"); +	return 0; +    } +    /* edns is not examined, but removed from message to help cache */ +    if(parse_extract_edns(prs, &edns) != LDNS_RCODE_NOERROR) +	return 0; + +    /* remove CD-bit, we asked for in case we handle validation ourself */ +    prs->flags &= ~BIT_CD; + +    /* allocate response dns_msg in region */ +    qstate->return_msg = (struct dns_msg*)regional_alloc(qstate->region, sizeof(struct dns_msg)); +    if (!qstate->return_msg) +       return 0; + +    memset(qstate->return_msg, 0, sizeof(*qstate->return_msg)); +    if(!parse_create_msg(pkt, prs, NULL, &(qstate->return_msg)->qinfo, &(qstate->return_msg)->rep, qstate->region)) { +	log_err("storeResponse: malloc failure: allocating incoming dns_msg"); +	return 0; +    } +     +    /* Make sure that the RA flag is set (since the presence of  +     * this module means that recursion is available) */ +    /* qstate->return_msg->rep->flags |= BIT_RA; */ + +    /* Clear the AA flag */ +    /* FIXME: does this action go here or in some other module? */ +    /*qstate->return_msg->rep->flags &= ~BIT_AA; */ + +    /* make sure QR flag is on */ +    /*qstate->return_msg->rep->flags |= BIT_QR; */ + +    if(verbosity >= VERB_ALGO) +	log_dns_msg("storeResponse: packet:", &qstate->return_msg->qinfo, qstate->return_msg->rep); + +    return 1; +} + + +/* Convert reply->addr to string */ +void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen) +{ +	int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family; +	void* sinaddr = &((struct sockaddr_in*) &(reply->addr))->sin_addr; + +	if(af == AF_INET6) +		sinaddr = &((struct sockaddr_in6*)&(reply->addr))->sin6_addr; +	dest[0] = 0; +	if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0) +	   return; +	dest[maxlen-1] = 0; +}  | 
