77 ============================================================================
88 */
99
10+ #define _GNU_SOURCE
1011#include <errno.h>
1112#include <string.h>
1213#include <unistd.h>
@@ -103,28 +104,49 @@ static int
103104hev_socks5_session_udp_fwd_b (HevSocks5SessionUDP * self , unsigned int num )
104105{
105106 char buf [UDP_BUF_SIZE * num ];
106- HevSocks5UDPMsg msgv [num ];
107+ HevSocks5UDPMsg smv [num ];
107108 int i , res ;
109+ int s = 0 ;
108110
109111 for (i = 0 ; i < num ; i ++ ) {
110- msgv [i ].buf = buf + UDP_BUF_SIZE * i ;
111- msgv [i ].len = UDP_BUF_SIZE ;
112+ smv [i ].buf = buf + UDP_BUF_SIZE * i ;
113+ smv [i ].len = UDP_BUF_SIZE ;
112114 }
113115
114- res = hev_socks5_udp_recvmmsg (HEV_SOCKS5_UDP (self ), msgv , num , 1 );
116+ res = hev_socks5_udp_recvmmsg (HEV_SOCKS5_UDP (self ), smv , num , 1 );
115117 if (res <= 0 ) {
116118 if (res == -1 && errno == EAGAIN )
117119 return 0 ;
118120 LOG_D ("%p socks5 session udp fwd b recv" , self );
119121 return -1 ;
120122 }
121123
122- for ( i = 0 ; i < res ; i ++ ) {
124+ while ( s < res ) {
123125 struct sockaddr_in6 saddr ;
124- int ret , fd , family ;
126+ struct mmsghdr dmv [res ];
127+ struct iovec iov [res ];
128+ int fd , f , n , r ;
129+
130+ for (i = s , n = 0 ; i < res ; i ++ ) {
131+ dmv [n ].msg_hdr .msg_name = & self -> addr ;
132+ dmv [n ].msg_hdr .msg_namelen = sizeof (self -> addr );
133+ dmv [n ].msg_hdr .msg_controllen = 0 ;
134+ dmv [n ].msg_hdr .msg_iov = & iov [n ];
135+ dmv [n ].msg_hdr .msg_iovlen = 1 ;
136+ iov [n ].iov_base = smv [i ].buf ;
137+ iov [n ].iov_len = smv [i ].len ;
138+
139+ if (n ++ == 0 )
140+ continue ;
141+
142+ r = hev_socks5_addr_len (smv [i ].addr );
143+ r = memcmp (smv [0 ].addr , smv [i ].addr , r );
144+ if (r )
145+ break ;
146+ }
125147
126- ret = hev_socks5_addr_into_sockaddr6 (msgv [ i ].addr , & saddr , & family );
127- if (ret < 0 ) {
148+ r = hev_socks5_addr_into_sockaddr6 (smv [ s ].addr , & saddr , & f );
149+ if (r < 0 ) {
128150 LOG_D ("%p socks5 session udp fwd b addr" , self );
129151 return -1 ;
130152 }
@@ -135,13 +157,15 @@ hev_socks5_session_udp_fwd_b (HevSocks5SessionUDP *self, unsigned int num)
135157 return -1 ;
136158 }
137159
138- ret = sendto ( fd , msgv [ i ]. buf , msgv [ i ]. len , 0 ,
139- ( struct sockaddr * ) & self -> addr , sizeof ( self -> addr ) );
160+ f = MSG_DONTWAIT | MSG_WAITALL ;
161+ r = hev_task_io_socket_sendmmsg ( fd , dmv , n , f , NULL , NULL );
140162 hev_tsocks_cache_put (fd );
141- if (ret <= 0 ) {
163+ if (r <= 0 ) {
142164 LOG_D ("%p socks5 session udp fwd b send" , self );
143165 return -1 ;
144166 }
167+
168+ s += n ;
145169 }
146170
147171 return 1 ;
0 commit comments