#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); }