@ -2,63 +2,45 @@ package tcp
import (
"context"
"fmt"
"io"
"net"
"net/url"
"sync"
pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services"
"github.com/hashicorp/boundary/internal/observability/event"
"github.com/hashicorp/boundary/internal/servers/worker/proxy"
"github.com/hashicorp/boundary/internal/servers/worker/session"
"nhooyr.io/websocket"
)
func init ( ) {
err := proxy . RegisterHandler ( "tcp" , handle Tcp ProxyV1 )
err := proxy . RegisterHandler ( "tcp" , handle Proxy)
if err != nil {
panic ( err )
}
}
// handle Tcp ProxyV1 creates a tcp proxy between the incoming websocket conn and the
// handle Proxy creates a tcp proxy between the incoming websocket conn and the
// connection it creates with the remote endpoint. handleTcpProxyV1 sets the connectionId
// as connected in the repository.
//
// handle Tcp ProxyV1 blocks until an error (EOF on happy path) is received on either
// handle Proxy blocks until an error (EOF on happy path) is received on either
// connection.
//
// All options are ignored.
func handleTcpProxyV1 ( ctx context . Context , conf proxy . Config , _ ... proxy . Option ) {
const op = "tcp.HandleTcpProxyV1"
si := conf . SessionInfo
si . RLock ( )
sessionId := si . LookupSessionResponse . GetAuthorization ( ) . GetSessionId ( )
si . RUnlock ( )
func handleProxy ( ctx context . Context , conf proxy . Config , _ ... proxy . Option ) error {
conn := conf . ClientConn
sessionUrl , err := url . Parse ( conf . RemoteEndpoint )
if err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error parsing endpoint information" , "session_id" , sessionId , "endpoint" , conf . RemoteEndpoint ) )
if err = conn . Close ( websocket . StatusInternalError , "cannot parse endpoint url" ) ; err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error closing client connection" ) )
}
return
return fmt . Errorf ( "error parsing endpoint information: %w" , err )
}
if sessionUrl . Scheme != "tcp" {
event . WriteError ( ctx , op , err , event . WithInfo ( "session_id" , sessionId , "endpoint" , conf . RemoteEndpoint ) )
if err = conn . Close ( websocket . StatusInternalError , "invalid scheme for type" ) ; err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error closing client connection" ) )
}
return
return fmt . Errorf ( "invalid scheme for tcp proxy: %v" , sessionUrl . Scheme )
}
remoteConn , err := net . Dial ( "tcp" , sessionUrl . Host )
if err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error dialing endpoint" , "endpoint" , conf . RemoteEndpoint ) )
if err = conn . Close ( websocket . StatusInternalError , "endpoint dialing failed" ) ; err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error closing client connection" ) )
}
return
return fmt . Errorf ( "error dialing endpoint: %w" , err )
}
// Assert this for better Go 1.11 splice support
tcpRemoteConn := remoteConn . ( * net . TCPConn )
@ -75,15 +57,13 @@ func handleTcpProxyV1(ctx context.Context, conf proxy.Config, _ ...proxy.Option)
connStatus , err := session . ConnectConnection ( ctx , conf . SessionClient , connectionInfo )
if err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error marking connection as connected" ) )
if err = conn . Close ( websocket . StatusInternalError , "failed to mark connection as connected" ) ; err != nil {
event . WriteError ( ctx , op , err , event . WithInfoMsg ( "error closing client connection" ) )
}
return
return fmt . Errorf ( "error marking connection as connected: %w" , err )
}
si . Lock ( )
si . ConnInfoMap [ conf . ConnectionId ] . Status = connStatus
si . Unlock ( )
// Update connection info to set connection status
conf . SessionInfo . Lock ( )
conf . SessionInfo . ConnInfoMap [ conf . ConnectionId ] . Status = connStatus
conf . SessionInfo . Unlock ( )
// Get a wrapped net.Conn so we can use io.Copy
netConn := websocket . NetConn ( ctx , conn , websocket . MessageBinary )
@ -103,4 +83,5 @@ func handleTcpProxyV1(ctx context.Context, conf proxy.Config, _ ...proxy.Option)
_ = netConn . Close ( )
} ( )
connWg . Wait ( )
return nil
}