]>
git.saurik.com Git - apple/network_cmds.git/blob - unbound/pythonmod/pythonmod_utils.c
2 * pythonmod_utils.c: utilities used by wrapper
4 * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
5 * Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
7 * This software is open source.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * * Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
20 * * Neither the name of the organization nor the names of its
21 * contributors may be used to endorse or promote products derived from this
22 * software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
38 * Utility functions for the python module that perform stores and loads and
42 #include "util/module.h"
43 #include "util/netevent.h"
44 #include "util/net_help.h"
45 #include "services/cache/dns.h"
46 #include "services/cache/rrset.h"
47 #include "util/data/msgparse.h"
48 #include "util/data/msgreply.h"
49 #include "util/storage/slabhash.h"
50 #include "util/regional.h"
51 #include "ldns/sbuffer.h"
53 #undef _POSIX_C_SOURCE
57 /* Store the reply_info and query_info pair in message cache (qstate->msg_cache) */
58 int storeQueryInCache(struct module_qstate
* qstate
, struct query_info
* qinfo
, struct reply_info
* msgrep
, int is_referral
)
63 if (msgrep
->authoritative
) /*authoritative answer can't be stored in cache*/
65 PyErr_SetString(PyExc_ValueError
, "Authoritative answer can't be stored");
69 return dns_cache_store(qstate
->env
, qinfo
, msgrep
, is_referral
,
70 qstate
->prefetch_leeway
, 0, NULL
, qstate
->query_flags
);
73 /* Invalidate the message associated with query_info stored in message cache */
74 void invalidateQueryInCache(struct module_qstate
* qstate
, struct query_info
* qinfo
)
77 struct lruhash_entry
* e
;
81 h
= query_info_hash(qinfo
, qstate
->query_flags
);
82 if ((e
=slabhash_lookup(qstate
->env
->msg_cache
, h
, qinfo
, 0)))
84 r
= (struct reply_info
*)(e
->data
);
88 if(rrset_array_lock(r
->ref
, r
->rrset_count
, *qstate
->env
->now
)) {
89 for(i
=0; i
< r
->rrset_count
; i
++)
91 struct packed_rrset_data
* data
=
92 (struct packed_rrset_data
*) r
->ref
[i
].key
->entry
.data
;
93 if(i
>0 && r
->ref
[i
].key
== r
->ref
[i
-1].key
)
97 for(j
=0; j
<data
->count
+ data
->rrsig_count
; j
++)
98 data
->rr_ttl
[j
] = r
->ttl
;
100 rrset_array_unlock(r
->ref
, r
->rrset_count
);
103 lock_rw_unlock(&e
->lock
);
105 log_info("invalidateQueryInCache: qinfo is not in cache");
109 /* Create response according to the ldns packet content */
110 int createResponse(struct module_qstate
* qstate
, sldns_buffer
* pkt
)
112 struct msg_parse
* prs
;
113 struct edns_data edns
;
116 prs
= (struct msg_parse
*) regional_alloc(qstate
->env
->scratch
, sizeof(struct msg_parse
));
118 log_err("storeResponse: out of memory on incoming message");
122 memset(prs
, 0, sizeof(*prs
));
123 memset(&edns
, 0, sizeof(edns
));
125 sldns_buffer_set_position(pkt
, 0);
126 if (parse_packet(pkt
, prs
, qstate
->env
->scratch
) != LDNS_RCODE_NOERROR
) {
127 verbose(VERB_ALGO
, "storeResponse: parse error on reply packet");
130 /* edns is not examined, but removed from message to help cache */
131 if(parse_extract_edns(prs
, &edns
) != LDNS_RCODE_NOERROR
)
134 /* remove CD-bit, we asked for in case we handle validation ourself */
135 prs
->flags
&= ~BIT_CD
;
137 /* allocate response dns_msg in region */
138 qstate
->return_msg
= (struct dns_msg
*)regional_alloc(qstate
->region
, sizeof(struct dns_msg
));
139 if (!qstate
->return_msg
)
142 memset(qstate
->return_msg
, 0, sizeof(*qstate
->return_msg
));
143 if(!parse_create_msg(pkt
, prs
, NULL
, &(qstate
->return_msg
)->qinfo
, &(qstate
->return_msg
)->rep
, qstate
->region
)) {
144 log_err("storeResponse: malloc failure: allocating incoming dns_msg");
148 /* Make sure that the RA flag is set (since the presence of
149 * this module means that recursion is available) */
150 /* qstate->return_msg->rep->flags |= BIT_RA; */
152 /* Clear the AA flag */
153 /* FIXME: does this action go here or in some other module? */
154 /*qstate->return_msg->rep->flags &= ~BIT_AA; */
156 /* make sure QR flag is on */
157 /*qstate->return_msg->rep->flags |= BIT_QR; */
159 if(verbosity
>= VERB_ALGO
)
160 log_dns_msg("storeResponse: packet:", &qstate
->return_msg
->qinfo
, qstate
->return_msg
->rep
);
166 /* Convert reply->addr to string */
167 void reply_addr2str(struct comm_reply
* reply
, char* dest
, int maxlen
)
169 int af
= (int)((struct sockaddr_in
*) &(reply
->addr
))->sin_family
;
170 void* sinaddr
= &((struct sockaddr_in
*) &(reply
->addr
))->sin_addr
;
173 sinaddr
= &((struct sockaddr_in6
*)&(reply
->addr
))->sin6_addr
;
175 if (inet_ntop(af
, sinaddr
, dest
, (socklen_t
)maxlen
) == 0)