mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-25 23:01:38 +00:00
Fix race on tun conns, but still deadlocks if more than one connection is opened
This commit is contained in:
parent
79bcfbf175
commit
781cd7571f
@ -265,7 +265,6 @@ func main() {
|
|||||||
// Start the TUN/TAP interface
|
// Start the TUN/TAP interface
|
||||||
if listener, err := n.core.ConnListen(); err == nil {
|
if listener, err := n.core.ConnListen(); err == nil {
|
||||||
if dialer, err := n.core.ConnDialer(); err == nil {
|
if dialer, err := n.core.ConnDialer(); err == nil {
|
||||||
logger.Println("Got listener", listener, "and dialer", dialer)
|
|
||||||
n.tuntap.Init(state, logger, listener, dialer)
|
n.tuntap.Init(state, logger, listener, dialer)
|
||||||
if err := n.tuntap.Start(); err != nil {
|
if err := n.tuntap.Start(); err != nil {
|
||||||
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
||||||
|
@ -30,7 +30,6 @@ type TunAdapter struct {
|
|||||||
config *config.NodeState
|
config *config.NodeState
|
||||||
log *log.Logger
|
log *log.Logger
|
||||||
reconfigure chan chan error
|
reconfigure chan chan error
|
||||||
conns map[crypto.NodeID]*yggdrasil.Conn
|
|
||||||
listener *yggdrasil.Listener
|
listener *yggdrasil.Listener
|
||||||
dialer *yggdrasil.Dialer
|
dialer *yggdrasil.Dialer
|
||||||
addr address.Address
|
addr address.Address
|
||||||
@ -39,6 +38,7 @@ type TunAdapter struct {
|
|||||||
mtu int
|
mtu int
|
||||||
iface *water.Interface
|
iface *water.Interface
|
||||||
mutex sync.RWMutex // Protects the below
|
mutex sync.RWMutex // Protects the below
|
||||||
|
conns map[crypto.NodeID]*yggdrasil.Conn
|
||||||
isOpen bool
|
isOpen bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,13 +173,24 @@ func (tun *TunAdapter) handler() error {
|
|||||||
tun.log.Errorln("TUN/TAP error accepting connection:", err)
|
tun.log.Errorln("TUN/TAP error accepting connection:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tun.log.Println("Accepted connection from", conn.RemoteAddr())
|
|
||||||
go tun.connReader(conn)
|
go tun.connReader(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *TunAdapter) connReader(conn *yggdrasil.Conn) error {
|
func (tun *TunAdapter) connReader(conn *yggdrasil.Conn) error {
|
||||||
tun.conns[conn.RemoteAddr()] = conn
|
remoteNodeID := conn.RemoteAddr()
|
||||||
|
tun.mutex.Lock()
|
||||||
|
if _, isIn := tun.conns[remoteNodeID]; isIn {
|
||||||
|
tun.mutex.Unlock()
|
||||||
|
return errors.New("duplicate connection")
|
||||||
|
}
|
||||||
|
tun.conns[remoteNodeID] = conn
|
||||||
|
tun.mutex.Unlock()
|
||||||
|
defer func() {
|
||||||
|
tun.mutex.Lock()
|
||||||
|
delete(tun.conns, remoteNodeID)
|
||||||
|
tun.mutex.Unlock()
|
||||||
|
}()
|
||||||
b := make([]byte, 65535)
|
b := make([]byte, 65535)
|
||||||
for {
|
for {
|
||||||
n, err := conn.Read(b)
|
n, err := conn.Read(b)
|
||||||
@ -242,8 +253,9 @@ func (tun *TunAdapter) ifaceReader() error {
|
|||||||
}
|
}
|
||||||
dstNodeID, dstNodeIDMask = dstAddr.GetNodeIDandMask()
|
dstNodeID, dstNodeIDMask = dstAddr.GetNodeIDandMask()
|
||||||
// Do we have an active connection for this node ID?
|
// Do we have an active connection for this node ID?
|
||||||
|
tun.mutex.Lock()
|
||||||
if conn, isIn := tun.conns[*dstNodeID]; isIn {
|
if conn, isIn := tun.conns[*dstNodeID]; isIn {
|
||||||
tun.log.Println("Got", &conn)
|
tun.mutex.Unlock()
|
||||||
w, err := conn.Write(bs)
|
w, err := conn.Write(bs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.log.Println("Unable to write to remote:", err)
|
tun.log.Println("Unable to write to remote:", err)
|
||||||
@ -253,11 +265,12 @@ func (tun *TunAdapter) ifaceReader() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tun.log.Println("Opening connection for", *dstNodeID)
|
|
||||||
if conn, err := tun.dialer.DialByNodeIDandMask(dstNodeID, dstNodeIDMask); err == nil {
|
if conn, err := tun.dialer.DialByNodeIDandMask(dstNodeID, dstNodeIDMask); err == nil {
|
||||||
tun.conns[*dstNodeID] = &conn
|
tun.conns[*dstNodeID] = &conn
|
||||||
|
tun.mutex.Unlock()
|
||||||
go tun.connReader(&conn)
|
go tun.connReader(&conn)
|
||||||
} else {
|
} else {
|
||||||
|
tun.mutex.Unlock()
|
||||||
tun.log.Println("Error dialing:", err)
|
tun.log.Println("Error dialing:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package yggdrasil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -124,7 +123,6 @@ func (c *Conn) Write(b []byte) (bytesWritten int, err error) {
|
|||||||
return 0, errors.New("session is closed")
|
return 0, errors.New("session is closed")
|
||||||
}
|
}
|
||||||
if c.session == nil {
|
if c.session == nil {
|
||||||
fmt.Println("No session found, starting search for", &c)
|
|
||||||
c.core.router.doAdmin(func() {
|
c.core.router.doAdmin(func() {
|
||||||
c.startSearch()
|
c.startSearch()
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user