diff --git a/src/config/config.go b/src/config/config.go index 93b77ee..95d9bbd 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -22,8 +22,11 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/types" ) +type MTU = types.MTU + // NodeState represents the active and previous configuration of an Yggdrasil // node. A NodeState object is returned when starting an Yggdrasil node. Note // that this structure and related functions are likely to disappear soon. @@ -71,7 +74,7 @@ type NodeConfig struct { SigningPrivateKey string `comment:"Your private signing key. DO NOT share this with anyone!"` LinkLocalTCPPort uint16 `comment:"The port number to be used for the link-local TCP listeners for the\nconfigured MulticastInterfaces. This option does not affect listeners\nspecified in the Listen option. Unless you plan to firewall link-local\ntraffic, it is best to leave this as the default value of 0. This\noption cannot currently be changed by reloading config during runtime."` IfName string `comment:"Local network interface name for TUN adapter, or \"auto\" to select\nan interface automatically, or \"none\" to run without TUN."` - IfMTU int `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` + IfMTU MTU `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` SessionFirewall SessionFirewall `comment:"The session firewall controls who can send/receive network traffic\nto/from. This is useful if you want to protect this node without\nresorting to using a real firewall. This does not affect traffic\nbeing routed via this node to somewhere else. Rules are prioritised as\nfollows: blacklist, whitelist, always allow outgoing, direct, remote."` TunnelRouting TunnelRouting `comment:"Allow tunneling non-Yggdrasil traffic over Yggdrasil. This effectively\nallows you to use Yggdrasil to route to, or to bridge other networks,\nsimilar to a VPN tunnel. Tunnelling works between any two nodes and\ndoes not require them to be directly peered."` SwitchOptions SwitchOptions `comment:"Advanced options for tuning the switch. Normally you will not need\nto edit these options."` diff --git a/src/defaults/defaults.go b/src/defaults/defaults.go index ceb58ba..a0d372e 100644 --- a/src/defaults/defaults.go +++ b/src/defaults/defaults.go @@ -1,5 +1,7 @@ package defaults +import "github.com/yggdrasil-network/yggdrasil-go/src/types" + // Defines which parameters are expected by default for configuration on a // specific platform. These values are populated in the relevant defaults_*.go // for the platform being targeted. They must be set. @@ -14,7 +16,7 @@ type platformDefaultParameters struct { DefaultMulticastInterfaces []string // TUN/TAP - MaximumIfMTU int - DefaultIfMTU int + MaximumIfMTU types.MTU + DefaultIfMTU types.MTU DefaultIfName string } diff --git a/src/tuntap/iface.go b/src/tuntap/iface.go index 5efbc8a..1e5902e 100644 --- a/src/tuntap/iface.go +++ b/src/tuntap/iface.go @@ -55,7 +55,7 @@ type tunReader struct { func (r *tunReader) _read() { // Get a slice to store the packet in - recvd := util.ResizeBytes(util.GetBytes(), r.tun.mtu+TUN_OFFSET_BYTES) + recvd := util.ResizeBytes(util.GetBytes(), int(r.tun.mtu)+TUN_OFFSET_BYTES) // Wait for a packet to be delivered to us through the TUN adapter n, err := r.tun.iface.Read(recvd, TUN_OFFSET_BYTES) if n <= TUN_OFFSET_BYTES || err != nil { diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index 807ce7f..be0ea70 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -25,8 +25,11 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/defaults" "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" + "github.com/yggdrasil-network/yggdrasil-go/src/types" ) +type MTU = types.MTU + const tun_IPv6_HEADER_LENGTH = 40 // TunAdapter represents a running TUN interface and extends the @@ -46,7 +49,7 @@ type TunAdapter struct { subnet address.Subnet ckr cryptokey icmpv6 ICMPv6 - mtu int + mtu MTU iface tun.Device phony.Inbox // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below //mutex sync.RWMutex // Protects the below @@ -63,7 +66,7 @@ type TunOptions struct { // Gets the maximum supported MTU for the platform based on the defaults in // defaults.GetDefaults(). -func getSupportedMTU(mtu int) int { +func getSupportedMTU(mtu MTU) MTU { if mtu < 1280 { return 1280 } @@ -85,7 +88,7 @@ func (tun *TunAdapter) Name() string { // MTU gets the adapter's MTU. This can range between 1280 and 65535, although // the maximum value is determined by your platform. The returned value will // never exceed that of MaximumMTU(). -func (tun *TunAdapter) MTU() int { +func (tun *TunAdapter) MTU() MTU { return getSupportedMTU(tun.mtu) } @@ -96,14 +99,14 @@ func DefaultName() string { // DefaultMTU gets the default TUN interface MTU for your platform. This can // be as high as MaximumMTU(), depending on platform, but is never lower than 1280. -func DefaultMTU() int { +func DefaultMTU() MTU { return defaults.GetDefaults().DefaultIfMTU } // MaximumMTU returns the maximum supported TUN interface MTU for your // platform. This can be as high as 65535, depending on platform, but is never // lower than 1280. -func MaximumMTU() int { +func MaximumMTU() MTU { return defaults.GetDefaults().MaximumIfMTU } @@ -165,7 +168,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.core.SetMaximumSessionMTU(uint16(tun.MTU())) + tun.core.SetMaximumSessionMTU(tun.MTU()) tun.isOpen = true go tun.handler() tun.reader.Act(nil, tun.reader._read) // Start the reader diff --git a/src/tuntap/tun_bsd.go b/src/tuntap/tun_bsd.go index 219e348..4710e8c 100644 --- a/src/tuntap/tun_bsd.go +++ b/src/tuntap/tun_bsd.go @@ -73,14 +73,14 @@ type in6_ifreq_lifetime struct { } // Configures the TUN adapter with the correct IPv6 address and MTU. -func (tun *TunAdapter) setup(ifname string, addr string, mtu int) error { - iface, err := wgtun.CreateTUN(ifname, mtu) +func (tun *TunAdapter) setup(ifname string, addr string, mtu MTU) error { + iface, err := wgtun.CreateTUN(ifname, int(mtu)) if err != nil { panic(err) } tun.iface = iface if mtu, err := iface.MTU(); err == nil { - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(MTU(mtu)) } else { tun.mtu = 0 } diff --git a/src/tuntap/tun_darwin.go b/src/tuntap/tun_darwin.go index cf2fbfb..b984e16 100644 --- a/src/tuntap/tun_darwin.go +++ b/src/tuntap/tun_darwin.go @@ -16,17 +16,17 @@ import ( ) // Configures the "utun" adapter with the correct IPv6 address and MTU. -func (tun *TunAdapter) setup(ifname string, addr string, mtu int) error { +func (tun *TunAdapter) setup(ifname string, addr string, mtu MTU) error { if ifname == "auto" { ifname = "utun" } - iface, err := wgtun.CreateTUN(ifname, mtu) + iface, err := wgtun.CreateTUN(ifname, int(mtu)) if err != nil { panic(err) } tun.iface = iface if mtu, err := iface.MTU(); err == nil { - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(MTU(mtu)) } else { tun.mtu = 0 } diff --git a/src/tuntap/tun_linux.go b/src/tuntap/tun_linux.go index 4206b26..ad7b64e 100644 --- a/src/tuntap/tun_linux.go +++ b/src/tuntap/tun_linux.go @@ -10,17 +10,17 @@ import ( ) // Configures the TUN adapter with the correct IPv6 address and MTU. -func (tun *TunAdapter) setup(ifname string, addr string, mtu int) error { +func (tun *TunAdapter) setup(ifname string, addr string, mtu MTU) error { if ifname == "auto" { ifname = "\000" } - iface, err := wgtun.CreateTUN(ifname, mtu) + iface, err := wgtun.CreateTUN(ifname, int(mtu)) if err != nil { panic(err) } tun.iface = iface if mtu, err := iface.MTU(); err == nil { - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(MTU(mtu)) } else { tun.mtu = 0 } @@ -43,7 +43,7 @@ func (tun *TunAdapter) setupAddress(addr string) error { if err := netlink.AddrAdd(nlintf, nladdr); err != nil { return err } - if err := netlink.LinkSetMTU(nlintf, tun.mtu); err != nil { + if err := netlink.LinkSetMTU(nlintf, int(tun.mtu)); err != nil { return err } if err := netlink.LinkSetUp(nlintf); err != nil { diff --git a/src/tuntap/tun_windows.go b/src/tuntap/tun_windows.go index 9b5f7b0..8eb2165 100644 --- a/src/tuntap/tun_windows.go +++ b/src/tuntap/tun_windows.go @@ -19,7 +19,7 @@ import ( // This is to catch Windows platforms // Configures the TUN adapter with the correct IPv6 address and MTU. -func (tun *TunAdapter) setup(ifname string, addr string, mtu int) error { +func (tun *TunAdapter) setup(ifname string, addr string, mtu MTU) error { if ifname == "auto" { ifname = defaults.GetDefaults().DefaultIfName } @@ -30,7 +30,7 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu int) error { if guid, err = windows.GUIDFromString("{8f59971a-7872-4aa6-b2eb-061fc4e9d0a7}"); err != nil { return err } - if iface, err = wgtun.CreateTUNWithRequestedGUID(ifname, &guid, mtu); err != nil { + if iface, err = wgtun.CreateTUNWithRequestedGUID(ifname, &guid, int(mtu)); err != nil { return err } tun.iface = iface @@ -42,15 +42,15 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu int) error { tun.log.Errorln("Failed to set up TUN MTU:", err) return err } - if mtu, err = iface.MTU(); err == nil { - tun.mtu = mtu + if mtu, err := iface.MTU(); err == nil { + tun.mtu = MTU(mtu) } return nil }) } // Sets the MTU of the TAP adapter. -func (tun *TunAdapter) setupMTU(mtu int) error { +func (tun *TunAdapter) setupMTU(mtu MTU) error { if tun.iface == nil || tun.Name() == "" { return errors.New("Can't configure MTU as TUN adapter is not present") } diff --git a/src/types/types.go b/src/types/types.go new file mode 100644 index 0000000..5d1c024 --- /dev/null +++ b/src/types/types.go @@ -0,0 +1,3 @@ +package types + +type MTU uint16 diff --git a/src/yggdrasil/api.go b/src/yggdrasil/api.go index 693dbd0..39b2a52 100644 --- a/src/yggdrasil/api.go +++ b/src/yggdrasil/api.go @@ -99,7 +99,7 @@ type Session struct { Coords []uint64 // The coordinates of the remote node BytesSent uint64 // Bytes sent to the session BytesRecvd uint64 // Bytes received from the session - MTU uint16 // The maximum supported message size of the session + MTU MTU // The maximum supported message size of the session Uptime time.Duration // How long this session has been active for WasMTUFixed bool // This field is no longer used } @@ -364,8 +364,8 @@ func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) { } // GetMaximumSessionMTU returns the maximum allowed session MTU size. -func (c *Core) GetMaximumSessionMTU() uint16 { - var mtu uint16 +func (c *Core) GetMaximumSessionMTU() MTU { + var mtu MTU phony.Block(&c.router, func() { mtu = c.router.sessions.myMaximumMTU }) @@ -375,7 +375,7 @@ func (c *Core) GetMaximumSessionMTU() uint16 { // 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) { +func (c *Core) SetMaximumSessionMTU(mtu MTU) { phony.Block(&c.router, func() { if c.router.sessions.myMaximumMTU != mtu { c.router.sessions.myMaximumMTU = mtu diff --git a/src/yggdrasil/conn.go b/src/yggdrasil/conn.go index 9a26432..dab38d3 100644 --- a/src/yggdrasil/conn.go +++ b/src/yggdrasil/conn.go @@ -8,10 +8,13 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/util" + "github.com/yggdrasil-network/yggdrasil-go/src/types" "github.com/Arceliar/phony" ) +type MTU = types.MTU + // ConnError implements the net.Error interface type ConnError struct { error @@ -65,7 +68,7 @@ type Conn struct { nodeID *crypto.NodeID nodeMask *crypto.NodeID session *sessionInfo - mtu uint16 + mtu MTU readCallback func([]byte) readBuffer chan []byte } @@ -93,7 +96,7 @@ func (c *Conn) String() string { return s } -func (c *Conn) setMTU(from phony.Actor, mtu uint16) { +func (c *Conn) setMTU(from phony.Actor, mtu MTU) { c.Act(from, func() { c.mtu = mtu }) } diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index ecc7d49..91c530d 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -36,8 +36,8 @@ type sessionInfo struct { myHandle crypto.Handle // theirNonce crypto.BoxNonce // myNonce crypto.BoxNonce // - theirMTU uint16 // - myMTU uint16 // + theirMTU MTU // + myMTU MTU // wasMTUFixed bool // Was the MTU fixed by a receive error? timeOpened time.Time // Time the session was opened time time.Time // Time we last received a packet @@ -63,7 +63,7 @@ type sessionPing struct { Coords []byte // Tstamp int64 // unix time, but the only real requirement is that it increases IsPong bool // - MTU uint16 // + MTU MTU // } // Updates session info in response to a ping, after checking that the ping is OK. @@ -117,7 +117,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 + myMaximumMTU MTU // 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 @@ -385,7 +385,7 @@ func (ss *sessions) handlePing(ping *sessionPing) { // Get the MTU of the session. // Will be equal to the smaller of this node's MTU or the remote node's MTU. // If sending over links with a maximum message size (this was a thing with the old UDP code), it could be further lowered, to a minimum of 1280. -func (sinfo *sessionInfo) _getMTU() uint16 { +func (sinfo *sessionInfo) _getMTU() MTU { if sinfo.theirMTU == 0 || sinfo.myMTU == 0 { return 0 } diff --git a/src/yggdrasil/wire.go b/src/yggdrasil/wire.go index 4ff19e2..18a647d 100644 --- a/src/yggdrasil/wire.go +++ b/src/yggdrasil/wire.go @@ -380,7 +380,7 @@ func (p *sessionPing) decode(bs []byte) bool { if pType == wire_SessionPong { p.IsPong = true } - p.MTU = uint16(mtu) + p.MTU = MTU(mtu) return true }