summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/transport')
-rw-r--r--pkg/tcpip/transport/icmp/endpoint.go22
-rw-r--r--pkg/tcpip/transport/icmp/icmp_state_autogen.go7
-rw-r--r--pkg/tcpip/transport/packet/endpoint.go23
-rw-r--r--pkg/tcpip/transport/packet/packet_state_autogen.go7
-rw-r--r--pkg/tcpip/transport/raw/endpoint.go23
-rw-r--r--pkg/tcpip/transport/raw/raw_state_autogen.go7
-rw-r--r--pkg/tcpip/transport/udp/endpoint.go13
-rw-r--r--pkg/tcpip/transport/udp/udp_state_autogen.go3
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)