Browse Source

options for enable TFO

pull/1269/head
Darien Raymond 6 years ago
parent
commit
6d750e8149
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
  1. 131
      transport/internet/config.pb.go
  2. 12
      transport/internet/config.proto
  3. 14
      transport/internet/http/hub.go
  4. 1
      transport/internet/sockopt.go
  5. 45
      transport/internet/sockopt_linux.go
  6. 6
      transport/internet/sockopt_other.go
  7. 2
      transport/internet/system_dialer.go
  8. 39
      transport/internet/system_listener.go
  9. 2
      transport/internet/tcp/hub.go
  10. 8
      transport/internet/tcp_hub.go
  11. 77
      transport/internet/websocket/hub.go
  12. 6
      transport/internet/websocket/ws_test.go

131
transport/internet/config.pb.go

@ -48,7 +48,36 @@ func (x TransportProtocol) String() string {
return proto.EnumName(TransportProtocol_name, int32(x))
}
func (TransportProtocol) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_config_807c5df32db81c88, []int{0}
return fileDescriptor_config_d7068fe3707ce485, []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
)
var SocketConfig_TCPFastOpenState_name = map[int32]string{
0: "AsIs",
1: "Enable",
2: "Disable",
}
var SocketConfig_TCPFastOpenState_value = map[string]int32{
"AsIs": 0,
"Enable": 1,
"Disable": 2,
}
func (x SocketConfig_TCPFastOpenState) String() string {
return proto.EnumName(SocketConfig_TCPFastOpenState_name, int32(x))
}
func (SocketConfig_TCPFastOpenState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_config_d7068fe3707ce485, []int{3, 0}
}
type TransportConfig struct {
@ -68,7 +97,7 @@ func (m *TransportConfig) Reset() { *m = TransportConfig{} }
func (m *TransportConfig) String() string { return proto.CompactTextString(m) }
func (*TransportConfig) ProtoMessage() {}
func (*TransportConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_config_807c5df32db81c88, []int{0}
return fileDescriptor_config_d7068fe3707ce485, []int{0}
}
func (m *TransportConfig) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TransportConfig.Unmarshal(m, b)
@ -129,7 +158,7 @@ func (m *StreamConfig) Reset() { *m = StreamConfig{} }
func (m *StreamConfig) String() string { return proto.CompactTextString(m) }
func (*StreamConfig) ProtoMessage() {}
func (*StreamConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_config_807c5df32db81c88, []int{1}
return fileDescriptor_config_d7068fe3707ce485, []int{1}
}
func (m *StreamConfig) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StreamConfig.Unmarshal(m, b)
@ -203,7 +232,7 @@ func (m *ProxyConfig) Reset() { *m = ProxyConfig{} }
func (m *ProxyConfig) String() string { return proto.CompactTextString(m) }
func (*ProxyConfig) ProtoMessage() {}
func (*ProxyConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_config_807c5df32db81c88, []int{2}
return fileDescriptor_config_d7068fe3707ce485, []int{2}
}
func (m *ProxyConfig) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ProxyConfig.Unmarshal(m, b)
@ -230,18 +259,22 @@ func (m *ProxyConfig) GetTag() string {
return ""
}
// SocketConfig is options to be applied on network sockets.
type SocketConfig struct {
Mark int32 `protobuf:"varint,1,opt,name=mark,proto3" json:"mark,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
// 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=v2ray.core.transport.internet.SocketConfig_TCPFastOpenState" json:"tfo,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SocketConfig) Reset() { *m = SocketConfig{} }
func (m *SocketConfig) String() string { return proto.CompactTextString(m) }
func (*SocketConfig) ProtoMessage() {}
func (*SocketConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_config_807c5df32db81c88, []int{3}
return fileDescriptor_config_d7068fe3707ce485, []int{3}
}
func (m *SocketConfig) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SocketConfig.Unmarshal(m, b)
@ -268,47 +301,59 @@ func (m *SocketConfig) GetMark() int32 {
return 0
}
func (m *SocketConfig) GetTfo() SocketConfig_TCPFastOpenState {
if m != nil {
return m.Tfo
}
return SocketConfig_AsIs
}
func init() {
proto.RegisterType((*TransportConfig)(nil), "v2ray.core.transport.internet.TransportConfig")
proto.RegisterType((*StreamConfig)(nil), "v2ray.core.transport.internet.StreamConfig")
proto.RegisterType((*ProxyConfig)(nil), "v2ray.core.transport.internet.ProxyConfig")
proto.RegisterType((*SocketConfig)(nil), "v2ray.core.transport.internet.SocketConfig")
proto.RegisterEnum("v2ray.core.transport.internet.TransportProtocol", TransportProtocol_name, TransportProtocol_value)
proto.RegisterEnum("v2ray.core.transport.internet.SocketConfig_TCPFastOpenState", SocketConfig_TCPFastOpenState_name, SocketConfig_TCPFastOpenState_value)
}
func init() {
proto.RegisterFile("v2ray.com/core/transport/internet/config.proto", fileDescriptor_config_807c5df32db81c88)
}
var fileDescriptor_config_807c5df32db81c88 = []byte{
// 456 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0xe1, 0x8a, 0x13, 0x31,
0x10, 0xc7, 0xdd, 0x6e, 0x7b, 0xb6, 0xd3, 0xde, 0xdd, 0x36, 0x9f, 0x8a, 0x70, 0x58, 0x57, 0x90,
0xa2, 0x90, 0x3d, 0xd6, 0x37, 0x68, 0xef, 0x83, 0xa2, 0xa7, 0xcb, 0x76, 0x55, 0x38, 0x90, 0x92,
0x8b, 0xb1, 0x2c, 0x77, 0x49, 0x4a, 0x12, 0xc5, 0x7d, 0x25, 0x3f, 0xfb, 0x10, 0x3e, 0x96, 0x24,
0xbb, 0x09, 0x45, 0xa5, 0x1e, 0xf8, 0x6d, 0xc8, 0xfc, 0xe7, 0x3f, 0xf3, 0x9b, 0x09, 0xe0, 0xaf,
0xb9, 0x22, 0x0d, 0xa6, 0x92, 0x67, 0x54, 0x2a, 0x96, 0x19, 0x45, 0x84, 0xde, 0x49, 0x65, 0xb2,
0x5a, 0x18, 0xa6, 0x04, 0x33, 0x19, 0x95, 0xe2, 0x73, 0xbd, 0xc5, 0x3b, 0x25, 0x8d, 0x44, 0x67,
0x5e, 0xaf, 0x18, 0x0e, 0x5a, 0xec, 0xb5, 0x0f, 0xce, 0x7f, 0xb3, 0xa3, 0x92, 0x73, 0x29, 0x32,
0xcd, 0x54, 0x4d, 0x6e, 0x33, 0xd3, 0xec, 0xd8, 0xa7, 0x0d, 0x67, 0x5a, 0x93, 0x2d, 0x6b, 0x0d,
0xd3, 0x9f, 0x11, 0x9c, 0x56, 0xde, 0x68, 0xe5, 0x5a, 0xa1, 0xd7, 0x30, 0x74, 0x49, 0x2a, 0x6f,
0x67, 0xd1, 0x3c, 0x5a, 0x9c, 0xe4, 0xe7, 0xf8, 0x60, 0x5f, 0x1c, 0x1c, 0x8a, 0xae, 0xae, 0x0c,
0x0e, 0xe8, 0x31, 0x1c, 0xfb, 0x78, 0x23, 0x08, 0x67, 0xb3, 0x78, 0x1e, 0x2d, 0x46, 0xe5, 0xc4,
0x3f, 0xbe, 0x21, 0x9c, 0xa1, 0x25, 0x0c, 0x35, 0x33, 0xa6, 0x16, 0x5b, 0x3d, 0xeb, 0xcd, 0xa3,
0xc5, 0x38, 0x7f, 0xb2, 0xdf, 0xb2, 0xe5, 0xc0, 0x2d, 0x07, 0xae, 0x2c, 0xc7, 0x65, 0x8b, 0x51,
0x86, 0xba, 0xf4, 0x47, 0x0c, 0x93, 0xb5, 0x51, 0x8c, 0xf0, 0x8e, 0xa3, 0xf8, 0x7f, 0x8e, 0x65,
0x6f, 0x16, 0x1d, 0x62, 0x19, 0xfc, 0x85, 0xe5, 0x23, 0xa0, 0x60, 0xbd, 0xd9, 0xa3, 0x8a, 0x17,
0xe3, 0x1c, 0xdf, 0x75, 0x80, 0x16, 0xa1, 0x9c, 0x06, 0xcd, 0xba, 0x33, 0xb2, 0x33, 0x68, 0x46,
0xbf, 0xa8, 0xda, 0x34, 0x1b, 0x7b, 0x51, 0xbf, 0x4f, 0xff, 0x68, 0xb7, 0x83, 0xd6, 0x30, 0x0d,
0xa2, 0x30, 0x42, 0xdf, 0x8d, 0x70, 0xd7, 0xc5, 0x26, 0xde, 0x20, 0x74, 0xae, 0xe0, 0x54, 0x4b,
0x7a, 0xc3, 0xf6, 0xa8, 0x8e, 0xdc, 0xad, 0x9e, 0xfd, 0x83, 0x6a, 0xed, 0xaa, 0x3a, 0xa4, 0x93,
0xd6, 0xc3, 0xbb, 0xa6, 0x0f, 0x61, 0x5c, 0x28, 0xf9, 0xad, 0xe9, 0x8e, 0x96, 0x40, 0x6c, 0xc8,
0xd6, 0xdd, 0x6b, 0x54, 0xda, 0x30, 0x4d, 0x61, 0xb2, 0x6f, 0x80, 0x10, 0xf4, 0x39, 0x51, 0x37,
0x4e, 0x32, 0x28, 0x5d, 0xfc, 0xf4, 0x0a, 0xa6, 0x7f, 0xdc, 0x0e, 0xdd, 0x87, 0xb8, 0x5a, 0x15,
0xc9, 0x3d, 0x1b, 0xbc, 0xbb, 0x28, 0x92, 0x08, 0x0d, 0xa1, 0x7f, 0xf9, 0x6a, 0x55, 0x24, 0x3d,
0x74, 0x0c, 0xa3, 0x0f, 0xec, 0xba, 0xf5, 0x4d, 0x62, 0x9b, 0x78, 0x51, 0x55, 0x45, 0xd2, 0x47,
0x09, 0x4c, 0x2e, 0x24, 0x27, 0xb5, 0xe8, 0x72, 0x83, 0xe5, 0x5b, 0x78, 0x44, 0x25, 0x3f, 0x8c,
0x58, 0x44, 0x57, 0x43, 0x1f, 0x7f, 0xef, 0x9d, 0xbd, 0xcf, 0x4b, 0xd2, 0xe0, 0x95, 0xd5, 0x86,
0xb1, 0xf0, 0xcb, 0x2e, 0x7f, 0x7d, 0xe4, 0xbe, 0xcb, 0xf3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff,
0xba, 0x0d, 0x33, 0xbb, 0xfd, 0x03, 0x00, 0x00,
proto.RegisterFile("v2ray.com/core/transport/internet/config.proto", fileDescriptor_config_d7068fe3707ce485)
}
var fileDescriptor_config_d7068fe3707ce485 = []byte{
// 518 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0xd1, 0x8a, 0x13, 0x31,
0x14, 0x86, 0x77, 0x3a, 0x6d, 0xb7, 0x3d, 0xed, 0x76, 0xd3, 0x5c, 0x15, 0x61, 0xb1, 0x56, 0x90,
0xa2, 0x90, 0x59, 0x46, 0xbc, 0xf3, 0xc6, 0xb6, 0x8a, 0x8b, 0xee, 0xee, 0x30, 0x1d, 0x15, 0x16,
0xa4, 0xa4, 0x63, 0xb6, 0x0c, 0xdb, 0x99, 0x94, 0x24, 0x8a, 0x7d, 0x24, 0xbd, 0xf6, 0x21, 0x7c,
0x2c, 0x49, 0x66, 0x12, 0xca, 0x2a, 0x75, 0xc5, 0xbb, 0x33, 0x73, 0xfe, 0xfc, 0xe7, 0xff, 0x72,
0x02, 0xe4, 0x4b, 0x28, 0xe8, 0x96, 0xa4, 0x3c, 0x0f, 0x52, 0x2e, 0x58, 0xa0, 0x04, 0x2d, 0xe4,
0x86, 0x0b, 0x15, 0x64, 0x85, 0x62, 0xa2, 0x60, 0x2a, 0x48, 0x79, 0x71, 0x9d, 0xad, 0xc8, 0x46,
0x70, 0xc5, 0xf1, 0x89, 0xd5, 0x0b, 0x46, 0x9c, 0x96, 0x58, 0xed, 0xbd, 0xd3, 0x5b, 0x76, 0x29,
0xcf, 0x73, 0x5e, 0x04, 0x92, 0x89, 0x8c, 0xae, 0x03, 0xb5, 0xdd, 0xb0, 0x4f, 0x8b, 0x9c, 0x49,
0x49, 0x57, 0xac, 0x34, 0x1c, 0xfd, 0xf4, 0xe0, 0x38, 0xb1, 0x46, 0x53, 0x33, 0x0a, 0xbf, 0x85,
0x96, 0x69, 0xa6, 0x7c, 0x3d, 0xf0, 0x86, 0xde, 0xb8, 0x17, 0x9e, 0x92, 0xbd, 0x73, 0x89, 0x73,
0x88, 0xaa, 0x73, 0xb1, 0x73, 0xc0, 0x0f, 0xe1, 0xc8, 0xd6, 0x8b, 0x82, 0xe6, 0x6c, 0xe0, 0x0f,
0xbd, 0x71, 0x3b, 0xee, 0xda, 0x9f, 0x17, 0x34, 0x67, 0x78, 0x02, 0x2d, 0xc9, 0x94, 0xca, 0x8a,
0x95, 0x1c, 0xd4, 0x86, 0xde, 0xb8, 0x13, 0x3e, 0xda, 0x1d, 0x59, 0x72, 0x90, 0x92, 0x83, 0x24,
0x9a, 0xe3, 0xbc, 0xc4, 0x88, 0xdd, 0xb9, 0xd1, 0x0f, 0x1f, 0xba, 0x73, 0x25, 0x18, 0xcd, 0x2b,
0x8e, 0xe8, 0xff, 0x39, 0x26, 0xb5, 0x81, 0xb7, 0x8f, 0xa5, 0xf1, 0x07, 0x96, 0x8f, 0x80, 0x9d,
0xf5, 0x62, 0x87, 0xca, 0x1f, 0x77, 0x42, 0x72, 0xd7, 0x00, 0x25, 0x42, 0xdc, 0x77, 0x9a, 0x79,
0x65, 0xa4, 0x33, 0x48, 0x96, 0x7e, 0x16, 0x99, 0xda, 0x2e, 0xf4, 0x46, 0xed, 0x7d, 0xda, 0x9f,
0xfa, 0x76, 0xf0, 0x1c, 0xfa, 0x4e, 0xe4, 0x22, 0xd4, 0x4d, 0x84, 0xbb, 0x5e, 0x2c, 0xb2, 0x06,
0x6e, 0x72, 0x02, 0xc7, 0x92, 0xa7, 0x37, 0x6c, 0x87, 0xaa, 0x69, 0x76, 0xf5, 0xe4, 0x2f, 0x54,
0x73, 0x73, 0xaa, 0x42, 0xea, 0x95, 0x1e, 0xd6, 0x75, 0x74, 0x1f, 0x3a, 0x91, 0xe0, 0x5f, 0xb7,
0xd5, 0xd2, 0x10, 0xf8, 0x8a, 0xae, 0xcc, 0xbe, 0xda, 0xb1, 0x2e, 0x47, 0xdf, 0x3c, 0xe8, 0xee,
0x3a, 0x60, 0x0c, 0xf5, 0x9c, 0x8a, 0x1b, 0xa3, 0x69, 0xc4, 0xa6, 0xc6, 0x17, 0xe0, 0xab, 0x6b,
0x6e, 0xde, 0x4e, 0x2f, 0x7c, 0xfe, 0x0f, 0x79, 0x48, 0x32, 0x8d, 0x5e, 0x51, 0xa9, 0x2e, 0x37,
0xac, 0x98, 0x2b, 0xaa, 0x58, 0xac, 0x8d, 0x46, 0xcf, 0x00, 0xdd, 0x6e, 0xe0, 0x16, 0xd4, 0x5f,
0xc8, 0x33, 0x89, 0x0e, 0x30, 0x40, 0xf3, 0x65, 0x41, 0x97, 0x6b, 0x86, 0x3c, 0xdc, 0x81, 0xc3,
0x59, 0x26, 0xcd, 0x47, 0xed, 0xf1, 0x15, 0xf4, 0x7f, 0x7b, 0x43, 0xf8, 0x10, 0xfc, 0x64, 0x1a,
0xa1, 0x03, 0x5d, 0xbc, 0x9b, 0x45, 0xc8, 0xd3, 0x4e, 0xe7, 0x6f, 0xa6, 0x11, 0xaa, 0xe1, 0x23,
0x68, 0x7f, 0x60, 0xcb, 0x32, 0x10, 0xf2, 0x75, 0xe3, 0x75, 0x92, 0x44, 0xa8, 0x8e, 0x11, 0x74,
0x67, 0x3c, 0xa7, 0x59, 0x51, 0xf5, 0x1a, 0x93, 0x4b, 0x78, 0x90, 0xf2, 0x7c, 0x3f, 0x5a, 0xe4,
0x5d, 0xb5, 0x6c, 0xfd, 0xbd, 0x76, 0xf2, 0x3e, 0x8c, 0xe9, 0x96, 0x4c, 0xb5, 0xd6, 0xc5, 0x22,
0x67, 0x55, 0x7f, 0xd9, 0x34, 0xcf, 0xf6, 0xe9, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x8d,
0xe5, 0xd8, 0x85, 0x04, 0x00, 0x00,
}

12
transport/internet/config.proto

@ -55,4 +55,16 @@ message ProxyConfig {
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;
}

14
transport/internet/http/hub.go

@ -9,6 +9,7 @@ import (
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/common/session"
"v2ray.com/core/common/signal/done"
"v2ray.com/core/transport/internet"
"v2ray.com/core/transport/internet/tls"
@ -116,9 +117,18 @@ func Listen(ctx context.Context, address net.Address, port net.Port, handler int
listener.server = server
go func() {
err := server.ListenAndServeTLS("", "")
tcpListener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{
IP: address.IP(),
Port: int(port),
})
if err != nil {
newError("failed to listen on", address, ":", port).Base(err).WriteToLog(session.ExportIDToError(ctx))
return
}
err = server.ServeTLS(tcpListener, "", "")
if err != nil {
newError("stoping serving TLS").Base(err).WriteToLog()
newError("stoping serving TLS").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
}()

1
transport/internet/sockopt.go

@ -0,0 +1 @@
package internet

45
transport/internet/sockopt_linux.go

@ -1,12 +1,53 @@
package internet
import "syscall"
import (
"strings"
"syscall"
)
func applySocketOptions(fd uintptr, config *SocketConfig) error {
const (
// For incoming connections.
TCP_FASTOPEN = 23
// For out-going connections.
TCP_FASTOPEN_CONNECT = 30
)
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
if config.Mark != 0 {
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, int(config.Mark)); err != nil {
return err
}
}
if strings.HasPrefix(network, "tcp") {
switch config.Tfo {
case SocketConfig_Enable:
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 1); err != nil {
return err
}
case SocketConfig_Disable:
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 0); err != nil {
return err
}
}
}
return nil
}
func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
if strings.HasPrefix(network, "tcp") {
switch config.Tfo {
case SocketConfig_Enable:
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 1); err != nil {
return err
}
case SocketConfig_Disable:
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 0); err != nil {
return err
}
}
}
return nil
}

6
transport/internet/sockopt_other.go

@ -2,6 +2,10 @@
package internet
func applySocketOptions(fd uintptr, config *SocketConfig) error {
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
return nil
}
func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
return nil
}

2
transport/internet/system_dialer.go

@ -31,7 +31,7 @@ func (DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.D
config := streamSettings.SocketSettings
dialer.Control = func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
if err := applySocketOptions(fd, config); err != nil {
if err := applyOutboundSocketOptions(network, address, fd, config); err != nil {
newError("failed to apply socket options").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
})

39
transport/internet/system_listener.go

@ -0,0 +1,39 @@
package internet
import (
"context"
"v2ray.com/core/common/net"
"v2ray.com/core/common/session"
)
var (
effectiveTCPListener = DefaultTCPListener{}
)
type DefaultTCPListener struct{}
func (tl *DefaultTCPListener) Listen(ctx context.Context, addr *net.TCPAddr) (*net.TCPListener, error) {
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return nil, err
}
streamSettings := StreamSettingsFromContext(ctx)
if streamSettings != nil && streamSettings.SocketSettings != nil {
config := streamSettings.SocketSettings
rawConn, err := l.SyscallConn()
if err != nil {
return nil, err
}
if err := rawConn.Control(func(fd uintptr) {
if err := applyInboundSocketOptions("tcp", fd, config); err != nil {
newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
}); err != nil {
return nil, err
}
}
return l, nil
}

2
transport/internet/tcp/hub.go

@ -23,7 +23,7 @@ type Listener struct {
// ListenTCP creates a new Listener based on configurations.
func ListenTCP(ctx context.Context, address net.Address, port net.Port, handler internet.ConnHandler) (internet.Listener, error) {
listener, err := net.ListenTCP("tcp", &net.TCPAddr{
listener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{
IP: address.IP(),
Port: int(port),
})

8
transport/internet/tcp_hub.go

@ -38,6 +38,10 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, handler
ctx = ContextWithStreamSettings(ctx, settings)
}
if address.Family().IsDomain() && address.Domain() == "localhost" {
address = net.LocalHostIP
}
protocol := settings.ProtocolName
listenFunc := transportListenerCache[protocol]
if listenFunc == nil {
@ -49,3 +53,7 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, handler
}
return listener, nil
}
func ListenSystemTCP(ctx context.Context, addr *net.TCPAddr) (*net.TCPListener, error) {
return effectiveTCPListener.Listen(ctx, addr)
}

77
transport/internet/websocket/hub.go

@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"net/http"
"strconv"
"sync"
"time"
@ -13,6 +12,7 @@ import (
"v2ray.com/core/common"
"v2ray.com/core/common/net"
http_proto "v2ray.com/core/common/protocol/http"
"v2ray.com/core/common/session"
"v2ray.com/core/transport/internet"
v2tls "v2ray.com/core/transport/internet/tls"
)
@ -50,58 +50,61 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
type Listener struct {
sync.Mutex
listener net.Listener
tlsConfig *tls.Config
config *Config
addConn internet.ConnHandler
listener net.Listener
config *Config
addConn internet.ConnHandler
}
func ListenWS(ctx context.Context, address net.Address, port net.Port, addConn internet.ConnHandler) (internet.Listener, error) {
networkSettings := internet.StreamSettingsFromContext(ctx)
wsSettings := networkSettings.ProtocolSettings.(*Config)
l := &Listener{
config: wsSettings,
addConn: addConn,
}
var tlsConfig *tls.Config
if config := v2tls.ConfigFromContext(ctx); config != nil {
l.tlsConfig = config.GetTLSConfig()
tlsConfig = config.GetTLSConfig()
}
err := l.listenws(address, port)
return l, err
}
listener, err := listenTCP(ctx, address, port, tlsConfig)
if err != nil {
return nil, err
}
func (ln *Listener) listenws(address net.Address, port net.Port) error {
netAddr := address.String() + ":" + strconv.Itoa(int(port.Value()))
var listener net.Listener
if ln.tlsConfig == nil {
l, err := net.Listen("tcp", netAddr)
if err != nil {
return newError("failed to listen TCP ", netAddr).Base(err)
}
listener = l
} else {
l, err := tls.Listen("tcp", netAddr, ln.tlsConfig)
if err != nil {
return newError("failed to listen TLS ", netAddr).Base(err)
}
listener = l
l := &Listener{
config: wsSettings,
addConn: addConn,
listener: listener,
}
ln.listener = listener
go func() {
err := http.Serve(listener, &requestHandler{
path: ln.config.GetNormalizedPath(),
ln: ln,
})
if err != nil {
newError("failed to serve http for WebSocket").Base(err).AtWarning().WriteToLog()
if err := l.serve(); err != nil {
newError("failed to serve http for WebSocket").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
}
}()
return nil
return l, err
}
func listenTCP(ctx context.Context, address net.Address, port net.Port, tlsConfig *tls.Config) (net.Listener, error) {
listener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{
IP: address.IP(),
Port: int(port),
})
if err != nil {
return nil, newError("failed to listen TCP on", address, ":", port).Base(err)
}
if tlsConfig != nil {
return tls.NewListener(listener, tlsConfig), nil
}
return listener, nil
}
func (ln *Listener) serve() error {
return http.Serve(ln.listener, &requestHandler{
path: ln.config.GetNormalizedPath(),
ln: ln,
})
}
// Addr implements net.Listener.Addr().

6
transport/internet/websocket/ws_test.go

@ -24,7 +24,7 @@ func Test_listenWSAndDial(t *testing.T) {
Path: "ws",
},
})
listen, err := ListenWS(lctx, net.DomainAddress("localhost"), 13146, func(conn internet.Connection) {
listen, err := ListenWS(lctx, net.LocalHostIP, 13146, func(conn internet.Connection) {
go func(c internet.Connection) {
defer c.Close()
@ -79,7 +79,7 @@ func TestDialWithRemoteAddr(t *testing.T) {
Path: "ws",
},
})
listen, err := ListenWS(lctx, net.DomainAddress("localhost"), 13148, func(conn internet.Connection) {
listen, err := ListenWS(lctx, net.LocalHostIPv6, 13148, func(conn internet.Connection) {
go func(c internet.Connection) {
defer c.Close()
@ -138,7 +138,7 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
},
})
listen, err := ListenWS(ctx, net.DomainAddress("localhost"), 13143, func(conn internet.Connection) {
listen, err := ListenWS(ctx, net.LocalHostIP, 13143, func(conn internet.Connection) {
go func() {
_ = conn.Close()
}()

Loading…
Cancel
Save