udp-handler.c 2.69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*  Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
16 17 18 19 20 21 22


/*
 * Udp handler listen on stdin and send to stdout.
 * To use this handler initialize it with udp_master_init_stdin.
 */

23 24 25
#include "knot/server/udp-handler.c"
#include "knot/common/debug.h"

26 27 28 29 30 31 32 33 34 35 36 37 38 39
struct udp_stdin {
	struct iovec iov[NBUFS];
	uint8_t buf[NBUFS][KNOT_WIRE_MAX_PKTSIZE];
	struct sockaddr_storage addr;
};

static void *udp_stdin_init(void)
{
	struct udp_stdin *rq = malloc(sizeof(struct udp_stdin));
	memset(rq, 0, sizeof(struct udp_stdin));
	for (unsigned i = 0; i < NBUFS; ++i) {
		rq->iov[i].iov_base = rq->buf[i];
		rq->iov[i].iov_len = KNOT_WIRE_MAX_PKTSIZE;
	}
40 41 42 43 44

	struct sockaddr_in * a = (struct sockaddr_in *) &rq->addr;
	a->sin_family=AF_INET;
	a->sin_addr.s_addr = IN_LOOPBACKNET;
	a->sin_port = 42;
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
	return rq;
}

static int udp_stdin_deinit(void *d)
{
	free(d);
	return 0;
}

static int udp_stdin_recv(int fd, void *d)
{
	struct udp_stdin *rq = (struct udp_stdin *) d;
	rq->iov[RX].iov_len = fread(rq->iov[RX].iov_base,
	                            1, rq->iov[RX].iov_len, stdin);
	return rq->iov[RX].iov_len;
}

static int udp_stdin_handle(udp_context_t *ctx, void *d)
{
	struct udp_stdin *rq = (struct udp_stdin *) d;
	udp_handle(ctx, STDIN_FILENO, &rq->addr, &rq->iov[RX], &rq->iov[TX]);
	return 0;
}

static int udp_stdin_send(void *d)
{
	struct udp_stdin *rq = (struct udp_stdin *) d;
72
	//fwrite(rq->iov[TX].iov_base, 1, rq->iov[TX].iov_len, stdout);
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
	if (getenv("AFL_PERSISTENT")) {
		raise(SIGSTOP);
	} else {
		exit(0);
	}
	return 0;
}

/*!
 * \brief Initialize udp_handler with stdio
 */
void udp_master_init_stdio(server_t *server) {

	log_info("AFL, UDP handler listen on stdin");

	// register our dummy interface to server
	iface_t * ifc = malloc(sizeof(iface_t));
	ifc->fd[RX] = STDIN_FILENO;
	ifc->fd[TX] = STDOUT_FILENO;
92 93 94

	fprintf(stderr, "LIST SIZE %zu\n", list_size(&server->ifaces->l));

95 96
	add_tail(&server->ifaces->l, (node_t *)ifc);

97 98


99 100 101 102 103 104
	_udp_init = udp_stdin_init;
	_udp_recv = udp_stdin_recv;
	_udp_handle = udp_stdin_handle;
	_udp_send = udp_stdin_send;
	_udp_deinit = udp_stdin_deinit;
}