mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-22 14:38:35 +00:00
Delay and detect H2 settings frame
Do not send fake H2 settings packet if the upper level (xhttp) will send the real packet
This commit is contained in:
parent
49f5025763
commit
5eeac447fe
42
conn.go
42
conn.go
@ -29,6 +29,8 @@ type Conn struct {
|
||||
ClientVer [3]byte
|
||||
ClientTime time.Time
|
||||
ClientShortId [8]byte
|
||||
PostHandshakeRecord []TrafficPacket
|
||||
PosthandshakeMutex sync.Mutex
|
||||
|
||||
// constant
|
||||
conn net.Conn
|
||||
@ -1314,10 +1316,50 @@ func (c *Conn) Write(b []byte) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
c.PosthandshakeMutex.Lock()
|
||||
if c.PostHandshakeRecord != nil {
|
||||
for _, packet := range c.PostHandshakeRecord {
|
||||
for i, length := range packet.Lens {
|
||||
if length <= 100 && i == len(packet.Lens) - 1 && isH2Settings(b) {
|
||||
fmt.Printf("REALITY skip fake H2 Settings frame len(postHandshakeRecord): %v\n", length)
|
||||
} else {
|
||||
plainText := make([]byte, length-16)
|
||||
plainText[0] = 23
|
||||
plainText[1] = 3
|
||||
plainText[2] = 3
|
||||
plainText[3] = byte((length - 5) >> 8)
|
||||
plainText[4] = byte((length - 5))
|
||||
plainText[5] = 23
|
||||
postHandshakeRecord := c.out.cipher.(aead).Seal(plainText[:5], c.out.seq[:], plainText[5:], plainText[:5])
|
||||
c.out.incSeq()
|
||||
c.write(postHandshakeRecord)
|
||||
fmt.Printf("REALITY Send with data, len(postHandshakeRecord): %v\tlen(buffer):%v\n", length, len(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
c.PostHandshakeRecord = nil
|
||||
}
|
||||
c.PosthandshakeMutex.Unlock()
|
||||
|
||||
n, err := c.writeRecordLocked(recordTypeApplicationData, b)
|
||||
return n + m, c.out.setErrorLocked(err)
|
||||
}
|
||||
|
||||
func isH2Settings(b []byte) bool {
|
||||
if len(b) < 9 {
|
||||
return false
|
||||
}
|
||||
if b[3] == 0x04 && b[5] == 0x00 && b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x00 {
|
||||
// H2 settings with stream identifier of zero (0x0) is used for connection control messages
|
||||
return true
|
||||
}
|
||||
if b[3] == 0x08 && b[5] == 0x00 && b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x00 {
|
||||
// H2 window update, unlikely but put here anyways
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// handleRenegotiation processes a HelloRequest handshake message.
|
||||
func (c *Conn) handleRenegotiation() error {
|
||||
if c.vers == VersionTLS13 {
|
||||
|
@ -90,13 +90,13 @@ func (c *DetectConn) Read(b []byte) (n int, err error) {
|
||||
for {
|
||||
data := make([]byte, 0, 2048)
|
||||
n, err = c.Conn.Read(data[len(data):cap(data)])
|
||||
data = data[:len(data)+n]
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
newPacket := TrafficPacket {
|
||||
SinceHandshake: time.Since(c.HandshakeDone),
|
||||
}
|
||||
c.PostHandshakeRecordsLens[c.Sni] = append(c.PostHandshakeRecordsLens[c.Sni], newPacket)
|
||||
for len(data) > 0 {
|
||||
if len(data) >= 5 && bytes.Equal(data[:3], []byte{23, 3, 3}) {
|
||||
length := int(binary.BigEndian.Uint16(data[3:5])) + 5
|
||||
@ -106,5 +106,6 @@ func (c *DetectConn) Read(b []byte) (n int, err error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
c.PostHandshakeRecordsLens[c.Sni] = append(c.PostHandshakeRecordsLens[c.Sni], newPacket)
|
||||
}
|
||||
}
|
||||
|
39
tls.go
39
tls.go
@ -374,21 +374,32 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
for _, packet := range postHandshakeRecordsLens[hs.clientHello.serverName] {
|
||||
for _, length := range packet.Lens {
|
||||
plainText := make([]byte, length-16)
|
||||
plainText[0] = 23
|
||||
plainText[1] = 3
|
||||
plainText[2] = 3
|
||||
plainText[3] = byte((length - 5) >> 8)
|
||||
plainText[4] = byte((length - 5))
|
||||
plainText[5] = 23
|
||||
postHandshakeRecord := hs.c.out.cipher.(aead).Seal(plainText[:5], hs.c.out.seq[:], plainText[5:], plainText[:5])
|
||||
hs.c.out.incSeq()
|
||||
hs.c.write(postHandshakeRecord)
|
||||
fmt.Printf("REALITY remoteAddr: %v\tlen(postHandshakeRecord): %v\n", remoteAddr, len(postHandshakeRecord))
|
||||
hs.c.PostHandshakeRecord = postHandshakeRecordsLens[hs.clientHello.serverName]
|
||||
go func(){
|
||||
if hs.c.PostHandshakeRecord != nil {
|
||||
time.Sleep(hs.c.PostHandshakeRecord[0].SinceHandshake)
|
||||
}
|
||||
}
|
||||
hs.c.PosthandshakeMutex.Lock()
|
||||
defer hs.c.PosthandshakeMutex.Unlock()
|
||||
if hs.c.PostHandshakeRecord != nil {
|
||||
for _, packet := range hs.c.PostHandshakeRecord {
|
||||
for _, length := range packet.Lens {
|
||||
plainText := make([]byte, length-16)
|
||||
plainText[0] = 23
|
||||
plainText[1] = 3
|
||||
plainText[2] = 3
|
||||
plainText[3] = byte((length - 5) >> 8)
|
||||
plainText[4] = byte((length - 5))
|
||||
plainText[5] = 23
|
||||
postHandshakeRecord := hs.c.out.cipher.(aead).Seal(plainText[:5], hs.c.out.seq[:], plainText[5:], plainText[:5])
|
||||
hs.c.out.incSeq()
|
||||
hs.c.write(postHandshakeRecord)
|
||||
fmt.Printf("REALITY remoteAddr: %v\tSend after sleep%s\tlen(postHandshakeRecord): %v\n", remoteAddr, packet.SinceHandshake, len(postHandshakeRecord))
|
||||
}
|
||||
}
|
||||
hs.c.PostHandshakeRecord = nil
|
||||
}
|
||||
}()
|
||||
hs.c.isHandshakeComplete.Store(true)
|
||||
break
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user