diff options
Diffstat (limited to 'ghost.go')
-rw-r--r-- | ghost.go | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/ghost.go b/ghost.go new file mode 100644 index 0000000..d3f4396 --- /dev/null +++ b/ghost.go @@ -0,0 +1,104 @@ +package main + +import ( + "bufio" + "crypto/tls" + "io" + "log" + "net" + "sync" + + ircgomsg "github.com/ergochat/irc-go/ircmsg" +) + +func ghost(serverAddress, listenAddress string) { + listener, err := net.Listen("tcp", listenAddress) + if err != nil { + log.Fatalf("Failed to listen on %s: %v", listenAddress, err) + } + defer listener.Close() + + log.Printf("IRC Bouncer listening on %s", listenAddress) + log.Printf("Connecting clients to IRC server: %s", serverAddress) + + for { + clientConn, err := listener.Accept() + if err != nil { + log.Printf("Failed to accept client connection: %v", err) + + continue + } + + go handleClientConnection(clientConn, serverAddress) + } +} + +func handleClientConnection(clientConn net.Conn, serverAddress string) { + log.Printf("Client connected from: %s", clientConn.RemoteAddr()) + + // ircServerConn, err := net.Dial("tcp", serverAddress) + ircServerConn, err := tls.Dial("tcp", serverAddress, nil) + if err != nil { + log.Printf("Failed to connect to IRC server %s: %v", serverAddress, err) + clientConn.Close() + + return + } + + log.Printf("Successfully connected to IRC server: %s", serverAddress) + + done := make(chan struct{}) + + var once sync.Once + + closeConnections := func() { + once.Do(func() { + clientConn.Close() + ircServerConn.Close() + close(done) + }) + } + + go relay(clientConn, ircServerConn, closeConnections) + + go relay(ircServerConn, clientConn, closeConnections) + + <-done + log.Printf("Connection closed for client: %s", clientConn.RemoteAddr()) +} + +func relay(src, dest net.Conn, closer func()) { + reader := bufio.NewReader(src) + + for { + line, err := reader.ReadString('\n') + if err != nil { + if err != io.EOF { + log.Printf("Relay read error on: %v", err) + } + closer() + + return + } + + msg, err := ircgomsg.ParseLine(line) + if err != nil { + log.Printf("Failed to parse IRC message: %v", err) + } + + if msg.Command == "PRIVMSG" { + } + + if msg.Command == "MSG" { + } + + log.Println(msg) + + _, err = io.WriteString(dest, line) + if err != nil { + closer() + + return + } + } +} |