diff options
-rw-r--r-- | pkg/tcpip/link/rawfile/blockingpoll_amd64.s | 2 | ||||
-rw-r--r-- | pkg/tcpip/link/rawfile/blockingpoll_arm64.s | 2 | ||||
-rw-r--r-- | pkg/tcpip/link/rawfile/rawfile_unsafe.go | 16 | ||||
-rw-r--r-- | pkg/tcpip/transport/internal/network/endpoint.go | 23 | ||||
-rw-r--r-- | pkg/tcpip/transport/internal/network/network_state_autogen.go | 47 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 2 |
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, |