diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-10-21 20:58:49 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-10-21 20:58:49 +0000 |
commit | 87c093062bc55f6f6604d1f58c7aa365debc0605 (patch) | |
tree | 6efecfde0b6b9cd02a9b17f6aba650d41a13a26d | |
parent | f76a604701b6726e619652d424db4a78362494e0 (diff) | |
parent | 207221ffb27f2010c46468d827f1817432df3960 (diff) |
Merge release-20211011.0-39-g207221ffb (automated)
-rw-r--r-- | pkg/tcpip/adapters/gonet/gonet.go | 24 | ||||
-rw-r--r-- | pkg/tcpip/header/ipv4.go | 9 |
2 files changed, 28 insertions, 5 deletions
diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 010e2e833..1f2bcaf65 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -19,6 +19,7 @@ import ( "bytes" "context" "errors" + "fmt" "io" "net" "time" @@ -471,9 +472,9 @@ func DialTCP(s *stack.Stack, addr tcpip.FullAddress, network tcpip.NetworkProtoc return DialContextTCP(context.Background(), s, addr, network) } -// DialContextTCP creates a new TCPConn connected to the specified address -// with the option of adding cancellation and timeouts. -func DialContextTCP(ctx context.Context, s *stack.Stack, addr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*TCPConn, error) { +// DialTCPWithBind creates a new TCPConn connected to the specified +// remoteAddress with its local address bound to localAddr. +func DialTCPWithBind(ctx context.Context, s *stack.Stack, localAddr, remoteAddr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*TCPConn, error) { // Create TCP endpoint, then connect. var wq waiter.Queue ep, err := s.NewEndpoint(tcp.ProtocolNumber, network, &wq) @@ -494,7 +495,14 @@ func DialContextTCP(ctx context.Context, s *stack.Stack, addr tcpip.FullAddress, default: } - err = ep.Connect(addr) + // Bind before connect if requested. + if localAddr != (tcpip.FullAddress{}) { + if err = ep.Bind(localAddr); err != nil { + return nil, fmt.Errorf("ep.Bind(%+v) = %s", localAddr, err) + } + } + + err = ep.Connect(remoteAddr) if _, ok := err.(*tcpip.ErrConnectStarted); ok { select { case <-ctx.Done(): @@ -510,7 +518,7 @@ func DialContextTCP(ctx context.Context, s *stack.Stack, addr tcpip.FullAddress, return nil, &net.OpError{ Op: "connect", Net: "tcp", - Addr: fullToTCPAddr(addr), + Addr: fullToTCPAddr(remoteAddr), Err: errors.New(err.String()), } } @@ -518,6 +526,12 @@ func DialContextTCP(ctx context.Context, s *stack.Stack, addr tcpip.FullAddress, return NewTCPConn(&wq, ep), nil } +// DialContextTCP creates a new TCPConn connected to the specified address +// with the option of adding cancellation and timeouts. +func DialContextTCP(ctx context.Context, s *stack.Stack, addr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*TCPConn, error) { + return DialTCPWithBind(ctx, s, tcpip.FullAddress{} /* localAddr */, addr /* remoteAddr */, network) +} + // A UDPConn is a wrapper around a UDP tcpip.Endpoint that implements // net.Conn and net.PacketConn. type UDPConn struct { diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index dcc549c7b..7baaf0d17 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -208,6 +208,15 @@ var IPv4EmptySubnet = func() tcpip.Subnet { return subnet }() +// IPv4LoopbackSubnet is the loopback subnet for IPv4. +var IPv4LoopbackSubnet = func() tcpip.Subnet { + subnet, err := tcpip.NewSubnet(tcpip.Address("\x7f\x00\x00\x00"), tcpip.AddressMask("\xff\x00\x00\x00")) + if err != nil { + panic(err) + } + return subnet +}() + // IPVersion returns the version of IP used in the given packet. It returns -1 // if the packet is not large enough to contain the version field. func IPVersion(b []byte) int { |