mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-26 16:58:47 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4add189c24 |
+8
-12
@@ -17,7 +17,7 @@ import (
|
|||||||
type Holder struct {
|
type Holder struct {
|
||||||
domainToIP cache.Lru
|
domainToIP cache.Lru
|
||||||
ipRange *net.IPNet
|
ipRange *net.IPNet
|
||||||
mu *sync.Mutex
|
mu sync.Mutex
|
||||||
|
|
||||||
config *FakeDnsPool
|
config *FakeDnsPool
|
||||||
}
|
}
|
||||||
@@ -49,9 +49,7 @@ func (fkdns *Holder) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fkdns *Holder) Close() error {
|
func (fkdns *Holder) Close() error {
|
||||||
fkdns.domainToIP = nil
|
// nothing to do for now, just wait GC
|
||||||
fkdns.ipRange = nil
|
|
||||||
fkdns.mu = nil
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +68,7 @@ func NewFakeDNSHolder() (*Holder, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) {
|
func NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) {
|
||||||
return &Holder{nil, nil, nil, conf}, nil
|
return &Holder{config: conf}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fkdns *Holder) initializeFromConfig() error {
|
func (fkdns *Holder) initializeFromConfig() error {
|
||||||
@@ -92,7 +90,6 @@ func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
|
|||||||
}
|
}
|
||||||
fkdns.domainToIP = cache.NewLru(lruSize)
|
fkdns.domainToIP = cache.NewLru(lruSize)
|
||||||
fkdns.ipRange = ipRange
|
fkdns.ipRange = ipRange
|
||||||
fkdns.mu = new(sync.Mutex)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +100,7 @@ func (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address {
|
|||||||
if v, ok := fkdns.domainToIP.Get(domain); ok {
|
if v, ok := fkdns.domainToIP.Get(domain); ok {
|
||||||
return []net.Address{v.(net.Address)}
|
return []net.Address{v.(net.Address)}
|
||||||
}
|
}
|
||||||
currentTimeMillis := uint64(time.Now().UnixNano() / 1e6)
|
currentTimeMillis := uint64(time.Now().UnixMilli())
|
||||||
ones, bits := fkdns.ipRange.Mask.Size()
|
ones, bits := fkdns.ipRange.Mask.Size()
|
||||||
rooms := bits - ones
|
rooms := bits - ones
|
||||||
if rooms < 64 {
|
if rooms < 64 {
|
||||||
@@ -202,12 +199,11 @@ func (h *HolderMulti) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *HolderMulti) Close() error {
|
func (h *HolderMulti) Close() error {
|
||||||
|
var errs []error
|
||||||
for _, v := range h.holders {
|
for _, v := range h.holders {
|
||||||
if err := v.Close(); err != nil {
|
errs = append(errs, v.Close())
|
||||||
return errors.New("Cannot close all fake dns pools").Base(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return errors.Combine(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HolderMulti) createHolderGroups() error {
|
func (h *HolderMulti) createHolderGroups() error {
|
||||||
@@ -222,7 +218,7 @@ func (h *HolderMulti) createHolderGroups() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) {
|
func NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) {
|
||||||
holderMulti := &HolderMulti{nil, conf}
|
holderMulti := &HolderMulti{config: conf}
|
||||||
if err := holderMulti.createHolderGroups(); err != nil {
|
if err := holderMulti.createHolderGroups(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"math/big"
|
"math/big"
|
||||||
"slices"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
utls "github.com/refraction-networking/utls"
|
utls "github.com/refraction-networking/utls"
|
||||||
@@ -91,24 +90,18 @@ func (c *UConn) HandshakeContextServerName(ctx context.Context) string {
|
|||||||
return c.ConnectionState().ServerName
|
return c.ConnectionState().ServerName
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebsocketHandshakeContext basically calls UConn.Handshake inside it but it will try
|
// WebsocketHandshake basically calls UConn.Handshake inside it but it will only send
|
||||||
// to build outer ALPN to `http/1.1` or `h2 http/1.1` (if manually specified for camouflage)
|
// http/1.1 in its ALPN.
|
||||||
func (c *UConn) WebsocketHandshakeContext(ctx context.Context) error {
|
func (c *UConn) WebsocketHandshakeContext(ctx context.Context) error {
|
||||||
config := *utils.AccessField[*utls.Config](c, "config")
|
|
||||||
ALPN := slices.Clone(config.NextProtos)
|
|
||||||
// set other kinds of ALPN to http/1.1
|
|
||||||
if !slices.Equal(ALPN, []string{"h2", "http/1.1"}) {
|
|
||||||
ALPN = []string{"http/1.1"}
|
|
||||||
}
|
|
||||||
// Build the handshake state. This will apply every variable of the TLS of the
|
// Build the handshake state. This will apply every variable of the TLS of the
|
||||||
// fingerprint in the UConn
|
// fingerprint in the UConn
|
||||||
if err := c.BuildHandshakeState(); err != nil {
|
if err := c.BuildHandshakeState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Do not modify outer ALPN if ECH is used
|
config := *utils.AccessField[*utls.Config](c, "config")
|
||||||
// Outer ALPN will be h2,http/1.1, and real http/1.1 in config will be hidden in ECH
|
// Do not modify outer ALPN to http/1.1 if ECH is used
|
||||||
|
// Outer ALPN will be h2,http/1.1, and real ALPN in config will be hidden in ECH
|
||||||
if config.EncryptedClientHelloConfigList != nil {
|
if config.EncryptedClientHelloConfigList != nil {
|
||||||
config.NextProtos = []string{"http/1.1"}
|
|
||||||
return c.HandshakeContext(ctx)
|
return c.HandshakeContext(ctx)
|
||||||
}
|
}
|
||||||
// Iterate over extensions and check for utls.ALPNExtension
|
// Iterate over extensions and check for utls.ALPNExtension
|
||||||
@@ -116,12 +109,12 @@ func (c *UConn) WebsocketHandshakeContext(ctx context.Context) error {
|
|||||||
for _, extension := range c.Extensions {
|
for _, extension := range c.Extensions {
|
||||||
if alpn, ok := extension.(*utls.ALPNExtension); ok {
|
if alpn, ok := extension.(*utls.ALPNExtension); ok {
|
||||||
hasALPNExtension = true
|
hasALPNExtension = true
|
||||||
alpn.AlpnProtocols = ALPN
|
alpn.AlpnProtocols = []string{"http/1.1"}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !hasALPNExtension { // Append extension if doesn't exists
|
if !hasALPNExtension { // Append extension if doesn't exists
|
||||||
c.Extensions = append(c.Extensions, &utls.ALPNExtension{AlpnProtocols: ALPN})
|
c.Extensions = append(c.Extensions, &utls.ALPNExtension{AlpnProtocols: []string{"http/1.1"}})
|
||||||
}
|
}
|
||||||
// Rebuild the client hello and do the handshake
|
// Rebuild the client hello and do the handshake
|
||||||
if err := c.BuildHandshakeState(); err != nil {
|
if err := c.BuildHandshakeState(); err != nil {
|
||||||
@@ -153,7 +146,9 @@ func copyConfig(c *tls.Config) *utls.Config {
|
|||||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
||||||
KeyLogWriter: c.KeyLogWriter,
|
KeyLogWriter: c.KeyLogWriter,
|
||||||
EncryptedClientHelloConfigList: c.EncryptedClientHelloConfigList,
|
EncryptedClientHelloConfigList: c.EncryptedClientHelloConfigList,
|
||||||
NextProtos: c.NextProtos,
|
}
|
||||||
|
if config.EncryptedClientHelloConfigList != nil {
|
||||||
|
config.NextProtos = c.NextProtos
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user