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/conn.go | |
| download | qchat-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.go | 67 |
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 +} |
