@@ -39,7 +39,7 @@ var HintMap = map[string]uint32{
3939 "keep-alive" : HINT_KEEPALIVE ,
4040}
4141
42- func (outbound * Outbound ) dial (host string , port int , b []byte , offset int , length int ) (net.Conn , * ConnectionInfo , error ) {
42+ func (outbound * Outbound ) dial (host string , port int , header []byte , offset int , length int ) (net.Conn , * ConnectionInfo , error ) {
4343 var conn net.Conn
4444 raddrs , err := outbound .GetRemoteAddresses (host , port )
4545 if err != nil {
@@ -51,11 +51,14 @@ func (outbound *Outbound) dial(host string, port int, b []byte, offset int, leng
5151 tfo := hint & HINT_TFO != 0
5252 keepalive := hint & HINT_KEEPALIVE != 0
5353 timeout := time .Millisecond * time .Duration (outbound .Timeout )
54+ headerLen := len (header )
5455
5556 var raddr * net.TCPAddr = nil
5657 var laddr * net.TCPAddr = nil
57- for i := 0 ; i < len (raddrs ); i ++ {
58- raddr = raddrs [mathrand .Intn (len (raddrs ))]
58+ raddr_index := mathrand .Intn (len (raddrs ))
59+ raddrs_len := len (raddrs )
60+ for i := 0 ; i < raddrs_len ; i ++ {
61+ raddr = raddrs [(i + raddr_index ) % raddrs_len ]
5962 if device != "" {
6063 if laddr , err = GetLocalTCPAddr (device , raddr .IP .To4 () == nil ); err != nil {
6164 return nil , nil , err
@@ -67,13 +70,13 @@ func (outbound *Outbound) dial(host string, port int, b []byte, offset int, leng
6770 break
6871 }
6972 }
70-
73+
7174 if err != nil {
7275 return nil , nil , err
7376 }
7477
7578 if hint & HINT_TLS1_3 != 0 {
76- b [2 ] = 0x4
79+ header [2 ] = 0x4
7780 }
7881
7982 if tfo {
@@ -98,7 +101,7 @@ func (outbound *Outbound) dial(host string, port int, b []byte, offset int, leng
98101 }
99102 }
100103
101- TFOLen := len ( b )
104+ TFOLen := headerLen
102105 if hint & (HINT_TCPFRAG ) != 0 {
103106 TFOLen = offset + length / 2
104107 }
@@ -107,79 +110,75 @@ func (outbound *Outbound) dial(host string, port int, b []byte, offset int, leng
107110 TFOLen = 1220
108111 }
109112
110- if _ , err = conn .Write (b [:TFOLen ]); err != nil {
113+ if _ , err = conn .Write (header [:TFOLen ]); err != nil {
111114 conn .Close ()
112115 return nil , nil , err
113116 }
114117
115- if TFOLen < len (b ) {
116- _ , err = conn .Write (b [TFOLen :])
118+ if TFOLen < headerLen {
119+ _ , err = conn .Write (header [TFOLen :])
120+ }
121+
122+ return conn , nil , err
123+ } else if hint & (HINT_OOB ) != 0 {
124+ SegOffset := 0
125+ cut := offset + length / 2
126+ if hint & (HINT_TTL ) != 0 {
127+ oob := []byte {0 }
128+ err = SendWithOption (conn , header [:offset ], header [offset :offset + 1 ], 0 , int (outbound .TTL ))
129+ err = SendWithOption (conn , header [offset + 1 :cut ], oob , 0 , 64 )
130+ SegOffset = cut
131+ } else if hint & (HINT_TCPFRAG ) != 0 {
132+ oob := [2 ]byte {header [offset ], 0 }
133+ _ , err = conn .Write (header [:1 ])
134+ time .Sleep (time .Millisecond )
135+ err = SendWithOption (conn , header [1 :offset ], oob [:], 0 , 0 )
136+ SegOffset = offset + 1
137+ } else {
138+ oob := [2 ]byte {header [2 ], 0 }
139+ err = SendWithOption (conn , header [:2 ], oob [:], 0 , 0 )
140+ SegOffset = 3
141+ }
142+
143+ if err == nil {
144+ _ , err = conn .Write (header [SegOffset :])
117145 }
118146
119147 return conn , nil , err
120148 } else if hint & (HINT_TTL | HINT_WMD5 ) != 0 {
121- fakepayload , cut := outbound .GetFakePayload (b , offset , length )
149+ fakepayload , cut := outbound .GetFakePayload (header , offset , length )
122150 fakepaylen := len (fakepayload )
123151 if fakepaylen > cut {
124152 fakepaylen = cut
125153 }
126154
127- if err = outbound .SendWithFakePayload (conn , fakepayload [:fakepaylen ], b [:fakepaylen ]); err != nil {
155+ if err = outbound .SendWithFakePayload (conn , fakepayload [:fakepaylen ], header [:fakepaylen ]); err != nil {
128156 conn .Close ()
129157 return nil , nil , err
130158 }
131159
132- if fakepaylen < len ( b ) {
133- _ , err = conn .Write (b [fakepaylen :])
160+ if fakepaylen < headerLen {
161+ _ , err = conn .Write (header [fakepaylen :])
134162 }
135163
136164 return conn , nil , err
137- } else {
138- proxyConn , err := outbound .ProxyHandshake (conn , nil , host , port )
139-
140- if err == nil && b != nil {
141- SegOffset := 0
142- cut := offset + length / 2
143- oob := []byte {0 }
144- if cut > 4 {
145- if hint & (HINT_TCPFRAG ) != 0 {
146- if hint & (HINT_OOB ) != 0 {
147- if err = SendWithOption (conn , b [0 :offset ], oob , 0 , 0 ); err == nil {
148- time .Sleep (80 * time .Millisecond )
149- err = SendWithOption (conn , b [offset :offset + 2 ], oob , 0 , 0 )
150- time .Sleep (80 * time .Millisecond )
151- }
152- SegOffset += offset + 2
153- } else {
154- if _ , err = conn .Write (b [0 :1 ]); err == nil {
155- _ , err = conn .Write (b [1 :4 ])
156- }
157- SegOffset += 4
158- }
159- } else if hint & (HINT_OOB ) != 0 {
160- err = SendWithOption (conn , b [0 :offset ], b [offset :offset + 1 ], 0 , 0 )
161- SegOffset += offset + 1
162- }
163-
164- if hint & (HINT_OOB ) != 0 {
165- cut := offset + length / 2
166- if cut > 4 && hint & HINT_OOB != 0 {
167- err = SendWithOption (conn , b [SegOffset :cut ], oob , 0 , 0 )
168- SegOffset = cut
169- }
170- }
171- }
172-
173- if err == nil {
174- _ , err = conn .Write (b [SegOffset :])
165+ } else if hint & (HINT_TCPFRAG ) != 0 {
166+ SegOffset := 0
167+ cut := offset + length / 2
168+ if cut > 4 {
169+ if _ , err = conn .Write (header [:1 ]); err == nil {
170+ _ , err = conn .Write (header [1 :4 ])
175171 }
172+ SegOffset += 4
176173 }
177174
178- if err != nil {
179- conn .Close ()
180- return nil , nil , err
175+ if err == nil {
176+ _ , err = conn .Write (header [SegOffset :])
181177 }
182178
179+ return conn , nil , err
180+ } else {
181+ proxyConn , err := outbound .ProxyHandshake (conn , nil , host , port )
183182 return proxyConn , nil , err
184183 }
185184}
0 commit comments