Skip to content

Latest commit

 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-splice gopher

go-splice

Go Reference

Pure Kernel-Space bridge in Go.

Bridge copies bytes in both directions between two TCP connections until both sides close. On Linux it issues the splice(2) syscalls directly through SyscallConn(), moving payload socket-to-socket in kernel space — no per-connection buffer, no GC churn. On every other platform it falls back to io.Copy automatically.

This does not beat the standard library — it mirrors it. io.Copy between two *net.TCPConn already uses splice(2) under the hood, with pooled pipes and larger per-call transfers than this package uses. go-splice reimplements the same syscalls explicitly so the mechanism is legible top to bottom. In production, plain io.Copy is usually the right call; reach for this to read and understand how the fast path actually works.

Install

go get github.com/allenbiji/go-splice

Usage

A complete TCP proxy:

package main

import (
	"log"
	"net"

	"github.com/allenbiji/go-splice"
)

func main() {
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()
	log.Println("proxy listening on :8080")

	for {
		client, err := ln.Accept()
		if err != nil {
			continue
		}
		go handle(client.(*net.TCPConn))
	}
}

func handle(client *net.TCPConn) {
	defer client.Close()

	up, err := net.Dial("tcp", "127.0.0.1:9000")
	if err != nil {
		return
	}
	server := up.(*net.TCPConn)
	defer server.Close()

	n, err := goSplice.Bridge(client, server)
	if err != nil {
		log.Printf("bridge closed with error: %v", err)
		return
	}
	log.Printf("session closed, %d bytes relayed", n)
}

API

func Bridge(clientConn, serverConn *net.TCPConn) (int64, error)

Relays bytes in both directions until both directions reach EOF or error. Returns the total bytes relayed across both directions.

As each direction hits a clean EOF, Bridge half-closes the destination's write side (CloseWrite) so the peer sees an orderly end instead of a stalled, half-open connection. On a hard transport error it closes both connections so neither side waits on an OS timeout. Takes concrete *net.TCPConn values — the splice path needs the raw sockets.

How it works

On Linux, Bridge gets the raw file descriptors from each connection via SyscallConn(), creates one kernel pipe per direction with unix.Pipe, and runs the classic two-stage splice: splice(socket → pipe) then splice(pipe → socket), both with SPLICE_F_MOVE|SPLICE_F_NONBLOCK. The payload never enters user space.

The non-blocking part is what keeps it cooperative with Go's scheduler. When a socket isn't ready the kernel returns EAGAIN; the splice callback returns false, and RawConn.Read/Write park the goroutine on the netpoller until the fd is ready again — so thousands of idle connections cost almost no CPU, exactly as they would under io.Copy.

Off Linux, a //go:build !linux file provides the same Bridge signature backed by two io.Copy goroutines, so the package builds and behaves identically everywhere.

How it differs from io.Copy

Same syscalls, two deliberate differences: the standard library requests up to 1 MiB per splice and draws pipes from a pool, while this reference implementation splices in 32 KiB chunks and allocates a fresh pipe pair per connection. Under heavy connection churn, io.Copy therefore does strictly fewer syscalls. That's the point of the comparison — it's a teaching implementation, not a faster one.

When to use

Use it (or, in production, plain io.Copy) for pure byte relays — load balancers, forward proxies, tunnels, P2P sidecars — where the payload is untouched.

Don't expect the splice path if you need to inspect, log, or modify traffic, or if you're terminating TLS. A *tls.Conn isn't a *net.TCPConn, and splice deliberately keeps the bytes out of your process.

Requirements

  • Linux for the splice(2) path (uses golang.org/x/sys/unix). Other platforms fall back to io.Copy automatically.
  • Go 1.11+.

License

MIT

About

Pure Kernel-Space TCP Bridge for Go

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages