aboutsummaryrefslogtreecommitdiffstats
path: root/ghost.go
diff options
context:
space:
mode:
Diffstat (limited to 'ghost.go')
-rw-r--r--ghost.go104
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
+ }
+ }
+}