Skip to content

Commit

Permalink
g3-journal: add direct send method
Browse files Browse the repository at this point in the history
  • Loading branch information
zh-jq-b committed Sep 7, 2023
1 parent 032cb5b commit f3aba46
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 13 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 14 additions & 13 deletions doc/standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ The code should comply to these, but should be more compliant to existing popula
- [rfc4122](https://datatracker.ietf.org/doc/html/rfc4122)
: A Universally Unique IDentifier (UUID) URN Namespace

## Encoding
## Systemd Journal

- [netstring](http://cr.yp.to/proto/netstrings.txt)
- [JOURNAL_NATIVE_PROTOCOL](https://systemd.io/JOURNAL_NATIVE_PROTOCOL/)
: Native Journal Protocol

## Syslog

Expand Down Expand Up @@ -71,32 +72,32 @@ The code should comply to these, but should be more compliant to existing popula
## X.509

- [rfc7468](https://datatracker.ietf.org/doc/html/rfc7468)
: Textual Encodings of PKIX, PKCS, and CMS Structures
: Textual Encodings of PKIX, PKCS, and CMS Structures
- [rfc5280](https://datatracker.ietf.org/doc/html/rfc5280)
: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
- [rfc5758](https://datatracker.ietf.org/doc/html/rfc5758)
: Internet X.509 Public Key Infrastructure: Additional Algorithms and Identifiers for DSA and ECDSA
: Internet X.509 Public Key Infrastructure: Additional Algorithms and Identifiers for DSA and ECDSA
- [rfc4055](https://datatracker.ietf.org/doc/html/rfc4055/)
: Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
: Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

## Cryptography

- [NIST SP 800-186](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186.pdf)
: Recommendations for Discrete Logarithm-based Cryptography: Elliptic Curve Domain Parameters
: Recommendations for Discrete Logarithm-based Cryptography: Elliptic Curve Domain Parameters
- [SEC2-v2](https://www.secg.org/sec2-v2.pdf)
: SEC 2: Recommended Elliptic Curve Domain Parameters
: SEC 2: Recommended Elliptic Curve Domain Parameters

# Network Protocol

## Happy Eyeballs

- [rfc8305](https://datatracker.ietf.org/doc/html/rfc8305)
: Happy Eyeballs Version 2: Better Connectivity Using Concurrency
: Happy Eyeballs Version 2: Better Connectivity Using Concurrency

## PROXY protocol

- [haproxy-proxy-protocol](https://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt)
: The PROXY protocol Versions 1 & 2
: The PROXY protocol Versions 1 & 2

## Socks

Expand Down Expand Up @@ -328,8 +329,8 @@ The code should comply to these, but should be more compliant to existing popula
## NAT Traversal

- [rfc8489](https://datatracker.ietf.org/doc/html/rfc8489)
: Session Traversal Utilities for NAT (STUN)
: Session Traversal Utilities for NAT (STUN)
- [rfc8656](https://datatracker.ietf.org/doc/html/rfc8656)
: Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)
: Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)
- [rfc8445](https://datatracker.ietf.org/doc/html/rfc8445)
: Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal
: Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal
2 changes: 2 additions & 0 deletions lib/g3-journal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ edition.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow.workspace = true
slog = { workspace = true, features = ["nested-values"] }
serde.workspace = true
serde_json.workspace = true
nix = { workspace = true, features = ["fs", "socket", "uio"] }
libsystemd = "0.6"
itoa.workspace = true
ryu.workspace = true
Expand Down
87 changes: 87 additions & 0 deletions lib/g3-journal/src/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2023 ByteDance and/or its affiliates.
*
* 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 std::ffi::CStr;
use std::fs::File;
use std::io::Write;
use std::os::fd::AsRawFd;
use std::os::unix::net::UnixDatagram;
use std::sync::OnceLock;

use anyhow::{anyhow, Context};
use nix::fcntl::{fcntl, FcntlArg, SealFlag};
use nix::sys::memfd::{memfd_create, MemFdCreateFlag};
use nix::sys::socket::{sendmsg, ControlMessage, MsgFlags, UnixAddr};

/// Default path of the systemd-journald `AF_UNIX` datagram socket.
static SD_JOURNAL_SOCK_PATH: &str = "/run/systemd/journal/socket";
static SD_SOCK: OnceLock<UnixDatagram> = OnceLock::new();

const MEM_FD_NAME: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"journal-logging\0") };

#[allow(unused)]
pub(crate) fn journal_send(data: &[u8]) -> anyhow::Result<()> {
// TODO use thread local socket path
let sock = SD_SOCK.get_or_init(|| UnixDatagram::unbound().unwrap());

if let Err(e) = sock.send_to(data, SD_JOURNAL_SOCK_PATH) {
if e.raw_os_error() == Some(nix::libc::EMSGSIZE) {
// fallback if size limit reached
send_memfd_payload(sock, data).context("sending with memfd failed")
} else {
Err(anyhow!("send_to failed: {e}"))
}
} else {
Ok(())
}
}

/// Send an overlarge payload to systemd-journald socket.
///
/// This is a slow-path for sending a large payload that could not otherwise fit
/// in a UNIX datagram. Payload is thus written to a memfd, which is sent as ancillary
/// data.
fn send_memfd_payload(sock: &UnixDatagram, data: &[u8]) -> anyhow::Result<()> {
let tmpfd = memfd_create(MEM_FD_NAME, MemFdCreateFlag::MFD_ALLOW_SEALING)
.map_err(|e| anyhow!("unable to create memfd: {e}"))?;

let mut mem_file = File::from(tmpfd);
mem_file
.write_all(data)
.map_err(|e| anyhow!("failed to write to memfd: {e}"))?;

// Seal the memfd, so that journald knows it can safely mmap/read it.
fcntl(mem_file.as_raw_fd(), FcntlArg::F_ADD_SEALS(SealFlag::all()))
.map_err(|e| anyhow!("unable to seal memfd: {e}"))?;

let fds = &[mem_file.as_raw_fd()];
let ancillary = [ControlMessage::ScmRights(fds)];
let path = UnixAddr::new(SD_JOURNAL_SOCK_PATH)
.map_err(|e| anyhow!("unable to create new unix address: {e}"))?;
sendmsg(
sock.as_raw_fd(),
&[],
&ancillary,
MsgFlags::empty(),
Some(&path),
)
.map_err(|e| anyhow!("sendmsg failed: {e}"))?;

// Close our side of the memfd after we send it to systemd.
drop(mem_file);

Ok(())
}
2 changes: 2 additions & 0 deletions lib/g3-journal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ use g3_types::log::{AsyncLogConfig, AsyncLogger, LogStats};
#[macro_use]
mod macros;

mod io;

mod format;
pub use format::JournalFormatter;

Expand Down

0 comments on commit f3aba46

Please sign in to comment.