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
112
113
114
115
116
117
118
|
package wscat
import (
"fmt"
"net"
"net/http"
"os"
g "euandre.org/gobang/src"
"github.com/gorilla/websocket"
)
type CLIArgs struct {
FromAddr string
ToAddr string
}
const X = 1
var EmitActiveConnection = g.MakeGauge("active-connections")
func ParseArgs(args []string) CLIArgs {
if len(args) != 3 {
fmt.Fprintf(
os.Stderr,
"Usage: %s FROM.socket TO.socket\n",
args[0],
)
os.Exit(2)
}
return CLIArgs {
FromAddr: args[1],
ToAddr: args[2],
}
}
func Listen(fromAddr string) net.Listener {
listener, err := net.Listen("unix", fromAddr)
g.FatalIf(err)
g.Info("Started listening", "listen-start", "from-address", fromAddr)
return listener
}
func Start(toAddr string, listener net.Listener) {
upgrader := websocket.Upgrader {}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
connFrom, err := upgrader.Upgrade(w, r, nil)
if err != nil {
g.Warning(
"Error upgrading connection",
"upgrade-connection-error",
"err", err,
)
return
}
defer connFrom.Close()
EmitActiveConnection.Inc()
connTo, err := net.Dial("unix", toAddr)
if err != nil {
g.Error(
"Error dialing connection",
"dial-connection",
"err", err,
)
os.Exit(1)
}
defer connTo.Close()
messageType, reader, err := connFrom.NextReader()
if err != nil {
g.Warning(
"Failed to get next reader from connection",
"connection-next-reader-error",
"err", err,
)
return
}
writer, err := connFrom.NextWriter(messageType)
if err != nil {
g.Warning(
"Failed to get next reader from connection",
"connection-next-reader-error",
"err", err,
)
return
}
c := make(chan g.CopyResult)
go g.CopyData(c, "c2s", connTo, writer)
go g.CopyData(c, "s2c", reader, connTo)
go func() {
<- c
EmitActiveConnection.Dec()
}()
});
server := http.Server{}
err := server.Serve(listener)
g.FatalIf(err)
}
func Main() {
g.Init()
args := ParseArgs(os.Args)
listener := Listen(args.FromAddr)
Start(args.ToAddr, listener)
}
|