1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Utilities for handling sockets //! //! This crate is sort of an evolution of the `net2` crate after seeing the //! issues on it over time. The intention of this crate is to provide as direct //! as possible access to the system's functionality for sockets as possible. No //! extra fluff (e.g. multiple syscalls or builders) provided in this crate. As //! a result using this crate can be a little wordy, but it should give you //! maximal flexibility over configuration of sockets. //! //! # Examples //! //! ```no_run //! use std::net::SocketAddr; //! use socket2::{Socket, Domain, Type}; //! //! // create a TCP listener bound to two addresses //! let socket = Socket::new(Domain::ipv6(), Type::stream(), None).unwrap(); //! //! socket.bind(&"[::1]:12345".parse::<SocketAddr>().unwrap().into()).unwrap(); //! socket.set_only_v6(false); //! socket.listen(128).unwrap(); //! //! let listener = socket.into_tcp_listener(); //! // ... //! ``` #![doc(html_root_url = "https://docs.rs/socket2/0.3")] #![deny(missing_docs)] #[cfg(unix)] #[macro_use] extern crate cfg_if; #[cfg(target_os = "redox")] extern crate cfg_if; #[cfg(any(unix, target_os = "redox"))] extern crate libc; #[cfg(target_os = "redox")] extern crate syscall; #[cfg(windows)] extern crate winapi; #[cfg(test)] extern crate tempdir; use utils::NetInt; #[cfg(any(unix, target_os = "redox"))] use libc::{sockaddr_storage, socklen_t}; #[cfg(windows)] use winapi::shared::ws2def::SOCKADDR_STORAGE as sockaddr_storage; #[cfg(windows)] use winapi::um::ws2tcpip::socklen_t; mod sockaddr; mod socket; mod utils; #[cfg_attr(unix, path = "sys/unix/mod.rs")] #[cfg_attr(target_os = "redox", path = "sys/redox/mod.rs")] #[cfg_attr(windows, path = "sys/windows.rs")] mod sys; /// Newtype, owned, wrapper around a system socket. /// /// This type simply wraps an instance of a file descriptor (`c_int`) on Unix /// and an instance of `SOCKET` on Windows. This is the main type exported by /// this crate and is intended to mirror the raw semantics of sockets on /// platforms as closely as possible. Almost all methods correspond to /// precisely one libc or OS API call which is essentially just a "Rustic /// translation" of what's below. /// /// # Examples /// /// ```no_run /// use std::net::SocketAddr; /// use socket2::{Socket, Domain, Type, SockAddr}; /// /// // create a TCP listener bound to two addresses /// let socket = Socket::new(Domain::ipv4(), Type::stream(), None).unwrap(); /// /// socket.bind(&"127.0.0.1:12345".parse::<SocketAddr>().unwrap().into()).unwrap(); /// socket.bind(&"127.0.0.1:12346".parse::<SocketAddr>().unwrap().into()).unwrap(); /// socket.listen(128).unwrap(); /// /// let listener = socket.into_tcp_listener(); /// // ... /// ``` pub struct Socket { inner: sys::Socket, } /// The address of a socket. /// /// `SockAddr`s may be constructed directly to and from the standard library /// `SocketAddr`, `SocketAddrV4`, and `SocketAddrV6` types. pub struct SockAddr { storage: sockaddr_storage, len: socklen_t, } /// Specification of the communication domain for a socket. /// /// This is a newtype wrapper around an integer which provides a nicer API in /// addition to an injection point for documentation. Convenience constructors /// such as `Domain::ipv4`, `Domain::ipv6`, etc, are provided to avoid reaching /// into libc for various constants. /// /// This type is freely interconvertible with the `i32` type, however, if a raw /// value needs to be provided. #[derive(Copy, Clone)] pub struct Domain(i32); /// Specification of communication semantics on a socket. /// /// This is a newtype wrapper around an integer which provides a nicer API in /// addition to an injection point for documentation. Convenience constructors /// such as `Type::stream`, `Type::dgram`, etc, are provided to avoid reaching /// into libc for various constants. /// /// This type is freely interconvertible with the `i32` type, however, if a raw /// value needs to be provided. #[derive(Copy, Clone)] pub struct Type(i32); /// Protocol specification used for creating sockets via `Socket::new`. /// /// This is a newtype wrapper around an integer which provides a nicer API in /// addition to an injection point for documentation. /// /// This type is freely interconvertible with the `i32` type, however, if a raw /// value needs to be provided. #[derive(Copy, Clone)] pub struct Protocol(i32); fn hton<I: NetInt>(i: I) -> I { i.to_be() } #[cfg(not(target_os = "redox"))] fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }