1use std::net::IpAddr;
4
5use clickhouse::Row;
6use serde::{Deserialize, Serialize};
7use time::OffsetDateTime;
8
9#[derive(Debug, Clone, Row, Serialize, Deserialize)]
11pub struct ConnectionEvent {
12 #[serde(with = "clickhouse::serde::time::datetime64::millis")]
15 pub timestamp: OffsetDateTime,
16
17 pub duration_ms: u64,
19
20 pub conn_id: u64,
23
24 pub peer_ip: IpAddr,
26
27 pub peer_port: u16,
29
30 pub user_id: String,
33
34 pub auth_result: AuthResult,
36
37 pub target_type: TargetType,
40
41 pub target_host: String,
43
44 pub target_port: u16,
46
47 pub sni: String,
49
50 pub bytes_sent: u64,
53
54 pub bytes_recv: u64,
56
57 pub packets_sent: u64,
59
60 pub packets_recv: u64,
62
63 pub protocol: Protocol,
66
67 pub transport: Transport,
69
70 pub close_reason: CloseReason,
72
73 pub is_fallback: bool,
75
76 pub server_id: String,
79}
80
81impl ConnectionEvent {
82 pub fn new(conn_id: u64, peer_ip: IpAddr, peer_port: u16) -> Self {
84 Self {
85 timestamp: OffsetDateTime::now_utc(),
86 duration_ms: 0,
87 conn_id,
88 peer_ip,
89 peer_port,
90 user_id: String::new(),
91 auth_result: AuthResult::Skipped,
92 target_type: TargetType::Domain,
93 target_host: String::new(),
94 target_port: 0,
95 sni: String::new(),
96 bytes_sent: 0,
97 bytes_recv: 0,
98 packets_sent: 0,
99 packets_recv: 0,
100 protocol: Protocol::Tcp,
101 transport: Transport::Direct,
102 close_reason: CloseReason::Normal,
103 is_fallback: false,
104 server_id: String::new(),
105 }
106 }
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
111#[serde(rename_all = "snake_case")]
112pub enum AuthResult {
113 Success,
115 Failed,
117 Skipped,
119}
120
121impl From<AuthResult> for &'static str {
122 fn from(r: AuthResult) -> Self {
123 match r {
124 AuthResult::Success => "success",
125 AuthResult::Failed => "failed",
126 AuthResult::Skipped => "skipped",
127 }
128 }
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
133#[serde(rename_all = "snake_case")]
134pub enum TargetType {
135 Ipv4,
137 Ipv6,
139 Domain,
141}
142
143impl From<TargetType> for &'static str {
144 fn from(t: TargetType) -> Self {
145 match t {
146 TargetType::Ipv4 => "ipv4",
147 TargetType::Ipv6 => "ipv6",
148 TargetType::Domain => "domain",
149 }
150 }
151}
152
153#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
155#[serde(rename_all = "snake_case")]
156pub enum Protocol {
157 Tcp,
159 Udp,
161}
162
163impl From<Protocol> for &'static str {
164 fn from(p: Protocol) -> Self {
165 match p {
166 Protocol::Tcp => "tcp",
167 Protocol::Udp => "udp",
168 }
169 }
170}
171
172#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
174#[serde(rename_all = "snake_case")]
175pub enum Transport {
176 Direct,
178 WebSocket,
180}
181
182impl From<Transport> for &'static str {
183 fn from(t: Transport) -> Self {
184 match t {
185 Transport::Direct => "direct",
186 Transport::WebSocket => "websocket",
187 }
188 }
189}
190
191#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(rename_all = "snake_case")]
194pub enum CloseReason {
195 Normal,
197 Timeout,
199 Error,
201 Reset,
203 ServerShutdown,
205}
206
207impl From<CloseReason> for &'static str {
208 fn from(r: CloseReason) -> Self {
209 match r {
210 CloseReason::Normal => "normal",
211 CloseReason::Timeout => "timeout",
212 CloseReason::Error => "error",
213 CloseReason::Reset => "reset",
214 CloseReason::ServerShutdown => "shutdown",
215 }
216 }
217}