Skip to content

Commit 305e9f5

Browse files
committed
HevSocks5Worker: Refactor to support receiving multiple UDP packets.
1 parent b182405 commit 305e9f5

File tree

1 file changed

+84
-28
lines changed

1 file changed

+84
-28
lines changed

src/hev-socks5-worker.c

Lines changed: 84 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
============================================================================
88
*/
99

10+
#define _GNU_SOURCE
1011
#include <stdlib.h>
1112
#include <string.h>
1213
#include <unistd.h>
@@ -179,28 +180,64 @@ hev_socks5_udp_recvmsg (HevSocks5Worker *self, int fd, struct sockaddr *saddr,
179180
char buf[CMSG_SPACE (sizeof (struct sockaddr_in6))];
180181
struct cmsghdr align;
181182
} u;
182-
struct msghdr mh = { 0 };
183+
struct msghdr mh;
183184
struct iovec iov;
184185
int res;
185186

186-
iov.iov_base = buf;
187-
iov.iov_len = len;
188187
mh.msg_iov = &iov;
189188
mh.msg_iovlen = 1;
190189
mh.msg_name = saddr;
191190
mh.msg_namelen = sizeof (struct sockaddr_in6);
192191
mh.msg_control = u.buf;
193192
mh.msg_controllen = sizeof (u.buf);
194193

194+
iov.iov_base = buf;
195+
iov.iov_len = len;
196+
195197
res = hev_task_io_socket_recvmsg (fd, &mh, 0, task_io_yielder, self);
196-
if (res < 0)
198+
if (res <= 0)
197199
return res;
198200

199201
msg_to_sock_addr (&mh, daddr);
200202

201203
return res;
202204
}
203205

206+
static int
207+
_hev_socks5_udp_recvmmsg (HevSocks5Worker *self, int fd,
208+
struct sockaddr_in6 *saddr,
209+
struct sockaddr_in6 *daddr, struct iovec *iov,
210+
int num)
211+
{
212+
union
213+
{
214+
char buf[CMSG_SPACE (sizeof (struct sockaddr_in6))];
215+
struct cmsghdr align;
216+
} u[num];
217+
struct mmsghdr msgv[num];
218+
int i, res;
219+
220+
for (i = 0; i < num; i++) {
221+
msgv[i].msg_hdr.msg_iov = &iov[i];
222+
msgv[i].msg_hdr.msg_iovlen = 1;
223+
msgv[i].msg_hdr.msg_name = &saddr[i];
224+
msgv[i].msg_hdr.msg_namelen = sizeof (struct sockaddr_in6);
225+
msgv[i].msg_hdr.msg_control = u[i].buf;
226+
msgv[i].msg_hdr.msg_controllen = sizeof (u[i].buf);
227+
}
228+
229+
res = hev_task_io_socket_recvmmsg (fd, msgv, num, 0, task_io_yielder, self);
230+
if (res <= 0)
231+
return res;
232+
233+
for (i = 0; i < res; i++) {
234+
msg_to_sock_addr (&msgv[i].msg_hdr, (struct sockaddr *)&daddr[i]);
235+
iov[i].iov_len = msgv[i].msg_len;
236+
}
237+
238+
return res;
239+
}
240+
204241
static HevSocks5SessionUDP *
205242
hev_socks5_udp_session_find (HevSocks5Worker *self, struct sockaddr *addr)
206243
{
@@ -318,7 +355,7 @@ hev_socks5_udp_task_entry (void *data)
318355
HevRBTreeNode *node;
319356
const char *addr;
320357
const char *port;
321-
int fd;
358+
int fd, num;
322359

323360
LOG_D ("socks5 udp task run");
324361

@@ -331,33 +368,52 @@ hev_socks5_udp_task_entry (void *data)
331368
if (fd < 0)
332369
goto exit;
333370

371+
num = hev_config_get_misc_udp_copy_buffer_nums ();
334372
hev_task_add_fd (hev_task_self (), fd, POLLIN);
335373

336-
for (;;) {
337-
struct sockaddr_in6 saddr = { 0 };
338-
struct sockaddr_in6 daddr = { 0 };
339-
struct sockaddr *sap;
340-
struct sockaddr *dap;
341-
void *buf;
342-
int res;
343-
344-
buf = hev_malloc (UDP_BUF_SIZE);
345-
sap = (struct sockaddr *)&saddr;
346-
dap = (struct sockaddr *)&daddr;
347-
348-
res = hev_socks5_udp_recvmsg (self, fd, sap, dap, buf, UDP_BUF_SIZE);
349-
if (res == -1 || res == 0) {
350-
LOG_W ("socks5 udp recvmsg");
351-
hev_free (buf);
352-
continue;
353-
} else if (res < 0) {
354-
hev_free (buf);
355-
break;
374+
{
375+
struct iovec iov[num];
376+
int i;
377+
378+
for (i = 0; i < num; i++)
379+
iov[i].iov_base = NULL;
380+
381+
for (;;) {
382+
struct sockaddr_in6 saddr[num];
383+
struct sockaddr_in6 daddr[num];
384+
int res;
385+
386+
for (i = 0; i < num; i++) {
387+
if (!iov[i].iov_base) {
388+
iov[i].iov_base = hev_malloc (UDP_BUF_SIZE);
389+
iov[i].iov_len = UDP_BUF_SIZE;
390+
}
391+
}
392+
393+
res = _hev_socks5_udp_recvmmsg (self, fd, saddr, daddr, iov, num);
394+
if (res == -1 || res == 0) {
395+
LOG_W ("socks5 udp recvmmsg");
396+
continue;
397+
} else if (res < 0) {
398+
break;
399+
}
400+
401+
for (i = 0; i < res; i++) {
402+
struct sockaddr *sap = (struct sockaddr *)&saddr[i];
403+
struct sockaddr *dap = (struct sockaddr *)&daddr[i];
404+
int ret;
405+
406+
ret = hev_socks5_udp_dispatch (self, sap, dap, iov[i].iov_base,
407+
iov[i].iov_len);
408+
if (ret >= 0)
409+
iov[i].iov_base = NULL;
410+
}
356411
}
357412

358-
res = hev_socks5_udp_dispatch (self, sap, dap, buf, res);
359-
if (res < 0)
360-
hev_free (buf);
413+
for (i = 0; i < num; i++) {
414+
if (iov[i].iov_base)
415+
hev_free (iov[i].iov_base);
416+
}
361417
}
362418

363419
node = hev_rbtree_first (&self->udp_set);

0 commit comments

Comments
 (0)