Skip to content

Commit

Permalink
feat(ipv6): Add support to IPv6 port-forwarding
Browse files Browse the repository at this point in the history
  • Loading branch information
heyvito committed May 15, 2023
1 parent e57ac78 commit 17585c2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 22 deletions.
1 change: 1 addition & 0 deletions pkg/guestagent/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

var (
IPv4loopback1 = net.IPv4(127, 0, 0, 1)
IPv6loopback1 = net.IPv6loopback
)

type IPPort struct {
Expand Down
16 changes: 13 additions & 3 deletions pkg/hostagent/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,19 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
}
rules = append(rules, y.PortForwards...)
// Default forwards for all non-privileged ports from "127.0.0.1" and "::1"
rule := limayaml.PortForward{GuestIP: guestagentapi.IPv4loopback1}
limayaml.FillPortForwardDefaults(&rule, inst.Dir)
rules = append(rules, rule)
{
rule := limayaml.PortForward{GuestIP: guestagentapi.IPv4loopback1}
limayaml.FillPortForwardDefaults(&rule, inst.Dir)
rules = append(rules, rule)
}
{
rule := limayaml.PortForward{
HostIP: guestagentapi.IPv6loopback1,
GuestIP: guestagentapi.IPv6loopback1,
}
limayaml.FillPortForwardDefaults(&rule, inst.Dir)
rules = append(rules, rule)
}

limaDriver := driverutil.CreateTargetDriverInstance(&driver.BaseDriver{
Instance: inst,
Expand Down
2 changes: 1 addition & 1 deletion pkg/hostagent/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func hostAddress(rule limayaml.PortForward, guest api.IPPort) string {
return host.String()
}

func (pf *portForwarder) forwardingAddresses(guest api.IPPort) (string, string) {
func (pf *portForwarder) forwardingAddresses(guest api.IPPort) (hostAddr string, guestAddr string) {
for _, rule := range pf.rules {
if rule.GuestSocket != "" {
continue
Expand Down
67 changes: 49 additions & 18 deletions pkg/hostagent/port_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func forwardTCP(ctx context.Context, sshConfig *ssh.SSHConfig, port int, local,
return err
}

if !localIP.Equal(api.IPv4loopback1) || localPort >= 1024 {
if (!localIP.Equal(api.IPv4loopback1) && !localIP.Equal(net.IPv6loopback)) || localPort >= 1024 {
return forwardSSH(ctx, sshConfig, port, local, remote, verb, false)
}

Expand Down Expand Up @@ -86,9 +86,10 @@ func forwardTCP(ctx context.Context, sshConfig *ssh.SSHConfig, port int, local,
var pseudoLoopbackForwarders = make(map[string]*pseudoLoopbackForwarder)

type pseudoLoopbackForwarder struct {
ln *net.TCPListener
unixAddr *net.UnixAddr
onClose func() error
lns []*net.TCPListener
unixAddr *net.UnixAddr
onClose func() error
incomingConns chan *net.TCPConn
}

func newPseudoLoopbackForwarder(localPort int, unixSock string) (*pseudoLoopbackForwarder, error) {
Expand All @@ -97,38 +98,64 @@ func newPseudoLoopbackForwarder(localPort int, unixSock string) (*pseudoLoopback
return nil, err
}

lnAddr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("0.0.0.0:%d", localPort))
if err != nil {
return nil, err
toResolve := [][]string{
{"tcp4", fmt.Sprintf("0.0.0.0:%d", localPort)},
{"tcp6", fmt.Sprintf("[::]:%d", localPort)},
}
ln, err := net.ListenTCP("tcp4", lnAddr)
if err != nil {
return nil, err

var lns []*net.TCPListener
for _, addr := range toResolve {
network, address := addr[0], addr[1]
lnAddr, err := net.ResolveTCPAddr(network, address)
if err != nil {
return nil, err
}
ln, err := net.ListenTCP(network, lnAddr)
if err != nil {
return nil, err
}
lns = append(lns, ln)
}

plf := &pseudoLoopbackForwarder{
ln: ln,
unixAddr: unixAddr,
lns: lns,
incomingConns: make(chan *net.TCPConn, 10),
unixAddr: unixAddr,
}

return plf, nil
}

func (plf *pseudoLoopbackForwarder) Serve() error {
defer plf.ln.Close()
func (plf *pseudoLoopbackForwarder) acceptLn(ln *net.TCPListener) {
defer ln.Close()
for {
ac, err := plf.ln.AcceptTCP()
ac, err := ln.AcceptTCP()
if err != nil {
return err
logrus.WithError(err).Errorf("Stopping listening %#v", ln)
return
}
plf.incomingConns <- ac
}
}

func (plf *pseudoLoopbackForwarder) accept() {
for _, ln := range plf.lns {
go plf.acceptLn(ln)
}
}

func (plf *pseudoLoopbackForwarder) Serve() error {
plf.accept()

for ac := range plf.incomingConns {
remoteAddr := ac.RemoteAddr().String() // ip:port
remoteAddrIP, _, err := net.SplitHostPort(remoteAddr)
if err != nil {
logrus.WithError(err).Debugf("pseudoloopback forwarder: rejecting non-loopback remoteAddr %q (unparsable)", remoteAddr)
ac.Close()
continue
}
if remoteAddrIP != "127.0.0.1" {
if remoteAddrIP != "127.0.0.1" && remoteAddrIP != "::" {
logrus.WithError(err).Debugf("pseudoloopback forwarder: rejecting non-loopback remoteAddr %q", remoteAddr)
ac.Close()
continue
Expand All @@ -139,6 +166,8 @@ func (plf *pseudoLoopbackForwarder) Serve() error {
}
}(ac)
}

return nil
}

func (plf *pseudoLoopbackForwarder) forward(ac *net.TCPConn) error {
Expand All @@ -153,6 +182,8 @@ func (plf *pseudoLoopbackForwarder) forward(ac *net.TCPConn) error {
}

func (plf *pseudoLoopbackForwarder) Close() error {
_ = plf.ln.Close()
for _, ln := range plf.lns {
_ = ln.Close()
}
return plf.onClose()
}

0 comments on commit 17585c2

Please sign in to comment.