working server
* administration appears coorect * multiple clients for one agent * logging of active connections * simple echo server on the agent.
This commit is contained in:
		
							parent
							
								
									6c8e0adccf
								
							
						
					
					
						commit
						cfccf04f9d
					
				@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/creack/pty"
 | 
						"github.com/creack/pty"
 | 
				
			||||||
	"github.com/gliderlabs/ssh"
 | 
						"github.com/gliderlabs/ssh"
 | 
				
			||||||
 | 
						"github.com/hashicorp/yamux"
 | 
				
			||||||
	"github.com/pkg/sftp"
 | 
						"github.com/pkg/sftp"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -113,7 +114,31 @@ func main() {
 | 
				
			|||||||
	wsConn := iowrappers.NewWebSocketConn(conn)
 | 
						wsConn := iowrappers.NewWebSocketConn(conn)
 | 
				
			||||||
	defer wsConn.Close()
 | 
						defer wsConn.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// echo server
 | 
						listener, err := yamux.Client(wsConn, nil)
 | 
				
			||||||
	iowrappers.SynchronizeStreams(wsConn, wsConn)
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Println("Connection established to rendez-vous server, waiting for debug sessions")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Session is a listener
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							conn, err := listener.Accept()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								panic(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							go handleConnection(conn)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleConnection(conn io.ReadWriter) {
 | 
				
			||||||
 | 
						//stdio := bufio.NewReadWriter(
 | 
				
			||||||
 | 
						//	bufio.NewReaderSize(os.Stdin, 0),
 | 
				
			||||||
 | 
						//	bufio.NewWriterSize(os.Stdout, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// echo server
 | 
				
			||||||
 | 
						io.Copy(conn, conn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//iowrappers.SynchronizeStreams(conn, stdio)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,10 +4,14 @@ import (
 | 
				
			|||||||
	"cidebug/pkg/iowrappers"
 | 
						"cidebug/pkg/iowrappers"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"github.com/gorilla/websocket"
 | 
						"github.com/gorilla/websocket"
 | 
				
			||||||
 | 
						"github.com/hashicorp/yamux"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var upgrader = websocket.Upgrader{
 | 
					var upgrader = websocket.Upgrader{
 | 
				
			||||||
@ -16,7 +20,7 @@ var upgrader = websocket.Upgrader{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handleWebSocket(w http.ResponseWriter, r *http.Request,
 | 
					func handleWebSocket(w http.ResponseWriter, r *http.Request,
 | 
				
			||||||
	handler func(w http.ResponseWriter, r *http.Request, websockerConnection *iowrappers.WebSocketConn)) {
 | 
						handler func(w http.ResponseWriter, r *http.Request, websockerConnection iowrappers.ReadWriteAddrCloser)) {
 | 
				
			||||||
	conn, err := upgrader.Upgrade(w, r, nil)
 | 
						conn, err := upgrader.Upgrade(w, r, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("Error upgrading to WebSocket:", err)
 | 
							log.Println("Error upgrading to WebSocket:", err)
 | 
				
			||||||
@ -29,7 +33,7 @@ func handleWebSocket(w http.ResponseWriter, r *http.Request,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type WebSocketService struct {
 | 
					type WebSocketService struct {
 | 
				
			||||||
	handler func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn)
 | 
						handler func(w http.ResponseWriter, r *http.Request, conn iowrappers.ReadWriteAddrCloser)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (endpoint *WebSocketService) handle(w http.ResponseWriter, r *http.Request) {
 | 
					func (endpoint *WebSocketService) handle(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
@ -37,72 +41,106 @@ func (endpoint *WebSocketService) handle(w http.ResponseWriter, r *http.Request)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Agent struct {
 | 
					type Agent struct {
 | 
				
			||||||
	agent          *iowrappers.WebSocketConn
 | 
						// server session
 | 
				
			||||||
	publicId       string
 | 
						clientSession *yamux.Session
 | 
				
			||||||
	client         *iowrappers.WebSocketConn
 | 
						publicId      string
 | 
				
			||||||
	agentAvailable chan bool
 | 
						startTime     time.Time
 | 
				
			||||||
	clientClosed   chan bool
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Client struct {
 | 
				
			||||||
 | 
						publicId  string
 | 
				
			||||||
 | 
						agent     net.Conn
 | 
				
			||||||
 | 
						client    iowrappers.ReadWriteAddrCloser
 | 
				
			||||||
 | 
						startTime time.Time
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewAgent(publicId string,
 | 
					func NewAgent(publicId string,
 | 
				
			||||||
	agentConn *iowrappers.WebSocketConn,
 | 
						agentSession *yamux.Session) *Agent {
 | 
				
			||||||
	clientConn *iowrappers.WebSocketConn) *Agent {
 | 
					 | 
				
			||||||
	return &Agent{
 | 
						return &Agent{
 | 
				
			||||||
		agent:          agentConn,
 | 
							clientSession: agentSession,
 | 
				
			||||||
		publicId:       publicId,
 | 
							publicId:      publicId,
 | 
				
			||||||
		client:         clientConn,
 | 
							startTime:     time.Now(),
 | 
				
			||||||
		agentAvailable: make(chan bool, 1),
 | 
						}
 | 
				
			||||||
		clientClosed:   make(chan bool, 1),
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewClient(publicId string, clientConn iowrappers.ReadWriteAddrCloser, agentConn net.Conn) *Client {
 | 
				
			||||||
 | 
						return &Client{
 | 
				
			||||||
 | 
							publicId:  publicId,
 | 
				
			||||||
 | 
							agent:     agentConn,
 | 
				
			||||||
 | 
							client:    clientConn,
 | 
				
			||||||
 | 
							startTime: time.Now(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Admin struct {
 | 
					type Admin struct {
 | 
				
			||||||
	// map of public id to agent
 | 
						// map of public id to agent
 | 
				
			||||||
	mutex  sync.Mutex
 | 
						mutex   sync.Mutex
 | 
				
			||||||
	agents map[string]*Agent
 | 
						agents  map[string]*Agent
 | 
				
			||||||
 | 
						clients []*Client
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewAdmin() *Admin {
 | 
					func NewAdmin() *Admin {
 | 
				
			||||||
	admin := Admin{
 | 
						admin := Admin{
 | 
				
			||||||
		mutex:  sync.Mutex{},
 | 
							mutex:   sync.Mutex{},
 | 
				
			||||||
		agents: make(map[string]*Agent),
 | 
							agents:  make(map[string]*Agent),
 | 
				
			||||||
 | 
							clients: make([]*Client, 0), // not strictly needed
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &admin
 | 
						return &admin
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (admin *Admin) addAgent(publicId string, conn *iowrappers.WebSocketConn) (*Agent, error) {
 | 
					func (admin *Admin) logStatus() {
 | 
				
			||||||
 | 
						log.Printf("%-20s %-20s %-20s\n", "AGENT", "ACTIVE_SINCE", "REMOTE_ADDRESS")
 | 
				
			||||||
 | 
						for _, agent := range admin.agents {
 | 
				
			||||||
 | 
							agent.clientSession.RemoteAddr()
 | 
				
			||||||
 | 
							log.Printf("%-20s %-20s %-20s\n", agent.publicId,
 | 
				
			||||||
 | 
								agent.startTime.Format("2006-01-02 15:04:05"),
 | 
				
			||||||
 | 
								agent.clientSession.RemoteAddr().String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log.Println("")
 | 
				
			||||||
 | 
						log.Printf("%-20s %-20s %-20s\n", "CLIENT", "ACTIVE_SINCE", "REMOTE_ADDRESS")
 | 
				
			||||||
 | 
						for _, client := range admin.clients {
 | 
				
			||||||
 | 
							log.Printf("%-20s %-20s %-20s", client.publicId,
 | 
				
			||||||
 | 
								client.startTime.Format("2006-01-02 15:04:05"),
 | 
				
			||||||
 | 
								client.client.RemoteAddr())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log.Printf("\n")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (admin *Admin) addAgent(publicId string, conn io.ReadWriteCloser) (*Agent, error) {
 | 
				
			||||||
	admin.mutex.Lock()
 | 
						admin.mutex.Lock()
 | 
				
			||||||
	defer admin.mutex.Unlock()
 | 
						defer admin.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	agent := admin.agents[publicId]
 | 
						agent := admin.agents[publicId]
 | 
				
			||||||
	if agent != nil && agent.agent != nil && agent.agent != conn {
 | 
						if agent != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("A different agent with same publicId '%s' already registered", publicId)
 | 
							return nil, fmt.Errorf("A different agent with same publicId '%s' already registered", publicId)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if agent != nil {
 | 
						session, err := yamux.Client(conn, nil)
 | 
				
			||||||
		agent.agent = conn
 | 
						if err != nil {
 | 
				
			||||||
		return agent, nil
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	agent = NewAgent(publicId, conn, nil)
 | 
						agent = NewAgent(publicId, session)
 | 
				
			||||||
	admin.agents[publicId] = agent
 | 
						admin.agents[publicId] = agent
 | 
				
			||||||
 | 
						admin.logStatus()
 | 
				
			||||||
	return agent, nil
 | 
						return agent, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (admin *Admin) addClient(publicId string, conn *iowrappers.WebSocketConn) (*Agent, error) {
 | 
					func (admin *Admin) addClient(publicId string, clientConn iowrappers.ReadWriteAddrCloser) (*Client, error) {
 | 
				
			||||||
	admin.mutex.Lock()
 | 
						admin.mutex.Lock()
 | 
				
			||||||
	defer admin.mutex.Unlock()
 | 
						defer admin.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	agent := admin.agents[publicId]
 | 
						agent := admin.agents[publicId]
 | 
				
			||||||
	if agent != nil && agent.client != nil && agent.client != conn {
 | 
						if agent == nil {
 | 
				
			||||||
		// we should setup on-demend connections ot agents later.
 | 
							// we should setup on-demend connections ot agents later.
 | 
				
			||||||
		return nil, fmt.Errorf("A different client with same publicId '%s' already registered", publicId)
 | 
							return nil, fmt.Errorf("No agent found for publicId '%s'", publicId)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if agent != nil {
 | 
						agentConn, err := agent.clientSession.Open()
 | 
				
			||||||
		agent.client = conn
 | 
						if err != nil {
 | 
				
			||||||
		return agent, nil
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	agent = NewAgent(publicId, nil, conn)
 | 
						client := NewClient(publicId, clientConn, agentConn)
 | 
				
			||||||
	admin.agents[publicId] = agent
 | 
						admin.clients = append(admin.clients, client)
 | 
				
			||||||
	return agent, nil
 | 
						admin.logStatus()
 | 
				
			||||||
 | 
						return client, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (admin *Admin) RemoveAgent(publicId string) error {
 | 
					func (admin *Admin) RemoveAgent(publicId string) error {
 | 
				
			||||||
@ -113,32 +151,39 @@ func (admin *Admin) RemoveAgent(publicId string) error {
 | 
				
			|||||||
	if agent == nil {
 | 
						if agent == nil {
 | 
				
			||||||
		return fmt.Errorf("Cannot remove agent: '%s' not found", publicId)
 | 
							return fmt.Errorf("Cannot remove agent: '%s' not found", publicId)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	agent.agent = nil
 | 
						log.Printf("Removing agent: '%s'", publicId)
 | 
				
			||||||
	if agent.client == nil {
 | 
						err := agent.clientSession.Close()
 | 
				
			||||||
		log.Printf("Removing agent: '%s'", publicId)
 | 
						if err != nil {
 | 
				
			||||||
		delete(admin.agents, publicId)
 | 
							log.Printf("Could not close yamux client session for '%s'\n", publicId)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						delete(admin.agents, publicId)
 | 
				
			||||||
 | 
						admin.logStatus()
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (admin *Admin) RemoveClient(publicId string) error {
 | 
					func (admin *Admin) RemoveClient(client *Client) error {
 | 
				
			||||||
	admin.mutex.Lock()
 | 
						admin.mutex.Lock()
 | 
				
			||||||
	defer admin.mutex.Unlock()
 | 
						defer admin.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	agent := admin.agents[publicId]
 | 
						log.Printf("Removing client: '%s' created at %s\n", client.publicId,
 | 
				
			||||||
	if agent == nil {
 | 
							client.startTime.Format("2006-01-02 15:04:05"))
 | 
				
			||||||
		return fmt.Errorf("Cannot remove agent: '%s' not found", publicId)
 | 
						// try to explicitly close connection to the agent.
 | 
				
			||||||
	}
 | 
						_ = client.agent.Close()
 | 
				
			||||||
	agent.client = nil
 | 
						_ = client.client.Close()
 | 
				
			||||||
	if agent.agent == nil {
 | 
					
 | 
				
			||||||
		log.Printf("Removing client: '%s'", publicId)
 | 
						for i, _client := range admin.clients {
 | 
				
			||||||
		delete(admin.agents, publicId)
 | 
							if _client == _client {
 | 
				
			||||||
 | 
								admin.clients = append(admin.clients[:i], admin.clients[i+1:]...)
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						admin.logStatus()
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (admin *Admin) Register(publicId string, conn *iowrappers.WebSocketConn) error {
 | 
					func (admin *Admin) Register(publicId string, conn io.ReadWriteCloser) error {
 | 
				
			||||||
	defer conn.Close()
 | 
						defer conn.Close()
 | 
				
			||||||
 | 
						// TODO: remove agent return value
 | 
				
			||||||
	agent, err := admin.addAgent(publicId, conn)
 | 
						agent, err := admin.addAgent(publicId, conn)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@ -146,26 +191,24 @@ func (admin *Admin) Register(publicId string, conn *iowrappers.WebSocketConn) er
 | 
				
			|||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		admin.RemoveAgent(publicId)
 | 
							admin.RemoveAgent(publicId)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	log.Printf("After defer remove agent\n")
 | 
					 | 
				
			||||||
	agent.agentAvailable <- true
 | 
					 | 
				
			||||||
	log.Printf("Agent registered: '%s'\n", publicId)
 | 
						log.Printf("Agent registered: '%s'\n", publicId)
 | 
				
			||||||
	<-agent.clientClosed
 | 
						for !agent.clientSession.IsClosed() {
 | 
				
			||||||
 | 
							time.Sleep(1 * time.Second)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (admin *Admin) Connect(publicId string, conn *iowrappers.WebSocketConn) error {
 | 
					func (admin *Admin) Connect(publicId string, conn iowrappers.ReadWriteAddrCloser) error {
 | 
				
			||||||
	defer conn.Close()
 | 
						defer conn.Close()
 | 
				
			||||||
	agent, err := admin.addClient(publicId, conn)
 | 
						client, err := admin.addClient(publicId, conn)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		admin.RemoveClient(publicId)
 | 
							admin.RemoveClient(client)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	<-agent.agentAvailable
 | 
					 | 
				
			||||||
	log.Printf("Connecting client and agent: '%s'\n", publicId)
 | 
						log.Printf("Connecting client and agent: '%s'\n", publicId)
 | 
				
			||||||
	iowrappers.SynchronizeStreams(agent.client, agent.agent)
 | 
						iowrappers.SynchronizeStreams(client.client, client.agent)
 | 
				
			||||||
	agent.clientClosed <- true
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,14 +227,13 @@ func parsePublicId(path string) (publicId string, _ error) {
 | 
				
			|||||||
		return "", fmt.Errorf("Invalid URL path '%s'", path)
 | 
							return "", fmt.Errorf("Invalid URL path '%s'", path)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return matches[1], nil
 | 
						return matches[1], nil
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	admin := NewAdmin()
 | 
						admin := NewAdmin()
 | 
				
			||||||
	registrationService := WebSocketService{
 | 
						registrationService := WebSocketService{
 | 
				
			||||||
		handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) {
 | 
							handler: func(w http.ResponseWriter, r *http.Request, conn iowrappers.ReadWriteAddrCloser) {
 | 
				
			||||||
			publicId, err := parsePublicId(r.URL.Path)
 | 
								publicId, err := parsePublicId(r.URL.Path)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				log.Printf("Cannot parse public id from url: '%v'\n", err)
 | 
									log.Printf("Cannot parse public id from url: '%v'\n", err)
 | 
				
			||||||
@ -205,7 +247,7 @@ func main() {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	clientService := WebSocketService{
 | 
						clientService := WebSocketService{
 | 
				
			||||||
		handler: func(w http.ResponseWriter, r *http.Request, conn *iowrappers.WebSocketConn) {
 | 
							handler: func(w http.ResponseWriter, r *http.Request, conn iowrappers.ReadWriteAddrCloser) {
 | 
				
			||||||
			publicId, err := parsePublicId(r.URL.Path)
 | 
								publicId, err := parsePublicId(r.URL.Path)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				log.Printf("Cannot parse public id from url: '%v'\n", err)
 | 
									log.Printf("Cannot parse public id from url: '%v'\n", err)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							@ -6,6 +6,7 @@ require (
 | 
				
			|||||||
	github.com/creack/pty v1.1.21
 | 
						github.com/creack/pty v1.1.21
 | 
				
			||||||
	github.com/gliderlabs/ssh v0.3.7
 | 
						github.com/gliderlabs/ssh v0.3.7
 | 
				
			||||||
	github.com/gorilla/websocket v1.5.3
 | 
						github.com/gorilla/websocket v1.5.3
 | 
				
			||||||
 | 
						github.com/hashicorp/yamux v0.1.1
 | 
				
			||||||
	github.com/pkg/sftp v1.13.6
 | 
						github.com/pkg/sftp v1.13.6
 | 
				
			||||||
	golang.org/x/crypto v0.25.0
 | 
						golang.org/x/crypto v0.25.0
 | 
				
			||||||
	golang.org/x/term v0.22.0
 | 
						golang.org/x/term v0.22.0
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@ -9,6 +9,8 @@ github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
 | 
				
			|||||||
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
 | 
					github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
 | 
				
			||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
 | 
					github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
 | 
				
			||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 | 
					github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 | 
				
			||||||
 | 
					github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
 | 
				
			||||||
 | 
					github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
 | 
				
			||||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
 | 
					github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
 | 
				
			||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 | 
					github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 | 
				
			||||||
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
 | 
					github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,20 @@
 | 
				
			|||||||
package iowrappers
 | 
					package iowrappers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "github.com/gorilla/websocket"
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/gorilla/websocket"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type WebSocketConn struct {
 | 
					type WebSocketConn struct {
 | 
				
			||||||
	conn *websocket.Conn
 | 
						conn *websocket.Conn
 | 
				
			||||||
	buf  []byte
 | 
						buf  []byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewWebSocketConn(conn *websocket.Conn) *WebSocketConn {
 | 
					type ReadWriteAddrCloser interface {
 | 
				
			||||||
	return &WebSocketConn{conn: conn}
 | 
						io.ReadWriteCloser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RemoteAddr() net.Addr
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (websocketConn *WebSocketConn) Read(p []byte) (n int, err error) {
 | 
					func (websocketConn *WebSocketConn) Read(p []byte) (n int, err error) {
 | 
				
			||||||
@ -26,6 +32,10 @@ func (websocketConn *WebSocketConn) Read(p []byte) (n int, err error) {
 | 
				
			|||||||
	return n, err
 | 
						return n, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewWebSocketConn(conn *websocket.Conn) *WebSocketConn {
 | 
				
			||||||
 | 
						return &WebSocketConn{conn: conn}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (websocketConn *WebSocketConn) Write(p []byte) (n int, err error) {
 | 
					func (websocketConn *WebSocketConn) Write(p []byte) (n int, err error) {
 | 
				
			||||||
	err = websocketConn.conn.WriteMessage(websocket.BinaryMessage, p)
 | 
						err = websocketConn.conn.WriteMessage(websocket.BinaryMessage, p)
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
@ -37,3 +47,7 @@ func (websocketConn *WebSocketConn) Write(p []byte) (n int, err error) {
 | 
				
			|||||||
func (websocketConn *WebSocketConn) Close() error {
 | 
					func (websocketConn *WebSocketConn) Close() error {
 | 
				
			||||||
	return websocketConn.conn.Close()
 | 
						return websocketConn.conn.Close()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (websocketConn *WebSocketConn) RemoteAddr() net.Addr {
 | 
				
			||||||
 | 
						return websocketConn.conn.RemoteAddr()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ func SynchronizeStreams(stream1, stream2 io.ReadWriter) {
 | 
				
			|||||||
		}()
 | 
							}()
 | 
				
			||||||
		_, err := io.Copy(stream1, stream2)
 | 
							_, err := io.Copy(stream1, stream2)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Printf("error %v\n", err)
 | 
								log.Printf("sync streams error(1) %v\n", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,7 +23,7 @@ func SynchronizeStreams(stream1, stream2 io.ReadWriter) {
 | 
				
			|||||||
			waitChannel <- true
 | 
								waitChannel <- true
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
		_, err := io.Copy(stream2, stream1)
 | 
							_, err := io.Copy(stream2, stream1)
 | 
				
			||||||
		log.Printf("Error %v\n", err)
 | 
							log.Printf("sync streams error(2) %v\n", err)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<-waitChannel
 | 
						<-waitChannel
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user