mirror of
https://github.com/fumiama/WireGold.git
synced 2026-06-04 23:40:26 +08:00
feat: add param DoublePacket
This commit is contained in:
@@ -33,6 +33,7 @@ type Peer struct {
|
||||
QuerySeconds int64 `yaml:"QuerySeconds"`
|
||||
AllowTrans bool `yaml:"AllowTrans"`
|
||||
UseZstd bool `yaml:"UseZstd"`
|
||||
DoublePacket bool `yaml:"DoublePacket"`
|
||||
MTU int64 `yaml:"MTU"`
|
||||
MTURandomRange int64 `yaml:"MTURandomRange"`
|
||||
}
|
||||
|
||||
@@ -155,14 +155,15 @@ func (p *Packet) Unmarshal(data []byte) (complete bool, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// DecreaseAndGetTTL TTL 自减后返回
|
||||
func (p *Packet) DecreaseAndGetTTL() uint8 {
|
||||
p.TTL--
|
||||
return p.TTL
|
||||
}
|
||||
|
||||
// Marshal 将自身数据编码为 []byte
|
||||
// offset 必须为 8 的倍数,表示偏移的 8 位
|
||||
func (p *Packet) Marshal(src net.IP, teatype uint8, additional uint16, datasz uint32, offset uint16, dontfrag, hasmore bool) ([]byte, func()) {
|
||||
p.TTL--
|
||||
if p.TTL == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if src != nil {
|
||||
p.Src = src
|
||||
p.idxdatsz = (uint32(teatype) << 27) | (uint32(additional&0x07ff) << 16) | datasz&0xffff
|
||||
@@ -175,14 +176,13 @@ func (p *Packet) Marshal(src net.IP, teatype uint8, additional uint16, datasz ui
|
||||
if hasmore {
|
||||
offset |= 0x2000
|
||||
}
|
||||
p.Flags = PacketFlags(offset)
|
||||
|
||||
return helper.OpenWriterF(func(w *helper.Writer) {
|
||||
w.WriteUInt32(p.idxdatsz)
|
||||
w.WriteUInt16((uint16(p.TTL) << 8) | uint16(p.Proto))
|
||||
w.WriteUInt16(p.SrcPort)
|
||||
w.WriteUInt16(p.DstPort)
|
||||
w.WriteUInt16(uint16(p.Flags))
|
||||
w.WriteUInt16(uint16(PacketFlags(offset)))
|
||||
w.Write(p.Src.To4())
|
||||
w.Write(p.Dst.To4())
|
||||
w.Write(p.Hash[:])
|
||||
|
||||
@@ -125,25 +125,30 @@ func (m *Me) xorenc(data []byte) []byte {
|
||||
batchsz := len(data) / 8
|
||||
remain := len(data) % 8
|
||||
sum := m.mask
|
||||
newdat := helper.MakeBytes(len(data) + 8)
|
||||
_, _ = rand.Read(newdat[:8])
|
||||
if remain > 0 {
|
||||
var buf [8]byte
|
||||
p := batchsz * 8
|
||||
copy(buf[:], data[p:])
|
||||
sum ^= binary.LittleEndian.Uint64(buf[:])
|
||||
binary.LittleEndian.PutUint64(buf[:], sum)
|
||||
copy(data[p:], buf[:])
|
||||
copy(newdat[8+p:], buf[:])
|
||||
}
|
||||
for i := batchsz - 1; i >= 0; i-- {
|
||||
a := i * 8
|
||||
b := (i + 1) * 8
|
||||
sum ^= binary.LittleEndian.Uint64(data[a:b])
|
||||
binary.LittleEndian.PutUint64(data[a:b], sum)
|
||||
binary.LittleEndian.PutUint64(newdat[a+8:b+8], sum)
|
||||
}
|
||||
return data
|
||||
return newdat
|
||||
}
|
||||
|
||||
// xordec 按 8 字节, 以初始 m.mask 循环异或解码 data
|
||||
func (m *Me) xordec(data []byte) []byte {
|
||||
if len(data) <= 8 {
|
||||
return nil
|
||||
}
|
||||
batchsz := len(data) / 8
|
||||
remain := len(data) % 8
|
||||
this := uint64(0)
|
||||
@@ -173,5 +178,5 @@ func (m *Me) xordec(data []byte) []byte {
|
||||
} else {
|
||||
binary.LittleEndian.PutUint64(data[len(data)-8:], next^m.mask)
|
||||
}
|
||||
return data
|
||||
return data[8:]
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ type Link struct {
|
||||
allowtrans bool
|
||||
// 是否对数据进行 zstd 压缩
|
||||
usezstd bool
|
||||
// 是否采用双倍发包对抗强丢包
|
||||
doublepacket bool
|
||||
// udp 数据包的最大大小
|
||||
mtu uint16
|
||||
// 随机放缩 mtu 范围 (只减不增)
|
||||
|
||||
@@ -22,6 +22,7 @@ type PeerConfig struct {
|
||||
MTURandomRange uint16
|
||||
AllowTrans, NoPipe bool
|
||||
UseZstd bool
|
||||
DoublePacket bool
|
||||
}
|
||||
|
||||
// AddPeer 添加一个 peer
|
||||
@@ -41,6 +42,7 @@ func (m *Me) AddPeer(cfg *PeerConfig) (l *Link) {
|
||||
rawep: cfg.EndPoint,
|
||||
allowtrans: cfg.AllowTrans,
|
||||
usezstd: cfg.UseZstd,
|
||||
doublepacket: cfg.DoublePacket,
|
||||
me: m,
|
||||
mtu: cfg.MTU,
|
||||
mturandomrange: cfg.MTURandomRange,
|
||||
|
||||
@@ -34,6 +34,7 @@ func (m *Me) wait(data []byte) *head.Packet {
|
||||
return nil
|
||||
}
|
||||
crc := binary.LittleEndian.Uint64(data[52:head.PacketHeadLen])
|
||||
logrus.Debugf("[recv] packet crc %016x", crc)
|
||||
if m.recved.Get(crc) { // 是重放攻击
|
||||
logrus.Warnln("[recv] ignore duplicated crc packet", strconv.FormatUint(crc, 16))
|
||||
return nil
|
||||
@@ -78,5 +79,6 @@ func (m *Me) wait(data []byte) *head.Packet {
|
||||
return nil
|
||||
}
|
||||
m.recving.Set(hsh, h)
|
||||
m.recved.Set(crc, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/fumiama/WireGold/gold/head"
|
||||
"github.com/fumiama/WireGold/helper"
|
||||
@@ -88,8 +89,23 @@ func (l *Link) encrypt(p *head.Packet, sndcnt uint16, teatype uint8) {
|
||||
logrus.Debugln("[send] data len after xchacha20:", p.BodyLen(), "addt:", sndcnt)
|
||||
}
|
||||
|
||||
// write 向 peer 发一个包
|
||||
// write 向 peer 发包
|
||||
func (l *Link) write(p *head.Packet, teatype uint8, additional uint16, datasz uint32, offset uint16, istransfer, hasmore bool) (int, error) {
|
||||
if p.DecreaseAndGetTTL() <= 0 {
|
||||
return 0, ErrTTL
|
||||
}
|
||||
if l.doublepacket {
|
||||
cpp := p.Copy()
|
||||
time.AfterFunc(time.Millisecond*(10+time.Duration(rand.Intn(10))), func() {
|
||||
defer cpp.Put()
|
||||
_, _ = l.writeonce(cpp, teatype, additional, datasz, offset, istransfer, hasmore)
|
||||
})
|
||||
}
|
||||
return l.writeonce(p, teatype, additional, datasz, offset, istransfer, hasmore)
|
||||
}
|
||||
|
||||
// write 向 peer 发一个包
|
||||
func (l *Link) writeonce(p *head.Packet, teatype uint8, additional uint16, datasz uint32, offset uint16, istransfer, hasmore bool) (int, error) {
|
||||
peerep := l.endpoint
|
||||
if peerep == nil {
|
||||
return 0, errors.New("nil endpoint of " + p.Dst.String())
|
||||
@@ -103,9 +119,6 @@ func (l *Link) write(p *head.Packet, teatype uint8, additional uint16, datasz ui
|
||||
} else {
|
||||
d, cl = p.Marshal(l.me.me, teatype, additional, datasz, offset, false, hasmore)
|
||||
}
|
||||
if d == nil {
|
||||
return 0, ErrTTL
|
||||
}
|
||||
defer cl()
|
||||
|
||||
bound := 64
|
||||
@@ -118,5 +131,6 @@ func (l *Link) write(p *head.Packet, teatype uint8, additional uint16, datasz ui
|
||||
logrus.Debugln("[send] data bytes", hex.EncodeToString(d[:bound]), endl)
|
||||
d = l.me.xorenc(d)
|
||||
logrus.Debugln("[send] data xored", hex.EncodeToString(d[:bound]), endl)
|
||||
defer helper.PutBytes(d)
|
||||
return l.me.conn.WriteToPeer(d, peerep)
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ func testTunnel(t *testing.T, nw string, isplain bool, pshk *[32]byte, mtu uint1
|
||||
MTU: mtu,
|
||||
MTURandomRange: mtu / 2,
|
||||
UseZstd: true,
|
||||
DoublePacket: true,
|
||||
})
|
||||
p.AddPeer(&link.PeerConfig{
|
||||
PeerIP: "192.168.1.2",
|
||||
|
||||
@@ -154,6 +154,7 @@ func (wg *WG) init(srcport, dstport uint16) {
|
||||
AllowTrans: peer.AllowTrans,
|
||||
NoPipe: true,
|
||||
UseZstd: peer.UseZstd,
|
||||
DoublePacket: peer.DoublePacket,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user