Day 35 — I/O Patterns for Networking
Learning Objectives
- Implement bidirectional TCP proxying — the core of every proxy and load balancer
- Use
io.TeeReaderto tap traffic without breaking the data stream - Understand zero-copy concepts for high-throughput proxies
Exercise: TCP Traffic Mirror
package main
import (
"fmt"
"io"
"net"
"os"
"sync"
"time"
)
// mirrorConn proxies client↔upstream and tees all traffic to a tap writer
func mirrorConn(client net.Conn, upstreamAddr string, tap io.Writer) {
defer client.Close()
// Connect to upstream
upstream, err := net.DialTimeout("tcp", upstreamAddr, 5*time.Second)
if err != nil {
fmt.Fprintf(os.Stderr, "upstream connect failed: %v\n", err)
return
}
defer upstream.Close()
remote := client.RemoteAddr().String()
fmt.Printf("PROXY %s → %s\n", remote, upstreamAddr)
var wg sync.WaitGroup
wg.Add(2)
// client → upstream (tee to tap)
go func() {
defer wg.Done()
// TeeReader: every byte read from client is also written to tap
tee := io.TeeReader(client, prefixWriter(tap, fmt.Sprintf("[%s→UP] ", remote)))
n, err := io.Copy(upstream, tee)
fmt.Printf("SENT %s: %d bytes (err: %v)\n", remote, n, err)
upstream.(*net.TCPConn).CloseWrite() // signal EOF to upstream
}()
// upstream → client (tee to tap)
go func() {
defer wg.Done()
tee := io.TeeReader(upstream, prefixWriter(tap, fmt.Sprintf("[UP→%s] ", remote)))
n, err := io.Copy(client, tee)
fmt.Printf("RECV %s: %d bytes (err: %v)\n", remote, n, err)
client.(*net.TCPConn).CloseWrite()
}()
wg.Wait()
fmt.Printf("CLOSE %s\n", remote)
}
// prefixWriter adds a prefix to each Write call
type prefixWriter struct {
w io.Writer
prefix string
}
func (pw prefixWriter) Write(p []byte) (int, error) {
fmt.Fprintf(pw.w, "%s%d bytes: %q\n", pw.prefix, len(p), p)
return len(p), nil
}
func main() {
// Tap: write to file
tapFile, err := os.Create("traffic-tap.log")
if err != nil {
fmt.Println("ERROR:", err)
return
}
defer tapFile.Close()
ln, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("ERROR:", err)
return
}
fmt.Println("Mirror proxy on :8080 → upstream :9090")
fmt.Println("Traffic logged to traffic-tap.log")
for {
conn, err := ln.Accept()
if err != nil { return }
go mirrorConn(conn, "127.0.0.1:9090", tapFile)
}
}
Real-World Context
io.TeeReader is used by:
- Security tools: Wireshark-equivalent for HTTP traffic
- Debugging proxies: mitmproxy tees traffic to show you the payload
- WAFs: inspect the request body without consuming it (the body must still reach the backend)
- Compliance: PCI DSS requires recording transaction data for certain merchant levels