mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-22 06:28:35 +00:00
Three types of ALPN for post-handshake records detection & imitation
https://github.com/XTLS/Xray-core/issues/4778#issuecomment-3072047745
This commit is contained in:
parent
e62c4aed0d
commit
05a351a645
@ -5,6 +5,7 @@ import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -16,36 +17,50 @@ var GlobalPostHandshakeRecordsLens sync.Map
|
||||
|
||||
func DetectPostHandshakeRecordsLens(config *Config) {
|
||||
for sni := range config.ServerNames {
|
||||
key := config.Dest + " " + sni
|
||||
if _, loaded := GlobalPostHandshakeRecordsLens.LoadOrStore(key, false); !loaded {
|
||||
go func() {
|
||||
defer func() {
|
||||
val, _ := GlobalPostHandshakeRecordsLens.Load(key)
|
||||
if _, ok := val.(bool); ok {
|
||||
GlobalPostHandshakeRecordsLens.Store(key, []int{})
|
||||
}
|
||||
}()
|
||||
target, err := net.Dial("tcp", config.Dest)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if config.Xver == 1 || config.Xver == 2 {
|
||||
if _, err = proxyproto.HeaderProxyFromAddrs(config.Xver, target.LocalAddr(), target.RemoteAddr()).WriteTo(target); err != nil {
|
||||
for alpn := range 3 { // 0, 1, 2
|
||||
key := config.Dest + " " + sni + " " + strconv.Itoa(alpn)
|
||||
if _, loaded := GlobalPostHandshakeRecordsLens.LoadOrStore(key, false); !loaded {
|
||||
go func() {
|
||||
defer func() {
|
||||
val, _ := GlobalPostHandshakeRecordsLens.Load(key)
|
||||
if _, ok := val.(bool); ok {
|
||||
GlobalPostHandshakeRecordsLens.Store(key, []int{})
|
||||
}
|
||||
}()
|
||||
target, err := net.Dial("tcp", config.Dest)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
detectConn := &DetectConn{
|
||||
Conn: target,
|
||||
Key: key,
|
||||
}
|
||||
uConn := utls.UClient(detectConn, &utls.Config{
|
||||
ServerName: sni, // needs new loopvar behaviour
|
||||
}, utls.HelloChrome_Auto)
|
||||
if err = uConn.Handshake(); err != nil {
|
||||
return
|
||||
}
|
||||
io.Copy(io.Discard, uConn)
|
||||
}()
|
||||
if config.Xver == 1 || config.Xver == 2 {
|
||||
if _, err = proxyproto.HeaderProxyFromAddrs(config.Xver, target.LocalAddr(), target.RemoteAddr()).WriteTo(target); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
detectConn := &DetectConn{
|
||||
Conn: target,
|
||||
Key: key,
|
||||
}
|
||||
fingerprint := utls.HelloChrome_Auto
|
||||
nextProtos := []string{"h2", "http/1.1"}
|
||||
if alpn != 2 {
|
||||
fingerprint = utls.HelloGolang
|
||||
}
|
||||
if alpn == 1 {
|
||||
nextProtos = []string{"http/1.1"}
|
||||
}
|
||||
if alpn == 0 {
|
||||
nextProtos = nil
|
||||
}
|
||||
uConn := utls.UClient(detectConn, &utls.Config{
|
||||
ServerName: sni, // needs new loopvar behaviour
|
||||
NextProtos: nextProtos,
|
||||
}, fingerprint)
|
||||
if err = uConn.Handshake(); err != nil {
|
||||
return
|
||||
}
|
||||
io.Copy(io.Discard, uConn)
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
tls.go
10
tls.go
@ -371,7 +371,15 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
|
||||
break
|
||||
}
|
||||
for {
|
||||
if val, ok := GlobalPostHandshakeRecordsLens.Load(config.Dest + " " + hs.clientHello.serverName); ok {
|
||||
key := config.Dest + " " + hs.clientHello.serverName
|
||||
if len(hs.clientHello.alpnProtocols) == 0 {
|
||||
key += " 0"
|
||||
} else if hs.clientHello.alpnProtocols[0] == "h2" {
|
||||
key += " 2"
|
||||
} else {
|
||||
key += " 1"
|
||||
}
|
||||
if val, ok := GlobalPostHandshakeRecordsLens.Load(key); ok {
|
||||
if postHandshakeRecordsLens, ok := val.([]int); ok {
|
||||
for _, length := range postHandshakeRecordsLens {
|
||||
plainText := make([]byte, length-16)
|
||||
|
Loading…
Reference in New Issue
Block a user