refactor: restructure session initialization to avoid circular references

This commit is contained in:
2025-12-04 19:32:00 +07:00
parent 82050a738f
commit 039e979142
10 changed files with 448 additions and 330 deletions

View File

@ -1,105 +1,82 @@
package session
import (
"bytes"
"log"
"sync"
"tunnel_pls/session/forwarder"
"tunnel_pls/session/interaction"
"tunnel_pls/session/lifecycle"
"tunnel_pls/session/slug"
"tunnel_pls/types"
"golang.org/x/crypto/ssh"
)
const (
INITIALIZING Status = "INITIALIZING"
RUNNING Status = "RUNNING"
SETUP Status = "SETUP"
)
type TunnelType string
const (
HTTP TunnelType = "http"
TCP TunnelType = "tcp"
)
type SessionLifecycle interface {
Close() error
WaitForRunningStatus()
}
type SessionCloser interface {
Close() error
}
type Session interface {
SessionLifecycle
InteractionController
ForwardingController
}
lifecycle.Lifecycle
interaction.InteractionController
forwarder.ForwardingController
type Lifecycle struct {
Status Status
HandleGlobalRequest(ch <-chan *ssh.Request)
HandleTCPIPForward(req *ssh.Request)
HandleHTTPForward(req *ssh.Request, port uint16)
HandleTCPForward(req *ssh.Request, addr string, port uint16)
}
type SSHSession struct {
Lifecycle *Lifecycle
Interaction *Interaction
Forwarder *Forwarder
Conn *ssh.ServerConn
channel ssh.Channel
slug string
slugMu sync.RWMutex
Lifecycle lifecycle.SessionLifecycle
Interaction interaction.InteractionController
Forwarder forwarder.ForwardingController
SlugManager slug.Manager
}
func New(conn *ssh.ServerConn, forwardingReq <-chan *ssh.Request, sshChan <-chan ssh.NewChannel) {
session := SSHSession{
Lifecycle: &Lifecycle{
Status: INITIALIZING,
},
Interaction: &Interaction{
CommandBuffer: new(bytes.Buffer),
EditMode: false,
EditSlug: "",
channel: nil,
getSlug: nil,
setSlug: nil,
session: nil,
forwarder: nil,
},
Forwarder: &Forwarder{
Listener: nil,
TunnelType: "",
ForwardedPort: 0,
getSlug: nil,
setSlug: nil,
},
Conn: conn,
channel: nil,
slug: "",
slugManager := slug.NewManager()
forwarderManager := &forwarder.Forwarder{
Listener: nil,
TunnelType: "",
ForwardedPort: 0,
SlugManager: slugManager,
}
session.Forwarder.getSlug = session.GetSlug
session.Forwarder.setSlug = session.SetSlug
session.Interaction.getSlug = session.GetSlug
session.Interaction.setSlug = session.SetSlug
session.Interaction.session = &session
session.Interaction.forwarder = session.Forwarder
interactionManager := &interaction.Interaction{
CommandBuffer: nil,
EditMode: false,
EditSlug: "",
SlugManager: slugManager,
Forwarder: forwarderManager,
Lifecycle: nil,
}
lifecycleManager := &lifecycle.Lifecycle{
Status: "",
Conn: conn,
Channel: nil,
Interaction: interactionManager,
Forwarder: forwarderManager,
SlugManager: slugManager,
}
session := &SSHSession{
Lifecycle: lifecycleManager,
Interaction: interactionManager,
Forwarder: forwarderManager,
SlugManager: slugManager,
}
interactionManager.SetLifecycle(lifecycleManager)
go func() {
go session.waitForRunningStatus()
go session.Lifecycle.WaitForRunningStatus()
for channel := range sshChan {
ch, reqs, _ := channel.Accept()
if session.channel == nil {
session.channel = ch
session.Interaction.channel = ch
session.Lifecycle.Status = SETUP
if session.Lifecycle.GetChannel() == nil {
session.Lifecycle.SetChannel(ch)
session.Interaction.SetChannel(ch)
//session.Interaction.channel = ch
session.Lifecycle.SetStatus(types.SETUP)
go session.HandleGlobalRequest(forwardingReq)
}
go session.HandleGlobalRequest(reqs)
}
err := session.Close()
err := session.Lifecycle.Close()
if err != nil {
log.Printf("failed to close session: %v", err)
}
@ -107,14 +84,26 @@ func New(conn *ssh.ServerConn, forwardingReq <-chan *ssh.Request, sshChan <-chan
}()
}
func (s *SSHSession) GetSlug() string {
s.slugMu.RLock()
defer s.slugMu.RUnlock()
return s.slug
var (
clientsMutex sync.RWMutex
Clients = make(map[string]*SSHSession)
)
func registerClient(slug string, session *SSHSession) bool {
clientsMutex.Lock()
defer clientsMutex.Unlock()
if _, exists := Clients[slug]; exists {
return false
}
Clients[slug] = session
return true
}
func (s *SSHSession) SetSlug(slug string) {
s.slugMu.Lock()
s.slug = slug
s.slugMu.Unlock()
func unregisterClient(slug string) {
clientsMutex.Lock()
defer clientsMutex.Unlock()
delete(Clients, slug)
}