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:
commit
07ce8cde7a
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user