mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 21:10:29 +00:00
commit
dc0c3f9f8b
10
CHANGELOG.md
10
CHANGELOG.md
@ -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`
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -17,6 +17,7 @@ package yggdrasil
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
@ -304,38 +305,48 @@ 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
|
||||||
iface.core.log.Println("Disconnected:", themString)
|
if err == nil {
|
||||||
|
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]
|
||||||
}
|
for {
|
||||||
frag = bs[:len(frag)+n]
|
msg, ok, err2 := tcp_chop_msg(&frag)
|
||||||
for {
|
if err2 != nil {
|
||||||
msg, ok, err := tcp_chop_msg(&frag)
|
return fmt.Errorf("Message error: %v", err2)
|
||||||
if err != nil {
|
}
|
||||||
return
|
if !ok {
|
||||||
|
// We didn't get the whole message yet
|
||||||
|
break
|
||||||
|
}
|
||||||
|
newMsg := append(util_getBytes(), msg...)
|
||||||
|
in(newMsg)
|
||||||
|
util_yield()
|
||||||
}
|
}
|
||||||
if !ok {
|
frag = append(bs[:0], frag...)
|
||||||
break
|
}
|
||||||
} // We didn't get the whole message yet
|
if err != nil || n == 0 {
|
||||||
newMsg := append(util_getBytes(), msg...)
|
if err != io.EOF {
|
||||||
in(newMsg)
|
return err
|
||||||
util_yield()
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
frag = append(bs[:0], frag...)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user