Checkpoint the party/runtime stack before share-program and malicious-mode work.
Ship the TLS mesh, composer, Beaver/Yao/leaf MPC, prep/online paths, apps, and docs so the tree is pushable before elevating share_expr, security_mode, and prep resume. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
695f8e84f7
commit
0d22946a0e
1835 changed files with 170291 additions and 2849 deletions
161
include/dpf/net/link_log.hpp
Normal file
161
include/dpf/net/link_log.hpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/// @file dpf/net/link_log.hpp
|
||||
/// @brief Run-log records for listeners and established party links.
|
||||
/// @details `log_link_up` is called once per socket after the handshake and
|
||||
/// after the stream array has adopted and tuned it, so the socket
|
||||
/// options it reads back are the ones the kernel applied (Linux
|
||||
/// doubles `SO_SNDBUF`/`SO_RCVBUF` and clamps them to `wmem_max` and
|
||||
/// `rmem_max`). `TCP_INFO` at that point carries the kernel's RTT
|
||||
/// estimate from the connection setup and the handshake exchange.
|
||||
/// Encrypted links record the TLS version and cipher, how this side
|
||||
/// authenticated the peer (`auth=key` or `none`), the peer's key, and
|
||||
/// whether the peer authenticated this side. With encryption off the
|
||||
/// record says `auth=none encryption=none`, and the first plaintext
|
||||
/// link to an address off this host also raises one warning.
|
||||
#ifndef LIBDPF_INCLUDE_DPF_NET_LINK_LOG_HPP__
|
||||
#define LIBDPF_INCLUDE_DPF_NET_LINK_LOG_HPP__
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "dpf/log.hpp"
|
||||
#include "dpf/net/policy.hpp"
|
||||
#include "dpf/net/security.hpp"
|
||||
|
||||
namespace dpf
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline std::string sockaddr_text(const sockaddr_storage & ss)
|
||||
{
|
||||
char host[INET6_ADDRSTRLEN] = {};
|
||||
if (ss.ss_family == AF_INET)
|
||||
{
|
||||
const auto & a = reinterpret_cast<const sockaddr_in &>(ss);
|
||||
if (::inet_ntop(AF_INET, &a.sin_addr, host, sizeof(host)) == nullptr)
|
||||
return "unknown";
|
||||
return std::string(host) + ":" + std::to_string(ntohs(a.sin_port));
|
||||
}
|
||||
if (ss.ss_family == AF_INET6)
|
||||
{
|
||||
const auto & a = reinterpret_cast<const sockaddr_in6 &>(ss);
|
||||
if (::inet_ntop(AF_INET6, &a.sin6_addr, host, sizeof(host)) == nullptr)
|
||||
return "unknown";
|
||||
return "[" + std::string(host) + "]:" + std::to_string(ntohs(a.sin6_port));
|
||||
}
|
||||
if (ss.ss_family == AF_UNIX)
|
||||
{
|
||||
const auto & a = reinterpret_cast<const sockaddr_un &>(ss);
|
||||
return std::string("unix:") + (a.sun_path[0] != '\0' ? a.sun_path : "(unnamed)");
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
inline bool loopback(const sockaddr_storage & ss)
|
||||
{
|
||||
if (ss.ss_family == AF_INET)
|
||||
return (ntohl(reinterpret_cast<const sockaddr_in &>(ss).sin_addr.s_addr) >> 24)
|
||||
== 127u;
|
||||
if (ss.ss_family == AF_INET6)
|
||||
{
|
||||
const auto & a = reinterpret_cast<const sockaddr_in6 &>(ss).sin6_addr;
|
||||
if (IN6_IS_ADDR_LOOPBACK(&a))
|
||||
return true;
|
||||
return IN6_IS_ADDR_V4MAPPED(&a) && a.s6_addr[12] == 127;
|
||||
}
|
||||
return ss.ss_family == AF_UNIX;
|
||||
}
|
||||
|
||||
inline int int_opt(int fd, int level, int name)
|
||||
{
|
||||
int v = -1;
|
||||
socklen_t len = sizeof(v);
|
||||
if (::getsockopt(fd, level, name, &v, &len) != 0)
|
||||
return -1;
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// @brief Record a listener: this process accepts any address on `port`.
|
||||
/// @param encrypted whether connections on it must complete TLS 1.3 first
|
||||
inline void log_listen(unsigned short port, bool sctp, bool encrypted = false)
|
||||
{
|
||||
DPF_LOG(info, "listen").kv("addr", "0.0.0.0").kv("port", port)
|
||||
.kv("tcp", true).kv("sctp", sctp)
|
||||
.kv("encryption", encrypted ? "tls1.3" : "none");
|
||||
}
|
||||
|
||||
/// @brief Record one established socket of a party link.
|
||||
/// @param how `accept` or `connect`
|
||||
/// @param peer the other end's role (`p1`, `dealer`, ...)
|
||||
/// @param lane which socket of a `parallel` link (0 otherwise)
|
||||
/// @param sec how the link was secured (null or unencrypted: plaintext)
|
||||
inline void log_link_up(const char * how, const std::string & peer, transport kind,
|
||||
std::size_t lanes, std::uint32_t lane, std::uint32_t epoch, int fd,
|
||||
const socket_options & requested, const link_security * sec = nullptr)
|
||||
{
|
||||
const bool encrypted = sec != nullptr && sec->encrypted;
|
||||
if (!log::enabled(log::level::info) || fd < 0)
|
||||
return;
|
||||
sockaddr_storage local{};
|
||||
sockaddr_storage remote{};
|
||||
socklen_t local_len = sizeof(local);
|
||||
socklen_t remote_len = sizeof(remote);
|
||||
const bool have_local =
|
||||
::getsockname(fd, reinterpret_cast<sockaddr *>(&local), &local_len) == 0;
|
||||
const bool have_remote =
|
||||
::getpeername(fd, reinterpret_cast<sockaddr *>(&remote), &remote_len) == 0;
|
||||
{
|
||||
log::record rec(log::level::info, "link.up");
|
||||
rec.kv("how", how).kv("peer", peer).kv("transport", transport_name(kind))
|
||||
.kv("lanes", lanes).kv("lane", lane).kv("epoch", epoch)
|
||||
.kv("local", have_local ? detail::sockaddr_text(local) : std::string("unknown"))
|
||||
.kv("remote", have_remote ? detail::sockaddr_text(remote) : std::string("unknown"))
|
||||
.kv("auth", encrypted ? sec->peer_auth : std::string("none"))
|
||||
.kv("encryption",
|
||||
encrypted ? sec->protocol + "/" + sec->cipher : std::string("none"));
|
||||
if (encrypted)
|
||||
rec.kv("peer_key", sec->peer_key ? sec->peer_key->base64() : std::string("none"))
|
||||
.kv("peer_verified_us", sec->peer_verified_us);
|
||||
if (kind != transport::sctp)
|
||||
{
|
||||
rec.kv("nodelay", detail::int_opt(fd, IPPROTO_TCP, TCP_NODELAY))
|
||||
.kv("quickack_req", requested.quickack)
|
||||
.kv("keepalive", detail::int_opt(fd, SOL_SOCKET, SO_KEEPALIVE))
|
||||
.kv("sndbuf_req", requested.send_buffer)
|
||||
.kv("sndbuf", detail::int_opt(fd, SOL_SOCKET, SO_SNDBUF))
|
||||
.kv("rcvbuf_req", requested.recv_buffer)
|
||||
.kv("rcvbuf", detail::int_opt(fd, SOL_SOCKET, SO_RCVBUF));
|
||||
#if defined(TCP_INFO)
|
||||
tcp_info ti{};
|
||||
socklen_t ti_len = sizeof(ti);
|
||||
if (::getsockopt(fd, IPPROTO_TCP, TCP_INFO, &ti, &ti_len) == 0)
|
||||
rec.kv("rtt_us", ti.tcpi_rtt).kv("rttvar_us", ti.tcpi_rttvar)
|
||||
.kv("pmtu", ti.tcpi_pmtu).kv("snd_mss", ti.tcpi_snd_mss)
|
||||
.kv("snd_cwnd", ti.tcpi_snd_cwnd)
|
||||
.kv("retrans", ti.tcpi_total_retrans);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!encrypted && have_remote && !detail::loopback(remote)
|
||||
&& log::first_time("net.plaintext_remote"))
|
||||
DPF_LOG(warning, "link.plaintext").kv("remote", detail::sockaddr_text(remote))
|
||||
.kv("detail", "encryption is off: this party link is unauthenticated "
|
||||
"and unencrypted, and the handshake's party id is not verified");
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_NET_LINK_LOG_HPP__
|
||||
Loading…
Add table
Add a link
Reference in a new issue