mirror of
https://github.com/XTLS/REALITY.git
synced 2026-09-22 23:08:01 +03:00
Sync upstream Go 1.20
Excluding `boring` or test files
This commit is contained in:
@@ -35,11 +35,10 @@ type Conn struct {
|
||||
isClient bool
|
||||
handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
|
||||
|
||||
// handshakeStatus is 1 if the connection is currently transferring
|
||||
// isHandshakeComplete is true if the connection is currently transferring
|
||||
// application data (i.e. is not currently processing a handshake).
|
||||
// handshakeStatus == 1 implies handshakeErr == nil.
|
||||
// This field is only to be accessed with sync/atomic.
|
||||
handshakeStatus uint32
|
||||
// isHandshakeComplete is true implies handshakeErr == nil.
|
||||
isHandshakeComplete atomic.Bool
|
||||
// constant after handshake; protected by handshakeMutex
|
||||
handshakeMutex sync.Mutex
|
||||
handshakeErr error // error resulting from handshake
|
||||
@@ -55,6 +54,9 @@ type Conn struct {
|
||||
ocspResponse []byte // stapled OCSP response
|
||||
scts [][]byte // signed certificate timestamps from server
|
||||
peerCertificates []*x509.Certificate
|
||||
// activeCertHandles contains the cache handles to certificates in
|
||||
// peerCertificates that are used to track active references.
|
||||
activeCertHandles []*activeCert
|
||||
// verifiedChains contains the certificate chains that we built, as
|
||||
// opposed to the ones presented by the server.
|
||||
verifiedChains [][]*x509.Certificate
|
||||
@@ -115,10 +117,9 @@ type Conn struct {
|
||||
// handshake, nor deliver application data. Protected by in.Mutex.
|
||||
retryCount int
|
||||
|
||||
// activeCall is an atomic int32; the low bit is whether Close has
|
||||
// been called. the rest of the bits are the number of goroutines
|
||||
// in Conn.Write.
|
||||
activeCall int32
|
||||
// activeCall indicates whether Close has been call in the low bit.
|
||||
// the rest of the bits are the number of goroutines in Conn.Write.
|
||||
activeCall atomic.Int32
|
||||
|
||||
tmp [16]byte
|
||||
}
|
||||
@@ -639,7 +640,7 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
|
||||
if c.in.err != nil {
|
||||
return c.in.err
|
||||
}
|
||||
handshakeComplete := c.handshakeComplete()
|
||||
handshakeComplete := c.isHandshakeComplete.Load()
|
||||
|
||||
// This function modifies c.rawInput, which owns the c.input memory.
|
||||
if c.input.Len() != 0 {
|
||||
@@ -1154,15 +1155,15 @@ var (
|
||||
func (c *Conn) Write(b []byte) (int, error) {
|
||||
// interlock with Close below
|
||||
for {
|
||||
x := atomic.LoadInt32(&c.activeCall)
|
||||
x := c.activeCall.Load()
|
||||
if x&1 != 0 {
|
||||
return 0, net.ErrClosed
|
||||
}
|
||||
if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
|
||||
if c.activeCall.CompareAndSwap(x, x+2) {
|
||||
break
|
||||
}
|
||||
}
|
||||
defer atomic.AddInt32(&c.activeCall, -2)
|
||||
defer c.activeCall.Add(-2)
|
||||
|
||||
if err := c.Handshake(); err != nil {
|
||||
return 0, err
|
||||
@@ -1175,7 +1176,7 @@ func (c *Conn) Write(b []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !c.handshakeComplete() {
|
||||
if !c.isHandshakeComplete.Load() {
|
||||
return 0, alertInternalError
|
||||
}
|
||||
|
||||
@@ -1245,7 +1246,7 @@ func (c *Conn) handleRenegotiation() error {
|
||||
c.handshakeMutex.Lock()
|
||||
defer c.handshakeMutex.Unlock()
|
||||
|
||||
atomic.StoreUint32(&c.handshakeStatus, 0)
|
||||
c.isHandshakeComplete.Store(false)
|
||||
if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
|
||||
c.handshakes++
|
||||
}
|
||||
@@ -1363,11 +1364,11 @@ func (c *Conn) Close() error {
|
||||
// Interlock with Conn.Write above.
|
||||
var x int32
|
||||
for {
|
||||
x = atomic.LoadInt32(&c.activeCall)
|
||||
x = c.activeCall.Load()
|
||||
if x&1 != 0 {
|
||||
return net.ErrClosed
|
||||
}
|
||||
if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) {
|
||||
if c.activeCall.CompareAndSwap(x, x|1) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -1382,7 +1383,7 @@ func (c *Conn) Close() error {
|
||||
}
|
||||
|
||||
var alertErr error
|
||||
if c.handshakeComplete() {
|
||||
if c.isHandshakeComplete.Load() {
|
||||
if err := c.closeNotify(); err != nil {
|
||||
alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
|
||||
}
|
||||
@@ -1400,7 +1401,7 @@ var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake com
|
||||
// called once the handshake has completed and does not call CloseWrite on the
|
||||
// underlying connection. Most callers should just use Close.
|
||||
func (c *Conn) CloseWrite() error {
|
||||
if !c.handshakeComplete() {
|
||||
if !c.isHandshakeComplete.Load() {
|
||||
return errEarlyCloseWrite
|
||||
}
|
||||
|
||||
@@ -1454,7 +1455,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||
// Fast sync/atomic-based exit if there is no handshake in flight and the
|
||||
// last one succeeded without an error. Avoids the expensive context setup
|
||||
// and mutex for most Read and Write calls.
|
||||
if c.handshakeComplete() {
|
||||
if c.isHandshakeComplete.Load() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1497,7 +1498,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||
if err := c.handshakeErr; err != nil {
|
||||
return err
|
||||
}
|
||||
if c.handshakeComplete() {
|
||||
if c.isHandshakeComplete.Load() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1513,10 +1514,10 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||
c.flush()
|
||||
}
|
||||
|
||||
if c.handshakeErr == nil && !c.handshakeComplete() {
|
||||
if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
|
||||
c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
|
||||
}
|
||||
if c.handshakeErr != nil && c.handshakeComplete() {
|
||||
if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
|
||||
panic("tls: internal error: handshake returned an error but is marked successful")
|
||||
}
|
||||
|
||||
@@ -1532,7 +1533,7 @@ func (c *Conn) ConnectionState() ConnectionState {
|
||||
|
||||
func (c *Conn) connectionStateLocked() ConnectionState {
|
||||
var state ConnectionState
|
||||
state.HandshakeComplete = c.handshakeComplete()
|
||||
state.HandshakeComplete = c.isHandshakeComplete.Load()
|
||||
state.Version = c.vers
|
||||
state.NegotiatedProtocol = c.clientProtocol
|
||||
state.DidResume = c.didResume
|
||||
@@ -1576,7 +1577,7 @@ func (c *Conn) VerifyHostname(host string) error {
|
||||
if !c.isClient {
|
||||
return errors.New("tls: VerifyHostname called on TLS server connection")
|
||||
}
|
||||
if !c.handshakeComplete() {
|
||||
if !c.isHandshakeComplete.Load() {
|
||||
return errors.New("tls: handshake has not yet been performed")
|
||||
}
|
||||
if len(c.verifiedChains) == 0 {
|
||||
@@ -1584,7 +1585,3 @@ func (c *Conn) VerifyHostname(host string) error {
|
||||
}
|
||||
return c.peerCertificates[0].VerifyHostname(host)
|
||||
}
|
||||
|
||||
func (c *Conn) handshakeComplete() bool {
|
||||
return atomic.LoadUint32(&c.handshakeStatus) == 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user