]>
Commit | Line | Data |
---|---|---|
0531ce1d XL |
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 | ||
46de9a89 | 40 | use crate::utils::NetInt; |
0531ce1d | 41 | |
72b1a166 FG |
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 | } | |
0531ce1d XL |
73 | |
74 | mod sockaddr; | |
75 | mod socket; | |
76 | mod utils; | |
77 | ||
72b1a166 FG |
78 | #[cfg(test)] |
79 | mod tests; | |
80 | ||
46de9a89 FG |
81 | #[cfg(unix)] |
82 | #[path = "sys/unix.rs"] | |
83 | mod sys; | |
84 | #[cfg(windows)] | |
85 | #[path = "sys/windows.rs"] | |
86 | mod sys; | |
0531ce1d | 87 | |
72b1a166 | 88 | use sys::c_int; |
0531ce1d | 89 | |
72b1a166 FG |
90 | pub use sockaddr::SockAddr; |
91 | pub use socket::Socket; | |
0531ce1d XL |
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 | /// | |
72b1a166 | 100 | /// This type is freely interconvertible with C's `int` type, however, if a raw |
0531ce1d XL |
101 | /// value needs to be provided. |
102 | #[derive(Copy, Clone)] | |
72b1a166 FG |
103 | pub struct Domain(c_int); |
104 | ||
105 | impl Domain { | |
106 | /// Domain for IPv4 communication, corresponding to `AF_INET`. | |
107 | pub fn ipv4() -> Domain { | |
108 | Domain(sys::AF_INET) | |
109 | } | |
110 | ||
111 | /// Domain for IPv6 communication, corresponding to `AF_INET6`. | |
112 | pub fn ipv6() -> Domain { | |
113 | Domain(sys::AF_INET6) | |
114 | } | |
115 | } | |
116 | ||
117 | impl From<c_int> for Domain { | |
118 | fn from(d: c_int) -> Domain { | |
119 | Domain(d) | |
120 | } | |
121 | } | |
122 | ||
123 | impl From<Domain> for c_int { | |
124 | fn from(d: Domain) -> c_int { | |
125 | d.0 | |
126 | } | |
127 | } | |
0531ce1d XL |
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 | /// | |
72b1a166 | 136 | /// This type is freely interconvertible with C's `int` type, however, if a raw |
0531ce1d XL |
137 | /// value needs to be provided. |
138 | #[derive(Copy, Clone)] | |
72b1a166 FG |
139 | pub struct Type(c_int); |
140 | ||
141 | impl Type { | |
142 | /// Type corresponding to `SOCK_STREAM`. | |
143 | /// | |
144 | /// Used for protocols such as TCP. | |
145 | 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. | |
152 | pub fn dgram() -> Type { | |
153 | Type(sys::SOCK_DGRAM) | |
154 | } | |
155 | ||
156 | /// Type corresponding to `SOCK_SEQPACKET`. | |
157 | pub fn seqpacket() -> Type { | |
158 | Type(sys::SOCK_SEQPACKET) | |
159 | } | |
160 | ||
161 | /// Type corresponding to `SOCK_RAW`. | |
162 | #[cfg(not(target_os = "redox"))] | |
163 | pub fn raw() -> Type { | |
164 | Type(sys::SOCK_RAW) | |
165 | } | |
166 | } | |
167 | ||
168 | impl From<c_int> for Type { | |
169 | fn from(t: c_int) -> Type { | |
170 | Type(t) | |
171 | } | |
172 | } | |
173 | ||
174 | impl From<Type> for c_int { | |
175 | fn from(t: Type) -> c_int { | |
176 | t.0 | |
177 | } | |
178 | } | |
0531ce1d XL |
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 | /// | |
72b1a166 | 185 | /// This type is freely interconvertible with C's `int` type, however, if a raw |
0531ce1d XL |
186 | /// value needs to be provided. |
187 | #[derive(Copy, Clone)] | |
72b1a166 FG |
188 | pub struct Protocol(c_int); |
189 | ||
190 | impl Protocol { | |
191 | /// Protocol corresponding to `ICMPv4`. | |
192 | pub fn icmpv4() -> Self { | |
193 | Protocol(sys::IPPROTO_ICMP) | |
194 | } | |
195 | ||
196 | /// Protocol corresponding to `ICMPv6`. | |
197 | pub fn icmpv6() -> Self { | |
198 | Protocol(sys::IPPROTO_ICMPV6) | |
199 | } | |
200 | ||
201 | /// Protocol corresponding to `TCP`. | |
202 | pub fn tcp() -> Self { | |
203 | Protocol(sys::IPPROTO_TCP) | |
204 | } | |
205 | ||
206 | /// Protocol corresponding to `UDP`. | |
207 | pub fn udp() -> Self { | |
208 | Protocol(sys::IPPROTO_UDP) | |
209 | } | |
210 | } | |
211 | ||
212 | impl From<c_int> for Protocol { | |
213 | fn from(p: c_int) -> Protocol { | |
214 | Protocol(p) | |
215 | } | |
216 | } | |
217 | ||
218 | impl From<Protocol> for c_int { | |
219 | fn from(p: Protocol) -> c_int { | |
220 | p.0 | |
221 | } | |
222 | } | |
0531ce1d XL |
223 | |
224 | fn hton<I: NetInt>(i: I) -> I { | |
225 | i.to_be() | |
226 | } | |
227 | ||
228 | fn ntoh<I: NetInt>(i: I) -> I { | |
229 | I::from_be(i) | |
230 | } |