1
+ //! This crate provides high level SCTP networking.
2
+ //! Currently it only supports basic SCTP features like multi-homing
3
+ //! in one-to-one and one-to-many associations.
4
+ //! SCTP notifications and working directly on associtaion is not supported yet
5
+ //! but is in the TODO list.
6
+
1
7
extern crate sctp_sys;
2
8
extern crate libc;
3
9
@@ -14,9 +20,11 @@ use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
14
20
#[ cfg( target_os="windows" ) ]
15
21
use std:: os:: windows:: io:: { AsRawHandle , RawHandle , FromRawHandle } ;
16
22
17
-
23
+ /// Socket buffer type
18
24
pub enum SoBuffer {
25
+ /// RCV buffer
19
26
Receive ,
27
+ /// SND buffer
20
28
Send
21
29
}
22
30
@@ -44,7 +52,7 @@ impl SctpStream {
44
52
return Ok ( SctpStream ( sock) ) ;
45
53
}
46
54
47
- /// Create a new stream by connecting it to a remote endpoint
55
+ /// Create a new stream by connecting it to a remote endpoint having multiple addresses
48
56
pub fn connectx < A : ToSocketAddrs > ( addresses : & [ A ] ) -> Result < SctpStream > {
49
57
if addresses. len ( ) == 0 { return Err ( Error :: new ( ErrorKind :: InvalidInput , "No addresses given" ) ) ; }
50
58
let mut vec = Vec :: with_capacity ( addresses. len ( ) ) ;
@@ -164,18 +172,21 @@ impl FromRawFd for SctpStream {
164
172
}
165
173
166
174
167
- /// One-to-many SCTP stream .
168
- pub struct SctpDatagram ( SctpSocket ) ;
175
+ /// One-to-many SCTP endpoint .
176
+ pub struct SctpEndpoint ( SctpSocket ) ;
169
177
170
- impl SctpDatagram {
178
+ impl SctpEndpoint {
171
179
172
- /// Create a one-to-many SCTP socket bound to a single address
173
- pub fn bind < A : ToSocketAddrs > ( address : A ) -> Result < SctpDatagram > {
174
- return Self :: bindx ( & [ address] ) ;
180
+ /// Create a one-to-many SCTP endpoint bound to a single address
181
+ pub fn bind < A : ToSocketAddrs > ( address : A ) -> Result < SctpEndpoint > {
182
+ let raw_addr = try!( SocketAddr :: from_addr ( & address) ) ;
183
+ let sock = try!( SctpSocket :: new ( raw_addr. family ( ) , libc:: SOCK_STREAM ) ) ;
184
+ try!( sock. bind ( raw_addr) ) ;
185
+ return Ok ( SctpEndpoint ( sock) ) ;
175
186
}
176
187
177
- /// Create a one-to-many SCTP socket bound to a multiple addresses. Requires at least one address
178
- pub fn bindx < A : ToSocketAddrs > ( addresses : & [ A ] ) -> Result < SctpDatagram > {
188
+ /// Create a one-to-many SCTP endpoint bound to a multiple addresses. Requires at least one address
189
+ pub fn bindx < A : ToSocketAddrs > ( addresses : & [ A ] ) -> Result < SctpEndpoint > {
179
190
if addresses. len ( ) == 0 { return Err ( Error :: new ( ErrorKind :: InvalidInput , "No addresses given" ) ) ; }
180
191
let mut vec = Vec :: with_capacity ( addresses. len ( ) ) ;
181
192
let mut family = libc:: AF_INET ;
@@ -188,7 +199,7 @@ impl SctpDatagram {
188
199
let sock = try!( SctpSocket :: new ( family, SOCK_SEQPACKET ) ) ;
189
200
try!( sock. bindx ( & vec, BindOp :: AddAddr ) ) ;
190
201
try!( sock. listen ( -1 ) ) ;
191
- return Ok ( SctpDatagram ( sock) ) ;
202
+ return Ok ( SctpEndpoint ( sock) ) ;
192
203
}
193
204
194
205
/// Wait for data to be received. On success, returns a triplet containing
@@ -200,7 +211,7 @@ impl SctpDatagram {
200
211
201
212
/// Send data in Sctp style, to the provided address on the stream `stream`.
202
213
/// On success, returns the quantity on bytes sent
203
- pub fn send_to < A : ToSocketAddrs > ( & self , msg : & mut [ u8 ] , address : A , stream : u16 , ) -> Result < usize > {
214
+ pub fn send_to < A : ToSocketAddrs > ( & self , msg : & mut [ u8 ] , address : A , stream : u16 ) -> Result < usize > {
204
215
return self . 0 . sendmsg ( msg, Some ( address) , stream, 0 ) ;
205
216
}
206
217
@@ -210,36 +221,36 @@ impl SctpDatagram {
210
221
}
211
222
212
223
/// Try to clone this socket
213
- pub fn try_clone ( & self ) -> Result < SctpDatagram > {
214
- return Ok ( SctpDatagram ( try!( self . 0 . try_clone ( ) ) ) ) ;
224
+ pub fn try_clone ( & self ) -> Result < SctpEndpoint > {
225
+ return Ok ( SctpEndpoint ( try!( self . 0 . try_clone ( ) ) ) ) ;
215
226
}
216
227
}
217
228
218
229
#[ cfg( target_os="windows" ) ]
219
- impl AsRawHandle for SctpDatagram {
230
+ impl AsRawHandle for SctpEndpoint {
220
231
fn as_raw_handle ( & self ) -> RawHandle {
221
232
return return self . 0 . as_raw_handle ( ) ;
222
233
}
223
234
}
224
235
225
236
#[ cfg( target_os="windows" ) ]
226
- impl FromRawHandle for SctpDatagram {
227
- unsafe fn from_raw_handle ( hdl : RawHandle ) -> SctpDatagram {
228
- return SctpDatagram ( SctpSocket :: from_raw_handle ( hdl) ) ;
237
+ impl FromRawHandle for SctpEndpoint {
238
+ unsafe fn from_raw_handle ( hdl : RawHandle ) -> SctpEndpoint {
239
+ return SctpEndpoint ( SctpSocket :: from_raw_handle ( hdl) ) ;
229
240
}
230
241
}
231
242
232
243
#[ cfg( target_os="linux" ) ]
233
- impl AsRawFd for SctpDatagram {
244
+ impl AsRawFd for SctpEndpoint {
234
245
fn as_raw_fd ( & self ) -> RawFd {
235
246
return self . 0 . as_raw_fd ( ) ;
236
247
}
237
248
}
238
249
239
250
#[ cfg( target_os="linux" ) ]
240
- impl FromRawFd for SctpDatagram {
241
- unsafe fn from_raw_fd ( fd : RawFd ) -> SctpDatagram {
242
- return SctpDatagram ( SctpSocket :: from_raw_fd ( fd) ) ;
251
+ impl FromRawFd for SctpEndpoint {
252
+ unsafe fn from_raw_fd ( fd : RawFd ) -> SctpEndpoint {
253
+ return SctpEndpoint ( SctpSocket :: from_raw_fd ( fd) ) ;
243
254
}
244
255
}
245
256
@@ -267,7 +278,10 @@ impl SctpListener {
267
278
268
279
/// Create a listener bound to a single address
269
280
pub fn bind < A : ToSocketAddrs > ( address : A ) -> Result < SctpListener > {
270
- return Self :: bindx ( & [ address] ) ;
281
+ let raw_addr = try!( SocketAddr :: from_addr ( & address) ) ;
282
+ let sock = try!( SctpSocket :: new ( raw_addr. family ( ) , libc:: SOCK_STREAM ) ) ;
283
+ try!( sock. bind ( raw_addr) ) ;
284
+ return Ok ( SctpListener ( sock) ) ;
271
285
}
272
286
273
287
/// Create a listener bound to multiple addresses. Requires at least one address
0 commit comments