1pub mod request_limiter;
2
3use std::{io, mem::drop, net::SocketAddr, num::NonZeroU64, time::Duration};
4
5use bytes::Bytes;
6use futures::{FutureExt, StreamExt, future::BoxFuture};
7use futures_util::future::OptionFuture;
8use ipnet::IpNet;
9use listenfd::ListenFd;
10use smallvec::SmallVec;
11use socket2::SockRef;
12use tokio::{
13 io::AsyncWriteExt,
14 net::{TcpListener, TcpStream},
15 time::sleep,
16};
17use tokio_util::codec::Decoder;
18use tracing::Instrument;
19use vector_lib::{
20 EstimatedJsonEncodedSizeOf,
21 codecs::{ReadyFrames, StreamDecodingError, internal_events::DecoderFramingError},
22 config::{LegacyKey, LogNamespace, SourceAcknowledgementsConfig},
23 event::{BatchNotifier, BatchStatus, Event},
24 finalization::AddBatchNotifier,
25 lookup::{OwnedValuePath, path},
26 shutdown::ShutdownSignal,
27 source_sender::SourceSender,
28 tcp::TcpKeepaliveConfig,
29 tls::{
30 CertificateMetadata, MaybeTlsIncomingStream, MaybeTlsListener, MaybeTlsSettings,
31 TlsAcceptorReloader,
32 },
33};
34use vrl::value::ObjectMap;
35
36use self::request_limiter::RequestLimiter;
37use super::SocketListenAddr;
38use crate::{
39 config::SourceContext,
40 internal_events::{
41 ConnectionOpen, OpenGauge, SocketBindError, SocketEventsReceived, SocketMode,
42 SocketReceiveError, StreamClosedError, TcpBytesReceived, TcpSendAckError,
43 TcpSocketTlsConnectionError, TcpSocketTlsHandshakeTimeout, TcpSourceConnectionClosed,
44 },
45 net::is_graceful_tls_shutdown,
46 sources::util::{AfterReadExt, LenientFramedRead},
47};
48
49pub const MAX_IN_FLIGHT_EVENTS_TARGET: usize = 100_000;
50
51pub async fn try_bind_tcp_listener(
52 addr: SocketListenAddr,
53 mut listenfd: ListenFd,
54 tls: &MaybeTlsSettings,
55 tls_reloader: Option<TlsAcceptorReloader>,
56 allowlist: Option<Vec<IpNet>>,
57) -> crate::Result<MaybeTlsListener> {
58 match addr {
59 SocketListenAddr::SocketAddr(addr) => tls
60 .bind_reloadable(&addr, tls_reloader)
61 .await
62 .map_err(Into::into),
63 SocketListenAddr::SystemdFd(offset) => match listenfd.take_tcp_listener(offset)? {
64 Some(listener) => TcpListener::from_std(listener)
65 .map(Into::into)
66 .map_err(Into::into),
67 None => {
68 Err(io::Error::new(io::ErrorKind::AddrInUse, "systemd fd already consumed").into())
69 }
70 },
71 }
72 .map(|listener| listener.with_allowlist(allowlist))
73}
74
75#[derive(Clone, Copy, Eq, PartialEq)]
76pub enum TcpSourceAck {
77 Ack,
78 Error,
79 Reject,
80}
81
82pub trait TcpSourceAcker {
83 fn build_ack(self, ack: TcpSourceAck) -> Option<Bytes>;
84}
85
86pub struct TcpNullAcker;
87
88impl TcpSourceAcker for TcpNullAcker {
89 fn build_ack(self, _ack: TcpSourceAck) -> Option<Bytes> {
92 None
93 }
94}
95
96pub trait TcpSource: Clone + Send + Sync + 'static
97where
98 <<Self as TcpSource>::Decoder as tokio_util::codec::Decoder>::Item: std::marker::Send,
99{
100 type Error: From<io::Error>
103 + StreamDecodingError
104 + std::fmt::Debug
105 + std::fmt::Display
106 + Send
107 + Unpin;
108 type Item: Into<SmallVec<[Event; 1]>> + Send + Unpin;
109 type Decoder: Decoder<Item = (Self::Item, usize), Error = Self::Error> + Send + 'static;
110 type Acker: TcpSourceAcker + Send;
111
112 fn decoder(&self) -> Self::Decoder;
113
114 fn handle_events(&self, _events: &mut [Event], _host: std::net::SocketAddr) {}
115
116 fn build_acker(&self, item: &[Self::Item]) -> Self::Acker;
117
118 #[allow(clippy::too_many_arguments)]
119 fn run(
120 self,
121 addr: SocketListenAddr,
122 keepalive: Option<TcpKeepaliveConfig>,
123 shutdown_timeout_secs: Duration,
124 tls: MaybeTlsSettings,
125 tls_reloader: Option<TlsAcceptorReloader>,
126 tls_client_metadata_key: Option<OwnedValuePath>,
127 receive_buffer_bytes: Option<usize>,
128 max_connection_duration_secs: Option<u64>,
129 tls_handshake_timeout_secs: Option<NonZeroU64>,
130 cx: SourceContext,
131 acknowledgements: SourceAcknowledgementsConfig,
132 max_connections: Option<u32>,
133 allowlist: Option<Vec<IpNet>>,
134 source_name: &'static str,
135 log_namespace: LogNamespace,
136 ) -> crate::Result<crate::sources::Source> {
137 let acknowledgements = cx.do_acknowledgements(acknowledgements);
138
139 Ok(Box::pin(async move {
140 let listenfd = ListenFd::from_env();
141 let listener = try_bind_tcp_listener(addr, listenfd, &tls, tls_reloader, allowlist)
142 .await
143 .map_err(|error| {
144 emit!(SocketBindError {
145 mode: SocketMode::Tcp,
146 error: &error,
147 })
148 })?;
149
150 info!(
151 message = "Listening.",
152 addr = %listener
153 .local_addr()
154 .map(SocketListenAddr::SocketAddr)
155 .unwrap_or(addr)
156 );
157
158 let tripwire = cx.shutdown.clone();
159 let tripwire = async move {
160 _ = tripwire.await;
161 sleep(shutdown_timeout_secs).await;
162 }
163 .shared();
164
165 let connection_gauge = OpenGauge::new();
166 let shutdown_clone = cx.shutdown.clone();
167
168 let request_limiter =
169 RequestLimiter::new(MAX_IN_FLIGHT_EVENTS_TARGET, crate::num_threads());
170
171 listener
172 .accept_stream_limited(max_connections)
173 .take_until(shutdown_clone)
174 .for_each(move |(connection, tcp_connection_permit)| {
175 let shutdown_signal = cx.shutdown.clone();
176 let tripwire = tripwire.clone();
177 let source = self.clone();
178 let out = cx.out.clone();
179 let connection_gauge = connection_gauge.clone();
180 let request_limiter = request_limiter.clone();
181 let tls_client_metadata_key = tls_client_metadata_key.clone();
182
183 async move {
184 let socket = match connection {
185 Ok(socket) => socket,
186 Err(error) => {
187 emit!(SocketReceiveError {
188 mode: SocketMode::Tcp,
189 error: &error
190 });
191 return;
192 }
193 };
194
195 let peer_addr = socket.peer_addr();
196 let span = info_span!("connection", %peer_addr);
197
198 let tripwire = tripwire
199 .map(move |_| {
200 info!(
201 message = "Resetting connection (still open after seconds).",
202 seconds = ?shutdown_timeout_secs
203 );
204 })
205 .boxed();
206
207 span.clone().in_scope(|| {
208 debug!(message = "Accepted a new connection.", peer_addr = %peer_addr);
209
210 let open_token =
211 connection_gauge.open(|count| emit!(ConnectionOpen { count }));
212
213 let fut = handle_stream(
214 shutdown_signal,
215 socket,
216 keepalive,
217 receive_buffer_bytes,
218 max_connection_duration_secs,
219 tls_handshake_timeout_secs,
220 source,
221 tripwire,
222 peer_addr,
223 out,
224 acknowledgements,
225 request_limiter,
226 tls_client_metadata_key.clone(),
227 source_name,
228 log_namespace,
229 );
230
231 tokio::spawn(
232 fut.map(move |()| {
233 drop(open_token);
234 emit!(TcpSourceConnectionClosed);
240 drop(tcp_connection_permit);
241 })
242 .instrument(span.or_current()),
243 );
244 });
245 }
246 })
247 .map(Ok)
248 .await
249 }))
250 }
251}
252
253#[allow(clippy::too_many_arguments)]
254async fn handle_stream<T>(
255 mut shutdown_signal: ShutdownSignal,
256 mut socket: MaybeTlsIncomingStream<TcpStream>,
257 keepalive: Option<TcpKeepaliveConfig>,
258 receive_buffer_bytes: Option<usize>,
259 max_connection_duration_secs: Option<u64>,
260 tls_handshake_timeout_secs: Option<NonZeroU64>,
261 source: T,
262 mut tripwire: BoxFuture<'static, ()>,
263 peer_addr: SocketAddr,
264 mut out: SourceSender,
265 acknowledgements: bool,
266 request_limiter: RequestLimiter,
267 tls_client_metadata_key: Option<OwnedValuePath>,
268 source_name: &'static str,
269 log_namespace: LogNamespace,
270) where
271 <<T as TcpSource>::Decoder as tokio_util::codec::Decoder>::Item: std::marker::Send,
272 T: TcpSource,
273{
274 let handshake_timeout = OptionFuture::from(
275 tls_handshake_timeout_secs.map(|secs| tokio::time::sleep(Duration::from_secs(secs.get()))),
276 );
277 tokio::pin!(handshake_timeout);
278
279 tokio::select! {
280 result = socket.handshake() => {
281 if let Err(error) = result {
282 emit!(TcpSocketTlsConnectionError { error });
283 return;
284 }
285 },
286 Some(_) = &mut handshake_timeout => {
287 emit!(TcpSocketTlsHandshakeTimeout {
288 peer_addr,
289 timeout: Duration::from_secs(
290 tls_handshake_timeout_secs.map_or(0, NonZeroU64::get),
291 ),
292 });
293 return;
294 },
295 _ = &mut shutdown_signal => {
296 return;
297 }
298 };
299
300 if let Some(keepalive) = keepalive
301 && let Err(error) = socket.set_keepalive(keepalive)
302 {
303 warn!(message = "Failed configuring TCP keepalive.", %error);
304 }
305
306 if let Some(receive_buffer_bytes) = receive_buffer_bytes
307 && let Err(error) = socket.set_receive_buffer_bytes(receive_buffer_bytes)
308 {
309 warn!(message = "Failed configuring receive buffer size on TCP socket.", %error);
310 }
311
312 let socket = socket.after_read(move |byte_size| {
313 emit!(TcpBytesReceived {
314 byte_size,
315 peer_addr
316 });
317 });
318
319 let certificate_metadata = socket
320 .get_ref()
321 .ssl_stream()
322 .and_then(|stream| stream.ssl().peer_certificate())
323 .map(CertificateMetadata::from);
324
325 let reader = LenientFramedRead::new(socket, source.decoder());
326
327 let mut reader = ReadyFrames::new(reader);
328
329 let connection_close_timeout = OptionFuture::from(
330 max_connection_duration_secs
331 .map(|timeout_secs| tokio::time::sleep(Duration::from_secs(timeout_secs))),
332 );
333
334 tokio::pin!(connection_close_timeout);
335
336 loop {
337 let mut permit = tokio::select! {
338 _ = &mut tripwire => break,
339 Some(_) = &mut connection_close_timeout => {
340 if close_socket(reader.get_ref().get_ref().get_ref()) {
341 break;
342 }
343 None
344 },
345 _ = &mut shutdown_signal => {
346 if close_socket(reader.get_ref().get_ref().get_ref()) {
347 break;
348 }
349 None
350 },
351 permit = request_limiter.acquire() => {
352 Some(permit)
353 }
354 else => break,
355 };
356
357 let timeout = tokio::time::sleep(Duration::from_millis(10));
358 tokio::pin!(timeout);
359
360 tokio::select! {
361 _ = &mut tripwire => break,
362 _ = &mut shutdown_signal => {
363 if close_socket(reader.get_ref().get_ref().get_ref()) {
364 break;
365 }
366 },
367 _ = &mut timeout => {
368 continue;
371 }
372 res = reader.next() => {
373 match res {
374 Some(Ok((frames, _byte_size))) => {
375 let _num_frames = frames.len();
376 let acker = source.build_acker(&frames);
377 let (batch, receiver) = BatchNotifier::maybe_new_with_receiver(acknowledgements);
378
379 let mut events = frames.into_iter().flat_map(Into::into).collect::<Vec<Event>>();
380 let count = events.len();
381
382 emit!(SocketEventsReceived {
383 mode: SocketMode::Tcp,
384 byte_size: events.estimated_json_encoded_size_of(),
385 count,
386 });
387
388 if let Some(permit) = &mut permit {
389 permit.decoding_finished(events.len());
393 }
394
395 if let Some(batch) = batch {
396 for event in &mut events {
397 event.add_batch_notifier(batch.clone());
398 }
399 }
400
401
402 if let Some(certificate_metadata) = &certificate_metadata {
403 let mut metadata = ObjectMap::new();
404 metadata.insert("subject".into(), certificate_metadata.subject().into());
405 for event in &mut events {
406 let log = event.as_mut_log();
407
408 log_namespace.insert_source_metadata(
409 source_name,
410 log,
411 tls_client_metadata_key.as_ref().map(LegacyKey::Overwrite),
412 path!("tls_client_metadata"),
413 metadata.clone()
414 );
415 }
416 }
417
418 source.handle_events(&mut events, peer_addr);
419 match out.send_batch(events).await {
420 Ok(_) => {
421 let ack = match receiver {
422 None => TcpSourceAck::Ack,
423 Some(receiver) =>
424 match receiver.await {
425 BatchStatus::Delivered => TcpSourceAck::Ack,
426 BatchStatus::Errored => {TcpSourceAck::Error},
427 BatchStatus::Rejected => {
428 TcpSourceAck::Reject
430 }
431 }
432 };
433 if let Some(ack_bytes) = acker.build_ack(ack){
434 let stream = reader.get_mut().get_mut();
435 if let Err(error) = stream.write_all(&ack_bytes).await {
436 if is_graceful_tls_shutdown(&error) {
442 warn!(
443 message = "Connection closed by peer before acknowledgement could be sent.",
444 error = %error,
445 );
446 } else {
447 emit!(TcpSendAckError { error });
448 }
449 break;
450 }
451 }
452 if ack != TcpSourceAck::Ack {
453 break;
454 }
455 }
456 Err(_) => {
457 emit!(StreamClosedError { count });
458 break;
459 }
460 }
461 }
462 Some(Err(error)) => {
463 if !<<T as TcpSource>::Error as StreamDecodingError>::can_continue(&error) {
464 emit!(DecoderFramingError { error });
465 break;
466 }
467 }
468 None => {
469 debug!("Connection closed.");
470 break
471 },
472 }
473 }
474 else => break,
475 }
476
477 drop(permit);
478 }
479}
480
481fn close_socket(socket: &MaybeTlsIncomingStream<TcpStream>) -> bool {
482 debug!("Start graceful shutdown.");
483 if let Some(stream) = socket.get_ref() {
486 let socket = SockRef::from(stream);
487 if let Err(error) = socket.shutdown(std::net::Shutdown::Write) {
488 warn!(message = "Failed in signalling to the other side to close the TCP channel.", %error);
489 }
490 false
491 } else {
492 debug!("Closing connection that hasn't yet been fully established.");
494 true
495 }
496}