Skip to content

Commit

Permalink
feat: impl BroadcastSender
Browse files Browse the repository at this point in the history
  • Loading branch information
BBArikL committed Nov 14, 2024
1 parent 1feefe8 commit a96a7d1
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ doc-scrape-examples = true
name = "udp_sender"
path = "examples/udp_sender.rs"

[[example]]
doc-scrape-examples = true
name = "broadcast_sender"
path = "examples/broadcast_sender.rs"

[[example]]
doc-scrape-examples = true
name = "unix_sender"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Client library written in Rust to send messages to a Syslog server. Support impl
* RFC-5424 Formatter: [The Syslog Protocol](https://datatracker.ietf.org/doc/html/rfc5424)
* `UdpSender`: [RFC 5426 - Transmission of Syslog Messages over UDP](https://datatracker.ietf.org/doc/html/rfc5426)
* `TcpSender`: [RFC 6587 - Transmission of Syslog Messages over TCP](https://datatracker.ietf.org/doc/html/rfc6587)
* `BroadcastSender`: Broadcast UDP syslog messages.
* (unix only) Unix domain socket sender (datagram or stream)

## Getting Started
Expand Down
29 changes: 29 additions & 0 deletions examples/broadcast_sender.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 FastLabs Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use fasyslog::Severity;

fn main() {
let mut sender = fasyslog::sender::broadcast_well_known().unwrap();
let mut generator = names::Generator::default();
for _ in 0..100 {
let name = generator.next().unwrap();
let message = format!("Hello, {name}!");
let mut element = fasyslog::SDElement::new("exampleSDID@16253").unwrap();
element.add_param("jno", "sul").unwrap();
sender
.send_rfc5424(Severity::ERROR, Some("UDPIN"), vec![element], message)
.unwrap();
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
//! * [RFC-5424 Formatter]: [The Syslog Protocol](https://datatracker.ietf.org/doc/html/rfc5424)
//! * [`UdpSender`]: [RFC 5426 - Transmission of Syslog Messages over UDP](https://datatracker.ietf.org/doc/html/rfc5426)
//! * [`TcpSender`]: [RFC 6587 - Transmission of Syslog Messages over TCP](https://datatracker.ietf.org/doc/html/rfc6587)
//! * [`BroadcastSender`]: Broadcast UDP syslog messages.
//! * (unix only) Unix domain socket sender (datagram or stream)
//!
//! [RFC-3164 Formatter]: format::RFC3164Formatter
//! [RFC-5424 Formatter]: format::RFC5424Formatter
//! [`UdpSender`]: sender::UdpSender
//! [`TcpSender`]: sender::TcpSender
//! [`BroadcastSender`]: sender::BroadcastSender
//!
//! # Example
//!
Expand Down
8 changes: 7 additions & 1 deletion src/sender/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(crate) mod internal;
pub enum SyslogSender {
Tcp(TcpSender),
Udp(UdpSender),
Broadcast(BroadcastSender),
#[cfg(unix)]
UnixDatagram(UnixDatagramSender),
#[cfg(unix)]
Expand All @@ -54,6 +55,7 @@ impl SyslogSender {
match self {
SyslogSender::Tcp(sender) => sender.send_rfc3164(severity, message),
SyslogSender::Udp(sender) => sender.send_rfc3164(severity, message),
SyslogSender::Broadcast(sender) => sender.send_rfc3164(severity, message),
#[cfg(unix)]
SyslogSender::UnixDatagram(sender) => sender.send_rfc3164(severity, message),
#[cfg(unix)]
Expand All @@ -72,6 +74,9 @@ impl SyslogSender {
match self {
SyslogSender::Tcp(sender) => sender.send_rfc5424(severity, msgid, elements, message),
SyslogSender::Udp(sender) => sender.send_rfc5424(severity, msgid, elements, message),
SyslogSender::Broadcast(sender) => {
sender.send_rfc5424(severity, msgid, elements, message)
}
#[cfg(unix)]
SyslogSender::UnixDatagram(sender) => {
sender.send_rfc5424(severity, msgid, elements, message)
Expand All @@ -88,6 +93,7 @@ impl SyslogSender {
match self {
SyslogSender::Tcp(sender) => sender.send_formatted(formatted),
SyslogSender::Udp(sender) => sender.send_formatted(formatted),
SyslogSender::Broadcast(sender) => sender.send_formatted(formatted),
#[cfg(unix)]
SyslogSender::UnixDatagram(sender) => sender.send_formatted(formatted),
#[cfg(unix)]
Expand All @@ -107,7 +113,7 @@ impl SyslogSender {
pub fn flush(&mut self) -> io::Result<()> {
match self {
SyslogSender::Tcp(sender) => sender.flush(),
SyslogSender::Udp(_) => Ok(()),
SyslogSender::Udp(_) | SyslogSender::Broadcast(_) => Ok(()),
#[cfg(unix)]
SyslogSender::UnixDatagram(_) => Ok(()),
#[cfg(unix)]
Expand Down
55 changes: 55 additions & 0 deletions src/sender/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use core::net::SocketAddr;
use std::io;
use std::net::ToSocketAddrs;
use std::net::UdpSocket;
use std::str::FromStr;

use crate::format::SyslogContext;
use crate::sender::internal::impl_syslog_sender_common;
Expand All @@ -33,6 +35,20 @@ pub fn udp<L: ToSocketAddrs, R: ToSocketAddrs>(local: L, remote: R) -> io::Resul
UdpSender::connect(local, remote)
}

/// Create a UDP sender that broadcast messages to the well-known port (514).
///
/// See also [RFC-3164] §2 Transport Layer Protocol.
///
/// [RFC-3164]: https://datatracker.ietf.org/doc/html/rfc3164#section-2
pub fn broadcast_well_known() -> io::Result<BroadcastSender> {
broadcast(514)
}

/// Create a UDP sender that broadcast messages
pub fn broadcast(port: u16) -> io::Result<BroadcastSender> {
BroadcastSender::connect(port)
}

/// A syslog sender that sends messages to a UDP socket.
#[derive(Debug)]
pub struct UdpSender {
Expand Down Expand Up @@ -69,3 +85,42 @@ impl UdpSender {
}

impl_syslog_sender_common!(UdpSender);

/// A syslog sender that sends messages to a UDP socket.
#[derive(Debug)]
pub struct BroadcastSender {
socket: UdpSocket,
remote: SocketAddr,
context: SyslogContext,
}

impl BroadcastSender {
/// Connect to a UDP socket at the given address.
pub fn connect(port: u16) -> io::Result<Self> {
let socket = UdpSocket::bind("0.0.0.0:0")?;
socket.set_broadcast(true)?;
Ok(Self {
socket,
remote: SocketAddr::from_str(format!("255.255.255.255:{port}").as_str()).unwrap(),
context: SyslogContext::default(),
})
}

/// Set the context when formatting Syslog message.
pub fn set_context(&mut self, context: SyslogContext) {
self.context = context;
}

/// Mutate the context when formatting Syslog message.
pub fn mut_context(&mut self) -> &mut SyslogContext {
&mut self.context
}

/// Send a pre-formatted message.
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
self.socket.send_to(formatted, self.remote)?;
Ok(())
}
}

impl_syslog_sender_common!(BroadcastSender);

0 comments on commit a96a7d1

Please sign in to comment.