mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-23 10:05:17 +00:00
Refactor admin socket, export request/response structs, remove types package
This commit is contained in:
parent
dfca87ba80
commit
2d01386d6e
@ -1,7 +1,6 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -9,17 +8,12 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
//"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gologme/log"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||
//"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
||||
//"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/version"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||
)
|
||||
|
||||
@ -34,16 +28,26 @@ type AdminSocket struct {
|
||||
started bool
|
||||
}
|
||||
|
||||
// Info refers to information that is returned to the admin socket handler.
|
||||
type Info map[string]interface{}
|
||||
type AdminSocketResponse struct {
|
||||
Status string `json:"status"`
|
||||
Request struct {
|
||||
Name string `json:"request"`
|
||||
KeepAlive bool `json:"keepalive"`
|
||||
} `json:"request"`
|
||||
Response interface{} `json:"response"`
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
args []string // List of human-readable argument names
|
||||
handler func(Info) (Info, error) // First is input map, second is output
|
||||
args []string // List of human-readable argument names
|
||||
handler func(json.RawMessage) (interface{}, error) // First is input map, second is output
|
||||
}
|
||||
|
||||
type ListResponse struct {
|
||||
List map[string][]string `json:"list"`
|
||||
}
|
||||
|
||||
// AddHandler is called for each admin function to add the handler and help documentation to the API.
|
||||
func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(Info) (Info, error)) error {
|
||||
func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(json.RawMessage) (interface{}, error)) error {
|
||||
if _, ok := a.handlers[strings.ToLower(name)]; ok {
|
||||
return errors.New("handler already exists")
|
||||
}
|
||||
@ -61,70 +65,60 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.
|
||||
a.handlers = make(map[string]handler)
|
||||
current := state.GetCurrent()
|
||||
a.listenaddr = current.AdminListen
|
||||
a.AddHandler("list", []string{}, func(in Info) (Info, error) {
|
||||
handlers := make(map[string]interface{})
|
||||
for handlername, handler := range a.handlers {
|
||||
handlers[handlername] = Info{"fields": handler.args}
|
||||
_ = a.AddHandler("list", []string{}, func(_ json.RawMessage) (interface{}, error) {
|
||||
res := &ListResponse{}
|
||||
for name, handler := range a.handlers {
|
||||
res.List[name] = handler.args
|
||||
}
|
||||
return Info{"list": handlers}, nil
|
||||
return res, nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
|
||||
a.AddHandler("getSelf", []string{}, func(in Info) (Info, error) {
|
||||
ip := a.core.Address().String()
|
||||
subnet := a.core.Subnet()
|
||||
self := a.core.GetSelf()
|
||||
return Info{
|
||||
"self": Info{
|
||||
ip: Info{
|
||||
// TODO"box_pub_key": a.core.EncryptionPublicKey(),
|
||||
"build_name": version.BuildName(),
|
||||
"build_version": version.BuildVersion(),
|
||||
"key": hex.EncodeToString(self.Key[:]),
|
||||
"coords": fmt.Sprintf("%v", self.Coords),
|
||||
"subnet": subnet.String(),
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
a.AddHandler("getPeers", []string{}, func(in Info) (Info, error) {
|
||||
peers := make(Info)
|
||||
for _, p := range a.core.GetPeers() {
|
||||
addr := address.AddrForKey(p.Key)
|
||||
so := net.IP(addr[:]).String()
|
||||
peers[so] = Info{
|
||||
"key": hex.EncodeToString(p.Key[:]),
|
||||
"port": p.Port,
|
||||
"coords": fmt.Sprintf("%v", p.Coords),
|
||||
}
|
||||
_ = a.AddHandler("getSelf", []string{}, func(in json.RawMessage) (interface{}, error) {
|
||||
req := &GetSelfRequest{}
|
||||
res := &GetSelfResponse{}
|
||||
if err := json.Unmarshal(in, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Info{"peers": peers}, nil
|
||||
})
|
||||
a.AddHandler("getDHT", []string{}, func(in Info) (Info, error) {
|
||||
dht := make(Info)
|
||||
for _, d := range a.core.GetDHT() {
|
||||
addr := address.AddrForKey(d.Key)
|
||||
so := net.IP(addr[:]).String()
|
||||
dht[so] = Info{
|
||||
"key": hex.EncodeToString(d.Key[:]),
|
||||
"port": fmt.Sprintf("%v", d.Port),
|
||||
"next": fmt.Sprintf("%v", d.Next),
|
||||
}
|
||||
if err := a.getSelfHandler(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Info{"dht": dht}, nil
|
||||
return res, nil
|
||||
})
|
||||
a.AddHandler("getSessions", []string{}, func(in Info) (Info, error) {
|
||||
sessions := make(Info)
|
||||
for _, s := range a.core.GetSessions() {
|
||||
addr := address.AddrForKey(s.Key)
|
||||
so := net.IP(addr[:]).String()
|
||||
sessions[so] = Info{
|
||||
"key": hex.EncodeToString(s.Key[:]),
|
||||
}
|
||||
_ = a.AddHandler("getPeers", []string{}, func(in json.RawMessage) (interface{}, error) {
|
||||
req := &GetPeersRequest{}
|
||||
res := &GetPeersResponse{}
|
||||
if err := json.Unmarshal(in, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Info{"sessions": sessions}, nil
|
||||
if err := a.getPeersHandler(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
})
|
||||
_ = a.AddHandler("getDHT", []string{}, func(in json.RawMessage) (interface{}, error) {
|
||||
req := &GetDHTRequest{}
|
||||
res := &GetDHTResponse{}
|
||||
if err := json.Unmarshal(in, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := a.getDHTHandler(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
})
|
||||
_ = a.AddHandler("getSessions", []string{}, func(in json.RawMessage) (interface{}, error) {
|
||||
req := &GetSessionsRequest{}
|
||||
res := &GetSessionsResponse{}
|
||||
if err := json.Unmarshal(in, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := a.getSessionsHandler(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
})
|
||||
}
|
||||
|
||||
@ -209,20 +203,20 @@ func (a *AdminSocket) listen() {
|
||||
// handleRequest calls the request handler for each request sent to the admin API.
|
||||
func (a *AdminSocket) handleRequest(conn net.Conn) {
|
||||
decoder := json.NewDecoder(conn)
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
encoder := json.NewEncoder(conn)
|
||||
encoder.SetIndent("", " ")
|
||||
recv := make(Info)
|
||||
send := make(Info)
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r != nil {
|
||||
send = Info{
|
||||
"status": "error",
|
||||
"error": "Check your syntax and input types",
|
||||
}
|
||||
a.log.Debugln("Admin socket error:", r)
|
||||
if err := encoder.Encode(&send); err != nil {
|
||||
if err := encoder.Encode(&ErrorResponse{
|
||||
Error: "Check your syntax and input types",
|
||||
}); err != nil {
|
||||
a.log.Debugln("Admin socket JSON encode error:", err)
|
||||
}
|
||||
conn.Close()
|
||||
@ -230,83 +224,40 @@ func (a *AdminSocket) handleRequest(conn net.Conn) {
|
||||
}()
|
||||
|
||||
for {
|
||||
// Start with a clean slate on each request
|
||||
recv = Info{}
|
||||
send = Info{}
|
||||
|
||||
// Decode the input
|
||||
if err := decoder.Decode(&recv); err != nil {
|
||||
a.log.Debugln("Admin socket JSON decode error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Send the request back with the response, and default to "error"
|
||||
// unless the status is changed below by one of the handlers
|
||||
send["request"] = recv
|
||||
send["status"] = "error"
|
||||
|
||||
n := strings.ToLower(recv["request"].(string))
|
||||
|
||||
if _, ok := recv["request"]; !ok {
|
||||
send["error"] = "No request sent"
|
||||
goto respond
|
||||
}
|
||||
|
||||
if h, ok := a.handlers[n]; ok {
|
||||
// Check that we have all the required arguments
|
||||
for _, arg := range h.args {
|
||||
// An argument in [square brackets] is optional and not required,
|
||||
// so we can safely ignore those
|
||||
if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
|
||||
continue
|
||||
var err error
|
||||
var buf json.RawMessage
|
||||
_ = decoder.Decode(&buf)
|
||||
var resp AdminSocketResponse
|
||||
resp.Status = "success"
|
||||
if err = json.Unmarshal(buf, &resp.Request); err == nil {
|
||||
if resp.Request.Name == "" {
|
||||
resp.Status = "error"
|
||||
resp.Response = &ErrorResponse{
|
||||
Error: "No request specified",
|
||||
}
|
||||
// Check if the field is missing
|
||||
if _, ok := recv[arg]; !ok {
|
||||
send = Info{
|
||||
"status": "error",
|
||||
"error": "Expected field missing: " + arg,
|
||||
"expecting": arg,
|
||||
} else if h, ok := a.handlers[strings.ToLower(resp.Request.Name)]; ok {
|
||||
resp.Response, err = h.handler(buf)
|
||||
if err != nil {
|
||||
resp.Status = "error"
|
||||
resp.Response = &ErrorResponse{
|
||||
Error: err.Error(),
|
||||
}
|
||||
goto respond
|
||||
}
|
||||
}
|
||||
|
||||
// By this point we should have all the fields we need, so call
|
||||
// the handler
|
||||
response, err := h.handler(recv)
|
||||
if err != nil {
|
||||
send["error"] = err.Error()
|
||||
if response != nil {
|
||||
send["response"] = response
|
||||
goto respond
|
||||
}
|
||||
} else {
|
||||
send["status"] = "success"
|
||||
if response != nil {
|
||||
send["response"] = response
|
||||
goto respond
|
||||
resp.Status = "error"
|
||||
resp.Response = &ErrorResponse{
|
||||
Error: fmt.Sprintf("Unknown action '%s', try 'list' for help", resp.Request.Name),
|
||||
}
|
||||
}
|
||||
}
|
||||
j, _ := json.Marshal(resp)
|
||||
if err = encoder.Encode(resp); err != nil {
|
||||
a.log.Debugln("Encode error:", err)
|
||||
}
|
||||
if !resp.Request.KeepAlive {
|
||||
break
|
||||
} else {
|
||||
// Start with a clean response on each request, which defaults to an error
|
||||
// state. If a handler is found below then this will be overwritten
|
||||
send = Info{
|
||||
"request": recv,
|
||||
"status": "error",
|
||||
"error": fmt.Sprintf("Unknown action '%s', try 'list' for help", recv["request"].(string)),
|
||||
}
|
||||
goto respond
|
||||
}
|
||||
|
||||
// Send the response back
|
||||
respond:
|
||||
if err := encoder.Encode(&send); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// If "keepalive" isn't true then close the connection
|
||||
if keepalive, ok := recv["keepalive"]; !ok || !keepalive.(bool) {
|
||||
conn.Close()
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
src/admin/error.go
Normal file
5
src/admin/error.go
Normal file
@ -0,0 +1,5 @@
|
||||
package admin
|
||||
|
||||
type ErrorResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
34
src/admin/getdht.go
Normal file
34
src/admin/getdht.go
Normal file
@ -0,0 +1,34 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
)
|
||||
|
||||
type GetDHTRequest struct{}
|
||||
|
||||
type GetDHTResponse struct {
|
||||
DHT map[string]DHTEntry `json:"dht"`
|
||||
}
|
||||
|
||||
type DHTEntry struct {
|
||||
PublicKey string `json:"key"`
|
||||
Port uint64 `json:"port"`
|
||||
Next uint64 `json:"next"`
|
||||
}
|
||||
|
||||
func (a *AdminSocket) getDHTHandler(req *GetDHTRequest, res *GetDHTResponse) error {
|
||||
res.DHT = map[string]DHTEntry{}
|
||||
for _, d := range a.core.GetDHT() {
|
||||
addr := address.AddrForKey(d.Key)
|
||||
so := net.IP(addr[:]).String()
|
||||
res.DHT[so] = DHTEntry{
|
||||
PublicKey: hex.EncodeToString(d.Key[:]),
|
||||
Port: d.Port,
|
||||
Next: d.Next,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
35
src/admin/getpeers.go
Normal file
35
src/admin/getpeers.go
Normal file
@ -0,0 +1,35 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
)
|
||||
|
||||
type GetPeersRequest struct {
|
||||
}
|
||||
|
||||
type GetPeersResponse struct {
|
||||
Peers map[string]PeerEntry `json:"peers"`
|
||||
}
|
||||
|
||||
type PeerEntry struct {
|
||||
PublicKey string `json:"key"`
|
||||
Port uint64 `json:"port"`
|
||||
Coords []uint64 `json:"coords"`
|
||||
}
|
||||
|
||||
func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersResponse) error {
|
||||
res.Peers = map[string]PeerEntry{}
|
||||
for _, p := range a.core.GetPeers() {
|
||||
addr := address.AddrForKey(p.Key)
|
||||
so := net.IP(addr[:]).String()
|
||||
res.Peers[so] = PeerEntry{
|
||||
PublicKey: hex.EncodeToString(p.Key),
|
||||
Port: p.Port,
|
||||
Coords: p.Coords,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
31
src/admin/getself.go
Normal file
31
src/admin/getself.go
Normal file
@ -0,0 +1,31 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/version"
|
||||
)
|
||||
|
||||
type GetSelfRequest struct{}
|
||||
|
||||
type GetSelfResponse struct {
|
||||
BuildName string `json:"build_name"`
|
||||
BuildVersion string `json:"build_version"`
|
||||
PublicKey string `json:"key"`
|
||||
Coords []uint64 `json:"coords"`
|
||||
IPAddress string `json:"address"`
|
||||
Subnet string `json:"subnet"`
|
||||
}
|
||||
|
||||
func (a *AdminSocket) getSelfHandler(req *GetSelfRequest, res *GetSelfResponse) error {
|
||||
res.BuildName = version.BuildName()
|
||||
res.BuildVersion = version.BuildVersion()
|
||||
public := a.core.PrivateKey().Public().(ed25519.PublicKey)
|
||||
res.PublicKey = hex.EncodeToString(public[:])
|
||||
res.IPAddress = a.core.Address().String()
|
||||
snet := a.core.Subnet()
|
||||
res.Subnet = snet.String()
|
||||
// TODO: res.coords
|
||||
return nil
|
||||
}
|
30
src/admin/getsessions.go
Normal file
30
src/admin/getsessions.go
Normal file
@ -0,0 +1,30 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
)
|
||||
|
||||
type GetSessionsRequest struct{}
|
||||
|
||||
type GetSessionsResponse struct {
|
||||
Sessions map[string]SessionEntry `json:"sessions"`
|
||||
}
|
||||
|
||||
type SessionEntry struct {
|
||||
PublicKey string `json:"key"`
|
||||
}
|
||||
|
||||
func (a *AdminSocket) getSessionsHandler(req *GetSessionsRequest, res *GetSessionsResponse) error {
|
||||
res.Sessions = map[string]SessionEntry{}
|
||||
for _, s := range a.core.GetSessions() {
|
||||
addr := address.AddrForKey(s.Key)
|
||||
so := net.IP(addr[:]).String()
|
||||
res.Sessions[so] = SessionEntry{
|
||||
PublicKey: hex.EncodeToString(s.Key[:]),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -22,11 +22,8 @@ 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.
|
||||
@ -72,7 +69,7 @@ type NodeConfig struct {
|
||||
PrivateKey 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 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."`
|
||||
IfMTU uint16 `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."`
|
||||
NodeInfoPrivacy bool `comment:"By default, nodeinfo contains some defaults including the platform,\narchitecture and Yggdrasil version. These can help when surveying\nthe network and diagnosing network routing problems. Enabling\nnodeinfo privacy prevents this, so that only items specified in\n\"NodeInfo\" are sent back if specified."`
|
||||
NodeInfo map[string]interface{} `comment:"Optional node info. This must be a { \"key\": \"value\", ... } map\nor set as null. This is entirely optional but, if set, is visible\nto the whole network on request."`
|
||||
|
@ -1,7 +1,5 @@
|
||||
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.
|
||||
@ -16,7 +14,7 @@ type platformDefaultParameters struct {
|
||||
DefaultMulticastInterfaces []string
|
||||
|
||||
// TUN/TAP
|
||||
MaximumIfMTU types.MTU
|
||||
DefaultIfMTU types.MTU
|
||||
MaximumIfMTU uint16
|
||||
DefaultIfMTU uint16
|
||||
DefaultIfName string
|
||||
}
|
||||
|
@ -1,13 +1,34 @@
|
||||
package multicast
|
||||
|
||||
import "github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||
)
|
||||
|
||||
type GetMulticastInterfacesRequest struct{}
|
||||
type GetMulticastInterfacesResponse struct {
|
||||
Interfaces []string `json:"multicast_interfaces"`
|
||||
}
|
||||
|
||||
func (m *Multicast) getMulticastInterfacesHandler(req *GetMulticastInterfacesRequest, res *GetMulticastInterfacesResponse) error {
|
||||
res.Interfaces = []string{}
|
||||
for _, v := range m.Interfaces() {
|
||||
res.Interfaces = append(res.Interfaces, v.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Multicast) SetupAdminHandlers(a *admin.AdminSocket) {
|
||||
a.AddHandler("getMulticastInterfaces", []string{}, func(in admin.Info) (admin.Info, error) {
|
||||
var intfs []string
|
||||
for _, v := range m.Interfaces() {
|
||||
intfs = append(intfs, v.Name)
|
||||
_ = a.AddHandler("getMulticastInterfaces", []string{}, func(in json.RawMessage) (interface{}, error) {
|
||||
req := &GetMulticastInterfacesRequest{}
|
||||
res := &GetMulticastInterfacesResponse{}
|
||||
if err := json.Unmarshal(in, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return admin.Info{"multicast_interfaces": intfs}, nil
|
||||
if err := m.getMulticastInterfacesHandler(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
})
|
||||
}
|
||||
|
@ -1,57 +1,31 @@
|
||||
package tuntap
|
||||
|
||||
import (
|
||||
//"encoding/hex"
|
||||
//"errors"
|
||||
//"fmt"
|
||||
//"net"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||
)
|
||||
|
||||
func (t *TunAdapter) SetupAdminHandlers(a *admin.AdminSocket) {
|
||||
a.AddHandler("getTunTap", []string{}, func(in admin.Info) (r admin.Info, e error) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
r = admin.Info{"none": admin.Info{}}
|
||||
e = nil
|
||||
}
|
||||
}()
|
||||
type GetTUNRequest struct{}
|
||||
type GetTUNResponse map[string]uint16
|
||||
|
||||
return admin.Info{
|
||||
t.Name(): admin.Info{
|
||||
"mtu": t.mtu,
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
/*
|
||||
// TODO: rewrite this as I'm fairly sure it doesn't work right on many
|
||||
// platforms anyway, but it may require changes to Water
|
||||
a.AddHandler("setTunTap", []string{"name", "[tap_mode]", "[mtu]"}, func(in Info) (Info, error) {
|
||||
// Set sane defaults
|
||||
iftapmode := defaults.GetDefaults().DefaultIfTAPMode
|
||||
ifmtu := defaults.GetDefaults().DefaultIfMTU
|
||||
// Has TAP mode been specified?
|
||||
if tap, ok := in["tap_mode"]; ok {
|
||||
iftapmode = tap.(bool)
|
||||
}
|
||||
// Check we have enough params for MTU
|
||||
if mtu, ok := in["mtu"]; ok {
|
||||
if mtu.(float64) >= 1280 && ifmtu <= defaults.GetDefaults().MaximumIfMTU {
|
||||
ifmtu = int(in["mtu"].(float64))
|
||||
}
|
||||
}
|
||||
// Start the TUN adapter
|
||||
if err := a.startTunWithMTU(in["name"].(string), iftapmode, ifmtu); err != nil {
|
||||
return Info{}, errors.New("Failed to configure adapter")
|
||||
} else {
|
||||
return Info{
|
||||
a.core.router.tun.iface.Name(): Info{
|
||||
"tap_mode": a.core.router.tun.iface.IsTAP(),
|
||||
"mtu": ifmtu,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
})
|
||||
*/
|
||||
func (t *TunAdapter) getTUNHandler(req *GetTUNRequest, res *GetTUNResponse) error {
|
||||
res = &GetTUNResponse{
|
||||
t.Name(): t.MTU(),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TunAdapter) SetupAdminHandlers(a *admin.AdminSocket) {
|
||||
_ = a.AddHandler("getTunTap", []string{}, func(in json.RawMessage) (interface{}, error) {
|
||||
req := &GetTUNRequest{}
|
||||
res := &GetTUNResponse{}
|
||||
if err := json.Unmarshal(in, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := t.getTUNHandler(req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
})
|
||||
}
|
||||
|
@ -23,11 +23,10 @@ import (
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/types"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||
)
|
||||
|
||||
type MTU = types.MTU
|
||||
type MTU uint16
|
||||
|
||||
// TunAdapter represents a running TUN interface and extends the
|
||||
// yggdrasil.Adapter type. In order to use the TUN adapter with Yggdrasil, you
|
||||
@ -40,7 +39,7 @@ type TunAdapter struct {
|
||||
log *log.Logger
|
||||
addr address.Address
|
||||
subnet address.Subnet
|
||||
mtu MTU
|
||||
mtu uint16
|
||||
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
|
||||
@ -56,7 +55,7 @@ func (tun *TunAdapter) SetSessionGatekeeper(gatekeeper func(pubkey ed25519.Publi
|
||||
|
||||
// Gets the maximum supported MTU for the platform based on the defaults in
|
||||
// defaults.GetDefaults().
|
||||
func getSupportedMTU(mtu MTU) MTU {
|
||||
func getSupportedMTU(mtu uint16) uint16 {
|
||||
if mtu < 1280 {
|
||||
return 1280
|
||||
}
|
||||
@ -78,7 +77,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() MTU {
|
||||
func (tun *TunAdapter) MTU() uint16 {
|
||||
return getSupportedMTU(tun.mtu)
|
||||
}
|
||||
|
||||
@ -89,14 +88,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() MTU {
|
||||
func DefaultMTU() uint16 {
|
||||
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() MTU {
|
||||
func MaximumMTU() uint16 {
|
||||
return defaults.GetDefaults().MaximumIfMTU
|
||||
}
|
||||
|
||||
@ -151,7 +150,7 @@ func (tun *TunAdapter) _start() error {
|
||||
}
|
||||
mtu := current.IfMTU
|
||||
if tun.core.MTU() < uint64(mtu) {
|
||||
mtu = MTU(tun.core.MTU())
|
||||
mtu = uint16(tun.core.MTU())
|
||||
}
|
||||
if err := tun.setup(current.IfName, addr, mtu); err != nil {
|
||||
return err
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
// Configures the "utun" adapter with the correct IPv6 address and MTU.
|
||||
func (tun *TunAdapter) setup(ifname string, addr string, mtu MTU) error {
|
||||
func (tun *TunAdapter) setup(ifname string, addr string, mtu uint16) error {
|
||||
if ifname == "auto" {
|
||||
ifname = "utun"
|
||||
}
|
||||
@ -25,8 +25,8 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu MTU) error {
|
||||
panic(err)
|
||||
}
|
||||
tun.iface = iface
|
||||
if mtu, err := iface.MTU(); err == nil {
|
||||
tun.mtu = getSupportedMTU(MTU(mtu))
|
||||
if m, err := iface.MTU(); err == nil {
|
||||
tun.mtu = getSupportedMTU(uint16(m))
|
||||
} else {
|
||||
tun.mtu = 0
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
package types
|
||||
|
||||
type MTU uint16
|
Loading…
Reference in New Issue
Block a user