tcp_typed/
lib.rs

1//! A wrapper around platform TCP socket APIs that leverages the type system to ensure correct usage.
2//!
3//! **[Crates.io](https://crates.io/crates/tcp_typed) │ [Repo](https://github.com/alecmocatta/tcp_typed)**
4//!
5//! It's quite easy to accidentally misuse the Berkeley sockets or similar APIs, resulting in ECONNRESET/EPIPE/etc, data being lost on close, and potential hangs from non-exhaustive collection of events given edge-triggered notifications.
6//!
7//! This library aims to make it impossible to misuse in non-unsafe code.
8//!
9//! If you ever see a connection reset / ECONNRESET, EPIPE, data being lost on close, or panic, then it is a bug in this library! Please file an issue with as much info as possible.
10//!
11//! It's designed to be used in conjunction with an implementer of the [`Notifier`] trait – for example [`notifier`](https://github.com/alecmocatta/notifier). As long as the [`Notifier`] contract is fulfilled, then this library will collect all relevent events (connected, data in, data available to be written, remote closed, bytes acked, connection errors) upon each edge-triggered notification.
12//!
13//! # Note
14//!
15//! Currently doesn't support Windows.
16
17#![doc(html_root_url = "https://docs.rs/tcp_typed/0.1.4")]
18#![warn(
19	// missing_copy_implementations,
20	// missing_debug_implementations,
21	// missing_docs,
22	trivial_casts,
23	trivial_numeric_casts,
24	unused_import_braces,
25	unused_qualifications,
26	unused_results,
27	clippy::pedantic,
28)] // from https://github.com/rust-unofficial/patterns/blob/master/anti_patterns/deny-warnings.md
29#![allow(
30	clippy::inline_always,
31	clippy::doc_markdown,
32	clippy::if_not_else,
33	clippy::indexing_slicing,
34	clippy::new_ret_no_self,
35	clippy::needless_pass_by_value
36)]
37
38mod circular_buffer;
39mod connection;
40mod connection_states;
41mod socket_forwarder;
42
43use std::{fmt, net, time};
44
45#[cfg(unix)]
46type Fd = std::os::unix::io::RawFd;
47#[cfg(windows)]
48type Fd = std::os::windows::io::RawHandle;
49
50pub use connection::*;
51pub use connection_states::*;
52pub use socket_forwarder::*;
53
54/// Implementers and users are responsible for calling `fn poll(self, &impl Notifier)` on [Connection]s or the states ([Connecter], [Connectee], [ConnecterLocalClosed], etc) as instructed by calls made to it via this trait.
55pub trait Notifier {
56	type InstantSlot;
57	/// Poll as soon as possible; equivalent to add_instant(Instant::now()).
58	fn queue(&self);
59	/// Poll when we receive an edge-triggered event on this file descriptor.
60	fn add_fd(&self, fd: Fd);
61	/// No longer poll when we receive events on this file descriptor.
62	fn remove_fd(&self, fd: Fd);
63	/// Poll at this (typically future) instant.
64	fn add_instant(&self, instant: time::Instant) -> Self::InstantSlot;
65	/// No longer poll at this specific previously added instant.
66	fn remove_instant(&self, slot: Self::InstantSlot);
67}
68
69fn format_remote(addr: net::SocketAddr) -> RemoteAddr {
70	RemoteAddr(addr)
71}
72struct RemoteAddr(net::SocketAddr);
73impl fmt::Display for RemoteAddr {
74	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75		write!(f, "{}", &self.0)
76	}
77}
78
79const BUF: usize = 64 * 1024;
80const LISTEN_BACKLOG: usize = 128;