5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-01 19:41:35 +00:00

Merge pull request #613 from neilalexander/mtuagain

Add API functions for manipulating maximum session MTU
This commit is contained in:
Arceliar 2019-11-21 19:29:06 -06:00 committed by GitHub
commit 07ce8cde7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 11 deletions

View File

@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [0.3.12] - 2019-11-22 ## [0.3.12] - 2019-11-22
### Added ### Added
- New API functions `SetMaximumSessionMTU` and `GetMaximumSessionMTU`
- New command line parameters `-address` and `-subnet` for getting the address/subnet from the config file, for use with `-useconffile` or `-useconf` - New command line parameters `-address` and `-subnet` for getting the address/subnet from the config file, for use with `-useconffile` or `-useconf`
- A warning is now produced in the Yggdrasil output at startup when the MTU in the config is invalid or has been adjusted for some reason - A warning is now produced in the Yggdrasil output at startup when the MTU in the config is invalid or has been adjusted for some reason

View File

@ -35,6 +35,7 @@ const tun_ETHER_HEADER_LENGTH = 14
// you should pass this object to the yggdrasil.SetRouterAdapter() function // you should pass this object to the yggdrasil.SetRouterAdapter() function
// before calling yggdrasil.Start(). // before calling yggdrasil.Start().
type TunAdapter struct { type TunAdapter struct {
core *yggdrasil.Core
writer tunWriter writer tunWriter
reader tunReader reader tunReader
config *config.NodeState config *config.NodeState
@ -131,6 +132,7 @@ func (tun *TunAdapter) Init(core *yggdrasil.Core, config *config.NodeState, log
if !ok { if !ok {
return fmt.Errorf("invalid options supplied to TunAdapter module") return fmt.Errorf("invalid options supplied to TunAdapter module")
} }
tun.core = core
tun.config = config tun.config = config
tun.log = log tun.log = log
tun.listener = tunoptions.Listener tun.listener = tunoptions.Listener
@ -181,6 +183,7 @@ func (tun *TunAdapter) _start() error {
if tun.MTU() != current.IfMTU { 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.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 tun.isOpen = true
go tun.handler() go tun.handler()
tun.reader.Act(nil, tun.reader._read) // Start the reader tun.reader.Act(nil, tun.reader._read) // Start the reader
@ -230,6 +233,12 @@ func (tun *TunAdapter) UpdateConfig(config *config.NodeConfig) {
// Replace the active configuration with the supplied one // Replace the active configuration with the supplied one
tun.config.Replace(*config) tun.config.Replace(*config)
// If the MTU has changed in the TUN/TAP module then this is where we would
// tell the router so that updated session pings can be sent. However, we
// don't currently update the MTU of the adapter once it has been created so
// this doesn't actually happen in the real world yet.
// tun.core.SetMaximumSessionMTU(...)
// Notify children about the configuration change // Notify children about the configuration change
tun.Act(nil, tun.ckr.configure) tun.Act(nil, tun.ckr.configure)
} }

View File

@ -363,6 +363,27 @@ func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) {
c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy) c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy)
} }
// GetMaximumSessionMTU returns the maximum allowed session MTU size.
func (c *Core) GetMaximumSessionMTU() uint16 {
var mtu uint16
phony.Block(&c.router, func() {
mtu = c.router.sessions.myMaximumMTU
})
return mtu
}
// SetMaximumSessionMTU sets the maximum allowed session MTU size. The default
// value is 65535 bytes. Session pings will be sent to update all open sessions
// if the MTU has changed.
func (c *Core) SetMaximumSessionMTU(mtu uint16) {
phony.Block(&c.router, func() {
if c.router.sessions.myMaximumMTU != mtu {
c.router.sessions.myMaximumMTU = mtu
c.router.sessions.reconfigure()
}
})
}
// GetNodeInfo requests nodeinfo from a remote node, as specified by the public // GetNodeInfo requests nodeinfo from a remote node, as specified by the public
// key and coordinates specified. The third parameter specifies whether a cached // key and coordinates specified. The third parameter specifies whether a cached
// result is acceptable - this results in less traffic being generated than is // result is acceptable - this results in less traffic being generated than is

View File

@ -55,10 +55,6 @@ type sessionInfo struct {
callbacks []chan func() // Finished work from crypto workers callbacks []chan func() // Finished work from crypto workers
} }
func (sinfo *sessionInfo) reconfigure() {
// This is where reconfiguration would go, if we had anything to do
}
// Represents a session ping/pong packet, andincludes information like public keys, a session handle, coords, a timestamp to prevent replays, and the tun/tap MTU. // Represents a session ping/pong packet, andincludes information like public keys, a session handle, coords, a timestamp to prevent replays, and the tun/tap MTU.
type sessionPing struct { type sessionPing struct {
SendPermPub crypto.BoxPubKey // Sender's permanent key SendPermPub crypto.BoxPubKey // Sender's permanent key
@ -121,6 +117,7 @@ type sessions struct {
lastCleanup time.Time lastCleanup time.Time
isAllowedHandler func(pubkey *crypto.BoxPubKey, initiator bool) bool // Returns true or false if session setup is allowed isAllowedHandler func(pubkey *crypto.BoxPubKey, initiator bool) bool // Returns true or false if session setup is allowed
isAllowedMutex sync.RWMutex // Protects the above 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 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 sinfos map[crypto.Handle]*sessionInfo // Maps handle onto session info
byTheirPerm map[crypto.BoxPubKey]*crypto.Handle // Maps theirPermPub onto handle byTheirPerm map[crypto.BoxPubKey]*crypto.Handle // Maps theirPermPub onto handle
@ -133,12 +130,19 @@ func (ss *sessions) init(r *router) {
ss.sinfos = make(map[crypto.Handle]*sessionInfo) ss.sinfos = make(map[crypto.Handle]*sessionInfo)
ss.byTheirPerm = make(map[crypto.BoxPubKey]*crypto.Handle) ss.byTheirPerm = make(map[crypto.BoxPubKey]*crypto.Handle)
ss.lastCleanup = time.Now() ss.lastCleanup = time.Now()
ss.myMaximumMTU = 65535
} }
func (ss *sessions) reconfigure() { func (ss *sessions) reconfigure() {
ss.router.Act(nil, func() {
for _, session := range ss.sinfos { for _, session := range ss.sinfos {
session.reconfigure() sinfo, mtu := session, ss.myMaximumMTU
sinfo.Act(ss.router, func() {
sinfo.myMTU = mtu
})
session.ping(ss.router)
} }
})
} }
// Determines whether the session with a given publickey is allowed based on // Determines whether the session with a given publickey is allowed based on
@ -187,9 +191,7 @@ func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo {
sinfo.mySesPriv = *priv sinfo.mySesPriv = *priv
sinfo.myNonce = *crypto.NewBoxNonce() sinfo.myNonce = *crypto.NewBoxNonce()
sinfo.theirMTU = 1280 sinfo.theirMTU = 1280
ss.router.core.config.Mutex.RLock() sinfo.myMTU = ss.myMaximumMTU
sinfo.myMTU = uint16(ss.router.core.config.Current.IfMTU)
ss.router.core.config.Mutex.RUnlock()
now := time.Now() now := time.Now()
sinfo.timeOpened = now sinfo.timeOpened = now
sinfo.time = now sinfo.time = now