fix deadlock from use of phony.Block by actors when ckr is enabled

This commit is contained in:
Arceliar 2019-10-03 18:44:47 -05:00
parent 6ddb0f93f3
commit b2922189b8
2 changed files with 9 additions and 13 deletions

View File

@ -31,7 +31,7 @@ func (s *tunConn) close() {
} }
func (s *tunConn) _close_from_tun() { func (s *tunConn) _close_from_tun() {
s.conn.Close() go s.conn.Close() // Just in case it blocks on actor operations
delete(s.tun.addrToConn, s.addr) delete(s.tun.addrToConn, s.addr)
delete(s.tun.subnetToConn, s.snet) delete(s.tun.subnetToConn, s.snet)
func() { func() {

View File

@ -96,7 +96,7 @@ func (c *Conn) setMTU(from phony.Actor, mtu uint16) {
c.Act(from, func() { c.mtu = mtu }) c.Act(from, func() { c.mtu = mtu })
} }
// This should never be called from the router goroutine, used in the dial functions // This should never be called from an actor, used in the dial functions
func (c *Conn) search() error { func (c *Conn) search() error {
var err error var err error
done := make(chan struct{}) done := make(chan struct{})
@ -118,6 +118,10 @@ func (c *Conn) search() error {
sinfo.setConn(nil, c) sinfo.setConn(nil, c)
} }
c.session = sinfo c.session = sinfo
c.nodeID = crypto.GetNodeID(&c.session.theirPermPub)
for i := range c.nodeMask {
c.nodeMask[i] = 0xFF
}
err = e err = e
close(done) close(done)
} }
@ -133,12 +137,6 @@ func (c *Conn) search() error {
if c.session == nil && err == nil { if c.session == nil && err == nil {
panic("search failed but returned no error") panic("search failed but returned no error")
} }
if c.session != nil {
c.nodeID = crypto.GetNodeID(&c.session.theirPermPub)
for i := range c.nodeMask {
c.nodeMask[i] = 0xFF
}
}
return err return err
} }
@ -262,7 +260,7 @@ func (c *Conn) _write(msg FlowKeyMessage) error {
c.session.Act(c, func() { c.session.Act(c, func() {
// Send the packet // Send the packet
c.session._send(msg) c.session._send(msg)
// Session keep-alive, while we wait for the crypto workers from send // Session keep-alive, while we wait for the crypto workers from sefnd
switch { switch {
case time.Since(c.session.time) > 6*time.Second: case time.Since(c.session.time) > 6*time.Second:
if c.session.time.Before(c.session.pingTime) && time.Since(c.session.pingTime) > 6*time.Second { if c.session.time.Before(c.session.pingTime) && time.Since(c.session.pingTime) > 6*time.Second {
@ -353,10 +351,8 @@ func (c *Conn) LocalAddr() crypto.NodeID {
// RemoteAddr returns the complete node ID of the remote side of the connection. // RemoteAddr returns the complete node ID of the remote side of the connection.
func (c *Conn) RemoteAddr() crypto.NodeID { func (c *Conn) RemoteAddr() crypto.NodeID {
// TODO warn that this can block while waiting for the Conn actor to run, so don't call it from other actors... // RemoteAddr is set during the dial or accept, and isn't changed, so it's safe to access directly
var n crypto.NodeID return *c.nodeID
phony.Block(c, func() { n = *c.nodeID })
return n
} }
// SetDeadline is equivalent to calling both SetReadDeadline and // SetDeadline is equivalent to calling both SetReadDeadline and