1use std::net::{Ipv4Addr, SocketAddr};
2
3use bytes::BytesMut;
4use chrono::Utc;
5use futures::StreamExt;
6use listenfd::ListenFd;
7use vector_lib::{
8 EstimatedJsonEncodedSizeOf,
9 codecs::{
10 DecoderFramedRead, StreamDecodingError,
11 decoding::{DeserializerConfig, FramingConfig},
12 },
13 config::{LegacyKey, LogNamespace},
14 configurable::configurable_component,
15 internal_event::{ByteSize, BytesReceived, InternalEventHandle as _, Protocol},
16 lookup::{lookup_v2::OptionalValuePath, owned_value_path, path},
17};
18
19use super::default_host_key;
20use crate::{
21 SourceSender,
22 codecs::Decoder,
23 event::Event,
24 internal_events::{
25 SocketBindError, SocketEventsReceived, SocketMode, SocketMulticastGroupJoinError,
26 SocketReceiveError, StreamClosedError,
27 },
28 net,
29 serde::default_decoding,
30 shutdown::ShutdownSignal,
31 sources::{
32 Source,
33 socket::SocketConfig,
34 util::net::{SocketListenAddr, try_bind_udp_socket},
35 },
36};
37
38#[configurable_component]
40#[serde(deny_unknown_fields)]
41#[derive(Clone, Debug)]
42pub struct UdpConfig {
43 #[configurable(derived)]
44 address: SocketListenAddr,
45
46 #[serde(default)]
58 #[configurable(metadata(docs::examples = "['224.0.0.2', '224.0.0.4']"))]
59 pub(super) multicast_groups: Vec<Ipv4Addr>,
60
61 #[serde(default)]
75 pub(super) multicast_interface: Option<Ipv4Addr>,
76
77 #[serde(default = "default_max_length")]
81 #[configurable(metadata(docs::type_unit = "bytes"))]
82 pub(super) max_length: usize,
83
84 host_key: Option<OptionalValuePath>,
94
95 #[serde(default = "default_port_key")]
103 port_key: OptionalValuePath,
104
105 #[configurable(metadata(docs::type_unit = "bytes"))]
107 receive_buffer_bytes: Option<usize>,
108
109 #[configurable(derived)]
110 pub(super) framing: Option<FramingConfig>,
111
112 #[configurable(derived)]
113 #[serde(default = "default_decoding")]
114 pub(super) decoding: DeserializerConfig,
115
116 #[serde(default)]
118 #[configurable(metadata(docs::hidden))]
119 pub log_namespace: Option<bool>,
120}
121
122fn default_port_key() -> OptionalValuePath {
123 OptionalValuePath::from(owned_value_path!("port"))
124}
125
126fn default_max_length() -> usize {
127 crate::serde::default_max_length()
128}
129
130impl UdpConfig {
131 pub(super) fn host_key(&self) -> OptionalValuePath {
132 self.host_key.clone().unwrap_or(default_host_key())
133 }
134
135 pub const fn port_key(&self) -> &OptionalValuePath {
136 &self.port_key
137 }
138
139 pub(super) const fn framing(&self) -> &Option<FramingConfig> {
140 &self.framing
141 }
142
143 pub(super) const fn decoding(&self) -> &DeserializerConfig {
144 &self.decoding
145 }
146
147 pub(super) const fn address(&self) -> SocketListenAddr {
148 self.address
149 }
150
151 pub fn from_address(address: SocketListenAddr) -> Self {
152 Self {
153 address,
154 multicast_groups: Vec::new(),
155 multicast_interface: None,
156 max_length: default_max_length(),
157 host_key: None,
158 port_key: default_port_key(),
159 receive_buffer_bytes: None,
160 framing: None,
161 decoding: default_decoding(),
162 log_namespace: None,
163 }
164 }
165
166 pub const fn set_log_namespace(&mut self, val: Option<bool>) -> &mut Self {
167 self.log_namespace = val;
168 self
169 }
170}
171
172pub(super) fn udp(
173 config: UdpConfig,
174 decoder: Decoder,
175 mut shutdown: ShutdownSignal,
176 mut out: SourceSender,
177 log_namespace: LogNamespace,
178) -> Source {
179 Box::pin(async move {
180 let listenfd = ListenFd::from_env();
181 let socket = try_bind_udp_socket(config.address, listenfd)
182 .await
183 .map_err(|error| {
184 emit!(SocketBindError {
185 mode: SocketMode::Udp,
186 error,
187 })
188 })?;
189
190 if !config.multicast_groups.is_empty() {
191 socket.set_multicast_loop_v4(true).unwrap();
192 let listen_addr = match config.address() {
193 SocketListenAddr::SocketAddr(SocketAddr::V4(addr)) => addr,
194 SocketListenAddr::SocketAddr(SocketAddr::V6(_)) => {
195 unimplemented!("IPv6 multicast is not supported")
199 }
200 SocketListenAddr::SystemdFd(_) => {
201 unimplemented!("Multicast for systemd fd sockets is not supported")
202 }
203 };
204 for group_addr in config.multicast_groups {
205 let interface = config.multicast_interface.unwrap_or(*listen_addr.ip());
206 socket
207 .join_multicast_v4(group_addr, interface)
208 .map_err(|error| {
209 emit!(SocketMulticastGroupJoinError {
210 error,
211 group_addr,
212 interface,
213 })
214 })?;
215 info!(message = "Joined multicast group.", group = %group_addr);
216 }
217 }
218
219 if let Some(receive_buffer_bytes) = config.receive_buffer_bytes
220 && let Err(error) = net::set_receive_buffer_size(&socket, receive_buffer_bytes)
221 {
222 warn!(message = "Failed configuring receive buffer size on UDP socket.", %error);
223 }
224
225 let mut max_length = config.max_length;
226
227 if let Some(receive_buffer_bytes) = config.receive_buffer_bytes {
228 max_length = std::cmp::min(max_length, receive_buffer_bytes);
229 }
230
231 let bytes_received = register!(BytesReceived::from(Protocol::UDP));
232
233 info!(message = "Listening.", address = %config.address);
234 let mut buf = BytesMut::with_capacity(max_length + 1);
236 loop {
237 buf.resize(max_length + 1, 0);
238 tokio::select! {
239 recv = socket.recv_from(&mut buf) => {
240 let (byte_size, address) = match recv {
241 Ok(res) => res,
242 Err(error) => {
243 #[cfg(windows)]
244 if let Some(err) = error.raw_os_error() {
245 if err == 10040 {
246 warn!(
248 message = "Discarding frame larger than max_length.",
249 max_length = max_length
250 );
251 continue;
252 }
253 }
254
255 return Err(emit!(SocketReceiveError {
256 mode: SocketMode::Udp,
257 error
258 }));
259 }
260 };
261
262 bytes_received.emit(ByteSize(byte_size));
263 let payload = buf.split_to(byte_size);
264 let truncated = byte_size == max_length + 1;
265 let mut stream =
266 DecoderFramedRead::new(payload.as_ref(), decoder.clone()).peekable();
267
268 while let Some(result) = stream.next().await {
269 let last = Pin::new(&mut stream).peek().await.is_none();
270 match result {
271 Ok((mut events, _byte_size)) => {
272 if last && truncated {
273 _ = events.pop();
275 warn!(
276 message = "Discarding frame larger than max_length.",
277 max_length = max_length
278 );
279 }
280
281 if events.is_empty() {
282 continue;
283 }
284
285 let count = events.len();
286 emit!(SocketEventsReceived {
287 mode: SocketMode::Udp,
288 byte_size: events.estimated_json_encoded_size_of(),
289 count,
290 });
291
292 let now = Utc::now();
293
294 for event in &mut events {
295 if let Event::Log(log) = event {
296 log_namespace.insert_standard_vector_source_metadata(
297 log,
298 SocketConfig::NAME,
299 now,
300 );
301
302 let legacy_host_key = config
303 .host_key
304 .clone()
305 .unwrap_or(default_host_key())
306 .path;
307
308 log_namespace.insert_source_metadata(
309 SocketConfig::NAME,
310 log,
311 legacy_host_key.as_ref().map(LegacyKey::InsertIfEmpty),
312 path!("host"),
313 address.ip().to_string()
314 );
315
316 let legacy_port_key = config.port_key.clone().path;
317
318 log_namespace.insert_source_metadata(
319 SocketConfig::NAME,
320 log,
321 legacy_port_key.as_ref().map(LegacyKey::InsertIfEmpty),
322 path!("port"),
323 address.port()
324 );
325 }
326 }
327
328 tokio::select!{
329 result = out.send_batch(events) => {
330 if result.is_err() {
331 emit!(StreamClosedError { count });
332 return Ok(())
333 }
334 }
335 _ = &mut shutdown => return Ok(()),
336 }
337 }
338 Err(error) => {
339 if !error.can_continue() {
342 break;
343 }
344 }
345 }
346 }
347 }
348 _ = &mut shutdown => return Ok(()),
349 }
350 }
351 })
352}