summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/tcpip/link/rawfile/blockingpoll_amd64.s2
-rw-r--r--pkg/tcpip/link/rawfile/blockingpoll_arm64.s2
-rw-r--r--pkg/tcpip/link/rawfile/rawfile_unsafe.go16
-rw-r--r--pkg/tcpip/transport/internal/network/endpoint.go23
-rw-r--r--pkg/tcpip/transport/internal/network/network_state_autogen.go47
-rw-r--r--pkg/tcpip/transport/udp/endpoint.go2
6 files changed, 61 insertions, 31 deletions
diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s
index 298bad55d..f2c230720 100644
--- a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s
+++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s
@@ -27,7 +27,7 @@ TEXT ·BlockingPoll(SB),NOSPLIT,$0-40
MOVQ $0x0, R10 // sigmask parameter which isn't used here
MOVQ $0x10f, AX // SYS_PPOLL
SYSCALL
- CMPQ AX, $0xfffffffffffff001
+ CMPQ AX, $0xfffffffffffff002
JLS ok
MOVQ $-1, n+24(FP)
NEGQ AX
diff --git a/pkg/tcpip/link/rawfile/blockingpoll_arm64.s b/pkg/tcpip/link/rawfile/blockingpoll_arm64.s
index b62888b93..8807586c7 100644
--- a/pkg/tcpip/link/rawfile/blockingpoll_arm64.s
+++ b/pkg/tcpip/link/rawfile/blockingpoll_arm64.s
@@ -27,7 +27,7 @@ TEXT ·BlockingPoll(SB),NOSPLIT,$0-40
MOVD $0x0, R3 // sigmask parameter which isn't used here
MOVD $0x49, R8 // SYS_PPOLL
SVC
- CMP $0xfffffffffffff001, R0
+ CMP $0xfffffffffffff002, R0
BLS ok
MOVD $-1, R1
MOVD R1, n+24(FP)
diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go
index e76fc55b6..87a0b9a62 100644
--- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go
+++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go
@@ -181,7 +181,9 @@ func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, tcpip
if e == 0 {
return int(n), nil
}
-
+ if e != 0 && e != unix.EWOULDBLOCK {
+ return 0, TranslateErrno(e)
+ }
stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN)
if stopped {
return -1, nil
@@ -204,6 +206,10 @@ func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MMsgHdr) (int, tcpi
return int(n), nil
}
+ if e != 0 && e != unix.EWOULDBLOCK {
+ return 0, TranslateErrno(e)
+ }
+
stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN)
if stopped {
return -1, nil
@@ -228,5 +234,13 @@ func BlockingPollUntilStopped(efd int, fd int, events int16) (bool, unix.Errno)
},
}
_, errno := BlockingPoll(&pevents[0], len(pevents), nil)
+ if errno != 0 {
+ return pevents[0].Revents&unix.POLLIN != 0, errno
+ }
+
+ if pevents[1].Revents&unix.POLLHUP != 0 || pevents[1].Revents&unix.POLLERR != 0 {
+ errno = unix.ECONNRESET
+ }
+
return pevents[0].Revents&unix.POLLIN != 0, errno
}
diff --git a/pkg/tcpip/transport/internal/network/endpoint.go b/pkg/tcpip/transport/internal/network/endpoint.go
index c5b575e1c..09b629022 100644
--- a/pkg/tcpip/transport/internal/network/endpoint.go
+++ b/pkg/tcpip/transport/internal/network/endpoint.go
@@ -44,8 +44,9 @@ type Endpoint struct {
state uint32
// The following fields are protected by mu.
- mu sync.RWMutex `state:"nosave"`
- info stack.TransportEndpointInfo
+ mu sync.RWMutex `state:"nosave"`
+ wasBound bool
+ info stack.TransportEndpointInfo
// owner is the owner of transmitted packets.
owner tcpip.PacketOwner
writeShutdown bool
@@ -248,6 +249,9 @@ func (e *Endpoint) AcquireContextForWrite(opts tcpip.WriteOptions) (WriteContext
nicID = e.info.BindNICID
}
+ if nicID == 0 {
+ nicID = e.info.RegisterNICID
+ }
dst, netProto, err := e.checkV4MappedLocked(*opts.To)
if err != nil {
@@ -294,9 +298,9 @@ func (e *Endpoint) Disconnect() {
}
// Exclude ephemerally bound endpoints.
- if e.info.BindNICID != 0 || e.info.ID.LocalAddress == "" {
+ if e.wasBound {
e.info.ID = stack.TransportEndpointID{
- LocalAddress: e.info.ID.LocalAddress,
+ LocalAddress: e.info.BindAddr,
}
e.setEndpointState(transport.DatagramEndpointStateBound)
} else {
@@ -477,10 +481,12 @@ func (e *Endpoint) BindAndThen(addr tcpip.FullAddress, f func(tcpip.NetworkProto
return err
}
+ e.wasBound = true
+
e.info.ID = stack.TransportEndpointID{
LocalAddress: addr.Addr,
}
- e.info.BindNICID = nicID
+ e.info.BindNICID = addr.NIC
e.info.RegisterNICID = nicID
e.info.BindAddr = addr.Addr
e.effectiveNetProto = netProto
@@ -488,6 +494,13 @@ func (e *Endpoint) BindAndThen(addr tcpip.FullAddress, f func(tcpip.NetworkProto
return nil
}
+// WasBound returns true iff the endpoint was ever bound.
+func (e *Endpoint) WasBound() bool {
+ e.mu.RLock()
+ defer e.mu.RUnlock()
+ return e.wasBound
+}
+
// GetLocalAddress returns the address that the endpoint is bound to.
func (e *Endpoint) GetLocalAddress() tcpip.FullAddress {
e.mu.RLock()
diff --git a/pkg/tcpip/transport/internal/network/network_state_autogen.go b/pkg/tcpip/transport/internal/network/network_state_autogen.go
index 0ce695bb8..f72149c1c 100644
--- a/pkg/tcpip/transport/internal/network/network_state_autogen.go
+++ b/pkg/tcpip/transport/internal/network/network_state_autogen.go
@@ -16,6 +16,7 @@ func (e *Endpoint) StateFields() []string {
"netProto",
"transProto",
"state",
+ "wasBound",
"info",
"owner",
"writeShutdown",
@@ -39,17 +40,18 @@ func (e *Endpoint) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(1, &e.netProto)
stateSinkObject.Save(2, &e.transProto)
stateSinkObject.Save(3, &e.state)
- stateSinkObject.Save(4, &e.info)
- stateSinkObject.Save(5, &e.owner)
- stateSinkObject.Save(6, &e.writeShutdown)
- stateSinkObject.Save(7, &e.effectiveNetProto)
- stateSinkObject.Save(8, &e.multicastMemberships)
- stateSinkObject.Save(9, &e.ttl)
- stateSinkObject.Save(10, &e.multicastTTL)
- stateSinkObject.Save(11, &e.multicastAddr)
- stateSinkObject.Save(12, &e.multicastNICID)
- stateSinkObject.Save(13, &e.ipv4TOS)
- stateSinkObject.Save(14, &e.ipv6TClass)
+ stateSinkObject.Save(4, &e.wasBound)
+ stateSinkObject.Save(5, &e.info)
+ stateSinkObject.Save(6, &e.owner)
+ stateSinkObject.Save(7, &e.writeShutdown)
+ stateSinkObject.Save(8, &e.effectiveNetProto)
+ stateSinkObject.Save(9, &e.multicastMemberships)
+ stateSinkObject.Save(10, &e.ttl)
+ stateSinkObject.Save(11, &e.multicastTTL)
+ stateSinkObject.Save(12, &e.multicastAddr)
+ stateSinkObject.Save(13, &e.multicastNICID)
+ stateSinkObject.Save(14, &e.ipv4TOS)
+ stateSinkObject.Save(15, &e.ipv6TClass)
}
func (e *Endpoint) afterLoad() {}
@@ -60,17 +62,18 @@ func (e *Endpoint) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(1, &e.netProto)
stateSourceObject.Load(2, &e.transProto)
stateSourceObject.Load(3, &e.state)
- stateSourceObject.Load(4, &e.info)
- stateSourceObject.Load(5, &e.owner)
- stateSourceObject.Load(6, &e.writeShutdown)
- stateSourceObject.Load(7, &e.effectiveNetProto)
- stateSourceObject.Load(8, &e.multicastMemberships)
- stateSourceObject.Load(9, &e.ttl)
- stateSourceObject.Load(10, &e.multicastTTL)
- stateSourceObject.Load(11, &e.multicastAddr)
- stateSourceObject.Load(12, &e.multicastNICID)
- stateSourceObject.Load(13, &e.ipv4TOS)
- stateSourceObject.Load(14, &e.ipv6TClass)
+ stateSourceObject.Load(4, &e.wasBound)
+ stateSourceObject.Load(5, &e.info)
+ stateSourceObject.Load(6, &e.owner)
+ stateSourceObject.Load(7, &e.writeShutdown)
+ stateSourceObject.Load(8, &e.effectiveNetProto)
+ stateSourceObject.Load(9, &e.multicastMemberships)
+ stateSourceObject.Load(10, &e.ttl)
+ stateSourceObject.Load(11, &e.multicastTTL)
+ stateSourceObject.Load(12, &e.multicastAddr)
+ stateSourceObject.Load(13, &e.multicastNICID)
+ stateSourceObject.Load(14, &e.ipv4TOS)
+ stateSourceObject.Load(15, &e.ipv6TClass)
}
func (m *multicastMembership) StateTypeName() string {
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go
index f171a16f8..4255457f9 100644
--- a/pkg/tcpip/transport/udp/endpoint.go
+++ b/pkg/tcpip/transport/udp/endpoint.go
@@ -547,7 +547,7 @@ func (e *endpoint) Disconnect() tcpip.Error {
info := e.net.Info()
info.ID.LocalPort = e.localPort
info.ID.RemotePort = e.remotePort
- if info.BindNICID != 0 || info.ID.LocalAddress == "" {
+ if e.net.WasBound() {
var err tcpip.Error
id = stack.TransportEndpointID{
LocalPort: info.ID.LocalPort,