1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
package main
import (
"bytes"
"fmt"
"io"
"log/slog"
"net"
"os"
"strconv"
)
func main() {
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)
}
}
|