55 "encoding/binary"
66 "io"
77 "net"
8+ "strconv"
89 "sync"
910 "time"
1011
@@ -16,36 +17,50 @@ var GlobalPostHandshakeRecordsLens sync.Map
1617
1718func DetectPostHandshakeRecordsLens (config * Config ) {
1819 for sni := range config .ServerNames {
19- key := config .Dest + " " + sni
20- if _ , loaded := GlobalPostHandshakeRecordsLens .LoadOrStore (key , false ); ! loaded {
21- go func () {
22- defer func () {
23- val , _ := GlobalPostHandshakeRecordsLens .Load (key )
24- if _ , ok := val .(bool ); ok {
25- GlobalPostHandshakeRecordsLens .Store (key , []int {})
20+ for alpn := range 3 { // 0, 1, 2
21+ key := config .Dest + " " + sni + " " + strconv .Itoa (alpn )
22+ if _ , loaded := GlobalPostHandshakeRecordsLens .LoadOrStore (key , false ); ! loaded {
23+ go func () {
24+ defer func () {
25+ val , _ := GlobalPostHandshakeRecordsLens .Load (key )
26+ if _ , ok := val .(bool ); ok {
27+ GlobalPostHandshakeRecordsLens .Store (key , []int {})
28+ }
29+ }()
30+ target , err := net .Dial ("tcp" , config .Dest )
31+ if err != nil {
32+ return
2633 }
27- }()
28- target , err := net .Dial ("tcp" , config .Dest )
29- if err != nil {
30- return
31- }
32- if config .Xver == 1 || config .Xver == 2 {
33- if _ , err = proxyproto .HeaderProxyFromAddrs (config .Xver , target .LocalAddr (), target .RemoteAddr ()).WriteTo (target ); err != nil {
34+ if config .Xver == 1 || config .Xver == 2 {
35+ if _ , err = proxyproto .HeaderProxyFromAddrs (config .Xver , target .LocalAddr (), target .RemoteAddr ()).WriteTo (target ); err != nil {
36+ return
37+ }
38+ }
39+ detectConn := & DetectConn {
40+ Conn : target ,
41+ Key : key ,
42+ }
43+ fingerprint := utls .HelloChrome_Auto
44+ nextProtos := []string {"h2" , "http/1.1" }
45+ if alpn != 2 {
46+ fingerprint = utls .HelloGolang
47+ }
48+ if alpn == 1 {
49+ nextProtos = []string {"http/1.1" }
50+ }
51+ if alpn == 0 {
52+ nextProtos = nil
53+ }
54+ uConn := utls .UClient (detectConn , & utls.Config {
55+ ServerName : sni , // needs new loopvar behaviour
56+ NextProtos : nextProtos ,
57+ }, fingerprint )
58+ if err = uConn .Handshake (); err != nil {
3459 return
3560 }
36- }
37- detectConn := & DetectConn {
38- Conn : target ,
39- Key : key ,
40- }
41- uConn := utls .UClient (detectConn , & utls.Config {
42- ServerName : sni , // needs new loopvar behaviour
43- }, utls .HelloChrome_Auto )
44- if err = uConn .Handshake (); err != nil {
45- return
46- }
47- io .Copy (io .Discard , uConn )
48- }()
61+ io .Copy (io .Discard , uConn )
62+ }()
63+ }
4964 }
5065 }
5166}
0 commit comments