Skip to content

Commit

Permalink
TCP client
Browse files Browse the repository at this point in the history
- `output.tcpcli`: Issue DNS-OARC#47: Add simple TCP client
- `output.udpcli`: `socket()` does not need protocol
  • Loading branch information
jelu committed May 3, 2018
1 parent 0acfc3e commit 313495c
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 9 deletions.
17 changes: 10 additions & 7 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ lua_objects = core.luao lib.luao input.luao filter.luao output.luao
dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS)

# C source and headers
dnsjit_SOURCES += core/producer.c core/log.c core/receiver.c core/object.c core/object/ip.c core/object/tcp.c core/object/pcap.c core/object/dns.c core/object/icmp6.c core/object/ieee802.c core/object/udp.c core/object/loop.c core/object/packet.c core/object/ip6.c core/object/gre.c core/object/linuxsll.c core/object/icmp.c core/object/null.c core/object/ether.c core/tracking.c core/mutex.c lib/clock.c input/zero.c input/pcap.c input/fpcap.c input/mmpcap.c input/pcapthread.c filter/lua.c filter/split.c filter/thread.c filter/timing.c filter/coro.c filter/layer.c output/udpcli.c output/cpool.c output/cpool/client_pool.c output/cpool/client.c output/null.c
dist_dnsjit_SOURCES += core/mutex.h core/receiver.h core/object.h core/log.h core/timespec.h core/producer.h core/tracking.h core/object/icmp.h core/object/ip.h core/object/loop.h core/object/dns.h core/object/ip6.h core/object/null.h core/object/tcp.h core/object/udp.h core/object/packet.h core/object/icmp6.h core/object/ether.h core/object/pcap.h core/object/ieee802.h core/object/linuxsll.h core/object/gre.h lib/clock.h input/zero.h input/fpcap.h input/pcap.h input/mmpcap.h input/pcapthread.h filter/lua.h filter/split.h filter/layer.h filter/timing.h filter/thread.h filter/coro.h output/null.h output/cpool/client_pool.h output/cpool/client.h output/cpool.h output/udpcli.h
dnsjit_SOURCES += core/producer.c core/log.c core/receiver.c core/object.c core/object/ip.c core/object/tcp.c core/object/pcap.c core/object/dns.c core/object/icmp6.c core/object/ieee802.c core/object/udp.c core/object/loop.c core/object/packet.c core/object/ip6.c core/object/gre.c core/object/linuxsll.c core/object/icmp.c core/object/null.c core/object/ether.c core/tracking.c core/mutex.c lib/clock.c input/zero.c input/pcap.c input/fpcap.c input/mmpcap.c input/pcapthread.c filter/lua.c filter/split.c filter/thread.c filter/timing.c filter/coro.c filter/layer.c output/udpcli.c output/cpool.c output/tcpcli.c output/cpool/client_pool.c output/cpool/client.c output/null.c
dist_dnsjit_SOURCES += core/mutex.h core/receiver.h core/object.h core/log.h core/timespec.h core/producer.h core/tracking.h core/object/icmp.h core/object/ip.h core/object/loop.h core/object/dns.h core/object/ip6.h core/object/null.h core/object/tcp.h core/object/udp.h core/object/packet.h core/object/icmp6.h core/object/ether.h core/object/pcap.h core/object/ieee802.h core/object/linuxsll.h core/object/gre.h lib/clock.h input/zero.h input/fpcap.h input/pcap.h input/mmpcap.h input/pcapthread.h filter/lua.h filter/split.h filter/layer.h filter/timing.h filter/thread.h filter/coro.h output/null.h output/cpool/client_pool.h output/cpool/client.h output/cpool.h output/tcpcli.h output/udpcli.h

# Lua headers
dist_dnsjit_SOURCES += core/timespec.hh core/mutex.hh core/tracking.hh core/object/loop.hh core/object/gre.hh core/object/linuxsll.hh core/object/tcp.hh core/object/ether.hh core/object/icmp.hh core/object/ieee802.hh core/object/ip6.hh core/object/udp.hh core/object/packet.hh core/object/dns.hh core/object/pcap.hh core/object/icmp6.hh core/object/ip.hh core/object/null.hh core/producer.hh core/receiver.hh core/object.hh core/log.hh lib/clock.hh input/zero.hh input/mmpcap.hh input/pcap.hh input/fpcap.hh input/pcapthread.hh filter/layer.hh filter/coro.hh filter/lua.hh filter/thread.hh filter/timing.hh filter/split.hh output/udpcli.hh output/cpool.hh output/null.hh
lua_hobjects += core/timespec.luaho core/mutex.luaho core/tracking.luaho core/object/loop.luaho core/object/gre.luaho core/object/linuxsll.luaho core/object/tcp.luaho core/object/ether.luaho core/object/icmp.luaho core/object/ieee802.luaho core/object/ip6.luaho core/object/udp.luaho core/object/packet.luaho core/object/dns.luaho core/object/pcap.luaho core/object/icmp6.luaho core/object/ip.luaho core/object/null.luaho core/producer.luaho core/receiver.luaho core/object.luaho core/log.luaho lib/clock.luaho input/zero.luaho input/mmpcap.luaho input/pcap.luaho input/fpcap.luaho input/pcapthread.luaho filter/layer.luaho filter/coro.luaho filter/lua.luaho filter/thread.luaho filter/timing.luaho filter/split.luaho output/udpcli.luaho output/cpool.luaho output/null.luaho
dist_dnsjit_SOURCES += core/timespec.hh core/mutex.hh core/tracking.hh core/object/loop.hh core/object/gre.hh core/object/linuxsll.hh core/object/tcp.hh core/object/ether.hh core/object/icmp.hh core/object/ieee802.hh core/object/ip6.hh core/object/udp.hh core/object/packet.hh core/object/dns.hh core/object/pcap.hh core/object/icmp6.hh core/object/ip.hh core/object/null.hh core/producer.hh core/receiver.hh core/object.hh core/log.hh lib/clock.hh input/zero.hh input/mmpcap.hh input/pcap.hh input/fpcap.hh input/pcapthread.hh filter/layer.hh filter/coro.hh filter/lua.hh filter/thread.hh filter/timing.hh filter/split.hh output/udpcli.hh output/cpool.hh output/tcpcli.hh output/null.hh
lua_hobjects += core/timespec.luaho core/mutex.luaho core/tracking.luaho core/object/loop.luaho core/object/gre.luaho core/object/linuxsll.luaho core/object/tcp.luaho core/object/ether.luaho core/object/icmp.luaho core/object/ieee802.luaho core/object/ip6.luaho core/object/udp.luaho core/object/packet.luaho core/object/dns.luaho core/object/pcap.luaho core/object/icmp6.luaho core/object/ip.luaho core/object/null.luaho core/producer.luaho core/receiver.luaho core/object.luaho core/log.luaho lib/clock.luaho input/zero.luaho input/mmpcap.luaho input/pcap.luaho input/fpcap.luaho input/pcapthread.luaho filter/layer.luaho filter/coro.luaho filter/lua.luaho filter/thread.luaho filter/timing.luaho filter/split.luaho output/udpcli.luaho output/cpool.luaho output/tcpcli.luaho output/null.luaho

# Lua sources
dist_dnsjit_SOURCES += core/mutex.lua core/log.lua core/tracking.lua core/timespec.lua core/producer.lua core/object/pcap.lua core/object/icmp6.lua core/object/gre.lua core/object/ether.lua core/object/ip.lua core/object/ieee802.lua core/object/tcp.lua core/object/ip6.lua core/object/linuxsll.lua core/object/null.lua core/object/loop.lua core/object/icmp.lua core/object/packet.lua core/object/dns.lua core/object/udp.lua core/receiver.lua core/object.lua lib/getopt.lua lib/clock.lua lib/parseconf.lua input/pcapthread.lua input/fpcap.lua input/pcap.lua input/zero.lua input/mmpcap.lua filter/coro.lua filter/timing.lua filter/split.lua filter/layer.lua filter/thread.lua filter/lua.lua output/cpool.lua output/null.lua output/udpcli.lua
lua_objects += core/mutex.luao core/log.luao core/tracking.luao core/timespec.luao core/producer.luao core/object/pcap.luao core/object/icmp6.luao core/object/gre.luao core/object/ether.luao core/object/ip.luao core/object/ieee802.luao core/object/tcp.luao core/object/ip6.luao core/object/linuxsll.luao core/object/null.luao core/object/loop.luao core/object/icmp.luao core/object/packet.luao core/object/dns.luao core/object/udp.luao core/receiver.luao core/object.luao lib/getopt.luao lib/clock.luao lib/parseconf.luao input/pcapthread.luao input/fpcap.luao input/pcap.luao input/zero.luao input/mmpcap.luao filter/coro.luao filter/timing.luao filter/split.luao filter/layer.luao filter/thread.luao filter/lua.luao output/cpool.luao output/null.luao output/udpcli.luao
dist_dnsjit_SOURCES += core/mutex.lua core/log.lua core/tracking.lua core/timespec.lua core/producer.lua core/object/pcap.lua core/object/icmp6.lua core/object/gre.lua core/object/ether.lua core/object/ip.lua core/object/ieee802.lua core/object/tcp.lua core/object/ip6.lua core/object/linuxsll.lua core/object/null.lua core/object/loop.lua core/object/icmp.lua core/object/packet.lua core/object/dns.lua core/object/udp.lua core/receiver.lua core/object.lua lib/getopt.lua lib/clock.lua lib/parseconf.lua input/pcapthread.lua input/fpcap.lua input/pcap.lua input/zero.lua input/mmpcap.lua filter/coro.lua filter/timing.lua filter/split.lua filter/layer.lua filter/thread.lua filter/lua.lua output/tcpcli.lua output/cpool.lua output/null.lua output/udpcli.lua
lua_objects += core/mutex.luao core/log.luao core/tracking.luao core/timespec.luao core/producer.luao core/object/pcap.luao core/object/icmp6.luao core/object/gre.luao core/object/ether.luao core/object/ip.luao core/object/ieee802.luao core/object/tcp.luao core/object/ip6.luao core/object/linuxsll.luao core/object/null.luao core/object/loop.luao core/object/icmp.luao core/object/packet.luao core/object/dns.luao core/object/udp.luao core/receiver.luao core/object.luao lib/getopt.luao lib/clock.luao lib/parseconf.luao input/pcapthread.luao input/fpcap.luao input/pcap.luao input/zero.luao input/mmpcap.luao filter/coro.luao filter/timing.luao filter/split.luao filter/layer.luao filter/thread.luao filter/lua.luao output/tcpcli.luao output/cpool.luao output/null.luao output/udpcli.luao

dnsjit_LDFLAGS = -Wl,-E
dnsjit_LDADD += $(lua_hobjects) $(lua_objects)
Expand All @@ -62,7 +62,7 @@ man1_MANS = dnsjit.1
CLEANFILES += $(man1_MANS)

man3_MANS = dnsjit.core.3 dnsjit.lib.3 dnsjit.input.3 dnsjit.filter.3 dnsjit.output.3
man3_MANS += dnsjit.core.mutex.3 dnsjit.core.log.3 dnsjit.core.tracking.3 dnsjit.core.timespec.3 dnsjit.core.producer.3 dnsjit.core.object.pcap.3 dnsjit.core.object.icmp6.3 dnsjit.core.object.gre.3 dnsjit.core.object.ether.3 dnsjit.core.object.ip.3 dnsjit.core.object.ieee802.3 dnsjit.core.object.tcp.3 dnsjit.core.object.ip6.3 dnsjit.core.object.linuxsll.3 dnsjit.core.object.null.3 dnsjit.core.object.loop.3 dnsjit.core.object.icmp.3 dnsjit.core.object.packet.3 dnsjit.core.object.dns.3 dnsjit.core.object.udp.3 dnsjit.core.receiver.3 dnsjit.core.object.3 dnsjit.lib.getopt.3 dnsjit.lib.clock.3 dnsjit.lib.parseconf.3 dnsjit.input.pcapthread.3 dnsjit.input.fpcap.3 dnsjit.input.pcap.3 dnsjit.input.zero.3 dnsjit.input.mmpcap.3 dnsjit.filter.coro.3 dnsjit.filter.timing.3 dnsjit.filter.split.3 dnsjit.filter.layer.3 dnsjit.filter.thread.3 dnsjit.filter.3.3 dnsjit.output.cpool.3 dnsjit.output.null.3 dnsjit.output.udpcli.3
man3_MANS += dnsjit.core.mutex.3 dnsjit.core.log.3 dnsjit.core.tracking.3 dnsjit.core.timespec.3 dnsjit.core.producer.3 dnsjit.core.object.pcap.3 dnsjit.core.object.icmp6.3 dnsjit.core.object.gre.3 dnsjit.core.object.ether.3 dnsjit.core.object.ip.3 dnsjit.core.object.ieee802.3 dnsjit.core.object.tcp.3 dnsjit.core.object.ip6.3 dnsjit.core.object.linuxsll.3 dnsjit.core.object.null.3 dnsjit.core.object.loop.3 dnsjit.core.object.icmp.3 dnsjit.core.object.packet.3 dnsjit.core.object.dns.3 dnsjit.core.object.udp.3 dnsjit.core.receiver.3 dnsjit.core.object.3 dnsjit.lib.getopt.3 dnsjit.lib.clock.3 dnsjit.lib.parseconf.3 dnsjit.input.pcapthread.3 dnsjit.input.fpcap.3 dnsjit.input.pcap.3 dnsjit.input.zero.3 dnsjit.input.mmpcap.3 dnsjit.filter.coro.3 dnsjit.filter.timing.3 dnsjit.filter.split.3 dnsjit.filter.layer.3 dnsjit.filter.thread.3 dnsjit.filter.3.3 dnsjit.output.tcpcli.3 dnsjit.output.cpool.3 dnsjit.output.null.3 dnsjit.output.udpcli.3
CLEANFILES += *.3in $(man3_MANS)

.lua.luao:
Expand Down Expand Up @@ -220,6 +220,9 @@ dnsjit.filter.thread.3in: filter/thread.lua gen-manpage.lua
dnsjit.filter.3.3in: filter/lua.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/lua.lua" > "$@"

dnsjit.output.tcpcli.3in: output/tcpcli.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/tcpcli.lua" > "$@"

dnsjit.output.cpool.3in: output/cpool.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/cpool.lua" > "$@"

Expand Down
204 changes: 204 additions & 0 deletions src/output/tcpcli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/*
* Copyright (c) 2018, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"

#include "output/tcpcli.h"
#include "core/object/dns.h"
#include "core/object/udp.h"
#include "core/object/tcp.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

static core_log_t _log = LOG_T_INIT("output.tcpcli");
static output_tcpcli_t _defaults = {
LOG_T_INIT_OBJ("output.tcpcli"),
0, 0, -1,
};

core_log_t* output_tcpcli_log()
{
return &_log;
}

int output_tcpcli_init(output_tcpcli_t* self, const char* host, const char* port)
{
struct addrinfo* addr;
int err;

if (!self || !host || !port) {
return 1;
}

*self = _defaults;

ldebug("init %s %s", host, port);

if ((err = getaddrinfo(host, port, 0, &addr))) {
lcritical("getaddrinfo() %d", err);
return 1;
}
if (!addr) {
lcritical("getaddrinfo failed");
return 1;
}
ldebug("getaddrinfo() flags: 0x%x family: 0x%x socktype: 0x%x protocol: 0x%x addrlen: %d",
addr->ai_flags,
addr->ai_family,
addr->ai_socktype,
addr->ai_protocol,
addr->ai_addrlen);

if ((self->fd = socket(addr->ai_addr->sa_family, SOCK_STREAM, 0)) < 0) {
lcritical("socket failed");
freeaddrinfo(addr);
return 1;
}

if (connect(self->fd, addr->ai_addr, addr->ai_addrlen)) {
lcritical("connect failed");
freeaddrinfo(addr);
close(self->fd);
self->fd = -1;
return 1;
}

freeaddrinfo(addr);

if ((err = fcntl(self->fd, F_GETFL)) == -1
|| fcntl(self->fd, F_SETFL, err | O_NONBLOCK)) {
lcritical("fcntl failed");
}

return 0;
}

int output_tcpcli_destroy(output_tcpcli_t* self)
{
if (!self) {
return 1;
}

ldebug("destroy");

if (self->fd > -1) {
shutdown(self->fd, SHUT_RDWR);
close(self->fd);
}

return 0;
}

static int _receive(void* ctx, const core_object_t* obj)
{
output_tcpcli_t* self = (output_tcpcli_t*)ctx;
const uint8_t* payload;
size_t len, sent;
uint16_t dnslen;

if (!self) {
return 1;
}

for (; obj;) {
switch (obj->obj_type) {
case CORE_OBJECT_DNS:
obj = obj->obj_prev;
continue;
case CORE_OBJECT_UDP:
payload = ((core_object_udp_t*)obj)->payload;
len = ((core_object_udp_t*)obj)->len;
break;
case CORE_OBJECT_TCP:
payload = ((core_object_tcp_t*)obj)->payload;
len = ((core_object_tcp_t*)obj)->len;
break;
default:
return 1;
}

if (len < 3 || payload[2] & 0x80) {
return 0;
}

sent = 0;
self->pkts++;

dnslen = htons(len);

for (;;) {
ssize_t ret = sendto(self->fd, ((uint8_t*)&dnslen) + sent, sizeof(dnslen) - sent, 0, 0, 0);
if (ret > -1) {
sent += ret;
if (sent < sizeof(dnslen))
continue;

sent = 0;
for (;;) {
ssize_t ret = sendto(self->fd, payload + sent, len - sent, 0, 0, 0);
if (ret > -1) {
sent += ret;
if (sent < len)
continue;
return 0;
}
switch (errno) {
case EAGAIN:
#if EAGAIN != EWOULDBLOCK
case EWOULDBLOCK:
#endif
continue;
default:
break;
}
self->errs++;
break;
}
break;
}
switch (errno) {
case EAGAIN:
#if EAGAIN != EWOULDBLOCK
case EWOULDBLOCK:
#endif
continue;
default:
break;
}
self->errs++;
break;
}
break;
}

return 1;
}

core_receiver_t output_tcpcli_receiver()
{
return _receive;
}
29 changes: 29 additions & 0 deletions src/output/tcpcli.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/

#include "core/log.h"
#include "core/receiver.h"

#ifndef __dnsjit_output_tcpcli_h
#define __dnsjit_output_tcpcli_h

#include "output/tcpcli.hh"

#endif
35 changes: 35 additions & 0 deletions src/output/tcpcli.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2018, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/

//lua:require("dnsjit.core.log")
//lua:require("dnsjit.core.receiver_h")

typedef struct output_tcpcli {
core_log_t _log;
size_t pkts, errs;
int fd;
} output_tcpcli_t;

core_log_t* output_tcpcli_log();

int output_tcpcli_init(output_tcpcli_t* self, const char* host, const char* port);
int output_tcpcli_destroy(output_tcpcli_t* self);

core_receiver_t output_tcpcli_receiver();
Loading

0 comments on commit 313495c

Please sign in to comment.