Skip to content

Commit 4bc3d49

Browse files
committed
Merge remote-tracking branch 'upstream/Alpha' into Alpha
2 parents 69423f0 + fd74ecb commit 4bc3d49

6 files changed

Lines changed: 55 additions & 18 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ jobs:
362362
shell: bash
363363

364364
- name: Tag Repo
365-
uses: richardsimko/update-tag@v1
365+
uses: richardsimko/update-tag@v3
366366
with:
367367
tag_name: Prerelease-${{ github.ref_name }}
368368
env:

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ require (
2727
github.com/metacubex/jls-tls v0.0.0-20260723084315-67adc0e2f796
2828
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604
2929
github.com/metacubex/mhurl v0.1.0
30-
github.com/metacubex/mipstack v0.0.0-20260826102845-dc187ebcbdc7
30+
github.com/metacubex/mipstack v0.0.0-20260902082959-c7e60ae7a02a
3131
github.com/metacubex/mlkem v0.1.0
3232
github.com/metacubex/quic-go v0.61.1-0.20260727080200-2548683b76f4
3333
github.com/metacubex/randv2 v0.2.0
3434
github.com/metacubex/restls-client-go v0.1.9
3535
github.com/metacubex/sevenzip v1.6.4
3636
github.com/metacubex/sing v0.5.7
3737
github.com/metacubex/sing-mux v0.3.10
38-
github.com/metacubex/sing-quic v0.0.0-20260726014900-38b0e9295f51
38+
github.com/metacubex/sing-quic v0.0.0-20260904234848-1c242664697a
3939
github.com/metacubex/sing-shadowsocks v0.2.12
4040
github.com/metacubex/sing-shadowsocks2 v0.2.7
4141
github.com/metacubex/sing-tun v0.4.22

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604 h1:hJwCVlE3ojViC3
133133
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604/go.mod h1:lpmN3m269b3V5jFCWtffqBLS4U3QQoIid9ugtO+OhVc=
134134
github.com/metacubex/mhurl v0.1.0 h1:ZdW4Zxe3j3uJ89gNytOazHu6kbHn5owutN/VfXOI8GE=
135135
github.com/metacubex/mhurl v0.1.0/go.mod h1:2qpQImCbXoUs6GwJrjuEXKelPyoimsIXr07eNKZdS00=
136-
github.com/metacubex/mipstack v0.0.0-20260826102845-dc187ebcbdc7 h1:3wIzjgx+tJmlvKUT3zQG1VFkn7825Pyqj41BvgstpdE=
137-
github.com/metacubex/mipstack v0.0.0-20260826102845-dc187ebcbdc7/go.mod h1:+bbwALZI0pbi2auSG5A3ptdpV2DZ2eLObziXo+P7oj0=
136+
github.com/metacubex/mipstack v0.0.0-20260902082959-c7e60ae7a02a h1:WMeY2354p4XDjHIo+1CrXfMRhIq7JhxMEBwty+BN+ts=
137+
github.com/metacubex/mipstack v0.0.0-20260902082959-c7e60ae7a02a/go.mod h1:+bbwALZI0pbi2auSG5A3ptdpV2DZ2eLObziXo+P7oj0=
138138
github.com/metacubex/mlkem v0.1.0 h1:wFClitonSFcmipzzQvax75beLQU+D7JuC+VK1RzSL8I=
139139
github.com/metacubex/mlkem v0.1.0/go.mod h1:amhaXZVeYNShuy9BILcR7P0gbeo/QLZsnqCdL8U2PDQ=
140140
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb h1:wk6mHYPURSUvWcUv72gNP79oiylFsscBSDPJ6ieV6Iw=
@@ -155,8 +155,8 @@ github.com/metacubex/sing v0.5.7 h1:8OC+fhKFSv/l9ehEhJRaZZAOuthfZo68SteBVLe8QqM=
155155
github.com/metacubex/sing v0.5.7/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
156156
github.com/metacubex/sing-mux v0.3.10 h1:r5CuZ/KuwFsEcRRwpLvzLncW4fDzNfmSEcBEWcy/+94=
157157
github.com/metacubex/sing-mux v0.3.10/go.mod h1:8bT7ZKT3clRrJjYc/x5CRYibC1TX/bK73a3r3+2E+Fc=
158-
github.com/metacubex/sing-quic v0.0.0-20260726014900-38b0e9295f51 h1:FpQj1XfYBIm4LAml+LDjvnfjDs20cSDsFmgjThOqmks=
159-
github.com/metacubex/sing-quic v0.0.0-20260726014900-38b0e9295f51/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
158+
github.com/metacubex/sing-quic v0.0.0-20260904234848-1c242664697a h1:qZzQwtWDrPU1LXoMow0/iLHY3mb7uauS/mho8hYcenE=
159+
github.com/metacubex/sing-quic v0.0.0-20260904234848-1c242664697a/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
160160
github.com/metacubex/sing-shadowsocks v0.2.12 h1:Wqzo8bYXrK5aWqxu/TjlTnYZzAKtKsaFQBdr6IHFaBE=
161161
github.com/metacubex/sing-shadowsocks v0.2.12/go.mod h1:2e5EIaw0rxKrm1YTRmiMnDulwbGxH9hAFlrwQLQMQkU=
162162
github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6wVj3PPBVhor3A=

transport/hysteria/core/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ func (c *Client) DialUDP(dialer utils.PacketDialer) (UDPConn, error) {
230230
}
231231
// Send request
232232
err = WriteClientRequest(stream, ClientRequest{
233-
UDP: false,
233+
UDP: true,
234234
})
235235
if err != nil {
236236
_ = stream.Close()

transport/hysteria/core/protocol.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (m udpMessage) Size() int {
248248
}
249249

250250
func (m udpMessage) Pack() []byte {
251-
data := make([]byte, m.Size())
251+
data := make([]byte, 0, m.Size())
252252
buffer := bytes.NewBuffer(data)
253253
_ = binary.Write(buffer, binary.BigEndian, m.SessionID)
254254
_ = binary.Write(buffer, binary.BigEndian, uint16(len(m.Host)))

transport/trusttunnel/client.go

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import (
1111
"sync/atomic"
1212
"time"
1313

14+
atomic2 "github.com/metacubex/mihomo/common/atomic"
1415
"github.com/metacubex/mihomo/common/httputils"
1516
"github.com/metacubex/mihomo/common/once"
1617
"github.com/metacubex/mihomo/component/dialer"
1718
C "github.com/metacubex/mihomo/constant"
1819
"github.com/metacubex/mihomo/transport/vmess"
1920

2021
"github.com/metacubex/http"
22+
"github.com/metacubex/http/httptrace"
2123
"golang.org/x/exp/slices"
2224
)
2325

@@ -139,7 +141,7 @@ func (c *Client) resetHealthCheckTimer() {
139141
c.healthCheckTimer.Reset(DefaultHealthCheckTimeout)
140142
}
141143

142-
func (c *Client) roundTrip(request *http.Request, conn *httpConn) {
144+
func (c *Client) roundTrip(ctx context.Context, request *http.Request, conn *httpConn) error {
143145
c.startOnce.Do(c.start)
144146
pipeReader, pipeWriter := io.Pipe()
145147
request.Body = pipeReader
@@ -151,20 +153,36 @@ func (c *Client) roundTrip(request *http.Request, conn *httpConn) {
151153
conn.closeFn = once.OnceFunc(func() {
152154
c.count.Add(-1)
153155
})
154-
ctx, cancel := context.WithCancel(c.ctx) // requestCtx must alive during conn not closed
155-
conn.cancelFn = cancel // cancel ctx when conn closed
156+
requestCtx, cancel := context.WithCancel(c.ctx) // requestCtx must alive during conn not closed
157+
conn.cancelFn = cancel // cancel ctx when conn closed
158+
159+
// Use gotConn to detect when TCP connection is established, so we can
160+
// return the conn immediately without waiting for the HTTP response.
161+
gotConn := make(chan bool, 1)
162+
addrCtx := httputils.NewAddrContext(&conn.NetAddr, requestCtx)
163+
streamCtx := httptrace.WithClientTrace(addrCtx, &httptrace.ClientTrace{
164+
GotConn: func(info httptrace.GotConnInfo) {
165+
select {
166+
case gotConn <- true:
167+
default: // GotConn maybe called multiple times, ignore the second and later calls
168+
}
169+
},
170+
})
171+
172+
var requestErr atomic2.TypedValue[error]
156173
go func() {
157-
timeout := time.AfterFunc(C.DefaultTCPTimeout, cancel) // only cancel when RoundTrip timeout
158-
defer timeout.Stop() // RoundTrip already returned, stop the timer
159-
request = request.WithContext(httputils.NewAddrContext(&conn.NetAddr, ctx))
174+
request = request.WithContext(streamCtx)
160175
response, err := c.roundTripper.RoundTrip(request)
161176
if err != nil {
177+
requestErr.Store(err)
178+
close(gotConn)
162179
_ = pipeWriter.CloseWithError(err)
163180
_ = pipeReader.CloseWithError(err)
164181
conn.setup(nil, err)
165182
} else if response.StatusCode != http.StatusOK {
166183
_ = response.Body.Close()
167184
err = fmt.Errorf("unexpected status code: %d", response.StatusCode)
185+
requestErr.Store(err)
168186
_ = pipeWriter.CloseWithError(err)
169187
_ = pipeReader.CloseWithError(err)
170188
conn.setup(nil, err)
@@ -173,6 +191,13 @@ func (c *Client) roundTrip(request *http.Request, conn *httpConn) {
173191
conn.setup(response.Body, nil)
174192
}
175193
}()
194+
195+
select {
196+
case <-ctx.Done():
197+
return ctx.Err()
198+
case <-gotConn:
199+
return requestErr.Load()
200+
}
176201
}
177202

178203
func (c *Client) newConnectRequest(host, userAgent string) *http.Request {
@@ -193,21 +218,33 @@ func (c *Client) newConnectRequest(host, userAgent string) *http.Request {
193218
func (c *Client) Dial(ctx context.Context, host string) (net.Conn, error) {
194219
request := c.newConnectRequest(host, TCPUserAgent)
195220
conn := &tcpConn{}
196-
c.roundTrip(request, &conn.httpConn)
221+
err := c.roundTrip(ctx, request, &conn.httpConn)
222+
if err != nil {
223+
_ = conn.Close()
224+
return nil, err
225+
}
197226
return conn, nil
198227
}
199228

200229
func (c *Client) ListenPacket(ctx context.Context) (net.PacketConn, error) {
201230
request := c.newConnectRequest(UDPMagicAddress, UDPUserAgent)
202231
conn := &clientPacketConn{}
203-
c.roundTrip(request, &conn.httpConn)
232+
err := c.roundTrip(ctx, request, &conn.httpConn)
233+
if err != nil {
234+
_ = conn.Close()
235+
return nil, err
236+
}
204237
return conn, nil
205238
}
206239

207240
func (c *Client) ListenICMP(ctx context.Context) (*IcmpConn, error) {
208241
request := c.newConnectRequest(ICMPMagicAddress, ICMPUserAgent)
209242
conn := &IcmpConn{}
210-
c.roundTrip(request, &conn.httpConn)
243+
err := c.roundTrip(ctx, request, &conn.httpConn)
244+
if err != nil {
245+
_ = conn.Close()
246+
return nil, err
247+
}
211248
return conn, nil
212249
}
213250

0 commit comments

Comments
 (0)