mobile_nebula/nebula/control.go

136 lines
2.8 KiB
Go
Raw Normal View History

2020-07-27 20:43:58 +00:00
package mobileNebula
import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"net"
"os"
2021-04-23 21:23:06 +00:00
"runtime"
2020-07-27 20:43:58 +00:00
"runtime/debug"
"github.com/sirupsen/logrus"
"github.com/slackhq/nebula"
)
type Nebula struct {
c *nebula.Control
l *logrus.Logger
}
2021-04-23 21:23:06 +00:00
func init() {
// Reduces memory utilization according to https://twitter.com/felixge/status/1355846360562589696?s=20
runtime.MemProfileRate = 0
}
2020-07-27 20:43:58 +00:00
func NewNebula(configData string, key string, logFile string, tunFd int) (*Nebula, error) {
// GC more often, largely for iOS due to extension 15mb limit
debug.SetGCPercent(20)
yamlConfig, err := RenderConfig(configData, key)
if err != nil {
return nil, err
}
l := logrus.New()
f, err := os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return nil, err
}
l.SetOutput(f)
2021-04-23 21:23:06 +00:00
config := nebula.NewConfig(l)
err = config.LoadString(yamlConfig)
if err != nil {
return nil, fmt.Errorf("failed to load config: %s", err)
}
2020-07-27 20:43:58 +00:00
//TODO: inject our version
c, err := nebula.Main(config, false, "", l, &tunFd)
if err != nil {
switch v := err.(type) {
case nebula.ContextualError:
v.Log(l)
return nil, v.Unwrap()
2020-07-27 20:43:58 +00:00
default:
l.WithError(err).Error("Failed to start")
2020-07-27 20:43:58 +00:00
return nil, err
}
}
return &Nebula{c, l}, nil
}
2021-04-23 21:23:06 +00:00
func (n *Nebula) Log(v string) {
n.l.Println(v)
}
2020-07-27 20:43:58 +00:00
func (n *Nebula) Start() {
n.c.Start()
}
func (n *Nebula) ShutdownBlock() {
n.c.ShutdownBlock()
}
func (n *Nebula) Stop() {
n.c.Stop()
}
2021-04-23 21:23:06 +00:00
func (n *Nebula) Rebind(reason string) {
n.l.Infof("Rebinding UDP listener and updating lighthouses due to %s", reason)
2020-07-27 20:43:58 +00:00
n.c.RebindUDPServer()
}
func (n *Nebula) ListHostmap(pending bool) (string, error) {
hosts := n.c.ListHostmap(pending)
b, err := json.Marshal(hosts)
if err != nil {
return "", err
}
return string(b), nil
}
func (n *Nebula) GetHostInfoByVpnIp(vpnIp string, pending bool) (string, error) {
b, err := json.Marshal(n.c.GetHostInfoByVpnIP(stringIpToInt(vpnIp), pending))
2020-07-27 20:43:58 +00:00
if err != nil {
return "", err
}
return string(b), nil
}
func (n *Nebula) CloseTunnel(vpnIp string) bool {
return n.c.CloseTunnel(stringIpToInt(vpnIp), false)
}
func (n *Nebula) SetRemoteForTunnel(vpnIp string, addr string) (string, error) {
udpAddr := nebula.NewUDPAddrFromString(addr)
if udpAddr == nil {
return "", errors.New("could not parse udp address")
}
b, err := json.Marshal(n.c.SetRemoteForTunnel(stringIpToInt(vpnIp), *udpAddr))
if err != nil {
return "", err
}
return string(b), nil
}
2021-04-23 21:23:06 +00:00
func (n *Nebula) Sleep() {
if closed := n.c.CloseAllTunnels(true); closed > 0 {
n.l.WithField("tunnels", closed).Info("Sleep called, closed non lighthouse tunnels")
}
}
2020-07-27 20:43:58 +00:00
func stringIpToInt(ip string) uint32 {
n := net.ParseIP(ip)
if len(n) == 16 {
return binary.BigEndian.Uint32(n[12:16])
}
return binary.BigEndian.Uint32(n)
}