mirror of https://github.com/getdnsapi/getdns.git
added edns_client_subnet_private to getdns_context
https://tools.ietf.org/html/draft-ietf-dnsop-edns-client-subnet-04 Using the above spec, an intermediate resolver may forward a chunk of the client's IP address to the authoritative resolver. Setting edns_client_subnet_private to a getdns_context in stub mode will indicate to the next-hop recursive resolver that the client wishes to keep their address information private.
This commit is contained in:
parent
0b388872ea
commit
df3725e635
|
@ -881,6 +881,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->edns_extended_rcode = 0;
|
||||
result->edns_version = 0;
|
||||
result->edns_do_bit = 0;
|
||||
result->edns_client_subnet_private = 0;
|
||||
result-> tls_ctx = NULL;
|
||||
|
||||
result->extension = &result->mini_event.loop;
|
||||
|
@ -1897,6 +1898,26 @@ getdns_context_set_edns_do_bit(struct getdns_context *context, uint8_t value)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_edns_do_bit */
|
||||
|
||||
/*
|
||||
* getdns_context_set_edns_client_subnet_private
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_edns_client_subnet_private(struct getdns_context *context, uint8_t value)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* only allow 1 */
|
||||
if (value != 0 && value != 1) {
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
|
||||
context->edns_client_subnet_private = value;
|
||||
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_edns_client_subnet_private */
|
||||
|
||||
/*
|
||||
* getdns_context_set_extended_memory_functions
|
||||
*
|
||||
|
@ -2966,4 +2987,12 @@ getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value) {
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t* value) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
*value = context->edns_client_subnet_private;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/* context.c */
|
||||
|
|
|
@ -157,6 +157,7 @@ struct getdns_context {
|
|||
uint8_t edns_version;
|
||||
uint8_t edns_do_bit;
|
||||
int edns_maximum_udp_payload_size; /* -1 is unset */
|
||||
uint8_t edns_client_subnet_private;
|
||||
SSL_CTX* tls_ctx;
|
||||
|
||||
getdns_update_callback update_callback;
|
||||
|
|
|
@ -194,6 +194,11 @@ getdns_context_get_edns_version(getdns_context *context, uint8_t* value);
|
|||
getdns_return_t
|
||||
getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t value);
|
||||
getdns_return_t
|
||||
getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t* value);
|
||||
|
||||
|
||||
/**
|
||||
* Pretty print the getdns_dict in a given buffer snprintf style.
|
||||
|
@ -366,6 +371,8 @@ typedef enum getdns_tls_authentication_t {
|
|||
|
||||
#define GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION 618
|
||||
#define GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION_TEXT "Change related to getdns_context_set_tls_authentication"
|
||||
#define GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE 619
|
||||
#define GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE_TEXT "Change related to getdns_context_set_edns_client_subnet_private"
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_authentication(
|
||||
|
|
|
@ -13,6 +13,7 @@ getdns_context_get_dnssec_allowed_skew
|
|||
getdns_context_get_dnssec_trust_anchors
|
||||
getdns_context_get_dns_transport
|
||||
getdns_context_get_dns_transport_list
|
||||
getdns_context_get_edns_client_subnet_private
|
||||
getdns_context_get_edns_do_bit
|
||||
getdns_context_get_edns_extended_rcode
|
||||
getdns_context_get_edns_maximum_udp_payload_size
|
||||
|
@ -36,6 +37,7 @@ getdns_context_set_dnssec_allowed_skew
|
|||
getdns_context_set_dnssec_trust_anchors
|
||||
getdns_context_set_dns_transport
|
||||
getdns_context_set_dns_transport_list
|
||||
getdns_context_set_edns_client_subnet_private
|
||||
getdns_context_set_edns_do_bit
|
||||
getdns_context_set_edns_extended_rcode
|
||||
getdns_context_set_edns_maximum_udp_payload_size
|
||||
|
|
|
@ -367,7 +367,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
with_opt = edns_do_bit != 0 || edns_maximum_udp_payload_size != 512 ||
|
||||
edns_extended_rcode != 0 || edns_version != 0 || noptions ||
|
||||
edns_cookies;
|
||||
edns_cookies || context->edns_client_subnet_private;
|
||||
|
||||
edns_maximum_udp_payload_size = with_opt &&
|
||||
( edns_maximum_udp_payload_size == -1 ||
|
||||
|
@ -437,6 +437,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->dnssec_return_only_secure = dnssec_return_only_secure;
|
||||
result->dnssec_return_validation_chain = dnssec_return_validation_chain;
|
||||
result->edns_cookies = edns_cookies;
|
||||
result->edns_client_subnet_private = context->edns_client_subnet_private;
|
||||
|
||||
/* will be set by caller */
|
||||
result->user_pointer = NULL;
|
||||
|
|
23
src/stub.c
23
src/stub.c
|
@ -130,6 +130,20 @@ calc_new_cookie(getdns_upstream *upstream, uint8_t *cookie)
|
|||
cookie[i % 8] ^= md_value[i];
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
attach_edns_client_subnet_private(getdns_network_req *req)
|
||||
{
|
||||
/* see
|
||||
* https://tools.ietf.org/html/draft-ietf-dnsop-edns-client-subnet-04#section-6 */
|
||||
/* all-zeros is a request to not leak the data further: */
|
||||
/* "\x00\x00" FAMILY: 0 (because no address) */
|
||||
/* "\x00" SOURCE PREFIX-LENGTH: 0 */
|
||||
/* "\x00"; SCOPE PREFIX-LENGTH: 0 */
|
||||
return _getdns_network_req_add_upstream_option(req,
|
||||
GLDNS_EDNS_CLIENT_SUBNET,
|
||||
4, NULL);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
attach_edns_cookie(getdns_network_req *req)
|
||||
{
|
||||
|
@ -702,6 +716,9 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
|||
if (netreq->owner->edns_cookies)
|
||||
if (attach_edns_cookie(netreq))
|
||||
return STUB_OUT_OF_OPTIONS;
|
||||
if (netreq->owner->edns_client_subnet_private)
|
||||
if (attach_edns_client_subnet_private(netreq))
|
||||
return STUB_OUT_OF_OPTIONS;
|
||||
}
|
||||
pkt_len = netreq->response - netreq->query;
|
||||
/* We have an initialized packet buffer.
|
||||
|
@ -1153,6 +1170,9 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
|||
/* we do not edns_cookie over TLS, since TLS
|
||||
* provides stronger guarantees than cookies
|
||||
* already */
|
||||
if (netreq->owner->edns_client_subnet_private)
|
||||
if (attach_edns_client_subnet_private(netreq))
|
||||
return STUB_OUT_OF_OPTIONS;
|
||||
}
|
||||
|
||||
pkt_len = netreq->response - netreq->query;
|
||||
|
@ -1260,6 +1280,9 @@ stub_udp_write_cb(void *userarg)
|
|||
if (netreq->owner->edns_cookies)
|
||||
if (attach_edns_cookie(netreq))
|
||||
return; /* too many upstream options */
|
||||
if (netreq->owner->edns_client_subnet_private)
|
||||
if (attach_edns_client_subnet_private(netreq))
|
||||
return; /* too many upstream options */
|
||||
}
|
||||
pkt_len = netreq->response - netreq->query;
|
||||
if ((ssize_t)pkt_len != sendto(netreq->fd, netreq->query, pkt_len, 0,
|
||||
|
|
|
@ -275,6 +275,7 @@ typedef struct getdns_dns_req {
|
|||
int dnssec_return_only_secure;
|
||||
int dnssec_return_validation_chain;
|
||||
int edns_cookies;
|
||||
int edns_client_subnet_private;
|
||||
|
||||
/* Internally used by return_validation_chain */
|
||||
int dnssec_ok_checking_disabled;
|
||||
|
|
Loading…
Reference in New Issue