@@ -168,7 +168,7 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) {
168168}
169169
170170
171- use self :: ffi:: { cmsghdr, msghdr, type_of_cmsg_len , type_of_cmsg_data } ;
171+ use self :: ffi:: { cmsghdr, msghdr, type_of_cmsg_data , type_of_msg_iovlen , type_of_cmsg_len } ;
172172
173173/// A structure used to make room in a cmsghdr passed to recvmsg. The
174174/// size and alignment match that of a cmsghdr followed by a T, but the
@@ -204,11 +204,17 @@ impl<'a> RecvMsg<'a> {
204204 /// Iterate over the valid control messages pointed to by this
205205 /// msghdr.
206206 pub fn cmsgs ( & self ) -> CmsgIterator {
207- CmsgIterator ( self . cmsg_buffer )
207+ CmsgIterator {
208+ buf : self . cmsg_buffer ,
209+ next : 0
210+ }
208211 }
209212}
210213
211- pub struct CmsgIterator < ' a > ( & ' a [ u8 ] ) ;
214+ pub struct CmsgIterator < ' a > {
215+ buf : & ' a [ u8 ] ,
216+ next : usize ,
217+ }
212218
213219impl < ' a > Iterator for CmsgIterator < ' a > {
214220 type Item = ControlMessage < ' a > ;
@@ -217,12 +223,11 @@ impl<'a> Iterator for CmsgIterator<'a> {
217223 // although we handle the invariants in slightly different places to
218224 // get a better iterator interface.
219225 fn next ( & mut self ) -> Option < ControlMessage < ' a > > {
220- let buf = self . 0 ;
221226 let sizeof_cmsghdr = mem:: size_of :: < cmsghdr > ( ) ;
222- if buf. len ( ) < sizeof_cmsghdr {
227+ if self . buf . len ( ) < sizeof_cmsghdr {
223228 return None ;
224229 }
225- let cmsg: & cmsghdr = unsafe { mem:: transmute ( buf. as_ptr ( ) ) } ;
230+ let cmsg: & cmsghdr = unsafe { mem:: transmute ( self . buf . as_ptr ( ) ) } ;
226231
227232 // This check is only in the glibc implementation of CMSG_NXTHDR
228233 // (although it claims the kernel header checks this), but such
@@ -232,12 +237,20 @@ impl<'a> Iterator for CmsgIterator<'a> {
232237 return None ;
233238 }
234239 let len = cmsg_len - sizeof_cmsghdr;
240+ let aligned_cmsg_len = if self . next == 0 {
241+ // CMSG_FIRSTHDR
242+ cmsg_len
243+ } else {
244+ // CMSG_NXTHDR
245+ cmsg_align ( cmsg_len)
246+ } ;
235247
236248 // Advance our internal pointer.
237- if cmsg_align ( cmsg_len ) > buf. len ( ) {
249+ if aligned_cmsg_len > self . buf . len ( ) {
238250 return None ;
239251 }
240- self . 0 = & buf[ cmsg_align ( cmsg_len) ..] ;
252+ self . buf = & self . buf [ aligned_cmsg_len..] ;
253+ self . next += 1 ;
241254
242255 match ( cmsg. cmsg_level , cmsg. cmsg_type ) {
243256 ( libc:: SOL_SOCKET , libc:: SCM_RIGHTS ) => unsafe {
@@ -370,9 +383,9 @@ pub fn sendmsg<'a>(fd: RawFd, iov: &[IoVec<&'a [u8]>], cmsgs: &[ControlMessage<'
370383 msg_name : name as * const c_void ,
371384 msg_namelen : namelen,
372385 msg_iov : iov. as_ptr ( ) ,
373- msg_iovlen : iov. len ( ) as size_t ,
386+ msg_iovlen : iov. len ( ) as type_of_msg_iovlen ,
374387 msg_control : cmsg_ptr,
375- msg_controllen : capacity as size_t ,
388+ msg_controllen : capacity as type_of_cmsg_len ,
376389 msg_flags : 0 ,
377390 } ;
378391 let ret = unsafe { ffi:: sendmsg ( fd, & mhdr, flags. bits ( ) ) } ;
@@ -393,9 +406,9 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
393406 msg_name : & mut address as * const _ as * const c_void ,
394407 msg_namelen : mem:: size_of :: < sockaddr_storage > ( ) as socklen_t ,
395408 msg_iov : iov. as_ptr ( ) as * const IoVec < & [ u8 ] > , // safe cast to add const-ness
396- msg_iovlen : iov. len ( ) as size_t ,
409+ msg_iovlen : iov. len ( ) as type_of_msg_iovlen ,
397410 msg_control : msg_control as * const c_void ,
398- msg_controllen : msg_controllen as size_t ,
411+ msg_controllen : msg_controllen as type_of_cmsg_len ,
399412 msg_flags : 0 ,
400413 } ;
401414 let ret = unsafe { ffi:: recvmsg ( fd, & mut mhdr, flags. bits ( ) ) } ;
0 commit comments