Import the patches from the files in the tarball in

issue #365 https://github.com/NLnetLabs/unbound/files/5659923/patches.tar.gz
from iruzanov.  The merge conflicts are fixed, but no changes are made
to the patched code.
This commit is contained in:
W.C.A. Wijngaards 2020-12-09 11:00:51 +01:00
parent b49cc2e667
commit bdfa65c6ab
10 changed files with 353 additions and 95 deletions

View file

@ -1159,9 +1159,21 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
} }
#endif #endif
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
if(worker->dtenv.log_client_query_messages) /*
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type, * sending src (client)/dst (local service) addresses over DNSTAP from incoming request handler
c->buffer); */
if(worker->dtenv.log_client_query_messages) {
struct sockaddr_storage* dst_addr;
if(repinfo->addr.ss_family == AF_INET)
dst_addr = mk_local_addr(&((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
else
dst_addr = mk_local_addr(&((struct sockaddr_in6*)repinfo->c->socket->addr->ai_addr)->sin6_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
log_addr(VERB_ALGO, "request from client", &repinfo->addr, repinfo->addrlen);
log_addr(VERB_ALGO, "to local addr", dst_addr, sizeof(dst_addr));
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, dst_addr, c->type, c->buffer);
if(dst_addr)
free(dst_addr);
}
#endif #endif
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr, acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
repinfo->addrlen); repinfo->addrlen);
@ -1584,9 +1596,21 @@ send_reply_rc:
if(is_secure_answer) worker->stats.ans_secure++; if(is_secure_answer) worker->stats.ans_secure++;
} }
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
if(worker->dtenv.log_client_response_messages) /*
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, * sending src (client)/dst (local service) addresses over DNSTAP from send_reply code label (when we serviced local zone for ex.)
c->type, c->buffer); */
if(worker->dtenv.log_client_response_messages) {
struct sockaddr_storage* dst_addr;
if(repinfo->addr.ss_family == AF_INET)
dst_addr = mk_local_addr(&((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
else
dst_addr = mk_local_addr(&((struct sockaddr_in6*)repinfo->c->socket->addr->ai_addr)->sin6_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
log_addr(VERB_ALGO, "from local addr", dst_addr, sizeof(dst_addr));
log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, dst_addr, c->type, c->buffer);
if(dst_addr)
free(dst_addr);
}
#endif #endif
if(worker->env.cfg->log_replies) if(worker->env.cfg->log_replies)
{ {

View file

@ -302,42 +302,73 @@ dt_fill_buffer(sldns_buffer *b, ProtobufCBinaryData *p, protobuf_c_boolean *has)
static void static void
dt_msg_fill_net(struct dt_msg *dm, dt_msg_fill_net(struct dt_msg *dm,
struct sockaddr_storage *ss, struct sockaddr_storage *qs,
struct sockaddr_storage *rs,
enum comm_point_type cptype, enum comm_point_type cptype,
ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr, ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
uint32_t *port, protobuf_c_boolean *has_port) uint32_t *qport, protobuf_c_boolean *has_qport,
ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
uint32_t *rport, protobuf_c_boolean *has_rport)
{ {
log_assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET); log_assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
if (ss->ss_family == AF_INET6) { if (qs->ss_family == AF_INET6) {
struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss; struct sockaddr_in6 *q = (struct sockaddr_in6 *) qs;
/* socket_family */ /* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6; dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
dm->m.has_socket_family = 1; dm->m.has_socket_family = 1;
/* addr: query_address or response_address */ /* addr: query_address or response_address */
addr->data = s->sin6_addr.s6_addr; qaddr->data = q->sin6_addr.s6_addr;
addr->len = 16; /* IPv6 */ qaddr->len = 16; /* IPv6 */
*has_addr = 1; *has_qaddr = 1;
/* port: query_port or response_port */ /* port: query_port or response_port */
*port = ntohs(s->sin6_port); *qport = ntohs(q->sin6_port);
*has_port = 1; *has_qport = 1;
} else if (ss->ss_family == AF_INET) { } else if (qs->ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *) ss; struct sockaddr_in *q = (struct sockaddr_in *) qs;
/* socket_family */ /* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET; dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
dm->m.has_socket_family = 1; dm->m.has_socket_family = 1;
/* addr: query_address or response_address */ /* addr: query_address or response_address */
addr->data = (uint8_t *) &s->sin_addr.s_addr; qaddr->data = (uint8_t *) &q->sin_addr.s_addr;
addr->len = 4; /* IPv4 */ qaddr->len = 4; /* IPv4 */
*has_addr = 1; *has_qaddr = 1;
/* port: query_port or response_port */ /* port: query_port or response_port */
*port = ntohs(s->sin_port); *qport = ntohs(q->sin_port);
*has_port = 1; *has_qport = 1;
}
/*
* This block is to fill second set of fields in DNSTAP-message defined as request_/response_ names.
* Additional responsive structure is: struct sockaddr_storage *rs
*/
if (rs->ss_family == AF_INET6) {
struct sockaddr_in6 *r = (struct sockaddr_in6 *) rs;
/* addr: query_address or response_address */
raddr->data = r->sin6_addr.s6_addr;
raddr->len = 16; /* IPv6 */
*has_raddr = 1;
/* port: query_port or response_port */
*rport = ntohs(r->sin6_port);
*has_rport = 1;
} else if (rs->ss_family == AF_INET) {
struct sockaddr_in *r = (struct sockaddr_in *) rs;
/* addr: query_address or response_address */
raddr->data = (uint8_t *) &r->sin_addr.s_addr;
raddr->len = 4; /* IPv4 */
*has_raddr = 1;
/* port: query_port or response_port */
*rport = ntohs(r->sin_port);
*has_rport = 1;
} }
log_assert(cptype == comm_udp || cptype == comm_tcp); log_assert(cptype == comm_udp || cptype == comm_tcp);
@ -355,6 +386,7 @@ dt_msg_fill_net(struct dt_msg *dm,
void void
dt_msg_send_client_query(struct dt_env *env, dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock, struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype, enum comm_point_type cptype,
sldns_buffer *qmsg) sldns_buffer *qmsg)
{ {
@ -374,11 +406,14 @@ dt_msg_send_client_query(struct dt_env *env,
/* query_message */ /* query_message */
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message); dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, query_address, query_port */ /* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp); log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, qsock, cptype, dt_msg_fill_net(&dm, qsock, rsock, cptype,
&dm.m.query_address, &dm.m.has_query_address, &dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port); &dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf); dt_send(env, dm.buf, dm.len_buf);
@ -387,6 +422,7 @@ dt_msg_send_client_query(struct dt_env *env,
void void
dt_msg_send_client_response(struct dt_env *env, dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock, struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype, enum comm_point_type cptype,
sldns_buffer *rmsg) sldns_buffer *rmsg)
{ {
@ -406,11 +442,13 @@ dt_msg_send_client_response(struct dt_env *env,
/* response_message */ /* response_message */
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message); dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, query_address, query_port */ /* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp); log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, qsock, cptype, dt_msg_fill_net(&dm, qsock, rsock, cptype,
&dm.m.query_address, &dm.m.has_query_address, &dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port); &dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf); dt_send(env, dm.buf, dm.len_buf);
@ -419,6 +457,7 @@ dt_msg_send_client_response(struct dt_env *env,
void void
dt_msg_send_outside_query(struct dt_env *env, dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock, struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype, enum comm_point_type cptype,
uint8_t *zone, size_t zone_len, uint8_t *zone, size_t zone_len,
sldns_buffer *qmsg) sldns_buffer *qmsg)
@ -454,11 +493,13 @@ dt_msg_send_outside_query(struct dt_env *env,
/* query_message */ /* query_message */
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message); dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, response_address, response_port */ /* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp); log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, rsock, cptype, dt_msg_fill_net(&dm, rsock, qsock, cptype,
&dm.m.response_address, &dm.m.has_response_address, &dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port); &dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf); dt_send(env, dm.buf, dm.len_buf);
@ -467,6 +508,7 @@ dt_msg_send_outside_query(struct dt_env *env,
void void
dt_msg_send_outside_response(struct dt_env *env, dt_msg_send_outside_response(struct dt_env *env,
struct sockaddr_storage *rsock, struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype, enum comm_point_type cptype,
uint8_t *zone, size_t zone_len, uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len, uint8_t *qbuf, size_t qbuf_len,
@ -510,11 +552,13 @@ dt_msg_send_outside_response(struct dt_env *env,
/* response_message */ /* response_message */
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message); dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, response_address, response_port */ /* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp); log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, rsock, cptype, dt_msg_fill_net(&dm, rsock, qsock, cptype,
&dm.m.response_address, &dm.m.has_response_address, &dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port); &dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf); dt_send(env, dm.buf, dm.len_buf);

View file

@ -123,12 +123,14 @@ dt_delete(struct dt_env *env);
* Create and send a new dnstap "Message" event of type CLIENT_QUERY. * Create and send a new dnstap "Message" event of type CLIENT_QUERY.
* @param env: dnstap environment object. * @param env: dnstap environment object.
* @param qsock: address/port of client. * @param qsock: address/port of client.
* @param rsock: local (service) address/port.
* @param cptype: comm_udp or comm_tcp. * @param cptype: comm_udp or comm_tcp.
* @param qmsg: query message. * @param qmsg: query message.
*/ */
void void
dt_msg_send_client_query(struct dt_env *env, dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock, struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype, enum comm_point_type cptype,
struct sldns_buffer *qmsg); struct sldns_buffer *qmsg);
@ -136,12 +138,14 @@ dt_msg_send_client_query(struct dt_env *env,
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE. * Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
* @param env: dnstap environment object. * @param env: dnstap environment object.
* @param qsock: address/port of client. * @param qsock: address/port of client.
* @param rsock: local (service) address/port.
* @param cptype: comm_udp or comm_tcp. * @param cptype: comm_udp or comm_tcp.
* @param rmsg: response message. * @param rmsg: response message.
*/ */
void void
dt_msg_send_client_response(struct dt_env *env, dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock, struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype, enum comm_point_type cptype,
struct sldns_buffer *rmsg); struct sldns_buffer *rmsg);
@ -150,7 +154,8 @@ dt_msg_send_client_response(struct dt_env *env,
* FORWARDER_QUERY. The type used is dependent on the value of the RD bit * FORWARDER_QUERY. The type used is dependent on the value of the RD bit
* in the query header. * in the query header.
* @param env: dnstap environment object. * @param env: dnstap environment object.
* @param rsock: address/port of server the query is being sent to. * @param rsock: address/port of server (upstream) the query is being sent to.
* @param qsock: address/port of server (local) the query is being sent from.
* @param cptype: comm_udp or comm_tcp. * @param cptype: comm_udp or comm_tcp.
* @param zone: query zone. * @param zone: query zone.
* @param zone_len: length of zone. * @param zone_len: length of zone.
@ -159,6 +164,7 @@ dt_msg_send_client_response(struct dt_env *env,
void void
dt_msg_send_outside_query(struct dt_env *env, dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock, struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype, enum comm_point_type cptype,
uint8_t *zone, size_t zone_len, uint8_t *zone, size_t zone_len,
struct sldns_buffer *qmsg); struct sldns_buffer *qmsg);
@ -168,7 +174,8 @@ dt_msg_send_outside_query(struct dt_env *env,
* FORWARDER_RESPONSE. The type used is dependent on the value of the RD bit * FORWARDER_RESPONSE. The type used is dependent on the value of the RD bit
* in the query header. * in the query header.
* @param env: dnstap environment object. * @param env: dnstap environment object.
* @param rsock: address/port of server the response was received from. * @param rsock: address/port of server (upstream) the response was received from.
* @param qsock: address/port of server (local) the response was received to.
* @param cptype: comm_udp or comm_tcp. * @param cptype: comm_udp or comm_tcp.
* @param zone: query zone. * @param zone: query zone.
* @param zone_len: length of zone. * @param zone_len: length of zone.
@ -181,6 +188,7 @@ dt_msg_send_outside_query(struct dt_env *env,
void void
dt_msg_send_outside_response(struct dt_env *env, dt_msg_send_outside_response(struct dt_env *env,
struct sockaddr_storage *rsock, struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype, enum comm_point_type cptype,
uint8_t *zone, size_t zone_len, uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len, uint8_t *qbuf, size_t qbuf_len,

View file

@ -133,6 +133,16 @@ verbose_print_addr(struct addrinfo *addr)
} }
} }
void
verbose_print_unbound_socket(struct unbound_socket* ub_sock)
{
if(verbosity >= VERB_ALGO) {
log_info("listing of unbound_socket structure:");
verbose_print_addr(ub_sock->addr);
log_info("s is: %d, fam is: %s, tcp_read_fd is: %d", ub_sock->s, ub_sock->fam == AF_INET?"AF_INET":"AF_INET6", ub_sock->tcp_read_fd);
}
}
#ifdef HAVE_SYSTEMD #ifdef HAVE_SYSTEMD
static int static int
systemd_get_activated(int family, int socktype, int listen, systemd_get_activated(int family, int socktype, int listen,
@ -916,7 +926,7 @@ static int
make_sock(int stype, const char* ifname, const char* port, make_sock(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd, struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind, int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
int use_systemd, int dscp) int use_systemd, int dscp, struct unbound_socket** ub_sock)
{ {
struct addrinfo *res = NULL; struct addrinfo *res = NULL;
int r, s, inuse, noproto; int r, s, inuse, noproto;
@ -958,7 +968,12 @@ make_sock(int stype, const char* ifname, const char* port,
*noip6 = 1; *noip6 = 1;
} }
} }
freeaddrinfo(res);
(*ub_sock)->addr = res;
(*ub_sock)->s = s;
(*ub_sock)->fam = hints->ai_family;
(*ub_sock)->tcp_read_fd = -1;
return s; return s;
} }
@ -967,7 +982,7 @@ static int
make_sock_port(int stype, const char* ifname, const char* port, make_sock_port(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd, struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind, int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
int use_systemd, int dscp) int use_systemd, int dscp, struct unbound_socket** ub_sock)
{ {
char* s = strchr(ifname, '@'); char* s = strchr(ifname, '@');
if(s) { if(s) {
@ -990,11 +1005,11 @@ make_sock_port(int stype, const char* ifname, const char* port,
p[strlen(s+1)]=0; p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6, rcv, return make_sock(stype, newif, p, hints, v6only, noip6, rcv,
snd, reuseport, transparent, tcp_mss, nodelay, freebind, snd, reuseport, transparent, tcp_mss, nodelay, freebind,
use_systemd, dscp); use_systemd, dscp, ub_sock);
} }
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd, return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd,
dscp); dscp, ub_sock);
} }
/** /**
@ -1005,7 +1020,7 @@ make_sock_port(int stype, const char* ifname, const char* port,
* @return false on failure. list in unchanged then. * @return false on failure. list in unchanged then.
*/ */
static int static int
port_insert(struct listen_port** list, int s, enum listen_type ftype) port_insert(struct listen_port** list, int s, enum listen_type ftype, struct unbound_socket* ub_sock)
{ {
struct listen_port* item = (struct listen_port*)malloc( struct listen_port* item = (struct listen_port*)malloc(
sizeof(struct listen_port)); sizeof(struct listen_port));
@ -1014,6 +1029,7 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype)
item->next = *list; item->next = *list;
item->fd = s; item->fd = s;
item->ftype = ftype; item->ftype = ftype;
item->socket = ub_sock;
*list = item; *list = item;
return 1; return 1;
} }
@ -1043,7 +1059,7 @@ set_recvpktinfo(int s, int family)
return 0; return 0;
} }
# else # else
log_err("no IPV6_RECVPKTINFO and no IPV6_PKTINFO option, please " log_err("no IPV6_RECVPKTINFO and IPV6_PKTINFO options, please "
"disable interface-automatic or do-ip6 in config"); "disable interface-automatic or do-ip6 in config");
return 0; return 0;
# endif /* defined IPV6_RECVPKTINFO */ # endif /* defined IPV6_RECVPKTINFO */
@ -1142,6 +1158,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
int s, noip6=0; int s, noip6=0;
int is_https = if_is_https(ifname, port, https_port); int is_https = if_is_https(ifname, port, https_port);
int nodelay = is_https && http2_nodelay; int nodelay = is_https && http2_nodelay;
struct unbound_socket* ub_sock;
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT
int is_dnscrypt = ((strchr(ifname, '@') && int is_dnscrypt = ((strchr(ifname, '@') &&
atoi(strchr(ifname, '@')+1) == dnscrypt_port) || atoi(strchr(ifname, '@')+1) == dnscrypt_port) ||
@ -1153,10 +1170,14 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
if(!do_udp && !do_tcp) if(!do_udp && !do_tcp)
return 0; return 0;
if(do_auto) { if(do_auto) {
ub_sock = malloc(sizeof(struct unbound_socket));
if(!ub_sock)
return 0;
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent, &noip6, rcv, snd, reuseport, transparent,
tcp_mss, nodelay, freebind, use_systemd, dscp)) == -1) { tcp_mss, nodelay, freebind, use_systemd, dscp, &ub_sock)) == -1) {
if(noip6) { if(noip6) {
log_warn("IPv6 protocol not available"); log_warn("IPv6 protocol not available");
return 1; return 1;
@ -1169,15 +1190,18 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
return 0; return 0;
} }
if(!port_insert(list, s, if(!port_insert(list, s,
is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil)) { is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil, ub_sock)) {
sock_close(s); sock_close(s);
return 0; return 0;
} }
} else if(do_udp) { } else if(do_udp) {
ub_sock = malloc(sizeof(struct unbound_socket));
if(!ub_sock)
return 0;
/* regular udp socket */ /* regular udp socket */
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent, &noip6, rcv, snd, reuseport, transparent,
tcp_mss, nodelay, freebind, use_systemd, dscp)) == -1) { tcp_mss, nodelay, freebind, use_systemd, dscp, &ub_sock)) == -1) {
if(noip6) { if(noip6) {
log_warn("IPv6 protocol not available"); log_warn("IPv6 protocol not available");
return 1; return 1;
@ -1185,12 +1209,15 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
return 0; return 0;
} }
if(!port_insert(list, s, if(!port_insert(list, s,
is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp)) { is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp, ub_sock)) {
sock_close(s); sock_close(s);
return 0; return 0;
} }
} }
if(do_tcp) { if(do_tcp) {
ub_sock = malloc(sizeof(struct unbound_socket));
if(!ub_sock)
return 0;
int is_ssl = if_is_ssl(ifname, port, ssl_port, int is_ssl = if_is_ssl(ifname, port, ssl_port,
tls_additional_port); tls_additional_port);
enum listen_type port_type; enum listen_type port_type;
@ -1204,7 +1231,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
port_type = listen_type_tcp; port_type = listen_type_tcp;
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1, if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
&noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay, &noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay,
freebind, use_systemd, dscp)) == -1) { freebind, use_systemd, dscp, &ub_sock)) == -1) {
if(noip6) { if(noip6) {
/*log_warn("IPv6 protocol not available");*/ /*log_warn("IPv6 protocol not available");*/
return 1; return 1;
@ -1213,7 +1240,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
} }
if(is_ssl) if(is_ssl)
verbose(VERB_ALGO, "setup TCP for SSL service"); verbose(VERB_ALGO, "setup TCP for SSL service");
if(!port_insert(list, s, port_type)) { if(!port_insert(list, s, port_type, ub_sock)) {
sock_close(s); sock_close(s);
return 0; return 0;
} }
@ -1280,14 +1307,14 @@ listen_create(struct comm_base* base, struct listen_port* ports,
if(ports->ftype == listen_type_udp || if(ports->ftype == listen_type_udp ||
ports->ftype == listen_type_udp_dnscrypt) ports->ftype == listen_type_udp_dnscrypt)
cp = comm_point_create_udp(base, ports->fd, cp = comm_point_create_udp(base, ports->fd,
front->udp_buff, cb, cb_arg); front->udp_buff, cb, cb_arg, ports->socket);
else if(ports->ftype == listen_type_tcp || else if(ports->ftype == listen_type_tcp ||
ports->ftype == listen_type_tcp_dnscrypt) ports->ftype == listen_type_tcp_dnscrypt)
cp = comm_point_create_tcp(base, ports->fd, cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, tcp_idle_timeout, tcp_accept_count, tcp_idle_timeout,
harden_large_queries, 0, NULL, harden_large_queries, 0, NULL,
tcp_conn_limit, bufsize, front->udp_buff, tcp_conn_limit, bufsize, front->udp_buff,
ports->ftype, cb, cb_arg); ports->ftype, cb, cb_arg, ports->socket);
else if(ports->ftype == listen_type_ssl || else if(ports->ftype == listen_type_ssl ||
ports->ftype == listen_type_http) { ports->ftype == listen_type_http) {
cp = comm_point_create_tcp(base, ports->fd, cp = comm_point_create_tcp(base, ports->fd,
@ -1295,7 +1322,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
harden_large_queries, harden_large_queries,
http_max_streams, http_endpoint, http_max_streams, http_endpoint,
tcp_conn_limit, bufsize, front->udp_buff, tcp_conn_limit, bufsize, front->udp_buff,
ports->ftype, cb, cb_arg); ports->ftype, cb, cb_arg, ports->socket);
if(http_notls && ports->ftype == listen_type_http) if(http_notls && ports->ftype == listen_type_http)
cp->ssl = NULL; cp->ssl = NULL;
else else
@ -1322,7 +1349,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
} else if(ports->ftype == listen_type_udpancil || } else if(ports->ftype == listen_type_udpancil ||
ports->ftype == listen_type_udpancil_dnscrypt) ports->ftype == listen_type_udpancil_dnscrypt)
cp = comm_point_create_udp_ancil(base, ports->fd, cp = comm_point_create_udp_ancil(base, ports->fd,
front->udp_buff, cb, cb_arg); front->udp_buff, cb, cb_arg, ports->socket);
if(!cp) { if(!cp) {
log_err("can't create commpoint"); log_err("can't create commpoint");
listen_delete(front); listen_delete(front);
@ -1656,6 +1683,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
} }
} }
} }
return list; return list;
} }
@ -1667,6 +1695,8 @@ void listening_ports_free(struct listen_port* list)
if(list->fd != -1) { if(list->fd != -1) {
sock_close(list->fd); sock_close(list->fd);
} }
free(list->socket->addr);
free(list->socket);
free(list); free(list);
list = nx; list = nx;
} }

View file

@ -102,6 +102,20 @@ enum listen_type {
listen_type_http listen_type_http
}; };
/*
* socket properties (just like NSD nsd_socket structure definition)
*/
struct unbound_socket {
/** socket-address structure */
struct addrinfo * addr;
/** socket descriptor returned by socket() syscall */
int s;
/** address family (AF_INET/IF_INET6) */
int fam;
/** descriptor returned by accept() syscall for further usage. TODO: actually it might be useless here unlike in NSD where we have no comm_points mechanism with callback pointers for every created communication point */
int tcp_read_fd;
};
/** /**
* Single linked list to store shared ports that have been * Single linked list to store shared ports that have been
* opened for use by all threads. * opened for use by all threads.
@ -113,6 +127,8 @@ struct listen_port {
int fd; int fd;
/** type of file descriptor, udp or tcp */ /** type of file descriptor, udp or tcp */
enum listen_type ftype; enum listen_type ftype;
/** fill in unbpound_socket structure for every opened socket at Unbound startup */
struct unbound_socket* socket;
}; };
/** /**
@ -424,4 +440,9 @@ int http2_submit_dns_response(void* v);
char* set_ip_dscp(int socket, int addrfamily, int ds); char* set_ip_dscp(int socket, int addrfamily, int ds);
/** for debug and profiling purposes only
* @param unbound_socket: the structure containing created socket info we want to print or log for
*/
void verbose_print_unbound_socket(struct unbound_socket* ub_sock);
#endif /* LISTEN_DNSPORT_H */ #endif /* LISTEN_DNSPORT_H */

View file

@ -1440,7 +1440,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
return NULL; return NULL;
} }
pc->cp = comm_point_create_udp(outnet->base, -1, pc->cp = comm_point_create_udp(outnet->base, -1,
outnet->udp_buff, outnet_udp_cb, outnet); outnet->udp_buff, outnet_udp_cb, outnet, NULL);
if(!pc->cp) { if(!pc->cp) {
log_err("malloc failed"); log_err("malloc failed");
free(pc); free(pc);
@ -1921,11 +1921,27 @@ randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout)
comm_timer_set(pend->timer, &tv); comm_timer_set(pend->timer, &tv);
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/*
* sending src (local service)/dst (upstream) addresses over DNSTAP
* TODO: right now there are no chances to get the src (local service) addr. So we will pass 0.0.0.0 (::)
* to argument for dt_msg_send_outside_query()/dt_msg_send_outside_response() calls.
* For the both UDP and TCP.
*/
if(outnet->dtenv && if(outnet->dtenv &&
(outnet->dtenv->log_resolver_query_messages || (outnet->dtenv->log_resolver_query_messages ||
outnet->dtenv->log_forwarder_query_messages)) sq->outnet->dtenv->log_forwarder_query_messages)) {
dt_msg_send_outside_query(outnet->dtenv, &pend->addr, comm_udp, if(addr_is_ip6(&sq->addr, sq->addrlen)) {
pend->sq->zone, pend->sq->zonelen, packet); log_addr(VERB_ALGO, "from local addr", &sq->outnet->ip6_ifs->addr, sq->outnet->ip6_ifs->addrlen);
log_addr(VERB_ALGO, "request to upstream", &sq->addr, sq->addrlen);
dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr, &sq->outnet->ip6_ifs->addr,
comm_tcp, sq->zone, sq->zonelen, packet);
} else {
log_addr(VERB_ALGO, "from local addr", &sq->outnet->ip4_ifs->addr, sq->outnet->ip4_ifs->addrlen);
log_addr(VERB_ALGO, "request to upstream", &sq->addr, sq->addrlen);
dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr, &sq->outnet->ip4_ifs->addr,
comm_tcp, sq->zone, sq->zonelen, packet);
}
}
#endif #endif
return 1; return 1;
} }
@ -2707,12 +2723,26 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
infra_update_tcp_works(sq->outnet->infra, &sq->addr, infra_update_tcp_works(sq->outnet->infra, &sq->addr,
sq->addrlen, sq->zone, sq->zonelen); sq->addrlen, sq->zone, sq->zonelen);
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/*
* sending src (local service)/dst (upstream) addresses over DNSTAP
*/
if(error==NETEVENT_NOERROR && sq->outnet->dtenv && if(error==NETEVENT_NOERROR && sq->outnet->dtenv &&
(sq->outnet->dtenv->log_resolver_response_messages || (sq->outnet->dtenv->log_resolver_response_messages ||
sq->outnet->dtenv->log_forwarder_response_messages)) sq->outnet->dtenv->log_forwarder_response_messages)) {
dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr, if(addr_is_ip6(&sq->addr, sq->addrlen)) {
log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
log_addr(VERB_ALGO, "to local addr", &sq->outnet->ip6_ifs->addr, sq->outnet->ip6_ifs->addrlen);
dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr, &sq->outnet->ip6_ifs->addr,
c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer); &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
} else {
log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
log_addr(VERB_ALGO, "to local addr", &sq->outnet->ip4_ifs->addr, sq->outnet->ip4_ifs->addrlen);
dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr, &sq->outnet->ip4_ifs->addr,
c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
}
}
#endif #endif
if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS && if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS &&
(LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
@ -2903,12 +2933,26 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
return 0; return 0;
} }
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/*
* sending src (local service)/dst (upstream) addresses over DNSTAP
*/
if(error == NETEVENT_NOERROR && outnet->dtenv && if(error == NETEVENT_NOERROR && outnet->dtenv &&
(outnet->dtenv->log_resolver_response_messages || (outnet->dtenv->log_resolver_response_messages ||
outnet->dtenv->log_forwarder_response_messages)) outnet->dtenv->log_forwarder_response_messages)) {
dt_msg_send_outside_response(outnet->dtenv, &sq->addr, c->type, if(addr_is_ip6(&sq->addr, sq->addrlen)) {
log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
log_addr(VERB_ALGO, "to local addr", &sq->outnet->ip6_ifs->addr, sq->outnet->ip6_ifs->addrlen);
dt_msg_send_outside_response(outnet->dtenv, &sq->addr, &sq->outnet->ip6_ifs->addr, c->type,
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer); &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
} else {
log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
log_addr(VERB_ALGO, "to addr", &sq->outnet->ip4_ifs->addr, sq->outnet->ip4_ifs->addrlen);
dt_msg_send_outside_response(outnet->dtenv, &sq->addr, &sq->outnet->ip4_ifs->addr, c->type,
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
}
}
#endif #endif
if( (sq->status == serviced_query_UDP_EDNS if( (sq->status == serviced_query_UDP_EDNS
||sq->status == serviced_query_UDP_EDNS_FRAG) ||sq->status == serviced_query_UDP_EDNS_FRAG)
@ -3180,7 +3224,7 @@ outnet_comm_point_for_udp(struct outside_network* outnet,
return NULL; return NULL;
} }
cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff, cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
cb, cb_arg); cb, cb_arg, NULL);
if(!cp) { if(!cp) {
log_err("malloc failure"); log_err("malloc failure");
close(fd); close(fd);

View file

@ -1609,5 +1609,39 @@ sock_close(int socket)
{ {
closesocket(socket); closesocket(socket);
} }
# endif /* USE_WINSOCK */ # endif /* USE_WINSOCK */
struct sockaddr_storage*
mk_local_addr(void* addr, u_short port, u_char family)
{
struct sockaddr_storage* dst_addr = malloc(sizeof(struct sockaddr_storage));
if(!dst_addr) {
log_err("malloc failure");
return NULL;
}
if(family == AF_INET) {
struct in_addr* v4addr = (struct in_addr*)addr;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr = *v4addr;
sin.sin_port = port;
memcpy(dst_addr, &sin, sizeof(sin));
} else if(family == AF_INET6) {
struct in6_addr* v6addr = (struct in6_addr*)addr;
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = *v6addr;
sin6.sin6_port = port;
sin6.sin6_flowinfo = 0;
memcpy(dst_addr, &sin6, sizeof(sin6));
} else {
log_err("unknown inet address family");
free(dst_addr);
return NULL;
}
return dst_addr;
}

View file

@ -502,4 +502,14 @@ char* sock_strerror(int errn);
/** close the socket with close, or wsa closesocket */ /** close the socket with close, or wsa closesocket */
void sock_close(int socket); void sock_close(int socket);
/**
* Make and fill a stucture of sockaddr_storage* (malloced) type
* Note: currently it needed to form local address used by dnstap functions only
* @param addr: this is in_addr or in6_addr internet address structure
* @param port: TCP/UDP port
* @param family: Internet address family
* @return: pointer to created sockaddr_storage structure or NULL on error
*/
struct sockaddr_storage* mk_local_addr(void* addr, u_short port, u_char family);
#endif /* NET_HELP_H */ #endif /* NET_HELP_H */

View file

@ -51,6 +51,16 @@
#include "dnstap/dnstap.h" #include "dnstap/dnstap.h"
#include "dnscrypt/dnscrypt.h" #include "dnscrypt/dnscrypt.h"
#include "services/listen_dnsport.h" #include "services/listen_dnsport.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_OPENSSL_SSL_H #ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif #endif
@ -152,7 +162,7 @@ struct internal_signal {
static struct comm_point* comm_point_create_tcp_handler( static struct comm_point* comm_point_create_tcp_handler(
struct comm_base *base, struct comm_point* parent, size_t bufsize, struct comm_base *base, struct comm_point* parent, size_t bufsize,
struct sldns_buffer* spoolbuf, comm_point_callback_type* callback, struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
void* callback_arg); void* callback_arg, struct unbound_socket* socket);
/* -------- End of local definitions -------- */ /* -------- End of local definitions -------- */
@ -398,7 +408,9 @@ static void p_ancil(const char* str, struct comm_reply* r)
log_info("%s: unknown srctype %d", str, r->srctype); log_info("%s: unknown srctype %d", str, r->srctype);
return; return;
} }
if(r->srctype == 6) { if(r->srctype == 6) {
#ifdef IPV6_PKTINFO
char buf[1024]; char buf[1024];
if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr, if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr,
buf, (socklen_t)sizeof(buf)) == 0) { buf, (socklen_t)sizeof(buf)) == 0) {
@ -406,6 +418,7 @@ static void p_ancil(const char* str, struct comm_reply* r)
} }
buf[sizeof(buf)-1]=0; buf[sizeof(buf)-1]=0;
log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex); log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
#endif
} else if(r->srctype == 4) { } else if(r->srctype == 4) {
#ifdef IP_PKTINFO #ifdef IP_PKTINFO
char buf1[1024], buf2[1024]; char buf1[1024], buf2[1024];
@ -3147,7 +3160,7 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
struct comm_point* struct comm_point*
comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer, comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
comm_point_callback_type* callback, void* callback_arg) comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket)
{ {
struct comm_point* c = (struct comm_point*)calloc(1, struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point)); sizeof(struct comm_point));
@ -3186,6 +3199,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
c->inuse = 0; c->inuse = 0;
c->callback = callback; c->callback = callback;
c->cb_arg = callback_arg; c->cb_arg = callback_arg;
c->socket = socket;
evbits = UB_EV_READ | UB_EV_PERSIST; evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */ /* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits, c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
@ -3206,7 +3220,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
struct comm_point* struct comm_point*
comm_point_create_udp_ancil(struct comm_base *base, int fd, comm_point_create_udp_ancil(struct comm_base *base, int fd,
sldns_buffer* buffer, sldns_buffer* buffer,
comm_point_callback_type* callback, void* callback_arg) comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket)
{ {
struct comm_point* c = (struct comm_point*)calloc(1, struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point)); sizeof(struct comm_point));
@ -3245,6 +3259,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
#endif #endif
c->callback = callback; c->callback = callback;
c->cb_arg = callback_arg; c->cb_arg = callback_arg;
c->socket = socket;
evbits = UB_EV_READ | UB_EV_PERSIST; evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */ /* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits, c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
@ -3266,7 +3281,7 @@ static struct comm_point*
comm_point_create_tcp_handler(struct comm_base *base, comm_point_create_tcp_handler(struct comm_base *base,
struct comm_point* parent, size_t bufsize, struct comm_point* parent, size_t bufsize,
struct sldns_buffer* spoolbuf, comm_point_callback_type* callback, struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
void* callback_arg) void* callback_arg, struct unbound_socket* socket)
{ {
struct comm_point* c = (struct comm_point*)calloc(1, struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point)); sizeof(struct comm_point));
@ -3322,6 +3337,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
c->repinfo.c = c; c->repinfo.c = c;
c->callback = callback; c->callback = callback;
c->cb_arg = callback_arg; c->cb_arg = callback_arg;
c->socket = socket;
if(spoolbuf) { if(spoolbuf) {
c->tcp_req_info = tcp_req_info_create(spoolbuf); c->tcp_req_info = tcp_req_info_create(spoolbuf);
if(!c->tcp_req_info) { if(!c->tcp_req_info) {
@ -3479,7 +3495,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
uint32_t http_max_streams, char* http_endpoint, uint32_t http_max_streams, char* http_endpoint,
struct tcl_list* tcp_conn_limit, size_t bufsize, struct tcl_list* tcp_conn_limit, size_t bufsize,
struct sldns_buffer* spoolbuf, enum listen_type port_type, struct sldns_buffer* spoolbuf, enum listen_type port_type,
comm_point_callback_type* callback, void* callback_arg) comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket)
{ {
struct comm_point* c = (struct comm_point*)calloc(1, struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point)); sizeof(struct comm_point));
@ -3529,6 +3545,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
#endif #endif
c->callback = NULL; c->callback = NULL;
c->cb_arg = NULL; c->cb_arg = NULL;
c->socket = socket;
evbits = UB_EV_READ | UB_EV_PERSIST; evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */ /* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits, c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
@ -3549,7 +3566,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
port_type == listen_type_ssl || port_type == listen_type_ssl ||
port_type == listen_type_tcp_dnscrypt) { port_type == listen_type_tcp_dnscrypt) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base, c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
c, bufsize, spoolbuf, callback, callback_arg); c, bufsize, spoolbuf, callback, callback_arg, socket);
} else if(port_type == listen_type_http) { } else if(port_type == listen_type_http) {
c->tcp_handlers[i] = comm_point_create_http_handler( c->tcp_handlers[i] = comm_point_create_http_handler(
base, c, bufsize, harden_large_queries, base, c, bufsize, harden_large_queries,
@ -3925,20 +3942,40 @@ comm_point_send_reply(struct comm_reply *repinfo)
comm_point_send_udp_msg(repinfo->c, buffer, comm_point_send_udp_msg(repinfo->c, buffer,
(struct sockaddr*)&repinfo->addr, repinfo->addrlen); (struct sockaddr*)&repinfo->addr, repinfo->addrlen);
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
if(repinfo->c->dtenv != NULL && /*
repinfo->c->dtenv->log_client_response_messages) * sending src (client)/dst (local service) addresses over DNSTAP from udp callback
dt_msg_send_client_response(repinfo->c->dtenv, */
&repinfo->addr, repinfo->c->type, repinfo->c->buffer); if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) {
struct sockaddr_storage* dst_addr;
if(repinfo->addr.ss_family == AF_INET)
dst_addr = mk_local_addr(&((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
else
dst_addr = mk_local_addr(&((struct sockaddr_in6*)repinfo->c->socket->addr->ai_addr)->sin6_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
log_addr(VERB_ALGO, "from local addr", dst_addr, sizeof(dst_addr));
log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->addr, dst_addr, repinfo->c->type, repinfo->c->buffer);
if(dst_addr)
free(dst_addr);
}
#endif #endif
} else { } else {
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
if(repinfo->c->tcp_parent->dtenv != NULL && /*
repinfo->c->tcp_parent->dtenv->log_client_response_messages) * sending src (client)/dst (local service) addresses over DNSTAP from TCP callback
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, */
&repinfo->addr, repinfo->c->type, if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) {
( repinfo->c->tcp_req_info struct sockaddr_storage* dst_addr;
? repinfo->c->tcp_req_info->spool_buffer if(repinfo->addr.ss_family == AF_INET)
: repinfo->c->buffer )); dst_addr = mk_local_addr(&((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
else
dst_addr = mk_local_addr(&((struct sockaddr_in6*)repinfo->c->socket->addr->ai_addr)->sin6_addr, ((struct sockaddr_in*)repinfo->c->socket->addr->ai_addr)->sin_port, repinfo->addr.ss_family);
log_addr(VERB_ALGO, "from local addr", dst_addr, sizeof(dst_addr));
log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->addr, dst_addr, repinfo->c->type,
( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer ));
if(dst_addr)
free(dst_addr);
}
#endif #endif
if(repinfo->c->tcp_req_info) { if(repinfo->c->tcp_req_info) {
tcp_req_info_send_reply(repinfo->c->tcp_req_info); tcp_req_info_send_reply(repinfo->c->tcp_req_info);

View file

@ -70,6 +70,7 @@ struct comm_point;
struct comm_reply; struct comm_reply;
struct tcl_list; struct tcl_list;
struct ub_event_base; struct ub_event_base;
struct unbound_socket;
struct mesh_state; struct mesh_state;
struct mesh_area; struct mesh_area;
@ -167,6 +168,8 @@ struct comm_point {
/** behind the scenes structure, with say libevent info. alloced. */ /** behind the scenes structure, with say libevent info. alloced. */
struct internal_event* ev; struct internal_event* ev;
struct unbound_socket* socket;
/** file descriptor for communication point */ /** file descriptor for communication point */
int fd; int fd;
@ -493,12 +496,13 @@ struct ub_event_base* comm_base_internal(struct comm_base* b);
* @param buffer: shared buffer by UDP sockets from this thread. * @param buffer: shared buffer by UDP sockets from this thread.
* @param callback: callback function pointer. * @param callback: callback function pointer.
* @param callback_arg: will be passed to your callback function. * @param callback_arg: will be passed to your callback function.
* @param unbound_socket: and opened socket properties will be passed to your callback function.
* @return: returns the allocated communication point. NULL on error. * @return: returns the allocated communication point. NULL on error.
* Sets timeout to NULL. Turns off TCP options. * Sets timeout to NULL. Turns off TCP options.
*/ */
struct comm_point* comm_point_create_udp(struct comm_base* base, struct comm_point* comm_point_create_udp(struct comm_base* base,
int fd, struct sldns_buffer* buffer, int fd, struct sldns_buffer* buffer,
comm_point_callback_type* callback, void* callback_arg); comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
/** /**
* Create an UDP with ancillary data comm point. Calls malloc. * Create an UDP with ancillary data comm point. Calls malloc.
@ -509,12 +513,13 @@ struct comm_point* comm_point_create_udp(struct comm_base* base,
* @param buffer: shared buffer by UDP sockets from this thread. * @param buffer: shared buffer by UDP sockets from this thread.
* @param callback: callback function pointer. * @param callback: callback function pointer.
* @param callback_arg: will be passed to your callback function. * @param callback_arg: will be passed to your callback function.
* @param unbound_socket: and opened socket properties will be passed to your callback function.
* @return: returns the allocated communication point. NULL on error. * @return: returns the allocated communication point. NULL on error.
* Sets timeout to NULL. Turns off TCP options. * Sets timeout to NULL. Turns off TCP options.
*/ */
struct comm_point* comm_point_create_udp_ancil(struct comm_base* base, struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
int fd, struct sldns_buffer* buffer, int fd, struct sldns_buffer* buffer,
comm_point_callback_type* callback, void* callback_arg); comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
/** /**
* Create a TCP listener comm point. Calls malloc. * Create a TCP listener comm point. Calls malloc.
@ -537,6 +542,7 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
* to select handler type to use. * to select handler type to use.
* @param callback: callback function pointer for TCP handlers. * @param callback: callback function pointer for TCP handlers.
* @param callback_arg: will be passed to your callback function. * @param callback_arg: will be passed to your callback function.
* @param unbound_socket: and opened socket properties will be passed to your callback function.
* @return: returns the TCP listener commpoint. You can find the * @return: returns the TCP listener commpoint. You can find the
* TCP handlers in the array inside the listener commpoint. * TCP handlers in the array inside the listener commpoint.
* returns NULL on error. * returns NULL on error.