Fix deadlock between flow judgement and close
This commit is contained in:
parent
e5c21070ae
commit
2d9b8aed5f
1 changed files with 13 additions and 4 deletions
|
|
@ -201,8 +201,8 @@ func (d *ForwardDispatcher) Dispatch(packet []byte) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
d.access.RLock()
|
d.access.RLock()
|
||||||
defer d.access.RUnlock()
|
|
||||||
if d.returnPath.closed.Load() {
|
if d.returnPath.closed.Load() {
|
||||||
|
d.access.RUnlock()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
key := parsed.flowKey()
|
key := parsed.flowKey()
|
||||||
|
|
@ -213,13 +213,16 @@ func (d *ForwardDispatcher) Dispatch(packet []byte) bool {
|
||||||
loaded = false
|
loaded = false
|
||||||
}
|
}
|
||||||
if loaded {
|
if loaded {
|
||||||
return d.handleHit(key, entry, &parsed, packet, now)
|
handled := d.handleHit(key, entry, &parsed, packet, now)
|
||||||
|
d.access.RUnlock()
|
||||||
|
return handled
|
||||||
}
|
}
|
||||||
|
d.access.RUnlock()
|
||||||
if parsed.protocol == uint8(header.TCPProtocolNumber) &&
|
if parsed.protocol == uint8(header.TCPProtocolNumber) &&
|
||||||
(parsed.tcpFlags&header.TCPFlagSyn == 0 || parsed.tcpFlags&header.TCPFlagAck != 0) {
|
(parsed.tcpFlags&header.TCPFlagSyn == 0 || parsed.tcpFlags&header.TCPFlagAck != 0) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return d.judgeAndInstall(key, &parsed, packet, now)
|
return d.judgeAndInstall(key, &parsed, packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ForwardDispatcher) handleHit(key flowKey, entry *flowEntry, packet *forwardPacket, raw []byte, now int64) bool {
|
func (d *ForwardDispatcher) handleHit(key flowKey, entry *flowEntry, packet *forwardPacket, raw []byte, now int64) bool {
|
||||||
|
|
@ -273,12 +276,18 @@ func (d *ForwardDispatcher) handleHit(key flowKey, entry *flowEntry, packet *for
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ForwardDispatcher) judgeAndInstall(key flowKey, packet *forwardPacket, raw []byte, now int64) bool {
|
func (d *ForwardDispatcher) judgeAndInstall(key flowKey, packet *forwardPacket, raw []byte) bool {
|
||||||
var firstPacket []byte
|
var firstPacket []byte
|
||||||
if packet.protocol == uint8(header.UDPProtocolNumber) {
|
if packet.protocol == uint8(header.UDPProtocolNumber) {
|
||||||
firstPacket = header.UDP(packet.transport).Payload()
|
firstPacket = header.UDP(packet.transport).Payload()
|
||||||
}
|
}
|
||||||
verdict := d.handler.JudgeFlow(packet.protocol, packet.source, packet.destination, firstPacket)
|
verdict := d.handler.JudgeFlow(packet.protocol, packet.source, packet.destination, firstPacket)
|
||||||
|
d.access.RLock()
|
||||||
|
defer d.access.RUnlock()
|
||||||
|
if d.returnPath.closed.Load() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
now := d.now()
|
||||||
switch verdict.Action {
|
switch verdict.Action {
|
||||||
case ActionFlow:
|
case ActionFlow:
|
||||||
if verdict.Port != nil {
|
if verdict.Port != nil {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue