mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-22 00:56:53 +00:00
https://github.com/XTLS/Xray-core/pull/6327#issuecomment-5645958010 https://github.com/XTLS/Xray-core/pull/6754#issuecomment-5720818254 https://github.com/XTLS/Xray-core/pull/6754#issuecomment-5751585906
108 lines
3.0 KiB
Go
108 lines
3.0 KiB
Go
package internet
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
|
|
"github.com/xtls/xray-core/common"
|
|
"github.com/xtls/xray-core/common/net"
|
|
"github.com/xtls/xray-core/common/net/cnc"
|
|
"github.com/xtls/xray-core/transport/internet/finalmask"
|
|
)
|
|
|
|
// MemoryStreamConfig is a parsed form of StreamConfig. It is used to reduce the number of Protobuf parses.
|
|
type MemoryStreamConfig struct {
|
|
Destination *net.Destination
|
|
ProtocolName string
|
|
ProtocolSettings interface{}
|
|
SecurityType string
|
|
SecuritySettings interface{}
|
|
FinalMask *finalmask.FinalMask
|
|
QuicParams *QuicParams
|
|
SocketSettings *SocketConfig
|
|
DownloadSettings *MemoryStreamConfig
|
|
}
|
|
|
|
// ToMemoryStreamConfig converts a StreamConfig to MemoryStreamConfig. It returns a default non-nil MemoryStreamConfig for nil input.
|
|
func ToMemoryStreamConfig(s *StreamConfig) (*MemoryStreamConfig, error) {
|
|
ets, err := s.GetEffectiveTransportSettings()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mss := &MemoryStreamConfig{
|
|
ProtocolName: s.GetEffectiveProtocol(),
|
|
ProtocolSettings: ets,
|
|
}
|
|
|
|
if s != nil {
|
|
if s.Address != nil {
|
|
mss.Destination = &net.Destination{
|
|
Address: s.Address.AsAddress(),
|
|
Port: net.Port(s.Port),
|
|
Network: net.Network_TCP,
|
|
}
|
|
}
|
|
mss.SocketSettings = s.SocketSettings
|
|
}
|
|
|
|
if s != nil && s.HasSecuritySettings() {
|
|
ess, err := s.GetEffectiveSecuritySettings()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mss.SecurityType = s.SecurityType
|
|
mss.SecuritySettings = ess
|
|
}
|
|
|
|
var tcpMasks []finalmask.TCPMask
|
|
var udpMasks []finalmask.UDPMask
|
|
|
|
if s != nil {
|
|
for i := range s.Tcpmasks {
|
|
instance := common.Must2(s.Tcpmasks[i].GetInstance())
|
|
tcpMasks = append(tcpMasks, instance.(finalmask.TCPMask))
|
|
}
|
|
for i := range s.Udpmasks {
|
|
instance := common.Must2(s.Udpmasks[i].GetInstance())
|
|
udpMasks = append(udpMasks, instance.(finalmask.UDPMask))
|
|
}
|
|
}
|
|
|
|
dialTCP := func(ctx context.Context, dest net.Destination) (net.Conn, error) {
|
|
return DialSystem(ctx, dest, mss.SocketSettings)
|
|
}
|
|
listen := func(ctx context.Context, addr net.Addr) (net.Listener, error) {
|
|
return ListenSystem(ctx, addr, mss.SocketSettings)
|
|
}
|
|
dialUDP := func(ctx context.Context, dest net.Destination) (net.PacketConn, net.Addr, error) {
|
|
conn, err := DialSystem(ctx, dest, mss.SocketSettings)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
var newConn net.PacketConn
|
|
var udpAddr net.Addr
|
|
switch c := conn.(type) {
|
|
case *PacketConnWrapper:
|
|
newConn = c.PacketConn
|
|
udpAddr = conn.RemoteAddr()
|
|
case *cnc.Connection:
|
|
newConn = &FakePacketConn{Conn: c}
|
|
udpAddr = &net.UDPAddr{IP: []byte{0, 0, 0, 0}, Port: 0}
|
|
default:
|
|
panic(reflect.TypeOf(c))
|
|
}
|
|
return newConn, udpAddr, nil
|
|
}
|
|
listenPacket := func(ctx context.Context, addr net.Addr) (net.PacketConn, error) {
|
|
return ListenSystemPacket(ctx, addr, mss.SocketSettings)
|
|
}
|
|
mss.FinalMask = finalmask.NewFinalMask(tcpMasks, udpMasks, dialTCP, listen, dialUDP, listenPacket)
|
|
|
|
if s != nil && s.QuicParams != nil {
|
|
mss.QuicParams = s.QuicParams
|
|
}
|
|
|
|
return mss, nil
|
|
}
|