|
| 1 | +// Copyright 2024 FastLabs Developers |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | + |
| 15 | +use std::borrow::Cow; |
| 16 | +use std::io; |
| 17 | +use std::io::BufWriter; |
| 18 | +use std::net::TcpStream; |
| 19 | +use std::net::ToSocketAddrs; |
| 20 | + |
| 21 | +use native_tls::TlsConnector; |
| 22 | +use native_tls::TlsConnectorBuilder; |
| 23 | +use native_tls::TlsStream; |
| 24 | + |
| 25 | +use crate::format::SyslogContext; |
| 26 | +use crate::sender::internal::impl_syslog_sender_common; |
| 27 | +use crate::sender::internal::impl_syslog_stream_send_formatted; |
| 28 | + |
| 29 | +/// Create a TLS sender that sends messages to the well-known port (6514). |
| 30 | +/// |
| 31 | +/// See also [RFC-5425] §4.1 Port Assignment. |
| 32 | +/// |
| 33 | +/// [RFC-5425]: https://datatracker.ietf.org/doc/html/rfc5425#section-4.1 |
| 34 | +pub fn tls_well_known<S: AsRef<str>>(domain: S) -> io::Result<TlsSender> { |
| 35 | + let domain = domain.as_ref(); |
| 36 | + tls(format!("{domain}:6514"), domain) |
| 37 | +} |
| 38 | + |
| 39 | +/// Create a TLS sender that sends messages to the given address. |
| 40 | +pub fn tls<A: ToSocketAddrs, S: AsRef<str>>(addr: A, domain: S) -> io::Result<TlsSender> { |
| 41 | + tls_with(addr, domain, TlsConnector::builder()) |
| 42 | +} |
| 43 | + |
| 44 | +/// Create a TLS sender that sends messages to the given address with certificate builder. |
| 45 | +pub fn tls_with<A: ToSocketAddrs, S: AsRef<str>>( |
| 46 | + addr: A, |
| 47 | + domain: S, |
| 48 | + builder: TlsConnectorBuilder, |
| 49 | +) -> io::Result<TlsSender> { |
| 50 | + TlsSender::connect(addr, domain, builder) |
| 51 | +} |
| 52 | + |
| 53 | +/// A syslog sender that sends messages to a TCP socket over TLS. |
| 54 | +#[derive(Debug)] |
| 55 | +pub struct TlsSender { |
| 56 | + writer: BufWriter<TlsStream<TcpStream>>, |
| 57 | + context: SyslogContext, |
| 58 | + postfix: Cow<'static, str>, |
| 59 | +} |
| 60 | + |
| 61 | +impl TlsSender { |
| 62 | + /// Connect to a TCP socket over TLS at the given address. |
| 63 | + pub fn connect<A: ToSocketAddrs, S: AsRef<str>>( |
| 64 | + addr: A, |
| 65 | + domain: S, |
| 66 | + builder: TlsConnectorBuilder, |
| 67 | + ) -> io::Result<Self> { |
| 68 | + let domain = domain.as_ref(); |
| 69 | + let stream = TcpStream::connect(addr)?; |
| 70 | + let connector = builder.build().map_err(io::Error::other)?; |
| 71 | + let stream = connector |
| 72 | + .connect(domain, stream) |
| 73 | + .map_err(io::Error::other)?; |
| 74 | + Ok(Self { |
| 75 | + writer: BufWriter::new(stream), |
| 76 | + context: SyslogContext::default(), |
| 77 | + postfix: Cow::Borrowed("\r\n"), |
| 78 | + }) |
| 79 | + } |
| 80 | + |
| 81 | + /// Set the postfix when formatting Syslog message. |
| 82 | + /// |
| 83 | + /// This is generally '\r\n' as defined in [RFC-6587] §3.4.2. |
| 84 | + /// |
| 85 | + /// [RFC-6587]: https://datatracker.ietf.org/doc/html/rfc6587 |
| 86 | + pub fn set_postfix(&mut self, postfix: impl Into<Cow<'static, str>>) { |
| 87 | + self.postfix = postfix.into(); |
| 88 | + } |
| 89 | + |
| 90 | + /// Set the context when formatting Syslog message. |
| 91 | + pub fn set_context(mut self, context: SyslogContext) { |
| 92 | + self.context = context; |
| 93 | + } |
| 94 | + |
| 95 | + /// Mutate the context when formatting Syslog message. |
| 96 | + pub fn mut_context(&mut self) -> &mut SyslogContext { |
| 97 | + &mut self.context |
| 98 | + } |
| 99 | +} |
| 100 | + |
| 101 | +impl_syslog_sender_common!(TlsSender); |
| 102 | +impl_syslog_stream_send_formatted!(TlsSender); |
0 commit comments