package server import ( "bufio" "context" "fmt" "log" "net" "codeberg.org/snonux/gorum/internal/config" ) type handlerCb func(message string) string func tcpServerRun(ctx context.Context, conf config.Config, cb handlerCb) error { listener, err := net.Listen("tcp", conf.Address) if err != nil { return fmt.Errorf("error starting TCP server: %s", err.Error()) } defer listener.Close() log.Println("server: listening on", conf.Address) for { conn, err := listener.Accept() if err != nil { log.Println("server: error accepting connection:", err) continue } if !conf.IsNodeWithLookup(conn.RemoteAddr().String(), net.LookupIP) { log.Println("server: denying connection, peer not a node:", conn.RemoteAddr().String()) conn.Close() continue } log.Println("server: client connected:", conn.RemoteAddr().String()) go handleConnection(ctx, conn, cb) } } func handleConnection(ctx context.Context, conn net.Conn, cb handlerCb) { defer conn.Close() var ( remoteAddr = conn.RemoteAddr().String() reader = bufio.NewReader(conn) ) for { select { case <-ctx.Done(): log.Println("server: context done, disconnecting client:", remoteAddr) return default: message, err := reader.ReadString('\n') if err != nil { log.Println("server: client disconnected:", remoteAddr, err) return } log.Println("server: received message", remoteAddr, message) response := cb(message) if _, err := conn.Write([]byte(response)); err != nil { log.Println("error:", err) } } } }