refactor: restructure session initialization to avoid circular references
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user