package main import ( "embed" "flag" "fmt" "log" "net/http" "time" "inet.af/tcpproxy" ) //go:embed pub webfonts templates/*.html var content embed.FS var dataFlag = flag.String("data", "./infinite.db", "Path to database.") var hostFlag = flag.String("host", "0.0.0.0", "Host to listen on.") var portFlag = flag.Int("port", 7878, "Port to listen on.") var runTest = flag.Bool("test", false, "Run data test") var listenString string func init() { flag.Parse() listenString = fmt.Sprintf("%s:%d", *hostFlag, *portFlag) } func main() { //currentTime := time.Now() noodleChannel := make(chan Noodle) db := NewDatabase(*dataFlag) defer db.Close() if *runTest { runTestSequence(db) } go systemCheck(db, noodleChannel) go tcpProxify(noodleChannel) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content)))) // TODO: CRYPTO hrefs http.HandleFunc("/", handleMain(db, &noodleChannel)) http.HandleFunc("/delete", handleDelete(db, &noodleChannel)) log.Printf("Server starting on %s", listenString) log.Fatal(http.ListenAndServe(listenString, nil)) } func systemCheck(db *Database, noodleChannel chan Noodle) { for { noodles := db.GetAll() for _, noodle := range noodles { noodleChannel <- noodle } time.Sleep(60 * time.Second) } } func startProxy(proxy *tcpproxy.Proxy) { log.Print(proxy.Run()) } func tcpProxify(noodleChannel chan Noodle) { noodleMap := make(map[string]*tcpproxy.Proxy) for { noodle := <-noodleChannel _, running := noodleMap[noodle.Id] if noodle.IsUp && !running { var p tcpproxy.Proxy src := fmt.Sprintf("0.0.0.0:%d", noodle.ListenPort) dst := fmt.Sprintf("%s:%d", noodle.DestHost, noodle.DestPort) log.Printf("Starting a noodle from %s to %s", src, dst) p.AddRoute(src, tcpproxy.To(dst)) //p.Start() noodleMap[noodle.Id] = &p go startProxy(&p) continue } if !noodle.IsUp && running { log.Printf("Closing noodle=%v", noodle) err := noodleMap[noodle.Id].Close() if err != nil { log.Print(err) } } //p.AddHTTPHostRoute(":80", "foo.com", tcpproxy.To("10.0.0.1:8081")) //p.AddHTTPHostRoute(":80", "bar.com", tcpproxy.To("10.0.0.2:8082")) //p.AddRoute(":80", tcpproxy.To("10.0.0.1:8081")) // fallback //p.AddSNIRoute(":443", "foo.com", tcpproxy.To("10.0.0.1:4431")) //p.AddSNIRoute(":443", "bar.com", tcpproxy.To("10.0.0.2:4432")) //p.AddRoute(":443", tcpproxy.To("10.0.0.1:4431")) // fallback //log.Fatal(p.Run()) } } func runTestSequence(db *Database) { for i := 0; i < 21; i++ { noodle := Noodle{db.MakeID(), "Name_Test", "Proto_Test", 1080+i, 22, "localhost", time.Now().Second(), true} log.Printf("Test noodle=%v", noodle) db.Add(noodle) log.Printf("Test id=%s exists=%s", noodle.Id, db.Handle.Has(noodle.Id)) log.Printf("Test GetAllGeneric=%v", db.GetAllGeneric()) //db.Delete(noodle.Id) } }