1
1
package tls
2
2
3
3
import (
4
+ "context"
4
5
"crypto/rand"
5
6
"crypto/tls"
6
7
"math/big"
8
+ "time"
7
9
8
10
utls "github.com/refraction-networking/utls"
9
11
"github.com/xtls/xray-core/common/buf"
@@ -14,7 +16,7 @@ import (
14
16
15
17
type Interface interface {
16
18
net.Conn
17
- Handshake ( ) error
19
+ HandshakeContext ( ctx context. Context ) error
18
20
VerifyHostname (host string ) error
19
21
NegotiatedProtocol () (name string , mutual bool )
20
22
}
@@ -25,15 +27,25 @@ type Conn struct {
25
27
* tls.Conn
26
28
}
27
29
30
+ const tlsCloseTimeout = 250 * time .Millisecond
31
+
32
+ func (c * Conn ) Close () error {
33
+ timer := time .AfterFunc (tlsCloseTimeout , func () {
34
+ c .Conn .NetConn ().Close ()
35
+ })
36
+ defer timer .Stop ()
37
+ return c .Conn .Close ()
38
+ }
39
+
28
40
func (c * Conn ) WriteMultiBuffer (mb buf.MultiBuffer ) error {
29
41
mb = buf .Compact (mb )
30
42
mb , err := buf .WriteMultiBuffer (c , mb )
31
43
buf .ReleaseMulti (mb )
32
44
return err
33
45
}
34
46
35
- func (c * Conn ) HandshakeAddress ( ) net.Address {
36
- if err := c .Handshake ( ); err != nil {
47
+ func (c * Conn ) HandshakeAddressContext ( ctx context. Context ) net.Address {
48
+ if err := c .HandshakeContext ( ctx ); err != nil {
37
49
return nil
38
50
}
39
51
state := c .ConnectionState ()
@@ -64,8 +76,16 @@ type UConn struct {
64
76
* utls.UConn
65
77
}
66
78
67
- func (c * UConn ) HandshakeAddress () net.Address {
68
- if err := c .Handshake (); err != nil {
79
+ func (c * UConn ) Close () error {
80
+ timer := time .AfterFunc (tlsCloseTimeout , func () {
81
+ c .Conn .NetConn ().Close ()
82
+ })
83
+ defer timer .Stop ()
84
+ return c .Conn .Close ()
85
+ }
86
+
87
+ func (c * UConn ) HandshakeAddressContext (ctx context.Context ) net.Address {
88
+ if err := c .HandshakeContext (ctx ); err != nil {
69
89
return nil
70
90
}
71
91
state := c .ConnectionState ()
@@ -77,7 +97,7 @@ func (c *UConn) HandshakeAddress() net.Address {
77
97
78
98
// WebsocketHandshake basically calls UConn.Handshake inside it but it will only send
79
99
// http/1.1 in its ALPN.
80
- func (c * UConn ) WebsocketHandshake ( ) error {
100
+ func (c * UConn ) WebsocketHandshakeContext ( ctx context. Context ) error {
81
101
// Build the handshake state. This will apply every variable of the TLS of the
82
102
// fingerprint in the UConn
83
103
if err := c .BuildHandshakeState (); err != nil {
@@ -99,7 +119,7 @@ func (c *UConn) WebsocketHandshake() error {
99
119
if err := c .BuildHandshakeState (); err != nil {
100
120
return err
101
121
}
102
- return c .Handshake ( )
122
+ return c .HandshakeContext ( ctx )
103
123
}
104
124
105
125
func (c * UConn ) NegotiatedProtocol () (name string , mutual bool ) {
@@ -118,7 +138,7 @@ func copyConfig(c *tls.Config) *utls.Config {
118
138
ServerName : c .ServerName ,
119
139
InsecureSkipVerify : c .InsecureSkipVerify ,
120
140
VerifyPeerCertificate : c .VerifyPeerCertificate ,
121
- KeyLogWriter : c .KeyLogWriter ,
141
+ KeyLogWriter : c .KeyLogWriter ,
122
142
}
123
143
}
124
144
0 commit comments