1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Utilities for handling sockets
12 //!
13 //! This crate is sort of an evolution of the `net2` crate after seeing the
14 //! issues on it over time. The intention of this crate is to provide as direct
15 //! as possible access to the system's functionality for sockets as possible. No
16 //! extra fluff (e.g. multiple syscalls or builders) provided in this crate. As
17 //! a result using this crate can be a little wordy, but it should give you
18 //! maximal flexibility over configuration of sockets.
19 //!
20 //! # Examples
21 //!
22 //! ```no_run
23 //! use std::net::SocketAddr;
24 //! use socket2::{Socket, Domain, Type};
25 //!
26 //! // create a TCP listener bound to two addresses
27 //! let socket = Socket::new(Domain::ipv6(), Type::stream(), None).unwrap();
28 //!
29 //! socket.bind(&"[::1]:12345".parse::<SocketAddr>().unwrap().into()).unwrap();
30 //! socket.set_only_v6(false);
31 //! socket.listen(128).unwrap();
32 //!
33 //! let listener = socket.into_tcp_listener();
34 //! // ...
35 //! ```
36
37 #![doc(html_root_url = "https://docs.rs/socket2/0.3")]
38 #![deny(missing_docs)]
39
40 use crate::utils::NetInt;
41
42 /// Macro to implement `fmt::Debug` for a type, printing the constant names
43 /// rather than a number.
44 ///
45 /// Note this is used in the `sys` module and thus must be defined before
46 /// defining the modules.
47 macro_rules! impl_debug {
48 (
49 // Type name for which to implement `fmt::Debug`.
50 $type: path,
51 $(
52 $(#[$target: meta])*
53 // The flag(s) to check.
54 // Need to specific the libc crate because Windows doesn't use
55 // `libc` but `winapi`.
56 $libc: ident :: $flag: ident
57 ),+ $(,)*
58 ) => {
59 impl std::fmt::Debug for $type {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 let string = match self.0 {
62 $(
63 $(#[$target])*
64 $libc :: $flag => stringify!($flag),
65 )+
66 n => return write!(f, "{}", n),
67 };
68 f.write_str(string)
69 }
70 }
71 };
72 }
73
74 mod sockaddr;
75 mod socket;
76 mod utils;
77
78 #[cfg(test)]
79 mod tests;
80
81 #[cfg(unix)]
82 #[path = "sys/unix.rs"]
83 mod sys;
84 #[cfg(windows)]
85 #[path = "sys/windows.rs"]
86 mod sys;
87
88 use sys::c_int;
89
90 pub use sockaddr::SockAddr;
91 pub use socket::Socket;
92
93 /// Specification of the communication domain for a socket.
94 ///
95 /// This is a newtype wrapper around an integer which provides a nicer API in
96 /// addition to an injection point for documentation. Convenience constructors
97 /// such as `Domain::ipv4`, `Domain::ipv6`, etc, are provided to avoid reaching
98 /// into libc for various constants.
99 ///
100 /// This type is freely interconvertible with C's `int` type, however, if a raw
101 /// value needs to be provided.
102 #[derive(Copy, Clone)]
103 pub struct Domain(c_int);
104
105 impl Domain {
106 /// Domain for IPv4 communication, corresponding to `AF_INET`.
ipv4() -> Domain107 pub fn ipv4() -> Domain {
108 Domain(sys::AF_INET)
109 }
110
111 /// Domain for IPv6 communication, corresponding to `AF_INET6`.
ipv6() -> Domain112 pub fn ipv6() -> Domain {
113 Domain(sys::AF_INET6)
114 }
115 }
116
117 impl From<c_int> for Domain {
from(d: c_int) -> Domain118 fn from(d: c_int) -> Domain {
119 Domain(d)
120 }
121 }
122
123 impl From<Domain> for c_int {
from(d: Domain) -> c_int124 fn from(d: Domain) -> c_int {
125 d.0
126 }
127 }
128
129 /// Specification of communication semantics on a socket.
130 ///
131 /// This is a newtype wrapper around an integer which provides a nicer API in
132 /// addition to an injection point for documentation. Convenience constructors
133 /// such as `Type::stream`, `Type::dgram`, etc, are provided to avoid reaching
134 /// into libc for various constants.
135 ///
136 /// This type is freely interconvertible with C's `int` type, however, if a raw
137 /// value needs to be provided.
138 #[derive(Copy, Clone)]
139 pub struct Type(c_int);
140
141 impl Type {
142 /// Type corresponding to `SOCK_STREAM`.
143 ///
144 /// Used for protocols such as TCP.
stream() -> Type145 pub fn stream() -> Type {
146 Type(sys::SOCK_STREAM)
147 }
148
149 /// Type corresponding to `SOCK_DGRAM`.
150 ///
151 /// Used for protocols such as UDP.
dgram() -> Type152 pub fn dgram() -> Type {
153 Type(sys::SOCK_DGRAM)
154 }
155
156 /// Type corresponding to `SOCK_SEQPACKET`.
seqpacket() -> Type157 pub fn seqpacket() -> Type {
158 Type(sys::SOCK_SEQPACKET)
159 }
160
161 /// Type corresponding to `SOCK_RAW`.
162 #[cfg(not(target_os = "redox"))]
raw() -> Type163 pub fn raw() -> Type {
164 Type(sys::SOCK_RAW)
165 }
166 }
167
168 impl From<c_int> for Type {
from(t: c_int) -> Type169 fn from(t: c_int) -> Type {
170 Type(t)
171 }
172 }
173
174 impl From<Type> for c_int {
from(t: Type) -> c_int175 fn from(t: Type) -> c_int {
176 t.0
177 }
178 }
179
180 /// Protocol specification used for creating sockets via `Socket::new`.
181 ///
182 /// This is a newtype wrapper around an integer which provides a nicer API in
183 /// addition to an injection point for documentation.
184 ///
185 /// This type is freely interconvertible with C's `int` type, however, if a raw
186 /// value needs to be provided.
187 #[derive(Copy, Clone)]
188 pub struct Protocol(c_int);
189
190 impl Protocol {
191 /// Protocol corresponding to `ICMPv4`.
icmpv4() -> Self192 pub fn icmpv4() -> Self {
193 Protocol(sys::IPPROTO_ICMP)
194 }
195
196 /// Protocol corresponding to `ICMPv6`.
icmpv6() -> Self197 pub fn icmpv6() -> Self {
198 Protocol(sys::IPPROTO_ICMPV6)
199 }
200
201 /// Protocol corresponding to `TCP`.
tcp() -> Self202 pub fn tcp() -> Self {
203 Protocol(sys::IPPROTO_TCP)
204 }
205
206 /// Protocol corresponding to `UDP`.
udp() -> Self207 pub fn udp() -> Self {
208 Protocol(sys::IPPROTO_UDP)
209 }
210 }
211
212 impl From<c_int> for Protocol {
from(p: c_int) -> Protocol213 fn from(p: c_int) -> Protocol {
214 Protocol(p)
215 }
216 }
217
218 impl From<Protocol> for c_int {
from(p: Protocol) -> c_int219 fn from(p: Protocol) -> c_int {
220 p.0
221 }
222 }
223
hton<I: NetInt>(i: I) -> I224 fn hton<I: NetInt>(i: I) -> I {
225 i.to_be()
226 }
227
ntoh<I: NetInt>(i: I) -> I228 fn ntoh<I: NetInt>(i: I) -> I {
229 I::from_be(i)
230 }
231