Skip to content

Commit 0acfc3e

Browse files
authored
Merge pull request #59 from jelu/udpcli
UDP client
2 parents fffb397 + 983fc72 commit 0acfc3e

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

src/output/udpcli.c

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
#include "config.h"
2222

2323
#include "output/udpcli.h"
24+
#include "core/object/dns.h"
2425
#include "core/object/udp.h"
26+
#include "core/object/tcp.h"
2527

2628
#include <sys/types.h>
2729
#include <sys/socket.h>
@@ -30,6 +32,7 @@
3032
#include <fcntl.h>
3133
#include <string.h>
3234
#include <netinet/in.h>
35+
#include <errno.h>
3336

3437
static core_log_t _log = LOG_T_INIT("output.udpcli");
3538
static output_udpcli_t _defaults = {
@@ -110,23 +113,61 @@ int output_udpcli_destroy(output_udpcli_t* self)
110113

111114
static int _receive(void* ctx, const core_object_t* obj)
112115
{
113-
output_udpcli_t* self = (output_udpcli_t*)ctx;
114-
core_object_udp_t* udp = (core_object_udp_t*)obj;
116+
output_udpcli_t* self = (output_udpcli_t*)ctx;
117+
const uint8_t* payload;
118+
size_t len, sent;
115119

116-
if (!self || !obj || obj->obj_type != CORE_OBJECT_UDP) {
120+
if (!self) {
117121
return 1;
118122
}
119123

120-
if (udp->len < 3 || udp->payload[2] & 0x80) {
121-
return 0;
122-
}
123-
124-
self->pkts++;
125-
if (sendto(self->fd, udp->payload, udp->len, 0, (struct sockaddr*)self->addr, self->addr_len) < 0) {
126-
self->errs++;
124+
for (; obj;) {
125+
switch (obj->obj_type) {
126+
case CORE_OBJECT_DNS:
127+
obj = obj->obj_prev;
128+
continue;
129+
case CORE_OBJECT_UDP:
130+
payload = ((core_object_udp_t*)obj)->payload;
131+
len = ((core_object_udp_t*)obj)->len;
132+
break;
133+
case CORE_OBJECT_TCP:
134+
payload = ((core_object_tcp_t*)obj)->payload;
135+
len = ((core_object_tcp_t*)obj)->len;
136+
break;
137+
default:
138+
return 1;
139+
}
140+
141+
if (len < 3 || payload[2] & 0x80) {
142+
return 0;
143+
}
144+
145+
sent = 0;
146+
self->pkts++;
147+
for (;;) {
148+
ssize_t ret = sendto(self->fd, payload + sent, len - sent, 0, (struct sockaddr*)self->addr, self->addr_len);
149+
if (ret > -1) {
150+
sent += ret;
151+
if (sent < len)
152+
continue;
153+
return 0;
154+
}
155+
switch (errno) {
156+
case EAGAIN:
157+
#if EAGAIN != EWOULDBLOCK
158+
case EWOULDBLOCK:
159+
#endif
160+
continue;
161+
default:
162+
break;
163+
}
164+
self->errs++;
165+
break;
166+
}
167+
break;
127168
}
128169

129-
return 0;
170+
return 1;
130171
}
131172

132173
core_receiver_t output_udpcli_receiver()

0 commit comments

Comments
 (0)