mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-23 23:18:36 +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
|
ClientVer [3]byte
|
||||||
ClientTime time.Time
|
ClientTime time.Time
|
||||||
ClientShortId [8]byte
|
ClientShortId [8]byte
|
||||||
|
PostHandshakeRecord []TrafficPacket
|
||||||
|
PosthandshakeMutex sync.Mutex
|
||||||
|
|
||||||
// constant
|
// constant
|
||||||
conn net.Conn
|
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)
|
n, err := c.writeRecordLocked(recordTypeApplicationData, b)
|
||||||
return n + m, c.out.setErrorLocked(err)
|
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.
|
// handleRenegotiation processes a HelloRequest handshake message.
|
||||||
func (c *Conn) handleRenegotiation() error {
|
func (c *Conn) handleRenegotiation() error {
|
||||||
if c.vers == VersionTLS13 {
|
if c.vers == VersionTLS13 {
|
||||||
|
@ -90,13 +90,13 @@ func (c *DetectConn) Read(b []byte) (n int, err error) {
|
|||||||
for {
|
for {
|
||||||
data := make([]byte, 0, 2048)
|
data := make([]byte, 0, 2048)
|
||||||
n, err = c.Conn.Read(data[len(data):cap(data)])
|
n, err = c.Conn.Read(data[len(data):cap(data)])
|
||||||
|
data = data[:len(data)+n]
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
newPacket := TrafficPacket {
|
newPacket := TrafficPacket {
|
||||||
SinceHandshake: time.Since(c.HandshakeDone),
|
SinceHandshake: time.Since(c.HandshakeDone),
|
||||||
}
|
}
|
||||||
c.PostHandshakeRecordsLens[c.Sni] = append(c.PostHandshakeRecordsLens[c.Sni], newPacket)
|
|
||||||
for len(data) > 0 {
|
for len(data) > 0 {
|
||||||
if len(data) >= 5 && bytes.Equal(data[:3], []byte{23, 3, 3}) {
|
if len(data) >= 5 && bytes.Equal(data[:3], []byte{23, 3, 3}) {
|
||||||
length := int(binary.BigEndian.Uint16(data[3:5])) + 5
|
length := int(binary.BigEndian.Uint16(data[3:5])) + 5
|
||||||
@ -106,5 +106,6 @@ func (c *DetectConn) Read(b []byte) (n int, err error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c.PostHandshakeRecordsLens[c.Sni] = append(c.PostHandshakeRecordsLens[c.Sni], newPacket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
tls.go
15
tls.go
@ -374,7 +374,15 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for _, packet := range postHandshakeRecordsLens[hs.clientHello.serverName] {
|
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 {
|
for _, length := range packet.Lens {
|
||||||
plainText := make([]byte, length-16)
|
plainText := make([]byte, length-16)
|
||||||
plainText[0] = 23
|
plainText[0] = 23
|
||||||
@ -386,9 +394,12 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
|
|||||||
postHandshakeRecord := hs.c.out.cipher.(aead).Seal(plainText[:5], hs.c.out.seq[:], plainText[5:], plainText[:5])
|
postHandshakeRecord := hs.c.out.cipher.(aead).Seal(plainText[:5], hs.c.out.seq[:], plainText[5:], plainText[:5])
|
||||||
hs.c.out.incSeq()
|
hs.c.out.incSeq()
|
||||||
hs.c.write(postHandshakeRecord)
|
hs.c.write(postHandshakeRecord)
|
||||||
fmt.Printf("REALITY remoteAddr: %v\tlen(postHandshakeRecord): %v\n", remoteAddr, len(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)
|
hs.c.isHandshakeComplete.Store(true)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user