diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index d5bed523..6feb533b 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -35,6 +35,7 @@ const tun_ETHER_HEADER_LENGTH = 14 // you should pass this object to the yggdrasil.SetRouterAdapter() function // before calling yggdrasil.Start(). type TunAdapter struct { + core *yggdrasil.Core writer tunWriter reader tunReader config *config.NodeState @@ -131,6 +132,7 @@ func (tun *TunAdapter) Init(core *yggdrasil.Core, config *config.NodeState, log if !ok { return fmt.Errorf("invalid options supplied to TunAdapter module") } + tun.core = core tun.config = config tun.log = log tun.listener = tunoptions.Listener @@ -181,6 +183,7 @@ func (tun *TunAdapter) _start() error { if tun.MTU() != current.IfMTU { tun.log.Warnf("Warning: Interface MTU %d automatically adjusted to %d (supported range is 1280-%d)", current.IfMTU, tun.MTU(), MaximumMTU(tun.IsTAP())) } + tun.core.SetMaximumSessionMTU(uint16(tun.MTU())) tun.isOpen = true go tun.handler() tun.reader.Act(nil, tun.reader._read) // Start the reader diff --git a/src/yggdrasil/api.go b/src/yggdrasil/api.go index 6dd70b8e..59cc8310 100644 --- a/src/yggdrasil/api.go +++ b/src/yggdrasil/api.go @@ -363,6 +363,22 @@ func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) { c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy) } +// GetMaximumSessionMTU returns the maximum allowed session MTU size. +func (c *Core) GetMaximumSessionMTU(mtu uint16) uint16 { + return c.router.sessions.myMaximumMTU +} + +// SetMaximumSessionMTU sets the maximum allowed session MTU size. The return +// value contains the actual set value, since Yggdrasil will not accept MTUs +// below 1280 bytes. The default value is 65535 bytes. +func (c *Core) SetMaximumSessionMTU(mtu uint16) uint16 { + if mtu < 1280 { + mtu = 1280 + } + c.router.sessions.myMaximumMTU = mtu + return mtu +} + // GetNodeInfo requests nodeinfo from a remote node, as specified by the public // key and coordinates specified. The third parameter specifies whether a cached // result is acceptable - this results in less traffic being generated than is diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index 2f5e0af3..b287377a 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -121,6 +121,7 @@ type sessions struct { lastCleanup time.Time isAllowedHandler func(pubkey *crypto.BoxPubKey, initiator bool) bool // Returns true or false if session setup is allowed isAllowedMutex sync.RWMutex // Protects the above + myMaximumMTU uint16 // Maximum allowed session MTU permShared map[crypto.BoxPubKey]*crypto.BoxSharedKey // Maps known permanent keys to their shared key, used by DHT a lot sinfos map[crypto.Handle]*sessionInfo // Maps handle onto session info byTheirPerm map[crypto.BoxPubKey]*crypto.Handle // Maps theirPermPub onto handle @@ -133,6 +134,7 @@ func (ss *sessions) init(r *router) { ss.sinfos = make(map[crypto.Handle]*sessionInfo) ss.byTheirPerm = make(map[crypto.BoxPubKey]*crypto.Handle) ss.lastCleanup = time.Now() + ss.myMaximumMTU = 65535 } func (ss *sessions) reconfigure() { @@ -187,9 +189,9 @@ func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo { sinfo.mySesPriv = *priv sinfo.myNonce = *crypto.NewBoxNonce() sinfo.theirMTU = 1280 - ss.router.core.config.Mutex.RLock() - sinfo.myMTU = uint16(ss.router.core.config.Current.IfMTU) - ss.router.core.config.Mutex.RUnlock() + // TODO: sinfo.myMTU becomes unnecessary if we always have a reference to the + // sessions struct so let's check if that is the case + sinfo.myMTU = ss.myMaximumMTU now := time.Now() sinfo.timeOpened = now sinfo.time = now