@@ -23,7 +23,7 @@ type TLSFragment struct {
2323}
2424
2525type fragmentConn struct {
26- dialer * net.Dialer
26+ dialer net.Dialer
2727 fragment TLSFragment
2828 network string
2929 destination M.Socksaddr
@@ -50,41 +50,40 @@ func (c *fragmentConn) Write(b []byte) (n int, err error) {
5050 if c .conn == nil {
5151 return 0 , c .err
5252 }
53- // Check if payload is a valid TLS clientHello packet
54- if len (b ) >= 5 && b [0 ] = = 22 {
55- clientHelloLen := int ( binary . BigEndian . Uint16 ( b [ 3 : 5 ]) )
56- clientHelloData := b [ 5 :]
57-
58- for i := 0 ; i < clientHelloLen ; {
59- fragmentEnd := i + int ( randBetween ( int64 ( c . fragment . SizeMin ), int64 ( c . fragment . SizeMax )))
60- if fragmentEnd > clientHelloLen {
61- fragmentEnd = clientHelloLen
62- }
63-
64- fragment := clientHelloData [ i : fragmentEnd ]
65- i = fragmentEnd
66-
67- header := make ([]byte , 5 )
68- header [0 ] = b [0 ]
69- binary .BigEndian .PutUint16 (header [1 :], binary .BigEndian .Uint16 (b [1 :3 ]))
70- binary .BigEndian .PutUint16 (header [3 :], uint16 (len ( fragment ) ))
71- payload := append (header , fragment ... )
72-
73- _ , err := c .conn .Write (payload )
74- if err != nil {
75- c .err = err
76- return 0 , c .err
77- }
78-
79- randomInterval := randBetween ( int64 ( c .fragment .SleepMin ), int64 ( c . fragment . SleepMax ))
80- time .Sleep (time .Duration (randomInterval ) )
53+ // Do not fragment if it's not a TLS clientHello packet
54+ if len (b ) < 5 || b [0 ] ! = 22 {
55+ return c . conn . Write ( b )
56+ }
57+
58+ clientHelloLen := int ( binary . BigEndian . Uint16 ( b [ 3 : 5 ]))
59+ clientHelloData := b [ 5 :]
60+
61+ for fragmentStart := 0 ; fragmentStart < clientHelloLen ; {
62+ fragmentEnd := fragmentStart + int ( randBetween ( int64 ( c . fragment . SizeMin ), int64 ( c . fragment . SizeMax )))
63+ if fragmentEnd > clientHelloLen {
64+ fragmentEnd = clientHelloLen
65+ }
66+
67+ header := make ([]byte , 5 )
68+ header [0 ] = b [0 ]
69+ binary .BigEndian .PutUint16 (header [1 :], binary .BigEndian .Uint16 (b [1 :3 ]))
70+ binary .BigEndian .PutUint16 (header [3 :], uint16 (fragmentEnd - fragmentStart ))
71+ payload := append (header , clientHelloData [ fragmentStart : fragmentEnd ] ... )
72+
73+ _ , err := c .conn .Write (payload )
74+ if err != nil {
75+ c .err = err
76+ return 0 , c .err
77+ }
78+
79+ if c .fragment .SleepMax != 0 {
80+ time .Sleep (time .Duration (randBetween ( int64 ( c . fragment . SleepMin ), int64 ( c . fragment . SleepMax ))) * time . Millisecond )
8181 }
8282
83- return len ( b ), nil
83+ fragmentStart = fragmentEnd
8484 }
8585
86- // Write directly if not a clientHello packet
87- return c .conn .Write (b )
86+ return len (b ), nil
8887}
8988
9089func (c * fragmentConn ) Close () error {
0 commit comments