Skip to content

Commit 8242263

Browse files
author
pierresy
committed
Renamed SctpDatagram to SctpEndpoint, added some comments, and removed some panic!(...)
1 parent c67c160 commit 8242263

File tree

4 files changed

+76
-41
lines changed

4 files changed

+76
-41
lines changed

examples/one_to_many.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use sctp::*;
33

44
fn main() {
55
// Create a new Sctp endpoint, and bind it to one or more socket addresses
6-
// let sock = match SctpDatagram::bind("0.0.0.0:3868") {
7-
let sock = match SctpDatagram::bindx(&["10.0.2.15:3868", "127.0.0.1:3868"]) {
6+
// let sock = match SctpEndpoint::bind("0.0.0.0:3868") {
7+
let sock = match SctpEndpoint::bindx(&["10.0.2.15:3868", "127.0.0.1:3868"]) {
88
Ok(s) => s,
99
Err(e) => panic!("{:?}", e.kind())
1010
};

examples/stream.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use std::io::prelude::*;
55

66
fn main() {
77
// Create a new one-to-one stream
8-
match SctpStream::connect("127.0.0.1:3868") {
8+
// match SctpStream::connect("127.0.0.1:3868") {
9+
match SctpStream::connectx(&["10.0.2.15:3868", "127.0.0.1:3868"]) {
910
Err(e) => println!("{:?}", e.kind()),
1011
Ok(mut peer) => {
1112
// Set SCTP no delay

src/lib.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
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+
17
extern crate sctp_sys;
28
extern crate libc;
39

@@ -14,9 +20,11 @@ use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
1420
#[cfg(target_os="windows")]
1521
use std::os::windows::io::{AsRawHandle, RawHandle, FromRawHandle};
1622

17-
23+
/// Socket buffer type
1824
pub enum SoBuffer {
25+
/// RCV buffer
1926
Receive,
27+
/// SND buffer
2028
Send
2129
}
2230

@@ -44,7 +52,7 @@ impl SctpStream {
4452
return Ok(SctpStream(sock));
4553
}
4654

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
4856
pub fn connectx<A: ToSocketAddrs>(addresses: &[A]) -> Result<SctpStream> {
4957
if addresses.len() == 0 { return Err(Error::new(ErrorKind::InvalidInput, "No addresses given")); }
5058
let mut vec = Vec::with_capacity(addresses.len());
@@ -164,18 +172,21 @@ impl FromRawFd for SctpStream {
164172
}
165173

166174

167-
/// One-to-many SCTP stream.
168-
pub struct SctpDatagram(SctpSocket);
175+
/// One-to-many SCTP endpoint.
176+
pub struct SctpEndpoint(SctpSocket);
169177

170-
impl SctpDatagram {
178+
impl SctpEndpoint {
171179

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));
175186
}
176187

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> {
179190
if addresses.len() == 0 { return Err(Error::new(ErrorKind::InvalidInput, "No addresses given")); }
180191
let mut vec = Vec::with_capacity(addresses.len());
181192
let mut family = libc::AF_INET;
@@ -188,7 +199,7 @@ impl SctpDatagram {
188199
let sock = try!(SctpSocket::new(family, SOCK_SEQPACKET));
189200
try!(sock.bindx(&vec, BindOp::AddAddr));
190201
try!(sock.listen(-1));
191-
return Ok(SctpDatagram(sock));
202+
return Ok(SctpEndpoint(sock));
192203
}
193204

194205
/// Wait for data to be received. On success, returns a triplet containing
@@ -200,7 +211,7 @@ impl SctpDatagram {
200211

201212
/// Send data in Sctp style, to the provided address on the stream `stream`.
202213
/// 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> {
204215
return self.0.sendmsg(msg, Some(address), stream, 0);
205216
}
206217

@@ -210,36 +221,36 @@ impl SctpDatagram {
210221
}
211222

212223
/// 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())));
215226
}
216227
}
217228

218229
#[cfg(target_os="windows")]
219-
impl AsRawHandle for SctpDatagram {
230+
impl AsRawHandle for SctpEndpoint {
220231
fn as_raw_handle(&self) -> RawHandle {
221232
return return self.0.as_raw_handle();
222233
}
223234
}
224235

225236
#[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));
229240
}
230241
}
231242

232243
#[cfg(target_os="linux")]
233-
impl AsRawFd for SctpDatagram {
244+
impl AsRawFd for SctpEndpoint {
234245
fn as_raw_fd(&self) -> RawFd {
235246
return self.0.as_raw_fd();
236247
}
237248
}
238249

239250
#[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));
243254
}
244255
}
245256

@@ -267,7 +278,10 @@ impl SctpListener {
267278

268279
/// Create a listener bound to a single address
269280
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));
271285
}
272286

273287
/// Create a listener bound to multiple addresses. Requires at least one address

src/sctpsock.rs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ extern "system" {
4747
#[cfg(target_os="windows")]
4848
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;
4949
}
50+
#[cfg(target_os="linux")]
51+
pub const SO_RCVTIMEO: libc::c_int = 20;
52+
#[cfg(target_os="linux")]
53+
pub const SO_SNDTIMEO: libc::c_int = 21;
54+
55+
#[cfg(target_os="windows")]
56+
pub const SO_RCVTIMEO: libc::c_int = 0x1006;
57+
#[cfg(target_os="windows")]
58+
pub const SO_SNDTIMEO: libc::c_int = 0x1005;
5059

5160
/// SCTP bind operation
5261
#[allow(dead_code)]
@@ -126,7 +135,7 @@ impl RawSocketAddr for SocketAddr {
126135

127136
unsafe fn from_raw_ptr(addr: *const libc::sockaddr, len: libc::socklen_t) -> Result<SocketAddr> {
128137
if len < size_of::<libc::sockaddr>() as libc::socklen_t {
129-
panic!("Invalid address length");
138+
return Err(Error::new(ErrorKind::InvalidInput, "Invalid address length"));
130139
}
131140
return match (*addr).sa_family as libc::c_int {
132141
libc::AF_INET if len >= size_of::<libc::sockaddr_in>() as libc::socklen_t => Ok(SocketAddr::V4(transmute(*(addr as *const libc::sockaddr_in)))),
@@ -195,13 +204,23 @@ impl SctpSocket {
195204
}
196205

197206
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-
}
207+
let ret = match sctp_sys::sctp_connectx(self.0, buf as *mut libc::sockaddr, addresses.len() as i32, &mut assoc) {
208+
0 => Ok(assoc),
209+
_ => Err(Error::last_os_error()),
210+
};
203211
libc::free(buf as *mut libc::c_void);
204-
return Ok(assoc);
212+
return ret;
213+
}
214+
}
215+
216+
/// Bind the socket to a single address
217+
pub fn bind<A: ToSocketAddrs>(&self, address: A) -> Result<()> {
218+
let raw_addr = try!(SocketAddr::from_addr(&address));
219+
unsafe {
220+
return match libc::bind(self.0, raw_addr.as_ptr(), raw_addr.addr_len()) {
221+
0 => Ok(()),
222+
_ => Err(Error::last_os_error())
223+
};
205224
}
206225
}
207226

@@ -221,13 +240,12 @@ impl SctpSocket {
221240
offset += len as isize;
222241
}
223242

224-
if sctp_sys::sctp_bindx(self.0, buf as *mut libc::sockaddr, addresses.len() as i32, op.flag()) != 0 {
225-
let err = Error::last_os_error();
226-
libc::free(buf as *mut libc::c_void);
227-
return Err(err);
228-
}
243+
let ret = match sctp_sys::sctp_bindx(self.0, buf as *mut libc::sockaddr, addresses.len() as i32, op.flag()) {
244+
0 => Ok(()),
245+
_ => Err(Error::last_os_error())
246+
};
229247
libc::free(buf as *mut libc::c_void);
230-
return Ok(());
248+
return ret;
231249
}
232250
}
233251

@@ -261,14 +279,16 @@ impl SctpSocket {
261279
if len == 0 { return Err(Error::new(ErrorKind::AddrNotAvailable, "Socket is unbound")); }
262280

263281
let mut vec = Vec::with_capacity(len as usize);
264-
265282
let mut offset = 0;
266283
for _ in 0..len {
267284
let sockaddr = addrs.offset(offset) as *const libc::sockaddr;
268285
let len = match (*sockaddr).sa_family as i32 {
269286
libc::AF_INET => size_of::<libc::sockaddr_in>(),
270287
libc::AF_INET6 => size_of::<libc::sockaddr_in6>(),
271-
f => panic!("Unsupported address family : {}", f)
288+
f => {
289+
what.free(addrs as *mut libc::sockaddr);
290+
return Err(Error::new(ErrorKind::Other, format!("Unsupported address family : {}", f)));
291+
}
272292
} as libc::socklen_t;
273293
vec.push(try!(SocketAddr::from_raw_ptr(sockaddr, len)));
274294
offset += len as isize;

0 commit comments

Comments
 (0)