summaryrefslogtreecommitdiff
path: root/deprecated-webircgateway/pkg/webircgateway/transport_tcp.go
diff options
context:
space:
mode:
Diffstat (limited to 'deprecated-webircgateway/pkg/webircgateway/transport_tcp.go')
-rw-r--r--deprecated-webircgateway/pkg/webircgateway/transport_tcp.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/deprecated-webircgateway/pkg/webircgateway/transport_tcp.go b/deprecated-webircgateway/pkg/webircgateway/transport_tcp.go
new file mode 100644
index 0000000..b4af7b3
--- /dev/null
+++ b/deprecated-webircgateway/pkg/webircgateway/transport_tcp.go
@@ -0,0 +1,113 @@
+package webircgateway
+
+import (
+ "bufio"
+ "net"
+ "strings"
+ "sync"
+)
+
+type TransportTcp struct {
+ gateway *Gateway
+}
+
+func (t *TransportTcp) Init(g *Gateway) {
+ t.gateway = g
+}
+
+func (t *TransportTcp) Start(lAddr string) {
+ l, err := net.Listen("tcp", lAddr)
+ if err != nil {
+ t.gateway.Log(3, "TCP error listening: "+err.Error())
+ return
+ }
+ // Close the listener when the application closes.
+ defer l.Close()
+ t.gateway.Log(2, "TCP listening on "+lAddr)
+ for {
+ // Listen for an incoming connection.
+ conn, err := l.Accept()
+ if err != nil {
+ t.gateway.Log(3, "TCP error accepting: "+err.Error())
+ break
+ }
+ // Handle connections in a new goroutine.
+ go t.handleConn(conn)
+ }
+}
+
+func (t *TransportTcp) handleConn(conn net.Conn) {
+ client := t.gateway.NewClient()
+
+ client.RemoteAddr = conn.RemoteAddr().String()
+
+ clientHostnames, err := net.LookupAddr(client.RemoteAddr)
+ if err != nil {
+ client.RemoteHostname = client.RemoteAddr
+ } else {
+ // FQDNs include a . at the end. Strip it out
+ potentialHostname := strings.Trim(clientHostnames[0], ".")
+
+ // Must check that the resolved hostname also resolves back to the users IP
+ addr, err := net.LookupIP(potentialHostname)
+ if err == nil && len(addr) == 1 && addr[0].String() == client.RemoteAddr {
+ client.RemoteHostname = potentialHostname
+ } else {
+ client.RemoteHostname = client.RemoteAddr
+ }
+ }
+
+ _, remoteAddrPort, _ := net.SplitHostPort(conn.RemoteAddr().String())
+ client.Tags["remote-port"] = remoteAddrPort
+
+ client.Log(2, "New tcp client on %s from %s %s", conn.LocalAddr().String(), client.RemoteAddr, client.RemoteHostname)
+ client.Ready()
+
+ // We wait until the client send queue has been drained
+ var sendDrained sync.WaitGroup
+ sendDrained.Add(1)
+
+ // Read from TCP
+ go func() {
+ reader := bufio.NewReader(conn)
+ for {
+ data, err := reader.ReadString('\n')
+ if err == nil {
+ message := strings.TrimRight(data, "\r\n")
+ client.Log(1, "client->: %s", message)
+ select {
+ case client.Recv <- message:
+ default:
+ client.Log(3, "Recv queue full. Dropping data")
+ // TODO: Should this really just drop the data or close the connection?
+ }
+
+ } else {
+ client.Log(1, "TCP connection closed (%s)", err.Error())
+ break
+
+ }
+ }
+
+ close(client.Recv)
+ }()
+
+ // Process signals for the client
+ for {
+ signal, ok := <-client.Signals
+ if !ok {
+ sendDrained.Done()
+ break
+ }
+
+ if signal[0] == "data" {
+ //line := strings.Trim(signal[1], "\r\n")
+ line := signal[1] + "\n"
+ client.Log(1, "->tcp: %s", signal[1])
+ conn.Write([]byte(line))
+ }
+ }
+
+ sendDrained.Wait()
+ conn.Close()
+}