1
0
mirror of https://github.com/fumiama/WireGold.git synced 2026-06-04 23:40:26 +08:00
This commit is contained in:
源文雨
2023-08-04 16:07:35 +08:00
parent c90cee8c1b
commit 8163c38884
5 changed files with 62 additions and 17 deletions

View File

@@ -66,23 +66,58 @@ func (l *Link) DecodePreshared(additional uint16, b []byte) (db []byte) {
return
}
// xor 按 8 字节, 以初始 m.mask 循环异或 data
func (m *Me) xor(data []byte) []byte {
// xorenc 按 8 字节, 以初始 m.mask 循环异或编码 data
func (m *Me) xorenc(data []byte) []byte {
batchsz := len(data) / 8
remain := len(data) % 8
sum := m.mask
for i := 0; i < batchsz; i++ {
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[:])
}
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)
}
return data
}
// xordec 按 8 字节, 以初始 m.mask 循环异或解码 data
func (m *Me) xordec(data []byte) []byte {
batchsz := len(data) / 8
remain := len(data) % 8
this := uint64(0)
next := uint64(0)
if len(data) >= 8 {
next = binary.LittleEndian.Uint64(data[:8])
}
for i := 0; i < batchsz-1; i++ {
a := i * 8
b := (i + 1) * 8
this = next
next = binary.LittleEndian.Uint64(data[a+8 : b+8])
binary.LittleEndian.PutUint64(data[a:b], this^next)
}
if remain > 0 {
var buf [8]byte
copy(buf[:], data[remain:])
sum ^= binary.LittleEndian.Uint64(buf[:])
binary.LittleEndian.PutUint64(buf[:], sum)
copy(data[remain:], buf[:])
a := (batchsz - 1) * 8
b := batchsz * 8
copy(buf[:], data[b:])
this = next
next = binary.LittleEndian.Uint64(buf[:]) | (m.mask & (uint64(0xffffffff_ffffffff) << (uint64(remain) * 8)))
if batchsz > 0 {
binary.LittleEndian.PutUint64(data[a:b], this^next)
}
binary.LittleEndian.PutUint64(buf[:], next^m.mask)
copy(data[b:], buf[:])
} else {
binary.LittleEndian.PutUint64(data[len(data)-8:], next^m.mask)
}
return data
}

View File

@@ -3,6 +3,7 @@ package link
import (
"bytes"
"crypto/rand"
"io"
"testing"
)
@@ -10,15 +11,20 @@ func TestXOR(t *testing.T) {
m := Me{
mask: 0x12345678_90abcdef,
}
buf := make([]byte, 65535)
for i := 1; i < 65536; i++ {
buf := make([]byte, 4096)
buf2 := make([]byte, 4096)
for i := 1; i < 4096; i++ {
data := buf[:i]
_, err := rand.Read(data)
orgdata := buf2[:i]
r1 := bytes.NewBuffer(data[:0])
r2 := bytes.NewBuffer(orgdata[:0])
w := io.MultiWriter(r1, r2)
_, err := io.CopyN(w, rand.Reader, int64(i))
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(m.xor(m.xor(data)), data) {
t.Fatal("unexpected xor at ", i)
if !bytes.Equal(m.xordec(m.xorenc(r1.Bytes())), r2.Bytes()) {
t.Fatal("unexpected xor at", i)
}
}
}

View File

@@ -2,6 +2,7 @@ package link
import (
"encoding/binary"
"encoding/hex"
"io"
"net"
"strconv"
@@ -99,6 +100,9 @@ func NewMe(cfg *MyConfig) (m Me) {
m.dstport = cfg.DstPort
m.mtu = cfg.MTU & 0xfff8
m.mask = cfg.Mask
var buf [8]byte
binary.BigEndian.PutUint64(buf[:], m.mask)
logrus.Infoln("[me] xor mask", hex.EncodeToString(buf[:]))
if m.writer == nil {
m.writer = helper.SelectWriter()
}

View File

@@ -18,14 +18,14 @@ func (m *Me) wait(data []byte) *head.Packet {
if len(data) < 60 { // not a valid packet
return nil
}
bound := 256
bound := 64
endl := "..."
if len(data) < bound {
bound = len(data)
endl = "."
}
logrus.Debugln("[recv] data bytes", hex.EncodeToString(data[:bound]), endl)
data = m.xor(data)
data = m.xordec(data)
logrus.Debugln("[recv] data xored", hex.EncodeToString(data[:bound]), endl)
flags := binary.LittleEndian.Uint16(data[10:12])
if flags&0x8000 == 0x8000 { // not a valid packet

View File

@@ -99,7 +99,7 @@ func (l *Link) write(p *head.Packet, teatype uint8, additional, mtu uint16, data
if peerep == nil {
return 0, errors.New("[send] nil endpoint of " + p.Dst.String())
}
bound := 256
bound := 64
endl := "..."
if len(d) < bound {
bound = len(d)
@@ -107,9 +107,9 @@ func (l *Link) write(p *head.Packet, teatype uint8, additional, mtu uint16, data
}
logrus.Debugln("[send] write", len(d), "bytes data from ep", l.me.myep.LocalAddr(), "to", peerep, "offset:", fmt.Sprintf("%04x", offset))
logrus.Debugln("[send] data bytes", hex.EncodeToString(d[:bound]), endl)
d = l.me.xor(d)
n, err = l.me.myep.WriteToUDP(d, peerep)
d = l.me.xorenc(d)
logrus.Debugln("[send] data xored", hex.EncodeToString(d[:bound]), endl)
n, err = l.me.myep.WriteToUDP(d, peerep)
cl()
}
return