package app import ( "fmt" "log" "net/http" "time" "infinite-noodle/internal/noodle" "infinite-noodle/internal/web" "inet.af/tcpproxy" ) type Config struct { DataPath string Host string Port int RunTest bool } func Run(cfg Config) error { listenAddr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) noodleChannel := make(chan noodle.Noodle) db := noodle.NewDatabase(cfg.DataPath) defer db.Close() if cfg.RunTest { runTestSequence(db) } go systemCheck(db, noodleChannel) go tcpProxify(noodleChannel) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(web.StaticFiles())))) http.HandleFunc("/", web.HandleMain(db, &noodleChannel)) http.HandleFunc("/delete", web.HandleDelete(db, &noodleChannel)) log.Printf("Server starting on %s", listenAddr) return http.ListenAndServe(listenAddr, nil) } func systemCheck(db *noodle.Database, noodleChannel chan noodle.Noodle) { for { noodles := db.GetAll() for _, item := range noodles { noodleChannel <- item } time.Sleep(60 * time.Second) } } func startProxy(proxy *tcpproxy.Proxy) { log.Print(proxy.Run()) } func tcpProxify(noodleChannel chan noodle.Noodle) { noodleMap := make(map[string]*tcpproxy.Proxy) for { item := <-noodleChannel _, running := noodleMap[item.Id] if item.IsUp && !running { var proxy tcpproxy.Proxy src := fmt.Sprintf("0.0.0.0:%d", item.ListenPort) dst := fmt.Sprintf("%s:%d", item.DestHost, item.DestPort) log.Printf("Starting a noodle from %s to %s", src, dst) proxy.AddRoute(src, tcpproxy.To(dst)) noodleMap[item.Id] = &proxy go startProxy(&proxy) continue } if !item.IsUp && running { log.Printf("Closing noodle=%v", item) if err := noodleMap[item.Id].Close(); err != nil { log.Print(err) } } } } func runTestSequence(db *noodle.Database) { for i := 0; i < 21; i++ { item := noodle.Noodle{ Id: db.MakeID(), Name: "Name_Test", Proto: "Proto_Test", ListenPort: 1080 + i, DestPort: 22, DestHost: "localhost", Expiration: time.Now().Second(), IsUp: true, } log.Printf("Test noodle=%v", item) db.Add(item) log.Printf("Test id=%s exists=%t", item.Id, db.Handle.Has(item.Id)) log.Printf("Test GetAllGeneric=%v", db.GetAllGeneric()) } }