diff options
Diffstat (limited to 'deprecated-webircgateway/pkg/webircgateway/transport_tcp.go')
| -rw-r--r-- | deprecated-webircgateway/pkg/webircgateway/transport_tcp.go | 113 |
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() +} |
