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