pingora_core/protocols/
digest.rs1use std::sync::Arc;
18use std::time::{Duration, SystemTime};
19
20use once_cell::sync::OnceCell;
21
22use super::l4::ext::{get_original_dest, get_recv_buf, get_tcp_info, TCP_INFO};
23use super::l4::socket::SocketAddr;
24use super::raw_connect::ProxyDigest;
25use super::tls::digest::SslDigest;
26
27#[derive(Clone, Debug, Default)]
29pub struct Digest {
30 pub ssl_digest: Option<Arc<SslDigest>>,
32 pub timing_digest: Vec<Option<TimingDigest>>,
34 pub proxy_digest: Option<Arc<ProxyDigest>>,
36 pub socket_digest: Option<Arc<SocketDigest>>,
38}
39
40pub trait ProtoDigest {
42 fn get_digest(&self) -> Option<&Digest> {
43 None
44 }
45}
46
47#[derive(Clone, Debug)]
49pub struct TimingDigest {
50 pub established_ts: SystemTime,
52}
53
54impl Default for TimingDigest {
55 fn default() -> Self {
56 TimingDigest {
57 established_ts: SystemTime::UNIX_EPOCH,
58 }
59 }
60}
61
62#[derive(Debug)]
63pub struct SocketDigest {
65 #[cfg(unix)]
66 raw_fd: std::os::unix::io::RawFd,
67 #[cfg(windows)]
68 raw_sock: std::os::windows::io::RawSocket,
69 pub peer_addr: OnceCell<Option<SocketAddr>>,
71 pub local_addr: OnceCell<Option<SocketAddr>>,
73 pub original_dst: OnceCell<Option<SocketAddr>>,
75}
76
77impl SocketDigest {
78 #[cfg(unix)]
79 pub fn from_raw_fd(raw_fd: std::os::unix::io::RawFd) -> SocketDigest {
80 SocketDigest {
81 raw_fd,
82 peer_addr: OnceCell::new(),
83 local_addr: OnceCell::new(),
84 original_dst: OnceCell::new(),
85 }
86 }
87
88 #[cfg(windows)]
89 pub fn from_raw_socket(raw_sock: std::os::windows::io::RawSocket) -> SocketDigest {
90 SocketDigest {
91 raw_sock,
92 peer_addr: OnceCell::new(),
93 local_addr: OnceCell::new(),
94 original_dst: OnceCell::new(),
95 }
96 }
97
98 #[cfg(unix)]
99 pub fn peer_addr(&self) -> Option<&SocketAddr> {
100 self.peer_addr
101 .get_or_init(|| SocketAddr::from_raw_fd(self.raw_fd, true))
102 .as_ref()
103 }
104
105 #[cfg(windows)]
106 pub fn peer_addr(&self) -> Option<&SocketAddr> {
107 self.peer_addr
108 .get_or_init(|| SocketAddr::from_raw_socket(self.raw_sock, true))
109 .as_ref()
110 }
111
112 #[cfg(unix)]
113 pub fn local_addr(&self) -> Option<&SocketAddr> {
114 self.local_addr
115 .get_or_init(|| SocketAddr::from_raw_fd(self.raw_fd, false))
116 .as_ref()
117 }
118
119 #[cfg(windows)]
120 pub fn local_addr(&self) -> Option<&SocketAddr> {
121 self.local_addr
122 .get_or_init(|| SocketAddr::from_raw_socket(self.raw_sock, false))
123 .as_ref()
124 }
125
126 fn is_inet(&self) -> bool {
127 self.local_addr().and_then(|p| p.as_inet()).is_some()
128 }
129
130 #[cfg(unix)]
131 pub fn tcp_info(&self) -> Option<TCP_INFO> {
132 if self.is_inet() {
133 get_tcp_info(self.raw_fd).ok()
134 } else {
135 None
136 }
137 }
138
139 #[cfg(windows)]
140 pub fn tcp_info(&self) -> Option<TCP_INFO> {
141 if self.is_inet() {
142 get_tcp_info(self.raw_sock).ok()
143 } else {
144 None
145 }
146 }
147
148 #[cfg(unix)]
149 pub fn get_recv_buf(&self) -> Option<usize> {
150 if self.is_inet() {
151 get_recv_buf(self.raw_fd).ok()
152 } else {
153 None
154 }
155 }
156
157 #[cfg(windows)]
158 pub fn get_recv_buf(&self) -> Option<usize> {
159 if self.is_inet() {
160 get_recv_buf(self.raw_sock).ok()
161 } else {
162 None
163 }
164 }
165
166 #[cfg(unix)]
167 pub fn original_dst(&self) -> Option<&SocketAddr> {
168 self.original_dst
169 .get_or_init(|| {
170 get_original_dest(self.raw_fd)
171 .ok()
172 .flatten()
173 .map(SocketAddr::Inet)
174 })
175 .as_ref()
176 }
177
178 #[cfg(windows)]
179 pub fn original_dst(&self) -> Option<&SocketAddr> {
180 self.original_dst
181 .get_or_init(|| {
182 get_original_dest(self.raw_sock)
183 .ok()
184 .flatten()
185 .map(SocketAddr::Inet)
186 })
187 .as_ref()
188 }
189}
190
191pub trait GetTimingDigest {
193 fn get_timing_digest(&self) -> Vec<Option<TimingDigest>>;
195 fn get_read_pending_time(&self) -> Duration {
196 Duration::ZERO
197 }
198 fn get_write_pending_time(&self) -> Duration {
199 Duration::ZERO
200 }
201}
202
203pub trait GetProxyDigest {
205 fn get_proxy_digest(&self) -> Option<Arc<ProxyDigest>>;
206 fn set_proxy_digest(&mut self, _digest: ProxyDigest) {}
207}
208
209pub trait GetSocketDigest {
211 fn get_socket_digest(&self) -> Option<Arc<SocketDigest>>;
212 fn set_socket_digest(&mut self, _socket_digest: SocketDigest) {}
213}