// vim:ts=4:sts=4:sw=4:noet:tw=72 package main import ( "flag" "fmt" "log" "net" "strings" "time" "code.dnix.de/an/irc" "code.dnix.de/an/xlog" ) var saddr = flag.String("server", "irc.example.com:6667", "Server address") var laddr = flag.String("listen", "0.0.0.0:6667", "Listen address") func init() { flag.Parse() } func main() { listen, err := net.Listen("tcp", *laddr) if err != nil { xlog.Fatal(err.Error()) return } for { cconn, err := listen.Accept() if err != nil { log.Println(err) continue } go bounce(cconn, saddr) } } func bounce(cconn net.Conn, saddr *string) { done := make(chan bool, 5) client := NewIRCConn(cconn, done) defer func() { client.Close() }() sconn, err := net.Dial("tcp", *saddr) if err != nil { log.Println(err) return } server := NewIRCConn(sconn, done) defer func() { server.Close() }() if !login(server, client) { return } go relay(server, client) go relay(client, server) <-done } func login(server, client *IRCConn) bool { nick := "" user := "" pass := "" for { s := client.Read() msg := irc.Parse(s) msg.Cmd = strings.ToUpper(msg.Cmd) switch msg.Cmd { case "PASS": pass = msg.Args[0] case "USER": user = msg.Args[0] case "NICK": nick = msg.Args[0] } if nick != "" && user != "" { if authenticate(nick, pass) { server.Write(fmt.Sprintf("NICK %s", nick)) server.Write(fmt.Sprintf("USER %s %s %s :%s", user, user, user, user)) return true } else { return false } } } } func authenticate(name, password string) bool { return true } func relay(conn1 *IRCConn, conn2 *IRCConn) { for { if conn1.closed || conn2.closed { return } s := conn1.Read() if s != "" { conn2.Write(s) } time.Sleep(1 * time.Millisecond) } }