mirror of
https://github.com/fumiama/WireGold.git
synced 2026-06-05 07:50:24 +08:00
optimize(link): drop static lstn buf
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@@ -31,40 +30,10 @@ 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() {
|
||||||
n := uint(runtime.NumCPU())
|
|
||||||
if n > 64 {
|
|
||||||
n = 64 // 只用最多 64 核
|
|
||||||
}
|
|
||||||
logrus.Infoln("[listen] use cpu num:", n)
|
|
||||||
listenbuf := make([]byte, lstnbufgragsz*n)
|
|
||||||
hasntfinished := make([]sync.Mutex, n)
|
|
||||||
for {
|
for {
|
||||||
usenewbuf := false
|
lbf := pbuf.NewBytes(lstnbufgragsz)
|
||||||
i := uint(0)
|
|
||||||
for !hasntfinished[i].TryLock() {
|
|
||||||
i++
|
|
||||||
i %= n
|
|
||||||
if i == 0 { // looked up a full round, make a new buf
|
|
||||||
usenewbuf = true
|
|
||||||
if config.ShowDebugLog {
|
|
||||||
logrus.Debugln("[listen] use new buf")
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if config.ShowDebugLog && !usenewbuf {
|
|
||||||
logrus.Debugln("[listen] lock index", i)
|
|
||||||
}
|
|
||||||
var lbf pbuf.Bytes
|
|
||||||
if usenewbuf {
|
|
||||||
lbf = pbuf.NewBytes(lstnbufgragsz)
|
|
||||||
} else {
|
|
||||||
if config.ShowDebugLog {
|
|
||||||
logrus.Debugln("[listen] take index", i, "slice", i*lstnbufgragsz, (i+1)*lstnbufgragsz, "cap", lstnbufgragsz)
|
|
||||||
}
|
|
||||||
lbf = pbuf.ParseBytes(listenbuf[i*lstnbufgragsz : (i+1)*lstnbufgragsz : (i+1)*lstnbufgragsz]...)
|
|
||||||
}
|
|
||||||
n, addr, err := conn.ReadFromPeer(lbf.Bytes())
|
n, addr, err := conn.ReadFromPeer(lbf.Bytes())
|
||||||
|
lbf.KeepAlive()
|
||||||
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")
|
||||||
return
|
return
|
||||||
@@ -76,13 +45,6 @@ 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 !usenewbuf {
|
|
||||||
if config.ShowDebugLog {
|
|
||||||
logrus.Debugln("[listen] unlock index", i)
|
|
||||||
}
|
|
||||||
hasntfinished[i].Unlock()
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
@@ -91,17 +53,13 @@ func (m *Me) listen() (conn p2p.Conn, err error) {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
index := -1
|
go m.waitordispatch(addr, lbf, n)
|
||||||
if !usenewbuf {
|
|
||||||
index = int(i)
|
|
||||||
}
|
|
||||||
go m.waitordispatch(index, addr, lbf.Trans().SliceTo(n), hasntfinished)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Me) waitordispatch(index int, addr p2p.EndPoint, buf pbuf.Bytes, hasntfinished []sync.Mutex) {
|
func (m *Me) waitordispatch(addr p2p.EndPoint, buf pbuf.Bytes, n int) {
|
||||||
recvtotlcnt := atomic.AddUint64(&m.recvtotlcnt, uint64(buf.Len()))
|
recvtotlcnt := atomic.AddUint64(&m.recvtotlcnt, uint64(buf.Len()))
|
||||||
recvloopcnt := atomic.AddUintptr(&m.recvloopcnt, 1)
|
recvloopcnt := atomic.AddUintptr(&m.recvloopcnt, 1)
|
||||||
recvlooptime := atomic.LoadInt64(&m.recvlooptime)
|
recvlooptime := atomic.LoadInt64(&m.recvlooptime)
|
||||||
@@ -111,56 +69,41 @@ func (m *Me) waitordispatch(index int, addr p2p.EndPoint, buf pbuf.Bytes, hasntf
|
|||||||
atomic.StoreUint64(&m.recvtotlcnt, 0)
|
atomic.StoreUint64(&m.recvtotlcnt, 0)
|
||||||
atomic.StoreInt64(&m.recvlooptime, now)
|
atomic.StoreInt64(&m.recvlooptime, now)
|
||||||
}
|
}
|
||||||
packet := m.wait(buf.Trans().Bytes())
|
packet := m.wait(buf.SliceTo(n).Bytes())
|
||||||
|
buf.KeepAlive()
|
||||||
if packet == nil {
|
if packet == nil {
|
||||||
if index < 0 {
|
|
||||||
if config.ShowDebugLog {
|
|
||||||
logrus.Debugln("[listen] queue waiting")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] queue waiting, unlock index", index)
|
logrus.Debugln("[listen] queue waiting")
|
||||||
}
|
}
|
||||||
hasntfinished[index].Unlock()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] index", index, "dispatch", len(packet.Pointer().UnsafeBody()), "bytes packet")
|
logrus.Debugln("[listen] dispatch", len(packet.Pointer().UnsafeBody()), "bytes packet")
|
||||||
}
|
}
|
||||||
if index >= 0 {
|
m.dispatch(packet, addr)
|
||||||
defer hasntfinished[index].Unlock()
|
|
||||||
m.dispatch(packet, addr, index)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
m.dispatch(packet, addr, index)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Me) dispatch(packet *orbyte.Item[head.Packet], addr p2p.EndPoint, index int) {
|
func (m *Me) dispatch(packet *orbyte.Item[head.Packet], addr p2p.EndPoint) {
|
||||||
if config.ShowDebugLog {
|
|
||||||
defer logrus.Debugln("[listen] dispatched, unlock index", index)
|
|
||||||
logrus.Debugln("[listen] start dispatching index", index)
|
|
||||||
}
|
|
||||||
pp := packet.Pointer
|
pp := packet.Pointer
|
||||||
r := pp().Len() - pp().BodyLen()
|
r := pp().Len() - pp().BodyLen()
|
||||||
if r > 0 {
|
if r > 0 {
|
||||||
logrus.Warnln("[listen] @", index, "packet from endpoint", addr, "len", pp().BodyLen(), "is smaller than it declared len", pp().Len(), ", drop it")
|
logrus.Warnln("[listen] packet from endpoint", addr, "len", pp().BodyLen(), "is smaller than it declared len", pp().Len(), ", drop it")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, ok := m.IsInPeer(pp().Src.String())
|
p, ok := m.IsInPeer(pp().Src.String())
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "recv from endpoint", addr, "src", pp().Src, "dst", pp().Dst)
|
logrus.Debugln("[listen] recv from endpoint", addr, "src", pp().Src, "dst", pp().Dst)
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
logrus.Warnln("[listen] @", index, "packet from", pp().Src, "to", pp().Dst, "is refused")
|
logrus.Warnln("[listen] packet from", pp().Src, "to", pp().Dst, "is refused")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if helper.IsNilInterface(p.endpoint) || !p.endpoint.Euqal(addr) {
|
if helper.IsNilInterface(p.endpoint) || !p.endpoint.Euqal(addr) {
|
||||||
if m.ep.Network() == "tcp" && !addr.Euqal(p.endpoint) {
|
if m.ep.Network() == "tcp" && !addr.Euqal(p.endpoint) {
|
||||||
logrus.Infoln("[listen] @", index, "set endpoint of peer", p.peerip, "to", addr.String())
|
logrus.Infoln("[listen] set endpoint of peer", p.peerip, "to", addr.String())
|
||||||
p.endpoint = addr
|
p.endpoint = addr
|
||||||
} else { // others are all no status link
|
} else { // others are all no status link
|
||||||
logrus.Infoln("[listen] @", index, "set endpoint of peer", p.peerip, "to", addr.String())
|
logrus.Infoln("[listen] set endpoint of peer", p.peerip, "to", addr.String())
|
||||||
p.endpoint = addr
|
p.endpoint = addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +112,7 @@ func (m *Me) dispatch(packet *orbyte.Item[head.Packet], addr p2p.EndPoint, index
|
|||||||
switch {
|
switch {
|
||||||
case p.IsToMe(pp().Dst):
|
case p.IsToMe(pp().Dst):
|
||||||
if !p.Accept(pp().Src) {
|
if !p.Accept(pp().Src) {
|
||||||
logrus.Warnln("[listen] @", index, "refused packet from", pp().Src.String()+":"+strconv.Itoa(int(pp().SrcPort)))
|
logrus.Warnln("[listen] refused packet from", pp().Src.String()+":"+strconv.Itoa(int(pp().SrcPort)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addt := pp().AdditionalData()
|
addt := pp().AdditionalData()
|
||||||
@@ -177,7 +120,7 @@ func (m *Me) dispatch(packet *orbyte.Item[head.Packet], addr p2p.EndPoint, index
|
|||||||
data, err := p.decode(pp().CipherIndex(), addt, pp().TransBody().Bytes())
|
data, err := p.decode(pp().CipherIndex(), addt, pp().TransBody().Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "drop invalid packet key idx:", pp().CipherIndex(), "addt:", addt, "err:", err)
|
logrus.Debugln("[listen] drop invalid packet key idx:", pp().CipherIndex(), "addt:", addt, "err:", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -185,19 +128,19 @@ func (m *Me) dispatch(packet *orbyte.Item[head.Packet], addr p2p.EndPoint, index
|
|||||||
dat, err := decodezstd(data.Trans().Bytes())
|
dat, err := decodezstd(data.Trans().Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "drop invalid zstd packet:", err)
|
logrus.Debugln("[listen] drop invalid zstd packet:", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "zstd decoded len:", dat.Len())
|
logrus.Debugln("[listen] zstd decoded len:", dat.Len())
|
||||||
}
|
}
|
||||||
data = dat
|
data = dat
|
||||||
}
|
}
|
||||||
pp().SetBody(data)
|
pp().SetBody(data)
|
||||||
if !pp().IsVaildHash() {
|
if !pp().IsVaildHash() {
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "drop invalid hash packet")
|
logrus.Debugln("[listen] drop invalid hash packet")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -205,63 +148,63 @@ func (m *Me) dispatch(packet *orbyte.Item[head.Packet], addr p2p.EndPoint, index
|
|||||||
case head.ProtoHello:
|
case head.ProtoHello:
|
||||||
switch {
|
switch {
|
||||||
case len(pp().UnsafeBody()) == 0:
|
case len(pp().UnsafeBody()) == 0:
|
||||||
logrus.Warnln("[listen] @", index, "recv old hello packet, do nothing")
|
logrus.Warnln("[listen] recv old hello packet, do nothing")
|
||||||
case pp().UnsafeBody()[0] == byte(head.HelloPing):
|
case pp().UnsafeBody()[0] == byte(head.HelloPing):
|
||||||
n, err := p.WritePacket(head.NewPacketPartial(
|
n, err := p.WritePacket(head.NewPacketPartial(
|
||||||
head.ProtoHello, m.SrcPort(), p.peerip, m.DstPort(), pbuf.ParseBytes(byte(head.HelloPong))), false)
|
head.ProtoHello, m.SrcPort(), p.peerip, m.DstPort(), pbuf.ParseBytes(byte(head.HelloPong))), false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
logrus.Infoln("[listen] @", index, "recv hello, send", n, "bytes hello ack packet")
|
logrus.Infoln("[listen] recv hello, send", n, "bytes hello ack packet")
|
||||||
} else {
|
} else {
|
||||||
logrus.Errorln("[listen] @", index, "send hello ack packet error:", err)
|
logrus.Errorln("[listen] send hello ack packet error:", err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
logrus.Infoln("[listen] @", index, "recv hello ack packet, do nothing")
|
logrus.Infoln("[listen] recv hello ack packet, do nothing")
|
||||||
}
|
}
|
||||||
case head.ProtoNotify:
|
case head.ProtoNotify:
|
||||||
logrus.Infoln("[listen] @", index, "recv notify from", pp().Src)
|
logrus.Infoln("[listen] recv notify from", pp().Src)
|
||||||
p.onNotify(pp().UnsafeBody())
|
p.onNotify(pp().UnsafeBody())
|
||||||
runtime.KeepAlive(packet)
|
runtime.KeepAlive(packet)
|
||||||
case head.ProtoQuery:
|
case head.ProtoQuery:
|
||||||
logrus.Infoln("[listen] @", index, "recv query from", pp().Src)
|
logrus.Infoln("[listen] recv query from", pp().Src)
|
||||||
p.onQuery(pp().UnsafeBody())
|
p.onQuery(pp().UnsafeBody())
|
||||||
runtime.KeepAlive(packet)
|
runtime.KeepAlive(packet)
|
||||||
case head.ProtoData:
|
case head.ProtoData:
|
||||||
if p.pipe != nil {
|
if p.pipe != nil {
|
||||||
p.pipe <- packet.Copy()
|
p.pipe <- packet.Copy()
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "deliver to pipe of", p.peerip)
|
logrus.Debugln("[listen] deliver to pipe of", p.peerip)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err := m.nic.Write(pp().UnsafeBody())
|
_, err := m.nic.Write(pp().UnsafeBody())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorln("[listen] @", index, "deliver", pp().BodyLen(), "bytes data to nic err:", err)
|
logrus.Errorln("[listen] deliver", pp().BodyLen(), "bytes data to nic err:", err)
|
||||||
} else if config.ShowDebugLog {
|
} else if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "deliver", pp().BodyLen(), "bytes data to nic")
|
logrus.Debugln("[listen] deliver", pp().BodyLen(), "bytes data to nic")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
logrus.Warnln("[listen] @", index, "recv unknown proto:", pp().Proto)
|
logrus.Warnln("[listen] recv unknown proto:", pp().Proto)
|
||||||
}
|
}
|
||||||
case p.Accept(pp().Dst):
|
case p.Accept(pp().Dst):
|
||||||
if !p.allowtrans {
|
if !p.allowtrans {
|
||||||
logrus.Warnln("[listen] @", index, "refused to trans packet to", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)))
|
logrus.Warnln("[listen] refused to trans packet to", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 转发
|
// 转发
|
||||||
lnk := m.router.NextHop(pp().Dst.String())
|
lnk := m.router.NextHop(pp().Dst.String())
|
||||||
if lnk == nil {
|
if lnk == nil {
|
||||||
logrus.Warnln("[listen] @", index, "transfer drop packet: nil nexthop")
|
logrus.Warnln("[listen] transfer drop packet: nil nexthop")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n, err := lnk.WritePacket(packet, true)
|
n, err := lnk.WritePacket(packet, true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if config.ShowDebugLog {
|
if config.ShowDebugLog {
|
||||||
logrus.Debugln("[listen] @", index, "trans", n, "bytes packet to", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)))
|
logrus.Debugln("[listen] trans", n, "bytes packet to", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logrus.Errorln("[listen] @", index, "trans packet to", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)), "err:", err)
|
logrus.Errorln("[listen] trans packet to", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)), "err:", err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
logrus.Warnln("[listen] @", index, "packet dst", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)), "is not in peers")
|
logrus.Warnln("[listen] packet dst", pp().Dst.String()+":"+strconv.Itoa(int(pp().DstPort)), "is not in peers")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user