]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
support for ssl-upstream (works from unbound-control).
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 1 Nov 2011 09:26:58 +0000 (09:26 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 1 Nov 2011 09:26:58 +0000 (09:26 +0000)
git-svn-id: file:///svn/unbound/trunk@2532 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/outside_network.c
util/netevent.c
util/netevent.h

index 17920c717f91f44f2c1fcaf37b3d5b90eb059fd2..8045d4bcfeaa233d1a2766d5b96011aa37e98b77 100644 (file)
@@ -1,3 +1,7 @@
+1 November 2011: Wouter
+       - dns over ssl support as a client, ssl-upstream yes turns it on.
+         It performs an SSL transaction for every DNS query (250 msec).
+
 31 October 2011: Wouter
        - dns over ssl support, ssl-service-pem and ssl-service-key files
          can be given and then TCP queries are serviced wrapped in SSL.
index 3a41554c739c137d844f86a7ef579b35a8c438ce..3366b9ed6056b21e31478f003b173db46578fbbe 100644 (file)
@@ -58,6 +58,7 @@
 #include "util/net_help.h"
 #include "util/random.h"
 #include "util/fptr_wlist.h"
+#include <openssl/ssl.h>
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -237,6 +238,18 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
                        return 0;
                }
        }
+       if(w->outnet->sslctx) {
+               pend->c->ssl = outgoing_ssl_fd(w->outnet->sslctx, s);
+               if(!pend->c->ssl) {
+                       pend->c->fd = s;
+                       comm_point_close(pend->c);
+                       return 0;
+               }
+#ifdef USE_WINSOCK
+               comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
+#endif
+               pend->c->ssl_shake_state = comm_ssl_shake_write;
+       }
        w->pkt = NULL;
        w->next_waiting = (void*)pend;
        pend->id = LDNS_ID_WIRE(pkt);
@@ -280,6 +293,11 @@ static void
 decomission_pending_tcp(struct outside_network* outnet, 
        struct pending_tcp* pend)
 {
+       if(pend->c->ssl) {
+               SSL_shutdown(pend->c->ssl);
+               SSL_free(pend->c->ssl);
+               pend->c->ssl = NULL;
+       }
        comm_point_close(pend->c);
        pend->next_free = outnet->tcp_free;
        outnet->tcp_free = pend;
index 328679948b64596ac8b8b97ee01779a2e06f5fdb..a6bdbcaff57aca8f553d3d992552d963e23c554a 100644 (file)
@@ -709,6 +709,18 @@ static long win_bio_cb(BIO *b, int oper, const char* ATTR_UNUSED(argp),
        /* return original return value */
        return retvalue;
 }
+
+/** set win bio callbacks for nonblocking operations */
+void
+comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl)
+{
+       SSL* ssl = (SSL*)thessl;
+       /* set them both just in case, but usually they are the same BIO */
+       BIO_set_callback(SSL_get_rbio(ssl), &win_bio_cb);
+       BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)comm_point_internal(c));
+       BIO_set_callback(SSL_get_wbio(ssl), &win_bio_cb);
+       BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)comm_point_internal(c));
+}
 #endif
 
 void 
@@ -736,17 +748,14 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
                return;
        if(c->ssl) {
                c_hdl->ssl = incoming_ssl_fd(c->ssl, new_fd);
-               if(!c_hdl->ssl)
+               if(!c_hdl->ssl) {
+                       c_hdl->fd = new_fd;
+                       comm_point_close(c_hdl);
                        return;
+               }
                c_hdl->ssl_shake_state = comm_ssl_shake_read;
 #ifdef USE_WINSOCK
-               /* set them both just in case, but usually they are the same BIO */
-               BIO_set_callback(SSL_get_rbio(c_hdl->ssl), &win_bio_cb);
-               BIO_set_callback_arg(SSL_get_rbio(c_hdl->ssl),
-                       (char*)comm_point_internal(c_hdl));
-               BIO_set_callback(SSL_get_wbio(c_hdl->ssl), &win_bio_cb);
-               BIO_set_callback_arg(SSL_get_wbio(c_hdl->ssl),
-                       (char*)comm_point_internal(c_hdl));
+               comm_point_tcp_win_bio_cb(c_hdl, c_hdl->ssl);
 #endif
        }
 
@@ -862,7 +871,7 @@ ssl_handshake(struct comm_point* c)
                }
        }
        /* this is where peer verification could take place */
-       log_addr(VERB_ALGO, "SSL connection from", &c->repinfo.addr,
+       log_addr(VERB_ALGO, "SSL DNS connection", &c->repinfo.addr,
                c->repinfo.addrlen);
 
        /* setup listen rw correctly */
@@ -1037,6 +1046,15 @@ ssl_handle_write(struct comm_point* c)
        return 1;
 }
 
+/** handle ssl tcp connection with dns contents */
+static int
+ssl_handle_it(struct comm_point* c)
+{
+       if(c->tcp_is_reading)
+               return ssl_handle_read(c);
+       return ssl_handle_write(c);
+}
+
 /** Handle tcp reading callback. 
  * @param fd: file descriptor of socket.
  * @param c: comm point to read from into buffer.
@@ -1048,10 +1066,10 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
 {
        ssize_t r;
        log_assert(c->type == comm_tcp || c->type == comm_local);
+       if(c->ssl)
+               return ssl_handle_it(c);
        if(!c->tcp_is_reading)
                return 0;
-       if(c->ssl)
-               return ssl_handle_read(c);
 
        log_assert(fd != -1);
        if(c->tcp_byte_count < sizeof(uint16_t)) {
@@ -1148,7 +1166,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
 {
        ssize_t r;
        log_assert(c->type == comm_tcp);
-       if(c->tcp_is_reading)
+       if(c->tcp_is_reading && !c->ssl)
                return 0;
        log_assert(fd != -1);
        if(c->tcp_byte_count == 0 && c->tcp_check_nb_connect) {
@@ -1191,7 +1209,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
                }
        }
        if(c->ssl)
-               return ssl_handle_write(c);
+               return ssl_handle_it(c);
 
        if(c->tcp_byte_count < sizeof(uint16_t)) {
                uint16_t len = htons(ldns_buffer_limit(c->buffer));
index 5425eebc6c65c1016be116254edb3c5943f97db6..ade37cdae13dc3fcc7096ca5a9dd6abaf168b5ed 100644 (file)
@@ -636,4 +636,14 @@ void comm_point_local_handle_callback(int fd, short event, void* arg);
  */
 void comm_point_raw_handle_callback(int fd, short event, void* arg);
 
+#ifdef USE_WINSOCK
+/**
+ * Callback for openssl BIO to on windows detect WSAEWOULDBLOCK and notify
+ * the winsock_event of this for proper TCP nonblocking implementation.
+ * @param c: comm_point, fd must be set its struct event is registered.
+ * @param ssl: openssl SSL, fd must be set so it has a bio.
+ */
+void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl);
+#endif
+
 #endif /* NET_EVENT_H */