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