1pub mod tcp;
2pub mod udp;
3#[cfg(unix)]
4mod unix;
5
6use vector_lib::{
7 codecs::decoding::DeserializerConfig,
8 config::{LegacyKey, LogNamespace, log_schema},
9 configurable::configurable_component,
10 lookup::{lookup_v2::OptionalValuePath, owned_value_path},
11};
12use vrl::value::{Kind, kind::Collection};
13
14use crate::{
15 codecs::DecodingConfig,
16 config::{GenerateConfig, Resource, SourceConfig, SourceContext, SourceOutput},
17 sources::util::net::TcpSource,
18 tls::MaybeTlsSettings,
19};
20
21#[configurable_component(source("socket", "Collect logs over a socket."))]
23#[derive(Clone, Debug)]
24pub struct SocketConfig {
25 #[serde(flatten)]
26 pub mode: Mode,
27}
28
29#[configurable_component]
31#[derive(Clone, Debug)]
32#[serde(tag = "mode", rename_all = "snake_case")]
33#[configurable(metadata(docs::enum_tag_description = "The type of socket to use."))]
34#[allow(clippy::large_enum_variant)] pub enum Mode {
36 Tcp(tcp::TcpConfig),
38
39 Udp(udp::UdpConfig),
41
42 #[cfg(unix)]
44 UnixDatagram(unix::UnixConfig),
45
46 #[cfg(unix)]
48 #[serde(alias = "unix")]
49 UnixStream(unix::UnixConfig),
50}
51
52impl SocketConfig {
53 pub fn new_tcp(tcp_config: tcp::TcpConfig) -> Self {
54 tcp_config.into()
55 }
56
57 pub fn make_basic_tcp_config(addr: std::net::SocketAddr) -> Self {
58 tcp::TcpConfig::from_address(addr.into()).into()
59 }
60
61 fn decoding(&self) -> DeserializerConfig {
62 match &self.mode {
63 Mode::Tcp(config) => config.decoding().clone(),
64 Mode::Udp(config) => config.decoding().clone(),
65 #[cfg(unix)]
66 Mode::UnixDatagram(config) => config.decoding().clone(),
67 #[cfg(unix)]
68 Mode::UnixStream(config) => config.decoding().clone(),
69 }
70 }
71
72 fn log_namespace(&self, global_log_namespace: LogNamespace) -> LogNamespace {
73 match &self.mode {
74 Mode::Tcp(config) => global_log_namespace.merge(config.log_namespace),
75 Mode::Udp(config) => global_log_namespace.merge(config.log_namespace),
76 #[cfg(unix)]
77 Mode::UnixDatagram(config) => global_log_namespace.merge(config.log_namespace),
78 #[cfg(unix)]
79 Mode::UnixStream(config) => global_log_namespace.merge(config.log_namespace),
80 }
81 }
82}
83
84impl From<tcp::TcpConfig> for SocketConfig {
85 fn from(config: tcp::TcpConfig) -> Self {
86 SocketConfig {
87 mode: Mode::Tcp(config),
88 }
89 }
90}
91
92impl From<udp::UdpConfig> for SocketConfig {
93 fn from(config: udp::UdpConfig) -> Self {
94 SocketConfig {
95 mode: Mode::Udp(config),
96 }
97 }
98}
99
100impl GenerateConfig for SocketConfig {
101 fn generate_config() -> toml::Value {
102 toml::from_str(
103 r#"mode = "tcp"
104 address = "0.0.0.0:9000""#,
105 )
106 .unwrap()
107 }
108}
109
110#[async_trait::async_trait]
111#[typetag::serde(name = "socket")]
112impl SourceConfig for SocketConfig {
113 async fn build(&self, cx: SourceContext) -> crate::Result<super::Source> {
114 match self.mode.clone() {
115 Mode::Tcp(config) => {
116 let log_namespace = cx.log_namespace(config.log_namespace);
117
118 let decoding = config.decoding().clone();
119 let decoder = DecodingConfig::new(
120 config
121 .framing
122 .clone()
123 .unwrap_or_else(|| decoding.default_stream_framing()),
124 decoding,
125 log_namespace,
126 )
127 .build()?;
128
129 let tcp = tcp::RawTcpSource::new(config.clone(), decoder, log_namespace);
130 let tls_config = config.tls().as_ref().map(|tls| tls.tls_config.clone());
131 let tls_client_metadata_key = config
132 .tls()
133 .as_ref()
134 .and_then(|tls| tls.client_metadata_key.clone())
135 .and_then(|k| k.path);
136 let tls = MaybeTlsSettings::from_config(tls_config.as_ref(), true)?;
137 tcp.run(
138 config.address(),
139 config.keepalive(),
140 config.shutdown_timeout_secs(),
141 tls,
142 None, tls_client_metadata_key,
144 config.receive_buffer_bytes(),
145 config.max_connection_duration_secs(),
146 cx,
147 false.into(),
148 config.connection_limit,
149 config.permit_origin.map(Into::into),
150 SocketConfig::NAME,
151 log_namespace,
152 )
153 }
154 Mode::Udp(config) => {
155 let log_namespace = cx.log_namespace(config.log_namespace);
156 let decoding = config.decoding().clone();
157 let framing = config
158 .framing()
159 .clone()
160 .unwrap_or_else(|| decoding.default_message_based_framing());
161 let decoder = DecodingConfig::new(framing, decoding, log_namespace).build()?;
162 Ok(udp::udp(
163 config,
164 decoder,
165 cx.shutdown,
166 cx.out,
167 log_namespace,
168 ))
169 }
170 #[cfg(unix)]
171 Mode::UnixDatagram(config) => {
172 let log_namespace = cx.log_namespace(config.log_namespace);
173 let decoding = config.decoding.clone();
174 let framing = config
175 .framing
176 .clone()
177 .unwrap_or_else(|| decoding.default_message_based_framing());
178 let decoder = DecodingConfig::new(framing, decoding, log_namespace).build()?;
179
180 unix::unix_datagram(config, decoder, cx.shutdown, cx.out, log_namespace)
181 }
182 #[cfg(unix)]
183 Mode::UnixStream(config) => {
184 let log_namespace = cx.log_namespace(config.log_namespace);
185
186 let decoding = config.decoding().clone();
187 let decoder = DecodingConfig::new(
188 config
189 .framing
190 .clone()
191 .unwrap_or_else(|| decoding.default_stream_framing()),
192 decoding,
193 log_namespace,
194 )
195 .build()?;
196
197 unix::unix_stream(config, decoder, cx.shutdown, cx.out, log_namespace)
198 }
199 }
200 }
201
202 fn outputs(&self, global_log_namespace: LogNamespace) -> Vec<SourceOutput> {
203 let log_namespace = self.log_namespace(global_log_namespace);
204
205 let schema_definition = self
206 .decoding()
207 .schema_definition(log_namespace)
208 .with_standard_vector_source_metadata();
209
210 let schema_definition = match &self.mode {
211 Mode::Tcp(config) => {
212 let legacy_host_key = config.host_key().path.map(LegacyKey::InsertIfEmpty);
213
214 let legacy_port_key = config.port_key().clone().path.map(LegacyKey::InsertIfEmpty);
215
216 let tls_client_metadata_path = config
217 .tls()
218 .as_ref()
219 .and_then(|tls| tls.client_metadata_key.as_ref())
220 .and_then(|k| k.path.clone())
221 .map(LegacyKey::Overwrite);
222
223 schema_definition
224 .with_source_metadata(
225 Self::NAME,
226 legacy_host_key,
227 &owned_value_path!("host"),
228 Kind::bytes(),
229 Some("host"),
230 )
231 .with_source_metadata(
232 Self::NAME,
233 legacy_port_key,
234 &owned_value_path!("port"),
235 Kind::integer(),
236 None,
237 )
238 .with_source_metadata(
239 Self::NAME,
240 tls_client_metadata_path,
241 &owned_value_path!("tls_client_metadata"),
242 Kind::object(Collection::empty().with_unknown(Kind::bytes()))
243 .or_undefined(),
244 None,
245 )
246 }
247 Mode::Udp(config) => {
248 let legacy_host_key = config.host_key().path.map(LegacyKey::InsertIfEmpty);
249
250 let legacy_port_key = config.port_key().clone().path.map(LegacyKey::InsertIfEmpty);
251
252 schema_definition
253 .with_source_metadata(
254 Self::NAME,
255 legacy_host_key,
256 &owned_value_path!("host"),
257 Kind::bytes(),
258 None,
259 )
260 .with_source_metadata(
261 Self::NAME,
262 legacy_port_key,
263 &owned_value_path!("port"),
264 Kind::integer(),
265 None,
266 )
267 }
268 #[cfg(unix)]
269 Mode::UnixDatagram(config) => {
270 let legacy_host_key = config.host_key().clone().path.map(LegacyKey::InsertIfEmpty);
271
272 schema_definition.with_source_metadata(
273 Self::NAME,
274 legacy_host_key,
275 &owned_value_path!("host"),
276 Kind::bytes(),
277 None,
278 )
279 }
280 #[cfg(unix)]
281 Mode::UnixStream(config) => {
282 let legacy_host_key = config.host_key().clone().path.map(LegacyKey::InsertIfEmpty);
283
284 schema_definition.with_source_metadata(
285 Self::NAME,
286 legacy_host_key,
287 &owned_value_path!("host"),
288 Kind::bytes(),
289 None,
290 )
291 }
292 };
293
294 vec![SourceOutput::new_maybe_logs(
295 self.decoding().output_type(),
296 schema_definition,
297 )]
298 }
299
300 fn resources(&self) -> Vec<Resource> {
301 match self.mode.clone() {
302 Mode::Tcp(tcp) => vec![tcp.address().as_tcp_resource()],
303 Mode::Udp(udp) => vec![udp.address().as_udp_resource()],
304 #[cfg(unix)]
305 Mode::UnixDatagram(_) => vec![],
306 #[cfg(unix)]
307 Mode::UnixStream(_) => vec![],
308 }
309 }
310
311 fn can_acknowledge(&self) -> bool {
312 false
313 }
314}
315
316pub(crate) fn default_host_key() -> OptionalValuePath {
317 log_schema().host_key().cloned().into()
318}
319
320#[cfg(test)]
321mod test {
322 use std::{
323 collections::HashMap,
324 net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket},
325 sync::{
326 Arc,
327 atomic::{AtomicBool, Ordering},
328 },
329 thread,
330 };
331
332 use approx::assert_relative_eq;
333 use bytes::{BufMut, Bytes, BytesMut};
334 use futures::{StreamExt, stream};
335 use rand::{SeedableRng, rngs::SmallRng, seq::SliceRandom};
336 use serde_json::json;
337 use tokio::{
338 io::AsyncReadExt,
339 net::TcpStream,
340 task::JoinHandle,
341 time::{Duration, Instant, timeout},
342 };
343 #[cfg(unix)]
344 use vector_lib::codecs::{
345 CharacterDelimitedDecoderConfig, decoding::CharacterDelimitedDecoderOptions,
346 };
347 use vector_lib::{
348 codecs::{GelfDeserializerConfig, NewlineDelimitedDecoderConfig},
349 event::EventContainer,
350 lookup::{lookup_v2::OptionalValuePath, owned_value_path, path},
351 };
352 use vrl::{btreemap, value, value::ObjectMap};
353 #[cfg(unix)]
354 use {
355 super::{Mode, unix::UnixConfig},
356 crate::sources::util::unix::UNNAMED_SOCKET_HOST,
357 crate::test_util::wait_for,
358 futures::{SinkExt, Stream},
359 std::future::ready,
360 std::os::unix::fs::PermissionsExt,
361 std::path::PathBuf,
362 tokio::{
363 io::AsyncWriteExt,
364 net::{UnixDatagram, UnixStream},
365 task::yield_now,
366 },
367 tokio_util::codec::{FramedWrite, LinesCodec},
368 };
369
370 use super::{SocketConfig, tcp::TcpConfig, udp::UdpConfig};
371 use crate::{
372 SourceSender,
373 config::{ComponentKey, GlobalOptions, SourceConfig, SourceContext, log_schema},
374 event::{Event, LogEvent},
375 shutdown::{ShutdownSignal, SourceShutdownCoordinator},
376 sinks::util::tcp::TcpSinkConfig,
377 sources::util::net::SocketListenAddr,
378 test_util::{
379 addr::{PortGuard, next_addr, next_addr_any},
380 collect_n, collect_n_limited,
381 components::{
382 COMPONENT_ERROR_TAGS, SOCKET_PUSH_SOURCE_TAGS, assert_source_compliance,
383 assert_source_error,
384 },
385 random_string, send_lines, send_lines_tls, wait_for_tcp,
386 },
387 tls::{self, TlsConfig, TlsEnableableConfig, TlsSourceConfig},
388 };
389
390 async fn wait_for_tcp_and_release(guard: PortGuard, addr: SocketAddr) {
391 wait_for_tcp(addr).await;
392 drop(guard) }
394
395 pub fn bind_unused_udp() -> UdpSocket {
396 UdpSocket::bind((IpAddr::V4(Ipv4Addr::LOCALHOST), 0))
398 .expect("Failed to bind UDP socket to OS-assigned port")
399 }
400
401 pub fn bind_unused_udp_multicast() -> UdpSocket {
405 let socket = UdpSocket::bind((IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0))
406 .expect("Failed to bind UDP socket to OS-assigned port");
407 socket2::SockRef::from(&socket)
408 .set_multicast_if_v4(&Ipv4Addr::LOCALHOST)
409 .expect("Failed to set multicast interface to loopback");
410 socket
411 }
412
413 fn get_gelf_payload(message: &str) -> String {
414 serde_json::to_string(&json!({
415 "version": "1.1",
416 "host": "example.org",
417 "short_message": message,
418 "timestamp": 1234567890.123,
419 "level": 6,
420 "_foo": "bar",
421 }))
422 .unwrap()
423 }
424
425 fn create_gelf_chunk(
426 message_id: u64,
427 sequence_number: u8,
428 total_chunks: u8,
429 payload: &[u8],
430 ) -> Bytes {
431 const GELF_MAGIC: [u8; 2] = [0x1e, 0x0f];
432 let mut chunk = BytesMut::new();
433 chunk.put_slice(&GELF_MAGIC);
434 chunk.put_u64(message_id);
435 chunk.put_u8(sequence_number);
436 chunk.put_u8(total_chunks);
437 chunk.put(payload);
438 chunk.freeze()
439 }
440
441 fn get_gelf_chunks(short_message: &str, max_size: usize, rng: &mut SmallRng) -> Vec<Bytes> {
442 let message_id = rand::random();
443 let payload = get_gelf_payload(short_message);
444 let payload_chunks = payload.as_bytes().chunks(max_size).collect::<Vec<_>>();
445 let total_chunks = payload_chunks.len();
446 assert!(total_chunks <= 128, "too many gelf chunks");
447
448 let mut chunks = payload_chunks
449 .into_iter()
450 .enumerate()
451 .map(|(i, payload_chunk)| {
452 create_gelf_chunk(message_id, i as u8, total_chunks as u8, payload_chunk)
453 })
454 .collect::<Vec<_>>();
455 chunks.shuffle(rng);
457 chunks
458 }
459
460 #[test]
461 fn generate_config() {
462 crate::test_util::test_generate_config::<SocketConfig>();
463 }
464
465 #[tokio::test]
467 async fn tcp_it_includes_host() {
468 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
469 let (tx, mut rx) = SourceSender::new_test();
470 let (guard, addr) = next_addr();
471
472 let server = SocketConfig::from(TcpConfig::from_address(addr.into()))
473 .build(SourceContext::new_test(tx, None))
474 .await
475 .unwrap();
476 tokio::spawn(server);
477
478 wait_for_tcp_and_release(guard, addr).await;
479
480 let addr = send_lines(addr, vec!["test".to_owned()].into_iter())
481 .await
482 .unwrap();
483
484 let event = rx.next().await.unwrap();
485
486 assert_eq!(event.as_log()["host"], addr.ip().to_string().into());
487 assert_eq!(event.as_log()["port"], addr.port().into());
488 })
489 .await;
490 }
491
492 #[tokio::test]
493 async fn tcp_it_includes_vector_namespaced_fields() {
494 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
495 let (tx, mut rx) = SourceSender::new_test();
496 let (guard, addr) = next_addr();
497 let mut conf = TcpConfig::from_address(addr.into());
498 conf.set_log_namespace(Some(true));
499
500 let server = SocketConfig::from(conf)
501 .build(SourceContext::new_test(tx, None))
502 .await
503 .unwrap();
504 tokio::spawn(server);
505
506 wait_for_tcp_and_release(guard, addr).await;
507
508 let addr = send_lines(addr, vec!["test".to_owned()].into_iter())
509 .await
510 .unwrap();
511
512 let event = rx.next().await.unwrap();
513 let log = event.as_log();
514 let event_meta = log.metadata().value();
515
516 assert_eq!(log.value(), &"test".into());
517 assert_eq!(
518 event_meta.get(path!("vector", "source_type")).unwrap(),
519 &value!(SocketConfig::NAME)
520 );
521 assert_eq!(
522 event_meta.get(path!(SocketConfig::NAME, "host")).unwrap(),
523 &value!(addr.ip().to_string())
524 );
525 assert_eq!(
526 event_meta.get(path!(SocketConfig::NAME, "port")).unwrap(),
527 &value!(addr.port())
528 );
529 })
530 .await;
531 }
532
533 #[tokio::test]
534 async fn tcp_splits_on_newline() {
535 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
536 let (tx, rx) = SourceSender::new_test();
537 let (guard, addr) = next_addr();
538
539 let server = SocketConfig::from(TcpConfig::from_address(addr.into()))
540 .build(SourceContext::new_test(tx, None))
541 .await
542 .unwrap();
543 tokio::spawn(server);
544
545 wait_for_tcp_and_release(guard, addr).await;
546
547 send_lines(addr, vec!["foo\nbar".to_owned()].into_iter())
548 .await
549 .unwrap();
550
551 let events = collect_n(rx, 2).await;
552
553 assert_eq!(events.len(), 2);
554 assert_eq!(
555 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
556 "foo".into()
557 );
558 assert_eq!(
559 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
560 "bar".into()
561 );
562 })
563 .await;
564 }
565
566 #[tokio::test]
567 async fn tcp_it_includes_source_type() {
568 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
569 let (tx, mut rx) = SourceSender::new_test();
570 let (guard, addr) = next_addr();
571
572 let server = SocketConfig::from(TcpConfig::from_address(addr.into()))
573 .build(SourceContext::new_test(tx, None))
574 .await
575 .unwrap();
576 tokio::spawn(server);
577
578 wait_for_tcp_and_release(guard, addr).await;
579 send_lines(addr, vec!["test".to_owned()].into_iter())
580 .await
581 .unwrap();
582
583 let event = rx.next().await.unwrap();
584 assert_eq!(
585 event.as_log()[log_schema().source_type_key().unwrap().to_string()],
586 "socket".into()
587 );
588 })
589 .await;
590 }
591
592 #[tokio::test]
593 async fn tcp_continue_after_long_line() {
594 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
595 let (tx, mut rx) = SourceSender::new_test();
596 let (guard, addr) = next_addr();
597
598 let mut config = TcpConfig::from_address(addr.into());
599 config.set_framing(Some(
600 NewlineDelimitedDecoderConfig::new_with_max_length(10).into(),
601 ));
602
603 let server = SocketConfig::from(config)
604 .build(SourceContext::new_test(tx, None))
605 .await
606 .unwrap();
607 tokio::spawn(server);
608
609 let lines = vec![
610 "short".to_owned(),
611 "this is too long".to_owned(),
612 "more short".to_owned(),
613 ];
614
615 wait_for_tcp_and_release(guard, addr).await;
616 send_lines(addr, lines.into_iter()).await.unwrap();
617
618 let event = rx.next().await.unwrap();
619 assert_eq!(
620 event.as_log()[log_schema().message_key().unwrap().to_string()],
621 "short".into()
622 );
623
624 let event = rx.next().await.unwrap();
625 assert_eq!(
626 event.as_log()[log_schema().message_key().unwrap().to_string()],
627 "more short".into()
628 );
629 })
630 .await;
631 }
632
633 #[tokio::test]
634 async fn tcp_with_tls() {
635 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
636 let (tx, mut rx) = SourceSender::new_test();
637 let (guard, addr) = next_addr();
638
639 let mut config = TcpConfig::from_address(addr.into());
640 config.set_tls(Some(TlsSourceConfig {
641 tls_config: TlsEnableableConfig {
642 enabled: Some(true),
643 options: TlsConfig {
644 verify_certificate: Some(true),
645 crt_file: Some(tls::TEST_PEM_CRT_PATH.into()),
646 key_file: Some(tls::TEST_PEM_KEY_PATH.into()),
647 ca_file: Some(tls::TEST_PEM_CA_PATH.into()),
648 ..Default::default()
649 },
650 },
651 client_metadata_key: Some(OptionalValuePath::from(owned_value_path!("tls_peer"))),
652 }));
653
654 let server = SocketConfig::from(config)
655 .build(SourceContext::new_test(tx, None))
656 .await
657 .unwrap();
658 tokio::spawn(server);
659
660 let lines = vec!["one line".to_owned(), "another line".to_owned()];
661
662 wait_for_tcp_and_release(guard, addr).await;
663 send_lines_tls(
664 addr,
665 "localhost".into(),
666 lines.into_iter(),
667 std::path::Path::new(tls::TEST_PEM_CA_PATH),
668 std::path::Path::new(tls::TEST_PEM_CLIENT_CRT_PATH),
669 std::path::Path::new(tls::TEST_PEM_CLIENT_KEY_PATH),
670 )
671 .await
672 .unwrap();
673
674 let event = rx.next().await.unwrap();
675 assert_eq!(
676 event.as_log()[log_schema().message_key().unwrap().to_string()],
677 "one line".into()
678 );
679
680 let tls_meta: ObjectMap = btreemap!(
681 "subject" => "CN=localhost,OU=Vector,O=Datadog,L=New York,ST=New York,C=US"
682 );
683
684 assert_eq!(event.as_log()["tls_peer"], tls_meta.clone().into(),);
685
686 let event = rx.next().await.unwrap();
687 assert_eq!(
688 event.as_log()[log_schema().message_key().unwrap().to_string()],
689 "another line".into()
690 );
691
692 assert_eq!(event.as_log()["tls_peer"], tls_meta.clone().into(),);
693 })
694 .await;
695 }
696
697 #[tokio::test]
698 async fn tcp_with_tls_vector_namespace() {
699 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
700 let (tx, mut rx) = SourceSender::new_test();
701 let (guard, addr) = next_addr();
702
703 let mut config = TcpConfig::from_address(addr.into());
704 config.set_tls(Some(TlsSourceConfig {
705 tls_config: TlsEnableableConfig {
706 enabled: Some(true),
707 options: TlsConfig {
708 verify_certificate: Some(true),
709 crt_file: Some(tls::TEST_PEM_CRT_PATH.into()),
710 key_file: Some(tls::TEST_PEM_KEY_PATH.into()),
711 ca_file: Some(tls::TEST_PEM_CA_PATH.into()),
712 ..Default::default()
713 },
714 },
715 client_metadata_key: None,
716 }));
717 config.log_namespace = Some(true);
718
719 let server = SocketConfig::from(config)
720 .build(SourceContext::new_test(tx, None))
721 .await
722 .unwrap();
723 tokio::spawn(server);
724
725 let lines = vec!["one line".to_owned(), "another line".to_owned()];
726
727 wait_for_tcp_and_release(guard, addr).await;
728 send_lines_tls(
729 addr,
730 "localhost".into(),
731 lines.into_iter(),
732 std::path::Path::new(tls::TEST_PEM_CA_PATH),
733 std::path::Path::new(tls::TEST_PEM_CLIENT_CRT_PATH),
734 std::path::Path::new(tls::TEST_PEM_CLIENT_KEY_PATH),
735 )
736 .await
737 .unwrap();
738
739 let event = rx.next().await.unwrap();
740 let log = event.as_log();
741 let event_meta = log.metadata().value();
742
743 assert_eq!(log.value(), &"one line".into());
744
745 let tls_meta: ObjectMap = btreemap!(
746 "subject" => "CN=localhost,OU=Vector,O=Datadog,L=New York,ST=New York,C=US"
747 );
748
749 assert_eq!(
750 event_meta
751 .get(path!(SocketConfig::NAME, "tls_client_metadata"))
752 .unwrap(),
753 &value!(tls_meta.clone())
754 );
755
756 let event = rx.next().await.unwrap();
757 let log = event.as_log();
758 let event_meta = log.metadata().value();
759
760 assert_eq!(log.value(), &"another line".into());
761
762 assert_eq!(
763 event_meta
764 .get(path!(SocketConfig::NAME, "tls_client_metadata"))
765 .unwrap(),
766 &value!(tls_meta.clone())
767 );
768 })
769 .await;
770 }
771
772 #[tokio::test]
773 async fn tcp_shutdown_simple() {
774 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
775 let source_id = ComponentKey::from("tcp_shutdown_simple");
776 let (tx, mut rx) = SourceSender::new_test();
777 let (guard, addr) = next_addr();
778 let (cx, mut shutdown) = SourceContext::new_shutdown(&source_id, tx);
779
780 let server = SocketConfig::from(TcpConfig::from_address(addr.into()))
782 .build(cx)
783 .await
784 .unwrap();
785 let source_handle = tokio::spawn(server);
786
787 wait_for_tcp_and_release(guard, addr).await;
789 send_lines(addr, vec!["test".to_owned()].into_iter())
790 .await
791 .unwrap();
792
793 let event = rx.next().await.unwrap();
794 assert_eq!(
795 event.as_log()[log_schema().message_key().unwrap().to_string()],
796 "test".into()
797 );
798
799 let deadline = Instant::now() + Duration::from_secs(10);
801 let shutdown_complete = shutdown.shutdown_source(&source_id, deadline);
802 let shutdown_success = shutdown_complete.await;
803 assert!(shutdown_success);
804
805 _ = source_handle.await.unwrap();
807 })
808 .await;
809 }
810
811 #[tokio::test]
814 async fn tcp_shutdown_infinite_stream() {
815 let (guard, addr) = next_addr();
820
821 let (source_tx, source_rx) = SourceSender::new_test_sender_with_options(10_000, None);
822 let source_key = ComponentKey::from("tcp_shutdown_infinite_stream");
823 let (source_cx, mut shutdown) = SourceContext::new_shutdown(&source_key, source_tx);
824
825 let mut source_config = TcpConfig::from_address(addr.into());
826 source_config.set_shutdown_timeout_secs(1);
827 let source_task = SocketConfig::from(source_config)
828 .build(source_cx)
829 .await
830 .unwrap();
831
832 let source_handle = tokio::spawn(source_task);
834 wait_for_tcp_and_release(guard, addr).await;
835
836 let message = random_string(512);
840 let message_bytes = Bytes::from(message.clone());
841
842 #[derive(Clone, Debug)]
843 struct Serializer {
844 bytes: Bytes,
845 }
846 impl tokio_util::codec::Encoder<Event> for Serializer {
847 type Error = vector_lib::codecs::encoding::Error;
848
849 fn encode(&mut self, _: Event, buffer: &mut BytesMut) -> Result<(), Self::Error> {
850 buffer.put(self.bytes.as_ref());
851 buffer.put_u8(b'\n');
852 Ok(())
853 }
854 }
855 let sink_config = TcpSinkConfig::from_address(format!("localhost:{}", addr.port()));
856 let encoder = Serializer {
857 bytes: message_bytes,
858 };
859 let (sink, _healthcheck) = sink_config.build(Default::default(), encoder).unwrap();
860
861 tokio::spawn(async move {
862 let input = stream::repeat_with(|| LogEvent::default().into()).boxed();
863 sink.run(input).await.unwrap();
864 });
865
866 let events = collect_n_limited(source_rx, 100)
870 .await
871 .into_iter()
872 .collect::<Vec<_>>();
873 assert_eq!(100, events.len());
874
875 let message_key = log_schema().message_key().unwrap().to_string();
876 let expected_message = message.clone().into();
877 for event in events.into_iter().flat_map(EventContainer::into_events) {
878 assert_eq!(event.as_log()[message_key.as_str()], expected_message);
879 }
880
881 let shutdown_timeout_limit = Duration::from_secs(10);
884 let deadline = Instant::now() + shutdown_timeout_limit;
885 let shutdown_complete = shutdown.shutdown_source(&source_key, deadline);
886
887 let shutdown_result = timeout(shutdown_timeout_limit, shutdown_complete).await;
888 assert_eq!(shutdown_result, Ok(true));
889
890 let source_result = source_handle.await.expect("source task should not panic");
891 assert_eq!(source_result, Ok(()));
892 }
893
894 #[tokio::test]
895 async fn tcp_connection_close_after_max_duration() {
896 let (tx, _) = SourceSender::new_test();
897 let (guard, addr) = next_addr();
898
899 let mut source_config = TcpConfig::from_address(addr.into());
900 source_config.set_max_connection_duration_secs(Some(1));
901 let source_task = SocketConfig::from(source_config)
902 .build(SourceContext::new_test(tx, None))
903 .await
904 .unwrap();
905
906 drop(tokio::spawn(source_task));
908 wait_for_tcp_and_release(guard, addr).await;
909
910 let mut stream: TcpStream = TcpStream::connect(addr)
911 .await
912 .expect("stream should be able to connect");
913 let start = Instant::now();
914
915 let timeout = tokio::time::sleep(Duration::from_millis(1200));
916 let mut buffer = [0u8; 10];
917
918 tokio::select! {
919 _ = timeout => {
920 panic!("timed out waiting for stream to close")
921 },
922 read_result = stream.read(&mut buffer) => {
923 match read_result {
924 Ok(0) => assert_relative_eq!(start.elapsed().as_secs_f64(), 1.0, epsilon = 0.3),
926 Ok(_) => panic!("unexpectedly read data from stream"),
927 Err(e) => panic!("{e:}")
928 }
929 }
930 }
931 }
932
933 async fn send_lines_udp(to: SocketAddr, lines: impl IntoIterator<Item = String>) -> UdpSocket {
935 send_lines_udp_from(bind_unused_udp(), to, lines)
936 }
937
938 fn send_lines_udp_from(
939 from: UdpSocket,
940 to: SocketAddr,
941 lines: impl IntoIterator<Item = String>,
942 ) -> UdpSocket {
943 send_packets_udp_from(from, to, lines.into_iter().map(|line| line.into()))
944 }
945
946 async fn send_packets_udp(
947 to: SocketAddr,
948 packets: impl IntoIterator<Item = Bytes>,
949 ) -> UdpSocket {
950 send_packets_udp_from(bind_unused_udp(), to, packets)
951 }
952
953 fn send_packets_udp_from(
954 from: UdpSocket,
955 to: SocketAddr,
956 packets: impl IntoIterator<Item = Bytes>,
957 ) -> UdpSocket {
958 for packet in packets {
959 assert_eq!(
960 from.send_to(&packet, to)
961 .map_err(|error| panic!("{error:}"))
962 .ok()
963 .unwrap(),
964 packet.len()
965 );
966 thread::sleep(Duration::from_millis(1));
968 }
969
970 thread::sleep(Duration::from_millis(10));
972
973 from
975 }
976
977 async fn init_udp_with_shutdown(
978 sender: SourceSender,
979 source_id: &ComponentKey,
980 shutdown: &mut SourceShutdownCoordinator,
981 ) -> (SocketAddr, JoinHandle<Result<(), ()>>) {
982 let (shutdown_signal, _) = shutdown.register_source(source_id, false);
983 init_udp_inner(sender, source_id, shutdown_signal, None, false).await
984 }
985
986 async fn init_udp(sender: SourceSender, use_log_namespace: bool) -> SocketAddr {
987 init_udp_inner(
988 sender,
989 &ComponentKey::from("default"),
990 ShutdownSignal::noop(),
991 None,
992 use_log_namespace,
993 )
994 .await
995 .0
996 }
997
998 async fn init_udp_with_config(sender: SourceSender, config: UdpConfig) -> SocketAddr {
999 init_udp_inner(
1000 sender,
1001 &ComponentKey::from("default"),
1002 ShutdownSignal::noop(),
1003 Some(config),
1004 false,
1005 )
1006 .await
1007 .0
1008 }
1009
1010 async fn init_udp_inner(
1011 sender: SourceSender,
1012 source_key: &ComponentKey,
1013 shutdown_signal: ShutdownSignal,
1014 config: Option<UdpConfig>,
1015 use_vector_namespace: bool,
1016 ) -> (SocketAddr, JoinHandle<Result<(), ()>>) {
1017 let (guard, address, mut config) = match config {
1018 Some(config) => match config.address() {
1019 SocketListenAddr::SocketAddr(addr) => (None, addr, config),
1020 _ => panic!("listen address should not be systemd FD offset in tests"),
1021 },
1022 None => {
1023 let (guard, address) = next_addr();
1024 (
1025 Some(guard),
1026 address,
1027 UdpConfig::from_address(address.into()),
1028 )
1029 }
1030 };
1031
1032 let config = if use_vector_namespace {
1033 config.set_log_namespace(Some(true));
1034 config
1035 } else {
1036 config
1037 };
1038
1039 let server = SocketConfig::from(config)
1040 .build(SourceContext {
1041 key: source_key.clone(),
1042 globals: GlobalOptions::default(),
1043 enrichment_tables: Default::default(),
1044 shutdown: shutdown_signal,
1045 out: sender,
1046 proxy: Default::default(),
1047 acknowledgements: false,
1048 schema: Default::default(),
1049 schema_definitions: HashMap::default(),
1050 extra_context: Default::default(),
1051 metrics_storage: Default::default(),
1052 })
1053 .await
1054 .unwrap();
1055 let source_handle = tokio::spawn(server);
1056
1057 tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
1059
1060 if let Some(guard) = guard {
1061 drop(guard)
1062 }
1063
1064 (address, source_handle)
1065 }
1066
1067 #[tokio::test]
1068 async fn udp_message() {
1069 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1070 let (tx, rx) = SourceSender::new_test();
1071 let address = init_udp(tx, false).await;
1072
1073 send_lines_udp(address, vec!["test".to_string()]).await;
1074 let events = collect_n(rx, 1).await;
1075
1076 assert_eq!(
1077 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1078 "test".into()
1079 );
1080 })
1081 .await;
1082 }
1083
1084 #[tokio::test]
1085 async fn udp_message_preserves_newline() {
1086 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1087 let (tx, rx) = SourceSender::new_test();
1088 let address = init_udp(tx, false).await;
1089
1090 send_lines_udp(address, vec!["foo\nbar".to_string()]).await;
1091 let events = collect_n(rx, 1).await;
1092
1093 assert_eq!(
1094 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1095 "foo\nbar".into()
1096 );
1097 })
1098 .await;
1099 }
1100
1101 #[tokio::test]
1102 async fn udp_multiple_packets() {
1103 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1104 let (tx, rx) = SourceSender::new_test();
1105 let address = init_udp(tx, false).await;
1106
1107 send_lines_udp(address, vec!["test".to_string(), "test2".to_string()]).await;
1108 let events = collect_n(rx, 2).await;
1109
1110 assert_eq!(
1111 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1112 "test".into()
1113 );
1114 assert_eq!(
1115 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1116 "test2".into()
1117 );
1118 })
1119 .await;
1120 }
1121
1122 #[tokio::test]
1123 async fn udp_max_length() {
1124 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1125 let (tx, rx) = SourceSender::new_test();
1126 let (_, address) = next_addr();
1127 let mut config = UdpConfig::from_address(address.into());
1128 config.max_length = 11;
1129 let address = init_udp_with_config(tx, config).await;
1130
1131 send_lines_udp(
1132 address,
1133 vec![
1134 "short line".to_string(),
1135 "test with a long line".to_string(),
1136 "a short un".to_string(),
1137 ],
1138 )
1139 .await;
1140
1141 let events = collect_n(rx, 2).await;
1142 assert_eq!(
1143 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1144 "short line".into()
1145 );
1146 assert_eq!(
1147 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1148 "a short un".into()
1149 );
1150 })
1151 .await;
1152 }
1153
1154 #[cfg(unix)]
1155 #[tokio::test]
1156 async fn udp_max_length_delimited() {
1161 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1162 let (tx, rx) = SourceSender::new_test();
1163 let (_, address) = next_addr();
1164 let mut config = UdpConfig::from_address(address.into());
1165 config.max_length = 10;
1166 config.framing = Some(
1167 CharacterDelimitedDecoderConfig {
1168 character_delimited: CharacterDelimitedDecoderOptions::new(b',', None),
1169 }
1170 .into(),
1171 );
1172 let address = init_udp_with_config(tx, config).await;
1173
1174 send_lines_udp(
1175 address,
1176 vec!["test with, long line".to_string(), "short one".to_string()],
1177 )
1178 .await;
1179
1180 let events = collect_n(rx, 2).await;
1181 assert_eq!(
1182 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1183 "test with".into()
1184 );
1185 assert_eq!(
1186 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1187 "short one".into()
1188 );
1189 })
1190 .await;
1191 }
1192
1193 #[tokio::test]
1194 async fn udp_decodes_chunked_gelf_messages() {
1195 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1196 let (tx, rx) = SourceSender::new_test();
1197 let (_, address) = next_addr();
1198 let mut config = UdpConfig::from_address(address.into());
1199 config.decoding = GelfDeserializerConfig::default().into();
1200 let address = init_udp_with_config(tx, config).await;
1201 let seed = 42;
1202 let mut rng = SmallRng::seed_from_u64(seed);
1203 let max_size = 300;
1204 let big_message = "This is a very large message".repeat(500);
1205 let another_big_message = "This is another very large message".repeat(500);
1206 let mut chunks = get_gelf_chunks(big_message.as_str(), max_size, &mut rng);
1207 let mut another_chunks =
1208 get_gelf_chunks(another_big_message.as_str(), max_size, &mut rng);
1209 chunks.append(&mut another_chunks);
1210 chunks.shuffle(&mut rng);
1211
1212 send_packets_udp(address, chunks).await;
1213
1214 let events = collect_n(rx, 2).await;
1215 assert_eq!(
1216 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1217 big_message.into()
1218 );
1219 assert_eq!(
1220 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1221 another_big_message.into()
1222 );
1223 })
1224 .await;
1225 }
1226
1227 #[tokio::test]
1228 async fn udp_it_includes_host() {
1229 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1230 let (tx, rx) = SourceSender::new_test();
1231 let address = init_udp(tx, false).await;
1232
1233 let from = send_lines_udp(address, vec!["test".to_string()]).await;
1234 let events = collect_n(rx, 1).await;
1235
1236 assert_eq!(
1237 events[0].as_log()["host"],
1238 from.local_addr().unwrap().ip().to_string().into()
1239 );
1240 assert_eq!(
1241 events[0].as_log()["port"],
1242 from.local_addr().unwrap().port().into()
1243 );
1244 })
1245 .await;
1246 }
1247
1248 #[tokio::test]
1249 async fn udp_it_includes_vector_namespaced_fields() {
1250 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1251 let (tx, rx) = SourceSender::new_test();
1252 let address = init_udp(tx, true).await;
1253
1254 let from = send_lines_udp(address, vec!["test".to_string()]).await;
1255 let events = collect_n(rx, 1).await;
1256 let log = events[0].as_log();
1257 let event_meta = log.metadata().value();
1258
1259 assert_eq!(log.value(), &"test".into());
1260 assert_eq!(
1261 event_meta.get(path!("vector", "source_type")).unwrap(),
1262 &value!(SocketConfig::NAME)
1263 );
1264 assert_eq!(
1265 event_meta.get(path!(SocketConfig::NAME, "host")).unwrap(),
1266 &value!(from.local_addr().unwrap().ip().to_string())
1267 );
1268 assert_eq!(
1269 event_meta.get(path!(SocketConfig::NAME, "port")).unwrap(),
1270 &value!(from.local_addr().unwrap().port())
1271 );
1272 })
1273 .await;
1274 }
1275
1276 #[tokio::test]
1277 async fn udp_it_includes_source_type() {
1278 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1279 let (tx, rx) = SourceSender::new_test();
1280 let address = init_udp(tx, false).await;
1281
1282 _ = send_lines_udp(address, vec!["test".to_string()]).await;
1283 let events = collect_n(rx, 1).await;
1284
1285 assert_eq!(
1286 events[0].as_log()[log_schema().source_type_key().unwrap().to_string()],
1287 "socket".into()
1288 );
1289 })
1290 .await;
1291 }
1292
1293 #[tokio::test]
1294 async fn udp_shutdown_simple() {
1295 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1296 let (tx, rx) = SourceSender::new_test();
1297 let source_id = ComponentKey::from("udp_shutdown_simple");
1298
1299 let mut shutdown = SourceShutdownCoordinator::default();
1300 let (address, source_handle) =
1301 init_udp_with_shutdown(tx, &source_id, &mut shutdown).await;
1302
1303 send_lines_udp(address, vec!["test".to_string()]).await;
1304 let events = collect_n(rx, 1).await;
1305
1306 assert_eq!(
1307 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1308 "test".into()
1309 );
1310
1311 let deadline = Instant::now() + Duration::from_secs(10);
1313 let shutdown_complete = shutdown.shutdown_source(&source_id, deadline);
1314 let shutdown_success = shutdown_complete.await;
1315 assert!(shutdown_success);
1316
1317 _ = source_handle.await.unwrap();
1319 })
1320 .await;
1321 }
1322
1323 #[tokio::test]
1324 async fn udp_shutdown_infinite_stream() {
1325 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1326 let (tx, rx) = SourceSender::new_test();
1327 let source_id = ComponentKey::from("udp_shutdown_infinite_stream");
1328
1329 let mut shutdown = SourceShutdownCoordinator::default();
1330 let (address, source_handle) =
1331 init_udp_with_shutdown(tx, &source_id, &mut shutdown).await;
1332
1333 let run_pump_atomic_sender = Arc::new(AtomicBool::new(true));
1335 let run_pump_atomic_receiver = Arc::clone(&run_pump_atomic_sender);
1336 let pump_handle = tokio::task::spawn_blocking(move || {
1337 let handle = tokio::runtime::Handle::current();
1338 handle.block_on(send_lines_udp(
1339 address,
1340 std::iter::repeat("test".to_string())
1341 .take_while(move |_| run_pump_atomic_receiver.load(Ordering::Relaxed)),
1342 ));
1343 });
1344
1345 let events = collect_n(rx, 100).await;
1347 assert_eq!(100, events.len());
1348 for event in events {
1349 assert_eq!(
1350 event.as_log()[log_schema().message_key().unwrap().to_string()],
1351 "test".into()
1352 );
1353 }
1354
1355 let deadline = Instant::now() + Duration::from_secs(10);
1356 let shutdown_complete = shutdown.shutdown_source(&source_id, deadline);
1357 let shutdown_success = shutdown_complete.await;
1358 assert!(shutdown_success);
1359
1360 _ = source_handle.await.unwrap();
1362
1363 run_pump_atomic_sender.store(false, Ordering::Relaxed);
1365 assert!(pump_handle.await.is_ok());
1366 })
1367 .await;
1368 }
1369
1370 #[tokio::test]
1371 async fn multicast_udp_message() {
1372 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1373 let (tx, mut rx) = SourceSender::new_test();
1374 let (_guard, socket_address) = next_addr_any();
1376 let multicast_ip_address: Ipv4Addr = "224.0.0.2".parse().unwrap();
1377 let multicast_socket_address =
1378 SocketAddr::new(IpAddr::V4(multicast_ip_address), socket_address.port());
1379 let mut config = UdpConfig::from_address(socket_address.into());
1380 config.multicast_groups = vec![multicast_ip_address];
1381 config.multicast_interface = Some(Ipv4Addr::LOCALHOST);
1385 init_udp_with_config(tx, config).await;
1386
1387 send_lines_udp_from(
1390 bind_unused_udp_multicast(),
1391 multicast_socket_address,
1392 ["test".to_string()],
1393 );
1394
1395 let event = rx.next().await.expect("must receive an event");
1396 assert_eq!(
1397 event.as_log()[log_schema().message_key().unwrap().to_string()],
1398 "test".into()
1399 );
1400 })
1401 .await;
1402 }
1403
1404 #[tokio::test]
1405 async fn multiple_multicast_addresses_udp_message() {
1406 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1407 let (tx, mut rx) = SourceSender::new_test();
1408 let (_guard, socket_address) = next_addr_any();
1409 let multicast_ip_addresses = (2..12)
1410 .map(|i| format!("224.0.0.{i}").parse().unwrap())
1411 .collect::<Vec<Ipv4Addr>>();
1412 let multicast_ip_socket_addresses = multicast_ip_addresses
1413 .iter()
1414 .map(|ip_address| SocketAddr::new(IpAddr::V4(*ip_address), socket_address.port()))
1415 .collect::<Vec<SocketAddr>>();
1416 let mut config = UdpConfig::from_address(socket_address.into());
1417 config.multicast_groups = multicast_ip_addresses;
1418 config.multicast_interface = Some(Ipv4Addr::LOCALHOST);
1419 init_udp_with_config(tx, config).await;
1420
1421 let mut from = bind_unused_udp_multicast();
1422 for multicast_ip_socket_address in multicast_ip_socket_addresses {
1423 from = send_lines_udp_from(
1424 from,
1425 multicast_ip_socket_address,
1426 [multicast_ip_socket_address.to_string()],
1427 );
1428
1429 let event = rx.next().await.expect("must receive an event");
1430 assert_eq!(
1431 event.as_log()[log_schema().message_key().unwrap().to_string()],
1432 multicast_ip_socket_address.to_string().into()
1433 );
1434 }
1435 })
1436 .await;
1437 }
1438
1439 #[tokio::test]
1440 async fn multicast_and_unicast_udp_message() {
1441 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1442 let (tx, mut rx) = SourceSender::new_test();
1443 let (_guard, socket_address) = next_addr_any();
1444 let multicast_ip_address: Ipv4Addr = "224.0.0.2".parse().unwrap();
1445 let multicast_socket_address =
1446 SocketAddr::new(IpAddr::V4(multicast_ip_address), socket_address.port());
1447 let mut config = UdpConfig::from_address(socket_address.into());
1448 config.multicast_groups = vec![multicast_ip_address];
1449 config.multicast_interface = Some(Ipv4Addr::LOCALHOST);
1450 init_udp_with_config(tx, config).await;
1451
1452 let _ = send_lines_udp_from(
1455 bind_unused_udp_multicast(),
1456 multicast_socket_address,
1457 ["test".to_string()],
1458 );
1459 let event = rx.next().await.expect("must receive an event");
1460 assert_eq!(
1461 event.as_log()[log_schema().message_key().unwrap().to_string()],
1462 "test".into()
1463 );
1464
1465 let to = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), socket_address.port());
1468 send_lines_udp_from(bind_unused_udp(), to, ["test".to_string()]);
1472 let event = rx.next().await.expect("must receive an event");
1473 assert_eq!(
1474 event.as_log()[log_schema().message_key().unwrap().to_string()],
1475 "test".into()
1476 );
1477 })
1478 .await;
1479 }
1480
1481 #[tokio::test]
1482 async fn udp_invalid_multicast_group() {
1483 assert_source_error(&COMPONENT_ERROR_TAGS, async {
1484 let (tx, _rx) = SourceSender::new_test();
1485 let (_, socket_address) = next_addr_any();
1486 let invalid_multicast_ip_address: Ipv4Addr = "192.168.0.3".parse().unwrap();
1487 let mut config = UdpConfig::from_address(socket_address.into());
1488 config.multicast_groups = vec![invalid_multicast_ip_address];
1489 init_udp_with_config(tx, config).await;
1490 })
1491 .await;
1492 }
1493
1494 #[cfg(unix)]
1497 async fn init_unix(sender: SourceSender, stream: bool, use_vector_namespace: bool) -> PathBuf {
1498 init_unix_inner(sender, stream, use_vector_namespace, None).await
1499 }
1500
1501 #[cfg(unix)]
1502 async fn init_unix_with_config(
1503 sender: SourceSender,
1504 stream: bool,
1505 use_vector_namespace: bool,
1506 config: UnixConfig,
1507 ) -> PathBuf {
1508 init_unix_inner(sender, stream, use_vector_namespace, Some(config)).await
1509 }
1510
1511 #[cfg(unix)]
1512 async fn init_unix_inner(
1513 sender: SourceSender,
1514 stream: bool,
1515 use_vector_namespace: bool,
1516 config: Option<UnixConfig>,
1517 ) -> PathBuf {
1518 let mut config = config.unwrap_or_else(|| {
1519 UnixConfig::new(tempfile::tempdir().unwrap().keep().join("unix_test"))
1520 });
1521
1522 let in_path = config.path.clone();
1523
1524 if use_vector_namespace {
1525 config.log_namespace = Some(true);
1526 }
1527
1528 let mode = if stream {
1529 Mode::UnixStream(config)
1530 } else {
1531 Mode::UnixDatagram(config)
1532 };
1533
1534 let server = SocketConfig { mode }
1535 .build(SourceContext::new_test(sender, None))
1536 .await
1537 .unwrap();
1538 tokio::spawn(server);
1539
1540 while if stream {
1542 std::os::unix::net::UnixStream::connect(&in_path).is_err()
1543 } else {
1544 let socket = std::os::unix::net::UnixDatagram::unbound().unwrap();
1545 socket.connect(&in_path).is_err()
1546 } {
1547 yield_now().await;
1548 }
1549
1550 in_path
1551 }
1552
1553 #[cfg(unix)]
1554 async fn unix_send_lines(stream: bool, path: PathBuf, lines: &[&str]) {
1555 match stream {
1556 false => send_lines_unix_datagram(path, lines).await,
1557 true => send_lines_unix_stream(path, lines).await,
1558 }
1559 }
1560
1561 #[cfg(unix)]
1562 async fn unix_message(
1563 message: &str,
1564 stream: bool,
1565 use_vector_namespace: bool,
1566 ) -> (PathBuf, impl Stream<Item = Event> + use<>) {
1567 let (tx, rx) = SourceSender::new_test();
1568 let path = init_unix(tx, stream, use_vector_namespace).await;
1569 let path_clone = path.clone();
1570
1571 unix_send_lines(stream, path, &[message]).await;
1572
1573 (path_clone, rx)
1574 }
1575
1576 #[cfg(unix)]
1577 async fn unix_multiple_packets(stream: bool) {
1578 let (tx, rx) = SourceSender::new_test();
1579 let path = init_unix(tx, stream, false).await;
1580
1581 unix_send_lines(stream, path, &["test", "test2"]).await;
1582 let events = collect_n(rx, 2).await;
1583
1584 assert_eq!(2, events.len());
1585 assert_eq!(
1586 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1587 "test".into()
1588 );
1589 assert_eq!(
1590 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1591 "test2".into()
1592 );
1593 }
1594
1595 #[cfg(unix)]
1596 fn parses_unix_config(mode: &str) -> SocketConfig {
1597 serde_yaml::from_str::<SocketConfig>(&format!(
1598 "mode: \"{mode}\"\npath: \"/does/not/exist\""
1599 ))
1600 .unwrap()
1601 }
1602
1603 #[cfg(unix)]
1604 fn parses_unix_config_file_mode(mode: &str) -> SocketConfig {
1605 serde_yaml::from_str::<SocketConfig>(&format!(
1606 "mode: \"{mode}\"\npath: \"/does/not/exist\"\nsocket_file_mode: 511"
1607 ))
1608 .unwrap()
1609 }
1610
1611 #[cfg(unix)]
1613 async fn send_lines_unix_datagram(path: PathBuf, lines: &[&str]) {
1614 let packets = lines.iter().map(|line| Bytes::from(line.to_string()));
1615 send_packets_unix_datagram(path, packets).await;
1616 }
1617
1618 #[cfg(unix)]
1619 async fn send_packets_unix_datagram(path: PathBuf, packets: impl IntoIterator<Item = Bytes>) {
1620 let socket = UnixDatagram::unbound().unwrap();
1621 socket.connect(path).unwrap();
1622
1623 for packet in packets {
1624 socket.send(&packet).await.unwrap();
1625 }
1626 socket.shutdown(std::net::Shutdown::Both).unwrap();
1627 }
1628
1629 #[cfg(unix)]
1630 #[tokio::test]
1631 async fn unix_datagram_message() {
1632 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1633 let (_, rx) = unix_message("test", false, false).await;
1634 let events = collect_n(rx, 1).await;
1635
1636 assert_eq!(events.len(), 1);
1637 assert_eq!(
1638 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1639 "test".into()
1640 );
1641 assert_eq!(
1642 events[0].as_log()[log_schema().source_type_key().unwrap().to_string()],
1643 "socket".into()
1644 );
1645 assert_eq!(events[0].as_log()["host"], UNNAMED_SOCKET_HOST.into());
1646 })
1647 .await;
1648 }
1649
1650 #[ignore]
1651 #[cfg(unix)]
1652 #[tokio::test]
1653 async fn unix_datagram_socket_test() {
1654 use tempfile::tempdir;
1658 use tokio::net::UnixDatagram;
1659
1660 let tmp = tempdir().unwrap();
1661
1662 let tx_path = tmp.path().join("tx");
1663
1664 let tx_type = "bound";
1667
1668 let tx = if tx_type == "bound" {
1669 UnixDatagram::bind(&tx_path).unwrap()
1670 } else {
1671 UnixDatagram::unbound().unwrap()
1672 };
1673
1674 let rx_path = tmp.path().join("rx");
1680 let rx = UnixDatagram::bind(&rx_path).unwrap();
1681
1682 tx.connect(&rx_path).unwrap();
1684
1685 let bytes = b"hello world";
1687 tx.send(bytes).await.unwrap();
1688
1689 let mut buf = vec![0u8; 24];
1690 let (size, _) = rx.recv_from(&mut buf).await.unwrap();
1691
1692 let dgram = &buf[..size];
1693 assert_eq!(dgram, bytes);
1694 }
1695
1696 #[cfg(unix)]
1697 #[tokio::test]
1698 async fn unix_datagram_chunked_gelf_messages() {
1699 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1700 let (tx, rx) = SourceSender::new_test();
1701 let in_path = tempfile::tempdir().unwrap().keep().join("unix_test");
1702 let mut config = UnixConfig::new(in_path.clone());
1703 config.decoding = GelfDeserializerConfig::default().into();
1704 let path = init_unix_with_config(tx, false, false, config).await;
1705 let seed = 42;
1706 let mut rng = SmallRng::seed_from_u64(seed);
1707 let max_size = 20;
1708 let big_message = "This is a very large message".repeat(5);
1709 let another_big_message = "This is another very large message".repeat(5);
1710 let mut chunks = get_gelf_chunks(big_message.as_str(), max_size, &mut rng);
1711 let mut another_chunks =
1712 get_gelf_chunks(another_big_message.as_str(), max_size, &mut rng);
1713 chunks.append(&mut another_chunks);
1714 chunks.shuffle(&mut rng);
1715
1716 send_packets_unix_datagram(path, chunks).await;
1717
1718 let events = collect_n(rx, 2).await;
1719 assert_eq!(
1720 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1721 big_message.into()
1722 );
1723 assert_eq!(
1724 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1725 another_big_message.into()
1726 );
1727 })
1728 .await;
1729 }
1730
1731 #[cfg(unix)]
1732 #[tokio::test]
1733 async fn unix_datagram_message_with_vector_namespace() {
1734 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1735 let (_, rx) = unix_message("test", false, true).await;
1736 let events = collect_n(rx, 1).await;
1737 let log = events[0].as_log();
1738 let event_meta = log.metadata().value();
1739
1740 assert_eq!(log.value(), &"test".into());
1741 assert_eq!(events.len(), 1);
1742
1743 assert_eq!(
1744 event_meta.get(path!("vector", "source_type")).unwrap(),
1745 &value!(SocketConfig::NAME)
1746 );
1747
1748 assert_eq!(
1749 event_meta.get(path!(SocketConfig::NAME, "host")).unwrap(),
1750 &value!(UNNAMED_SOCKET_HOST)
1751 );
1752 })
1753 .await;
1754 }
1755
1756 #[cfg(unix)]
1757 #[tokio::test]
1758 async fn unix_datagram_message_preserves_newline() {
1759 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1760 let (_, rx) = unix_message("foo\nbar", false, false).await;
1761 let events = collect_n(rx, 1).await;
1762
1763 assert_eq!(events.len(), 1);
1764 assert_eq!(
1765 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1766 "foo\nbar".into()
1767 );
1768 assert_eq!(
1769 events[0].as_log()[log_schema().source_type_key().unwrap().to_string()],
1770 "socket".into()
1771 );
1772 })
1773 .await;
1774 }
1775
1776 #[cfg(unix)]
1777 #[tokio::test]
1778 async fn unix_datagram_multiple_packets() {
1779 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1780 unix_multiple_packets(false).await
1781 })
1782 .await;
1783 }
1784
1785 #[cfg(unix)]
1786 #[test]
1787 fn parses_unix_datagram_config() {
1788 let config = parses_unix_config("unix_datagram");
1789 assert!(matches!(config.mode, Mode::UnixDatagram { .. }));
1790 }
1791
1792 #[cfg(unix)]
1793 #[test]
1794 fn parses_unix_datagram_perms() {
1795 let config = parses_unix_config_file_mode("unix_datagram");
1796 assert!(matches!(config.mode, Mode::UnixDatagram { .. }));
1797 }
1798
1799 #[cfg(unix)]
1800 #[tokio::test]
1801 async fn unix_datagram_permissions() {
1802 let in_path = tempfile::tempdir().unwrap().keep().join("unix_test");
1803 let (tx, _) = SourceSender::new_test();
1804
1805 let mut config = UnixConfig::new(in_path.clone());
1806 config.socket_file_mode = Some(0o555);
1807 let mode = Mode::UnixDatagram(config);
1808 let server = SocketConfig { mode }
1809 .build(SourceContext::new_test(tx, None))
1810 .await
1811 .unwrap();
1812 tokio::spawn(server);
1813
1814 wait_for(|| {
1815 match std::fs::metadata(&in_path) {
1816 Ok(meta) => {
1817 match meta.permissions().mode() {
1818 0o140555 => ready(true),
1820 _ => ready(false),
1821 }
1822 }
1823 Err(_) => ready(false),
1824 }
1825 })
1826 .await;
1827 }
1828
1829 #[cfg(unix)]
1831 async fn send_lines_unix_stream(path: PathBuf, lines: &[&str]) {
1832 let socket = UnixStream::connect(path).await.unwrap();
1833 let mut sink = FramedWrite::new(socket, LinesCodec::new());
1834
1835 let lines = lines.iter().map(|s| Ok(s.to_string()));
1836 let lines = lines.collect::<Vec<_>>();
1837 sink.send_all(&mut stream::iter(lines)).await.unwrap();
1838
1839 let mut socket = sink.into_inner();
1840 socket.shutdown().await.unwrap();
1841 }
1842
1843 #[cfg(unix)]
1844 #[tokio::test]
1845 async fn unix_stream_message() {
1846 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1847 let (_, rx) = unix_message("test", true, false).await;
1848 let events = collect_n(rx, 1).await;
1849
1850 assert_eq!(1, events.len());
1851 assert_eq!(
1852 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1853 "test".into()
1854 );
1855 assert_eq!(
1856 events[0].as_log()[log_schema().source_type_key().unwrap().to_string()],
1857 "socket".into()
1858 );
1859 })
1860 .await;
1861 }
1862
1863 #[cfg(unix)]
1864 #[tokio::test]
1865 async fn unix_stream_message_with_vector_namespace() {
1866 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1867 let (_, rx) = unix_message("test", true, true).await;
1868 let events = collect_n(rx, 1).await;
1869 let log = events[0].as_log();
1870 let event_meta = log.metadata().value();
1871
1872 assert_eq!(log.value(), &"test".into());
1873 assert_eq!(1, events.len());
1874 assert_eq!(
1875 event_meta.get(path!("vector", "source_type")).unwrap(),
1876 &value!(SocketConfig::NAME)
1877 );
1878 assert_eq!(
1879 event_meta.get(path!(SocketConfig::NAME, "host")).unwrap(),
1880 &value!(UNNAMED_SOCKET_HOST)
1881 );
1882 })
1883 .await;
1884 }
1885
1886 #[cfg(unix)]
1887 #[tokio::test]
1888 async fn unix_stream_message_splits_on_newline() {
1889 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1890 let (_, rx) = unix_message("foo\nbar", true, false).await;
1891 let events = collect_n(rx, 2).await;
1892
1893 assert_eq!(events.len(), 2);
1894 assert_eq!(
1895 events[0].as_log()[log_schema().message_key().unwrap().to_string()],
1896 "foo".into()
1897 );
1898 assert_eq!(
1899 events[0].as_log()[log_schema().source_type_key().unwrap().to_string()],
1900 "socket".into()
1901 );
1902 assert_eq!(
1903 events[1].as_log()[log_schema().message_key().unwrap().to_string()],
1904 "bar".into()
1905 );
1906 assert_eq!(
1907 events[1].as_log()[log_schema().source_type_key().unwrap().to_string()],
1908 "socket".into()
1909 );
1910 })
1911 .await;
1912 }
1913
1914 #[cfg(unix)]
1915 #[tokio::test]
1916 async fn unix_stream_multiple_packets() {
1917 assert_source_compliance(&SOCKET_PUSH_SOURCE_TAGS, async {
1918 unix_multiple_packets(true).await
1919 })
1920 .await;
1921 }
1922
1923 #[cfg(unix)]
1924 #[test]
1925 fn parses_new_unix_stream_config() {
1926 let config = parses_unix_config("unix_stream");
1927 assert!(matches!(config.mode, Mode::UnixStream { .. }));
1928 }
1929
1930 #[cfg(unix)]
1931 #[test]
1932 fn parses_new_unix_datagram_perms() {
1933 let config = parses_unix_config_file_mode("unix_stream");
1934 assert!(matches!(config.mode, Mode::UnixStream { .. }));
1935 }
1936
1937 #[cfg(unix)]
1938 #[test]
1939 fn parses_old_unix_stream_config() {
1940 let config = parses_unix_config("unix");
1941 assert!(matches!(config.mode, Mode::UnixStream { .. }));
1942 }
1943
1944 #[cfg(unix)]
1945 #[tokio::test]
1946 async fn unix_stream_permissions() {
1947 let in_path = tempfile::tempdir().unwrap().keep().join("unix_test");
1948 let (tx, _) = SourceSender::new_test();
1949
1950 let mut config = UnixConfig::new(in_path.clone());
1951 config.socket_file_mode = Some(0o421);
1952 let mode = Mode::UnixStream(config);
1953 let server = SocketConfig { mode }
1954 .build(SourceContext::new_test(tx, None))
1955 .await
1956 .unwrap();
1957 tokio::spawn(server);
1958
1959 wait_for(|| {
1960 match std::fs::metadata(&in_path) {
1961 Ok(meta) => {
1962 match meta.permissions().mode() {
1963 0o140421 => ready(true),
1965 _ => ready(false),
1966 }
1967 }
1968 Err(_) => ready(false),
1969 }
1970 })
1971 .await;
1972 }
1973}