Skip to content

Commit 939f0c7

Browse files
committed
Client
- `core.compat`: - Add `struct sockaddr_storage` - Check that we found all types - `output.tcpcli`: Issue #47: Add `connect()` and `nonblocking()` - `output.udpcli`: - Issue #46: Add `connect()` and `nonblocking()` - Use `struct sockaddr_storage`
1 parent cb627ae commit 939f0c7

File tree

12 files changed

+277
-89
lines changed

12 files changed

+277
-89
lines changed

configure.ac

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ fi
6464

6565
# Checks for sizes
6666
AC_CHECK_SIZEOF([void*])
67-
AC_CHECK_SIZEOF([pthread_t])
68-
AC_CHECK_SIZEOF([pthread_mutex_t])
69-
AC_CHECK_SIZEOF([pthread_cond_t])
67+
AC_CHECK_SIZEOF([pthread_t],,[#include <pthread.h>])
68+
AC_CHECK_SIZEOF([pthread_mutex_t],,[#include <pthread.h>])
69+
AC_CHECK_SIZEOF([pthread_cond_t],,[#include <pthread.h>])
70+
AC_CHECK_SIZEOF([struct sockaddr_storage],,[#include <sys/types.h>
71+
#include <sys/socket.h>])
7072

7173
# Output Makefiles
7274
AC_CONFIG_FILES([

src/Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ AM_CFLAGS = -I$(srcdir) \
2828

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

31+
BUILT_SOURCES = core/compat.hh
32+
3133
bin_PROGRAMS = dnsjit
3234

3335
dnsjit_SOURCES = dnsjit.c globals.c \
@@ -43,7 +45,7 @@ lua_objects = core.luao lib.luao input.luao filter.luao output.luao
4345
dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS)
4446

4547
# C source and headers
46-
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
48+
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
4749
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
4850

4951
# Lua headers

src/core/compat.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2018, OARC, Inc.
3+
* All rights reserved.
4+
*
5+
* This file is part of dnsjit.
6+
*
7+
* dnsjit is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* dnsjit is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
#include "config.h"
22+
23+
#include <stdint.h>
24+
25+
#include "core/compat.hh"

src/gen-compat.lua

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
for line in io.lines("config.h") do
2-
local n,s = line:match("define SIZEOF_(PTHREAD%S*)_T (%d+)")
2+
local n, s = line:match("define SIZEOF_(%S*) (%d+)")
33
if n and s then
4-
s = math.ceil(s / 8)
5-
n = n:lower()
6-
print("typedef struct "..n.." { uint64_t a["..s.."]; } "..n.."_t;")
4+
if n:match("^PTHREAD") then
5+
s = math.ceil(s / 8)
6+
print("#if !defined(SIZEOF_"..n..") || SIZEOF_"..n.." == 0")
7+
print("#error \""..n.." is undefined or zero\"")
8+
print("#endif")
9+
n = n:lower()
10+
print("typedef struct "..n:sub(1,-3).." { uint64_t a["..s.."]; } "..n..";")
11+
elseif n:match("^STRUCT") then
12+
n = n:match("^STRUCT_(%S*)")
13+
if n == "SOCKADDR_STORAGE" then
14+
print("#if !defined(SIZEOF_STRUCT_"..n..") || SIZEOF_STRUCT_"..n.." == 0")
15+
print("#error \""..n.." is undefined or zero\"")
16+
print("#endif")
17+
n = n:lower()
18+
print("struct "..n.." { uint8_t a["..s.."]; };")
19+
end
20+
end
721
end
822
end

src/gen-makefile.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ AM_CFLAGS = -I$(srcdir) \
3030
3131
EXTRA_DIST = gen-manpage.lua gen-compat.lua dnsjit.1in
3232
33+
BUILT_SOURCES = core/compat.hh
34+
3335
bin_PROGRAMS = dnsjit
3436
3537
dnsjit_SOURCES = dnsjit.c globals.c \

src/output/tcpcli.c

Lines changed: 67 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,32 +31,58 @@
3131
#include <unistd.h>
3232
#include <fcntl.h>
3333
#include <string.h>
34-
#include <errno.h>
3534
#include <arpa/inet.h>
3635

3736
static core_log_t _log = LOG_T_INIT("output.tcpcli");
3837
static output_tcpcli_t _defaults = {
3938
LOG_T_INIT_OBJ("output.tcpcli"),
40-
0, 0, -1,
39+
0, 0, -1
4140
};
4241

4342
core_log_t* output_tcpcli_log()
4443
{
4544
return &_log;
4645
}
4746

48-
int output_tcpcli_init(output_tcpcli_t* self, const char* host, const char* port)
47+
int output_tcpcli_init(output_tcpcli_t* self)
48+
{
49+
if (!self) {
50+
return 1;
51+
}
52+
53+
*self = _defaults;
54+
55+
ldebug("init");
56+
57+
return 0;
58+
}
59+
60+
int output_tcpcli_destroy(output_tcpcli_t* self)
61+
{
62+
if (!self) {
63+
return 1;
64+
}
65+
66+
ldebug("destroy");
67+
68+
if (self->fd > -1) {
69+
shutdown(self->fd, SHUT_RDWR);
70+
close(self->fd);
71+
}
72+
73+
return 0;
74+
}
75+
76+
int output_tcpcli_connect(output_tcpcli_t* self, const char* host, const char* port)
4977
{
5078
struct addrinfo* addr;
5179
int err;
5280

53-
if (!self || !host || !port) {
81+
if (!self || self->fd > -1 || !host || !port) {
5482
return 1;
5583
}
5684

57-
*self = _defaults;
58-
59-
ldebug("init %s %s", host, port);
85+
ldebug("connect %s %s", host, port);
6086

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

90116
freeaddrinfo(addr);
117+
return 0;
118+
}
91119

92-
if ((err = fcntl(self->fd, F_GETFL)) == -1
93-
|| fcntl(self->fd, F_SETFL, err | O_NONBLOCK)) {
94-
lcritical("fcntl failed");
120+
int output_tcpcli_nonblocking(output_tcpcli_t* self)
121+
{
122+
int flags;
123+
124+
if (!self || self->fd < 0) {
125+
return -1;
95126
}
96127

97-
return 0;
128+
flags = fcntl(self->fd, F_GETFL);
129+
if (flags != -1) {
130+
flags = flags & O_NONBLOCK ? 1 : 0;
131+
}
132+
133+
return flags;
98134
}
99135

100-
int output_tcpcli_destroy(output_tcpcli_t* self)
136+
int output_tcpcli_set_nonblocking(output_tcpcli_t* self, int nonblocking)
101137
{
102-
if (!self) {
138+
int flags;
139+
140+
if (!self || self->fd < 0) {
103141
return 1;
104142
}
105143

106-
ldebug("destroy");
144+
ldebug("set nonblocking %d", nonblocking);
107145

108-
if (self->fd > -1) {
109-
shutdown(self->fd, SHUT_RDWR);
110-
close(self->fd);
146+
if ((flags = fcntl(self->fd, F_GETFL)) == -1) {
147+
lcritical("fcntl(FL_GETFL) failed");
148+
return 1;
149+
}
150+
151+
if (nonblocking) {
152+
if (fcntl(self->fd, F_SETFL, flags | O_NONBLOCK)) {
153+
lcritical("fcntl(FL_SETFL) failed");
154+
return 1;
155+
}
156+
} else {
157+
if (fcntl(self->fd, F_SETFL, flags & ~O_NONBLOCK)) {
158+
lcritical("fcntl(FL_SETFL) failed");
159+
return 1;
160+
}
111161
}
112162

113163
return 0;
@@ -166,29 +216,11 @@ static int _receive(void* ctx, const core_object_t* obj)
166216
continue;
167217
return 0;
168218
}
169-
switch (errno) {
170-
case EAGAIN:
171-
#if EAGAIN != EWOULDBLOCK
172-
case EWOULDBLOCK:
173-
#endif
174-
continue;
175-
default:
176-
break;
177-
}
178219
self->errs++;
179220
break;
180221
}
181222
break;
182223
}
183-
switch (errno) {
184-
case EAGAIN:
185-
#if EAGAIN != EWOULDBLOCK
186-
case EWOULDBLOCK:
187-
#endif
188-
continue;
189-
default:
190-
break;
191-
}
192224
self->errs++;
193225
break;
194226
}

src/output/tcpcli.hh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ typedef struct output_tcpcli {
2929

3030
core_log_t* output_tcpcli_log();
3131

32-
int output_tcpcli_init(output_tcpcli_t* self, const char* host, const char* port);
32+
int output_tcpcli_init(output_tcpcli_t* self);
3333
int output_tcpcli_destroy(output_tcpcli_t* self);
34+
int output_tcpcli_connect(output_tcpcli_t* self, const char* host, const char* port);
35+
int output_tcpcli_nonblocking(output_tcpcli_t* self);
36+
int output_tcpcli_set_nonblocking(output_tcpcli_t* self, int nonblocking);
3437

3538
core_receiver_t output_tcpcli_receiver();

src/output/tcpcli.lua

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,50 @@ local t_name = "output_tcpcli_t"
3333
local output_tcpcli_t = ffi.typeof(t_name)
3434
local Tcpcli = {}
3535

36-
-- Create a new Tcpcli output to send queries to the
36+
-- Create a new Tcpcli output. Optinally connect to the
3737
-- .I host
3838
-- and
39-
-- .IR port .
39+
-- .IR port right away or use
40+
-- .BR connect ()
41+
-- later on.
4042
function Tcpcli.new(host, port)
4143
local self = {
4244
obj = output_tcpcli_t(),
4345
}
44-
C.output_tcpcli_init(self.obj, host, port)
46+
C.output_tcpcli_init(self.obj)
4547
ffi.gc(self.obj, C.output_tcpcli_destroy)
46-
return setmetatable(self, { __index = Tcpcli })
48+
self = setmetatable(self, { __index = Tcpcli })
49+
if host and port then
50+
if self:connect(host, port) ~= 0 then
51+
return
52+
end
53+
end
54+
return self
55+
end
56+
57+
-- Connect to the
58+
-- .I host
59+
-- and
60+
-- .IR port .
61+
function Tcpcli.connect(host, port)
62+
return C.output_tcpcli_connect(self.obj, host, port)
63+
end
64+
65+
-- Enable (true) or disable (false) nonblocking mode and
66+
-- return 0 if successful, if
67+
-- .I bool
68+
-- is not specified then return if nonblocking mode is on (true) or off (false).
69+
function Tcpcli.nonblocking(bool)
70+
if bool == nil then
71+
if C.output_tcpcli_nonblocking(self.obj) == 1 then
72+
return true
73+
end
74+
return false
75+
elseif bool == true then
76+
return C.output_tcpcli_set_nonblocking(self.obj, 1)
77+
else
78+
return C.output_tcpcli_set_nonblocking(self.obj, 0)
79+
end
4780
end
4881

4982
-- Return the C functions and context for receiving objects.

0 commit comments

Comments
 (0)