Internal change.

PiperOrigin-RevId: 312559963
This commit is contained in:
gVisor bot
2020-05-20 14:57:59 -07:00
parent 76369b6480
commit a338eed1d8
5 changed files with 117 additions and 68 deletions
+65
View File
@@ -110,6 +110,71 @@ var (
ErrAddressFamilyNotSupported = &Error{msg: "address family not supported by protocol"}
)
var messageToError map[string]*Error
var populate sync.Once
// StringToError converts an error message to the error.
func StringToError(s string) *Error {
populate.Do(func() {
var errors = []*Error{
ErrUnknownProtocol,
ErrUnknownNICID,
ErrUnknownDevice,
ErrUnknownProtocolOption,
ErrDuplicateNICID,
ErrDuplicateAddress,
ErrNoRoute,
ErrBadLinkEndpoint,
ErrAlreadyBound,
ErrInvalidEndpointState,
ErrAlreadyConnecting,
ErrAlreadyConnected,
ErrNoPortAvailable,
ErrPortInUse,
ErrBadLocalAddress,
ErrClosedForSend,
ErrClosedForReceive,
ErrWouldBlock,
ErrConnectionRefused,
ErrTimeout,
ErrAborted,
ErrConnectStarted,
ErrDestinationRequired,
ErrNotSupported,
ErrQueueSizeNotSupported,
ErrNotConnected,
ErrConnectionReset,
ErrConnectionAborted,
ErrNoSuchFile,
ErrInvalidOptionValue,
ErrNoLinkAddress,
ErrBadAddress,
ErrNetworkUnreachable,
ErrMessageTooLong,
ErrNoBufferSpace,
ErrBroadcastDisabled,
ErrNotPermitted,
ErrAddressFamilyNotSupported,
}
messageToError = make(map[string]*Error)
for _, e := range errors {
if messageToError[e.String()] != nil {
panic("tcpip errors with duplicated message: " + e.String())
}
messageToError[e.String()] = e
}
})
e, ok := messageToError[s]
if !ok {
panic("unknown error message: " + s)
}
return e
}
// Errors related to Subnet
var (
errSubnetLengthMismatch = errors.New("subnet length of address and mask differ")
+2 -66
View File
@@ -314,7 +314,7 @@ func (e *endpoint) loadLastError(s string) {
return
}
e.lastError = loadError(s)
e.lastError = tcpip.StringToError(s)
}
// saveHardError is invoked by stateify.
@@ -332,71 +332,7 @@ func (e *EndpointInfo) loadHardError(s string) {
return
}
e.HardError = loadError(s)
}
var messageToError map[string]*tcpip.Error
var populate sync.Once
func loadError(s string) *tcpip.Error {
populate.Do(func() {
var errors = []*tcpip.Error{
tcpip.ErrUnknownProtocol,
tcpip.ErrUnknownNICID,
tcpip.ErrUnknownDevice,
tcpip.ErrUnknownProtocolOption,
tcpip.ErrDuplicateNICID,
tcpip.ErrDuplicateAddress,
tcpip.ErrNoRoute,
tcpip.ErrBadLinkEndpoint,
tcpip.ErrAlreadyBound,
tcpip.ErrInvalidEndpointState,
tcpip.ErrAlreadyConnecting,
tcpip.ErrAlreadyConnected,
tcpip.ErrNoPortAvailable,
tcpip.ErrPortInUse,
tcpip.ErrBadLocalAddress,
tcpip.ErrClosedForSend,
tcpip.ErrClosedForReceive,
tcpip.ErrWouldBlock,
tcpip.ErrConnectionRefused,
tcpip.ErrTimeout,
tcpip.ErrAborted,
tcpip.ErrConnectStarted,
tcpip.ErrDestinationRequired,
tcpip.ErrNotSupported,
tcpip.ErrQueueSizeNotSupported,
tcpip.ErrNotConnected,
tcpip.ErrConnectionReset,
tcpip.ErrConnectionAborted,
tcpip.ErrNoSuchFile,
tcpip.ErrInvalidOptionValue,
tcpip.ErrNoLinkAddress,
tcpip.ErrBadAddress,
tcpip.ErrNetworkUnreachable,
tcpip.ErrMessageTooLong,
tcpip.ErrNoBufferSpace,
tcpip.ErrBroadcastDisabled,
tcpip.ErrNotPermitted,
tcpip.ErrAddressFamilyNotSupported,
}
messageToError = make(map[string]*tcpip.Error)
for _, e := range errors {
if messageToError[e.String()] != nil {
panic("tcpip errors with duplicated message: " + e.String())
}
messageToError[e.String()] = e
}
})
e, ok := messageToError[s]
if !ok {
panic("unknown error message: " + s)
}
return e
e.HardError = tcpip.StringToError(s)
}
// saveMeasureTime is invoked by stateify.
+32
View File
@@ -106,6 +106,9 @@ type endpoint struct {
bindToDevice tcpip.NICID
broadcast bool
lastErrorMu sync.Mutex `state:"nosave"`
lastError *tcpip.Error `state:".(string)"`
// Values used to reserve a port or register a transport endpoint.
// (which ever happens first).
boundBindToDevice tcpip.NICID
@@ -188,6 +191,15 @@ func (e *endpoint) UniqueID() uint64 {
return e.uniqueID
}
func (e *endpoint) takeLastError() *tcpip.Error {
e.lastErrorMu.Lock()
defer e.lastErrorMu.Unlock()
err := e.lastError
e.lastError = nil
return err
}
// Abort implements stack.TransportEndpoint.Abort.
func (e *endpoint) Abort() {
e.Close()
@@ -243,6 +255,10 @@ func (e *endpoint) IPTables() (stack.IPTables, error) {
// Read reads data from the endpoint. This method does not block if
// there is no data pending.
func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) {
if err := e.takeLastError(); err != nil {
return buffer.View{}, tcpip.ControlMessages{}, err
}
e.rcvMu.Lock()
if e.rcvList.Empty() {
@@ -382,6 +398,10 @@ func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-c
}
func (e *endpoint) write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-chan struct{}, *tcpip.Error) {
if err := e.takeLastError(); err != nil {
return 0, nil, err
}
// MSG_MORE is unimplemented. (This also means that MSG_EOR is a no-op.)
if opts.More {
return 0, nil, tcpip.ErrInvalidOptionValue
@@ -853,6 +873,7 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
switch o := opt.(type) {
case tcpip.ErrorOption:
return e.takeLastError()
case *tcpip.MulticastInterfaceOption:
e.mu.Lock()
*o = tcpip.MulticastInterfaceOption{
@@ -1316,6 +1337,17 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, pk
// HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket.
func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, pkt stack.PacketBuffer) {
if typ == stack.ControlPortUnreachable {
e.mu.RLock()
defer e.mu.RUnlock()
if e.state == StateConnected {
e.lastErrorMu.Lock()
defer e.lastErrorMu.Unlock()
e.lastError = tcpip.ErrConnectionRefused
}
}
}
// State implements tcpip.Endpoint.State.
+18
View File
@@ -37,6 +37,24 @@ func (u *udpPacket) loadData(data buffer.VectorisedView) {
u.data = data
}
// saveLastError is invoked by stateify.
func (e *endpoint) saveLastError() string {
if e.lastError == nil {
return ""
}
return e.lastError.String()
}
// loadLastError is invoked by stateify.
func (e *endpoint) loadLastError(s string) {
if s == "" {
return
}
e.lastError = tcpip.StringToError(s)
}
// beforeSave is invoked by stateify.
func (e *endpoint) beforeSave() {
// Stop incoming packets from being handled (and mutate endpoint state).
-2
View File
@@ -31,8 +31,6 @@ packetimpact_go_test(
packetimpact_go_test(
name = "udp_icmp_error_propagation",
srcs = ["udp_icmp_error_propagation_test.go"],
# TODO(b/153926291): Fix netstack then remove the line below.
expect_netstack_failure = True,
deps = [
"//pkg/tcpip",
"//pkg/tcpip/header",