aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Pervaz Boocha <mboocha@sudomsg.com>2026-02-24 23:43:18 +0530
committerMarc Pervaz Boocha <mboocha@sudomsg.com>2026-02-24 23:43:18 +0530
commit37809b8c855250b931ec592f12fd548ddfa1dabe (patch)
treee9fbb747cc8a29fc031dba3de77919c94edebc4a
parentAdded more logging stuff (diff)
downloadkit-37809b8c855250b931ec592f12fd548ddfa1dabe.tar
kit-37809b8c855250b931ec592f12fd548ddfa1dabe.tar.gz
kit-37809b8c855250b931ec592f12fd548ddfa1dabe.tar.bz2
kit-37809b8c855250b931ec592f12fd548ddfa1dabe.tar.lz
kit-37809b8c855250b931ec592f12fd548ddfa1dabe.tar.xz
kit-37809b8c855250b931ec592f12fd548ddfa1dabe.tar.zst
kit-37809b8c855250b931ec592f12fd548ddfa1dabe.zip
Split net packages
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--http/http.go3
-rw-r--r--http/http_test.go18
-rw-r--r--http/systemd_linux.go16
-rw-r--r--net/server.go (renamed from http/server.go)6
-rw-r--r--net/server_test.go (renamed from http/server_test.go)48
-rw-r--r--net/systemd_linux.go58
-rw-r--r--net/systemd_stub.go (renamed from http/systemd_stub.go)2
9 files changed, 107 insertions, 51 deletions
diff --git a/go.mod b/go.mod
index b775451..0cc7e2a 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,4 @@ module go.sudomsg.com/kit
go 1.26.0
-require (
- github.com/coreos/go-systemd/v22 v22.7.0
- golang.org/x/sync v0.19.0
-)
+require golang.org/x/sync v0.19.0
diff --git a/go.sum b/go.sum
index 30ce3a9..159532a 100644
--- a/go.sum
+++ b/go.sum
@@ -1,4 +1,2 @@
-github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
-github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
diff --git a/http/http.go b/http/http.go
index 71075a7..42d8f4f 100644
--- a/http/http.go
+++ b/http/http.go
@@ -10,6 +10,7 @@ import (
"time"
"go.sudomsg.com/kit/logging"
+ netkit "go.sudomsg.com/kit/net"
"golang.org/x/sync/errgroup"
)
@@ -22,7 +23,7 @@ import (
// Each server logs startup, shutdown, and errors.
//
// This function blocks until all servers have stopped or an error occurs.
-func RunHTTPServers(ctx context.Context, lns Listeners, handler http.Handler) error {
+func RunHTTPServers(ctx context.Context, lns netkit.Listeners, handler http.Handler) error {
g, ctx := errgroup.WithContext(ctx)
for _, ln := range lns {
diff --git a/http/http_test.go b/http/http_test.go
index d7eb3c4..dce9092 100644
--- a/http/http_test.go
+++ b/http/http_test.go
@@ -2,14 +2,28 @@ package http_test
import (
"context"
- httpServer "go.sudomsg.com/kit/http"
"io"
+ "net"
"net/http"
"strings"
"testing"
"time"
+
+ httpServer "go.sudomsg.com/kit/http"
+ netkit "go.sudomsg.com/kit/net"
)
+func newListener(tb testing.TB) net.Listener {
+ tb.Helper()
+
+ ln, err := net.Listen("tcp", "localhost:0")
+ if err != nil {
+ tb.Fatalf("failed to open listener: %v", err)
+ }
+ return ln
+}
+
+
func TestRunHTTPServers(t *testing.T) {
t.Parallel()
t.Run("basic serve and shutdown", func(t *testing.T) {
@@ -45,7 +59,7 @@ func TestRunHTTPServers(t *testing.T) {
cancel() // shutdown the server
}()
- err := httpServer.RunHTTPServers(ctx, httpServer.Listeners{ln}, handler)
+ err := httpServer.RunHTTPServers(ctx, netkit.Listeners{ln}, handler)
if err != nil {
t.Fatalf("RunHTTPServers failed: %v", err)
}
diff --git a/http/systemd_linux.go b/http/systemd_linux.go
deleted file mode 100644
index bf1e6a1..0000000
--- a/http/systemd_linux.go
+++ /dev/null
@@ -1,16 +0,0 @@
-//go:build linux
-
-package http
-
-import (
- "github.com/coreos/go-systemd/v22/activation"
-)
-
-func getSystemdListeners() (Listeners, error) {
- lns, err := activation.Listeners()
- if err != nil {
- return nil, err
- }
-
- return lns, nil
-}
diff --git a/http/server.go b/net/server.go
index b74e39b..22448b3 100644
--- a/http/server.go
+++ b/net/server.go
@@ -6,7 +6,7 @@
//
// This package is designed to be used with context cancellation for concurrency control.
-package http
+package net
import (
"context"
@@ -47,7 +47,11 @@ const (
NetTCP NetType = iota
NetTCP4
NetTCP6
+ NetUDP
+ NetUDP4
+ NetUDP6
NetUnix
+ NetUnixDatagram
NetUnixPacket
)
diff --git a/http/server_test.go b/net/server_test.go
index 0f49f01..ca4836c 100644
--- a/http/server_test.go
+++ b/net/server_test.go
@@ -1,11 +1,11 @@
-package http_test
+package net_test
import (
"net"
"strings"
"testing"
- "go.sudomsg.com/kit/http"
+ netkit "go.sudomsg.com/kit/net"
)
// helper to find free TCP ports
@@ -25,12 +25,12 @@ func TestOpenConfigListeners(t *testing.T) {
t.Parallel()
ctx := t.Context()
- cfg := []http.ServerConfig{
- {Network: http.NetTCP, Address: "localhost:0"},
- {Network: http.NetTCP, Address: "localhost:0"},
+ cfg := []netkit.ServerConfig{
+ {Network: netkit.NetTCP, Address: "localhost:0"},
+ {Network: netkit.NetTCP, Address: "localhost:0"},
}
- lns, err := http.OpenConfigListners(ctx, cfg)
+ lns, err := netkit.OpenConfigListners(ctx, cfg)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@@ -48,12 +48,12 @@ func TestOpenConfigListeners(t *testing.T) {
conflict := newListener(t)
defer conflict.Close()
- cfg := []http.ServerConfig{
- {Network: http.NetTCP, Address: "localhost:0"},
- {Network: http.NetTCP, Address: conflict.Addr().String()}, // will fail
+ cfg := []netkit.ServerConfig{
+ {Network: netkit.NetTCP, Address: "localhost:0"},
+ {Network: netkit.NetTCP, Address: conflict.Addr().String()}, // will fail
}
- lns, err := http.OpenConfigListners(ctx, cfg)
+ lns, err := netkit.OpenConfigListners(ctx, cfg)
if err == nil {
defer lns.CloseAll()
t.Fatal("expected error due to conflict, got nil")
@@ -67,7 +67,7 @@ func TestCloseAll(t *testing.T) {
ln1 := newListener(t)
ln2 := newListener(t)
- ls := http.Listeners{ln1, ln2}
+ ls := netkit.Listeners{ln1, ln2}
err := ls.CloseAll()
if err != nil {
t.Errorf("unexpected error from CloseAll: %v", err)
@@ -86,15 +86,15 @@ func TestInvalidConfig(t *testing.T) {
tests := []struct {
name string
- config http.ServerConfig
+ config netkit.ServerConfig
}{
{
name: "invalid network",
- config: http.ServerConfig{Network: -1, Address: "localhost:0"},
+ config: netkit.ServerConfig{Network: -1, Address: "localhost:0"},
},
{
name: "invalid address",
- config: http.ServerConfig{Network: http.NetTCP, Address: "::::"},
+ config: netkit.ServerConfig{Network: netkit.NetTCP, Address: "::::"},
},
}
@@ -104,7 +104,7 @@ func TestInvalidConfig(t *testing.T) {
ctx := t.Context()
- _, err := http.OpenConfigListners(ctx, []http.ServerConfig{tt.config})
+ _, err := netkit.OpenConfigListners(ctx, []netkit.ServerConfig{tt.config})
if err == nil {
t.Fatal("OpenConfigListners() expected error, got nil")
}
@@ -118,12 +118,12 @@ func TestNetType(t *testing.T) {
t.Run("RoundTrip", func(t *testing.T) {
t.Parallel()
- testCases := []http.NetType{
- http.NetTCP,
- http.NetTCP4,
- http.NetTCP6,
- http.NetUnix,
- http.NetUnixPacket,
+ testCases := []netkit.NetType{
+ netkit.NetTCP,
+ netkit.NetTCP4,
+ netkit.NetTCP6,
+ netkit.NetUnix,
+ netkit.NetUnixPacket,
}
for _, original := range testCases {
@@ -135,7 +135,7 @@ func TestNetType(t *testing.T) {
t.Fatalf("MarshalText failed: %v", err)
}
- var decoded http.NetType
+ var decoded netkit.NetType
if err := decoded.UnmarshalText(text); err != nil {
t.Fatalf("UnmarshalText failed: %v", err)
}
@@ -152,7 +152,7 @@ func TestNetType(t *testing.T) {
t.Fatalf("MarshalText failed: %v", err)
}
- var decoded http.NetType
+ var decoded netkit.NetType
if err := decoded.UnmarshalText([]byte(strings.ToUpper(string(text)))); err != nil {
t.Fatalf("UnmarshalText failed: %v", err)
}
@@ -171,7 +171,7 @@ func TestNetType(t *testing.T) {
t.Parallel()
input := "invalid"
- var decoded http.NetType
+ var decoded netkit.NetType
if err := decoded.UnmarshalText([]byte(input)); err == nil {
t.Errorf("expected error for input %q, got none", input)
diff --git a/net/systemd_linux.go b/net/systemd_linux.go
new file mode 100644
index 0000000..efccd27
--- /dev/null
+++ b/net/systemd_linux.go
@@ -0,0 +1,58 @@
+//go:build linux
+
+package net
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "strconv"
+)
+
+func getSystemdListeners() (Listeners, error) {
+ pidStr := os.Getenv("LISTEN_PID")
+ fdStr := os.Getenv("LISTEN_FDS")
+
+ if pidStr == "" || fdStr == "" {
+ return nil, nil // Not running under systemd
+ }
+
+ pid, err := strconv.Atoi(pidStr)
+ if err != nil {
+ // Not our activation — another process might have inherited the env.
+ return nil, nil
+ }
+ if pid != os.Getpid() {
+ return nil, fmt.Errorf("LISTEN_PID %d does not match current PID %d", pid, os.Getpid())
+ }
+
+ defer func() {
+ _ = os.Unsetenv("LISTEN_PID")
+ _ = os.Unsetenv("LISTEN_FDS")
+ }()
+
+ nfds, err := strconv.ParseUint(fdStr, 10, 64)
+ if err != nil {
+ return nil, fmt.Errorf("invalid LISTEN_FDS: %w", err)
+ }
+ if nfds == 0 {
+ return nil, nil // Nothing to do
+ }
+
+ lns := make(Listeners, 0, nfds)
+ for i := range nfds {
+ fd := i + 3
+ file := os.NewFile(uintptr(fd), fmt.Sprintf("fd_%d", fd))
+ if file == nil {
+ return nil, fmt.Errorf("fd %d was nil", fd)
+ }
+ ln, err := net.FileListener(file)
+ if err != nil {
+ file.Close()
+ return nil, fmt.Errorf("failed to create listener from fd %d: %w", fd, err)
+ }
+ lns = append(lns, ln)
+ }
+
+ return lns, nil
+}
diff --git a/http/systemd_stub.go b/net/systemd_stub.go
index 00699f3..502cf4b 100644
--- a/http/systemd_stub.go
+++ b/net/systemd_stub.go
@@ -1,6 +1,6 @@
//go:build !linux
-package http
+package net
func getSystemdListeners() (Listeners, error) {
return nil, nil // No-op on non-Linux