From be956cd27353a4bb585b1a648e8469cf7adb5edf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 14 Jan 2022 16:03:48 +0100 Subject: Adding upstream version 0.2.0. Signed-off-by: Daniel Baumann --- examples/client_receiver_uv.c | 134 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 examples/client_receiver_uv.c (limited to 'examples/client_receiver_uv.c') diff --git a/examples/client_receiver_uv.c b/examples/client_receiver_uv.c new file mode 100644 index 0000000..0454ba2 --- /dev/null +++ b/examples/client_receiver_uv.c @@ -0,0 +1,134 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "print_dnstap.c" + +#define BUF_SIZE 4096 + +uv_loop_t* loop; +uv_tcp_t sock; +uv_connect_t conn; +char rbuf[BUF_SIZE]; + +struct dnswire_reader reader; + +void client_alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) +{ + buf->base = rbuf; + buf->len = sizeof(rbuf); +} + +void client_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) +{ + if (nread > 0) { + /* + * We now push all the data we got to the reader. + */ + size_t pushed = 0; + + while (pushed < nread) { + enum dnswire_result res = dnswire_reader_push(&reader, (uint8_t*)&buf->base[pushed], nread - pushed, 0, 0); + + pushed += dnswire_reader_pushed(reader); + + switch (res) { + case dnswire_have_dnstap: + /* + * We got a DNSTAP message, lets print it! + */ + print_dnstap(dnswire_reader_dnstap(reader)); + break; + case dnswire_again: + case dnswire_need_more: + break; + case dnswire_endofdata: + /* + * The remote end sent a control stop or finish. + */ + uv_close((uv_handle_t*)handle, 0); + return; + default: + fprintf(stderr, "dnswire_reader_fread() error\n"); + uv_close((uv_handle_t*)handle, 0); + return; + } + } + } + if (nread < 0) { + if (nread != UV_EOF) { + fprintf(stderr, "client_read() error: %s\n", uv_err_name(nread)); + } else { + printf("disconnected\n"); + } + uv_close((uv_handle_t*)handle, 0); + } +} + +void on_connect(uv_connect_t* req, int status) +{ + /* + * We have connected to the sender, check that there was no errors + * and start receiving incoming frames. + */ + + if (status < 0) { + fprintf(stderr, "on_connect() error: %s\n", uv_strerror(status)); + return; + } + + uv_read_start((uv_stream_t*)&sock, client_alloc_buffer, client_read); +} + +int main(int argc, const char* argv[]) +{ + if (argc < 3) { + fprintf(stderr, "usage: client_receiver_uv \n"); + return 1; + } + + /* + * We first initialize the reader and check that it can allocate the + * buffers it needs. + */ + + if (dnswire_reader_init(&reader) != dnswire_ok) { + fprintf(stderr, "Unable to initialize dnswire reader\n"); + return 1; + } + + /* + * We set this reader to reject bidirectional communication. + */ + if (dnswire_reader_allow_bidirectional(&reader, false) != dnswire_ok) { + fprintf(stderr, "Unable to deny bidirectional communication\n"); + return 1; + } + + /* + * We setup a TCP client using libuv and connect to the given server. + */ + + struct sockaddr_storage addr; + int port = atoi(argv[2]); + + if (strchr(argv[1], ':')) { + uv_ip6_addr(argv[1], port, (struct sockaddr_in6*)&addr); + } else { + uv_ip4_addr(argv[1], port, (struct sockaddr_in*)&addr); + } + + loop = uv_default_loop(); + + uv_tcp_init(loop, &sock); + uv_tcp_connect(&conn, &sock, (const struct sockaddr*)&addr, on_connect); + + return uv_run(loop, UV_RUN_DEFAULT); +} -- cgit v1.2.3