reddb_server/
transport.rs1pub(crate) mod execution_admission;
8pub(crate) mod overload;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum TransportKind {
12 Router,
13 Http,
14 Https,
15 Grpc,
16 GrpcTls,
17 Wire,
18 WireTls,
19 Postgres,
20}
21
22impl TransportKind {
23 pub const fn as_str(self) -> &'static str {
24 match self {
25 Self::Router => "router",
26 Self::Http => "http",
27 Self::Https => "https",
28 Self::Grpc => "grpc",
29 Self::GrpcTls => "grpc-tls",
30 Self::Wire => "wire",
31 Self::WireTls => "wire-tls",
32 Self::Postgres => "pg-wire",
33 }
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum TransportRole {
40 Primary,
43 Secondary,
46}
47
48#[derive(Debug, Clone, PartialEq, Eq)]
49pub struct TransportDescriptor {
50 pub kind: TransportKind,
51 pub bind_addr: String,
52 pub explicit: bool,
53 pub role: TransportRole,
54}
55
56impl TransportDescriptor {
57 pub fn new(
58 kind: TransportKind,
59 bind_addr: String,
60 explicit: bool,
61 role: TransportRole,
62 ) -> Self {
63 Self {
64 kind,
65 bind_addr,
66 explicit,
67 role,
68 }
69 }
70}
71
72#[derive(Debug, Clone, Default, PartialEq, Eq)]
73pub struct TransportSet {
74 descriptors: Vec<TransportDescriptor>,
75}
76
77impl TransportSet {
78 pub fn new(descriptors: Vec<TransportDescriptor>) -> Self {
79 Self { descriptors }
80 }
81
82 pub fn descriptors(&self) -> &[TransportDescriptor] {
83 &self.descriptors
84 }
85
86 pub fn is_empty(&self) -> bool {
87 self.descriptors.is_empty()
88 }
89}
90
91#[derive(Debug, Clone, PartialEq, Eq)]
92pub struct TransportListenerState {
93 pub transport: String,
94 pub bind_addr: String,
95 pub explicit: bool,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct TransportListenerFailure {
100 pub transport: String,
101 pub bind_addr: String,
102 pub explicit: bool,
103 pub reason: String,
104}
105
106#[derive(Debug, Clone, Default, PartialEq, Eq)]
107pub struct TransportReadiness {
108 pub active: Vec<TransportListenerState>,
109 pub failed: Vec<TransportListenerFailure>,
110}
111
112impl TransportReadiness {
113 pub(crate) fn active(&mut self, transport: &str, bind_addr: &str, explicit: bool) {
114 self.active.push(TransportListenerState {
115 transport: transport.to_string(),
116 bind_addr: bind_addr.to_string(),
117 explicit,
118 });
119 }
120
121 pub(crate) fn failed(
122 &mut self,
123 transport: &str,
124 bind_addr: &str,
125 explicit: bool,
126 reason: String,
127 ) {
128 self.failed.push(TransportListenerFailure {
129 transport: transport.to_string(),
130 bind_addr: bind_addr.to_string(),
131 explicit,
132 reason,
133 });
134 }
135}
136
137pub(crate) fn is_loopback_bind(bind_addr: &str) -> bool {
141 let host = bind_addr
142 .rsplit_once(':')
143 .map(|(host, _)| host.trim_matches(['[', ']']))
144 .unwrap_or(bind_addr);
145 if host.eq_ignore_ascii_case("localhost") {
146 return true;
147 }
148 host.parse::<std::net::IpAddr>()
149 .map(|addr| addr.is_loopback())
150 .unwrap_or(false)
151}