Skip to content

Commit

Permalink
feat: impl BroadcastSender (#8)
Browse files Browse the repository at this point in the history
Signed-off-by: tison <wander4096@gmail.com>
Co-authored-by: Arik <BBArik@protonmail.com>
  • Loading branch information
tisonkun and BBArikL authored Nov 17, 2024
1 parent 236ceca commit ff0fd8e
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ 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)
* `TlsSender`: [RFC 5425 - Transport Layer Security (TLS) Transport Mapping for Syslog](https://datatracker.ietf.org/doc/html/rfc5425)
* This implementation is based on [`native-tls`](https://crates.io/crates/native-tls) and requires features `native-tls` turned on.
* (unix only) Unix domain socket sender (datagram or stream)

## Getting Started
Expand Down
27 changes: 27 additions & 0 deletions examples/broadcast_sender.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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!("Broadcast {name} to everyone!");
sender
.send_rfc5424(Severity::ERROR, None::<String>, Vec::new(), message)
.unwrap();
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@
//! * [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)
//! * [`TlsSender`]: [RFC 5425 - Transport Layer Security (TLS) Transport Mapping for Syslog](https://datatracker.ietf.org/doc/html/rfc5425)
//! * This implementation is based on [`native-tls`](https://crates.io/crates/native-tls) and
//! requires features `native-tls` turned on.
//! * (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
//! [`TlsSender`]: sender::TlsSender
//!
//! # Example
//!
Expand Down
2 changes: 2 additions & 0 deletions src/sender/native_tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub fn tls_with<A: ToSocketAddrs, S: AsRef<str>>(
}

/// A syslog sender that sends messages to a TCP socket over TLS.
///
/// Users can obtain a `TlsSender` by calling [`tls_well_known`], [`tls`], or [`tls_with`].
#[derive(Debug)]
pub struct TlsSender {
writer: BufWriter<TlsStream<TcpStream>>,
Expand Down
2 changes: 2 additions & 0 deletions src/sender/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub fn tcp<A: ToSocketAddrs>(addr: A) -> io::Result<TcpSender> {
}

/// A syslog sender that sends messages to a TCP socket.
///
/// Users can obtain a `TcpSender` by calling [`tcp_well_known`] or [`tcp`].
#[derive(Debug)]
pub struct TcpSender {
writer: BufWriter<TcpStream>,
Expand Down
32 changes: 30 additions & 2 deletions src/sender/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,27 @@ 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<UdpSender> {
broadcast(514)
}

/// Create a UDP sender that broadcast messages to the given port.
pub fn broadcast(port: u16) -> io::Result<UdpSender> {
let socket = UdpSocket::bind("0.0.0.0:0")?;
socket.set_broadcast(true)?;
socket.connect(format!("255.255.255.255:{port}"))?;
Ok(UdpSender::new(socket))
}

/// A syslog sender that sends messages to a UDP socket.
///
/// Users can obtain a `UdpSender` by calling [`udp_well_known`], [`udp`], [`broadcast_well_known`],
/// or [`broadcast`].
#[derive(Debug)]
pub struct UdpSender {
socket: UdpSocket,
Expand All @@ -45,10 +65,18 @@ impl UdpSender {
pub fn connect<L: ToSocketAddrs, R: ToSocketAddrs>(local: L, remote: R) -> io::Result<Self> {
let socket = UdpSocket::bind(local)?;
socket.connect(remote)?;
Ok(Self {
Ok(Self::new(socket))
}

/// Create a new UDP sender with the given socket.
///
/// This is useful when users want to configure the socket in fine-grained. Note that the
/// passed `socket` MUST be connected to the remote address.
pub fn new(socket: UdpSocket) -> Self {
Self {
socket,
context: SyslogContext::default(),
})
}
}

/// Set the context when formatting Syslog message.
Expand Down

0 comments on commit ff0fd8e

Please sign in to comment.