use std::convert::{Into, TryFrom};
use std::fmt::{self, Debug, Display};
use std::iter::Iterator;
use std::ops::Range;
use std::str;
use std::string::*;
use serde::ser::SerializeMap;
use serde::{Serialize, Serializer};
use crate::constants::*;
#[derive(Debug, Clone)]
pub struct Message {
pub id: EventID,
pub node: Option<Vec<u8>>,
pub ty: MessageType,
pub body: Body,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
pub struct EventID {
pub timestamp: u64,
pub sequence: u32,
}
impl Display for EventID {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let sec = self.timestamp / 1000;
let msec = self.timestamp % 1000;
let seq = self.sequence;
write!(f, "{sec}.{msec:03}:{seq}")
}
}
impl Serialize for EventID {
#[inline(always)]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.collect_str(&self)
}
}
impl PartialEq<str> for EventID {
fn eq(&self, other: &str) -> bool {
format!("{self}") == other
}
}
#[derive(PartialEq, Eq, Hash, Default, Clone, Copy)]
pub struct MessageType(pub u32);
impl Display for MessageType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match EVENT_NAMES.get(&(self.0)) {
Some(name) => write!(f, "{name}"),
None => write!(f, "UNKNOWN[{}]", self.0),
}
}
}
impl Debug for MessageType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match EVENT_NAMES.get(&(self.0)) {
Some(name) => write!(f, "MessageType({name})"),
None => write!(f, "MessageType({})", self.0),
}
}
}
impl Serialize for MessageType {
#[inline(always)]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match EVENT_NAMES.get(&(self.0)) {
Some(name) => s.collect_str(name),
None => s.collect_str(&format_args!("UNKNOWN[{}]", self.0)),
}
}
}
include!(concat!(env!("OUT_DIR"), "/message_type_impl.rs"));
impl MessageType {
pub fn is_multipart(&self) -> bool {
(1300..2100).contains(&self.0) || self == &MessageType::LOGIN
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
#[repr(usize)]
pub enum Common {
Arch,
Argc,
CapFe,
CapFi,
CapFp,
CapFver,
Comm,
Cwd,
Dev,
Exe,
Exit,
Inode,
Item,
Items,
Key,
Mode,
Name,
Nametype,
Pid,
PPid,
Ses,
Subj,
Success,
Syscall,
Tty,
}
const COMMON: &[(&str, Common)] = &[
("arch", Common::Arch),
("argc", Common::Argc),
("cap_fe", Common::CapFe),
("cap_fi", Common::CapFi),
("cap_fp", Common::CapFp),
("cap_fver", Common::CapFver),
("comm", Common::Comm),
("cwd", Common::Cwd),
("dev", Common::Dev),
("exe", Common::Exe),
("exit", Common::Exit),
("inode", Common::Inode),
("item", Common::Item),
("items", Common::Items),
("key", Common::Key),
("mode", Common::Mode),
("name", Common::Name),
("nametype", Common::Nametype),
("pid", Common::Pid),
("ppid", Common::PPid),
("ses", Common::Ses),
("subj", Common::Subj),
("success", Common::Success),
("syscall", Common::Syscall),
("tty", Common::Tty),
];
impl TryFrom<&[u8]> for Common {
type Error = &'static str;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let i = COMMON
.binary_search_by_key(&value, |(s, _)| s.as_bytes())
.map_err(|_| "unknown key")?;
Ok(COMMON[i].1)
}
}
impl From<Common> for &'static str {
fn from(value: Common) -> Self {
COMMON[value as usize].0
}
}
impl Display for Common {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let c = COMMON[*self as usize].0;
write!(f, "{c}")
}
}
pub(crate) type NVec = tinyvec::TinyVec<[u8; 14]>;
#[derive(PartialEq, Eq, Clone)]
pub enum Key {
Name(NVec),
NameUID(NVec),
NameGID(NVec),
Common(Common),
NameTranslated(NVec),
Arg(u32, Option<u16>),
ArgLen(u32),
Literal(&'static str),
}
impl Default for Key {
fn default() -> Self {
Key::Literal("no_key")
}
}
impl Debug for Key {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.to_string())
}
}
impl Display for Key {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Key::Arg(x, Some(y)) => write!(f, "a{x}[{y}]"),
Key::Arg(x, None) => write!(f, "a{x}"),
Key::ArgLen(x) => write!(f, "a{x}_len"),
Key::Name(r) | Key::NameUID(r) | Key::NameGID(r) => {
let s = unsafe { str::from_utf8_unchecked(r) };
f.write_str(s)
}
Key::Common(c) => write!(f, "{c}"),
Key::NameTranslated(r) => {
let s = unsafe { str::from_utf8_unchecked(r) };
f.write_str(&str::to_ascii_uppercase(s))
}
Key::Literal(s) => f.write_str(s),
}
}
}
impl Serialize for Key {
#[inline(always)]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
Key::Arg(x, Some(y)) => s.collect_str(&format_args!("a{x}[{y}]")),
Key::Arg(x, None) => s.collect_str(&format_args!("a{x}")),
Key::ArgLen(x) => s.collect_str(&format_args!("a{x}_len")),
Key::Name(r) | Key::NameUID(r) | Key::NameGID(r) => {
s.collect_str(unsafe { str::from_utf8_unchecked(r) })
}
Key::Common(c) => s.collect_str(c),
Key::NameTranslated(r) => {
s.collect_str(&str::to_ascii_uppercase(unsafe {
str::from_utf8_unchecked(r)
}))
}
Key::Literal(l) => s.collect_str(l),
}
}
}
impl PartialEq<str> for Key {
fn eq(&self, other: &str) -> bool {
self == other.as_bytes()
}
}
impl PartialEq<[u8]> for Key {
fn eq(&self, other: &[u8]) -> bool {
match self {
Key::Name(r) | Key::NameUID(r) | Key::NameGID(r) => r.as_ref() == other,
_ => self.to_string().as_bytes() == other,
}
}
}
impl From<&'static str> for Key {
fn from(value: &'static str) -> Self {
Self::Literal(value)
}
}
impl From<&[u8]> for Key {
fn from(value: &[u8]) -> Self {
Self::Name(NVec::from(value))
}
}
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum Quote {
None,
Single,
Double,
Braces,
}
#[derive(Clone)]
pub enum Number {
Hex(u64),
Dec(i64),
Oct(u64),
}
impl Debug for Number {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Num:<{self}>")
}
}
impl Display for Number {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Number::Hex(n) => write!(f, "0x{n:x}"),
Number::Oct(n) => write!(f, "0o{n:o}"),
Number::Dec(n) => write!(f, "{n}"),
}
}
}
impl Serialize for Number {
#[inline(always)]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
Number::Dec(n) => s.serialize_i64(*n),
_ => s.collect_str(&self),
}
}
}
#[derive(Clone)]
pub enum Value<'a> {
Empty,
Str(&'a [u8], Quote),
Segments(Vec<&'a [u8]>),
List(Vec<Value<'a>>),
StringifiedList(Vec<Value<'a>>),
Map(Vec<(Key, Value<'a>)>),
Number(Number),
Skipped((usize, usize)),
Literal(&'static str),
Owned(Vec<u8>),
}
impl Default for Value<'_> {
fn default() -> Self {
Self::Empty
}
}
impl Value<'_> {
pub fn str_len(&self) -> usize {
match self {
Value::Str(r, _) => r.len(),
Value::Segments(vr) => vr.iter().map(|r| r.len()).sum(),
_ => 0,
}
}
}
pub struct Body {
elems: Vec<(Key, Value<'static>)>,
arena: Vec<Vec<u8>>,
_pin: std::marker::PhantomPinned,
}
impl Default for Body {
fn default() -> Self {
Body {
elems: Vec::with_capacity(8),
arena: vec![],
_pin: std::marker::PhantomPinned,
}
}
}
impl Debug for Body {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut seq = f.debug_struct("Body");
for (k, v) in self {
seq.field(&k.to_string(), &v);
}
seq.finish()
}
}
impl Serialize for Body {
#[inline(always)]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
let mut map = s.serialize_map(None)?;
for (k, v) in self.into_iter() {
match k {
Key::Arg(_, _) | Key::ArgLen(_) => continue,
_ => map.serialize_entry(&k, &v)?,
}
}
map.end()
}
}
impl Body {
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(len: usize) -> Self {
Self {
elems: Vec::with_capacity(len),
..Self::default()
}
}
fn add_slice<'a, 'i>(&mut self, input: &'i [u8]) -> &'a [u8]
where
'a: 'i,
{
let ilen = input.len();
for buf in self.arena.iter() {
let Range { start, end } = input.as_ptr_range();
if buf.as_slice().as_ptr_range().contains(&start)
&& buf.as_slice().as_ptr_range().contains(&end)
{
let s = std::ptr::slice_from_raw_parts(start, ilen);
return unsafe { &*s };
}
}
for buf in self.arena.iter_mut() {
if buf.capacity() - buf.len() > ilen {
let e = buf.len();
buf.extend(input);
let s = std::ptr::slice_from_raw_parts(buf[e..].as_ptr(), ilen);
return unsafe { &*s };
}
}
self.arena
.push(Vec::with_capacity(1014 * (1 + (ilen / 1024))));
let i = self.arena.len() - 1;
let new_buf = &mut self.arena[i];
new_buf.extend(input);
let s = std::ptr::slice_from_raw_parts(new_buf[..].as_ptr(), ilen);
unsafe { &*s }
}
fn add_value<'a, 'i>(&mut self, v: Value<'i>) -> Value<'a>
where
'a: 'i,
{
match v {
Value::Str(s, q) => Value::Str(self.add_slice(s), q),
Value::Owned(s) => Value::Str(self.add_slice(s.as_slice()), Quote::None),
Value::List(vs) => Value::List(vs.into_iter().map(|v| self.add_value(v)).collect()),
Value::StringifiedList(vs) => {
Value::StringifiedList(vs.into_iter().map(|v| self.add_value(v)).collect())
}
Value::Segments(vs) => {
let vs = vs.iter().map(|s| self.add_slice(s)).collect();
Value::Segments(vs)
}
Value::Map(vs) => Value::Map(
vs.into_iter()
.map(|(k, v)| (k, self.add_value(v)))
.collect(),
),
Value::Empty | Value::Literal(_) | Value::Number(_) | Value::Skipped(_) => unsafe {
std::mem::transmute::<Value<'i>, Value<'a>>(v)
},
}
}
pub fn push(&mut self, kv: (Key, Value)) {
let (k, v) = kv;
let v = self.add_value(v);
self.elems.push((k, v));
}
pub fn len(&self) -> usize {
self.elems.len()
}
pub fn extend(&mut self, other: Self) {
self.arena.extend(other.arena);
self.elems.reserve(other.elems.len());
for (k, v) in other.elems {
self.push((k, v));
}
}
pub fn is_empty(&self) -> bool {
self.elems.is_empty()
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&(Key, Value<'_>)) -> bool,
{
self.elems.retain(f)
}
pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<&Value> {
let key = key.as_ref();
self.elems.iter().find(|(k, _)| k == key).map(|(_, v)| v)
}
}
impl Clone for Body {
fn clone(&self) -> Self {
let mut new = Body::default();
self.into_iter()
.cloned()
.for_each(|(k, v)| new.push((k, v)));
new
}
}
impl<'a> IntoIterator for &'a Body {
type Item = &'a (Key, Value<'a>);
type IntoIter = std::slice::Iter<'a, (Key, Value<'a>)>;
fn into_iter(self) -> Self::IntoIter {
self.elems.iter()
}
}
impl TryFrom<Value<'_>> for Vec<u8> {
type Error = &'static str;
fn try_from(v: Value) -> Result<Self, Self::Error> {
match v {
Value::Str(r, Quote::Braces) => {
let mut s = Vec::with_capacity(r.len() + 2);
s.push(b'{');
s.extend(Vec::from(r));
s.push(b'}');
Ok(s)
}
Value::Str(r, _) => Ok(Vec::from(r)),
Value::Empty => Ok("".into()),
Value::Segments(ranges) => {
let l = ranges.iter().map(|r| r.len()).sum();
let mut sb = Vec::with_capacity(l);
for r in ranges {
sb.extend(Vec::from(r));
}
Ok(sb)
}
Value::Number(_) => Err("Won't convert number to string"),
Value::List(_) | Value::StringifiedList(_) => Err("Can't convert list to scalar"),
Value::Map(_) => Err("Can't convert map to scalar"),
Value::Skipped(_) => Err("Can't convert skipped to scalar"),
Value::Literal(s) => Ok(s.to_string().into()),
Value::Owned(v) => Ok(v),
}
}
}
impl TryFrom<Value<'_>> for Vec<Vec<u8>> {
type Error = &'static str;
fn try_from(value: Value) -> Result<Self, Self::Error> {
match value {
Value::List(values) | Value::StringifiedList(values) => {
let mut rv = Vec::with_capacity(values.len());
for v in values {
let s = Vec::try_from(v)?;
rv.push(s);
}
Ok(rv)
}
_ => Err("not a list"),
}
}
}
impl Debug for Value<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Value::Str(r, _q) => write!(f, "Str:<{}>", &String::from_utf8_lossy(r)),
Value::Empty => write!(f, "Empty"),
Value::Segments(segs) => {
write!(f, "Segments<")?;
for (n, r) in segs.iter().enumerate() {
if n > 0 {
write!(f, ", ")?;
}
write!(f, "{}", String::from_utf8_lossy(r))?;
}
write!(f, ">")
}
Value::List(vs) => {
write!(f, "List:<")?;
for (n, v) in vs.iter().enumerate() {
if n > 0 {
write!(f, ", ")?;
}
match v {
Value::Str(r, _) => {
write!(f, "{}", String::from_utf8_lossy(r))?;
}
Value::Segments(rs) => {
for r in rs {
write!(f, "{}", String::from_utf8_lossy(r))?;
}
}
Value::Number(n) => write!(f, "{n:?}")?,
Value::Skipped((elems, bytes)) => {
write!(f, "Skip<elems{elems} bytes={bytes}>")?;
}
Value::Empty => panic!("list can't contain empty value"),
Value::List(_) | Value::StringifiedList(_) => {
panic!("list can't contain list")
}
Value::Map(_) => panic!("list can't contain map"),
Value::Literal(v) => write!(f, "{v:?}")?,
Value::Owned(v) => write!(f, "{}", String::from_utf8_lossy(v))?,
}
}
write!(f, ">")
}
Value::StringifiedList(vs) => {
write!(f, "StringifiedList:<")?;
for (n, v) in vs.iter().enumerate() {
if n > 0 {
write!(f, " ")?;
}
match v {
Value::Str(r, _) => {
write!(f, "{}", String::from_utf8_lossy(r))?;
}
Value::Segments(rs) => {
for r in rs {
write!(f, "{}", String::from_utf8_lossy(r))?;
}
}
Value::Number(n) => write!(f, "{n:?}")?,
Value::Skipped((elems, bytes)) => {
write!(f, "Skip<elems={elems} bytes={bytes}>")?;
}
Value::Empty => panic!("list can't contain empty value"),
Value::List(_) | Value::StringifiedList(_) => {
panic!("list can't contain list")
}
Value::Map(_) => panic!("List can't contain mapr"),
Value::Literal(v) => write!(f, "{v}")?,
Value::Owned(v) => write!(f, "{}", String::from_utf8_lossy(v))?,
}
}
write!(f, ">")
}
Value::Map(vs) => {
write!(f, "Map:<")?;
for (n, (k, v)) in vs.iter().enumerate() {
if n > 0 {
write!(f, " ")?;
}
write!(f, "{k:?}={v:?}")?;
}
write!(f, ">")
}
Value::Number(n) => write!(f, "{n:?}"),
Value::Skipped((elems, bytes)) => write!(f, "Skip<elems={elems} bytes={bytes}>"),
Value::Literal(s) => write!(f, "{s:?}"),
Value::Owned(v) => write!(f, "{}", String::from_utf8_lossy(v)),
}
}
}
impl Serialize for Value<'_> {
#[inline(always)]
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
Value::Empty => s.serialize_none(),
Value::Str(r, Quote::Braces) => {
let mut buf = Vec::with_capacity(r.len() + 2);
buf.push(b'{');
buf.extend(*r);
buf.push(b'}');
s.serialize_bytes(&buf)
}
Value::Str(r, _) => s.serialize_bytes(r),
Value::Segments(segs) => {
let l = segs.iter().map(|r| r.len()).sum();
let mut buf = Vec::with_capacity(l);
for seg in segs {
buf.extend(*seg);
}
s.serialize_bytes(&buf)
}
Value::List(vs) => s.collect_seq(vs.iter()),
Value::StringifiedList(vs) => {
let mut buf: Vec<u8> = Vec::with_capacity(vs.len());
let mut first = true;
for v in vs {
if first {
first = false;
} else {
buf.push(b' ');
}
if let Value::Skipped((args, bytes)) = v {
buf.extend(format!("<<< Skipped: args={args}, bytes={bytes} >>>").bytes());
} else {
buf.extend(v.clone().try_into().unwrap_or_else(|_| vec![b'x']));
}
}
s.serialize_bytes(&buf)
}
Value::Number(n) => n.serialize(s),
Value::Map(vs) => s.collect_map(vs.iter().cloned()),
Value::Skipped((args, bytes)) => {
let mut map = s.serialize_map(Some(2))?;
map.serialize_entry("skipped_args", args)?;
map.serialize_entry("skipped_bytes", bytes)?;
map.end()
}
Value::Literal(v) => s.collect_str(v),
Value::Owned(v) => Bytes(v).serialize(s),
}
}
}
impl PartialEq<str> for Value<'_> {
fn eq(&self, other: &str) -> bool {
self == other.as_bytes()
}
}
impl PartialEq<[u8]> for Value<'_> {
fn eq(&self, other: &[u8]) -> bool {
match self {
Value::Empty => other.is_empty(),
Value::Str(r, _) => r == &other,
Value::Segments(segs) => {
let l = segs.iter().map(|s| s.len()).sum();
let mut buf: Vec<u8> = Vec::with_capacity(l);
for s in segs {
buf.extend(*s);
}
buf == other
}
Value::Literal(s) => s.as_bytes() == other,
Value::Owned(v) => v == other,
Value::List(_)
| Value::StringifiedList(_)
| Value::Map(_)
| Value::Skipped(_)
| Value::Number(_) => false,
}
}
}
impl<'a> From<&'a [u8]> for Value<'a> {
fn from(value: &'a [u8]) -> Self {
Value::Str(value, Quote::None)
}
}
impl<'a> From<&'a str> for Value<'a> {
fn from(value: &'a str) -> Self {
Self::from(value.as_bytes())
}
}
impl From<Vec<u8>> for Value<'_> {
fn from(value: Vec<u8>) -> Self {
Value::Owned(value)
}
}
impl From<String> for Value<'_> {
fn from(value: String) -> Self {
Self::from(Vec::from(value))
}
}
impl From<i64> for Value<'_> {
fn from(value: i64) -> Self {
Value::Number(Number::Dec(value))
}
}
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Serialize for Bytes<'a> {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_bytes(self.0)
}
}