Skip to content

Commit

Permalink
Client
Browse files Browse the repository at this point in the history
- `core.compat`:
  - Add `struct sockaddr_storage`
  - Check that we found all types
- `output.tcpcli`: Issue DNS-OARC#47: Add `connect()` and `nonblocking()`
- `output.udpcli`:
  - Issue DNS-OARC#46: Add `connect()` and `nonblocking()`
  - Use `struct sockaddr_storage`
  • Loading branch information
jelu committed May 4, 2018
1 parent cb627ae commit db6854b
Show file tree
Hide file tree
Showing 12 changed files with 274 additions and 86 deletions.
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ AC_CHECK_SIZEOF([void*])
AC_CHECK_SIZEOF([pthread_t])
AC_CHECK_SIZEOF([pthread_mutex_t])
AC_CHECK_SIZEOF([pthread_cond_t])
AC_CHECK_SIZEOF([struct sockaddr_storage],,[#include <sys/types.h>
#include <sys/socket.h>])

# Output Makefiles
AC_CONFIG_FILES([
Expand Down
4 changes: 3 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ AM_CFLAGS = -I$(srcdir) \

EXTRA_DIST = gen-manpage.lua gen-compat.lua dnsjit.1in

BUILT_SOURCES = core/compat.hh

bin_PROGRAMS = dnsjit

dnsjit_SOURCES = dnsjit.c globals.c \
Expand All @@ -43,7 +45,7 @@ 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/tcpcli.c output/cpool/client_pool.c output/cpool/client.c output/null.c
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 core/compat.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
Expand Down
25 changes: 25 additions & 0 deletions src/core/compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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 <stdint.h>

#include "core/compat.hh"
22 changes: 18 additions & 4 deletions src/gen-compat.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
for line in io.lines("config.h") do
local n,s = line:match("define SIZEOF_(PTHREAD%S*)_T (%d+)")
local n, s = line:match("define SIZEOF_(%S*) (%d+)")
if n and s then
s = math.ceil(s / 8)
n = n:lower()
print("typedef struct "..n.." { uint64_t a["..s.."]; } "..n.."_t;")
if n:match("^PTHREAD") then
s = math.ceil(s / 8)
print("#if !defined(SIZEOF_"..n..") || SIZEOF_"..n.." == 0")
print("#error \""..n.." is undefined or zero\"")
print("#endif")
n = n:lower()
print("typedef struct "..n:sub(1,-3).." { uint64_t a["..s.."]; } "..n..";")
elseif n:match("^STRUCT") then
n = n:match("^STRUCT_(%S*)")
if n == "SOCKADDR_STORAGE" then
print("#if !defined(SIZEOF_STRUCT_"..n..") || SIZEOF_STRUCT_"..n.." == 0")
print("#error \""..n.." is undefined or zero\"")
print("#endif")
n = n:lower()
print("struct "..n.." { uint8_t a["..s.."]; };")
end
end
end
end
2 changes: 2 additions & 0 deletions src/gen-makefile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ AM_CFLAGS = -I$(srcdir) \
EXTRA_DIST = gen-manpage.lua gen-compat.lua dnsjit.1in
BUILT_SOURCES = core/compat.hh
bin_PROGRAMS = dnsjit
dnsjit_SOURCES = dnsjit.c globals.c \
Expand Down
102 changes: 67 additions & 35 deletions src/output/tcpcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,58 @@
#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,
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)
int output_tcpcli_init(output_tcpcli_t* self)
{
if (!self) {
return 1;
}

*self = _defaults;

ldebug("init");

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

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

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

*self = _defaults;

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

if ((err = getaddrinfo(host, port, 0, &addr))) {
lcritical("getaddrinfo() %d", err);
Expand Down Expand Up @@ -88,26 +114,50 @@ int output_tcpcli_init(output_tcpcli_t* self, const char* host, const char* port
}

freeaddrinfo(addr);
return 0;
}

if ((err = fcntl(self->fd, F_GETFL)) == -1
|| fcntl(self->fd, F_SETFL, err | O_NONBLOCK)) {
lcritical("fcntl failed");
int output_tcpcli_nonblocking(output_tcpcli_t* self)
{
int flags;

if (!self || self->fd < 0) {
return -1;
}

return 0;
flags = fcntl(self->fd, F_GETFL);
if (flags != -1) {
flags = flags & O_NONBLOCK ? 1 : 0;
}

return flags;
}

int output_tcpcli_destroy(output_tcpcli_t* self)
int output_tcpcli_set_nonblocking(output_tcpcli_t* self, int nonblocking)
{
if (!self) {
int flags;

if (!self || self->fd < 0) {
return 1;
}

ldebug("destroy");
ldebug("set nonblocking %d", nonblocking);

if (self->fd > -1) {
shutdown(self->fd, SHUT_RDWR);
close(self->fd);
if ((flags = fcntl(self->fd, F_GETFL)) == -1) {
lcritical("fcntl(FL_GETFL) failed");
return 1;
}

if (nonblocking) {
if (fcntl(self->fd, F_SETFL, flags | O_NONBLOCK)) {
lcritical("fcntl(FL_SETFL) failed");
return 1;
}
} else {
if (fcntl(self->fd, F_SETFL, flags & ~O_NONBLOCK)) {
lcritical("fcntl(FL_SETFL) failed");
return 1;
}
}

return 0;
Expand Down Expand Up @@ -166,29 +216,11 @@ static int _receive(void* ctx, const core_object_t* obj)
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;
}
Expand Down
5 changes: 4 additions & 1 deletion src/output/tcpcli.hh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ typedef struct output_tcpcli {

core_log_t* output_tcpcli_log();

int output_tcpcli_init(output_tcpcli_t* self, const char* host, const char* port);
int output_tcpcli_init(output_tcpcli_t* self);
int output_tcpcli_destroy(output_tcpcli_t* self);
int output_tcpcli_connect(output_tcpcli_t* self, const char* host, const char* port);
int output_tcpcli_nonblocking(output_tcpcli_t* self);
int output_tcpcli_set_nonblocking(output_tcpcli_t* self, int nonblocking);

core_receiver_t output_tcpcli_receiver();
41 changes: 37 additions & 4 deletions src/output/tcpcli.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,50 @@ local t_name = "output_tcpcli_t"
local output_tcpcli_t = ffi.typeof(t_name)
local Tcpcli = {}

-- Create a new Tcpcli output to send queries to the
-- Create a new Tcpcli output. Optinally connect to the
-- .I host
-- and
-- .IR port .
-- .IR port right away or use
-- .BR connect ()
-- later on.
function Tcpcli.new(host, port)
local self = {
obj = output_tcpcli_t(),
}
C.output_tcpcli_init(self.obj, host, port)
C.output_tcpcli_init(self.obj)
ffi.gc(self.obj, C.output_tcpcli_destroy)
return setmetatable(self, { __index = Tcpcli })
self = setmetatable(self, { __index = Tcpcli })
if host and port then
if self:connect(host, port) ~= 0 then
return
end
end
return self
end

-- Connect to the
-- .I host
-- and
-- .IR port .
function Tcpcli.connect(host, port)
return C.output_tcpcli_connect(self.obj, host, port)
end

-- Enable (true) or disable (false) nonblocking mode and
-- return 0 if successful, if
-- .I bool
-- is not specified then return if nonblocking mode is on (true) or off (false).
function Tcpcli.nonblocking(bool)
if bool == nil then
if C.output_tcpcli_nonblocking(self.obj) == 1 then
return true
end
return false
elseif bool == true then
return C.output_tcpcli_set_nonblocking(self.obj, 1)
else
return C.output_tcpcli_set_nonblocking(self.obj, 0)
end
end

-- Return the C functions and context for receiving objects.
Expand Down
Loading

0 comments on commit db6854b

Please sign in to comment.