mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Fix that if there are reply callbacks for the given rcode, those
are called per reply and a new message created if that was modified by the call. - Pass the comm_reply information to the inplace_cb_reply* functions during the mesh state and update the documentation on that.
This commit is contained in:
parent
edc8f363a7
commit
d55084ea9e
6 changed files with 34 additions and 49 deletions
|
|
@ -1,3 +1,10 @@
|
||||||
|
15 October 2020: George
|
||||||
|
- Fix that if there are reply callbacks for the given rcode, those
|
||||||
|
are called per reply and a new message created if that was modified
|
||||||
|
by the call.
|
||||||
|
- Pass the comm_reply information to the inplace_cb_reply* functions
|
||||||
|
during the mesh state and update the documentation on that.
|
||||||
|
|
||||||
15 October 2020: Wouter
|
15 October 2020: Wouter
|
||||||
- Merge PR #326 from netblue30: DoH: implement content-length
|
- Merge PR #326 from netblue30: DoH: implement content-length
|
||||||
header field
|
header field
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ The callback function's prototype is the following:
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh states.
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -105,8 +104,6 @@ The callback function's prototype is the following:
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -154,8 +151,6 @@ The callback function's prototype is the following:
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -201,8 +196,6 @@ The callback function's prototype is the following:
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ EDNS options
|
||||||
Inplace callbacks
|
Inplace callbacks
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
.. function:: inplace_cb_reply(qinfo, qstate, rep, rcode, edns, opt_list_out, region)
|
.. function:: inplace_cb_reply(qinfo, qstate, rep, rcode, edns, opt_list_out, region, \*\*kwargs)
|
||||||
|
|
||||||
Function prototype for callback functions used in
|
Function prototype for callback functions used in
|
||||||
`register_inplace_cb_reply`_, `register_inplace_cb_reply_cache`_,
|
`register_inplace_cb_reply`_, `register_inplace_cb_reply_cache`_,
|
||||||
|
|
@ -102,6 +102,9 @@ Inplace callbacks
|
||||||
:param edns: :class:`edns_data`
|
:param edns: :class:`edns_data`
|
||||||
:param opt_list_out: :class:`edns_option`. EDNS option list to append options to.
|
:param opt_list_out: :class:`edns_option`. EDNS option list to append options to.
|
||||||
:param region: :class:`regional`
|
:param region: :class:`regional`
|
||||||
|
:param \*\*kwargs: Dictionary that may contain parameters added in a future
|
||||||
|
release. Current parameters:
|
||||||
|
``repinfo``: :class:`comm_reply`. Reply information for a communication point.
|
||||||
|
|
||||||
.. function:: inplace_cb_query(qinfo, flags, qstate, addr, zone, region)
|
.. function:: inplace_cb_query(qinfo, flags, qstate, addr, zone, region)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
# This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is
|
# This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is
|
||||||
# intentionally bogus. The reply will contain an empty EDNS option
|
# intentionally bogus. The reply will contain an empty EDNS option
|
||||||
# with option code 65003.
|
# with option code 65003.
|
||||||
# Unbound will also log the source address(es) of the client(s) that made
|
# Unbound will also log the source address of the client that made
|
||||||
# the request.
|
# the request.
|
||||||
# (unbound needs to be validating for this example to work)
|
# (unbound needs to be validating for this example to work)
|
||||||
|
|
||||||
|
|
@ -91,8 +91,6 @@ def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -121,8 +119,6 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -173,8 +169,6 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -205,13 +199,11 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||||
release. Current parameters:
|
release. Current parameters:
|
||||||
``repinfo``: Reply information for a communication point (comm_reply).
|
``repinfo``: Reply information for a communication point (comm_reply).
|
||||||
It is None when the callback happens in the mesh
|
|
||||||
states(modules).
|
|
||||||
|
|
||||||
:return: True on success, False on failure.
|
:return: True on success, False on failure.
|
||||||
|
|
||||||
For demonstration purposes we want to reply with an empty EDNS code '65003'
|
For demonstration purposes we want to reply with an empty EDNS code '65003'
|
||||||
and log the IP address(es) of the client(s).
|
and log the IP address of the client.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
log_info("python: called back while servfail.")
|
log_info("python: called back while servfail.")
|
||||||
|
|
@ -219,30 +211,14 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||||
b = bytearray.fromhex("")
|
b = bytearray.fromhex("")
|
||||||
edns_opt_list_append(opt_list_out, 65003, b, region)
|
edns_opt_list_append(opt_list_out, 65003, b, region)
|
||||||
|
|
||||||
# Log the client(s) IP address(es)
|
# Log the client's IP address
|
||||||
comm_reply = kwargs['repinfo']
|
comm_reply = kwargs['repinfo']
|
||||||
if comm_reply:
|
if comm_reply:
|
||||||
# If it is not None this callback was called before the query reached
|
|
||||||
# the mesh states(modules). There is only one client associated with
|
|
||||||
# this query.
|
|
||||||
addr = comm_reply.addr
|
addr = comm_reply.addr
|
||||||
port = comm_reply.port
|
port = comm_reply.port
|
||||||
addr_family = comm_reply.family
|
addr_family = comm_reply.family
|
||||||
log_info("python: Client IP: {}({}), port: {}"
|
log_info("python: Client IP: {}({}), port: {}"
|
||||||
"".format(addr, addr_family, port))
|
"".format(addr, addr_family, port))
|
||||||
else:
|
|
||||||
# If it is not None this callback was called while the query is in the
|
|
||||||
# mesh states(modules). In this case they may be multiple clients
|
|
||||||
# waiting for this query.
|
|
||||||
# The following code is the same as with the resip.py example.
|
|
||||||
rl = qstate.mesh_info.reply_list
|
|
||||||
while (rl):
|
|
||||||
if rl.query_reply:
|
|
||||||
q = rl.query_reply
|
|
||||||
log_info("python: Client IP: {}({}), port: {}"
|
|
||||||
"".format(q.addr, q.family, q.port))
|
|
||||||
rl = rl.next
|
|
||||||
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1224,18 +1224,24 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||||
r->h2_stream->mesh_state = NULL;
|
r->h2_stream->mesh_state = NULL;
|
||||||
}
|
}
|
||||||
/* send the reply */
|
/* send the reply */
|
||||||
/* We don't reuse the encoded answer if either the previous or current
|
/* We don't reuse the encoded answer if:
|
||||||
* response has a local alias. We could compare the alias records
|
* - either the previous or current response has a local alias. We could
|
||||||
* and still reuse the previous answer if they are the same, but that
|
* compare the alias records and still reuse the previous answer if they
|
||||||
* would be complicated and error prone for the relatively minor case.
|
* are the same, but that would be complicated and error prone for the
|
||||||
* So we err on the side of safety. */
|
* relatively minor case. So we err on the side of safety.
|
||||||
if(prev && prev_buffer && prev->qflags == r->qflags &&
|
* - there are registered callback functions for the given rcode, as these
|
||||||
|
* need to be called for each reply. */
|
||||||
|
if(((rcode != LDNS_RCODE_SERVFAIL &&
|
||||||
|
!m->s.env->inplace_cb_lists[inplace_cb_reply]) ||
|
||||||
|
(rcode == LDNS_RCODE_SERVFAIL &&
|
||||||
|
!m->s.env->inplace_cb_lists[inplace_cb_reply_servfail])) &&
|
||||||
|
prev && prev_buffer && prev->qflags == r->qflags &&
|
||||||
!prev->local_alias && !r->local_alias &&
|
!prev->local_alias && !r->local_alias &&
|
||||||
prev->edns.edns_present == r->edns.edns_present &&
|
prev->edns.edns_present == r->edns.edns_present &&
|
||||||
prev->edns.bits == r->edns.bits &&
|
prev->edns.bits == r->edns.bits &&
|
||||||
prev->edns.udp_size == r->edns.udp_size &&
|
prev->edns.udp_size == r->edns.udp_size &&
|
||||||
edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
|
edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
|
||||||
== 0 && !m->s.env->inplace_cb_lists[inplace_cb_reply]) {
|
== 0) {
|
||||||
/* if the previous reply is identical to this one, fix ID */
|
/* if the previous reply is identical to this one, fix ID */
|
||||||
if(prev_buffer != r_buffer)
|
if(prev_buffer != r_buffer)
|
||||||
sldns_buffer_copy(r_buffer, prev_buffer);
|
sldns_buffer_copy(r_buffer, prev_buffer);
|
||||||
|
|
@ -1250,11 +1256,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||||
m->s.qinfo.local_alias = r->local_alias;
|
m->s.qinfo.local_alias = r->local_alias;
|
||||||
if(rcode == LDNS_RCODE_SERVFAIL) {
|
if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||||
rep, rcode, &r->edns, NULL, m->s.region))
|
rep, rcode, &r->edns, &r->query_reply, m->s.region))
|
||||||
r->edns.opt_list = NULL;
|
r->edns.opt_list = NULL;
|
||||||
} else {
|
} else {
|
||||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
|
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
|
||||||
&r->edns, NULL, m->s.region))
|
&r->edns, &r->query_reply, m->s.region))
|
||||||
r->edns.opt_list = NULL;
|
r->edns.opt_list = NULL;
|
||||||
}
|
}
|
||||||
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
|
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
|
||||||
|
|
@ -1271,7 +1277,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||||
m->s.qinfo.qname = r->qname;
|
m->s.qinfo.qname = r->qname;
|
||||||
m->s.qinfo.local_alias = r->local_alias;
|
m->s.qinfo.local_alias = r->local_alias;
|
||||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
|
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
|
||||||
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) ||
|
LDNS_RCODE_NOERROR, &r->edns, &r->query_reply, m->s.region) ||
|
||||||
!apply_edns_options(&r->edns, &edns_bak,
|
!apply_edns_options(&r->edns, &edns_bak,
|
||||||
m->s.env->cfg, r->query_reply.c,
|
m->s.env->cfg, r->query_reply.c,
|
||||||
m->s.region) ||
|
m->s.region) ||
|
||||||
|
|
@ -1281,7 +1287,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||||
secure))
|
secure))
|
||||||
{
|
{
|
||||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region))
|
rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region))
|
||||||
r->edns.opt_list = NULL;
|
r->edns.opt_list = NULL;
|
||||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||||
&m->s.qinfo, r->qid, r->qflags, &r->edns);
|
&m->s.qinfo, r->qid, r->qflags, &r->edns);
|
||||||
|
|
|
||||||
|
|
@ -552,7 +552,7 @@ struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
|
||||||
* @param rep: Reply info. Could be NULL.
|
* @param rep: Reply info. Could be NULL.
|
||||||
* @param rcode: return code.
|
* @param rcode: return code.
|
||||||
* @param edns: edns data of the reply.
|
* @param edns: edns data of the reply.
|
||||||
* @param repinfo: comm_reply. NULL.
|
* @param repinfo: comm_reply. Reply information for a communication point.
|
||||||
* @param region: region to store data.
|
* @param region: region to store data.
|
||||||
* @return false on failure (a callback function returned an error).
|
* @return false on failure (a callback function returned an error).
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue