mirror of
https://github.com/fumiama/WireGold.git
synced 2026-06-26 22:00:27 +08:00
fix: xor
This commit is contained in:
@@ -66,23 +66,58 @@ func (l *Link) DecodePreshared(additional uint16, b []byte) (db []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// xor 按 8 字节, 以初始 m.mask 循环异或 data
|
// xorenc 按 8 字节, 以初始 m.mask 循环异或编码 data
|
||||||
func (m *Me) xor(data []byte) []byte {
|
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
|
||||||
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
|
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(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 {
|
if remain > 0 {
|
||||||
var buf [8]byte
|
var buf [8]byte
|
||||||
copy(buf[:], data[remain:])
|
a := (batchsz - 1) * 8
|
||||||
sum ^= binary.LittleEndian.Uint64(buf[:])
|
b := batchsz * 8
|
||||||
binary.LittleEndian.PutUint64(buf[:], sum)
|
copy(buf[:], data[b:])
|
||||||
copy(data[remain:], buf[:])
|
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
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package link
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,15 +11,20 @@ func TestXOR(t *testing.T) {
|
|||||||
m := Me{
|
m := Me{
|
||||||
mask: 0x12345678_90abcdef,
|
mask: 0x12345678_90abcdef,
|
||||||
}
|
}
|
||||||
buf := make([]byte, 65535)
|
buf := make([]byte, 4096)
|
||||||
for i := 1; i < 65536; i++ {
|
buf2 := make([]byte, 4096)
|
||||||
|
for i := 1; i < 4096; i++ {
|
||||||
data := buf[: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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(m.xor(m.xor(data)), data) {
|
if !bytes.Equal(m.xordec(m.xorenc(r1.Bytes())), r2.Bytes()) {
|
||||||
t.Fatal("unexpected xor at ", i)
|
t.Fatal("unexpected xor at", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package link
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -99,6 +100,9 @@ func NewMe(cfg *MyConfig) (m Me) {
|
|||||||
m.dstport = cfg.DstPort
|
m.dstport = cfg.DstPort
|
||||||
m.mtu = cfg.MTU & 0xfff8
|
m.mtu = cfg.MTU & 0xfff8
|
||||||
m.mask = cfg.Mask
|
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 {
|
if m.writer == nil {
|
||||||
m.writer = helper.SelectWriter()
|
m.writer = helper.SelectWriter()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ func (m *Me) wait(data []byte) *head.Packet {
|
|||||||
if len(data) < 60 { // not a valid packet
|
if len(data) < 60 { // not a valid packet
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
bound := 256
|
bound := 64
|
||||||
endl := "..."
|
endl := "..."
|
||||||
if len(data) < bound {
|
if len(data) < bound {
|
||||||
bound = len(data)
|
bound = len(data)
|
||||||
endl = "."
|
endl = "."
|
||||||
}
|
}
|
||||||
logrus.Debugln("[recv] data bytes", hex.EncodeToString(data[:bound]), 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)
|
logrus.Debugln("[recv] data xored", hex.EncodeToString(data[:bound]), endl)
|
||||||
flags := binary.LittleEndian.Uint16(data[10:12])
|
flags := binary.LittleEndian.Uint16(data[10:12])
|
||||||
if flags&0x8000 == 0x8000 { // not a valid packet
|
if flags&0x8000 == 0x8000 { // not a valid packet
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func (l *Link) write(p *head.Packet, teatype uint8, additional, mtu uint16, data
|
|||||||
if peerep == nil {
|
if peerep == nil {
|
||||||
return 0, errors.New("[send] nil endpoint of " + p.Dst.String())
|
return 0, errors.New("[send] nil endpoint of " + p.Dst.String())
|
||||||
}
|
}
|
||||||
bound := 256
|
bound := 64
|
||||||
endl := "..."
|
endl := "..."
|
||||||
if len(d) < bound {
|
if len(d) < bound {
|
||||||
bound = len(d)
|
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] 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)
|
logrus.Debugln("[send] data bytes", hex.EncodeToString(d[:bound]), endl)
|
||||||
d = l.me.xor(d)
|
d = l.me.xorenc(d)
|
||||||
n, err = l.me.myep.WriteToUDP(d, peerep)
|
|
||||||
logrus.Debugln("[send] data xored", hex.EncodeToString(d[:bound]), endl)
|
logrus.Debugln("[send] data xored", hex.EncodeToString(d[:bound]), endl)
|
||||||
|
n, err = l.me.myep.WriteToUDP(d, peerep)
|
||||||
cl()
|
cl()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user