5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-10 08:40:28 +00:00

Merge pull request #156 from yggdrasil-network/develop

Version 0.2.4
This commit is contained in:
Neil Alexander 2018-07-08 18:46:48 +01:00 committed by GitHub
commit 059fe24526
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 298 additions and 149 deletions

View File

@ -25,6 +25,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- in case of vulnerabilities. - in case of vulnerabilities.
--> -->
## [0.2.4] - 2018-07-08
### Added
- Support for UNIX domain sockets for the admin socket using `unix:///path/to/file.sock`
- Centralised platform-specific defaults
### Changed
- Backpressure tuning, including reducing resource consumption
### Fixed
- macOS local ping bug, which previously prevented you from pinging your own `utun` adapter's IPv6 address
## [0.2.3] - 2018-06-29 ## [0.2.3] - 2018-06-29
### Added ### Added
- Begin keeping changelog (incomplete and possibly inaccurate information before this point). - Begin keeping changelog (incomplete and possibly inaccurate information before this point).

View File

@ -13,6 +13,8 @@ import (
"strings" "strings"
"sync/atomic" "sync/atomic"
"time" "time"
"yggdrasil/defaults"
) )
// TODO: Add authentication // TODO: Add authentication
@ -20,6 +22,7 @@ import (
type admin struct { type admin struct {
core *Core core *Core
listenaddr string listenaddr string
listener net.Listener
handlers []admin_handlerInfo handlers []admin_handlerInfo
} }
@ -155,15 +158,15 @@ func (a *admin) init(c *Core, listenaddr string) {
}) })
a.addHandler("setTunTap", []string{"name", "[tap_mode]", "[mtu]"}, func(in admin_info) (admin_info, error) { a.addHandler("setTunTap", []string{"name", "[tap_mode]", "[mtu]"}, func(in admin_info) (admin_info, error) {
// Set sane defaults // Set sane defaults
iftapmode := getDefaults().defaultIfTAPMode iftapmode := defaults.GetDefaults().DefaultIfTAPMode
ifmtu := getDefaults().defaultIfMTU ifmtu := defaults.GetDefaults().DefaultIfMTU
// Has TAP mode been specified? // Has TAP mode been specified?
if tap, ok := in["tap_mode"]; ok { if tap, ok := in["tap_mode"]; ok {
iftapmode = tap.(bool) iftapmode = tap.(bool)
} }
// Check we have enough params for MTU // Check we have enough params for MTU
if mtu, ok := in["mtu"]; ok { if mtu, ok := in["mtu"]; ok {
if mtu.(float64) >= 1280 && ifmtu <= getDefaults().maximumIfMTU { if mtu.(float64) >= 1280 && ifmtu <= defaults.GetDefaults().MaximumIfMTU {
ifmtu = int(in["mtu"].(float64)) ifmtu = int(in["mtu"].(float64))
} }
} }
@ -227,17 +230,37 @@ func (a *admin) start() error {
return nil return nil
} }
// cleans up when stopping
func (a *admin) close() error {
return a.listener.Close()
}
// listen is run by start and manages API connections. // listen is run by start and manages API connections.
func (a *admin) listen() { func (a *admin) listen() {
l, err := net.Listen("tcp", a.listenaddr) u, err := url.Parse(a.listenaddr)
if err == nil {
switch strings.ToLower(u.Scheme) {
case "unix":
a.listener, err = net.Listen("unix", a.listenaddr[7:])
case "tcp":
a.listener, err = net.Listen("tcp", u.Host)
default:
// err = errors.New(fmt.Sprint("protocol not supported: ", u.Scheme))
a.listener, err = net.Listen("tcp", a.listenaddr)
}
} else {
a.listener, err = net.Listen("tcp", a.listenaddr)
}
if err != nil { if err != nil {
a.core.log.Printf("Admin socket failed to listen: %v", err) a.core.log.Printf("Admin socket failed to listen: %v", err)
os.Exit(1) os.Exit(1)
} }
defer l.Close() a.core.log.Printf("%s admin socket listening on %s",
a.core.log.Printf("Admin socket listening on %s", l.Addr().String()) strings.ToUpper(a.listener.Addr().Network()),
a.listener.Addr().String())
defer a.listener.Close()
for { for {
conn, err := l.Accept() conn, err := a.listener.Accept()
if err == nil { if err == nil {
a.handleRequest(conn) a.handleRequest(conn)
} }

View File

@ -3,7 +3,7 @@ package config
// NodeConfig defines all configuration values needed to run a signle yggdrasil node // NodeConfig defines all configuration values needed to run a signle yggdrasil node
type NodeConfig struct { type NodeConfig struct {
Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."` Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."`
AdminListen string `comment:"Listen address for admin connections Default is to listen for local\nconnections only on TCP port 9001."` AdminListen string `comment:"Listen address for admin connections Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X."`
Peers []string `comment:"List of connection strings for static peers in URI format, i.e.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j"` Peers []string `comment:"List of connection strings for static peers in URI format, i.e.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j"`
AllowedEncryptionPublicKeys []string `comment:"List of peer encryption public keys to allow or incoming TCP\nconnections from. If left empty/undefined then all connections\nwill be allowed by default."` AllowedEncryptionPublicKeys []string `comment:"List of peer encryption public keys to allow or incoming TCP\nconnections from. If left empty/undefined then all connections\nwill be allowed by default."`
EncryptionPublicKey string `comment:"Your public encryption key. Your peers may ask you for this to put\ninto their AllowedEncryptionPublicKeys configuration."` EncryptionPublicKey string `comment:"Your public encryption key. Your peers may ask you for this to put\ninto their AllowedEncryptionPublicKeys configuration."`

View File

@ -9,6 +9,7 @@ import (
"regexp" "regexp"
"yggdrasil/config" "yggdrasil/config"
"yggdrasil/defaults"
) )
// The Core object represents the Yggdrasil node. You should create a Core // The Core object represents the Yggdrasil node. You should create a Core
@ -135,6 +136,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
func (c *Core) Stop() { func (c *Core) Stop() {
c.log.Println("Stopping...") c.log.Println("Stopping...")
c.tun.close() c.tun.close()
c.admin.close()
} }
// Generates a new encryption keypair. The encryption keys are used to // Generates a new encryption keypair. The encryption keys are used to
@ -197,26 +199,31 @@ func (c *Core) AddAllowedEncryptionPublicKey(boxStr string) error {
return c.admin.addAllowedEncryptionPublicKey(boxStr) return c.admin.addAllowedEncryptionPublicKey(boxStr)
} }
// Gets the default admin listen address for your platform.
func (c *Core) GetAdminDefaultListen() string {
return defaults.GetDefaults().DefaultAdminListen
}
// Gets the default TUN/TAP interface name for your platform. // Gets the default TUN/TAP interface name for your platform.
func (c *Core) GetTUNDefaultIfName() string { func (c *Core) GetTUNDefaultIfName() string {
return getDefaults().defaultIfName return defaults.GetDefaults().DefaultIfName
} }
// Gets the default TUN/TAP interface MTU for your platform. This can be as high // Gets the default TUN/TAP interface MTU for your platform. This can be as high
// as 65535, depending on platform, but is never lower than 1280. // as 65535, depending on platform, but is never lower than 1280.
func (c *Core) GetTUNDefaultIfMTU() int { func (c *Core) GetTUNDefaultIfMTU() int {
return getDefaults().defaultIfMTU return defaults.GetDefaults().DefaultIfMTU
} }
// Gets the maximum supported TUN/TAP interface MTU for your platform. This // Gets the maximum supported TUN/TAP interface MTU for your platform. This
// can be as high as 65535, depending on platform, but is never lower than 1280. // can be as high as 65535, depending on platform, but is never lower than 1280.
func (c *Core) GetTUNMaximumIfMTU() int { func (c *Core) GetTUNMaximumIfMTU() int {
return getDefaults().maximumIfMTU return defaults.GetDefaults().MaximumIfMTU
} }
// Gets the default TUN/TAP interface mode for your platform. // Gets the default TUN/TAP interface mode for your platform.
func (c *Core) GetTUNDefaultIfTAPMode() bool { func (c *Core) GetTUNDefaultIfTAPMode() bool {
return getDefaults().defaultIfTAPMode return defaults.GetDefaults().DefaultIfTAPMode
} }
// Gets the current TUN/TAP interface name. // Gets the current TUN/TAP interface name.

View File

@ -0,0 +1,15 @@
package defaults
// 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.
type platformDefaultParameters struct {
// Admin socket
DefaultAdminListen string
// TUN/TAP
MaximumIfMTU int
DefaultIfMTU int
DefaultIfName string
DefaultIfTAPMode bool
}

View File

@ -0,0 +1,18 @@
// +build darwin
package defaults
// Sane defaults for the macOS/Darwin platform. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 65535,
DefaultIfMTU: 65535,
DefaultIfName: "auto",
DefaultIfTAPMode: false,
}
}

View File

@ -0,0 +1,18 @@
// +build freebsd
package defaults
// Sane defaults for the BSD platforms. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 32767,
DefaultIfMTU: 32767,
DefaultIfName: "/dev/tap0",
DefaultIfTAPMode: true,
}
}

View File

@ -0,0 +1,18 @@
// +build linux
package defaults
// Sane defaults for the Linux platform. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 65535,
DefaultIfMTU: 65535,
DefaultIfName: "auto",
DefaultIfTAPMode: false,
}
}

View File

@ -0,0 +1,18 @@
// +build netbsd
package defaults
// Sane defaults for the BSD platforms. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 9000,
DefaultIfMTU: 9000,
DefaultIfName: "/dev/tap0",
DefaultIfTAPMode: true,
}
}

View File

@ -0,0 +1,18 @@
// +build openbsd
package defaults
// Sane defaults for the BSD platforms. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 16384,
DefaultIfMTU: 16384,
DefaultIfName: "/dev/tap0",
DefaultIfTAPMode: true,
}
}

View File

@ -0,0 +1,18 @@
// +build !linux,!darwin,!windows,!openbsd,!freebsd,!netbsd
package defaults
// Sane defaults for the other platforms. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 65535,
DefaultIfMTU: 65535,
DefaultIfName: "none",
DefaultIfTAPMode: false,
}
}

View File

@ -0,0 +1,18 @@
// +build windows
package defaults
// Sane defaults for the Windows platform. The "default" options may be
// may be replaced by the running configuration.
func GetDefaults() platformDefaultParameters {
return platformDefaultParameters{
// Admin
DefaultAdminListen: "tcp://localhost:9001",
// TUN/TAP
MaximumIfMTU: 65535,
DefaultIfMTU: 65535,
DefaultIfName: "auto",
DefaultIfTAPMode: true,
}
}

View File

@ -12,6 +12,7 @@ package yggdrasil
// A little annoying to do with constant changes from backpressure // A little annoying to do with constant changes from backpressure
import ( import (
"math/rand"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -595,55 +596,88 @@ type switch_packetInfo struct {
// Used to keep track of buffered packets // Used to keep track of buffered packets
type switch_buffer struct { type switch_buffer struct {
packets []switch_packetInfo // Currently buffered packets, which may be dropped if it grows too large packets []switch_packetInfo // Currently buffered packets, which may be dropped if it grows too large
count uint64 // Total queue size, including dropped packets size uint64 // Total queue size in bytes
} }
func (b *switch_buffer) dropTimedOut() { type switch_buffers struct {
// TODO figure out what timeout makes sense bufs map[string]switch_buffer // Buffers indexed by StreamID
const timeout = 25 * time.Millisecond size uint64 // Total size of all buffers, in bytes
now := time.Now() }
for len(b.packets) > 0 && now.Sub(b.packets[0].time) > timeout {
util_putBytes(b.packets[0].bytes) func (b *switch_buffers) cleanup(t *switchTable) {
b.packets = b.packets[1:] for streamID, buf := range b.bufs {
// Remove queues for which we have no next hop
packet := buf.packets[0]
coords := switch_getPacketCoords(packet.bytes)
if t.selfIsClosest(coords) {
for _, packet := range buf.packets {
util_putBytes(packet.bytes)
}
b.size -= buf.size
delete(b.bufs, streamID)
}
}
const maxSize = 4 * 1048576 // Maximum 4 MB
for b.size > maxSize {
// Drop a random queue
target := rand.Uint64() % b.size
var size uint64 // running total
for streamID, buf := range b.bufs {
size += buf.size
if size < target {
continue
}
var packet switch_packetInfo
packet, buf.packets = buf.packets[0], buf.packets[1:]
buf.size -= uint64(len(packet.bytes))
b.size -= uint64(len(packet.bytes))
util_putBytes(packet.bytes)
if len(buf.packets) == 0 {
delete(b.bufs, streamID)
} else {
// Need to update the map, since buf was retrieved by value
b.bufs[streamID] = buf
}
break
}
} }
} }
// Handles incoming idle notifications // Handles incoming idle notifications
// Loops over packets and sends the newest one that's OK for this peer to send // Loops over packets and sends the newest one that's OK for this peer to send
// Returns true if the peer is no longer idle, false if it should be added to the idle list // Returns true if the peer is no longer idle, false if it should be added to the idle list
func (t *switchTable) handleIdle(port switchPort, buffs map[string]switch_buffer) bool { func (t *switchTable) handleIdle(port switchPort, bufs *switch_buffers) bool {
to := t.core.peers.getPorts()[port] to := t.core.peers.getPorts()[port]
if to == nil { if to == nil {
return true return true
} }
var best string var best string
var bestSize uint64 var bestPriority float64
for streamID, buf := range buffs { bufs.cleanup(t)
now := time.Now()
for streamID, buf := range bufs.bufs {
// Filter over the streams that this node is closer to // Filter over the streams that this node is closer to
// Keep the one with the smallest queue // Keep the one with the smallest queue
buf.dropTimedOut()
if len(buf.packets) == 0 {
delete(buffs, streamID)
continue
}
buffs[streamID] = buf
packet := buf.packets[0] packet := buf.packets[0]
coords := switch_getPacketCoords(packet.bytes) coords := switch_getPacketCoords(packet.bytes)
if (bestSize == 0 || buf.count < bestSize) && t.portIsCloser(coords, port) { priority := float64(now.Sub(packet.time)) / float64(buf.size)
if priority > bestPriority && t.portIsCloser(coords, port) {
best = streamID best = streamID
bestSize = buf.count bestPriority = priority
} }
} }
if bestSize != 0 { if bestPriority != 0 {
buf := buffs[best] buf := bufs.bufs[best]
var packet switch_packetInfo var packet switch_packetInfo
// TODO decide if this should be LIFO or FIFO // TODO decide if this should be LIFO or FIFO
packet, buf.packets = buf.packets[0], buf.packets[1:] packet, buf.packets = buf.packets[0], buf.packets[1:]
buf.count-- buf.size -= uint64(len(packet.bytes))
bufs.size -= uint64(len(packet.bytes))
if len(buf.packets) == 0 { if len(buf.packets) == 0 {
delete(buffs, best) delete(bufs.bufs, best)
} else { } else {
buffs[best] = buf // Need to update the map, since buf was retrieved by value
bufs.bufs[best] = buf
} }
to.sendPacket(packet.bytes) to.sendPacket(packet.bytes)
return true return true
@ -654,25 +688,27 @@ func (t *switchTable) handleIdle(port switchPort, buffs map[string]switch_buffer
// The switch worker does routing lookups and sends packets to where they need to be // The switch worker does routing lookups and sends packets to where they need to be
func (t *switchTable) doWorker() { func (t *switchTable) doWorker() {
buffs := make(map[string]switch_buffer) // Packets per PacketStreamID (string) var bufs switch_buffers
idle := make(map[switchPort]struct{}) // this is to deduplicate things bufs.bufs = make(map[string]switch_buffer) // Packets per PacketStreamID (string)
idle := make(map[switchPort]struct{}) // this is to deduplicate things
for { for {
select { select {
case packet := <-t.packetIn: case bytes := <-t.packetIn:
// Try to send it somewhere (or drop it if it's corrupt or at a dead end) // Try to send it somewhere (or drop it if it's corrupt or at a dead end)
if !t.handleIn(packet, idle) { if !t.handleIn(bytes, idle) {
// There's nobody free to take it right now, so queue it for later // There's nobody free to take it right now, so queue it for later
streamID := switch_getPacketStreamID(packet) packet := switch_packetInfo{bytes, time.Now()}
buf := buffs[streamID] streamID := switch_getPacketStreamID(packet.bytes)
buf.dropTimedOut() buf := bufs.bufs[streamID]
pinfo := switch_packetInfo{packet, time.Now()} buf.packets = append(buf.packets, packet)
buf.packets = append(buf.packets, pinfo) buf.size += uint64(len(packet.bytes))
buf.count++ bufs.size += uint64(len(packet.bytes))
buffs[streamID] = buf bufs.bufs[streamID] = buf
bufs.cleanup(t)
} }
case port := <-t.idleIn: case port := <-t.idleIn:
// Try to find something to send to this peer // Try to find something to send to this peer
if !t.handleIdle(port, buffs) { if !t.handleIdle(port, &bufs) {
// Didn't find anything ready to send yet, so stay idle // Didn't find anything ready to send yet, so stay idle
idle[port] = struct{}{} idle[port] = struct{}{}
} }

View File

@ -3,6 +3,8 @@ package yggdrasil
// This manages the tun driver to send/recv packets to/from applications // This manages the tun driver to send/recv packets to/from applications
import ( import (
"yggdrasil/defaults"
"github.com/songgao/packets/ethernet" "github.com/songgao/packets/ethernet"
"github.com/yggdrasil-network/water" "github.com/yggdrasil-network/water"
) )
@ -20,21 +22,11 @@ type tunDevice struct {
iface *water.Interface iface *water.Interface
} }
// Defines which parameters are expected by default for a TUN/TAP adapter on a
// specific platform. These values are populated in the relevant tun_*.go for
// the platform being targeted. They must be set.
type tunDefaultParameters struct {
maximumIfMTU int
defaultIfMTU int
defaultIfName string
defaultIfTAPMode bool
}
// Gets the maximum supported MTU for the platform based on the defaults in // Gets the maximum supported MTU for the platform based on the defaults in
// getDefaults(). // defaults.GetDefaults().
func getSupportedMTU(mtu int) int { func getSupportedMTU(mtu int) int {
if mtu > getDefaults().maximumIfMTU { if mtu > defaults.GetDefaults().MaximumIfMTU {
return getDefaults().maximumIfMTU return defaults.GetDefaults().MaximumIfMTU
} }
return mtu return mtu
} }

View File

@ -13,17 +13,6 @@ import (
water "github.com/yggdrasil-network/water" water "github.com/yggdrasil-network/water"
) )
// Sane defaults for the Darwin/macOS platform. The "default" options may be
// may be replaced by the running configuration.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 65535,
defaultIfMTU: 65535,
defaultIfName: "auto",
defaultIfTAPMode: false,
}
}
// Configures the "utun" adapter with the correct IPv6 address and MTU. // Configures the "utun" adapter with the correct IPv6 address and MTU.
func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error {
if iftapmode { if iftapmode {

View File

@ -1,12 +0,0 @@
package yggdrasil
// Sane defaults for the FreeBSD platform. The "default" options may be
// may be replaced by the running configuration.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 32767,
defaultIfMTU: 32767,
defaultIfName: "/dev/tap0",
defaultIfTAPMode: true,
}
}

View File

@ -12,17 +12,6 @@ import (
water "github.com/yggdrasil-network/water" water "github.com/yggdrasil-network/water"
) )
// Sane defaults for the Linux platform. The "default" options may be
// may be replaced by the running configuration.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 65535,
defaultIfMTU: 65535,
defaultIfName: "auto",
defaultIfTAPMode: false,
}
}
// Configures the TAP adapter with the correct IPv6 address and MTU. // Configures the TAP adapter with the correct IPv6 address and MTU.
func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error {
var config water.Config var config water.Config

View File

@ -1,12 +0,0 @@
package yggdrasil
// Sane defaults for the NetBSD platform. The "default" options may be
// may be replaced by the running configuration.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 9000,
defaultIfMTU: 9000,
defaultIfName: "/dev/tap0",
defaultIfTAPMode: true,
}
}

View File

@ -1,12 +0,0 @@
package yggdrasil
// Sane defaults for the OpenBSD platform. The "default" options may be
// may be replaced by the running configuration.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 16384,
defaultIfMTU: 16384,
defaultIfName: "/dev/tap0",
defaultIfTAPMode: true,
}
}

View File

@ -7,17 +7,6 @@ import water "github.com/yggdrasil-network/water"
// This is to catch unsupported platforms // This is to catch unsupported platforms
// If your platform supports tun devices, you could try configuring it manually // If your platform supports tun devices, you could try configuring it manually
// These are sane defaults for any platform that has not been matched by one of
// the other tun_*.go files.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 65535,
defaultIfMTU: 65535,
defaultIfName: "none",
defaultIfTAPMode: false,
}
}
// Creates the TUN/TAP adapter, if supported by the Water library. Note that // Creates the TUN/TAP adapter, if supported by the Water library. Note that
// no guarantees are made at this point on an unsupported platform. // no guarantees are made at this point on an unsupported platform.
func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error {

View File

@ -10,17 +10,6 @@ import (
// This is to catch Windows platforms // This is to catch Windows platforms
// Sane defaults for the Windows platform. The "default" options may be
// may be replaced by the running configuration.
func getDefaults() tunDefaultParameters {
return tunDefaultParameters{
maximumIfMTU: 65535,
defaultIfMTU: 65535,
defaultIfName: "auto",
defaultIfTAPMode: true,
}
}
// Configures the TAP adapter with the correct IPv6 address and MTU. On Windows // Configures the TAP adapter with the correct IPv6 address and MTU. On Windows
// we don't make use of a direct operating system API to do this - we instead // we don't make use of a direct operating system API to do this - we instead
// delegate the hard work to "netsh". // delegate the hard work to "netsh".

View File

@ -23,6 +23,7 @@ import (
"yggdrasil" "yggdrasil"
"yggdrasil/config" "yggdrasil/config"
"yggdrasil/defaults"
) )
type nodeConfig = config.NodeConfig type nodeConfig = config.NodeConfig
@ -53,7 +54,7 @@ func generateConfig(isAutoconf bool) *nodeConfig {
r1 := rand.New(rand.NewSource(time.Now().UnixNano())) r1 := rand.New(rand.NewSource(time.Now().UnixNano()))
cfg.Listen = fmt.Sprintf("[::]:%d", r1.Intn(65534-32768)+32768) cfg.Listen = fmt.Sprintf("[::]:%d", r1.Intn(65534-32768)+32768)
} }
cfg.AdminListen = "localhost:9001" cfg.AdminListen = defaults.GetDefaults().DefaultAdminListen
cfg.EncryptionPublicKey = hex.EncodeToString(bpub[:]) cfg.EncryptionPublicKey = hex.EncodeToString(bpub[:])
cfg.EncryptionPrivateKey = hex.EncodeToString(bpriv[:]) cfg.EncryptionPrivateKey = hex.EncodeToString(bpriv[:])
cfg.SigningPublicKey = hex.EncodeToString(spub[:]) cfg.SigningPublicKey = hex.EncodeToString(spub[:])
@ -61,9 +62,9 @@ func generateConfig(isAutoconf bool) *nodeConfig {
cfg.Peers = []string{} cfg.Peers = []string{}
cfg.AllowedEncryptionPublicKeys = []string{} cfg.AllowedEncryptionPublicKeys = []string{}
cfg.MulticastInterfaces = []string{".*"} cfg.MulticastInterfaces = []string{".*"}
cfg.IfName = core.GetTUNDefaultIfName() cfg.IfName = defaults.GetDefaults().DefaultIfName
cfg.IfMTU = core.GetTUNDefaultIfMTU() cfg.IfMTU = defaults.GetDefaults().DefaultIfMTU
cfg.IfTAPMode = core.GetTUNDefaultIfTAPMode() cfg.IfTAPMode = defaults.GetDefaults().DefaultIfTAPMode
return &cfg return &cfg
} }

View File

@ -1,31 +1,49 @@
package main package main
import "errors"
import "flag" import "flag"
import "fmt" import "fmt"
import "strings" import "strings"
import "net" import "net"
import "net/url"
import "sort" import "sort"
import "encoding/json" import "encoding/json"
import "strconv" import "strconv"
import "os" import "os"
import "yggdrasil/defaults"
type admin_info map[string]interface{} type admin_info map[string]interface{}
func main() { func main() {
server := flag.String("endpoint", "localhost:9001", "Admin socket endpoint") server := flag.String("endpoint", defaults.GetDefaults().DefaultAdminListen, "Admin socket endpoint")
injson := flag.Bool("json", false, "Output in JSON format") injson := flag.Bool("json", false, "Output in JSON format")
flag.Parse() flag.Parse()
args := flag.Args() args := flag.Args()
if len(args) == 0 { if len(args) == 0 {
fmt.Println("usage:", os.Args[0], "[-endpoint=localhost:9001] [-json] command [key=value] [...]") fmt.Println("usage:", os.Args[0], "[-endpoint=proto://server] [-json] command [key=value] [...]")
fmt.Println("example:", os.Args[0], "getPeers") fmt.Println("example:", os.Args[0], "getPeers")
fmt.Println("example:", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false") fmt.Println("example:", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false")
fmt.Println("example:", os.Args[0], "-endpoint=localhost:9001 getDHT") fmt.Println("example:", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT")
fmt.Println("example:", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT")
return return
} }
conn, err := net.Dial("tcp", *server) var conn net.Conn
u, err := url.Parse(*server)
if err == nil {
switch strings.ToLower(u.Scheme) {
case "unix":
conn, err = net.Dial("unix", (*server)[7:])
case "tcp":
conn, err = net.Dial("tcp", u.Host)
default:
err = errors.New("protocol not supported")
}
} else {
conn, err = net.Dial("tcp", *server)
}
if err != nil { if err != nil {
panic(err) panic(err)
} }