github.com/MerlinKodo/sing-tun@v0.1.15/internal/clashtcpip/tcp.go (about) 1 package clashtcpip 2 3 import ( 4 "encoding/binary" 5 "net" 6 ) 7 8 const ( 9 TCPFin uint16 = 1 << 0 10 TCPSyn uint16 = 1 << 1 11 TCPRst uint16 = 1 << 2 12 TCPPuh uint16 = 1 << 3 13 TCPAck uint16 = 1 << 4 14 TCPUrg uint16 = 1 << 5 15 TCPEce uint16 = 1 << 6 16 TCPEwr uint16 = 1 << 7 17 TCPNs uint16 = 1 << 8 18 ) 19 20 const TCPHeaderSize = 20 21 22 type TCPPacket []byte 23 24 func (p TCPPacket) SourcePort() uint16 { 25 return binary.BigEndian.Uint16(p) 26 } 27 28 func (p TCPPacket) SetSourcePort(port uint16) { 29 binary.BigEndian.PutUint16(p, port) 30 } 31 32 func (p TCPPacket) DestinationPort() uint16 { 33 return binary.BigEndian.Uint16(p[2:]) 34 } 35 36 func (p TCPPacket) SetDestinationPort(port uint16) { 37 binary.BigEndian.PutUint16(p[2:], port) 38 } 39 40 func (p TCPPacket) Flags() uint16 { 41 return uint16(p[13] | (p[12] & 0x1)) 42 } 43 44 func (p TCPPacket) Checksum() uint16 { 45 return binary.BigEndian.Uint16(p[16:]) 46 } 47 48 func (p TCPPacket) SetChecksum(sum [2]byte) { 49 p[16] = sum[0] 50 p[17] = sum[1] 51 } 52 53 func (p TCPPacket) ResetChecksum(psum uint32) { 54 p.SetChecksum(zeroChecksum) 55 p.SetChecksum(Checksum(psum, p)) 56 } 57 58 func (p TCPPacket) Valid() bool { 59 return len(p) >= TCPHeaderSize 60 } 61 62 func (p TCPPacket) Verify(sourceAddress net.IP, targetAddress net.IP) error { 63 var checksum [2]byte 64 checksum[0] = p[16] 65 checksum[1] = p[17] 66 67 // reset checksum 68 p[16] = 0 69 p[17] = 0 70 71 // restore checksum 72 defer func() { 73 p[16] = checksum[0] 74 p[17] = checksum[1] 75 }() 76 77 // check checksum 78 s := uint32(0) 79 s += Sum(sourceAddress) 80 s += Sum(targetAddress) 81 s += uint32(TCP) 82 s += uint32(len(p)) 83 84 check := Checksum(s, p) 85 if checksum[0] != check[0] || checksum[1] != check[1] { 86 return ErrInvalidChecksum 87 } 88 89 return nil 90 }