Jelajahi Sumber

Enhance TCP Fast Open (#310)

risetechlab 4 tahun lalu
induk
melakukan
ad1807dd99

+ 21 - 10
infra/conf/transport_internet.go

@@ -2,6 +2,7 @@ package conf
 
 import (
 	"encoding/json"
+	"math"
 	"strings"
 
 	"github.com/golang/protobuf/proto"
@@ -450,20 +451,30 @@ func (p TransportProtocol) Build() (string, error) {
 }
 
 type SocketConfig struct {
-	Mark                int32  `json:"mark"`
-	TFO                 *bool  `json:"tcpFastOpen"`
-	TProxy              string `json:"tproxy"`
-	AcceptProxyProtocol bool   `json:"acceptProxyProtocol"`
+	Mark                int32       `json:"mark"`
+	TFO                 interface{} `json:"tcpFastOpen"`
+	TProxy              string      `json:"tproxy"`
+	AcceptProxyProtocol bool        `json:"acceptProxyProtocol"`
 }
 
 // Build implements Buildable.
 func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
-	var tfoSettings internet.SocketConfig_TCPFastOpenState
+	tfo := int32(-1)
 	if c.TFO != nil {
-		if *c.TFO {
-			tfoSettings = internet.SocketConfig_Enable
-		} else {
-			tfoSettings = internet.SocketConfig_Disable
+		switch v := c.TFO.(type) {
+		case bool:
+			if v {
+				tfo = 256
+			} else {
+				tfo = 0
+			}
+		case float64:
+			if v < 0 {
+				return nil, newError("tcpFastOpen: only boolean and non-negative integer value is acceptable")
+			}
+			tfo = int32(math.Min(v, math.MaxInt32))
+		default:
+			return nil, newError("tcpFastOpen: only boolean and non-negative integer value is acceptable")
 		}
 	}
 	var tproxy internet.SocketConfig_TProxyMode
@@ -478,7 +489,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
 
 	return &internet.SocketConfig{
 		Mark:                c.Mark,
-		Tfo:                 tfoSettings,
+		Tfo:                 tfo,
 		Tproxy:              tproxy,
 		AcceptProxyProtocol: c.AcceptProxyProtocol,
 	}, nil

+ 25 - 1
infra/conf/transport_test.go

@@ -39,7 +39,31 @@ func TestSocketConfig(t *testing.T) {
 			Parser: createParser(),
 			Output: &internet.SocketConfig{
 				Mark: 1,
-				Tfo:  internet.SocketConfig_Enable,
+				Tfo:  256,
+			},
+		},
+	})
+	runMultiTestCase(t, []TestCase{
+		{
+			Input: `{
+				"tcpFastOpen": false
+			}`,
+			Parser: createParser(),
+			Output: &internet.SocketConfig{
+				Mark: 0,
+				Tfo:  0,
+			},
+		},
+	})
+	runMultiTestCase(t, []TestCase{
+		{
+			Input: `{
+				"tcpFastOpen": 65535
+			}`,
+			Parser: createParser(),
+			Output: &internet.SocketConfig{
+				Mark: 0,
+				Tfo:  65535,
 			},
 		},
 	})

+ 60 - 121
transport/internet/config.pb.go

@@ -84,58 +84,6 @@ func (TransportProtocol) EnumDescriptor() ([]byte, []int) {
 	return file_transport_internet_config_proto_rawDescGZIP(), []int{0}
 }
 
-type SocketConfig_TCPFastOpenState int32
-
-const (
-	// AsIs is to leave the current TFO state as is, unmodified.
-	SocketConfig_AsIs SocketConfig_TCPFastOpenState = 0
-	// Enable is for enabling TFO explictly.
-	SocketConfig_Enable SocketConfig_TCPFastOpenState = 1
-	// Disable is for disabling TFO explictly.
-	SocketConfig_Disable SocketConfig_TCPFastOpenState = 2
-)
-
-// Enum value maps for SocketConfig_TCPFastOpenState.
-var (
-	SocketConfig_TCPFastOpenState_name = map[int32]string{
-		0: "AsIs",
-		1: "Enable",
-		2: "Disable",
-	}
-	SocketConfig_TCPFastOpenState_value = map[string]int32{
-		"AsIs":    0,
-		"Enable":  1,
-		"Disable": 2,
-	}
-)
-
-func (x SocketConfig_TCPFastOpenState) Enum() *SocketConfig_TCPFastOpenState {
-	p := new(SocketConfig_TCPFastOpenState)
-	*p = x
-	return p
-}
-
-func (x SocketConfig_TCPFastOpenState) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (SocketConfig_TCPFastOpenState) Descriptor() protoreflect.EnumDescriptor {
-	return file_transport_internet_config_proto_enumTypes[1].Descriptor()
-}
-
-func (SocketConfig_TCPFastOpenState) Type() protoreflect.EnumType {
-	return &file_transport_internet_config_proto_enumTypes[1]
-}
-
-func (x SocketConfig_TCPFastOpenState) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use SocketConfig_TCPFastOpenState.Descriptor instead.
-func (SocketConfig_TCPFastOpenState) EnumDescriptor() ([]byte, []int) {
-	return file_transport_internet_config_proto_rawDescGZIP(), []int{3, 0}
-}
-
 type SocketConfig_TProxyMode int32
 
 const (
@@ -172,11 +120,11 @@ func (x SocketConfig_TProxyMode) String() string {
 }
 
 func (SocketConfig_TProxyMode) Descriptor() protoreflect.EnumDescriptor {
-	return file_transport_internet_config_proto_enumTypes[2].Descriptor()
+	return file_transport_internet_config_proto_enumTypes[1].Descriptor()
 }
 
 func (SocketConfig_TProxyMode) Type() protoreflect.EnumType {
-	return &file_transport_internet_config_proto_enumTypes[2]
+	return &file_transport_internet_config_proto_enumTypes[1]
 }
 
 func (x SocketConfig_TProxyMode) Number() protoreflect.EnumNumber {
@@ -185,7 +133,7 @@ func (x SocketConfig_TProxyMode) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use SocketConfig_TProxyMode.Descriptor instead.
 func (SocketConfig_TProxyMode) EnumDescriptor() ([]byte, []int) {
-	return file_transport_internet_config_proto_rawDescGZIP(), []int{3, 1}
+	return file_transport_internet_config_proto_rawDescGZIP(), []int{3, 0}
 }
 
 type TransportConfig struct {
@@ -408,7 +356,7 @@ type SocketConfig struct {
 	// Mark of the connection. If non-zero, the value will be set to SO_MARK.
 	Mark int32 `protobuf:"varint,1,opt,name=mark,proto3" json:"mark,omitempty"`
 	// TFO is the state of TFO settings.
-	Tfo SocketConfig_TCPFastOpenState `protobuf:"varint,2,opt,name=tfo,proto3,enum=xray.transport.internet.SocketConfig_TCPFastOpenState" json:"tfo,omitempty"`
+	Tfo int32 `protobuf:"varint,2,opt,name=tfo,proto3" json:"tfo,omitempty"`
 	// TProxy is for enabling TProxy socket option.
 	Tproxy SocketConfig_TProxyMode `protobuf:"varint,3,opt,name=tproxy,proto3,enum=xray.transport.internet.SocketConfig_TProxyMode" json:"tproxy,omitempty"`
 	// ReceiveOriginalDestAddress is for enabling IP_RECVORIGDSTADDR socket
@@ -458,11 +406,11 @@ func (x *SocketConfig) GetMark() int32 {
 	return 0
 }
 
-func (x *SocketConfig) GetTfo() SocketConfig_TCPFastOpenState {
+func (x *SocketConfig) GetTfo() int32 {
 	if x != nil {
 		return x.Tfo
 	}
-	return SocketConfig_AsIs
+	return 0
 }
 
 func (x *SocketConfig) GetTproxy() SocketConfig_TProxyMode {
@@ -549,49 +497,42 @@ var file_transport_internet_config_proto_rawDesc = []byte{
 	0x0e, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22,
 	0x1f, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10,
 	0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67,
-	0x22, 0xd5, 0x03, 0x0a, 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x22, 0xe6, 0x02, 0x0a, 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
 	0x67, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
-	0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x48, 0x0a, 0x03, 0x74, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x36, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
-	0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x6f, 0x63,
-	0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x43, 0x50, 0x46, 0x61, 0x73,
-	0x74, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x03, 0x74, 0x66, 0x6f, 0x12,
-	0x48, 0x0a, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
-	0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64,
-	0x65, 0x52, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x63,
-	0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65,
-	0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61,
-	0x6c, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c,
-	0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01,
-	0x28, 0x0c, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12,
-	0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01,
-	0x28, 0x0d, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x32, 0x0a, 0x15,
-	0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x63, 0x63,
-	0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
-	0x22, 0x35, 0x0a, 0x10, 0x54, 0x43, 0x50, 0x46, 0x61, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x53,
-	0x74, 0x61, 0x74, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x0a,
-	0x0a, 0x06, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x69,
-	0x73, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x02, 0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f, 0x78,
-	0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x66, 0x66, 0x10, 0x00, 0x12, 0x0a,
-	0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65,
-	0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5a, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e,
-	0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a,
-	0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12,
-	0x08, 0x0a, 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x65, 0x62,
-	0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50,
-	0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x63, 0x6b,
-	0x65, 0x74, 0x10, 0x05, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79,
-	0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65,
-	0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73,
-	0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x03, 0x74, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78,
+	0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74,
+	0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
+	0x74, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54,
+	0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78,
+	0x79, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69,
+	0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65,
+	0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76,
+	0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64,
+	0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64,
+	0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64,
+	0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f,
+	0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64,
+	0x50, 0x6f, 0x72, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70,
+	0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79,
+	0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f,
+	0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x66, 0x66, 0x10, 0x00, 0x12,
+	0x0a, 0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52,
+	0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5a, 0x0a, 0x11, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07,
+	0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01,
+	0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x65,
+	0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54,
+	0x50, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x63,
+	0x6b, 0x65, 0x74, 0x10, 0x05, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61,
+	0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72,
+	0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e,
+	0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -606,32 +547,30 @@ func file_transport_internet_config_proto_rawDescGZIP() []byte {
 	return file_transport_internet_config_proto_rawDescData
 }
 
-var file_transport_internet_config_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_transport_internet_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
 var file_transport_internet_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
 var file_transport_internet_config_proto_goTypes = []interface{}{
-	(TransportProtocol)(0),             // 0: xray.transport.internet.TransportProtocol
-	(SocketConfig_TCPFastOpenState)(0), // 1: xray.transport.internet.SocketConfig.TCPFastOpenState
-	(SocketConfig_TProxyMode)(0),       // 2: xray.transport.internet.SocketConfig.TProxyMode
-	(*TransportConfig)(nil),            // 3: xray.transport.internet.TransportConfig
-	(*StreamConfig)(nil),               // 4: xray.transport.internet.StreamConfig
-	(*ProxyConfig)(nil),                // 5: xray.transport.internet.ProxyConfig
-	(*SocketConfig)(nil),               // 6: xray.transport.internet.SocketConfig
-	(*serial.TypedMessage)(nil),        // 7: xray.common.serial.TypedMessage
+	(TransportProtocol)(0),       // 0: xray.transport.internet.TransportProtocol
+	(SocketConfig_TProxyMode)(0), // 1: xray.transport.internet.SocketConfig.TProxyMode
+	(*TransportConfig)(nil),      // 2: xray.transport.internet.TransportConfig
+	(*StreamConfig)(nil),         // 3: xray.transport.internet.StreamConfig
+	(*ProxyConfig)(nil),          // 4: xray.transport.internet.ProxyConfig
+	(*SocketConfig)(nil),         // 5: xray.transport.internet.SocketConfig
+	(*serial.TypedMessage)(nil),  // 6: xray.common.serial.TypedMessage
 }
 var file_transport_internet_config_proto_depIdxs = []int32{
 	0, // 0: xray.transport.internet.TransportConfig.protocol:type_name -> xray.transport.internet.TransportProtocol
-	7, // 1: xray.transport.internet.TransportConfig.settings:type_name -> xray.common.serial.TypedMessage
+	6, // 1: xray.transport.internet.TransportConfig.settings:type_name -> xray.common.serial.TypedMessage
 	0, // 2: xray.transport.internet.StreamConfig.protocol:type_name -> xray.transport.internet.TransportProtocol
-	3, // 3: xray.transport.internet.StreamConfig.transport_settings:type_name -> xray.transport.internet.TransportConfig
-	7, // 4: xray.transport.internet.StreamConfig.security_settings:type_name -> xray.common.serial.TypedMessage
-	6, // 5: xray.transport.internet.StreamConfig.socket_settings:type_name -> xray.transport.internet.SocketConfig
-	1, // 6: xray.transport.internet.SocketConfig.tfo:type_name -> xray.transport.internet.SocketConfig.TCPFastOpenState
-	2, // 7: xray.transport.internet.SocketConfig.tproxy:type_name -> xray.transport.internet.SocketConfig.TProxyMode
-	8, // [8:8] is the sub-list for method output_type
-	8, // [8:8] is the sub-list for method input_type
-	8, // [8:8] is the sub-list for extension type_name
-	8, // [8:8] is the sub-list for extension extendee
-	0, // [0:8] is the sub-list for field type_name
+	2, // 3: xray.transport.internet.StreamConfig.transport_settings:type_name -> xray.transport.internet.TransportConfig
+	6, // 4: xray.transport.internet.StreamConfig.security_settings:type_name -> xray.common.serial.TypedMessage
+	5, // 5: xray.transport.internet.StreamConfig.socket_settings:type_name -> xray.transport.internet.SocketConfig
+	1, // 6: xray.transport.internet.SocketConfig.tproxy:type_name -> xray.transport.internet.SocketConfig.TProxyMode
+	7, // [7:7] is the sub-list for method output_type
+	7, // [7:7] is the sub-list for method input_type
+	7, // [7:7] is the sub-list for extension type_name
+	7, // [7:7] is the sub-list for extension extendee
+	0, // [0:7] is the sub-list for field type_name
 }
 
 func init() { file_transport_internet_config_proto_init() }
@@ -694,7 +633,7 @@ func file_transport_internet_config_proto_init() {
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_transport_internet_config_proto_rawDesc,
-			NumEnums:      3,
+			NumEnums:      2,
 			NumMessages:   4,
 			NumExtensions: 0,
 			NumServices:   0,

+ 1 - 10
transport/internet/config.proto

@@ -54,17 +54,8 @@ message SocketConfig {
   // Mark of the connection. If non-zero, the value will be set to SO_MARK.
   int32 mark = 1;
 
-  enum TCPFastOpenState {
-    // AsIs is to leave the current TFO state as is, unmodified.
-    AsIs = 0;
-    // Enable is for enabling TFO explictly.
-    Enable = 1;
-    // Disable is for disabling TFO explictly.
-    Disable = 2;
-  }
-
   // TFO is the state of TFO settings.
-  TCPFastOpenState tfo = 2;
+  int32 tfo = 2;
 
   enum TProxyMode {
     // TProxy is off.

+ 12 - 14
transport/internet/sockopt_darwin.go

@@ -15,13 +15,12 @@ const (
 
 func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
 	if isTCPSocket(network) {
-		switch config.Tfo {
-		case SocketConfig_Enable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, TCP_FASTOPEN_CLIENT); err != nil {
-				return err
-			}
-		case SocketConfig_Disable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, 0); err != nil {
+		tfo := config.Tfo
+		if tfo > 0 {
+			tfo = TCP_FASTOPEN_CLIENT
+		}
+		if tfo >= 0 {
+			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, int(tfo)); err != nil {
 				return err
 			}
 		}
@@ -32,13 +31,12 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
 
 func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
 	if isTCPSocket(network) {
-		switch config.Tfo {
-		case SocketConfig_Enable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, TCP_FASTOPEN_SERVER); err != nil {
-				return err
-			}
-		case SocketConfig_Disable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, 0); err != nil {
+		tfo := config.Tfo
+		if tfo > 0 {
+			tfo = TCP_FASTOPEN_SERVER
+		}
+		if tfo >= 0 {
+			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, int(tfo)); err != nil {
 				return err
 			}
 		}

+ 10 - 16
transport/internet/sockopt_freebsd.go

@@ -130,14 +130,13 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
 	}
 
 	if isTCPSocket(network) {
-		switch config.Tfo {
-		case SocketConfig_Enable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 1); err != nil {
-				return newError("failed to set TCP_FASTOPEN_CONNECT=1").Base(err)
-			}
-		case SocketConfig_Disable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {
-				return newError("failed to set TCP_FASTOPEN_CONNECT=0").Base(err)
+		tfo := int(config.Tfo)
+		if tfo > 0 {
+			tfo = 1
+		}
+		if tfo >= 0 {
+			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, tfo); err != nil {
+				return newError("failed to set TCP_FASTOPEN_CONNECT=", tfo).Base(err)
 			}
 		}
 	}
@@ -164,14 +163,9 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
 		}
 	}
 	if isTCPSocket(network) {
-		switch config.Tfo {
-		case SocketConfig_Enable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 1); err != nil {
-				return newError("failed to set TCP_FASTOPEN=1").Base(err)
-			}
-		case SocketConfig_Disable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {
-				return newError("failed to set TCP_FASTOPEN=0").Base(err)
+		if config.Tfo >= 0 {
+			if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, int(config.Tfo)); err != nil {
+				return newError("failed to set TCP_FASTOPEN=", config.Tfo).Base(err)
 			}
 		}
 	}

+ 10 - 16
transport/internet/sockopt_linux.go

@@ -48,14 +48,13 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
 	}
 
 	if isTCPSocket(network) {
-		switch config.Tfo {
-		case SocketConfig_Enable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 1); err != nil {
-				return newError("failed to set TCP_FASTOPEN_CONNECT=1").Base(err)
-			}
-		case SocketConfig_Disable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 0); err != nil {
-				return newError("failed to set TCP_FASTOPEN_CONNECT=0").Base(err)
+		tfo := int(config.Tfo)
+		if tfo > 0 {
+			tfo = 1
+		}
+		if tfo >= 0 {
+			if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, tfo); err != nil {
+				return newError("failed to set TCP_FASTOPEN_CONNECT=", tfo).Base(err)
 			}
 		}
 	}
@@ -76,14 +75,9 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
 		}
 	}
 	if isTCPSocket(network) {
-		switch config.Tfo {
-		case SocketConfig_Enable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 1); err != nil {
-				return newError("failed to set TCP_FASTOPEN=1").Base(err)
-			}
-		case SocketConfig_Disable:
-			if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 0); err != nil {
-				return newError("failed to set TCP_FASTOPEN=0").Base(err)
+		if config.Tfo >= 0 {
+			if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, int(config.Tfo)); err != nil {
+				return newError("failed to set TCP_FASTOPEN=", config.Tfo).Base(err)
 			}
 		}
 	}

+ 2 - 2
transport/internet/sockopt_test.go

@@ -17,14 +17,14 @@ func TestTCPFastOpen(t *testing.T) {
 			return b
 		},
 	}
-	dest, err := tcpServer.StartContext(context.Background(), &SocketConfig{Tfo: SocketConfig_Enable})
+	dest, err := tcpServer.StartContext(context.Background(), &SocketConfig{Tfo: 256})
 	common.Must(err)
 	defer tcpServer.Close()
 
 	ctx := context.Background()
 	dialer := DefaultSystemDialer{}
 	conn, err := dialer.Dial(ctx, nil, dest, &SocketConfig{
-		Tfo: SocketConfig_Enable,
+		Tfo: 1,
 	})
 	common.Must(err)
 	defer conn.Close()

+ 6 - 8
transport/internet/sockopt_windows.go

@@ -8,14 +8,12 @@ const (
 	TCP_FASTOPEN = 15
 )
 
-func setTFO(fd syscall.Handle, settings SocketConfig_TCPFastOpenState) error {
-	switch settings {
-	case SocketConfig_Enable:
-		if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, 1); err != nil {
-			return err
-		}
-	case SocketConfig_Disable:
-		if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, 0); err != nil {
+func setTFO(fd syscall.Handle, tfo int32) error {
+	if tfo > 0 {
+		tfo = 1
+	}
+	if tfo >= 0 {
+		if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, int(tfo)); err != nil {
 			return err
 		}
 	}