@@ -17,11 +17,13 @@ limitations under the License.
1717package server
1818
1919import (
20- "bytes"
20+ // "bytes"
2121 "fmt"
2222 "io"
23- "os/exec"
24- "strings"
23+ "net"
24+ //"os/exec"
25+ //"strings"
26+ "sync"
2527
2628 "github.com/containernetworking/plugins/pkg/ns"
2729 "github.com/pkg/errors"
@@ -58,46 +60,31 @@ func (c *criService) portForward(id string, port int32, stream io.ReadWriteClose
5860 return errors .Errorf ("failed to find network namespace fo sandbox %q in store" , id )
5961 }
6062
61- socat , err := exec .LookPath ("socat" )
62- if err != nil {
63- return errors .Wrap (err , "failed to find socat" )
64- }
65-
66- // Check following links for meaning of the options:
67- // * socat: https://linux.die.net/man/1/socat
68- args := []string {"-" , fmt .Sprintf ("TCP4:localhost:%d" , port )}
69- logrus .Infof ("Executing port forwarding command: %s %s" , socat , strings .Join (args , " " ))
7063 err = s .NetNS .GetNs ().Do (func (_ ns.NetNS ) error {
71- cmd := exec .Command (socat , args ... )
72- cmd .Stdout = stream
73-
74- stderr := new (bytes.Buffer )
75- cmd .Stderr = stderr
76-
77- // If we use Stdin, command.Run() won't return until the goroutine that's copying
78- // from stream finishes. Unfortunately, if you have a client like telnet connected
79- // via port forwarding, as long as the user's telnet client is connected to the user's
80- // local listener that port forwarding sets up, the telnet session never exits. This
81- // means that even if socat has finished running, command.Run() won't ever return
82- // (because the client still has the connection and stream open).
83- //
84- // The work around is to use StdinPipe(), as Wait() (called by Run()) closes the pipe
85- // when the command (socat) exits.
86- in , err := cmd .StdinPipe ()
64+ var wg sync.WaitGroup
65+ client , err := net .Dial ("tcp4" , fmt .Sprintf ("localhost:%d" , port ))
8766 if err != nil {
88- return errors .Wrap (err , "failed to create stdin pipe " )
67+ return errors .Wrap (err , "failed to dial " )
8968 }
69+ defer client .Close ()
70+
71+ wg .Add (1 )
9072 go func () {
91- if _ , err := io .Copy (in , stream ); err != nil {
92- logrus .WithError (err ).Errorf ("Failed to copy port forward input for %q port %d" , id , port )
73+ if _ , err := io .Copy (client , stream ); err != nil {
74+ logrus .WithError (err ).Errorf ("Failed to copy port forward input from %q port %d" , id , port )
9375 }
94- in .Close ()
95- logrus .Debugf ("Finish copy port forward input for %q port %d: %v" , id , port )
76+ wg .Done ()
9677 }()
78+ wg .Add (1 )
79+ go func () {
80+ if _ , err := io .Copy (stream , client ); err != nil {
81+ logrus .WithError (err ).Errorf ("Failed to copy port forward output for %q port %d" , id , port )
82+ }
83+ wg .Done ()
84+ }()
85+ wg .Wait ()
86+ logrus .Infof ("Finish copy port forward input for %q port %d: %v" , id , port )
9787
98- if err := cmd .Run (); err != nil {
99- return errors .Wrapf (err , "socat command returns error, stderr: %q" , stderr .String ())
100- }
10188 return nil
10289 })
10390 if err != nil {
0 commit comments