aboutsummaryrefslogtreecommitdiff
path: root/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'bridge')
-rw-r--r--bridge/main.go110
1 files changed, 108 insertions, 2 deletions
diff --git a/bridge/main.go b/bridge/main.go
index 8a55772..1c70fdc 100644
--- a/bridge/main.go
+++ b/bridge/main.go
@@ -1,5 +1,111 @@
package main
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "log/slog"
+ "net"
+ "os"
+ "strconv"
+)
+
func main() {
- println("hello!!!! this is the container bridge")
-} \ No newline at end of file
+ slog.Info("starting container bridge...")
+
+ info := getInfo()
+ slog.Info("got configuration from environment variables.", slog.Any("info", info))
+
+ source, err := net.Listen("tcp", fmt.Sprintf(":%d", info.Port))
+ dieIfErr(err, "failed to listen on port.")
+
+ slog.Info("listening...", slog.Uint64("port", uint64(info.Port)))
+ for {
+ conn, err := source.Accept()
+ if err != nil {
+ slog.Error("could not accept conenction.", slog.Any("error", err))
+ continue
+ }
+ slog.Info("accepted connection.", slog.String("remoteAddr", conn.RemoteAddr().String()))
+
+ go bridge(conn, info.SocketPath)
+ }
+}
+
+func bridge(source net.Conn, socketPath string) {
+ data := bytes.NewBuffer([]byte{})
+ for {
+ buffer := make([]byte, 1024)
+ n, err := source.Read(buffer)
+ if err != nil {
+ if err == io.EOF {
+ slog.Info("got EOF...", slog.String("remoteAddr", source.RemoteAddr().String()))
+ break
+ }
+ slog.Error("could not read from connection.", slog.Any("error", err))
+ break
+ }
+
+ n, err = data.Write(buffer[:n])
+ if err != nil {
+ slog.Error("could not write to buffer.", slog.Any("error", err))
+ break
+ }
+ }
+ source.Close()
+ slog.Info("connection completed. attempting write...", slog.String("remoteAddr", source.RemoteAddr().String()))
+
+ destination, err := net.Dial("unix", socketPath)
+ if err != nil {
+ slog.Error("could not connect to destination socket.", slog.Any("error", err))
+ return
+ }
+ defer destination.Close()
+
+ _, err = destination.Write(data.Bytes())
+ if err != nil {
+ slog.Error("could not write to destination socket.", slog.Any("error", err))
+ return
+ }
+
+ slog.Info("write to destination socket successful.", slog.String("remoteAddr", source.RemoteAddr().String()))
+}
+
+type Info struct {
+ Port uint64
+ SocketPath string
+}
+
+func getInfo() Info {
+ portStr := os.Getenv("PORT")
+ if portStr == "" {
+ die("`PORT` environment variable must be set.")
+ }
+
+ port, err := strconv.ParseUint(portStr, 10, 32)
+ dieIfErr(err, "could not parse `PORT` environment variable.")
+
+ path := os.Getenv("SOCKET_PATH")
+ if path == "" {
+ defaultPath := fmt.Sprintf("/run/cthcous/%d.socket", port)
+ slog.Warn("`SOCKET_PATH` environment variable not set.", "default", string(defaultPath))
+ }
+
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ die(fmt.Sprintf("socket path `%s` does not exist.", path))
+ }
+
+ return Info{Port: port, SocketPath: path}
+}
+
+func die(msg string) {
+ slog.Error(msg)
+ os.Exit(1)
+}
+
+func dieIfErr(err error, msg string) {
+ if err != nil {
+ slog.Error(msg, slog.Any("error", err))
+ os.Exit(1)
+ }
+}