mirror of
https://github.com/fumiama/WireGold.git
synced 2026-06-13 05:31:08 +08:00
fix(link): duplicate crc recv (#2)
This commit is contained in:
@@ -147,17 +147,19 @@ 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(PacketFlags(offset)))
|
w.WriteUInt16(uint16(p.Flags))
|
||||||
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[:])
|
||||||
w.WriteUInt64(CalcCRC64(w.Bytes()))
|
p.crc64 = CalcCRC64(w.Bytes())
|
||||||
|
w.WriteUInt64(p.crc64)
|
||||||
w.Write(p.Body())
|
w.Write(p.Body())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -213,6 +215,10 @@ func (p *Packet) Put() {
|
|||||||
PutPacket(p)
|
PutPacket(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Packet) CRC64() uint64 {
|
||||||
|
return p.crc64
|
||||||
|
}
|
||||||
|
|
||||||
// Body returns data
|
// Body returns data
|
||||||
func (p *Packet) Body() []byte {
|
func (p *Packet) Body() []byte {
|
||||||
return p.data[p.a:p.b]
|
return p.data[p.a:p.b]
|
||||||
@@ -256,3 +262,10 @@ func (p *Packet) Copy() *Packet {
|
|||||||
newp.buffered = false
|
newp.buffered = false
|
||||||
return newp
|
return newp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Packet) CopyWithBody() *Packet {
|
||||||
|
newp := p.Copy()
|
||||||
|
newp.data = helper.MakeBytes(len(p.data))
|
||||||
|
copy(newp.data, p.data)
|
||||||
|
return newp
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,52 @@ import (
|
|||||||
|
|
||||||
const lstnbufgragsz = 65536
|
const lstnbufgragsz = 65536
|
||||||
|
|
||||||
|
type lstnq struct {
|
||||||
|
index int
|
||||||
|
addr p2p.EndPoint
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type listenqueue chan lstnq
|
||||||
|
|
||||||
|
func (q listenqueue) listen(m *Me, hasntfinished []sync.Mutex) {
|
||||||
|
recvtotlcnt := uint64(0)
|
||||||
|
recvloopcnt := uint16(0)
|
||||||
|
recvlooptime := time.Now().UnixMilli()
|
||||||
|
for lstn := range q {
|
||||||
|
recvtotlcnt += uint64(len(lstn.buf))
|
||||||
|
recvloopcnt++
|
||||||
|
if recvloopcnt%m.speedloop == 0 {
|
||||||
|
now := time.Now().UnixMilli()
|
||||||
|
logrus.Infof("[listen] queue recv avg speed: %.2f KB/s", float64(recvtotlcnt)/float64(now-recvlooptime))
|
||||||
|
recvtotlcnt = 0
|
||||||
|
recvlooptime = now
|
||||||
|
}
|
||||||
|
packet := m.wait(lstn.buf[:len(lstn.buf):lstnbufgragsz])
|
||||||
|
if packet == nil {
|
||||||
|
if lstn.index < 0 {
|
||||||
|
if config.ShowDebugLog {
|
||||||
|
logrus.Debugln("[listen] queue waiting")
|
||||||
|
}
|
||||||
|
helper.PutBytes(lstn.buf)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.ShowDebugLog {
|
||||||
|
logrus.Debugln("[listen] queue waiting, unlock index", lstn.index)
|
||||||
|
}
|
||||||
|
hasntfinished[lstn.index].Unlock()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if lstn.index >= 0 {
|
||||||
|
go m.dispatch(packet, lstn.addr, lstn.index, hasntfinished[lstn.index].Unlock)
|
||||||
|
} else {
|
||||||
|
go m.dispatch(packet, lstn.addr, lstn.index, func() {
|
||||||
|
helper.PutBytes(lstn.buf)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 监听本机 endpoint
|
// 监听本机 endpoint
|
||||||
func (m *Me) listen() (conn p2p.Conn, err error) {
|
func (m *Me) listen() (conn p2p.Conn, err error) {
|
||||||
conn, err = m.ep.Listen()
|
conn, err = m.ep.Listen()
|
||||||
@@ -30,29 +76,40 @@ func (m *Me) listen() (conn p2p.Conn, err error) {
|
|||||||
m.ep = conn.LocalAddr()
|
m.ep = conn.LocalAddr()
|
||||||
logrus.Infoln("[listen] at", m.ep)
|
logrus.Infoln("[listen] at", m.ep)
|
||||||
go func() {
|
go func() {
|
||||||
recvtotlcnt := uint64(0)
|
n := uint(runtime.NumCPU())
|
||||||
recvloopcnt := uint16(0)
|
|
||||||
recvlooptime := time.Now().UnixMilli()
|
|
||||||
n := runtime.NumCPU()
|
|
||||||
if n > 64 {
|
if n > 64 {
|
||||||
n = 64 // 只用最多 64 核
|
n = 64 // 只用最多 64 核
|
||||||
}
|
}
|
||||||
logrus.Infoln("[listen] use cpu num:", n)
|
logrus.Infoln("[listen] use cpu num:", n)
|
||||||
listenbuff := make([]byte, lstnbufgragsz*n)
|
listenbuf := make([]byte, lstnbufgragsz*n)
|
||||||
hasntfinished := make([]sync.Mutex, n)
|
hasntfinished := make([]sync.Mutex, n)
|
||||||
for i := 0; err == nil; i++ {
|
q := make(listenqueue, n)
|
||||||
|
defer close(q)
|
||||||
|
go q.listen(m, hasntfinished)
|
||||||
|
i := uint(0)
|
||||||
|
for {
|
||||||
|
usenewbuf := false
|
||||||
i %= n
|
i %= n
|
||||||
for !hasntfinished[i].TryLock() {
|
for !hasntfinished[i].TryLock() {
|
||||||
i++
|
i++
|
||||||
i %= n
|
i %= n
|
||||||
if i == 0 { // looked up a full round
|
if i == 0 { // looked up a full round, make a new buf
|
||||||
time.Sleep(time.Millisecond * 10)
|
usenewbuf = true
|
||||||
|
if config.ShowDebugLog {
|
||||||
|
logrus.Debugln("[listen] use new buf")
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog && !usenewbuf {
|
||||||
logrus.Debugln("[listen] lock index", i)
|
logrus.Debugln("[listen] lock index", i)
|
||||||
}
|
}
|
||||||
lbf := listenbuff[i*lstnbufgragsz : (i+1)*lstnbufgragsz]
|
var lbf []byte
|
||||||
|
if usenewbuf {
|
||||||
|
lbf = helper.MakeBytes(lstnbufgragsz)
|
||||||
|
} else {
|
||||||
|
lbf = listenbuf[i*lstnbufgragsz : (i+1)*lstnbufgragsz]
|
||||||
|
}
|
||||||
n, addr, err := conn.ReadFromPeer(lbf)
|
n, addr, err := conn.ReadFromPeer(lbf)
|
||||||
if m.connections == nil || errors.Is(err, net.ErrClosed) {
|
if m.connections == nil || errors.Is(err, net.ErrClosed) {
|
||||||
logrus.Warnln("[listen] quit listening")
|
logrus.Warnln("[listen] quit listening")
|
||||||
@@ -65,31 +122,24 @@ func (m *Me) listen() (conn p2p.Conn, err error) {
|
|||||||
logrus.Errorln("[listen] reconnect udp err:", err)
|
logrus.Errorln("[listen] reconnect udp err:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if config.ShowDebugLog {
|
if !usenewbuf {
|
||||||
logrus.Debugln("[listen] unlock index", i)
|
if config.ShowDebugLog {
|
||||||
|
logrus.Debugln("[listen] unlock index", i)
|
||||||
|
}
|
||||||
|
hasntfinished[i].Unlock()
|
||||||
|
i--
|
||||||
}
|
}
|
||||||
hasntfinished[i].Unlock()
|
|
||||||
i--
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
recvtotlcnt += uint64(n)
|
lq := lstnq{
|
||||||
recvloopcnt++
|
index: -1,
|
||||||
if recvloopcnt%m.speedloop == 0 {
|
addr: addr,
|
||||||
now := time.Now().UnixMilli()
|
buf: lbf[:n],
|
||||||
logrus.Infof("[listen] recv avg speed: %.2f KB/s", float64(recvtotlcnt)/float64(now-recvlooptime))
|
|
||||||
recvtotlcnt = 0
|
|
||||||
recvlooptime = now
|
|
||||||
}
|
}
|
||||||
packet := m.wait(lbf[:n:lstnbufgragsz])
|
if !usenewbuf {
|
||||||
if packet == nil {
|
lq.index = int(i)
|
||||||
if config.ShowDebugLog {
|
|
||||||
logrus.Debugln("[listen] waiting, unlock index", i)
|
|
||||||
}
|
|
||||||
hasntfinished[i].Unlock()
|
|
||||||
i--
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
go m.dispatch(packet, addr, i, hasntfinished[i].Unlock)
|
q <- lq
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return
|
return
|
||||||
@@ -193,7 +243,7 @@ func (m *Me) dispatch(packet *head.Packet, addr p2p.EndPoint, index int, finish
|
|||||||
packet.Put()
|
packet.Put()
|
||||||
case head.ProtoData:
|
case head.ProtoData:
|
||||||
if p.pipe != nil {
|
if p.pipe != nil {
|
||||||
p.pipe <- packet
|
p.pipe <- packet.CopyWithBody()
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "deliver to pipe of", p.peerip)
|
logrus.Debugln("[listen] @", index, "deliver to pipe of", p.peerip)
|
||||||
}
|
}
|
||||||
@@ -204,8 +254,8 @@ func (m *Me) dispatch(packet *head.Packet, addr p2p.EndPoint, index int, finish
|
|||||||
} else if config.ShowDebugLog {
|
} else if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "deliver", packet.BodyLen(), "bytes data to nic")
|
logrus.Debugln("[listen] @", index, "deliver", packet.BodyLen(), "bytes data to nic")
|
||||||
}
|
}
|
||||||
packet.Put()
|
|
||||||
}
|
}
|
||||||
|
packet.Put()
|
||||||
default:
|
default:
|
||||||
logrus.Warnln("[listen] @", index, "recv unknown proto:", packet.Proto)
|
logrus.Warnln("[listen] @", index, "recv unknown proto:", packet.Proto)
|
||||||
packet.Put()
|
packet.Put()
|
||||||
|
|||||||
@@ -52,17 +52,17 @@ func (m *Me) wait(data []byte) *head.Packet {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
m.recved.Set(crc, true)
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[recv]", len(data), "bytes data with flag", hex.EncodeToString(data[11:12]), hex.EncodeToString(data[10:11]))
|
logrus.Debugln("[recv]", strconv.FormatUint(crc, 16), len(data), "bytes data with flag", hex.EncodeToString(data[11:12]), hex.EncodeToString(data[10:11]))
|
||||||
}
|
}
|
||||||
if flags.IsSingle() || flags.NoFrag() {
|
if flags.IsSingle() || flags.NoFrag() {
|
||||||
h := head.SelectPacket()
|
h := head.SelectPacket()
|
||||||
_, err := h.Unmarshal(data)
|
_, err := h.Unmarshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorln("[recv] unmarshal err:", err)
|
logrus.Errorln("[recv]", strconv.FormatUint(crc, 16), "unmarshal err:", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
m.recved.Set(crc, true)
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,35 +75,33 @@ func (m *Me) wait(data []byte) *head.Packet {
|
|||||||
h := m.recving.Get(hsh)
|
h := m.recving.Get(hsh)
|
||||||
if h != nil {
|
if h != nil {
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[recv] get another frag part of", strconv.FormatUint(hsh, 16))
|
logrus.Debugln("[recv]", strconv.FormatUint(crc, 16), "get another frag part of", strconv.FormatUint(hsh, 16))
|
||||||
}
|
}
|
||||||
ok, err := h.Unmarshal(data)
|
ok, err := h.Unmarshal(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if ok {
|
if ok {
|
||||||
m.recving.Delete(hsh)
|
m.recving.Delete(hsh)
|
||||||
m.recved.Set(crc, true)
|
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[recv] all parts of", strconv.FormatUint(hsh, 16), "has reached")
|
logrus.Debugln("[recv]", strconv.FormatUint(crc, 16), "all parts of", strconv.FormatUint(hsh, 16), "has reached")
|
||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
h.Put()
|
h.Put()
|
||||||
logrus.Errorln("[recv] unmarshal err:", err)
|
logrus.Errorln("[recv]", strconv.FormatUint(crc, 16), "unmarshal err:", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[recv] get new frag part of", strconv.FormatUint(hsh, 16))
|
logrus.Debugln("[recv]", strconv.FormatUint(crc, 16), "get new frag part of", strconv.FormatUint(hsh, 16))
|
||||||
}
|
}
|
||||||
h = head.SelectPacket()
|
h = head.SelectPacket()
|
||||||
_, err := h.Unmarshal(data)
|
_, err := h.Unmarshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.Put()
|
h.Put()
|
||||||
logrus.Errorln("[recv] unmarshal err:", err)
|
logrus.Errorln("[recv]", strconv.FormatUint(crc, 16), "unmarshal err:", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
m.recving.Set(hsh, h)
|
m.recving.Set(hsh, h)
|
||||||
m.recved.Set(crc, true)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/klauspost/compress/zstd"
|
"github.com/klauspost/compress/zstd"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -30,7 +29,8 @@ func (l *Link) WriteAndPut(p *head.Packet, istransfer bool) (n int, err error) {
|
|||||||
teatype := l.randkeyidx()
|
teatype := l.randkeyidx()
|
||||||
sndcnt := uint16(l.incgetsndcnt())
|
sndcnt := uint16(l.incgetsndcnt())
|
||||||
var buf [4]byte
|
var buf [4]byte
|
||||||
_, _ = crand.Read(buf[:])
|
_, _ = crand.Read(buf[:2])
|
||||||
|
binary.BigEndian.PutUint16(buf[2:4], sndcnt)
|
||||||
seq := binary.BigEndian.Uint32(buf[:])
|
seq := binary.BigEndian.Uint32(buf[:])
|
||||||
mtu := l.mtu
|
mtu := l.mtu
|
||||||
if l.mturandomrange > 0 {
|
if l.mturandomrange > 0 {
|
||||||
@@ -114,11 +114,7 @@ func (l *Link) write(p *head.Packet, teatype uint8, additional uint16, datasz ui
|
|||||||
return 0, ErrTTL
|
return 0, ErrTTL
|
||||||
}
|
}
|
||||||
if l.doublepacket {
|
if l.doublepacket {
|
||||||
cpp := p.Copy()
|
_, _ = l.writeonce(p, teatype, additional, datasz, offset, istransfer, hasmore, seq)
|
||||||
_ = time.AfterFunc(time.Millisecond*(10+time.Duration(rand.Intn(40))), func() {
|
|
||||||
defer cpp.Put()
|
|
||||||
_, _ = l.writeonce(cpp, teatype, additional, datasz, offset, istransfer, hasmore, seq)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return l.writeonce(p, teatype, additional, datasz, offset, istransfer, hasmore, seq)
|
return l.writeonce(p, teatype, additional, datasz, offset, istransfer, hasmore, seq)
|
||||||
}
|
}
|
||||||
@@ -147,7 +143,7 @@ func (l *Link) writeonce(p *head.Packet, teatype uint8, additional uint16, datas
|
|||||||
endl = "."
|
endl = "."
|
||||||
}
|
}
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[send] write", len(d), "bytes data from ep", l.me.conn.LocalAddr(), "to", peerep, "offset:", fmt.Sprintf("%04x", offset))
|
logrus.Debugln("[send] write", len(d), "bytes data from ep", l.me.conn.LocalAddr(), "to", peerep, "offset", fmt.Sprintf("%04x", offset), "crc", fmt.Sprintf("%016x", p.CRC64()))
|
||||||
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, seq)
|
d = l.me.xorenc(d, seq)
|
||||||
|
|||||||
Reference in New Issue
Block a user