summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2021-10-21 20:58:49 +0000
committergVisor bot <gvisor-bot@google.com>2021-10-21 20:58:49 +0000
commit87c093062bc55f6f6604d1f58c7aa365debc0605 (patch)
tree6efecfde0b6b9cd02a9b17f6aba650d41a13a26d
parentf76a604701b6726e619652d424db4a78362494e0 (diff)
parent207221ffb27f2010c46468d827f1817432df3960 (diff)
Merge release-20211011.0-39-g207221ffb (automated)
-rw-r--r--pkg/tcpip/adapters/gonet/gonet.go24
-rw-r--r--pkg/tcpip/header/ipv4.go9
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 {