@@ -198,9 +198,12 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
198
198
let mut msgs: [ libc:: mmsghdr ; BATCH_SIZE ] = unsafe { mem:: zeroed ( ) } ;
199
199
let mut iovecs: [ libc:: iovec ; BATCH_SIZE ] = unsafe { mem:: zeroed ( ) } ;
200
200
let mut cmsgs = [ cmsg:: Aligned ( [ 0u8 ; CMSG_LEN ] ) ; BATCH_SIZE ] ;
201
+ let mut addrs: [ CSocketAddr ; BATCH_SIZE ] = unsafe { mem:: zeroed ( ) } ;
201
202
for ( i, transmit) in transmits. iter ( ) . enumerate ( ) . take ( BATCH_SIZE ) {
203
+ addrs[ i] = CSocketAddr :: from_socket_addr ( transmit. destination ) ;
202
204
prepare_msg (
203
205
transmit,
206
+ & mut addrs[ i] ,
204
207
& mut msgs[ i] . msg_hdr ,
205
208
& mut iovecs[ i] ,
206
209
& mut cmsgs[ i] ,
@@ -233,7 +236,8 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
233
236
let mut ctrl = cmsg:: Aligned ( [ 0u8 ; CMSG_LEN ] ) ;
234
237
let mut sent = 0 ;
235
238
while sent < transmits. len ( ) {
236
- prepare_msg ( & transmits[ sent] , & mut hdr, & mut iov, & mut ctrl) ;
239
+ let mut addr = CSocketAddr :: from_socket_addr ( transmits[ sent] . destination ) ;
240
+ prepare_msg ( & transmits[ sent] , & mut addr, & mut hdr, & mut iov, & mut ctrl) ;
237
241
let n = unsafe { libc:: sendmsg ( io. as_raw_fd ( ) , & hdr, 0 ) } ;
238
242
if n == -1 {
239
243
let e = io:: Error :: last_os_error ( ) ;
@@ -338,19 +342,58 @@ fn in_addr(addr: &Ipv4Addr) -> libc::in_addr {
338
342
}
339
343
}
340
344
345
+ enum CSocketAddr {
346
+ V4 ( libc:: sockaddr_in ) ,
347
+ V6 ( libc:: sockaddr_in6 ) ,
348
+ }
349
+
350
+ impl CSocketAddr {
351
+ fn from_socket_addr ( addr : SocketAddr ) -> Self {
352
+ match addr {
353
+ SocketAddr :: V4 ( s) => CSocketAddr :: V4 ( libc:: sockaddr_in {
354
+ sin_family : libc:: AF_INET as _ ,
355
+ sin_port : s. port ( ) . to_be ( ) ,
356
+ sin_addr : in_addr ( s. ip ( ) ) ,
357
+ sin_zero : [ 0 ; 8 ] ,
358
+ #[ cfg( any( target_os = "freebsd" , target_os = "ios" , target_os = "macos" ) ) ]
359
+ sin_len : 0 ,
360
+ } ) ,
361
+ SocketAddr :: V6 ( s) => CSocketAddr :: V6 ( libc:: sockaddr_in6 {
362
+ sin6_family : libc:: AF_INET6 as _ ,
363
+ sin6_port : s. port ( ) . to_be ( ) ,
364
+ sin6_flowinfo : s. flowinfo ( ) ,
365
+ sin6_addr : libc:: in6_addr {
366
+ s6_addr : s. ip ( ) . octets ( ) ,
367
+ } ,
368
+ sin6_scope_id : s. scope_id ( ) ,
369
+ } ) ,
370
+ }
371
+ }
372
+ fn ptr_and_len ( & mut self ) -> ( * mut libc:: c_void , usize ) {
373
+ match self {
374
+ CSocketAddr :: V4 ( ref mut addr) => (
375
+ addr as * mut _ as * mut _ ,
376
+ mem:: size_of :: < libc:: sockaddr_in > ( ) ,
377
+ ) ,
378
+ CSocketAddr :: V6 ( ref mut addr) => (
379
+ addr as * mut _ as * mut _ ,
380
+ mem:: size_of :: < libc:: sockaddr_in6 > ( ) ,
381
+ ) ,
382
+ }
383
+ }
384
+ }
385
+
341
386
fn prepare_msg (
342
387
transmit : & Transmit ,
388
+ dest_addr : & mut CSocketAddr ,
343
389
hdr : & mut libc:: msghdr ,
344
390
iov : & mut libc:: iovec ,
345
391
ctrl : & mut cmsg:: Aligned < [ u8 ; CMSG_LEN ] > ,
346
392
) {
347
393
iov. iov_base = transmit. contents . as_ptr ( ) as * const _ as * mut _ ;
348
394
iov. iov_len = transmit. contents . len ( ) ;
349
395
350
- let ( name, namelen) = match transmit. destination {
351
- SocketAddr :: V4 ( ref addr) => ( addr as * const _ as _ , mem:: size_of :: < libc:: sockaddr_in > ( ) ) ,
352
- SocketAddr :: V6 ( ref addr) => ( addr as * const _ as _ , mem:: size_of :: < libc:: sockaddr_in6 > ( ) ) ,
353
- } ;
396
+ let ( name, namelen) = dest_addr. ptr_and_len ( ) ;
354
397
hdr. msg_name = name;
355
398
hdr. msg_namelen = namelen as _ ;
356
399
hdr. msg_iov = iov;
0 commit comments