about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlan Pearce2024-07-02 11:00:36 +0200
committerAlan Pearce2024-07-02 11:00:36 +0200
commitaf48d9a1bc24d14e113571a80c19dfaaf203c87c (patch)
tree2f024ebf8bf58c2747fe56c2494ec39f7019dca3
parenta70ddb349b0230201b58d748aec189db2f1a5608 (diff)
downloadx-af48d9a1bc24d14e113571a80c19dfaaf203c87c.tar.lz
x-af48d9a1bc24d14e113571a80c19dfaaf203c87c.tar.zst
x-af48d9a1bc24d14e113571a80c19dfaaf203c87c.zip
listenfd: init
-rw-r--r--go.mod1
-rw-r--r--go.sum4
-rw-r--r--listenfd/listenfd.go71
3 files changed, 76 insertions, 0 deletions
diff --git a/go.mod b/go.mod
index 14bff83..354f083 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.22.3
 require (
 	github.com/sykesm/zap-logfmt v0.0.4
 	github.com/thessem/zap-prettyconsole v0.5.0
+	gitlab.com/tozd/go/errors v0.8.1
 	go.uber.org/zap v1.27.0
 	moul.io/zapfilter v1.7.0
 )
diff --git a/go.sum b/go.sum
index be58455..1c809f5 100644
--- a/go.sum
+++ b/go.sum
@@ -5,7 +5,9 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -32,6 +34,8 @@ github.com/thessem/zap-prettyconsole v0.5.0 h1:AOu1GGUuDkGmj4tgRPSVf0vYGzDM+6cPW
 github.com/thessem/zap-prettyconsole v0.5.0/go.mod h1:3qfsE7y+bLOq7EQ+fMZHD3HYEp24ULFf5nhLSx6rjrE=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+gitlab.com/tozd/go/errors v0.8.1 h1:RfylffRAsl3PbDdHNUBEkTleTCiL/RIT+Ef8p0HRNCI=
+gitlab.com/tozd/go/errors v0.8.1/go.mod h1:PvIdUMLpPwxr+KEBxghQaCMydHXGYdJQn/PhdMqYREY=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
diff --git a/listenfd/listenfd.go b/listenfd/listenfd.go
new file mode 100644
index 0000000..cbf3163
--- /dev/null
+++ b/listenfd/listenfd.go
@@ -0,0 +1,71 @@
+package listenfd
+
+import (
+	"crypto/tls"
+	"net"
+	"os"
+	"strconv"
+
+	"go.alanpearce.eu/x/log"
+
+	"gitlab.com/tozd/go/errors"
+)
+
+const fdStart = 3
+
+func GetListener(i uint64, addr string, log *log.Logger) (l net.Listener, err error) {
+	l, err = getFDSocket(i)
+	if err != nil {
+		log.Warn("could not create listener from listenfd", "error", err)
+	}
+
+	log.Debug("listener from listenfd?", "passed", l != nil)
+	if l == nil {
+		l, err = net.Listen("tcp", addr)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not create listener")
+		}
+	}
+
+	return
+}
+
+func GetListenerTLS(
+	i uint64,
+	addr string,
+	config *tls.Config,
+	log *log.Logger,
+) (l net.Listener, err error) {
+	l, err = GetListener(i, addr, log)
+	if err != nil {
+		return nil, err
+	}
+
+	return tls.NewListener(l, config), nil
+}
+
+func getFDSocket(i uint64) (net.Listener, error) {
+	lfds, present := os.LookupEnv("LISTEN_FDS")
+	if !present {
+		return nil, nil
+	}
+	err := os.Unsetenv("LISTEN_FDS")
+	if err != nil {
+		return nil, errors.Wrap(err, "could not unset LISTEN_FDS")
+	}
+
+	fds, err := strconv.ParseUint(lfds, 10, 32)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not parse LISTEN_FDS")
+	}
+	if i >= fds {
+		return nil, errors.Errorf("only %d fds available, requested index %d", fds, i)
+	}
+
+	l, err := net.FileListener(os.NewFile(uintptr(i+fdStart), ""))
+	if err != nil {
+		return nil, errors.Wrap(err, "could not create listener")
+	}
+
+	return l, nil
+}