@@ -40,6 +40,14 @@ fn check_socket(sock: SOCKET) -> Result<SOCKET> {
40
40
return Ok ( sock) ;
41
41
}
42
42
43
+ // XXX: Until getsockopt is available in libc crate
44
+ extern "system" {
45
+ #[ cfg( target_os="linux" ) ]
46
+ fn getsockopt ( sock : SOCKET , level : libc:: c_int , optname : libc:: c_int , optval : * mut libc:: c_void , optlen : * mut libc:: socklen_t ) -> libc:: c_int ;
47
+ #[ cfg( target_os="windows" ) ]
48
+ fn getsockopt ( sock : SOCKET , level : libc:: c_int , optname : libc:: c_int , optval : * mut libc:: c_char , optlen : * mut libc:: c_int ) -> libc:: c_int ;
49
+ }
50
+
43
51
/// SCTP bind operation
44
52
#[ allow( dead_code) ]
45
53
pub enum BindOp {
@@ -170,6 +178,33 @@ impl SctpSocket {
170
178
}
171
179
}
172
180
181
+ /// Connect the socket to multiple addresses
182
+ pub fn connectx < A : ToSocketAddrs > ( & self , addresses : & [ A ] ) -> Result < sctp_sys:: sctp_assoc_t > {
183
+ if addresses. len ( ) == 0 { return Err ( Error :: new ( ErrorKind :: InvalidInput , "No addresses given" ) ) ; }
184
+ unsafe {
185
+ let buf: * mut u8 = libc:: malloc ( ( addresses. len ( ) * size_of :: < libc:: sockaddr_in6 > ( ) ) as u64 ) as * mut u8 ;
186
+ if buf. is_null ( ) {
187
+ return Err ( Error :: new ( ErrorKind :: Other , "Out of memory" ) ) ;
188
+ }
189
+ let mut offset = 0isize ;
190
+ for address in addresses {
191
+ let raw = try!( SocketAddr :: from_addr ( address) ) ;
192
+ let len = raw. addr_len ( ) ;
193
+ std:: ptr:: copy_nonoverlapping ( raw. as_ptr ( ) as * mut u8 , buf. offset ( offset) , len as usize ) ;
194
+ offset += len as isize ;
195
+ }
196
+
197
+ let mut assoc: sctp_sys:: sctp_assoc_t = 0 ;
198
+ if sctp_sys:: sctp_connectx ( self . 0 , buf as * mut libc:: sockaddr , addresses. len ( ) as i32 , & mut assoc) != 0 {
199
+ let err = Error :: last_os_error ( ) ;
200
+ libc:: free ( buf as * mut libc:: c_void ) ;
201
+ return Err ( err) ;
202
+ }
203
+ libc:: free ( buf as * mut libc:: c_void ) ;
204
+ return Ok ( assoc) ;
205
+ }
206
+ }
207
+
173
208
/// Bind the socket on multiple addresses
174
209
pub fn bindx < A : ToSocketAddrs > ( & self , addresses : & [ A ] , op : BindOp ) -> Result < ( ) > {
175
210
if addresses. len ( ) == 0 { return Err ( Error :: new ( ErrorKind :: InvalidInput , "No addresses given" ) ) ; }
@@ -325,18 +360,30 @@ impl SctpSocket {
325
360
} ;
326
361
}
327
362
328
- /// Set SCTP socket option
329
- pub fn setsockopt < T > ( & self , optname : libc:: c_int , optval : & T ) -> Result < ( ) > {
363
+ /// Set socket option
364
+ pub fn setsockopt < T > ( & self , level : libc :: c_int , optname : libc:: c_int , optval : & T ) -> Result < ( ) > {
330
365
unsafe {
331
- return match libc:: setsockopt ( self . 0 , sctp_sys :: SOL_SCTP , optname, transmute ( optval) , size_of :: < T > ( ) as libc:: socklen_t ) {
366
+ return match libc:: setsockopt ( self . 0 , level , optname, transmute ( optval) , size_of :: < T > ( ) as libc:: socklen_t ) {
332
367
0 => Ok ( ( ) ) ,
333
368
_ => Err ( Error :: last_os_error ( ) )
334
369
} ;
335
370
}
336
371
}
337
372
373
+ /// Get socket option
374
+ pub fn getsockopt < T > ( & self , level : libc:: c_int , optname : libc:: c_int ) -> Result < T > {
375
+ unsafe {
376
+ let mut val: T = zeroed ( ) ;
377
+ let mut len = size_of :: < T > ( ) as libc:: socklen_t ;
378
+ return match getsockopt ( self . 0 , level, optname, transmute ( & mut val) , & mut len) {
379
+ 0 => Ok ( val) ,
380
+ _ => Err ( Error :: last_os_error ( ) )
381
+ } ;
382
+ }
383
+ }
384
+
338
385
/// Get SCTP socket option
339
- pub fn getsockopt < T > ( & self , optname : libc:: c_int , assoc : sctp_sys:: sctp_assoc_t ) -> Result < T > {
386
+ pub fn sctp_opt_info < T > ( & self , optname : libc:: c_int , assoc : sctp_sys:: sctp_assoc_t ) -> Result < T > {
340
387
unsafe {
341
388
let mut val: T = zeroed ( ) ;
342
389
let mut len = size_of :: < T > ( ) as libc:: socklen_t ;
@@ -347,7 +394,6 @@ impl SctpSocket {
347
394
}
348
395
}
349
396
350
-
351
397
/// Try to clone this socket
352
398
pub fn try_clone ( & self ) -> Result < SctpSocket > {
353
399
unsafe {
0 commit comments