Skip to content

Commit f104d59

Browse files
author
pierresy
committed
Added shutdown and set_nodelay methods to SctpStream
1 parent 8b663b9 commit f104d59

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "rust-sctp"
4-
version = "0.0.1"
4+
version = "0.0.2"
55
description = "High level SCTP networking library"
66
repository = "https://github.com/phsym/rust-sctp"
77
documentation = "http://phsym.github.io/rust-sctp"

src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use sctp_sys::SOCK_SEQPACKET;
77

88
use std::io::prelude::*;
99
use std::io::{Result, Error, ErrorKind};
10-
use std::net::{ToSocketAddrs, SocketAddr};
10+
use std::net::{ToSocketAddrs, SocketAddr, Shutdown};
1111

1212
#[cfg(target_os="linux")]
1313
use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
@@ -53,6 +53,17 @@ impl SctpStream {
5353
return self.0.peer_addrs(0);
5454
}
5555

56+
/// Shuts down the read, write, or both halves of this connection
57+
pub fn shutdown(&self, how: Shutdown) -> Result<()> {
58+
return self.0.shutdown(how);
59+
}
60+
61+
/// Set or unset SCTP NO DELAY option
62+
pub fn set_nodelay(&self, nodelay: bool) -> Result<()> {
63+
let val: libc::c_int = if nodelay { 1 } else { 0 };
64+
return self.0.setsockopt(sctp_sys::SCTP_NODELAY, &val);
65+
}
66+
5667
/// Try to clone the SctpStream. On success, returns a new stream
5768
/// wrapping a new socket handler
5869
pub fn try_clone(&self) -> Result<SctpStream> {

src/sctpsock.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use libc;
33
use sctp_sys;
44

55
use std::io::{Result, Error, ErrorKind, Read, Write};
6-
use std::net::{ToSocketAddrs, SocketAddr};
7-
use std::mem::{transmute, size_of};
6+
use std::net::{ToSocketAddrs, SocketAddr, Shutdown};
7+
use std::mem::{transmute, size_of, zeroed};
88

99
#[cfg(target_os="linux")]
1010
use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
@@ -40,7 +40,7 @@ fn check_socket(sock: SOCKET) -> Result<SOCKET> {
4040
return Ok(sock);
4141
}
4242

43-
/// SCTP bind opeartion
43+
/// SCTP bind operation
4444
#[allow(dead_code)]
4545
pub enum BindOp {
4646
/// Add bind addresses
@@ -182,7 +182,7 @@ impl SctpSocket {
182182
for address in addresses {
183183
let raw = try!(SocketAddr::from_addr(address));
184184
let len = raw.addr_len();
185-
std::ptr::copy(raw.as_ptr() as *mut u8, buf.offset(offset), len as usize);
185+
std::ptr::copy_nonoverlapping(raw.as_ptr() as *mut u8, buf.offset(offset), len as usize);
186186
offset += len as isize;
187187
}
188188

@@ -286,7 +286,7 @@ impl SctpSocket {
286286
unsafe {
287287
let addr_ptr: *mut libc::sockaddr = transmute(&mut addr);
288288
let mut info: sctp_sys::sctp_sndrcvinfo = std::mem::zeroed();
289-
return match sctp_sys::sctp_recvmsg(self.0, msg.as_mut_ptr() as *mut libc::c_void, len, addr_ptr, &mut addr_len, &mut info, &mut flags){
289+
return match sctp_sys::sctp_recvmsg(self.0, msg.as_mut_ptr() as *mut libc::c_void, len, addr_ptr, &mut addr_len, &mut info, &mut flags) {
290290
res if res > 0 => Ok((res as usize, info.sinfo_stream, try!(SocketAddr::from_raw_ptr(addr_ptr, addr_len)))),
291291
_ => Err(Error::last_os_error())
292292
};
@@ -312,6 +312,42 @@ impl SctpSocket {
312312
}
313313
}
314314

315+
/// Shuts down the read, write, or both halves of this connection
316+
pub fn shutdown(&self, how: Shutdown) -> Result<()> {
317+
let side = match how {
318+
Shutdown::Read => libc::SHUT_RD,
319+
Shutdown::Write => libc::SHUT_WR,
320+
Shutdown::Both => libc::SHUT_RDWR
321+
};
322+
return match unsafe { libc::shutdown(self.0, side) } {
323+
0 => Ok(()),
324+
_ => Err(Error::last_os_error())
325+
};
326+
}
327+
328+
/// Set SCTP socket option
329+
pub fn setsockopt<T>(&self, optname: libc::c_int, optval: &T) -> Result<()> {
330+
unsafe {
331+
return match libc::setsockopt(self.0, sctp_sys::SOL_SCTP, optname, transmute(optval), size_of::<T>() as libc::socklen_t) {
332+
0 => Ok(()),
333+
_ => Err(Error::last_os_error())
334+
};
335+
}
336+
}
337+
338+
/// Get SCTP socket option
339+
pub fn getsockopt<T>(&self, optname: libc::c_int, assoc: sctp_sys::sctp_assoc_t) -> Result<T> {
340+
unsafe {
341+
let mut val: T = zeroed();
342+
let mut len = size_of::<T>() as libc::socklen_t;
343+
return match sctp_sys::sctp_opt_info(self.0, assoc, optname, transmute(&mut val), &mut len) {
344+
0 => Ok(val),
345+
_ => Err(Error::last_os_error())
346+
};
347+
}
348+
}
349+
350+
315351
/// Try to clone this socket
316352
pub fn try_clone(&self) -> Result<SctpSocket> {
317353
unsafe {

0 commit comments

Comments
 (0)