aboutsummaryrefslogtreecommitdiff
path: root/internal/server/conn.go
diff options
context:
space:
mode:
author2025-12-30 19:33:39 +0300
committer2025-12-30 19:33:39 +0300
commitd317e8f6df0e0e16445db606da1d683a6b35f531 (patch)
tree4b80de04e17a137cff2dc309508b5f841f48c994 /internal/server/conn.go
downloadqchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.gz
qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.bz2
qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.xz
qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.zip
начальный коммит
Diffstat (limited to 'internal/server/conn.go')
-rw-r--r--internal/server/conn.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/internal/server/conn.go b/internal/server/conn.go
new file mode 100644
index 0000000..1069b0b
--- /dev/null
+++ b/internal/server/conn.go
@@ -0,0 +1,67 @@
+package server
+
+import (
+ "context"
+ "fmt"
+ "log/slog"
+ "net"
+ "sync"
+
+ "golang.org/x/crypto/ssh"
+)
+
+func (s *Server) serveConn(ctx context.Context, nConn net.Conn, config *ssh.ServerConfig) error {
+ conn, chans, reqs, err := ssh.NewServerConn(nConn, config)
+ if err != nil {
+ return fmt.Errorf("failed to handshake: %w", err)
+ }
+ slog.Info("user connected", slog.Any("user", conn.User()), slog.String("ip", conn.RemoteAddr().String()))
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ wg.Go(func() {
+ ssh.DiscardRequests(reqs)
+ })
+
+ for newChannel := range chans {
+ if newChannel.ChannelType() != "session" {
+ newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
+ continue
+ }
+ channel, requests, err := newChannel.Accept()
+ if err != nil {
+ return fmt.Errorf("could not accept channel: %w", err)
+ }
+
+ wg.Go(func() {
+ for req := range requests {
+ switch req.Type {
+ case "pty-req":
+ req.Reply(true, nil)
+ case "shell":
+ req.Reply(true, nil)
+ default:
+ req.Reply(false, nil)
+ }
+ slog.Debug(
+ "req",
+ slog.String("type", req.Type),
+ slog.Bool("want-reply", req.WantReply),
+ slog.String("payload", string(req.Payload)),
+ )
+ }
+ })
+
+ wg.Go(func() {
+ identify := conn.Permissions.ExtraData["identify"].(string)
+ user := s.chat.NewUser(conn.User(), identify)
+ slog.Info("joined", slog.String("user", user.NUsername()))
+ s.serveClient(ctx, channel, user)
+ slog.Info("disconnected", slog.String("user", user.NUsername()))
+ conn.Close()
+ })
+ }
+
+ return nil
+}