fix: splitSeq, map struct{}, unlock before WriteToUDP
fix: splitSeq, map struct{}, unlock before WriteToUDP
This commit is contained in:
@@ -26,17 +26,17 @@ type Session struct {
|
|||||||
sendSeq uint32
|
sendSeq uint32
|
||||||
recvSeq uint32
|
recvSeq uint32
|
||||||
msgIndex uint32
|
msgIndex uint32
|
||||||
|
splitSeq uint16
|
||||||
|
|
||||||
orderIndex [MaxChannels]uint32
|
orderIndex [MaxChannels]uint32
|
||||||
orderNext [MaxChannels]uint32
|
orderNext [MaxChannels]uint32
|
||||||
orderQueues [MaxChannels]map[uint32][]byte
|
orderQueues [MaxChannels]map[uint32][]byte
|
||||||
|
|
||||||
recvSeqs map[uint32]bool
|
recvSeqs map[uint32]struct{}
|
||||||
pendingACK []uint32
|
pendingACK []uint32
|
||||||
pendingNACK []uint32
|
pendingNACK []uint32
|
||||||
|
|
||||||
splitMap map[uint16]*splitBuf
|
splitMap map[uint16]*splitBuf
|
||||||
|
|
||||||
recoveryMap map[uint32]*Datagram
|
recoveryMap map[uint32]*Datagram
|
||||||
|
|
||||||
lastRecv time.Time
|
lastRecv time.Time
|
||||||
@@ -55,12 +55,12 @@ func NewSession(conn *net.UDPConn, addr *net.UDPAddr, guid int64, mtu uint16) *S
|
|||||||
GUID: guid,
|
GUID: guid,
|
||||||
MTU: mtu,
|
MTU: mtu,
|
||||||
state: StateHandshaking,
|
state: StateHandshaking,
|
||||||
recvSeqs: make(map[uint32]bool),
|
recvSeqs: make(map[uint32]struct{}),
|
||||||
splitMap: make(map[uint16]*splitBuf),
|
splitMap: make(map[uint16]*splitBuf),
|
||||||
recoveryMap: make(map[uint32]*Datagram),
|
recoveryMap: make(map[uint32]*Datagram),
|
||||||
lastRecv: time.Now(),
|
lastRecv: time.Now(),
|
||||||
}
|
}
|
||||||
for i := 0; i < MaxChannels; i++ {
|
for i := range s.orderQueues {
|
||||||
s.orderQueues[i] = make(map[uint32][]byte)
|
s.orderQueues[i] = make(map[uint32][]byte)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
@@ -110,13 +110,16 @@ func (s *Session) HandleNACK(data []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
toResend := make([]*Datagram, 0, len(nums))
|
||||||
for _, n := range nums {
|
for _, n := range nums {
|
||||||
dg, ok := s.recoveryMap[n]
|
if dg, ok := s.recoveryMap[n]; ok {
|
||||||
if ok {
|
toResend = append(toResend, dg)
|
||||||
s.conn.WriteToUDP(dg.Encode(), s.Addr)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.mu.Unlock()
|
||||||
|
for _, dg := range toResend {
|
||||||
|
_, _ = s.conn.WriteToUDP(dg.Encode(), s.Addr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) FlushACKs() {
|
func (s *Session) FlushACKs() {
|
||||||
@@ -128,10 +131,10 @@ func (s *Session) FlushACKs() {
|
|||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
|
|
||||||
if len(acks) > 0 {
|
if len(acks) > 0 {
|
||||||
s.conn.WriteToUDP(EncodeACK(acks), s.Addr)
|
_, _ = s.conn.WriteToUDP(EncodeACK(acks), s.Addr)
|
||||||
}
|
}
|
||||||
if len(nacks) > 0 {
|
if len(nacks) > 0 {
|
||||||
s.conn.WriteToUDP(EncodeNACK(nacks), s.Addr)
|
_, _ = s.conn.WriteToUDP(EncodeNACK(nacks), s.Addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +168,8 @@ func (s *Session) Send(payload []byte, reliability Reliability, orderChannel byt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
splitID := s.splitID()
|
splitID := s.splitSeq
|
||||||
|
s.splitSeq++
|
||||||
count := (len(payload) + maxPayload - 1) / maxPayload
|
count := (len(payload) + maxPayload - 1) / maxPayload
|
||||||
orderIdx := s.orderIndex[orderChannel]
|
orderIdx := s.orderIndex[orderChannel]
|
||||||
if reliability.IsOrdered() {
|
if reliability.IsOrdered() {
|
||||||
@@ -177,15 +181,16 @@ func (s *Session) Send(payload []byte, reliability Reliability, orderChannel byt
|
|||||||
if end > len(payload) {
|
if end > len(payload) {
|
||||||
end = len(payload)
|
end = len(payload)
|
||||||
}
|
}
|
||||||
|
chunk := make([]byte, end-start)
|
||||||
|
copy(chunk, payload[start:end])
|
||||||
f := &Frame{
|
f := &Frame{
|
||||||
Reliability: reliability,
|
Reliability: reliability,
|
||||||
Split: true,
|
Split: true,
|
||||||
SplitCount: uint32(count),
|
SplitCount: uint32(count),
|
||||||
SplitID: splitID,
|
SplitID: splitID,
|
||||||
SplitIndex: uint32(i),
|
SplitIndex: uint32(i),
|
||||||
Payload: make([]byte, end-start),
|
Payload: chunk,
|
||||||
}
|
}
|
||||||
copy(f.Payload, payload[start:end])
|
|
||||||
if reliability.IsReliable() {
|
if reliability.IsReliable() {
|
||||||
f.MessageIndex = s.msgIndex
|
f.MessageIndex = s.msgIndex
|
||||||
s.msgIndex++
|
s.msgIndex++
|
||||||
@@ -198,32 +203,22 @@ func (s *Session) Send(payload []byte, reliability Reliability, orderChannel byt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) splitID() uint16 {
|
|
||||||
id := uint16(s.msgIndex & 0xffff)
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) sendDatagram(frames []*Frame) {
|
func (s *Session) sendDatagram(frames []*Frame) {
|
||||||
seq := s.sendSeq
|
seq := s.sendSeq
|
||||||
s.sendSeq++
|
s.sendSeq++
|
||||||
dg := &Datagram{SeqNum: seq, Frames: frames}
|
dg := &Datagram{SeqNum: seq, Frames: frames}
|
||||||
pkt := dg.Encode()
|
_, _ = s.conn.WriteToUDP(dg.Encode(), s.Addr)
|
||||||
s.conn.WriteToUDP(pkt, s.Addr)
|
|
||||||
|
|
||||||
hasReliable := false
|
|
||||||
for _, f := range frames {
|
for _, f := range frames {
|
||||||
if f.Reliability.IsReliable() {
|
if f.Reliability.IsReliable() {
|
||||||
hasReliable = true
|
s.recoveryMap[seq] = dg
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hasReliable {
|
|
||||||
s.recoveryMap[seq] = dg
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) SendRaw(data []byte) {
|
func (s *Session) SendRaw(data []byte) {
|
||||||
s.conn.WriteToUDP(data, s.Addr)
|
_, _ = s.conn.WriteToUDP(data, s.Addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) TimedOut() bool {
|
func (s *Session) TimedOut() bool {
|
||||||
@@ -240,5 +235,5 @@ func (s *Session) Disconnect() {
|
|||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
f := &Frame{Reliability: Unreliable, Payload: []byte{0x15}}
|
f := &Frame{Reliability: Unreliable, Payload: []byte{0x15}}
|
||||||
dg := &Datagram{SeqNum: seq, Frames: []*Frame{f}}
|
dg := &Datagram{SeqNum: seq, Frames: []*Frame{f}}
|
||||||
s.conn.WriteToUDP(dg.Encode(), s.Addr)
|
_, _ = s.conn.WriteToUDP(dg.Encode(), s.Addr)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user