Files
tesseract/internal/sshproxy/proxy_connection.go

85 lines
1.6 KiB
Go

package sshproxy
import (
"fmt"
"io"
"net"
"sync"
)
type proxyConnection struct {
internalPort int
externalPort int
listener net.Listener
// closedChan is used to notify that the proxy connection is closed
closedChan chan<- *proxyConnection
}
func newProxyConnection(toPort int, closedChan chan *proxyConnection) (*proxyConnection, error) {
l, err := net.Listen("tcp", ":0")
if err != nil {
return nil, err
}
externalPort := l.Addr().(*net.TCPAddr).Port
return &proxyConnection{
internalPort: toPort,
externalPort: externalPort,
listener: l,
closedChan: closedChan,
}, nil
}
func (c *proxyConnection) start() {
for {
conn, err := c.listener.Accept()
if err != nil {
fmt.Printf("error accepting connection at %v: %v\n", c.listener.Addr(), err)
}
go c.forwardConnectionToSSH(conn)
}
}
func (c *proxyConnection) forwardConnectionToSSH(conn net.Conn) {
containerConn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", c.internalPort))
if err != nil {
fmt.Printf("error connecting to container ssh at port %d\n", c.internalPort)
return
}
defer func() {
c.closedChan <- c
}()
defer containerConn.Close()
var wg sync.WaitGroup
defer wg.Wait()
wg.Add(1)
go func() {
defer wg.Done()
defer conn.Close()
for {
_, err := io.Copy(conn, containerConn)
if err != nil {
fmt.Println("read remote conn err", err)
break
}
}
}()
wg.Add(1)
go func() {
defer wg.Done()
defer conn.Close()
for {
_, err := io.Copy(containerConn, conn)
if err != nil {
fmt.Println("write remote conn err", err)
break
}
}
}()
}