]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Import the patches from the files in the tarball in
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 9 Dec 2020 10:00:51 +0000 (11:00 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 9 Dec 2020 10:00:51 +0000 (11:00 +0100)
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.

daemon/worker.c
dnstap/dnstap.c
dnstap/dnstap.h
services/listen_dnsport.c
services/listen_dnsport.h
services/outside_network.c
util/net_help.c
util/net_help.h
util/netevent.c
util/netevent.h

index 76c4bb5b1e76702912dd17bb887d17d369497378..36d4208f1b21ed4f351cef9b8eaffca7d285d131 100644 (file)
@@ -1159,9 +1159,21 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
        }
 #endif
 #ifdef USE_DNSTAP
-       if(worker->dtenv.log_client_query_messages)
-               dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
-                       c->buffer);
+       /*
+        * sending src (client)/dst (local service) addresses over DNSTAP from incoming request handler
+        */
+       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
        acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr, 
                repinfo->addrlen);
@@ -1584,9 +1596,21 @@ send_reply_rc:
                if(is_secure_answer) worker->stats.ans_secure++;
        }
 #ifdef USE_DNSTAP
-       if(worker->dtenv.log_client_response_messages)
-               dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
-                       c->type, c->buffer);
+       /*
+        * sending src (client)/dst (local service) addresses over DNSTAP from send_reply code label (when we serviced local zone for ex.)
+        */
+       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
        if(worker->env.cfg->log_replies)
        {
index b8a3216703c1d031e8ac3771ae58e44704dd44ce..2ee269be35f750ac0356012318fd29f1022396c3 100644 (file)
@@ -302,44 +302,75 @@ dt_fill_buffer(sldns_buffer *b, ProtobufCBinaryData *p, protobuf_c_boolean *has)
 
 static void
 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,
-               ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
-               uint32_t *port, protobuf_c_boolean *has_port)
+               ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
+               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);
-       if (ss->ss_family == AF_INET6) {
-               struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
+       log_assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
+       if (qs->ss_family == AF_INET6) {
+               struct sockaddr_in6 *q = (struct sockaddr_in6 *) qs;
 
                /* socket_family */
                dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
                dm->m.has_socket_family = 1;
 
                /* addr: query_address or response_address */
-               addr->data = s->sin6_addr.s6_addr;
-               addr->len = 16; /* IPv6 */
-               *has_addr = 1;
+               qaddr->data = q->sin6_addr.s6_addr;
+               qaddr->len = 16; /* IPv6 */
+               *has_qaddr = 1;
 
                /* port: query_port or response_port */
-               *port = ntohs(s->sin6_port);
-               *has_port = 1;
-       } else if (ss->ss_family == AF_INET) {
-               struct sockaddr_in *s = (struct sockaddr_in *) ss;
+               *qport = ntohs(q->sin6_port);
+               *has_qport = 1;
+       } else if (qs->ss_family == AF_INET) {
+               struct sockaddr_in *q = (struct sockaddr_in *) qs;
 
                /* socket_family */
                dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
                dm->m.has_socket_family = 1;
 
                /* addr: query_address or response_address */
-               addr->data = (uint8_t *) &s->sin_addr.s_addr;
-               addr->len = 4; /* IPv4 */
-               *has_addr = 1;
+               qaddr->data = (uint8_t *) &q->sin_addr.s_addr;
+               qaddr->len = 4; /* IPv4 */
+               *has_qaddr = 1;
 
                /* port: query_port or response_port */
-               *port = ntohs(s->sin_port);
-               *has_port = 1;
+               *qport = ntohs(q->sin_port);
+               *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);
        if (cptype == comm_udp) {
                /* socket_protocol */
@@ -355,6 +386,7 @@ dt_msg_fill_net(struct dt_msg *dm,
 void
 dt_msg_send_client_query(struct dt_env *env,
                         struct sockaddr_storage *qsock,
+                        struct sockaddr_storage *rsock,
                         enum comm_point_type cptype,
                         sldns_buffer *qmsg)
 {
@@ -374,11 +406,14 @@ dt_msg_send_client_query(struct dt_env *env,
        /* 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);
-       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_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))
                dt_send(env, dm.buf, dm.len_buf);
@@ -387,6 +422,7 @@ dt_msg_send_client_query(struct dt_env *env,
 void
 dt_msg_send_client_response(struct dt_env *env,
                            struct sockaddr_storage *qsock,
+                           struct sockaddr_storage *rsock,
                            enum comm_point_type cptype,
                            sldns_buffer *rmsg)
 {
@@ -406,11 +442,13 @@ dt_msg_send_client_response(struct dt_env *env,
        /* 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);
-       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_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))
                dt_send(env, dm.buf, dm.len_buf);
@@ -419,6 +457,7 @@ dt_msg_send_client_response(struct dt_env *env,
 void
 dt_msg_send_outside_query(struct dt_env *env,
                          struct sockaddr_storage *rsock,
+                         struct sockaddr_storage *qsock,
                          enum comm_point_type cptype,
                          uint8_t *zone, size_t zone_len,
                          sldns_buffer *qmsg)
@@ -454,11 +493,13 @@ dt_msg_send_outside_query(struct dt_env *env,
        /* 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);
-       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_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))
                dt_send(env, dm.buf, dm.len_buf);
@@ -467,6 +508,7 @@ dt_msg_send_outside_query(struct dt_env *env,
 void
 dt_msg_send_outside_response(struct dt_env *env,
                             struct sockaddr_storage *rsock,
+                            struct sockaddr_storage *qsock,
                             enum comm_point_type cptype,
                             uint8_t *zone, size_t zone_len,
                             uint8_t *qbuf, size_t qbuf_len,
@@ -510,11 +552,13 @@ dt_msg_send_outside_response(struct dt_env *env,
        /* 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);
-       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_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))
                dt_send(env, dm.buf, dm.len_buf);
index 783b8c51430a59bf12b34bac90754e4c9d5e0f33..449fae727eac258c9ce7e2104b56cec866dd273d 100644 (file)
@@ -123,12 +123,14 @@ dt_delete(struct dt_env *env);
  * Create and send a new dnstap "Message" event of type CLIENT_QUERY.
  * @param env: dnstap environment object.
  * @param qsock: address/port of client.
+ * @param rsock: local (service) address/port.
  * @param cptype: comm_udp or comm_tcp.
  * @param qmsg: query message.
  */
 void
 dt_msg_send_client_query(struct dt_env *env,
                         struct sockaddr_storage *qsock,
+                        struct sockaddr_storage *rsock,
                         enum comm_point_type cptype,
                         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.
  * @param env: dnstap environment object.
  * @param qsock: address/port of client.
+ * @param rsock: local (service) address/port.
  * @param cptype: comm_udp or comm_tcp.
  * @param rmsg: response message.
  */
 void
 dt_msg_send_client_response(struct dt_env *env,
                            struct sockaddr_storage *qsock,
+                           struct sockaddr_storage *rsock,
                            enum comm_point_type cptype,
                            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
  * in the query header.
  * @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 zone: query zone.
  * @param zone_len: length of zone.
@@ -159,6 +164,7 @@ dt_msg_send_client_response(struct dt_env *env,
 void
 dt_msg_send_outside_query(struct dt_env *env,
                          struct sockaddr_storage *rsock,
+                         struct sockaddr_storage *qsock,
                          enum comm_point_type cptype,
                          uint8_t *zone, size_t zone_len,
                          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
  * in the query header.
  * @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 zone: query zone.
  * @param zone_len: length of zone.
@@ -181,6 +188,7 @@ dt_msg_send_outside_query(struct dt_env *env,
 void
 dt_msg_send_outside_response(struct dt_env *env,
                             struct sockaddr_storage *rsock,
+                            struct sockaddr_storage *qsock,
                             enum comm_point_type cptype,
                             uint8_t *zone, size_t zone_len,
                             uint8_t *qbuf, size_t qbuf_len,
index 709c9e6ce698b27209d923be2fc8b4ee8ed839d7..02d44fcba26751dad279721a3891a380a4b74055 100644 (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
 static int
 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, 
        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 use_systemd, int dscp)
+       int use_systemd, int dscp, struct unbound_socket** ub_sock)
 {
        struct addrinfo *res = NULL;
        int r, s, inuse, noproto;
@@ -958,7 +968,12 @@ make_sock(int stype, const char* ifname, const char* port,
                        *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;
 }
 
@@ -967,7 +982,7 @@ static int
 make_sock_port(int stype, const char* ifname, const char* port, 
        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 use_systemd, int dscp)
+       int use_systemd, int dscp, struct unbound_socket** ub_sock)
 {
        char* s = strchr(ifname, '@');
        if(s) {
@@ -990,11 +1005,11 @@ make_sock_port(int stype, const char* ifname, const char* port,
                p[strlen(s+1)]=0;
                return make_sock(stype, newif, p, hints, v6only, noip6, rcv,
                        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,
                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.
  */
 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(
                sizeof(struct listen_port));
@@ -1014,6 +1029,7 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype)
        item->next = *list;
        item->fd = s;
        item->ftype = ftype;
+       item->socket = ub_sock;
        *list = item;
        return 1;
 }
@@ -1043,7 +1059,7 @@ set_recvpktinfo(int s, int family)
                        return 0;
                }
 #           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");
                return 0;
 #           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 is_https = if_is_https(ifname, port, https_port);
        int nodelay = is_https && http2_nodelay;
+       struct unbound_socket* ub_sock;
 #ifdef USE_DNSCRYPT
        int is_dnscrypt = ((strchr(ifname, '@') && 
                        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)
                return 0;
+
        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, 
                        &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) {
                                log_warn("IPv6 protocol not available");
                                return 1;
@@ -1169,15 +1190,18 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                        return 0;
                }
                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);
                        return 0;
                }
        } else if(do_udp) {
+               ub_sock = malloc(sizeof(struct unbound_socket));
+               if(!ub_sock)
+                       return 0;
                /* regular udp socket */
                if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, 
                        &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) {
                                log_warn("IPv6 protocol not available");
                                return 1;
@@ -1185,12 +1209,15 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                        return 0;
                }
                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);
                        return 0;
                }
        }
        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,
                        tls_additional_port);
                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;
                if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1, 
                        &noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay,
-                       freebind, use_systemd, dscp)) == -1) {
+                       freebind, use_systemd, dscp, &ub_sock)) == -1) {
                        if(noip6) {
                                /*log_warn("IPv6 protocol not available");*/
                                return 1;
@@ -1213,7 +1240,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                }
                if(is_ssl)
                        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);
                        return 0;
                }
@@ -1280,14 +1307,14 @@ listen_create(struct comm_base* base, struct listen_port* ports,
                if(ports->ftype == listen_type_udp ||
                   ports->ftype == listen_type_udp_dnscrypt)
                        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 ||
                                ports->ftype == listen_type_tcp_dnscrypt)
                        cp = comm_point_create_tcp(base, ports->fd, 
                                tcp_accept_count, tcp_idle_timeout,
                                harden_large_queries, 0, NULL,
                                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 ||
                        ports->ftype == listen_type_http) {
                        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,
                                http_max_streams, http_endpoint,
                                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)
                                cp->ssl = NULL;
                        else
@@ -1322,7 +1349,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
                } else if(ports->ftype == listen_type_udpancil ||
                                  ports->ftype == listen_type_udpancil_dnscrypt)
                        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) {
                        log_err("can't create commpoint");      
                        listen_delete(front);
@@ -1656,6 +1683,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                        }
                }
        }
+
        return list;
 }
 
@@ -1667,6 +1695,8 @@ void listening_ports_free(struct listen_port* list)
                if(list->fd != -1) {
                        sock_close(list->fd);
                }
+               free(list->socket->addr);
+               free(list->socket);
                free(list);
                list = nx;
        }
index 9d6ea2c33adfd1f60ecd8d8244c7ab07d3a00b27..96feea66707134c2034b8b670a79d0b82d8a584d 100644 (file)
@@ -102,6 +102,20 @@ enum listen_type {
        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 
  * opened for use by all threads.
@@ -113,6 +127,8 @@ struct listen_port {
        int fd;
        /** type of file descriptor, udp or tcp */
        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);
 
+/** 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 */
index 0886907f7c886ac2151491adea493101b88ab606..5d6b6c3c21b5b4a01f30cef79669ba3e523096b8 100644 (file)
@@ -1440,7 +1440,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
                        return NULL;
                }
                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) {
                        log_err("malloc failed");
                        free(pc);
@@ -1921,11 +1921,27 @@ randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout)
        comm_timer_set(pend->timer, &tv);
 
 #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 &&
           (outnet->dtenv->log_resolver_query_messages ||
-           outnet->dtenv->log_forwarder_query_messages))
-               dt_msg_send_outside_query(outnet->dtenv, &pend->addr, comm_udp,
-               pend->sq->zone, pend->sq->zonelen, packet);
+               sq->outnet->dtenv->log_forwarder_query_messages)) {
+                   if(addr_is_ip6(&sq->addr, sq->addrlen)) {
+                       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
        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,
                        sq->addrlen, sq->zone, sq->zonelen);
 #ifdef USE_DNSTAP
+       /*
+        * sending src (local service)/dst (upstream) addresses over DNSTAP
+        */
        if(error==NETEVENT_NOERROR && sq->outnet->dtenv &&
           (sq->outnet->dtenv->log_resolver_response_messages ||
-           sq->outnet->dtenv->log_forwarder_response_messages))
-               dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr,
-               c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
-               &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
+           sq->outnet->dtenv->log_forwarder_response_messages)) {
+               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,
+                         &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
        if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS &&
                (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;
        }
 #ifdef USE_DNSTAP
+       /*
+        * sending src (local service)/dst (upstream) addresses over DNSTAP
+        */
        if(error == NETEVENT_NOERROR && outnet->dtenv &&
           (outnet->dtenv->log_resolver_response_messages ||
-           outnet->dtenv->log_forwarder_response_messages))
-               dt_msg_send_outside_response(outnet->dtenv, &sq->addr, c->type,
-               sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
-               &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
+           outnet->dtenv->log_forwarder_response_messages)) {
+               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->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
        if( (sq->status == serviced_query_UDP_EDNS 
                ||sq->status == serviced_query_UDP_EDNS_FRAG)
@@ -3180,7 +3224,7 @@ outnet_comm_point_for_udp(struct outside_network* outnet,
                return NULL;
        }
        cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
-               cb, cb_arg);
+               cb, cb_arg, NULL);
        if(!cp) {
                log_err("malloc failure");
                close(fd);
index c5216bc2d8c6fe9387e1628c2c1bc65fecadaace..9745adcd390a7d48ad33c2a3fdc8a9c337b9f758 100644 (file)
@@ -1609,5 +1609,39 @@ sock_close(int socket)
 {
        closesocket(socket);
 }
-
 #  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;
+}
index 45b607a430d5a3893054a1cd6c8e8426ff92f115..d89319c0a981afa9d022342dea575daa972f6509 100644 (file)
@@ -502,4 +502,14 @@ char* sock_strerror(int errn);
 /** close the socket with close, or wsa closesocket */
 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 */
index d3e268a01e6cee8b6e6367767c2a626ac3b2dbd0..e98b76933cd02cf40f05a6377db1efdb2e99b8ca 100644 (file)
 #include "dnstap/dnstap.h"
 #include "dnscrypt/dnscrypt.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
 #include <openssl/ssl.h>
 #endif
@@ -152,7 +162,7 @@ struct internal_signal {
 static struct comm_point* comm_point_create_tcp_handler(
        struct comm_base *base, struct comm_point* parent, size_t bufsize,
        struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
-       void* callback_arg);
+       void* callback_arg, struct unbound_socket* socket);
 
 /* -------- End of local definitions -------- */
 
@@ -398,14 +408,17 @@ static void p_ancil(const char* str, struct comm_reply* r)
                log_info("%s: unknown srctype %d", str, r->srctype);
                return;
        }
+
        if(r->srctype == 6) {
-               char buf[1024];
-               if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr, 
-                       buf, (socklen_t)sizeof(buf)) == 0) {
-                       (void)strlcpy(buf, "(inet_ntop error)", sizeof(buf));
-               }
-               buf[sizeof(buf)-1]=0;
-               log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
+#ifdef IPV6_PKTINFO
+               char buf[1024];
+               if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr, 
+                       buf, (socklen_t)sizeof(buf)) == 0) {
+                       (void)strlcpy(buf, "(inet_ntop error)", sizeof(buf));
+               }
+               buf[sizeof(buf)-1]=0;
+               log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
+#endif
        } else if(r->srctype == 4) {
 #ifdef IP_PKTINFO
                char buf1[1024], buf2[1024];
@@ -3147,7 +3160,7 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
 
 struct comm_point* 
 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,
                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->callback = callback;
        c->cb_arg = callback_arg;
+       c->socket = socket;
        evbits = UB_EV_READ | UB_EV_PERSIST;
        /* ub_event stuff */
        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* 
 comm_point_create_udp_ancil(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,
                sizeof(struct comm_point));
@@ -3245,6 +3259,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
 #endif
        c->callback = callback;
        c->cb_arg = callback_arg;
+       c->socket = socket;
        evbits = UB_EV_READ | UB_EV_PERSIST;
        /* ub_event stuff */
        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, 
        struct comm_point* parent, size_t bufsize,
        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,
                sizeof(struct comm_point));
@@ -3322,6 +3337,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
        c->repinfo.c = c;
        c->callback = callback;
        c->cb_arg = callback_arg;
+       c->socket = socket;
        if(spoolbuf) {
                c->tcp_req_info = tcp_req_info_create(spoolbuf);
                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,
        struct tcl_list* tcp_conn_limit, size_t bufsize,
        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,
                sizeof(struct comm_point));
@@ -3529,6 +3545,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
 #endif
        c->callback = NULL;
        c->cb_arg = NULL;
+       c->socket = socket;
        evbits = UB_EV_READ | UB_EV_PERSIST;
        /* ub_event stuff */
        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_tcp_dnscrypt) {
                        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) {
                        c->tcp_handlers[i] = comm_point_create_http_handler(
                                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,
                        (struct sockaddr*)&repinfo->addr, repinfo->addrlen);
 #ifdef USE_DNSTAP
-               if(repinfo->c->dtenv != NULL &&
-                  repinfo->c->dtenv->log_client_response_messages)
-                       dt_msg_send_client_response(repinfo->c->dtenv,
-                       &repinfo->addr, repinfo->c->type, repinfo->c->buffer);
+               /*
+                * sending src (client)/dst (local service) addresses over DNSTAP from udp callback
+                */
+               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
        } else {
 #ifdef USE_DNSTAP
-               if(repinfo->c->tcp_parent->dtenv != NULL &&
-                  repinfo->c->tcp_parent->dtenv->log_client_response_messages)
-                       dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
-                       &repinfo->addr, repinfo->c->type,
-                       ( repinfo->c->tcp_req_info
-                       ? repinfo->c->tcp_req_info->spool_buffer
-                       : repinfo->c->buffer ));
+               /*
+                * sending src (client)/dst (local service) addresses over DNSTAP from TCP callback
+                */
+               if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->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->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
                if(repinfo->c->tcp_req_info) {
                        tcp_req_info_send_reply(repinfo->c->tcp_req_info);
index 266a74ff333e41de63f2e70e1674dda81210b92d..f43f0f49f89056e67f9d3628b6323a9ba85e26e4 100644 (file)
@@ -70,6 +70,7 @@ struct comm_point;
 struct comm_reply;
 struct tcl_list;
 struct ub_event_base;
+struct unbound_socket;
 
 struct mesh_state;
 struct mesh_area;
@@ -167,6 +168,8 @@ struct comm_point {
        /** behind the scenes structure, with say libevent info. alloced. */
        struct internal_event* ev;
 
+       struct unbound_socket* socket;
+
        /** file descriptor for communication point */
        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 callback: callback function pointer.
  * @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.
  * Sets timeout to NULL. Turns off TCP options.
  */
 struct comm_point* comm_point_create_udp(struct comm_base* base,
        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.
@@ -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 callback: callback function pointer.
  * @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.
  * Sets timeout to NULL. Turns off TCP options.
  */
 struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
        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.
@@ -537,6 +542,7 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
  *     to select handler type to use.
  * @param callback: callback function pointer for TCP handlers.
  * @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
  *     TCP handlers in the array inside the listener commpoint.
  *     returns NULL on error.