mirror of
https://github.com/soypat/lneto.git
synced 2026-08-05 15:33:41 +00:00
a2970b923d
* add ipv6 to xnet.StackAsync * dns improvements * improve DNS workings of StackAsync * add tentative ICMPv6 * work on prefixes and fix some small bugs, plan UDP/TCP6 * fix bugs in StackAsync and ipv4.Prefix.Contains * update arpsubtable * completely remove legacy internet.StackIP for StackIPv4/v6 * ipv4/ipv6 tcp/udp * add TCP6/UDP6 dialing APIs * add xnet.Stack6 interface * more ipv6 integration into StackAsync; various tweaks to lneto and documentation+TODOs * add stack6 tests * replace netip.Prefix with ipv4.Prefix where it makes sense
190 lines
4.5 KiB
Go
190 lines
4.5 KiB
Go
//go:build !tinygo && linux
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type program struct {
|
|
Name string
|
|
Link string // relative path for README link
|
|
Dir string // directory to build from, relative to repo root
|
|
ExtraProtocols string
|
|
PacketCapture bool
|
|
}
|
|
|
|
type buildTarget struct {
|
|
Name string
|
|
ext string // output file extension (determines format for tinygo)
|
|
build func(dir, outFile string) error
|
|
}
|
|
|
|
type result struct {
|
|
BinarySize int64
|
|
CompileTime time.Duration
|
|
DNC bool // Does Not Compile
|
|
Err error
|
|
}
|
|
|
|
func (r result) sizeString() string {
|
|
if r.DNC {
|
|
return "DNC"
|
|
}
|
|
if r.Err != nil {
|
|
return "ERR"
|
|
}
|
|
return formatSize(r.BinarySize)
|
|
}
|
|
|
|
func formatSize(n int64) string {
|
|
const mb = 1024 * 1024
|
|
if n >= mb {
|
|
return fmt.Sprintf("%.1fMB", float64(n)/mb)
|
|
}
|
|
return fmt.Sprintf("%dkB", (n+512)/1024)
|
|
}
|
|
|
|
func goBuild(goos, goarch string) func(dir, out string) error {
|
|
return func(dir, out string) error {
|
|
cmd := exec.Command("go", "build", "-o", out, ".")
|
|
cmd.Dir = dir
|
|
cmd.Env = append(os.Environ(), "GOOS="+goos, "GOARCH="+goarch)
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("%w: %s", err, out)
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func tinygoBuild(target string) func(dir, out string) error {
|
|
return func(dir, out string) error {
|
|
args := []string{"build"}
|
|
if target != "" {
|
|
args = append(args, "-target="+target)
|
|
}
|
|
args = append(args, "-o", out, ".")
|
|
cmd := exec.Command("tinygo", args...)
|
|
cmd.Dir = dir
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("%w: %s", err, out)
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
var buildTargets = []buildTarget{
|
|
{Name: "amd64 Go", ext: ".elf", build: goBuild("linux", "amd64")},
|
|
{Name: "WASM Go", ext: ".wasm", build: goBuild("wasip1", "wasm")},
|
|
{Name: "amd64 TinyGo", ext: ".elf", build: tinygoBuild("")},
|
|
{Name: "WASM TinyGo", ext: ".wasm", build: tinygoBuild("wasm")},
|
|
{Name: "Pico TinyGo", ext: ".bin", build: tinygoBuild("pico")},
|
|
}
|
|
|
|
var programs = []program{
|
|
{
|
|
Name: "Lneto MWE",
|
|
Link: "./examples/min-working-example/",
|
|
Dir: "examples/min-working-example",
|
|
ExtraProtocols: "DNS,NTP,DHCP",
|
|
PacketCapture: true,
|
|
},
|
|
{
|
|
Name: "Gvisor MWE w/ go-net",
|
|
Link: "./examples/_import_examples/gvisor-mwe/",
|
|
Dir: "examples/_import_examples/gvisor-mwe",
|
|
ExtraProtocols: "None",
|
|
PacketCapture: false,
|
|
},
|
|
}
|
|
|
|
func measure(dir, outFile string, fn func(dir, out string) error) result {
|
|
start := time.Now()
|
|
err := fn(dir, outFile)
|
|
elapsed := time.Since(start)
|
|
if err != nil {
|
|
return result{DNC: true, CompileTime: elapsed, Err: err}
|
|
}
|
|
fi, err := os.Stat(outFile)
|
|
if err != nil {
|
|
return result{Err: err, CompileTime: elapsed}
|
|
}
|
|
size := fi.Size()
|
|
os.Remove(outFile)
|
|
return result{BinarySize: size, CompileTime: elapsed}
|
|
}
|
|
|
|
func main() {
|
|
root := flag.String("root", ".", "path to repository root")
|
|
flag.Parse()
|
|
|
|
repoRoot, err := filepath.Abs(*root)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
tmpDir, err := os.MkdirTemp("", "binbench-*")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
type row struct {
|
|
prog program
|
|
results []result
|
|
}
|
|
rows := make([]row, len(programs))
|
|
for i, prog := range programs {
|
|
dir := filepath.Join(repoRoot, prog.Dir)
|
|
results := make([]result, len(buildTargets))
|
|
for j, bt := range buildTargets {
|
|
outFile := filepath.Join(tmpDir, fmt.Sprintf("p%d_t%d%s", i, j, bt.ext))
|
|
fmt.Fprintf(os.Stderr, "building %s for %s...\n", prog.Name, bt.Name)
|
|
r := measure(dir, outFile, bt.build)
|
|
if r.DNC {
|
|
fmt.Fprintf(os.Stderr, " DNC: %v\n", r.Err)
|
|
}
|
|
results[j] = r
|
|
}
|
|
rows[i] = row{prog: prog, results: results}
|
|
}
|
|
|
|
// Print markdown table.
|
|
headers := []string{"Program", "Extra Protocols", "Packet capture printing"}
|
|
for _, bt := range buildTargets {
|
|
headers = append(headers, bt.Name)
|
|
}
|
|
fmt.Printf("| %s |\n", strings.Join(headers, " | "))
|
|
|
|
aligns := make([]string, len(headers))
|
|
aligns[0] = "---"
|
|
aligns[1] = ":---:"
|
|
aligns[2] = ":---:"
|
|
for i := 3; i < len(aligns); i++ {
|
|
aligns[i] = "---"
|
|
}
|
|
fmt.Printf("|%s|\n", strings.Join(aligns, "|"))
|
|
|
|
for _, r := range rows {
|
|
pcap := "❌"
|
|
if r.prog.PacketCapture {
|
|
pcap = "✅"
|
|
}
|
|
cols := []string{
|
|
fmt.Sprintf("[%s](%s)", r.prog.Name, r.prog.Link),
|
|
r.prog.ExtraProtocols,
|
|
pcap,
|
|
}
|
|
for _, res := range r.results {
|
|
cols = append(cols, res.sizeString())
|
|
}
|
|
fmt.Printf("| %s |\n", strings.Join(cols, " | "))
|
|
}
|
|
}
|