1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#include <dnswire/reader.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include <arpa/inet.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>
#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 <IP> <port>\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);
}
|