diff options
| author | 2025-12-30 19:33:39 +0300 | |
|---|---|---|
| committer | 2025-12-30 19:33:39 +0300 | |
| commit | d317e8f6df0e0e16445db606da1d683a6b35f531 (patch) | |
| tree | 4b80de04e17a137cff2dc309508b5f841f48c994 /internal/server/server.go | |
| download | qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.gz qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.bz2 qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.xz qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.zip | |
начальный коммит
Diffstat (limited to 'internal/server/server.go')
| -rw-r--r-- | internal/server/server.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..1c28cd5 --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,70 @@ +package server + +import ( + "context" + "encoding/hex" + "fmt" + "log/slog" + "net" + "sync" + + "go.neonxp.ru/qchat/internal/chat" + "go.neonxp.ru/qchat/internal/config" + "golang.org/x/crypto/ssh" +) + +type Server struct { + cfg *config.Config + chat *chat.Chat +} + +func New(cfg *config.Config, ch *chat.Chat) *Server { + return &Server{ + cfg: cfg, + chat: ch, + } +} + +func (s *Server) Run(ctx context.Context) error { + config := &ssh.ServerConfig{ + PublicKeyCallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) { + return &ssh.Permissions{ + ExtraData: map[any]any{ + "identify": hex.EncodeToString(pubKey.Marshal()), + }, + }, nil + }, + } + + private, err := ssh.ParsePrivateKey([]byte(s.cfg.Server.PrivateKey)) + if err != nil { + return fmt.Errorf("failed to parse private key: %w", err) + } + config.AddHostKey(private) + listener, err := net.Listen("tcp", s.cfg.Server.Addr) + if err != nil { + return fmt.Errorf("failed to parse private key: %w", err) + } + go func() { + <-ctx.Done() + listener.Close() + }() + + wg := sync.WaitGroup{} + defer wg.Wait() + + slog.InfoContext(ctx, "started server at", slog.String("addr", s.cfg.Server.Addr)) + + for { + nConn, err := listener.Accept() + if err != nil { + slog.ErrorContext(ctx, "failed to accept incoming connection", slog.Any("err", err)) + continue + } + wg.Go(func() { + if err := s.serveConn(ctx, nConn, config); err != nil { + slog.ErrorContext(ctx, "connection error", slog.Any("err", err)) + } + }) + } +} |
