dsfx/dsfx-server/main.go
2025-03-09 12:33:27 -04:00

103 lines
2.6 KiB
Go

package main
import (
"context"
"flag"
"fmt"
"log/slog"
"net"
"os"
"koti.casa/numenor-labs/dsfx/shared/dcrypto"
"koti.casa/numenor-labs/dsfx/shared/dlog"
"koti.casa/numenor-labs/dsfx/shared/dnet"
)
var (
flagHost = flag.String("host", "localhost", "the host to listen on")
flagPort = flag.Int("port", 8000, "the port to listen on")
flagMasterKey = flag.String("masterKey", "", "the path to the master key file")
)
func main() {
ctx := context.Background()
// ---------------------------------------------------------------------------
// Logger
opts := &slog.HandlerOptions{
AddSource: false,
Level: slog.LevelDebug,
}
logger := slog.New(slog.NewTextHandler(os.Stdout, opts))
// Everything in the application will attempt to use the logger in stored in
// the context, but we also set the default with slog as a fallback. In cases
// where the context is not available, or the context is not a child of the
// context with the logger, the default logger will be used.
slog.SetDefault(logger)
ctx = dlog.WithContext(ctx, logger)
// ---------------------------------------------------------------------------
// Flags
flag.Parse()
if *flagMasterKey == "" {
slog.ErrorContext(ctx, "master key path is required")
os.Exit(1)
}
masterKey, err := dcrypto.LoadSigningKeyFromFile(*flagMasterKey)
if err != nil {
logger.ErrorContext(ctx, "failed to load master key", slog.Any("error", err))
os.Exit(1)
}
tcpAddrRaw := net.JoinHostPort(*flagHost, fmt.Sprint(*flagPort))
tcpAddr, err := net.ResolveTCPAddr("tcp", tcpAddrRaw)
if err != nil {
slog.ErrorContext(ctx, "invalid host or port")
os.Exit(1)
}
addr := dnet.FromTCPAddr(tcpAddr, &masterKey.PublicKey)
// ---------------------------------------------------------------------------
// Listener
listener, err := dnet.Listen(ctx, masterKey, addr)
if err != nil {
logger.ErrorContext(ctx, "listener error", slog.Any("error", err))
os.Exit(1)
}
logger.InfoContext(ctx, "listener created", slog.String("address", listener.Addr().String()))
for {
conn, err := listener.Accept()
if err != nil {
logger.ErrorContext(ctx, "accept failure", slog.Any("error", err))
continue
}
go handleConnection(ctx, conn)
}
}
func handleConnection(ctx context.Context, conn net.Conn) error {
defer conn.Close()
logger := dlog.FromContext(ctx)
msg := make([]byte, 1024)
n, err := conn.Read(msg)
if err != nil {
logger.ErrorContext(ctx, "failed to read from connection", slog.Any("error", err))
return err
}
logger.InfoContext(ctx, "received msg", slog.Int("bytes", n))
return nil
}