<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>tinytap on tinytap docs</title><link>https://shinagawa-web.github.io/tinytap/</link><description>Recent content in tinytap on tinytap docs</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://shinagawa-web.github.io/tinytap/index.xml" rel="self" type="application/rss+xml"/><item><title>Quick Start</title><link>https://shinagawa-web.github.io/tinytap/docs/quick-start/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/quick-start/</guid><description>&lt;h1 id="quick-start"&gt;Quick Start&lt;a class="anchor" href="#quick-start"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="install"&gt;Install&lt;a class="anchor" href="#install"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -fsSL https://raw.githubusercontent.com/shinagawa-web/tinytap/main/scripts/install.sh | sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="run"&gt;Run&lt;a class="anchor" href="#run"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Grant it the capabilities it needs, then run it (no full root required):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo setcap cap_dac_read_search,cap_perfmon,cap_bpf,cap_sys_admin,cap_syslog&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eip &lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;command -v tinytap&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tinytap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s the full set: plaintext HTTP and HTTPS (via the libssl uprobes,
&lt;code&gt;cap_sys_admin&lt;/code&gt;) both work out of the box. See
&lt;a href="https://shinagawa-web.github.io/tinytap/docs/running-without-root/"&gt;Running Without Full Root&lt;/a&gt; if you
want the smaller plaintext-only set instead, or a breakdown of what each
capability actually covers.&lt;/p&gt;
&lt;p&gt;With no config file, that opens the TUI (&lt;code&gt;j&lt;/code&gt;/&lt;code&gt;k&lt;/code&gt; to scroll, &lt;code&gt;Enter&lt;/code&gt; for the
detail panel, &lt;code&gt;q&lt;/code&gt; or &lt;code&gt;Ctrl-C&lt;/code&gt; to quit) as long as your terminal is at least
120x24. In a smaller or non-interactive terminal it prints guidance and exits
instead of silently streaming; see &lt;a href="https://shinagawa-web.github.io/tinytap/docs/configuration/"&gt;Configuration&lt;/a&gt;
to switch to the line-oriented &lt;code&gt;stdout&lt;/code&gt; mode.&lt;/p&gt;</description></item><item><title>Use Cases</title><link>https://shinagawa-web.github.io/tinytap/docs/use-cases/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/use-cases/</guid><description>&lt;h1 id="use-cases"&gt;Use Cases&lt;a class="anchor" href="#use-cases"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;tinytap&lt;/code&gt; attaches to a process&amp;rsquo;s socket syscalls and libssl uprobes and
decodes what it sees as HTTP/1.1; see
&lt;a href="https://shinagawa-web.github.io/tinytap/docs/how-it-works/"&gt;How It Works&lt;/a&gt; for the mechanism. That
gives it a few concrete uses beyond &amp;ldquo;watch traffic go by.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="see-exactly-what-your-app-sent-including-over-https"&gt;See exactly what your app sent, including over HTTPS&lt;a class="anchor" href="#see-exactly-what-your-app-sent-including-over-https"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An app makes an HTTPS call and you need to know precisely what went out: the
request line, every header (including &lt;code&gt;Authorization&lt;/code&gt;), the JSON body as
sent. Normally that means a proxy (mitmproxy, Charles) with a CA certificate
installed in the app&amp;rsquo;s trust store, which is extra setup and doesn&amp;rsquo;t work at
all against apps that pin certificates.&lt;/p&gt;</description></item><item><title>Usage</title><link>https://shinagawa-web.github.io/tinytap/docs/usage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/usage/</guid><description>&lt;h1 id="usage"&gt;Usage&lt;a class="anchor" href="#usage"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://shinagawa-web.github.io/tinytap/docs/quick-start/"&gt;Quick Start&lt;/a&gt; gets &lt;code&gt;tinytap&lt;/code&gt; running. This page
covers what to do once it&amp;rsquo;s up: reading the TUI, reading the &lt;code&gt;stdout&lt;/code&gt; JSONL
format, and when to reach for &lt;code&gt;doctor&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="tui"&gt;TUI&lt;a class="anchor" href="#tui"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;output = &amp;quot;auto&amp;quot;&lt;/code&gt; (the default) opens the TUI whenever stdout/stdin are an
interactive terminal of at least 120x24. See
&lt;a href="https://shinagawa-web.github.io/tinytap/docs/configuration/"&gt;Configuration&lt;/a&gt; to force it with &lt;code&gt;output = &amp;quot;tui&amp;quot;&lt;/code&gt; or opt out with &lt;code&gt;output = &amp;quot;stdout&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;img src="https://shinagawa-web.github.io/tinytap/tui-demo.gif" width="800" alt="tinytap's TUI: the request table on top, and the detail panel below showing the full request and response, including headers and the decoded JSON body"&gt;
&lt;h3 id="request-table"&gt;Request table&lt;a class="anchor" href="#request-table"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Every captured exchange is a row: timestamp, &lt;code&gt;process[pid]&lt;/code&gt;, method, path,
status, response size, latency. New rows arrive at the bottom; the view
follows the newest row automatically until you scroll away from it.&lt;/p&gt;</description></item><item><title>Where tinytap Runs</title><link>https://shinagawa-web.github.io/tinytap/docs/where-it-runs/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/where-it-runs/</guid><description>&lt;h1 id="where-tinytap-runs"&gt;Where tinytap Runs&lt;a class="anchor" href="#where-tinytap-runs"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;tinytap requires a Linux kernel.&lt;/strong&gt; It cannot run natively on macOS or
Windows, because eBPF is a Linux kernel technology. But that&amp;rsquo;s less
restrictive than it sounds, because Linux kernels are everywhere:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Where the user works&lt;/th&gt;
					&lt;th&gt;How tinytap runs there&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Linux (desktop, laptop, workstation, or server)&lt;/td&gt;
					&lt;td&gt;Native. Just run the binary.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Mac (Intel or Apple Silicon)&lt;/td&gt;
					&lt;td&gt;Inside a Linux VM (Docker Desktop&amp;rsquo;s VM, OrbStack, Lima, UTM, Multipass, etc.).&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Windows&lt;/td&gt;
					&lt;td&gt;Inside WSL2 (which is a real Linux kernel).&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="does-tinytap-see-inside-containers"&gt;Does tinytap see inside containers?&lt;a class="anchor" href="#does-tinytap-see-inside-containers"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A common question: &amp;ldquo;if my dev stack runs in Docker on my Mac, can tinytap see
inside the containers?&amp;rdquo;&lt;/p&gt;</description></item><item><title>Running Without Full Root</title><link>https://shinagawa-web.github.io/tinytap/docs/running-without-root/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/running-without-root/</guid><description>&lt;h1 id="running-without-full-root"&gt;Running Without Full Root&lt;a class="anchor" href="#running-without-full-root"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;sudo ./tinytap&lt;/code&gt; is the simplest path, but tinytap doesn&amp;rsquo;t need full root.&lt;/p&gt;
&lt;h2 id="the-minimal-set"&gt;The minimal set&lt;a class="anchor" href="#the-minimal-set"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Plaintext HTTP capture (syscall tracepoints, ringbuf) needs three
capabilities on every architecture, on a 5.11+ kernel. On an older kernel
(5.8–5.10, still within tinytap&amp;rsquo;s documented floor) a fourth capability,
&lt;code&gt;cap_sys_resource&lt;/code&gt;, is additionally needed. See
&lt;a href="#why-cap_sys_resource-turned-out-not-to-matter"&gt;Why &lt;code&gt;cap_sys_resource&lt;/code&gt; turned out not to matter&lt;/a&gt;
below for why:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo setcap cap_dac_read_search,cap_perfmon,cap_bpf&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eip ./tinytap
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./tinytap &lt;span style="color:#75715e"&gt;# no sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s enough for the core capture path everywhere, and for the optional
&lt;code&gt;sendfile&lt;/code&gt; payload-capture kprobe on arm64, but not for that same
kprobe on x86_64, which additionally needs &lt;code&gt;cap_syslog&lt;/code&gt; (see the table
below). Its failure degrades gracefully either way (sendfile events just
carry no payload bytes), so this only matters if you want full-fidelity
&lt;code&gt;sendfile&lt;/code&gt; capture on x86_64:&lt;/p&gt;</description></item><item><title>How It Works</title><link>https://shinagawa-web.github.io/tinytap/docs/how-it-works/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/how-it-works/</guid><description>&lt;h1 id="how-it-works"&gt;How It Works&lt;a class="anchor" href="#how-it-works"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;tinytap&lt;/code&gt; attaches eBPF probes to a process&amp;rsquo;s socket syscalls
(&lt;code&gt;accept4&lt;/code&gt;/&lt;code&gt;read&lt;/code&gt;/&lt;code&gt;write&lt;/code&gt;/&lt;code&gt;close&lt;/code&gt;/&lt;code&gt;recvfrom&lt;/code&gt;/&lt;code&gt;sendto&lt;/code&gt;/&lt;code&gt;recvmsg&lt;/code&gt;/&lt;code&gt;sendmsg&lt;/code&gt;),
parses the payload bytes as HTTP/1.1, pairs each request with its response,
and renders the exchange live, either in the terminal TUI or as JSONL
(one JSON object per exchange) on stdout:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&amp;#34;reqTsNs&amp;#34;:1754887677005000000,&amp;#34;latencyNs&amp;#34;:300000,&amp;#34;pid&amp;#34;:27122,&amp;#34;comm&amp;#34;:&amp;#34;python3&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;path&amp;#34;:&amp;#34;/&amp;#34;,&amp;#34;status&amp;#34;:200,&amp;#34;resBytes&amp;#34;:1304,&amp;#34;abandoned&amp;#34;:false,...}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;output = &amp;quot;auto&amp;quot;&lt;/code&gt; (the default) picks the TUI when stdout/stdin are an
interactive terminal of at least 120x24; otherwise it prints guidance and
exits rather than silently streaming; the JSONL stream is opt-in via
&lt;code&gt;output = &amp;quot;stdout&amp;quot;&lt;/code&gt;. &lt;code&gt;output = &amp;quot;tui&amp;quot;&lt;/code&gt; forces the TUI (and exits the same way
if the terminal can&amp;rsquo;t host it). &lt;code&gt;--version&lt;/code&gt; prints the build&amp;rsquo;s version,
commit, and date, and exits without needing root.&lt;/p&gt;</description></item><item><title>Configuration</title><link>https://shinagawa-web.github.io/tinytap/docs/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/configuration/</guid><description>&lt;h1 id="configuration"&gt;Configuration&lt;a class="anchor" href="#configuration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Session settings (&lt;code&gt;output&lt;/code&gt; and process filters) live in a TOML
config file, not CLI flags. &lt;code&gt;tinytap config init &amp;amp;&amp;amp; tinytap&lt;/code&gt; just works.
See &lt;code&gt;config init&lt;/code&gt; in &lt;a href="#cli-surface"&gt;CLI surface&lt;/a&gt; below.&lt;/p&gt;
&lt;h2 id="cli-surface"&gt;CLI surface&lt;a class="anchor" href="#cli-surface"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The only CLI surface is one-shot actions, not session settings:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Flag / command&lt;/th&gt;
					&lt;th&gt;What it does&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--config &amp;lt;path&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Point at an alternate config file&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--version&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Print build metadata, exiting before any eBPF load&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;config init&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Write a fully-populated default config file&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;doctor&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Read-only preflight checks (see &lt;a href="https://shinagawa-web.github.io/tinytap/docs/troubleshooting/"&gt;Troubleshooting&lt;/a&gt;)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="search-order-and-defaults"&gt;Search order and defaults&lt;a class="anchor" href="#search-order-and-defaults"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Search order when &lt;code&gt;--config &amp;lt;path&amp;gt;&lt;/code&gt; isn&amp;rsquo;t given:
&lt;code&gt;./tinytap.toml&lt;/code&gt;, then &lt;code&gt;$XDG_CONFIG_HOME/tinytap/config.toml&lt;/code&gt; (falling back
to &lt;code&gt;~/.config/tinytap/config.toml&lt;/code&gt;). Finding neither is not an error, and the
defaults below apply.&lt;/p&gt;</description></item><item><title>Server Compatibility</title><link>https://shinagawa-web.github.io/tinytap/docs/server-compatibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/server-compatibility/</guid><description>&lt;h1 id="server-compatibility"&gt;Server Compatibility&lt;a class="anchor" href="#server-compatibility"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Which syscall a plaintext HTTP server uses to send its response body
determines how much of it tinytap can see.&lt;/p&gt;
&lt;h2 id="compatibility-table"&gt;Compatibility table&lt;a class="anchor" href="#compatibility-table"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;See &lt;a href="#cross-server-summary"&gt;Cross-server summary&lt;/a&gt; below for what each
syscall means for visibility in practice.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Server&lt;/th&gt;
					&lt;th&gt;Syscall&lt;/th&gt;
					&lt;th&gt;Notes&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Python &lt;code&gt;http.server&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sendto&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Headers and body go out as separate &lt;code&gt;sendto&lt;/code&gt; calls, no chunking&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Go &lt;code&gt;net/http&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;write&lt;/code&gt; / &lt;code&gt;sendfile&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;write&lt;/code&gt; for small bodies, &lt;code&gt;sendfile&lt;/code&gt; above ~512 B&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Node.js &lt;code&gt;http.createServer&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;writev&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Chunked encoding when &lt;code&gt;Content-Length&lt;/code&gt; is unknown&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nginx (static, &lt;code&gt;sendfile on&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;writev&lt;/code&gt; + &lt;code&gt;sendfile&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Default nginx config&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nginx (static, &lt;code&gt;sendfile off&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;writev&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Body lives in &lt;code&gt;iovec[1+]&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nginx (reverse proxy)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;writev&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;proxy_pass&lt;/code&gt; never touches &lt;code&gt;sendfile&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Caddy&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;write&lt;/code&gt; / &lt;code&gt;sendfile&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Same syscall shape as Go &lt;code&gt;net/http&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Bun.serve&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sendto&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;No &lt;code&gt;sendfile&lt;/code&gt; despite &lt;code&gt;Bun.file()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Uvicorn (ASGI)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sendto&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Same shape as Python &lt;code&gt;http.server&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Gunicorn (WSGI)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sendto&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Same shape as Python &lt;code&gt;http.server&lt;/code&gt;/Uvicorn&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Axum (Rust / hyper)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;writev&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Content-Length&lt;/code&gt; always known, no chunking&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cross-server-summary"&gt;Cross-server summary&lt;a class="anchor" href="#cross-server-summary"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Across every server row in the table above, the outgoing syscall shape
falls into one of three groups, not based on language or performance but
on what each project treats as its core use case:&lt;/p&gt;</description></item><item><title>TLS Compatibility</title><link>https://shinagawa-web.github.io/tinytap/docs/tls-compatibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/tls-compatibility/</guid><description>&lt;h1 id="tls-compatibility"&gt;TLS Compatibility&lt;a class="anchor" href="#tls-compatibility"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Which TLS-terminating servers/clients tinytap can capture via the
&lt;code&gt;SSL_write&lt;/code&gt;/&lt;code&gt;SSL_read&lt;/code&gt;/&lt;code&gt;SSL_free&lt;/code&gt; libssl uprobes, a separate mechanism from
the &lt;a href="https://shinagawa-web.github.io/tinytap/docs/server-compatibility/"&gt;Server Compatibility&lt;/a&gt; sample-cap
table. The uprobe reads the plaintext buffer directly (up to its own 4096 B
cap) before encryption or after decryption, rather than sampling wire bytes
off the ciphertext syscalls underneath.&lt;/p&gt;
&lt;h2 id="whats-covered"&gt;What&amp;rsquo;s covered&lt;a class="anchor" href="#whats-covered"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;tinytap has been verified against Python &lt;code&gt;ssl&lt;/code&gt;-wrapped &lt;code&gt;http.server&lt;/code&gt;, nginx
(Debian-based and Alpine-based images), curl, and Node.js (NodeSource,
official, and nvm builds): TLS traffic decrypts and pairs correctly for
all of them. This only covers OpenSSL-based stacks; see
&lt;a href="https://shinagawa-web.github.io/tinytap/docs/limitations/"&gt;Current Limitations&lt;/a&gt; for what&amp;rsquo;s not covered,
such as Go&amp;rsquo;s &lt;code&gt;crypto/tls&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Platform Support</title><link>https://shinagawa-web.github.io/tinytap/docs/compat-matrix/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/compat-matrix/</guid><description>&lt;h1 id="platform-support"&gt;Platform Support&lt;a class="anchor" href="#platform-support"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Which Linux distributions and kernel versions tinytap has been verified on.
Every row in the table below is a real test run. Untested combinations are not listed.&lt;/p&gt;
&lt;h2 id="arm64"&gt;arm64&lt;a class="anchor" href="#arm64"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Distro&lt;/th&gt;
					&lt;th&gt;Kernel&lt;/th&gt;
					&lt;th&gt;Plaintext&lt;/th&gt;
					&lt;th&gt;TLS&lt;/th&gt;
					&lt;th&gt;Notes&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 25.10&lt;/td&gt;
					&lt;td&gt;6.17.0-41-generic&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 24.04&lt;/td&gt;
					&lt;td&gt;6.8.0&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 22.04&lt;/td&gt;
					&lt;td&gt;5.15.0&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;sendfile body not captured (&lt;code&gt;BPF_PROG_TYPE_TRACING&lt;/code&gt; not available in this kernel config)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fedora 43&lt;/td&gt;
					&lt;td&gt;6.17.1&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debian 12&lt;/td&gt;
					&lt;td&gt;6.1.0&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;sendfile body not captured; &lt;code&gt;cap_sys_admin&lt;/code&gt; required even for plaintext&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AlmaLinux 9&lt;/td&gt;
					&lt;td&gt;5.14.0 (RHEL)&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;sendfile body not captured&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Alpine 3.23&lt;/td&gt;
					&lt;td&gt;6.18.22-virt&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;sendfile body not captured; static binary required&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 20.04 (GA kernel)&lt;/td&gt;
					&lt;td&gt;5.4.0&lt;/td&gt;
					&lt;td&gt;✗&lt;/td&gt;
					&lt;td&gt;✗&lt;/td&gt;
					&lt;td&gt;kernel 5.8+ required&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="amd64"&gt;amd64&lt;a class="anchor" href="#amd64"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Distro&lt;/th&gt;
					&lt;th&gt;Kernel&lt;/th&gt;
					&lt;th&gt;Plaintext&lt;/th&gt;
					&lt;th&gt;TLS&lt;/th&gt;
					&lt;th&gt;Notes&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 26.04&lt;/td&gt;
					&lt;td&gt;7.0.0&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;sendfile body requires &lt;code&gt;cap_syslog&lt;/code&gt; (&lt;code&gt;kptr_restrict=1&lt;/code&gt; blocks kprobe symbol lookup without it)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fedora 43&lt;/td&gt;
					&lt;td&gt;6.17.1&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debian 12&lt;/td&gt;
					&lt;td&gt;6.1.0&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;cap_sys_admin&lt;/code&gt; required even for plaintext (&lt;code&gt;perf_event_paranoid=3&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 24.04&lt;/td&gt;
					&lt;td&gt;6.17.0-azure&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 22.04&lt;/td&gt;
					&lt;td&gt;6.8.0-azure&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;ldquo;sendfile body not captured&amp;rdquo; means &lt;code&gt;GET /file.bin&lt;/code&gt; returns status and size correctly but body bytes are 0. Only static file serving via &lt;code&gt;sendfile(2)&lt;/code&gt; is affected. All other capture paths work normally. See &lt;a href="https://shinagawa-web.github.io/tinytap/docs/server-compatibility/"&gt;Server Compatibility&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Installing &amp; Verifying Releases</title><link>https://shinagawa-web.github.io/tinytap/docs/installing-and-verifying/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/installing-and-verifying/</guid><description>&lt;h1 id="installing--verifying-releases"&gt;Installing &amp;amp; Verifying Releases&lt;a class="anchor" href="#installing--verifying-releases"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="installing-a-specific-version-or-location"&gt;Installing a specific version or location&lt;a class="anchor" href="#installing-a-specific-version-or-location"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Two env vars change the install script&amp;rsquo;s behavior. Set them on the &lt;code&gt;sh&lt;/code&gt;
side of the pipe, not before &lt;code&gt;curl&lt;/code&gt;, since a &lt;code&gt;VAR=val curl ... | sh&lt;/code&gt; prefix
only reaches &lt;code&gt;curl&lt;/code&gt;, not the piped-in script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -fsSL https://raw.githubusercontent.com/shinagawa-web/tinytap/main/scripts/install.sh | TINYTAP_VERSION&lt;span style="color:#f92672"&gt;=&lt;/span&gt;v0.6.1 sh &lt;span style="color:#75715e"&gt;# pin a release instead of the latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -fsSL https://raw.githubusercontent.com/shinagawa-web/tinytap/main/scripts/install.sh | INSTALL_DIR&lt;span style="color:#f92672"&gt;=&lt;/span&gt;~/bin sh &lt;span style="color:#75715e"&gt;# install somewhere other than /usr/local/bin&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="verifying-a-release-download"&gt;Verifying a release download&lt;a class="anchor" href="#verifying-a-release-download"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The install script already verifies the downloaded archive&amp;rsquo;s SHA-256
checksum automatically. This section is for downloading a release archive
by hand instead (from the
&lt;a href="https://github.com/shinagawa-web/tinytap/releases"&gt;releases page&lt;/a&gt; or in a
script that intentionally avoids &lt;code&gt;curl | sh&lt;/code&gt;) and confirming its full chain
of trust, including the cosign signature the install script doesn&amp;rsquo;t check.&lt;/p&gt;</description></item><item><title>Troubleshooting</title><link>https://shinagawa-web.github.io/tinytap/docs/troubleshooting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/troubleshooting/</guid><description>&lt;h1 id="troubleshooting"&gt;Troubleshooting&lt;a class="anchor" href="#troubleshooting"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;If it didn&amp;rsquo;t work, run &lt;code&gt;tinytap doctor&lt;/code&gt; first: read-only preflight checks
(kernel version, BTF availability, the required
&lt;a href="https://shinagawa-web.github.io/tinytap/docs/running-without-root/"&gt;capabilities&lt;/a&gt;, syscall tracepoint
availability, a dry-run BPF load, and the host&amp;rsquo;s libssl execute bit),
printed as a copy-paste-friendly report, without needing root or capabilities itself:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tinytap doctor&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For example, on a host that hasn&amp;rsquo;t been granted any capabilities yet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tinytap doctor — tinytap dev (commit none, built unknown)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[OK ] kernel version 6.17.0-41-generic (&amp;gt;= 5.8 required)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[OK ] kernel BTF /sys/kernel/btf/vmlinux present
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[BLOCKING] cap_dac_read_search missing
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Affects: Everything — needed to open /sys/kernel/tracing/events/syscalls/*/id to resolve tracepoint IDs.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Fix: sudo setcap cap_dac_read_search,cap_perfmon,cap_bpf,cap_sys_admin,cap_syslog=eip &amp;lt;path-to-tinytap&amp;gt; # adds cap_dac_read_search
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[BLOCKING] cap_perfmon missing
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Affects: Everything — needed to attach the tracepoint/kprobe/fentry programs.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Fix: sudo setcap cap_dac_read_search,cap_perfmon,cap_bpf,cap_sys_admin,cap_syslog=eip &amp;lt;path-to-tinytap&amp;gt; # adds cap_perfmon
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[BLOCKING] cap_bpf missing
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Affects: Everything — needed to load BPF programs and maps.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Fix: sudo setcap cap_dac_read_search,cap_perfmon,cap_bpf,cap_sys_admin,cap_syslog=eip &amp;lt;path-to-tinytap&amp;gt; # adds cap_bpf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[DEGRADED] cap_sys_admin missing
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Affects: TLS capture only. Plaintext HTTP capture is unaffected.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Fix: sudo setcap cap_dac_read_search,cap_perfmon,cap_bpf,cap_sys_admin,cap_syslog=eip &amp;lt;path-to-tinytap&amp;gt; # adds cap_sys_admin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[OK ] cap_syslog not needed on arm64
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[INFO ] perf_event_paranoid 4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[INFO ] unprivileged_bpf_disabled 2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[INFO ] RLIMIT_MEMLOCK soft=8388608 hard=8388608
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[OK ] syscall tracepoints all 16 present
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[OK ] architecture arm64 (sendfile kprobe + TLS uprobes supported)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[BLOCKING] BPF dry-run load remove memlock: failed to set memlock rlimit: operation not permitted
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Affects: Everything — this is the first step tinytap&amp;#39;s real startup performs.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Fix: run with the capabilities listed at https://shinagawa-web.github.io/tinytap/docs/running-without-root/, or as root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[OK ] libssl (host) /lib/aarch64-linux-gnu/libssl.so.3 executable
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;6 ok, 1 degraded, 4 blocking, 3 info&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Granting the capabilities named in each &lt;code&gt;Fix&lt;/code&gt; line (see
&lt;a href="https://shinagawa-web.github.io/tinytap/docs/running-without-root/"&gt;Running Without Full Root&lt;/a&gt;) turns
every &lt;code&gt;BLOCKING&lt;/code&gt;/&lt;code&gt;DEGRADED&lt;/code&gt; line above into &lt;code&gt;OK&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Terminology</title><link>https://shinagawa-web.github.io/tinytap/docs/terminology/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/terminology/</guid><description>&lt;h1 id="terminology"&gt;Terminology&lt;a class="anchor" href="#terminology"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;These terms appear throughout the docs, the code, and the issue tracker. They are deliberately process-relative, since &amp;ldquo;from whose point of view?&amp;rdquo; matters.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Term&lt;/th&gt;
					&lt;th&gt;Meaning&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Outgoing syscall&lt;/td&gt;
					&lt;td&gt;A syscall that writes data &lt;em&gt;out of&lt;/em&gt; a process address space: &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;sendto&lt;/code&gt;, &lt;code&gt;sendmsg&lt;/code&gt;, &lt;code&gt;writev&lt;/code&gt;. The user buffer is already populated at &lt;code&gt;sys_enter&lt;/code&gt;, so the payload can be sampled on entry.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Incoming syscall&lt;/td&gt;
					&lt;td&gt;A syscall that reads data &lt;em&gt;into&lt;/em&gt; a process address space: &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;recvfrom&lt;/code&gt;, &lt;code&gt;recvmsg&lt;/code&gt;, &lt;code&gt;readv&lt;/code&gt;. The user buffer is empty at &lt;code&gt;sys_enter&lt;/code&gt;: the kernel fills it during the syscall, so the payload is only observable at &lt;code&gt;sys_exit&lt;/code&gt; (with the return value telling us how much was actually filled).&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;send-side / receive-side&lt;/td&gt;
					&lt;td&gt;Synonyms for outgoing / incoming, common in libbpf and Pixie writing. Acceptable once a paragraph has already grounded the direction; avoid as the &lt;em&gt;first&lt;/em&gt; mention because they sound like they refer to the protocol direction (request vs response) when they actually refer to the syscall family.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="protocol-mapping-http"&gt;Protocol mapping (HTTP)&lt;a class="anchor" href="#protocol-mapping-http"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;tinytap&lt;/code&gt; is process-oriented, not protocol-aware. The same syscall carries the request on one side and the response on the other depending on who is calling it:&lt;/p&gt;</description></item><item><title>Current Limitations</title><link>https://shinagawa-web.github.io/tinytap/docs/limitations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/limitations/</guid><description>&lt;h1 id="current-limitations"&gt;Current Limitations&lt;a class="anchor" href="#current-limitations"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="http11-only"&gt;HTTP/1.1 only&lt;a class="anchor" href="#http11-only"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;No HTTP/2, gRPC, or other protocols yet.&lt;/p&gt;
&lt;h2 id="tls-capture-needs-openssl"&gt;TLS capture needs OpenSSL&lt;a class="anchor" href="#tls-capture-needs-openssl"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;TLS capture needs OpenSSL to be reachable: either a dynamically linked &lt;code&gt;libssl.so&lt;/code&gt;, or (confirmed for Node.js&amp;rsquo;s official/NodeSource/nvm builds) an unstripped binary that statically bundles OpenSSL and still exports its symbols. Stacks that don&amp;rsquo;t use OpenSSL at all remain invisible either way, which includes Go&amp;rsquo;s &lt;code&gt;crypto/tls&lt;/code&gt; and therefore Go-based proxies like Traefik and Caddy. Clients that hand OpenSSL a custom &lt;code&gt;BIO&lt;/code&gt; instead of calling &lt;code&gt;SSL_set_fd&lt;/code&gt; (e.g. curl) are captured and paired, but keyed on the &lt;code&gt;SSL*&lt;/code&gt; pointer rather than a socket fd, so their exchanges are marked &lt;code&gt;[ssl-keyed, fd unverified]&lt;/code&gt;. See &lt;a href="https://shinagawa-web.github.io/tinytap/docs/tls-compatibility/"&gt;TLS Compatibility&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Internals</title><link>https://shinagawa-web.github.io/tinytap/docs/internals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://shinagawa-web.github.io/tinytap/docs/internals/</guid><description>&lt;h1 id="internals"&gt;Internals&lt;a class="anchor" href="#internals"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;How eBPF and tinytap actually get the payload bytes: the three kernel-side
observation points, the ring buffer design constraints that shaped them, and
the libssl uprobe mechanism that decrypts TLS traffic. This page stops at
capture; see &lt;a href="https://shinagawa-web.github.io/tinytap/docs/how-it-works/"&gt;How It Works&lt;/a&gt; for the eBPF
background and build pipeline, and &lt;a href="https://shinagawa-web.github.io/tinytap/docs/usage/"&gt;Usage&lt;/a&gt; for the
JSONL shape the captured bytes end up in.&lt;/p&gt;
&lt;h2 id="one-picture"&gt;One picture&lt;a class="anchor" href="#one-picture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;┌──────────────────────────── kernel ─────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ [A] tracepoint/syscalls/sys_{enter,exit}_* │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ bpf/tinytap.bpf.c ────────────► ringbuf events (8 MiB)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ accept4 read write close recvfrom sendto │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ recvmsg sendmsg writev readv sendfile64 │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ▲ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ hash sendfile_sample_map (tid → 4096 B) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ [B] fentry/tcp_sendmsg_locked │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ bpf/tinytap_kprobe.bpf.c (sendfile&amp;#39;s body, read straight │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ off the page cache, before it │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ever reaches a socket buffer) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ [C] uprobe/uretprobe on libssl.so │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ bpf/tinytap_uprobe.bpf.c ────────────► ringbuf ssl_events (1 MiB)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ SSL_write / SSL_read / SSL_set_fd / SSL_free │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ────────────► hash ssl_fd_map │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└────────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ events.Decode │ events.DecodeSSL
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; capture() (main pipeline) captureTLS() (one pair per pid)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Three independent observation points converge on the same downstream
pipeline. It decodes the ring buffer record, feeds it to the HTTP parser,
and pairs request with response. TLS support added a new &lt;em&gt;entry point&lt;/em&gt;, not
a second capture engine.&lt;/p&gt;</description></item></channel></rss>