summaryrefslogtreecommitdiffstats
path: root/examples/client_receiver_uv.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/client_receiver_uv.c')
-rw-r--r--examples/client_receiver_uv.c134
1 files changed, 134 insertions, 0 deletions
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 <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);
+}