diff options
Diffstat (limited to 'pkg/tcpip/transport')
-rw-r--r-- | pkg/tcpip/transport/icmp/endpoint.go | 22 | ||||
-rw-r--r-- | pkg/tcpip/transport/icmp/icmp_state_autogen.go | 7 | ||||
-rw-r--r-- | pkg/tcpip/transport/packet/endpoint.go | 23 | ||||
-rw-r--r-- | pkg/tcpip/transport/packet/packet_state_autogen.go | 7 | ||||
-rw-r--r-- | pkg/tcpip/transport/raw/endpoint.go | 23 | ||||
-rw-r--r-- | pkg/tcpip/transport/raw/raw_state_autogen.go | 7 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 13 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/udp_state_autogen.go | 3 |
8 files changed, 90 insertions, 15 deletions
diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index ad71ff3b6..31116309e 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -74,6 +74,8 @@ type endpoint struct { route stack.Route `state:"manual"` ttl uint8 stats tcpip.TransportEndpointStats `state:"nosave"` + // linger is used for SO_LINGER socket option. + linger tcpip.LingerOption // owner is used to get uid and gid of the packet. owner tcpip.PacketOwner @@ -344,9 +346,14 @@ func (e *endpoint) Peek([][]byte) (int64, tcpip.ControlMessages, *tcpip.Error) { // SetSockOpt sets a socket option. func (e *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) *tcpip.Error { - switch opt.(type) { + switch v := opt.(type) { case *tcpip.SocketDetachFilterOption: return nil + + case *tcpip.LingerOption: + e.mu.Lock() + e.linger = *v + e.mu.Unlock() } return nil } @@ -415,8 +422,17 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) { } // GetSockOpt implements tcpip.Endpoint.GetSockOpt. -func (*endpoint) GetSockOpt(tcpip.GettableSocketOption) *tcpip.Error { - return tcpip.ErrUnknownProtocolOption +func (e *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) *tcpip.Error { + switch o := opt.(type) { + case *tcpip.LingerOption: + e.mu.Lock() + *o = e.linger + e.mu.Unlock() + return nil + + default: + return tcpip.ErrUnknownProtocolOption + } } func send4(r *stack.Route, ident uint16, data buffer.View, ttl uint8, owner tcpip.PacketOwner) *tcpip.Error { diff --git a/pkg/tcpip/transport/icmp/icmp_state_autogen.go b/pkg/tcpip/transport/icmp/icmp_state_autogen.go index c6b278677..776ef0850 100644 --- a/pkg/tcpip/transport/icmp/icmp_state_autogen.go +++ b/pkg/tcpip/transport/icmp/icmp_state_autogen.go @@ -58,6 +58,7 @@ func (x *endpoint) StateFields() []string { "shutdownFlags", "state", "ttl", + "linger", "owner", } } @@ -77,7 +78,8 @@ func (x *endpoint) StateSave(m state.Sink) { m.Save(9, &x.shutdownFlags) m.Save(10, &x.state) m.Save(11, &x.ttl) - m.Save(12, &x.owner) + m.Save(12, &x.linger) + m.Save(13, &x.owner) } func (x *endpoint) StateLoad(m state.Source) { @@ -92,7 +94,8 @@ func (x *endpoint) StateLoad(m state.Source) { m.Load(9, &x.shutdownFlags) m.Load(10, &x.state) m.Load(11, &x.ttl) - m.Load(12, &x.owner) + m.Load(12, &x.linger) + m.Load(13, &x.owner) m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) m.AfterLoad(x.afterLoad) } diff --git a/pkg/tcpip/transport/packet/endpoint.go b/pkg/tcpip/transport/packet/endpoint.go index 8bd4e5e37..072601d2d 100644 --- a/pkg/tcpip/transport/packet/endpoint.go +++ b/pkg/tcpip/transport/packet/endpoint.go @@ -83,6 +83,8 @@ type endpoint struct { stats tcpip.TransportEndpointStats `state:"nosave"` bound bool boundNIC tcpip.NICID + // linger is used for SO_LINGER socket option. + linger tcpip.LingerOption // lastErrorMu protects lastError. lastErrorMu sync.Mutex `state:"nosave"` @@ -298,10 +300,16 @@ func (ep *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // used with SetSockOpt, and this function always returns // tcpip.ErrNotSupported. func (ep *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) *tcpip.Error { - switch opt.(type) { + switch v := opt.(type) { case *tcpip.SocketDetachFilterOption: return nil + case *tcpip.LingerOption: + ep.mu.Lock() + ep.linger = *v + ep.mu.Unlock() + return nil + default: return tcpip.ErrUnknownProtocolOption } @@ -366,8 +374,17 @@ func (ep *endpoint) LastError() *tcpip.Error { } // GetSockOpt implements tcpip.Endpoint.GetSockOpt. -func (*endpoint) GetSockOpt(tcpip.GettableSocketOption) *tcpip.Error { - return tcpip.ErrNotSupported +func (ep *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) *tcpip.Error { + switch o := opt.(type) { + case *tcpip.LingerOption: + ep.mu.Lock() + *o = ep.linger + ep.mu.Unlock() + return nil + + default: + return tcpip.ErrNotSupported + } } // GetSockOptBool implements tcpip.Endpoint.GetSockOptBool. diff --git a/pkg/tcpip/transport/packet/packet_state_autogen.go b/pkg/tcpip/transport/packet/packet_state_autogen.go index e13dd7827..5edd9db89 100644 --- a/pkg/tcpip/transport/packet/packet_state_autogen.go +++ b/pkg/tcpip/transport/packet/packet_state_autogen.go @@ -62,6 +62,7 @@ func (x *endpoint) StateFields() []string { "closed", "bound", "boundNIC", + "linger", "lastError", } } @@ -71,7 +72,7 @@ func (x *endpoint) StateSave(m state.Sink) { var rcvBufSizeMax int = x.saveRcvBufSizeMax() m.SaveValue(5, rcvBufSizeMax) var lastError string = x.saveLastError() - m.SaveValue(13, lastError) + m.SaveValue(14, lastError) m.Save(0, &x.TransportEndpointInfo) m.Save(1, &x.netProto) m.Save(2, &x.waiterQueue) @@ -84,6 +85,7 @@ func (x *endpoint) StateSave(m state.Sink) { m.Save(10, &x.closed) m.Save(11, &x.bound) m.Save(12, &x.boundNIC) + m.Save(13, &x.linger) } func (x *endpoint) StateLoad(m state.Source) { @@ -99,8 +101,9 @@ func (x *endpoint) StateLoad(m state.Source) { m.Load(10, &x.closed) m.Load(11, &x.bound) m.Load(12, &x.boundNIC) + m.Load(13, &x.linger) m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) - m.LoadValue(13, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) + m.LoadValue(14, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) m.AfterLoad(x.afterLoad) } diff --git a/pkg/tcpip/transport/raw/endpoint.go b/pkg/tcpip/transport/raw/endpoint.go index fb03e6047..e37c00523 100644 --- a/pkg/tcpip/transport/raw/endpoint.go +++ b/pkg/tcpip/transport/raw/endpoint.go @@ -84,6 +84,8 @@ type endpoint struct { // Connect(), and is valid only when conneted is true. route stack.Route `state:"manual"` stats tcpip.TransportEndpointStats `state:"nosave"` + // linger is used for SO_LINGER socket option. + linger tcpip.LingerOption // owner is used to get uid and gid of the packet. owner tcpip.PacketOwner @@ -511,10 +513,16 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // SetSockOpt implements tcpip.Endpoint.SetSockOpt. func (e *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) *tcpip.Error { - switch opt.(type) { + switch v := opt.(type) { case *tcpip.SocketDetachFilterOption: return nil + case *tcpip.LingerOption: + e.mu.Lock() + e.linger = *v + e.mu.Unlock() + return nil + default: return tcpip.ErrUnknownProtocolOption } @@ -577,8 +585,17 @@ func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error { } // GetSockOpt implements tcpip.Endpoint.GetSockOpt. -func (*endpoint) GetSockOpt(tcpip.GettableSocketOption) *tcpip.Error { - return tcpip.ErrUnknownProtocolOption +func (e *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) *tcpip.Error { + switch o := opt.(type) { + case *tcpip.LingerOption: + e.mu.Lock() + *o = e.linger + e.mu.Unlock() + return nil + + default: + return tcpip.ErrUnknownProtocolOption + } } // GetSockOptBool implements tcpip.Endpoint.GetSockOptBool. diff --git a/pkg/tcpip/transport/raw/raw_state_autogen.go b/pkg/tcpip/transport/raw/raw_state_autogen.go index 853d60959..4930b46f4 100644 --- a/pkg/tcpip/transport/raw/raw_state_autogen.go +++ b/pkg/tcpip/transport/raw/raw_state_autogen.go @@ -59,6 +59,7 @@ func (x *endpoint) StateFields() []string { "closed", "connected", "bound", + "linger", "owner", } } @@ -79,7 +80,8 @@ func (x *endpoint) StateSave(m state.Sink) { m.Save(10, &x.closed) m.Save(11, &x.connected) m.Save(12, &x.bound) - m.Save(13, &x.owner) + m.Save(13, &x.linger) + m.Save(14, &x.owner) } func (x *endpoint) StateLoad(m state.Source) { @@ -95,7 +97,8 @@ func (x *endpoint) StateLoad(m state.Source) { m.Load(10, &x.closed) m.Load(11, &x.connected) m.Load(12, &x.bound) - m.Load(13, &x.owner) + m.Load(13, &x.linger) + m.Load(14, &x.owner) m.LoadValue(6, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) m.AfterLoad(x.afterLoad) } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index b572c39db..518f636f0 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -154,6 +154,9 @@ type endpoint struct { // owner is used to get uid and gid of the packet. owner tcpip.PacketOwner + + // linger is used for SO_LINGER socket option. + linger tcpip.LingerOption } // +stateify savable @@ -810,6 +813,11 @@ func (e *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) *tcpip.Error { case *tcpip.SocketDetachFilterOption: return nil + + case *tcpip.LingerOption: + e.mu.Lock() + e.linger = *v + e.mu.Unlock() } return nil } @@ -966,6 +974,11 @@ func (e *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) *tcpip.Error { *o = tcpip.BindToDeviceOption(e.bindToDevice) e.mu.RUnlock() + case *tcpip.LingerOption: + e.mu.RLock() + *o = e.linger + e.mu.RUnlock() + default: return tcpip.ErrUnknownProtocolOption } diff --git a/pkg/tcpip/transport/udp/udp_state_autogen.go b/pkg/tcpip/transport/udp/udp_state_autogen.go index 50fd0f186..ce3b1df48 100644 --- a/pkg/tcpip/transport/udp/udp_state_autogen.go +++ b/pkg/tcpip/transport/udp/udp_state_autogen.go @@ -85,6 +85,7 @@ func (x *endpoint) StateFields() []string { "multicastMemberships", "effectiveNetProtos", "owner", + "linger", } } @@ -125,6 +126,7 @@ func (x *endpoint) StateSave(m state.Sink) { m.Save(30, &x.multicastMemberships) m.Save(31, &x.effectiveNetProtos) m.Save(32, &x.owner) + m.Save(33, &x.linger) } func (x *endpoint) StateLoad(m state.Source) { @@ -159,6 +161,7 @@ func (x *endpoint) StateLoad(m state.Source) { m.Load(30, &x.multicastMemberships) m.Load(31, &x.effectiveNetProtos) m.Load(32, &x.owner) + m.Load(33, &x.linger) m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) m.LoadValue(22, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) m.AfterLoad(x.afterLoad) |