1
0
Fork 0
dnswire/examples/client_receiver_uv.c

135 lines
3.4 KiB
C
Raw Normal View History

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