mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-24 15:38:36 +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"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -16,36 +17,50 @@ var GlobalPostHandshakeRecordsLens sync.Map
|
|||||||
|
|
||||||
func DetectPostHandshakeRecordsLens(config *Config) {
|
func DetectPostHandshakeRecordsLens(config *Config) {
|
||||||
for sni := range config.ServerNames {
|
for sni := range config.ServerNames {
|
||||||
key := config.Dest + " " + sni
|
for alpn := range 3 { // 0, 1, 2
|
||||||
if _, loaded := GlobalPostHandshakeRecordsLens.LoadOrStore(key, false); !loaded {
|
key := config.Dest + " " + sni + " " + strconv.Itoa(alpn)
|
||||||
go func() {
|
if _, loaded := GlobalPostHandshakeRecordsLens.LoadOrStore(key, false); !loaded {
|
||||||
defer func() {
|
go func() {
|
||||||
val, _ := GlobalPostHandshakeRecordsLens.Load(key)
|
defer func() {
|
||||||
if _, ok := val.(bool); ok {
|
val, _ := GlobalPostHandshakeRecordsLens.Load(key)
|
||||||
GlobalPostHandshakeRecordsLens.Store(key, []int{})
|
if _, ok := val.(bool); ok {
|
||||||
}
|
GlobalPostHandshakeRecordsLens.Store(key, []int{})
|
||||||
}()
|
}
|
||||||
target, err := net.Dial("tcp", config.Dest)
|
}()
|
||||||
if err != nil {
|
target, err := net.Dial("tcp", config.Dest)
|
||||||
return
|
if err != nil {
|
||||||
}
|
|
||||||
if config.Xver == 1 || config.Xver == 2 {
|
|
||||||
if _, err = proxyproto.HeaderProxyFromAddrs(config.Xver, target.LocalAddr(), target.RemoteAddr()).WriteTo(target); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
if config.Xver == 1 || config.Xver == 2 {
|
||||||
detectConn := &DetectConn{
|
if _, err = proxyproto.HeaderProxyFromAddrs(config.Xver, target.LocalAddr(), target.RemoteAddr()).WriteTo(target); err != nil {
|
||||||
Conn: target,
|
return
|
||||||
Key: key,
|
}
|
||||||
}
|
}
|
||||||
uConn := utls.UClient(detectConn, &utls.Config{
|
detectConn := &DetectConn{
|
||||||
ServerName: sni, // needs new loopvar behaviour
|
Conn: target,
|
||||||
}, utls.HelloChrome_Auto)
|
Key: key,
|
||||||
if err = uConn.Handshake(); err != nil {
|
}
|
||||||
return
|
fingerprint := utls.HelloChrome_Auto
|
||||||
}
|
nextProtos := []string{"h2", "http/1.1"}
|
||||||
io.Copy(io.Discard, uConn)
|
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
|
break
|
||||||
}
|
}
|
||||||
for {
|
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 {
|
if postHandshakeRecordsLens, ok := val.([]int); ok {
|
||||||
for _, length := range postHandshakeRecordsLens {
|
for _, length := range postHandshakeRecordsLens {
|
||||||
plainText := make([]byte, length-16)
|
plainText := make([]byte, length-16)
|
||||||
|
Loading…
Reference in New Issue
Block a user