1use prelude::Protocol;
2use ffi::{IntoI32, AF_UNSPEC, AF_INET, AF_INET6, SOCK_STREAM,
3 IPPROTO_TCP, AI_PASSIVE, AI_NUMERICSERV};
4use stream_socket::StreamSocket;
5use socket_listener::SocketListener;
6use ip::{IpProtocol, IpEndpoint, Resolver, ResolverIter, ResolverQuery, Passive};
7
8use std::io;
9use std::fmt;
10use std::mem;
11
12#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
58pub struct Tcp {
59 family: i32,
60}
61
62impl Protocol for Tcp {
63 type Endpoint = IpEndpoint<Self>;
64
65 fn family_type(&self) -> i32 {
66 self.family
67 }
68
69 fn socket_type(&self) -> i32 {
70 SOCK_STREAM as i32
71 }
72
73 fn protocol_type(&self) -> i32 {
74 IPPROTO_TCP.i32()
75 }
76
77 unsafe fn uninitialized(&self) -> Self::Endpoint {
78 mem::uninitialized()
79 }
80}
81
82impl IpProtocol for Tcp {
83 fn v4() -> Tcp {
95 Tcp { family: AF_INET as i32 }
96 }
97
98 fn v6() -> Tcp {
110 Tcp { family: AF_INET6 as i32 }
111 }
112}
113
114impl fmt::Debug for Tcp {
115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116 if self.is_v4() {
117 write!(f, "TCPv4")
118 } else if self.is_v6() {
119 write!(f, "TCPv6")
120 } else {
121 unreachable!("Invalid address family ({}).", self.family);
122 }
123 }
124}
125
126impl fmt::Debug for IpEndpoint<Tcp> {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 write!(f, "Endpoint(TCP/{})", self)
129 }
130}
131
132impl fmt::Debug for Resolver<Tcp, StreamSocket<Tcp>> {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 write!(f, "Resolver(TCP)")
135 }
136}
137
138impl ResolverQuery<Tcp> for (Passive, u16) {
139 fn iter(self) -> io::Result<ResolverIter<Tcp>> {
140 let port = self.1.to_string();
141 ResolverIter::new(&Tcp { family: AF_UNSPEC }, "", &port, AI_PASSIVE | AI_NUMERICSERV)
142 }
143}
144
145impl<'a> ResolverQuery<Tcp> for (Passive, &'a str) {
146 fn iter(self) -> io::Result<ResolverIter<Tcp>> {
147 ResolverIter::new(&Tcp { family: AF_UNSPEC }, "", self.1, AI_PASSIVE)
148 }
149}
150
151impl<'a, 'b> ResolverQuery<Tcp> for (&'a str, &'b str) {
152 fn iter(self) -> io::Result<ResolverIter<Tcp>> {
153 ResolverIter::new(&Tcp { family: AF_UNSPEC }, self.0, self.1, 0)
154 }
155}
156
157pub type TcpEndpoint = IpEndpoint<Tcp>;
159
160pub type TcpSocket = StreamSocket<Tcp>;
162
163pub type TcpListener = SocketListener<Tcp, StreamSocket<Tcp>>;
165
166pub type TcpResolver = Resolver<Tcp, StreamSocket<Tcp>>;
168
169#[test]
170fn test_tcp() {
171 assert!(Tcp::v4() == Tcp::v4());
172 assert!(Tcp::v6() == Tcp::v6());
173 assert!(Tcp::v4() != Tcp::v6());
174}
175
176#[test]
177fn test_tcp_resolver() {
178 use IoContext;
179 use ip::*;
180
181 let ctx = &IoContext::new().unwrap();
182 let re = TcpResolver::new(ctx);
183 for ep in re.resolve(("127.0.0.1", "80")).unwrap() {
184 assert!(ep == TcpEndpoint::new(IpAddrV4::loopback(), 80));
185 }
186 for ep in re.resolve(("::1", "80")).unwrap() {
187 assert!(ep == TcpEndpoint::new(IpAddrV6::loopback(), 80));
188 }
189 for ep in re.resolve(("localhost", "http")).unwrap() {
190 assert!(ep.addr().is_loopback());
191 assert!(ep.port() == 80);
192 }
193}
194
195#[test]
196fn test_getsockname_v4() {
197 use prelude::Endpoint;
198 use core::IoContext;
199 use socket_base::ReuseAddr;
200 use ip::*;
201
202 let ctx = &IoContext::new().unwrap();
203 let ep = TcpEndpoint::new(IpAddrV4::any(), 12344);
204 let soc = TcpSocket::new(ctx, ep.protocol()).unwrap();
205 soc.set_option(ReuseAddr::new(true)).unwrap();
206 soc.bind(&ep).unwrap();
207 assert_eq!(soc.local_endpoint().unwrap(), ep);
208}
209
210#[test]
211fn test_getsockname_v6() {
212 use prelude::Endpoint;
213 use core::IoContext;
214 use socket_base::ReuseAddr;
215 use ip::*;
216
217 let ctx = &IoContext::new().unwrap();
218 let ep = TcpEndpoint::new(IpAddrV6::any(), 12346);
219 let soc = TcpSocket::new(ctx, ep.protocol()).unwrap();
220 soc.set_option(ReuseAddr::new(true)).unwrap();
221 soc.bind(&ep).unwrap();
222 assert_eq!(soc.local_endpoint().unwrap(), ep);
223}
224
225#[test]
226fn test_receive_error_when_not_connected() {
227 use core::IoContext;
228 use async::wrap;
229 use ip::Tcp;
230
231 use std::io;
232 use std::sync::{Arc, Mutex};
233
234 let ctx = &IoContext::new().unwrap();
235 let soc = Arc::new(Mutex::new(StreamSocket::new(ctx, Tcp::v4()).unwrap()));
236
237 let mut buf = [0; 256];
238 assert!(soc.lock().unwrap().receive(&mut buf, 0).is_err());
239
240 fn handler(_: Arc<Mutex<StreamSocket<Tcp>>>, res: io::Result<usize>) {
241 assert!(res.is_err());
242 }
243 soc.lock().unwrap().async_receive(&mut buf, 0, wrap(handler, &soc));
244
245 ctx.run();
246}
247
248#[test]
249fn test_send_error_when_not_connected() {
250 use core::IoContext;
251 use async::wrap;
252 use ip::Tcp;
253
254 use std::io;
255 use std::sync::{Arc, Mutex};
256
257 let ctx = &IoContext::new().unwrap();
258 let soc = Arc::new(Mutex::new(StreamSocket::new(ctx, Tcp::v4()).unwrap()));
259
260 let mut buf = [0; 256];
261 assert!(soc.lock().unwrap().send(&mut buf, 0).is_err());
262
263 fn handler(_: Arc<Mutex<StreamSocket<Tcp>>>, res: io::Result<usize>) {
264 assert!(res.is_err());
265 }
266 soc.lock().unwrap().async_send(&mut buf, 0, wrap(handler, &soc));
267
268 ctx.run();
269}
270
271#[test]
272fn test_format() {
273 use core::IoContext;
274
275 let ctx = &IoContext::new().unwrap();
276 println!("{:?}", Tcp::v4());
277 println!("{:?}", TcpEndpoint::new(Tcp::v4(), 12345));
278 println!("{:?}", TcpSocket::new(ctx, Tcp::v4()).unwrap());
279 println!("{:?}", TcpListener::new(ctx, Tcp::v4()).unwrap());
280 println!("{:?}", TcpResolver::new(ctx));
281}