5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-09-20 08:22:32 +00:00

Merge pull request #164 from yggdrasil-network/develop

Version 0.2.5
This commit is contained in:
Arceliar 2018-07-19 18:47:40 -05:00 committed by GitHub
commit dc0c3f9f8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 69 additions and 30 deletions

View File

@ -25,6 +25,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- in case of vulnerabilities. - in case of vulnerabilities.
--> -->
## [0.2.5] - 2018-07-19
### Changed
- Make `yggdrasilctl` less case sensitive
- More verbose TCP disconnect messages
### Fixed
- Fixed debug builds
- Cap maximum MTU on Linux in TAP mode
- Process successfully-read TCP traffic before checking for / handling errors (fixes EOF behavior)
## [0.2.4] - 2018-07-08 ## [0.2.4] - 2018-07-08
### Added ### Added
- Support for UNIX domain sockets for the admin socket using `unix:///path/to/file.sock` - Support for UNIX domain sockets for the admin socket using `unix:///path/to/file.sock`

View File

@ -309,7 +309,7 @@ func (a *admin) handleRequest(conn net.Conn) {
handlers: handlers:
for _, handler := range a.handlers { for _, handler := range a.handlers {
// We've found the handler that matches the request // We've found the handler that matches the request
if recv["request"] == handler.name { if strings.ToLower(recv["request"].(string)) == strings.ToLower(handler.name) {
// Check that we have all the required arguments // Check that we have all the required arguments
for _, arg := range handler.args { for _, arg := range handler.args {
// An argument in [square brackets] is optional and not required, // An argument in [square brackets] is optional and not required,

View File

@ -22,6 +22,8 @@ import "net/http"
import "runtime" import "runtime"
import "os" import "os"
import "yggdrasil/defaults"
// Start the profiler in debug builds, if the required environment variable is set. // Start the profiler in debug builds, if the required environment variable is set.
func init() { func init() {
envVarName := "PPROFLISTEN" envVarName := "PPROFLISTEN"
@ -239,15 +241,15 @@ func (c *Core) DEBUG_getDHTSize() int {
// TUN defaults // TUN defaults
func (c *Core) DEBUG_GetTUNDefaultIfName() string { func (c *Core) DEBUG_GetTUNDefaultIfName() string {
return getDefaults().defaultIfName return defaults.GetDefaults().DefaultIfName
} }
func (c *Core) DEBUG_GetTUNDefaultIfMTU() int { func (c *Core) DEBUG_GetTUNDefaultIfMTU() int {
return getDefaults().defaultIfMTU return defaults.GetDefaults().DefaultIfMTU
} }
func (c *Core) DEBUG_GetTUNDefaultIfTAPMode() bool { func (c *Core) DEBUG_GetTUNDefaultIfTAPMode() bool {
return getDefaults().defaultIfTAPMode return defaults.GetDefaults().DefaultIfTAPMode
} }
// udpInterface // udpInterface

View File

@ -17,6 +17,7 @@ package yggdrasil
import ( import (
"errors" "errors"
"fmt" "fmt"
"io"
"math/rand" "math/rand"
"net" "net"
"sync" "sync"
@ -304,39 +305,49 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
themAddrString := net.IP(themAddr[:]).String() themAddrString := net.IP(themAddr[:]).String()
themString := fmt.Sprintf("%s@%s", themAddrString, them) themString := fmt.Sprintf("%s@%s", themAddrString, them)
iface.core.log.Println("Connected:", themString) iface.core.log.Println("Connected:", themString)
iface.reader(sock, in) // In this goroutine, because of defers err = iface.reader(sock, in) // In this goroutine, because of defers
if err == nil {
iface.core.log.Println("Disconnected:", themString) iface.core.log.Println("Disconnected:", themString)
} else {
iface.core.log.Println("Disconnected:", themString, "with error:", err)
}
return return
} }
// This reads from the socket into a []byte buffer for incomping messages. // This reads from the socket into a []byte buffer for incomping messages.
// It copies completed messages out of the cache into a new slice, and passes them to the peer struct via the provided `in func([]byte)` argument. // It copies completed messages out of the cache into a new slice, and passes them to the peer struct via the provided `in func([]byte)` argument.
// Then it shifts the incomplete fragments of data forward so future reads won't overwrite it. // Then it shifts the incomplete fragments of data forward so future reads won't overwrite it.
func (iface *tcpInterface) reader(sock net.Conn, in func([]byte)) { func (iface *tcpInterface) reader(sock net.Conn, in func([]byte)) error {
bs := make([]byte, 2*tcp_msgSize) bs := make([]byte, 2*tcp_msgSize)
frag := bs[:0] frag := bs[:0]
for { for {
timeout := time.Now().Add(tcp_timeout) timeout := time.Now().Add(tcp_timeout)
sock.SetReadDeadline(timeout) sock.SetReadDeadline(timeout)
n, err := sock.Read(bs[len(frag):]) n, err := sock.Read(bs[len(frag):])
if err != nil || n == 0 { if n > 0 {
break
}
frag = bs[:len(frag)+n] frag = bs[:len(frag)+n]
for { for {
msg, ok, err := tcp_chop_msg(&frag) msg, ok, err2 := tcp_chop_msg(&frag)
if err != nil { if err2 != nil {
return return fmt.Errorf("Message error: %v", err2)
} }
if !ok { if !ok {
// We didn't get the whole message yet
break break
} // We didn't get the whole message yet }
newMsg := append(util_getBytes(), msg...) newMsg := append(util_getBytes(), msg...)
in(newMsg) in(newMsg)
util_yield() util_yield()
} }
frag = append(bs[:0], frag...) frag = append(bs[:0], frag...)
} }
if err != nil || n == 0 {
if err != io.EOF {
return err
}
return nil
}
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -29,6 +29,18 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int)
} }
tun.iface = iface tun.iface = iface
tun.mtu = getSupportedMTU(mtu) tun.mtu = getSupportedMTU(mtu)
// The following check is specific to Linux, as the TAP driver only supports
// an MTU of 65535-14 to make room for the ethernet headers. This makes sure
// that the MTU gets rounded down to 65521 instead of causing a panic.
if iftapmode {
if tun.mtu > 65535-tun_ETHER_HEADER_LENGTH {
tun.mtu = 65535-tun_ETHER_HEADER_LENGTH
}
}
// Friendly output
tun.core.log.Printf("Interface name: %s", tun.iface.Name())
tun.core.log.Printf("Interface IPv6: %s", addr)
tun.core.log.Printf("Interface MTU: %d", tun.mtu)
return tun.setupAddress(addr) return tun.setupAddress(addr)
} }

View File

@ -57,6 +57,10 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int)
if err != nil { if err != nil {
panic(err) panic(err)
} }
// Friendly output
tun.core.log.Printf("Interface name: %s", tun.iface.Name())
tun.core.log.Printf("Interface IPv6: %s", addr)
tun.core.log.Printf("Interface MTU: %d", tun.mtu)
return tun.setupAddress(addr) return tun.setupAddress(addr)
} }

View File

@ -63,7 +63,7 @@ func main() {
if i, err := strconv.Atoi(tokens[1]); err == nil { if i, err := strconv.Atoi(tokens[1]); err == nil {
send[tokens[0]] = i send[tokens[0]] = i
} else { } else {
switch tokens[1] { switch strings.ToLower(tokens[1]) {
case "true": case "true":
send[tokens[0]] = true send[tokens[0]] = true
case "false": case "false":
@ -104,10 +104,10 @@ func main() {
os.Exit(0) os.Exit(0)
} }
switch req["request"] { switch strings.ToLower(req["request"].(string)) {
case "dot": case "dot":
fmt.Println(res["dot"]) fmt.Println(res["dot"])
case "help", "getPeers", "getSwitchPeers", "getDHT", "getSessions": case "help", "getpeers", "getswitchpeers", "getdht", "getsessions":
maxWidths := make(map[string]int) maxWidths := make(map[string]int)
var keyOrder []string var keyOrder []string
keysOrdered := false keysOrdered := false
@ -163,7 +163,7 @@ func main() {
fmt.Println() fmt.Println()
} }
} }
case "getTunTap", "setTunTap": case "gettuntap", "settuntap":
for k, v := range res { for k, v := range res {
fmt.Println("Interface name:", k) fmt.Println("Interface name:", k)
if mtu, ok := v.(map[string]interface{})["mtu"].(float64); ok { if mtu, ok := v.(map[string]interface{})["mtu"].(float64); ok {
@ -173,7 +173,7 @@ func main() {
fmt.Println("TAP mode:", tap_mode) fmt.Println("TAP mode:", tap_mode)
} }
} }
case "getSelf": case "getself":
for k, v := range res["self"].(map[string]interface{}) { for k, v := range res["self"].(map[string]interface{}) {
fmt.Println("IPv6 address:", k) fmt.Println("IPv6 address:", k)
if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok { if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok {
@ -183,7 +183,7 @@ func main() {
fmt.Println("Coords:", coords) fmt.Println("Coords:", coords)
} }
} }
case "addPeer", "removePeer", "addAllowedEncryptionPublicKey", "removeAllowedEncryptionPublicKey": case "addpeer", "removepeer", "addallowedencryptionpublickey", "removeallowedencryptionpublickey":
if _, ok := res["added"]; ok { if _, ok := res["added"]; ok {
for _, v := range res["added"].([]interface{}) { for _, v := range res["added"].([]interface{}) {
fmt.Println("Added:", fmt.Sprint(v)) fmt.Println("Added:", fmt.Sprint(v))
@ -204,7 +204,7 @@ func main() {
fmt.Println("Not removed:", fmt.Sprint(v)) fmt.Println("Not removed:", fmt.Sprint(v))
} }
} }
case "getAllowedEncryptionPublicKeys": case "getallowedencryptionpublickeys":
if _, ok := res["allowed_box_pubs"]; !ok { if _, ok := res["allowed_box_pubs"]; !ok {
fmt.Println("All connections are allowed") fmt.Println("All connections are allowed")
} else if res["allowed_box_pubs"] == nil { } else if res["allowed_box_pubs"] == nil {
@ -215,7 +215,7 @@ func main() {
fmt.Println("-", v) fmt.Println("-", v)
} }
} }
case "getMulticastInterfaces": case "getmulticastinterfaces":
if _, ok := res["multicast_interfaces"]; !ok { if _, ok := res["multicast_interfaces"]; !ok {
fmt.Println("No multicast interfaces found") fmt.Println("No multicast interfaces found")
} else if res["multicast_interfaces"] == nil { } else if res["multicast_interfaces"] == nil {