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+
204241static HevSocks5SessionUDP *
205242hev_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