summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/socket/sockopt.rs91
1 files changed, 90 insertions, 1 deletions
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index f440a00c..424d7557 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -6,6 +6,28 @@ use libc::{self, c_int, uint8_t, c_void, socklen_t};
use std::mem;
use std::os::unix::io::RawFd;
+/// Helper for implementing `SetSockOpt` for a given socket option. See
+/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
+///
+/// This macro aims to help implementing `SetSockOpt` for different socket options that accept
+/// different kinds of data to be used with `setsockopt`.
+///
+/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option
+/// you are implementing represents a simple type.
+///
+/// # Arguments
+///
+/// * `$name:ident`: name of the type you want to implement `SetSockOpt` for.
+/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets*
+/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
+/// and more. Please refer to your system manual for more options. Will be passed as the second
+/// argument (`level`) to the `setsockopt` call.
+/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
+/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`)
+/// to the `setsockopt` call.
+/// * Type of the value that you are going to set.
+/// * Type that implements the `Set` trait for the type from the previous item (like `SetBool` for
+/// `bool`, `SetUsize` for `usize`, etc.).
macro_rules! setsockopt_impl {
($name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
impl SetSockOpt for $name {
@@ -25,6 +47,28 @@ macro_rules! setsockopt_impl {
}
}
+/// Helper for implementing `GetSockOpt` for a given socket option. See
+/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html).
+///
+/// This macro aims to help implementing `GetSockOpt` for different socket options that accept
+/// different kinds of data to be use with `getsockopt`.
+///
+/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option
+/// you are implementing represents a simple type.
+///
+/// # Arguments
+///
+/// * Name of the type you want to implement `GetSockOpt` for.
+/// * Socket layer, or a `protocol level`: could be *raw sockets* (`lic::SOL_SOCKET`), *ip
+/// protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), and more. Please refer
+/// to your system manual for more options. Will be passed as the second argument (`level`) to
+/// the `getsockopt` call.
+/// * A flag to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
+/// `libc::SO_ORIGINAL_DST` and others. Will be passed as the third argument (`option_name`) to
+/// the `getsockopt` call.
+/// * Type of the value that you are going to get.
+/// * Type that implements the `Get` trait for the type from the previous item (`GetBool` for
+/// `bool`, `GetUsize` for `usize`, etc.).
macro_rules! getsockopt_impl {
($name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
impl GetSockOpt for $name {
@@ -46,7 +90,31 @@ macro_rules! getsockopt_impl {
}
}
-// Helper to generate the sockopt accessors
+/// Helper to generate the sockopt accessors. See
+/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html) and
+/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
+///
+/// This macro aims to help implementing `GetSockOpt` and `SetSockOpt` for different socket options
+/// that accept different kinds of data to be use with `getsockopt` and `setsockopt` respectively.
+///
+/// Basically this macro wraps up the [`getsockopt_impl!`](macro.getsockopt_impl.html) and
+/// [`setsockopt_impl!`](macro.setsockopt_impl.html) macros.
+///
+/// # Arguments
+///
+/// * `GetOnly`, `SetOnly` or `Both`: whether you want to implement only getter, only setter or
+/// both of them.
+/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for.
+/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets*
+/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
+/// and more. Please refer to your system manual for more options. Will be passed as the second
+/// argument (`level`) to the `getsockopt`/`setsockopt` call.
+/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
+/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`)
+/// to the `setsockopt`/`getsockopt` call.
+/// * `$ty:ty`: type of the value that will be get/set.
+/// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`.
+/// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`.
macro_rules! sockopt_impl {
(GetOnly, $name:ident, $level:path, $flag:path, bool) => {
sockopt_impl!(GetOnly, $name, $level, $flag, bool, GetBool);
@@ -192,19 +260,33 @@ sockopt_impl!(Both, BindAny, libc::IPPROTO_IP, libc::IP_BINDANY, bool);
*
*/
+/// Helper trait that describes what is expected from a `GetSockOpt` getter.
unsafe trait Get<T> {
+ /// Returns an empty value.
unsafe fn blank() -> Self;
+ /// Returns a pointer to the stored value. This pointer will be passed to the system's
+ /// `getsockopt` call (`man 3p getsockopt`, argument `option_value`).
fn ffi_ptr(&mut self) -> *mut c_void;
+ /// Returns length of the stored value. This pointer will be passed to the system's
+ /// `getsockopt` call (`man 3p getsockopt`, argument `option_len`).
fn ffi_len(&mut self) -> *mut socklen_t;
+ /// Returns the stored value.
unsafe fn unwrap(self) -> T;
}
+/// Helper trait that describes what is expected from a `SetSockOpt` setter.
unsafe trait Set<'a, T> {
+ /// Initialize the setter with a given value.
fn new(val: &'a T) -> Self;
+ /// Returns a pointer to the stored value. This pointer will be passed to the system's
+ /// `setsockopt` call (`man 3p setsockopt`, argument `option_value`).
fn ffi_ptr(&self) -> *const c_void;
+ /// Returns length of the stored value. This pointer will be passed to the system's
+ /// `setsockopt` call (`man 3p setsockopt`, argument `option_len`).
fn ffi_len(&self) -> socklen_t;
}
+/// Getter for an arbitrary `struct`.
struct GetStruct<T> {
len: socklen_t,
val: T,
@@ -232,6 +314,7 @@ unsafe impl<T> Get<T> for GetStruct<T> {
}
}
+/// Setter for an arbitrary `struct`.
struct SetStruct<'a, T: 'static> {
ptr: &'a T,
}
@@ -250,6 +333,7 @@ unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
}
}
+/// Getter for a boolean value.
struct GetBool {
len: socklen_t,
val: c_int,
@@ -277,6 +361,7 @@ unsafe impl Get<bool> for GetBool {
}
}
+/// Setter for a boolean value.
struct SetBool {
val: c_int,
}
@@ -295,6 +380,7 @@ unsafe impl<'a> Set<'a, bool> for SetBool {
}
}
+/// Getter for an `u8` value.
struct GetU8 {
len: socklen_t,
val: uint8_t,
@@ -322,6 +408,7 @@ unsafe impl Get<u8> for GetU8 {
}
}
+/// Setter for an `u8` value.
struct SetU8 {
val: uint8_t,
}
@@ -340,6 +427,7 @@ unsafe impl<'a> Set<'a, u8> for SetU8 {
}
}
+/// Getter for an `usize` value.
struct GetUsize {
len: socklen_t,
val: c_int,
@@ -367,6 +455,7 @@ unsafe impl Get<usize> for GetUsize {
}
}
+/// Setter for an `usize` value.
struct SetUsize {
val: c_int,
}