Introduce tcpip.SockOptBool
...and port V6OnlyOption to it. PiperOrigin-RevId: 288789451
This commit is contained in:
parent
e21c584056
commit
d530df2f95
|
@ -222,6 +222,10 @@ type commonEndpoint interface {
|
|||
// transport.Endpoint.SetSockOpt.
|
||||
SetSockOpt(interface{}) *tcpip.Error
|
||||
|
||||
// SetSockOptBool implements tcpip.Endpoint.SetSockOptBool and
|
||||
// transport.Endpoint.SetSockOptBool.
|
||||
SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error
|
||||
|
||||
// SetSockOptInt implements tcpip.Endpoint.SetSockOptInt and
|
||||
// transport.Endpoint.SetSockOptInt.
|
||||
SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error
|
||||
|
@ -230,6 +234,10 @@ type commonEndpoint interface {
|
|||
// transport.Endpoint.GetSockOpt.
|
||||
GetSockOpt(interface{}) *tcpip.Error
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool and
|
||||
// transport.Endpoint.GetSockOpt.
|
||||
GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error)
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt and
|
||||
// transport.Endpoint.GetSockOpt.
|
||||
GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error)
|
||||
|
@ -1213,12 +1221,15 @@ func getSockOptIPv6(t *kernel.Task, ep commonEndpoint, name, outLen int) (interf
|
|||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var v tcpip.V6OnlyOption
|
||||
if err := ep.GetSockOpt(&v); err != nil {
|
||||
v, err := ep.GetSockOptBool(tcpip.V6OnlyOption)
|
||||
if err != nil {
|
||||
return nil, syserr.TranslateNetstackError(err)
|
||||
}
|
||||
|
||||
return int32(v), nil
|
||||
var o uint32
|
||||
if v {
|
||||
o = 1
|
||||
}
|
||||
return int32(o), nil
|
||||
|
||||
case linux.IPV6_PATHMTU:
|
||||
t.Kernel().EmitUnimplementedEvent(t)
|
||||
|
@ -1621,7 +1632,7 @@ func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte)
|
|||
}
|
||||
|
||||
v := usermem.ByteOrder.Uint32(optVal)
|
||||
return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.V6OnlyOption(v)))
|
||||
return syserr.TranslateNetstackError(ep.SetSockOptBool(tcpip.V6OnlyOption, v != 0))
|
||||
|
||||
case linux.IPV6_ADD_MEMBERSHIP,
|
||||
linux.IPV6_DROP_MEMBERSHIP,
|
||||
|
|
|
@ -175,6 +175,10 @@ type Endpoint interface {
|
|||
// types.
|
||||
SetSockOpt(opt interface{}) *tcpip.Error
|
||||
|
||||
// SetSockOptBool sets a socket option for simple cases when a value has
|
||||
// the int type.
|
||||
SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error
|
||||
|
||||
// SetSockOptInt sets a socket option for simple cases when a value has
|
||||
// the int type.
|
||||
SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error
|
||||
|
@ -183,6 +187,10 @@ type Endpoint interface {
|
|||
// tcpip.*Option types.
|
||||
GetSockOpt(opt interface{}) *tcpip.Error
|
||||
|
||||
// GetSockOptBool gets a socket option for simple cases when a return
|
||||
// value has the int type.
|
||||
GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error)
|
||||
|
||||
// GetSockOptInt gets a socket option for simple cases when a return
|
||||
// value has the int type.
|
||||
GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error)
|
||||
|
@ -851,10 +859,18 @@ func (e *baseEndpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (e *baseEndpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *baseEndpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *baseEndpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
func (e *baseEndpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
switch opt {
|
||||
case tcpip.ReceiveQueueSizeOption:
|
||||
|
|
|
@ -1701,9 +1701,8 @@ func addrForNewConnection(t *testing.T, s *stack.Stack) tcpip.Address {
|
|||
t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
|
||||
}
|
||||
defer ep.Close()
|
||||
v := tcpip.V6OnlyOption(1)
|
||||
if err := ep.SetSockOpt(v); err != nil {
|
||||
t.Fatalf("SetSockOpt(%+v): %s", v, err)
|
||||
if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
|
||||
t.Fatalf("SetSockOpt(tcpip.V6OnlyOption, true): %s", err)
|
||||
}
|
||||
if err := ep.Connect(dstAddr); err != nil {
|
||||
t.Fatalf("ep.Connect(%+v): %s", dstAddr, err)
|
||||
|
@ -1728,9 +1727,8 @@ func addrForNewConnectionWithAddr(t *testing.T, s *stack.Stack, addr tcpip.FullA
|
|||
t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
|
||||
}
|
||||
defer ep.Close()
|
||||
v := tcpip.V6OnlyOption(1)
|
||||
if err := ep.SetSockOpt(v); err != nil {
|
||||
t.Fatalf("SetSockOpt(%+v): %s", v, err)
|
||||
if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
|
||||
t.Fatalf("SetSockOpt(tcpip.V6OnlyOption, true): %s", err)
|
||||
}
|
||||
if err := ep.Bind(addr); err != nil {
|
||||
t.Fatalf("ep.Bind(%+v): %s", addr, err)
|
||||
|
@ -2066,9 +2064,8 @@ func TestAutoGenAddrTimerDeprecation(t *testing.T) {
|
|||
t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
|
||||
}
|
||||
defer ep.Close()
|
||||
v := tcpip.V6OnlyOption(1)
|
||||
if err := ep.SetSockOpt(v); err != nil {
|
||||
t.Fatalf("SetSockOpt(%+v): %s", v, err)
|
||||
if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
|
||||
t.Fatalf("SetSockOpt(tcpip.V6OnlyOption, true): %s", err)
|
||||
}
|
||||
|
||||
if err := ep.Connect(dstAddr); err != tcpip.ErrNoRoute {
|
||||
|
|
|
@ -61,11 +61,7 @@ func (c *testContext) createV6Endpoint(v6only bool) {
|
|||
c.t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
|
||||
var v tcpip.V6OnlyOption
|
||||
if v6only {
|
||||
v = 1
|
||||
}
|
||||
if err := c.ep.SetSockOpt(v); err != nil {
|
||||
if err := c.ep.SetSockOptBool(tcpip.V6OnlyOption, v6only); err != nil {
|
||||
c.t.Fatalf("SetSockOpt failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -201,54 +197,54 @@ func TestDistribution(t *testing.T) {
|
|||
"BindPortReuse",
|
||||
// 5 endpoints that all have reuse set.
|
||||
[]endpointSockopts{
|
||||
endpointSockopts{1, ""},
|
||||
endpointSockopts{1, ""},
|
||||
endpointSockopts{1, ""},
|
||||
endpointSockopts{1, ""},
|
||||
endpointSockopts{1, ""},
|
||||
{1, ""},
|
||||
{1, ""},
|
||||
{1, ""},
|
||||
{1, ""},
|
||||
{1, ""},
|
||||
},
|
||||
map[string][]float64{
|
||||
// Injected packets on dev0 get distributed evenly.
|
||||
"dev0": []float64{0.2, 0.2, 0.2, 0.2, 0.2},
|
||||
"dev0": {0.2, 0.2, 0.2, 0.2, 0.2},
|
||||
},
|
||||
},
|
||||
{
|
||||
"BindToDevice",
|
||||
// 3 endpoints with various bindings.
|
||||
[]endpointSockopts{
|
||||
endpointSockopts{0, "dev0"},
|
||||
endpointSockopts{0, "dev1"},
|
||||
endpointSockopts{0, "dev2"},
|
||||
{0, "dev0"},
|
||||
{0, "dev1"},
|
||||
{0, "dev2"},
|
||||
},
|
||||
map[string][]float64{
|
||||
// Injected packets on dev0 go only to the endpoint bound to dev0.
|
||||
"dev0": []float64{1, 0, 0},
|
||||
"dev0": {1, 0, 0},
|
||||
// Injected packets on dev1 go only to the endpoint bound to dev1.
|
||||
"dev1": []float64{0, 1, 0},
|
||||
"dev1": {0, 1, 0},
|
||||
// Injected packets on dev2 go only to the endpoint bound to dev2.
|
||||
"dev2": []float64{0, 0, 1},
|
||||
"dev2": {0, 0, 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
"ReuseAndBindToDevice",
|
||||
// 6 endpoints with various bindings.
|
||||
[]endpointSockopts{
|
||||
endpointSockopts{1, "dev0"},
|
||||
endpointSockopts{1, "dev0"},
|
||||
endpointSockopts{1, "dev1"},
|
||||
endpointSockopts{1, "dev1"},
|
||||
endpointSockopts{1, "dev1"},
|
||||
endpointSockopts{1, ""},
|
||||
{1, "dev0"},
|
||||
{1, "dev0"},
|
||||
{1, "dev1"},
|
||||
{1, "dev1"},
|
||||
{1, "dev1"},
|
||||
{1, ""},
|
||||
},
|
||||
map[string][]float64{
|
||||
// Injected packets on dev0 get distributed among endpoints bound to
|
||||
// dev0.
|
||||
"dev0": []float64{0.5, 0.5, 0, 0, 0, 0},
|
||||
"dev0": {0.5, 0.5, 0, 0, 0, 0},
|
||||
// Injected packets on dev1 get distributed among endpoints bound to
|
||||
// dev1 or unbound.
|
||||
"dev1": []float64{0, 0, 1. / 3, 1. / 3, 1. / 3, 0},
|
||||
"dev1": {0, 0, 1. / 3, 1. / 3, 1. / 3, 0},
|
||||
// Injected packets on dev999 go only to the unbound.
|
||||
"dev999": []float64{0, 0, 0, 0, 0, 1},
|
||||
"dev999": {0, 0, 0, 0, 0, 1},
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
|
|
@ -102,11 +102,21 @@ func (*fakeTransportEndpoint) SetSockOpt(interface{}) *tcpip.Error {
|
|||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
// SetSockOptBool sets a socket option. Currently not supported.
|
||||
func (*fakeTransportEndpoint) SetSockOptBool(tcpip.SockOptBool, bool) *tcpip.Error {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
// SetSockOptInt sets a socket option. Currently not supported.
|
||||
func (*fakeTransportEndpoint) SetSockOptInt(tcpip.SockOptInt, int) *tcpip.Error {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
|
||||
func (*fakeTransportEndpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (*fakeTransportEndpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
return -1, tcpip.ErrUnknownProtocolOption
|
||||
|
|
|
@ -423,6 +423,10 @@ type Endpoint interface {
|
|||
// SetSockOpt sets a socket option. opt should be one of the *Option types.
|
||||
SetSockOpt(opt interface{}) *Error
|
||||
|
||||
// SetSockOptBool sets a socket option, for simple cases where a value
|
||||
// has the bool type.
|
||||
SetSockOptBool(opt SockOptBool, v bool) *Error
|
||||
|
||||
// SetSockOptInt sets a socket option, for simple cases where a value
|
||||
// has the int type.
|
||||
SetSockOptInt(opt SockOptInt, v int) *Error
|
||||
|
@ -431,6 +435,10 @@ type Endpoint interface {
|
|||
// *Option types.
|
||||
GetSockOpt(opt interface{}) *Error
|
||||
|
||||
// GetSockOptBool gets a socket option for simple cases where a return
|
||||
// value has the bool type.
|
||||
GetSockOptBool(SockOptBool) (bool, *Error)
|
||||
|
||||
// GetSockOptInt gets a socket option for simple cases where a return
|
||||
// value has the int type.
|
||||
GetSockOptInt(SockOptInt) (int, *Error)
|
||||
|
@ -488,6 +496,15 @@ type WriteOptions struct {
|
|||
Atomic bool
|
||||
}
|
||||
|
||||
// SockOptBool represents socket options which values have the bool type.
|
||||
type SockOptBool int
|
||||
|
||||
const (
|
||||
// V6OnlyOption is used by {G,S}etSockOptBool to specify whether an IPv6
|
||||
// socket is to be restricted to sending and receiving IPv6 packets only.
|
||||
V6OnlyOption SockOptBool = iota
|
||||
)
|
||||
|
||||
// SockOptInt represents socket options which values have the int type.
|
||||
type SockOptInt int
|
||||
|
||||
|
@ -521,10 +538,6 @@ const (
|
|||
// the endpoint should be cleared and returned.
|
||||
type ErrorOption struct{}
|
||||
|
||||
// V6OnlyOption is used by SetSockOpt/GetSockOpt to specify whether an IPv6
|
||||
// socket is to be restricted to sending and receiving IPv6 packets only.
|
||||
type V6OnlyOption int
|
||||
|
||||
// CorkOption is used by SetSockOpt/GetSockOpt to specify if data should be
|
||||
// held until segments are full by the TCP transport protocol.
|
||||
type CorkOption int
|
||||
|
|
|
@ -350,11 +350,21 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SetSockOptBool sets a socket option. Currently not supported.
|
||||
func (e *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSockOptInt sets a socket option. Currently not supported.
|
||||
func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
|
||||
func (e *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
switch opt {
|
||||
|
|
|
@ -247,7 +247,12 @@ func (ep *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask {
|
|||
// used with SetSockOpt, and this function always returns
|
||||
// tcpip.ErrNotSupported.
|
||||
func (ep *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
||||
return tcpip.ErrNotSupported
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// SetSockOptBool implements tcpip.Endpoint.SetSockOptBool.
|
||||
func (ep *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// SetSockOptInt implements tcpip.Endpoint.SetSockOptInt.
|
||||
|
@ -255,16 +260,21 @@ func (ep *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
|||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (ep *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
return 0, tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
// GetSockOpt implements tcpip.Endpoint.GetSockOpt.
|
||||
func (ep *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
|
||||
return tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
|
||||
func (ep *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
return false, tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (ep *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
return 0, tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
// HandlePacket implements stack.PacketEndpoint.HandlePacket.
|
||||
func (ep *endpoint) HandlePacket(nicID tcpip.NICID, localAddr tcpip.LinkAddress, netProto tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
ep.rcvMu.Lock()
|
||||
|
|
|
@ -509,11 +509,36 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
|||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// SetSockOptBool implements tcpip.Endpoint.SetSockOptBool.
|
||||
func (e *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// SetSockOptInt implements tcpip.Endpoint.SetSockOptInt.
|
||||
func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOpt implements tcpip.Endpoint.GetSockOpt.
|
||||
func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
|
||||
switch o := opt.(type) {
|
||||
case tcpip.ErrorOption:
|
||||
return nil
|
||||
|
||||
case *tcpip.KeepaliveEnabledOption:
|
||||
*o = 0
|
||||
return nil
|
||||
|
||||
default:
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
}
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
|
||||
func (e *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
switch opt {
|
||||
|
@ -544,21 +569,6 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
|||
return -1, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOpt implements tcpip.Endpoint.GetSockOpt.
|
||||
func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
|
||||
switch o := opt.(type) {
|
||||
case tcpip.ErrorOption:
|
||||
return nil
|
||||
|
||||
case *tcpip.KeepaliveEnabledOption:
|
||||
*o = 0
|
||||
return nil
|
||||
|
||||
default:
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
}
|
||||
|
||||
// HandlePacket implements stack.RawTransportEndpoint.HandlePacket.
|
||||
func (e *endpoint) HandlePacket(route *stack.Route, pkt tcpip.PacketBuffer) {
|
||||
e.rcvMu.Lock()
|
||||
|
|
|
@ -391,9 +391,8 @@ func testV4Accept(t *testing.T, c *context.Context) {
|
|||
// Make sure we get the same error when calling the original ep and the
|
||||
// new one. This validates that v4-mapped endpoints are still able to
|
||||
// query the V6Only flag, whereas pure v4 endpoints are not.
|
||||
var v tcpip.V6OnlyOption
|
||||
expected := c.EP.GetSockOpt(&v)
|
||||
if err := nep.GetSockOpt(&v); err != expected {
|
||||
_, expected := c.EP.GetSockOptBool(tcpip.V6OnlyOption)
|
||||
if _, err := nep.GetSockOptBool(tcpip.V6OnlyOption); err != expected {
|
||||
t.Fatalf("GetSockOpt returned unexpected value: got %v, want %v", err, expected)
|
||||
}
|
||||
|
||||
|
@ -531,8 +530,7 @@ func TestV6AcceptOnV6(t *testing.T) {
|
|||
|
||||
// Make sure we can still query the v6 only status of the new endpoint,
|
||||
// that is, that it is in fact a v6 socket.
|
||||
var v tcpip.V6OnlyOption
|
||||
if err := nep.GetSockOpt(&v); err != nil {
|
||||
if _, err := nep.GetSockOptBool(tcpip.V6OnlyOption); err != nil {
|
||||
t.Fatalf("GetSockOpt failed failed: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1145,6 +1145,29 @@ func (e *endpoint) zeroReceiveWindow(scale uint8) bool {
|
|||
return ((e.rcvBufSize - e.rcvBufUsed) >> scale) == 0
|
||||
}
|
||||
|
||||
// SetSockOptBool sets a socket option.
|
||||
func (e *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
|
||||
switch opt {
|
||||
case tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
// We only allow this to be set when we're in the initial state.
|
||||
if e.state != StateInitial {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
e.v6only = v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSockOptInt sets a socket option.
|
||||
func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
||||
switch opt {
|
||||
|
@ -1289,23 +1312,6 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
|||
e.notifyProtocolGoroutine(notifyMSSChanged)
|
||||
return nil
|
||||
|
||||
case tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
// We only allow this to be set when we're in the initial state.
|
||||
if e.state != StateInitial {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
e.v6only = v != 0
|
||||
return nil
|
||||
|
||||
case tcpip.TTLOption:
|
||||
e.mu.Lock()
|
||||
e.ttl = uint8(v)
|
||||
|
@ -1446,6 +1452,25 @@ func (e *endpoint) readyReceiveSize() (int, *tcpip.Error) {
|
|||
return e.rcvBufUsed, nil
|
||||
}
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
|
||||
func (e *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
switch opt {
|
||||
case tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
v := e.v6only
|
||||
e.mu.Unlock()
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
switch opt {
|
||||
|
@ -1540,22 +1565,6 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
|
|||
}
|
||||
return nil
|
||||
|
||||
case *tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
v := e.v6only
|
||||
e.mu.Unlock()
|
||||
|
||||
*o = 0
|
||||
if v {
|
||||
*o = 1
|
||||
}
|
||||
return nil
|
||||
|
||||
case *tcpip.TTLOption:
|
||||
e.mu.Lock()
|
||||
*o = tcpip.TTLOption(e.ttl)
|
||||
|
|
|
@ -4028,12 +4028,12 @@ func TestConnectAvoidsBoundPorts(t *testing.T) {
|
|||
switch network {
|
||||
case "ipv4":
|
||||
case "ipv6":
|
||||
if err := ep.SetSockOpt(tcpip.V6OnlyOption(1)); err != nil {
|
||||
t.Fatalf("SetSockOpt(V6OnlyOption(1)) failed: %v", err)
|
||||
if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
|
||||
t.Fatalf("SetSockOpt(V6OnlyOption(true)) failed: %v", err)
|
||||
}
|
||||
case "dual":
|
||||
if err := ep.SetSockOpt(tcpip.V6OnlyOption(0)); err != nil {
|
||||
t.Fatalf("SetSockOpt(V6OnlyOption(0)) failed: %v", err)
|
||||
if err := ep.SetSockOptBool(tcpip.V6OnlyOption, false); err != nil {
|
||||
t.Fatalf("SetSockOpt(V6OnlyOption(false)) failed: %v", err)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("unknown network: '%s'", network)
|
||||
|
|
|
@ -475,11 +475,7 @@ func (c *Context) CreateV6Endpoint(v6only bool) {
|
|||
c.t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
|
||||
var v tcpip.V6OnlyOption
|
||||
if v6only {
|
||||
v = 1
|
||||
}
|
||||
if err := c.EP.SetSockOpt(v); err != nil {
|
||||
if err := c.EP.SetSockOptBool(tcpip.V6OnlyOption, v6only); err != nil {
|
||||
c.t.Fatalf("SetSockOpt failed failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -456,14 +456,9 @@ func (e *endpoint) Peek([][]byte) (int64, tcpip.ControlMessages, *tcpip.Error) {
|
|||
return 0, tcpip.ControlMessages{}, nil
|
||||
}
|
||||
|
||||
// SetSockOptInt implements tcpip.Endpoint.SetSockOptInt.
|
||||
func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSockOpt implements tcpip.Endpoint.SetSockOpt.
|
||||
func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
||||
switch v := opt.(type) {
|
||||
// SetSockOptBool implements tcpip.Endpoint.SetSockOptBool.
|
||||
func (e *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
|
||||
switch opt {
|
||||
case tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
|
@ -478,8 +473,20 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
|||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
e.v6only = v != 0
|
||||
e.v6only = v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSockOptInt implements tcpip.Endpoint.SetSockOptInt.
|
||||
func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSockOpt implements tcpip.Endpoint.SetSockOpt.
|
||||
func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
||||
switch v := opt.(type) {
|
||||
case tcpip.TTLOption:
|
||||
e.mu.Lock()
|
||||
e.ttl = uint8(v)
|
||||
|
@ -660,6 +667,25 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
|
||||
func (e *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
|
||||
switch opt {
|
||||
case tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
v := e.v6only
|
||||
e.mu.Unlock()
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return false, tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
|
||||
func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
|
||||
switch opt {
|
||||
|
@ -695,22 +721,6 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
|
|||
case tcpip.ErrorOption:
|
||||
return nil
|
||||
|
||||
case *tcpip.V6OnlyOption:
|
||||
// We only recognize this option on v6 endpoints.
|
||||
if e.NetProto != header.IPv6ProtocolNumber {
|
||||
return tcpip.ErrUnknownProtocolOption
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
v := e.v6only
|
||||
e.mu.Unlock()
|
||||
|
||||
*o = 0
|
||||
if v {
|
||||
*o = 1
|
||||
}
|
||||
return nil
|
||||
|
||||
case *tcpip.TTLOption:
|
||||
e.mu.Lock()
|
||||
*o = tcpip.TTLOption(e.ttl)
|
||||
|
|
|
@ -335,7 +335,7 @@ func (c *testContext) createEndpointForFlow(flow testFlow) {
|
|||
|
||||
c.createEndpoint(flow.sockProto())
|
||||
if flow.isV6Only() {
|
||||
if err := c.ep.SetSockOpt(tcpip.V6OnlyOption(1)); err != nil {
|
||||
if err := c.ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
|
||||
c.t.Fatalf("SetSockOpt failed: %v", err)
|
||||
}
|
||||
} else if flow.isBroadcast() {
|
||||
|
|
Loading…
Reference in New Issue