Home | History | Annotate | Line # | Download | only in dnstap
      1 /* dnstap support for NSD */
      2 
      3 /*
      4  * Copyright (c) 2013-2014, Farsight Security, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  * 1. Redistributions of source code must retain the above copyright
     12  * notice, this list of conditions and the following disclaimer.
     13  *
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  * notice, this list of conditions and the following disclaimer in the
     16  * documentation and/or other materials provided with the distribution.
     17  *
     18  * 3. Neither the name of the copyright holder nor the names of its
     19  * contributors may be used to endorse or promote products derived from
     20  * this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     25  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     29  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     31  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     32  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 #include "dnstap/dnstap_config.h"
     36 
     37 #ifdef USE_DNSTAP
     38 
     39 #include "config.h"
     40 #include <string.h>
     41 #include <sys/time.h>
     42 #ifdef HAVE_SYS_STAT_H
     43 #include <sys/stat.h>
     44 #endif
     45 #include <errno.h>
     46 #include <unistd.h>
     47 #include "util.h"
     48 #include "options.h"
     49 
     50 #include <fstrm.h>
     51 #include <protobuf-c/protobuf-c.h>
     52 
     53 #include "dnstap/dnstap.h"
     54 #include "dnstap/dnstap.pb-c.h"
     55 
     56 #ifdef HAVE_SSL
     57 #ifdef HAVE_OPENSSL_SSL_H
     58 #include <openssl/ssl.h>
     59 #endif
     60 #ifdef HAVE_OPENSSL_ERR_H
     61 #include <openssl/err.h>
     62 #endif
     63 #endif
     64 
     65 #define DNSTAP_CONTENT_TYPE		"protobuf:dnstap.Dnstap"
     66 #define DNSTAP_INITIAL_BUF_SIZE		256
     67 
     68 struct dt_msg {
     69 	void		*buf;
     70 	size_t		len_buf;
     71 	Dnstap__Dnstap	d;
     72 	Dnstap__Message	m;
     73 };
     74 
     75 static int
     76 dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
     77 {
     78 	ProtobufCBufferSimple sbuf;
     79 
     80 	memset(&sbuf, 0, sizeof(sbuf));
     81 	sbuf.base.append = protobuf_c_buffer_simple_append;
     82 	sbuf.len = 0;
     83 	sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE;
     84 	sbuf.data = malloc(sbuf.alloced);
     85 	if (sbuf.data == NULL)
     86 		return 0;
     87 	sbuf.must_free_data = 1;
     88 
     89 	*sz = dnstap__dnstap__pack_to_buffer(d, (ProtobufCBuffer *) &sbuf);
     90 	if (sbuf.data == NULL)
     91 		return 0;
     92 	*buf = sbuf.data;
     93 
     94 	return 1;
     95 }
     96 
     97 static void
     98 dt_send(const struct dt_env *env, void *buf, size_t len_buf)
     99 {
    100 	fstrm_res res;
    101 	if (!buf)
    102 		return;
    103 	res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf,
    104 				 fstrm_free_wrapper, NULL);
    105 	if (res != fstrm_res_success)
    106 		free(buf);
    107 }
    108 
    109 static void
    110 dt_msg_init(const struct dt_env *env,
    111 	    struct dt_msg *dm,
    112 	    Dnstap__Message__Type mtype)
    113 {
    114 	memset(dm, 0, sizeof(*dm));
    115 	dm->d.base.descriptor = &dnstap__dnstap__descriptor;
    116 	dm->m.base.descriptor = &dnstap__message__descriptor;
    117 	dm->d.type = DNSTAP__DNSTAP__TYPE__MESSAGE;
    118 	dm->d.message = &dm->m;
    119 	dm->m.type = mtype;
    120 	if (env->identity != NULL) {
    121 		dm->d.identity.data = (uint8_t *) env->identity;
    122 		dm->d.identity.len = (size_t) env->len_identity;
    123 		dm->d.has_identity = 1;
    124 	}
    125 	if (env->version != NULL) {
    126 		dm->d.version.data = (uint8_t *) env->version;
    127 		dm->d.version.len = (size_t) env->len_version;
    128 		dm->d.has_version = 1;
    129 	}
    130 }
    131 
    132 #ifdef HAVE_SSL
    133 /** TLS writer object for fstrm. */
    134 struct dt_tls_writer {
    135 	/* ip address */
    136 	char* ip;
    137 	/* if connected already */
    138 	int connected;
    139 	/* file descriptor */
    140 	int fd;
    141 	/* TLS context */
    142 	SSL_CTX* ctx;
    143 	/* SSL transport */
    144 	SSL* ssl;
    145 	/* the server name to authenticate */
    146 	char* tls_server_name;
    147 };
    148 
    149 void log_crypto_err(const char* str); /* in server.c */
    150 
    151 /* Create TLS writer object for fstrm. */
    152 static struct dt_tls_writer*
    153 tls_writer_init(char* ip, char* tls_server_name, char* tls_cert_bundle,
    154 	char* tls_client_key_file, char* tls_client_cert_file)
    155 {
    156 	struct dt_tls_writer* dtw = (struct dt_tls_writer*)calloc(1,
    157 		sizeof(*dtw));
    158 	if(!dtw) return NULL;
    159 	dtw->fd = -1;
    160 	dtw->ip = strdup(ip);
    161 	if(!dtw->ip) {
    162 		free(dtw);
    163 		return NULL;
    164 	}
    165 	dtw->ctx = SSL_CTX_new(SSLv23_client_method());
    166 	if(!dtw->ctx) {
    167 		log_msg(LOG_ERR, "dnstap: SSL_CTX_new failed");
    168 		free(dtw->ip);
    169 		free(dtw);
    170 		return NULL;
    171 	}
    172 #if SSL_OP_NO_SSLv2 != 0
    173 	if((SSL_CTX_set_options(dtw->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
    174 		!= SSL_OP_NO_SSLv2) {
    175 		log_msg(LOG_ERR, "dnstap: could not set SSL_OP_NO_SSLv2");
    176 		SSL_CTX_free(dtw->ctx);
    177 		free(dtw->ip);
    178 		free(dtw);
    179 		return NULL;
    180 	}
    181 #endif
    182 	if((SSL_CTX_set_options(dtw->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
    183 		!= SSL_OP_NO_SSLv3) {
    184 		log_msg(LOG_ERR, "dnstap: could not set SSL_OP_NO_SSLv3");
    185 		SSL_CTX_free(dtw->ctx);
    186 		free(dtw->ip);
    187 		free(dtw);
    188 		return NULL;
    189 	}
    190 #if defined(SSL_OP_NO_RENEGOTIATION)
    191 	/* disable client renegotiation */
    192 	if((SSL_CTX_set_options(dtw->ctx, SSL_OP_NO_RENEGOTIATION) &
    193 		SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) {
    194 		log_msg(LOG_ERR, "dnstap: could not set SSL_OP_NO_RENEGOTIATION");
    195 		SSL_CTX_free(dtw->ctx);
    196 		free(dtw->ip);
    197 		free(dtw);
    198 		return NULL;
    199 	}
    200 #endif
    201 	if(tls_client_key_file && tls_client_key_file[0]) {
    202 		if(!SSL_CTX_use_certificate_chain_file(dtw->ctx,
    203 			tls_client_cert_file)) {
    204 			log_msg(LOG_ERR, "dnstap: SSL_CTX_use_certificate_chain_file failed for %s", tls_client_cert_file);
    205 			SSL_CTX_free(dtw->ctx);
    206 			free(dtw->ip);
    207 			free(dtw);
    208 			return NULL;
    209 		}
    210 		if(!SSL_CTX_use_PrivateKey_file(dtw->ctx, tls_client_key_file,
    211 			SSL_FILETYPE_PEM)) {
    212 			log_msg(LOG_ERR, "dnstap: SSL_CTX_use_PrivateKey_file failed for %s", tls_client_key_file);
    213 			SSL_CTX_free(dtw->ctx);
    214 			free(dtw->ip);
    215 			free(dtw);
    216 			return NULL;
    217 		}
    218 		if(!SSL_CTX_check_private_key(dtw->ctx)) {
    219 			log_msg(LOG_ERR, "dnstap: SSL_CTX_check_private_key failed for %s", tls_client_key_file);
    220 			SSL_CTX_free(dtw->ctx);
    221 			free(dtw->ip);
    222 			free(dtw);
    223 			return NULL;
    224 		}
    225 	}
    226 	if(tls_cert_bundle && tls_cert_bundle[0]) {
    227 		if(!SSL_CTX_load_verify_locations(dtw->ctx, tls_cert_bundle, NULL)) {
    228 			log_msg(LOG_ERR, "dnstap: SSL_CTX_load_verify_locations failed for %s", tls_cert_bundle);
    229 			SSL_CTX_free(dtw->ctx);
    230 			free(dtw->ip);
    231 			free(dtw);
    232 			return NULL;
    233 		}
    234 		if(SSL_CTX_set_default_verify_paths(dtw->ctx) != 1) {
    235 			log_msg(LOG_ERR, "dnstap: SSL_CTX_set_default_verify_paths failed");
    236 			SSL_CTX_free(dtw->ctx);
    237 			free(dtw->ip);
    238 			free(dtw);
    239 			return NULL;
    240 		}
    241 		SSL_CTX_set_verify(dtw->ctx, SSL_VERIFY_PEER, NULL);
    242 	}
    243 	if(tls_server_name) {
    244 		dtw->tls_server_name = strdup(tls_server_name);
    245 		if(!dtw->tls_server_name) {
    246 				log_msg(LOG_ERR, "dnstap: strdup failed");
    247 				SSL_CTX_free(dtw->ctx);
    248 				free(dtw->ip);
    249 				free(dtw);
    250 				return NULL;
    251 		}
    252 	}
    253 	return dtw;
    254 }
    255 
    256 /* Delete TLS writer object */
    257 static void
    258 tls_writer_delete(struct dt_tls_writer* dtw)
    259 {
    260 	if(!dtw)
    261 		return;
    262 	if(dtw->ssl)
    263 		SSL_shutdown(dtw->ssl);
    264 	SSL_free(dtw->ssl);
    265 	dtw->ssl = NULL;
    266 	SSL_CTX_free(dtw->ctx);
    267 	if(dtw->fd != -1) {
    268 		close(dtw->fd);
    269 		dtw->fd = -1;
    270 	}
    271 	free(dtw->ip);
    272 	free(dtw->tls_server_name);
    273 	free(dtw);
    274 }
    275 
    276 /* The fstrm writer destroy callback for TLS */
    277 static fstrm_res
    278 dt_tls_writer_destroy(void* obj)
    279 {
    280 	struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj;
    281 	tls_writer_delete(dtw);
    282 	return fstrm_res_success;
    283 }
    284 
    285 /* The fstrm writer open callback for TLS */
    286 static fstrm_res
    287 dt_tls_writer_open(void* obj)
    288 {
    289 	struct sockaddr_storage addr;
    290 	socklen_t addrlen;
    291 	char* svr, *at = NULL;
    292 	int port = 3333;
    293 	int addrfamily;
    294 	struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj;
    295 	X509* x;
    296 
    297 	/* skip action if already connected */
    298 	if(dtw->connected)
    299 		return fstrm_res_success;
    300 
    301 	/* figure out port number */
    302 	svr = dtw->ip;
    303 	at = strchr(svr, '@');
    304 	if(at != NULL) {
    305 		*at = 0;
    306 		port = atoi(at+1);
    307 	}
    308 
    309 	/* parse addr */
    310 	memset(&addr, 0, sizeof(addr));
    311 #ifdef INET6
    312 	if(strchr(svr, ':')) {
    313 		struct sockaddr_in6 sa;
    314 		addrlen = (socklen_t)sizeof(struct sockaddr_in6);
    315 		memset(&sa, 0, addrlen);
    316 		sa.sin6_family = AF_INET6;
    317 		sa.sin6_port = (in_port_t)htons((uint16_t)port);
    318 		if(inet_pton((int)sa.sin6_family, svr, &sa.sin6_addr) <= 0) {
    319 			log_msg(LOG_ERR, "dnstap: could not parse IP: %s", svr);
    320 			if(at != NULL)
    321 				*at = '@';
    322 			return fstrm_res_failure;
    323 		}
    324 		memcpy(&addr, &sa, addrlen);
    325 		addrfamily = AF_INET6;
    326 	} else
    327 #else
    328 		if(1)
    329 #endif
    330 	{
    331 		struct sockaddr_in sa;
    332 		addrlen = (socklen_t)sizeof(struct sockaddr_in);
    333 		memset(&sa, 0, addrlen);
    334 		sa.sin_family = AF_INET;
    335 		sa.sin_port = (in_port_t)htons((uint16_t)port);
    336 		if(inet_pton((int)sa.sin_family, svr, &sa.sin_addr) <= 0) {
    337 			log_msg(LOG_ERR, "dnstap: could not parse IP: %s", svr);
    338 			if(at != NULL)
    339 				*at = '@';
    340 			return fstrm_res_failure;
    341 		}
    342 		memcpy(&addr, &sa, addrlen);
    343 		addrfamily = AF_INET;
    344 	}
    345 	if(at != NULL)
    346 		*at = '@';
    347 
    348 	/* open socket */
    349 	dtw->fd = socket(addrfamily, SOCK_STREAM, 0);
    350 	if(dtw->fd == -1) {
    351 		log_msg(LOG_ERR, "dnstap: socket failed: %s", strerror(errno));
    352 		return fstrm_res_failure;
    353 	}
    354 	if(connect(dtw->fd, (struct sockaddr*)&addr, addrlen) < 0) {
    355 		log_msg(LOG_ERR, "dnstap: connect failed: %s", strerror(errno));
    356 		return fstrm_res_failure;
    357 	}
    358 	dtw->connected = 1;
    359 
    360 	/* setup SSL */
    361 	dtw->ssl = SSL_new(dtw->ctx);
    362 	if(!dtw->ssl) {
    363 		log_msg(LOG_ERR, "dnstap: SSL_new failed");
    364 		return fstrm_res_failure;
    365 	}
    366 	SSL_set_connect_state(dtw->ssl);
    367 	(void)SSL_set_mode(dtw->ssl, SSL_MODE_AUTO_RETRY);
    368 	if(!SSL_set_fd(dtw->ssl, dtw->fd)) {
    369 		log_msg(LOG_ERR, "dnstap: SSL_set_fd failed");
    370 		return fstrm_res_failure;
    371 	}
    372 	if(dtw->tls_server_name && dtw->tls_server_name[0]) {
    373 		if(!SSL_set1_host(dtw->ssl, dtw->tls_server_name)) {
    374 			log_msg(LOG_ERR, "dnstap: TLS setting of hostname %s failed to %s",
    375 				dtw->tls_server_name, dtw->ip);
    376 			return fstrm_res_failure;
    377 		}
    378 	}
    379 
    380 	/* handshake */
    381 	while(1) {
    382 		int r;
    383 		ERR_clear_error();
    384 		if( (r=SSL_do_handshake(dtw->ssl)) == 1)
    385 			break;
    386 		r = SSL_get_error(dtw->ssl, r);
    387 		if(r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) {
    388 			if(r == SSL_ERROR_ZERO_RETURN) {
    389 				log_msg(LOG_ERR, "dnstap: EOF on SSL_do_handshake");
    390 				return fstrm_res_failure;
    391 			}
    392 			if(r == SSL_ERROR_SYSCALL) {
    393 				log_msg(LOG_ERR, "dnstap: SSL_do_handshake failed: %s", strerror(errno));
    394 				return fstrm_res_failure;
    395 			}
    396 			log_crypto_err("dnstap: SSL_do_handshake failed");
    397 			return fstrm_res_failure;
    398 		}
    399 		/* wants to be called again */
    400 	}
    401 
    402 	/* check authenticity of server */
    403 	if(SSL_get_verify_result(dtw->ssl) != X509_V_OK) {
    404 		log_crypto_err("SSL verification failed");
    405 		return fstrm_res_failure;
    406 	}
    407 #ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
    408 	x = SSL_get1_peer_certificate(dtw->ssl);
    409 #else
    410 	x = SSL_get_peer_certificate(dtw->ssl);
    411 #endif
    412 	if(!x) {
    413 		log_crypto_err("Server presented no peer certificate");
    414 		return fstrm_res_failure;
    415 	}
    416 	X509_free(x);
    417 
    418 	return fstrm_res_success;
    419 }
    420 
    421 /* The fstrm writer close callback for TLS */
    422 static fstrm_res
    423 dt_tls_writer_close(void* obj)
    424 {
    425 	struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj;
    426 	if(dtw->connected) {
    427 		dtw->connected = 0;
    428 		if(dtw->ssl)
    429 			SSL_shutdown(dtw->ssl);
    430 		SSL_free(dtw->ssl);
    431 		dtw->ssl = NULL;
    432 		if(dtw->fd != -1) {
    433 			close(dtw->fd);
    434 			dtw->fd = -1;
    435 		}
    436 		return fstrm_res_success;
    437 	}
    438 	return fstrm_res_failure;
    439 }
    440 
    441 /* The fstrm writer read callback for TLS */
    442 static fstrm_res
    443 dt_tls_writer_read(void* obj, void* buf, size_t nbytes)
    444 {
    445 	/* want to read nbytes of data */
    446 	struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj;
    447 	size_t nread = 0;
    448 	if(!dtw->connected)
    449 		return fstrm_res_failure;
    450 	while(nread < nbytes) {
    451 		int r;
    452 		ERR_clear_error();
    453 		if((r = SSL_read(dtw->ssl, ((char*)buf)+nread, nbytes-nread)) <= 0) {
    454 			r = SSL_get_error(dtw->ssl, r);
    455 			if(r == SSL_ERROR_ZERO_RETURN) {
    456 				log_msg(LOG_ERR, "dnstap: EOF from %s",
    457 					dtw->ip);
    458 				return fstrm_res_failure;
    459 			}
    460 			if(r == SSL_ERROR_SYSCALL) {
    461 				log_msg(LOG_ERR, "dnstap: read %s: %s",
    462 					dtw->ip, strerror(errno));
    463 				return fstrm_res_failure;
    464 			}
    465 			if(r == SSL_ERROR_SSL) {
    466 				log_crypto_err("dnstap: could not SSL_read");
    467 				return fstrm_res_failure;
    468 			}
    469 			log_msg(LOG_ERR, "dnstap: SSL_read failed with err %d",
    470 				r);
    471 			return fstrm_res_failure;
    472 		}
    473 		nread += r;
    474 	}
    475 	return fstrm_res_success;
    476 }
    477 
    478 /* The fstrm writer write callback for TLS */
    479 static fstrm_res
    480 dt_tls_writer_write(void* obj, const struct iovec* iov, int iovcnt)
    481 {
    482 	struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj;
    483 	int i;
    484 	if(!dtw->connected)
    485 		return fstrm_res_failure;
    486 	for(i=0; i<iovcnt; i++) {
    487 		if(SSL_write(dtw->ssl, iov[i].iov_base, (int)(iov[i].iov_len)) <= 0) {
    488 			log_crypto_err("dnstap: could not SSL_write");
    489 			return fstrm_res_failure;
    490 		}
    491 	}
    492 	return fstrm_res_success;
    493 }
    494 
    495 /* Create the fstrm writer object for TLS */
    496 static struct fstrm_writer*
    497 dt_tls_make_writer(struct fstrm_writer_options* fwopt,
    498 	struct dt_tls_writer* dtw)
    499 {
    500 	struct fstrm_rdwr* rdwr = fstrm_rdwr_init(dtw);
    501 	fstrm_rdwr_set_destroy(rdwr, dt_tls_writer_destroy);
    502 	fstrm_rdwr_set_open(rdwr, dt_tls_writer_open);
    503 	fstrm_rdwr_set_close(rdwr, dt_tls_writer_close);
    504 	fstrm_rdwr_set_read(rdwr, dt_tls_writer_read);
    505 	fstrm_rdwr_set_write(rdwr, dt_tls_writer_write);
    506 	return fstrm_writer_init(fwopt, &rdwr);
    507 }
    508 #endif /* HAVE_SSL */
    509 
    510 /* check that the socket file can be opened and exists, print error if not */
    511 static void
    512 check_socket_file(const char* socket_path)
    513 {
    514 	struct stat statbuf;
    515 	memset(&statbuf, 0, sizeof(statbuf));
    516 	if(stat(socket_path, &statbuf) < 0) {
    517 		log_msg(LOG_WARNING, "could not open dnstap-socket-path: %s, %s",
    518 			socket_path, strerror(errno));
    519 	}
    520 }
    521 
    522 struct dt_env *
    523 dt_create(const char *socket_path, char* ip, unsigned num_workers,
    524 	int tls, char* tls_server_name, char* tls_cert_bundle,
    525 	char* tls_client_key_file, char* tls_client_cert_file)
    526 {
    527 #ifndef NDEBUG
    528 	fstrm_res res;
    529 #endif
    530 	struct dt_env *env;
    531 	struct fstrm_iothr_options *fopt;
    532 	struct fstrm_unix_writer_options *fuwopt = NULL;
    533 	struct fstrm_tcp_writer_options *ftwopt = NULL;
    534 	struct fstrm_writer *fw;
    535 	struct fstrm_writer_options *fwopt;
    536 
    537 	assert(num_workers > 0);
    538 	if(ip == NULL || ip[0] == 0) {
    539 		VERBOSITY(1, (LOG_INFO, "attempting to connect to dnstap socket %s",
    540 			socket_path));
    541 		assert(socket_path != NULL);
    542 		check_socket_file(socket_path);
    543 	} else {
    544 		VERBOSITY(1, (LOG_INFO, "attempting to connect to dnstap %ssocket %s",
    545 			(tls?"tls ":""), ip));
    546 	}
    547 
    548 	env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
    549 	if (!env)
    550 		return NULL;
    551 
    552 	fwopt = fstrm_writer_options_init();
    553 #ifndef NDEBUG
    554 	res =
    555 #else
    556 	(void)
    557 #endif
    558 	    fstrm_writer_options_add_content_type(fwopt,
    559 		DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
    560 	assert(res == fstrm_res_success);
    561 
    562 	if(ip == NULL || ip[0] == 0) {
    563 		fuwopt = fstrm_unix_writer_options_init();
    564 		fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
    565 	} else {
    566 		char* at = strchr(ip, '@');
    567 		if(!tls) {
    568 			ftwopt = fstrm_tcp_writer_options_init();
    569 			if(at == NULL) {
    570 				fstrm_tcp_writer_options_set_socket_address(ftwopt, ip);
    571 				fstrm_tcp_writer_options_set_socket_port(ftwopt, "3333");
    572 			} else {
    573 				*at = 0;
    574 				fstrm_tcp_writer_options_set_socket_address(ftwopt, ip);
    575 				fstrm_tcp_writer_options_set_socket_port(ftwopt, at+1);
    576 				*at = '@';
    577 			}
    578 		} else {
    579 #ifdef HAVE_SSL
    580 			env->tls_writer = tls_writer_init(ip, tls_server_name,
    581 				tls_cert_bundle, tls_client_key_file,
    582 				tls_client_cert_file);
    583 #else
    584 			(void)tls_server_name;
    585 			(void)tls_cert_bundle;
    586 			(void)tls_client_key_file;
    587 			(void)tls_client_cert_file;
    588 			log_msg(LOG_ERR, "dnstap: tls enabled but compiled without ssl.");
    589 #endif
    590 			if(!env->tls_writer) {
    591 				log_msg(LOG_ERR, "dt_create: tls_writer_init() failed");
    592 				fstrm_writer_options_destroy(&fwopt);
    593 				free(env);
    594 				return NULL;
    595 			}
    596 		}
    597 	}
    598 	if(ip == NULL || ip[0] == 0)
    599 		fw = fstrm_unix_writer_init(fuwopt, fwopt);
    600 	else if(!tls)
    601 		fw = fstrm_tcp_writer_init(ftwopt, fwopt);
    602 #ifdef HAVE_SSL
    603 	else
    604 		fw = dt_tls_make_writer(fwopt, env->tls_writer);
    605 #endif
    606 	assert(fw != NULL);
    607 
    608 	fopt = fstrm_iothr_options_init();
    609 	fstrm_iothr_options_set_num_input_queues(fopt, num_workers);
    610 	env->iothr = fstrm_iothr_init(fopt, &fw);
    611 	if (env->iothr == NULL) {
    612 		log_msg(LOG_ERR, "dt_create: fstrm_iothr_init() failed");
    613 		fstrm_writer_destroy(&fw);
    614 		free(env);
    615 		env = NULL;
    616 	}
    617 	fstrm_iothr_options_destroy(&fopt);
    618 
    619 	if(ip == NULL || ip[0] == 0)
    620 		fstrm_unix_writer_options_destroy(&fuwopt);
    621 	else if(!tls)
    622 		fstrm_tcp_writer_options_destroy(&ftwopt);
    623 	fstrm_writer_options_destroy(&fwopt);
    624 
    625 	return env;
    626 }
    627 
    628 static void
    629 dt_apply_identity(struct dt_env *env, struct nsd_options *cfg)
    630 {
    631 	char buf[MAXHOSTNAMELEN+1];
    632 	if (!cfg->dnstap_send_identity)
    633 		return;
    634 	free(env->identity);
    635 	if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) {
    636 		if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
    637 			buf[MAXHOSTNAMELEN] = 0;
    638 			env->identity = strdup(buf);
    639 		} else {
    640 			error("dt_apply_identity: gethostname() failed");
    641 		}
    642 	} else {
    643 		env->identity = strdup(cfg->dnstap_identity);
    644 	}
    645 	if (env->identity == NULL)
    646 		error("dt_apply_identity: strdup() failed");
    647 	env->len_identity = (unsigned int)strlen(env->identity);
    648 	VERBOSITY(1, (LOG_INFO, "dnstap identity field set to \"%s\"",
    649 		env->identity));
    650 }
    651 
    652 static void
    653 dt_apply_version(struct dt_env *env, struct nsd_options *cfg)
    654 {
    655 	if (!cfg->dnstap_send_version)
    656 		return;
    657 	free(env->version);
    658 	if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0)
    659 		env->version = strdup(PACKAGE_STRING);
    660 	else
    661 		env->version = strdup(cfg->dnstap_version);
    662 	if (env->version == NULL)
    663 		error("dt_apply_version: strdup() failed");
    664 	env->len_version = (unsigned int)strlen(env->version);
    665 	VERBOSITY(1, (LOG_INFO, "dnstap version field set to \"%s\"",
    666 		env->version));
    667 }
    668 
    669 void
    670 dt_apply_cfg(struct dt_env *env, struct nsd_options *cfg)
    671 {
    672 	if (!cfg->dnstap_enable)
    673 		return;
    674 
    675 	dt_apply_identity(env, cfg);
    676 	dt_apply_version(env, cfg);
    677 	if ((env->log_auth_query_messages = (unsigned int)
    678 	     cfg->dnstap_log_auth_query_messages))
    679 	{
    680 		VERBOSITY(1, (LOG_INFO, "dnstap Message/AUTH_QUERY enabled"));
    681 	}
    682 	if ((env->log_auth_response_messages = (unsigned int)
    683 	     cfg->dnstap_log_auth_response_messages))
    684 	{
    685 		VERBOSITY(1, (LOG_INFO, "dnstap Message/AUTH_RESPONSE enabled"));
    686 	}
    687 }
    688 
    689 int
    690 dt_init(struct dt_env *env)
    691 {
    692 	env->ioq = fstrm_iothr_get_input_queue(env->iothr);
    693 	if (env->ioq == NULL)
    694 		return 0;
    695 	return 1;
    696 }
    697 
    698 void
    699 dt_delete(struct dt_env *env)
    700 {
    701 	if (!env)
    702 		return;
    703 	VERBOSITY(1, (LOG_INFO, "closing dnstap socket"));
    704 	fstrm_iothr_destroy(&env->iothr);
    705 	free(env->identity);
    706 	free(env->version);
    707 	free(env);
    708 }
    709 
    710 static void
    711 dt_fill_timeval(const struct timeval *tv,
    712 		uint64_t *time_sec, protobuf_c_boolean *has_time_sec,
    713 		uint32_t *time_nsec, protobuf_c_boolean *has_time_nsec)
    714 {
    715 #ifndef S_SPLINT_S
    716 	*time_sec = tv->tv_sec;
    717 	*time_nsec = tv->tv_usec * 1000;
    718 #endif
    719 	*has_time_sec = 1;
    720 	*has_time_nsec = 1;
    721 }
    722 
    723 static void
    724 dt_fill_buffer(uint8_t* pkt, size_t pktlen, ProtobufCBinaryData *p, protobuf_c_boolean *has)
    725 {
    726 	p->len = pktlen;
    727 	p->data = pkt;
    728 	*has = 1;
    729 }
    730 
    731 static void
    732 dt_msg_fill_net(struct dt_msg *dm,
    733 #ifdef INET6
    734 		struct sockaddr_storage *rs,
    735 		struct sockaddr_storage *qs,
    736 #else
    737 		struct sockaddr_in *rs,
    738 		struct sockaddr_in *qs,
    739 #endif
    740 		int is_tcp,
    741 		ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
    742 		uint32_t *rport, protobuf_c_boolean *has_rport,
    743 		ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
    744 		uint32_t *qport, protobuf_c_boolean *has_qport)
    745 
    746 {
    747 #ifdef INET6
    748 	assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
    749 	if (qs->ss_family == AF_INET6) {
    750 		struct sockaddr_in6 *s = (struct sockaddr_in6 *) qs;
    751 
    752 		/* socket_family */
    753 		dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
    754 		dm->m.has_socket_family = 1;
    755 
    756 		/* addr: query_address or response_address */
    757 		qaddr->data = s->sin6_addr.s6_addr;
    758 		qaddr->len = 16; /* IPv6 */
    759 		*has_qaddr = 1;
    760 
    761 		/* port: query_port or response_port */
    762 		*qport = ntohs(s->sin6_port);
    763 		*has_qport = 1;
    764 	} else if (qs->ss_family == AF_INET) {
    765 #else
    766 	if (qs->sin_family == AF_INET) {
    767 #endif /* INET6 */
    768 		struct sockaddr_in *s = (struct sockaddr_in *) qs;
    769 
    770 		/* socket_family */
    771 		dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
    772 		dm->m.has_socket_family = 1;
    773 
    774 		/* addr: query_address or response_address */
    775 		qaddr->data = (uint8_t *) &s->sin_addr.s_addr;
    776 		qaddr->len = 4; /* IPv4 */
    777 		*has_qaddr = 1;
    778 
    779 		/* port: query_port or response_port */
    780 		*qport = ntohs(s->sin_port);
    781 		*has_qport = 1;
    782 	}
    783 
    784 #ifdef INET6
    785         assert(rs->ss_family == AF_INET6 || rs->ss_family == AF_INET);
    786         if (rs->ss_family == AF_INET6) {
    787                 struct sockaddr_in6 *s = (struct sockaddr_in6 *) rs;
    788 
    789                 /* addr: query_address or response_address */
    790                 raddr->data = s->sin6_addr.s6_addr;
    791                 raddr->len = 16; /* IPv6 */
    792                 *has_raddr = 1;
    793 
    794                 /* port: query_port or response_port */
    795                 *rport = ntohs(s->sin6_port);
    796                 *has_rport = 1;
    797         } else if (rs->ss_family == AF_INET) {
    798 #else
    799         if (rs->sin_family == AF_INET) {
    800 #endif /* INET6 */
    801                 struct sockaddr_in *s = (struct sockaddr_in *) rs;
    802 
    803                 /* addr: query_address or response_address */
    804                 raddr->data = (uint8_t *) &s->sin_addr.s_addr;
    805                 raddr->len = 4; /* IPv4 */
    806                 *has_raddr = 1;
    807 
    808                 /* port: query_port or response_port */
    809                 *rport = ntohs(s->sin_port);
    810                 *has_rport = 1;
    811         }
    812 
    813 
    814 	if (!is_tcp) {
    815 		/* socket_protocol */
    816 		dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
    817 		dm->m.has_socket_protocol = 1;
    818 	} else {
    819 		/* socket_protocol */
    820 		dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
    821 		dm->m.has_socket_protocol = 1;
    822 	}
    823 }
    824 
    825 void
    826 dt_msg_send_auth_query(struct dt_env *env,
    827 #ifdef INET6
    828 	struct sockaddr_storage* local_addr,
    829 	struct sockaddr_storage* addr,
    830 #else
    831 	struct sockaddr_in* local_addr,
    832 	struct sockaddr_in* addr,
    833 #endif
    834 	int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen)
    835 {
    836 	struct dt_msg dm;
    837 	struct timeval qtime;
    838 
    839 	gettimeofday(&qtime, NULL);
    840 
    841 	/* type */
    842 	dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__AUTH_QUERY);
    843 
    844 	if(zone) {
    845 		/* query_zone */
    846 		dm.m.query_zone.data = zone;
    847 		dm.m.query_zone.len = zonelen;
    848 		dm.m.has_query_zone = 1;
    849 	}
    850 
    851 	/* query_time */
    852 	dt_fill_timeval(&qtime,
    853 			&dm.m.query_time_sec, &dm.m.has_query_time_sec,
    854 			&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
    855 
    856 	/* query_message */
    857 	dt_fill_buffer(pkt, pktlen, &dm.m.query_message, &dm.m.has_query_message);
    858 
    859 	/* socket_family, socket_protocol, query_address, query_port, reponse_address (local_address), response_port (local_port) */
    860 	dt_msg_fill_net(&dm, local_addr, addr, is_tcp,
    861 			&dm.m.response_address, &dm.m.has_response_address,
    862 			&dm.m.response_port, &dm.m.has_response_port,
    863 			&dm.m.query_address, &dm.m.has_query_address,
    864 			&dm.m.query_port, &dm.m.has_query_port);
    865 
    866 
    867 	if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
    868 		dt_send(env, dm.buf, dm.len_buf);
    869 }
    870 
    871 void
    872 dt_msg_send_auth_response(struct dt_env *env,
    873 #ifdef INET6
    874 	struct sockaddr_storage* local_addr,
    875 	struct sockaddr_storage* addr,
    876 #else
    877 	struct sockaddr_in* local_addr,
    878 	struct sockaddr_in* addr,
    879 #endif
    880 	int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen)
    881 {
    882 	struct dt_msg dm;
    883 	struct timeval rtime;
    884 
    885 	gettimeofday(&rtime, NULL);
    886 
    887 	/* type */
    888 	dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE);
    889 
    890 	if(zone) {
    891 		/* query_zone */
    892 		dm.m.query_zone.data = zone;
    893 		dm.m.query_zone.len = zonelen;
    894 		dm.m.has_query_zone = 1;
    895 	}
    896 
    897 	/* response_time */
    898 	dt_fill_timeval(&rtime,
    899 			&dm.m.response_time_sec, &dm.m.has_response_time_sec,
    900 			&dm.m.response_time_nsec, &dm.m.has_response_time_nsec);
    901 
    902 	/* response_message */
    903 	dt_fill_buffer(pkt, pktlen, &dm.m.response_message, &dm.m.has_response_message);
    904 
    905 	/* socket_family, socket_protocol, query_address, query_port, response_address (local_address), response_port (local_port)  */
    906 	dt_msg_fill_net(&dm, local_addr, addr, is_tcp,
    907 			&dm.m.response_address, &dm.m.has_response_address,
    908 			&dm.m.response_port, &dm.m.has_response_port,
    909 			&dm.m.query_address, &dm.m.has_query_address,
    910 			&dm.m.query_port, &dm.m.has_query_port);
    911 
    912 	if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
    913 		dt_send(env, dm.buf, dm.len_buf);
    914 }
    915 
    916 #endif /* USE_DNSTAP */
    917