Skip to content
This repository was archived by the owner on Mar 9, 2022. It is now read-only.

Commit 3049a7f

Browse files
committed
Getting rid of socat
Signed-off-by: abhi <[email protected]>
1 parent 616831f commit 3049a7f

File tree

1 file changed

+20
-36
lines changed

1 file changed

+20
-36
lines changed

pkg/server/sandbox_portforward.go

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ limitations under the License.
1717
package server
1818

1919
import (
20-
"bytes"
2120
"fmt"
2221
"io"
23-
"os/exec"
24-
"strings"
22+
"net"
23+
"sync"
2524

2625
"github.com/containernetworking/plugins/pkg/ns"
2726
"github.com/pkg/errors"
@@ -58,46 +57,31 @@ func (c *criService) portForward(id string, port int32, stream io.ReadWriteClose
5857
return errors.Errorf("failed to find network namespace fo sandbox %q in store", id)
5958
}
6059

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, " "))
7060
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()
61+
var wg sync.WaitGroup
62+
client, err := net.Dial("tcp4", fmt.Sprintf("localhost:%d", port))
8763
if err != nil {
88-
return errors.Wrap(err, "failed to create stdin pipe")
64+
return errors.Wrap(err, "failed to dial")
8965
}
66+
defer client.Close()
67+
68+
wg.Add(1)
9069
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)
70+
if _, err := io.Copy(client, stream); err != nil {
71+
logrus.WithError(err).Errorf("Failed to copy port forward input from %q port %d", id, port)
9372
}
94-
in.Close()
95-
logrus.Debugf("Finish copy port forward input for %q port %d: %v", id, port)
73+
wg.Done()
9674
}()
75+
wg.Add(1)
76+
go func() {
77+
if _, err := io.Copy(stream, client); err != nil {
78+
logrus.WithError(err).Errorf("Failed to copy port forward output for %q port %d", id, port)
79+
}
80+
wg.Done()
81+
}()
82+
wg.Wait()
83+
logrus.Infof("Finish copy port forward input for %q port %d: %v", id, port)
9784

98-
if err := cmd.Run(); err != nil {
99-
return errors.Wrapf(err, "socat command returns error, stderr: %q", stderr.String())
100-
}
10185
return nil
10286
})
10387
if err != nil {

0 commit comments

Comments
 (0)