EtherGuard-VPN/main_super.go

613 lines
19 KiB
Go
Raw Normal View History

2021-08-16 20:58:15 +02:00
/* SPDX-License-Identifier: MIT
*
2021-12-04 15:46:36 +01:00
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
2021-08-16 20:58:15 +02:00
*/
package main
2021-08-20 19:32:50 +02:00
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"net"
"os"
2021-11-06 10:47:06 +01:00
"os/exec"
2021-08-20 19:32:50 +02:00
"os/signal"
"strconv"
"syscall"
2021-08-21 16:54:24 +02:00
"time"
2021-08-16 20:58:15 +02:00
2021-11-06 10:47:06 +01:00
"github.com/google/shlex"
2021-12-02 18:13:48 +01:00
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/device"
2021-12-07 21:39:19 +01:00
"github.com/KusakabeSi/EtherGuard-VPN/gencfg"
2021-12-02 18:13:48 +01:00
"github.com/KusakabeSi/EtherGuard-VPN/ipc"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
"github.com/KusakabeSi/EtherGuard-VPN/tap"
2021-08-20 19:32:50 +02:00
yaml "gopkg.in/yaml.v2"
)
2021-12-02 18:13:48 +01:00
func checkNhTable(NhTable mtypes.NextHopTable, peers []mtypes.SuperPeerInfo) error {
allpeer := make(map[mtypes.Vertex]bool, len(peers))
for _, peer1 := range peers {
allpeer[peer1.NodeID] = true
}
for _, peer1 := range peers {
for _, peer2 := range peers {
if peer1.NodeID == peer2.NodeID {
continue
}
id1 := peer1.NodeID
id2 := peer2.NodeID
if dst, has := NhTable[id1]; has {
if next, has2 := dst[id2]; has2 {
2021-12-09 08:46:15 +01:00
if _, hasa := allpeer[next]; hasa {
} else {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("NextHopTable[%v][%v]=%v which is not in the peer list", id1, id2, next)
}
} else {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("NextHopTable[%v][%v] not found", id1, id2)
}
} else {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("NextHopTable[%v] not found", id1)
}
}
}
return nil
}
2021-08-20 19:32:50 +02:00
func printExampleSuperConf() {
2021-12-13 05:20:58 +01:00
sconfig, _ := gencfg.GetExampleSuperConf("", true)
2021-12-05 22:36:50 +01:00
scprint, _ := yaml.Marshal(sconfig)
fmt.Print(string(scprint))
}
func Super(configPath string, useUAPI bool, printExample bool, bindmode string) (err error) {
2021-08-20 19:32:50 +02:00
if printExample {
printExampleSuperConf()
return nil
}
2021-12-02 18:13:48 +01:00
var sconfig mtypes.SuperConfig
2021-09-21 22:03:11 +02:00
2021-12-07 21:39:19 +01:00
err = mtypes.ReadYaml(configPath, &sconfig)
2021-08-20 19:32:50 +02:00
if err != nil {
2021-09-21 22:03:11 +02:00
fmt.Printf("Error read config: %v\t%v\n", configPath, err)
return err
}
2021-12-02 18:13:48 +01:00
httpobj.http_sconfig = &sconfig
2021-12-13 05:20:58 +01:00
http_econfig_tmp, _ := gencfg.GetExampleEdgeConf(sconfig.EdgeTemplate, true)
2021-12-05 22:36:50 +01:00
httpobj.http_econfig_tmp = &http_econfig_tmp
2021-08-25 13:54:13 +02:00
NodeName := sconfig.NodeName
if len(NodeName) > 32 {
return errors.New("Node name can't longer than 32 :" + NodeName)
}
2021-12-04 03:32:59 +01:00
if sconfig.PeerAliveTimeout <= 0 {
return fmt.Errorf("PeerAliveTimeout must > 0 : %v", sconfig.PeerAliveTimeout)
}
2021-12-04 04:51:50 +01:00
if sconfig.HttpPostInterval < 0 {
return fmt.Errorf("HttpPostInterval must >= 0 : %v", sconfig.HttpPostInterval)
2021-12-04 03:32:59 +01:00
} else if sconfig.HttpPostInterval > sconfig.PeerAliveTimeout {
return fmt.Errorf("HttpPostInterval must <= PeerAliveTimeout : %v", sconfig.HttpPostInterval)
}
if sconfig.SendPingInterval <= 0 {
return fmt.Errorf("SendPingInterval must > 0 : %v", sconfig.SendPingInterval)
}
if sconfig.RePushConfigInterval <= 0 {
return fmt.Errorf("RePushConfigInterval must > 0 : %v", sconfig.RePushConfigInterval)
}
2021-08-20 19:32:50 +02:00
var logLevel int
switch sconfig.LogLevel.LogLevel {
case "verbose", "debug":
logLevel = device.LogLevelVerbose
case "error":
logLevel = device.LogLevelError
case "silent":
logLevel = device.LogLevelSilent
2021-08-26 11:06:40 +02:00
default:
logLevel = device.LogLevelError
2021-08-20 19:32:50 +02:00
}
logger4 := device.NewLogger(
logLevel,
2021-08-25 13:54:13 +02:00
fmt.Sprintf("(%s) ", NodeName+"_v4"),
2021-08-20 19:32:50 +02:00
)
logger6 := device.NewLogger(
logLevel,
2021-08-25 13:54:13 +02:00
fmt.Sprintf("(%s) ", NodeName+"_v6"),
2021-08-20 19:32:50 +02:00
)
2024-01-12 10:31:16 +01:00
EnabledAf := sconfig.DisableAf.Disalbed2Enabled()
if !EnabledAf.IPv4 {
sconfig.PrivKeyV4 = ""
}
if !EnabledAf.IPv6 {
sconfig.PrivKeyV6 = ""
}
2021-12-02 18:13:48 +01:00
httpobj.http_sconfig_path = configPath
httpobj.http_PeerState = make(map[string]*PeerState)
httpobj.http_PeerIPs = make(map[string]*HttpPeerLocalIP)
httpobj.http_PeerID2Info = make(map[mtypes.Vertex]mtypes.SuperPeerInfo)
httpobj.http_HashSalt = []byte(mtypes.RandomStr(32, fmt.Sprintf("%v", time.Now())))
httpobj.http_passwords = sconfig.Passwords
2021-08-21 16:54:24 +02:00
2021-12-02 18:13:48 +01:00
httpobj.http_super_chains = &mtypes.SUPER_Events{
Event_server_pong: make(chan mtypes.PongMsg, 1<<5),
Event_server_register: make(chan mtypes.RegisterMsg, 1<<5),
2021-08-20 19:32:50 +02:00
}
2021-12-13 05:20:58 +01:00
httpobj.http_graph, err = path.NewGraph(3, true, sconfig.GraphRecalculateSetting, mtypes.NTPInfo{}, mtypes.LoggerInfo{})
2021-12-09 08:46:15 +01:00
if err != nil {
return err
}
2021-12-04 03:32:59 +01:00
httpobj.http_graph.SetNHTable(httpobj.http_sconfig.NextHopTable)
if sconfig.GraphRecalculateSetting.StaticMode {
2021-12-02 18:13:48 +01:00
err = checkNhTable(httpobj.http_sconfig.NextHopTable, sconfig.Peers)
if err != nil {
return err
}
}
thetap4, _ := tap.CreateDummyTAP()
2024-01-12 10:31:16 +01:00
httpobj.http_device4 = device.NewDevice(thetap4, mtypes.NodeID_SuperNode, conn.NewDefaultBind(EnabledAf.GetOnly4(), bindmode, sconfig.FwMark), logger4, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version)
2021-12-02 18:13:48 +01:00
defer httpobj.http_device4.Close()
2021-09-21 03:15:23 +02:00
thetap6, _ := tap.CreateDummyTAP()
2024-01-12 10:31:16 +01:00
httpobj.http_device6 = device.NewDevice(thetap6, mtypes.NodeID_SuperNode, conn.NewDefaultBind(EnabledAf.GetOnly6(), bindmode, sconfig.FwMark), logger6, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version)
2021-12-02 18:13:48 +01:00
defer httpobj.http_device6.Close()
2021-09-21 03:15:23 +02:00
if sconfig.PrivKeyV4 != "" {
pk4, err := device.Str2PriKey(sconfig.PrivKeyV4)
if err != nil {
fmt.Println("Error decode base64 ", err)
return err
}
2021-12-02 18:13:48 +01:00
httpobj.http_device4.SetPrivateKey(pk4)
2024-01-12 05:02:39 +01:00
httpobj.http_device4.IpcSet("fwmark=" + fmt.Sprint(sconfig.FwMark) + "\n")
2021-12-02 18:13:48 +01:00
httpobj.http_device4.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
httpobj.http_device4.IpcSet("replace_peers=true\n")
2021-08-24 10:43:55 +02:00
}
2021-09-21 03:15:23 +02:00
if sconfig.PrivKeyV6 != "" {
pk6, err := device.Str2PriKey(sconfig.PrivKeyV6)
if err != nil {
fmt.Println("Error decode base64 ", err)
return err
}
2021-12-02 18:13:48 +01:00
httpobj.http_device6.SetPrivateKey(pk6)
2024-01-12 05:02:39 +01:00
httpobj.http_device6.IpcSet("fwmark=" + fmt.Sprint(sconfig.FwMark) + "\n")
2021-12-02 18:13:48 +01:00
httpobj.http_device6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
httpobj.http_device6.IpcSet("replace_peers=true\n")
2021-08-24 10:43:55 +02:00
}
2021-08-20 19:32:50 +02:00
for _, peerconf := range sconfig.Peers {
err := super_peeradd(peerconf)
if err != nil {
return err
}
2021-08-20 19:32:50 +02:00
}
2021-09-21 03:15:23 +02:00
logger4.Verbosef("Device4 started")
logger6.Verbosef("Device6 started")
2021-08-20 19:32:50 +02:00
errs := make(chan error, 1<<3)
term := make(chan os.Signal, 1)
if useUAPI {
2021-12-02 18:13:48 +01:00
uapi4, err := startUAPI(NodeName+"_v4", logger4, httpobj.http_device4, errs)
2021-08-20 19:32:50 +02:00
if err != nil {
return err
}
defer uapi4.Close()
2021-12-02 18:13:48 +01:00
uapi6, err := startUAPI(NodeName+"_v6", logger6, httpobj.http_device6, errs)
2021-08-20 19:32:50 +02:00
if err != nil {
return err
}
defer uapi6.Close()
}
2021-12-04 15:46:36 +01:00
2021-12-02 18:13:48 +01:00
go Event_server_event_hendler(httpobj.http_graph, httpobj.http_super_chains)
2021-12-03 23:46:58 +01:00
go RoutinePushSettings(mtypes.S2TD(sconfig.RePushConfigInterval))
2021-10-27 03:02:44 +02:00
go RoutineTimeoutCheck()
2021-12-10 19:30:45 +01:00
HttpServer(sconfig.ListenPort_EdgeAPI, sconfig.ListenPort_ManageAPI, sconfig.API_Prefix, errs)
2021-08-21 16:54:24 +02:00
2021-11-06 10:47:06 +01:00
if sconfig.PostScript != "" {
2021-12-04 15:46:36 +01:00
envs := make(map[string]string)
envs["EG_MODE"] = "super"
envs["EG_NODE_NAME"] = sconfig.NodeName
2021-11-06 10:47:06 +01:00
cmdarg, err := shlex.Split(sconfig.PostScript)
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("error parse PostScript %v", err)
2021-11-06 10:47:06 +01:00
}
if sconfig.LogLevel.LogInternal {
fmt.Printf("PostScript: exec.Command(%v)\n", cmdarg)
2021-11-06 10:47:06 +01:00
}
cmd := exec.Command(cmdarg[0], cmdarg[1:]...)
out, err := cmd.CombinedOutput()
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("exec.Command(%v) failed with %v", cmdarg, err)
2021-11-06 10:47:06 +01:00
}
if sconfig.LogLevel.LogInternal {
fmt.Printf("PostScript output: %s\n", string(out))
}
}
2021-12-10 19:21:35 +01:00
2022-01-24 15:02:41 +01:00
httpobj.http_device4.Chan_Device_Initialized <- struct{}{}
httpobj.http_device6.Chan_Device_Initialized <- struct{}{}
2021-12-10 19:21:35 +01:00
SdNotify, err := mtypes.SdNotify(false, mtypes.SdNotifyReady)
if sconfig.LogLevel.LogInternal {
fmt.Printf("Internal: SdNotify:%v err:%v\n", SdNotify, err)
2021-12-10 19:21:35 +01:00
}
2021-11-06 10:47:06 +01:00
signal.Notify(term, syscall.SIGTERM)
signal.Notify(term, os.Interrupt)
2021-08-20 19:32:50 +02:00
select {
case <-term:
case <-errs:
2021-12-02 18:13:48 +01:00
case <-httpobj.http_device4.Wait():
case <-httpobj.http_device6.Wait():
2021-08-20 19:32:50 +02:00
}
logger4.Verbosef("Shutting down")
return
}
2021-12-02 18:13:48 +01:00
func super_peeradd(peerconf mtypes.SuperPeerInfo) error {
// No lock, lock before call me
2021-09-21 22:03:11 +02:00
pk, err := device.Str2PubKey(peerconf.PubKey)
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("error decode base64 :%v", err)
}
2021-12-02 18:13:48 +01:00
if httpobj.http_sconfig.PrivKeyV4 != "" {
var psk device.NoisePresharedKey
if peerconf.PSKey != "" {
psk, err = device.Str2PSKey(peerconf.PSKey)
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("error decode base64 :%v", err)
}
}
2021-12-09 08:46:15 +01:00
peer4, err := httpobj.http_device4.NewPeer(pk, peerconf.NodeID, false, 0)
2021-09-21 22:03:11 +02:00
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("error create peer id :%v", err)
2021-09-21 22:03:11 +02:00
}
peer4.StaticConn = false
2021-09-21 22:03:11 +02:00
if peerconf.PSKey != "" {
peer4.SetPSK(psk)
}
2021-12-15 11:34:49 +01:00
if peerconf.EndPoint != "" {
2022-01-08 23:32:04 +01:00
err = peer4.SetEndpointFromConnURL(peerconf.EndPoint, conn.EnabledAf4, 0, true)
2021-12-15 11:34:49 +01:00
if err != nil {
if httpobj.http_sconfig.LogLevel.LogInternal {
fmt.Printf("Internal: Set endpoint failed:%v\n", err)
}
}
}
2021-09-21 22:03:11 +02:00
}
2021-12-02 18:13:48 +01:00
if httpobj.http_sconfig.PrivKeyV6 != "" {
var psk device.NoisePresharedKey
if peerconf.PSKey != "" {
psk, err = device.Str2PSKey(peerconf.PSKey)
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("error decode base64 :%v", err)
}
}
2021-12-09 08:46:15 +01:00
peer6, err := httpobj.http_device6.NewPeer(pk, peerconf.NodeID, false, 0)
2021-09-21 22:03:11 +02:00
if err != nil {
2021-12-09 08:46:15 +01:00
return fmt.Errorf("error create peer id :%v", err)
2021-09-21 22:03:11 +02:00
}
peer6.StaticConn = false
2021-09-21 22:03:11 +02:00
if peerconf.PSKey != "" {
peer6.SetPSK(psk)
}
2021-12-15 11:34:49 +01:00
if peerconf.EndPoint != "" {
2022-01-08 23:32:04 +01:00
err = peer6.SetEndpointFromConnURL(peerconf.EndPoint, conn.EnabledAf6, 0, true)
2021-12-15 11:34:49 +01:00
if err != nil {
if httpobj.http_sconfig.LogLevel.LogInternal {
fmt.Printf("Internal: Set endpoint failed:%v\n", err)
}
}
}
2021-09-21 22:03:11 +02:00
}
2021-12-02 18:13:48 +01:00
httpobj.http_PeerID2Info[peerconf.NodeID] = peerconf
2021-12-04 04:51:50 +01:00
2021-12-04 15:46:36 +01:00
SuperParams := mtypes.API_SuperParams{
SendPingInterval: httpobj.http_sconfig.SendPingInterval,
HttpPostInterval: httpobj.http_sconfig.HttpPostInterval,
PeerAliveTimeout: httpobj.http_sconfig.PeerAliveTimeout,
AdditionalCost: peerconf.AdditionalCost,
}
SuperParamStr, _ := json.Marshal(SuperParams)
md5_hash_raw := md5.Sum(append(SuperParamStr, httpobj.http_HashSalt...))
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
2021-12-04 04:51:50 +01:00
PS := PeerState{}
PS.NhTableState.Store("") // string
PS.PeerInfoState.Store("") // string
2021-12-04 15:46:36 +01:00
PS.SuperParamState.Store(new_hash_str) // string
PS.SuperParamStateClient.Store("") // string
2021-12-04 04:51:50 +01:00
PS.JETSecret.Store(mtypes.JWTSecret{}) // mtypes.JWTSecret
PS.httpPostCount.Store(uint64(0)) // uint64
PS.LastSeen.Store(time.Time{}) // time.Time
httpobj.http_PeerState[peerconf.PubKey] = &PS
2021-12-02 18:13:48 +01:00
httpobj.http_PeerIPs[peerconf.PubKey] = &HttpPeerLocalIP{}
2021-09-21 22:03:11 +02:00
return nil
}
2021-12-02 18:13:48 +01:00
func super_peerdel(toDelete mtypes.Vertex) {
// No lock, lock before call me
if _, has := httpobj.http_PeerID2Info[toDelete]; !has {
return
}
PubKey := httpobj.http_PeerID2Info[toDelete].PubKey
2021-12-09 08:46:15 +01:00
httpobj.http_pskdb.DelNode(toDelete)
2021-12-02 18:13:48 +01:00
delete(httpobj.http_PeerState, PubKey)
delete(httpobj.http_PeerIPs, PubKey)
delete(httpobj.http_PeerID2Info, toDelete)
go super_peerdel_notify(toDelete, PubKey)
}
func super_peerdel_notify(toDelete mtypes.Vertex, PubKey string) {
2021-12-04 03:32:59 +01:00
ServerUpdateMsg := mtypes.ServerUpdateMsg{
Node_id: toDelete,
Action: mtypes.Shutdown,
Code: int(syscall.ENOENT),
Params: "You've been removed from supernode.",
}
for i := 0; i < 10; i++ {
2021-12-04 03:32:59 +01:00
body, _ := mtypes.GetByte(&ServerUpdateMsg)
buf := make([]byte, path.EgHeaderLen+len(body))
2021-12-11 20:33:01 +01:00
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen], device.DefaultMTU)
2021-12-09 08:46:15 +01:00
header.SetSrc(mtypes.NodeID_SuperNode)
copy(buf[path.EgHeaderLen:], body)
header.SetDst(toDelete)
2021-12-02 18:13:48 +01:00
peer4 := httpobj.http_device4.LookupPeerByStr(PubKey)
httpobj.http_device4.SendPacket(peer4, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
2021-12-02 18:13:48 +01:00
peer6 := httpobj.http_device6.LookupPeerByStr(PubKey)
httpobj.http_device6.SendPacket(peer6, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
2021-12-03 23:46:58 +01:00
time.Sleep(mtypes.S2TD(0.1))
}
2021-12-02 18:13:48 +01:00
httpobj.http_device4.RemovePeerByID(toDelete)
httpobj.http_device6.RemovePeerByID(toDelete)
httpobj.http_graph.RemoveVirt(toDelete, true, false)
2021-09-21 22:03:11 +02:00
}
2021-12-02 18:13:48 +01:00
func Event_server_event_hendler(graph *path.IG, events *mtypes.SUPER_Events) {
2021-08-20 19:32:50 +02:00
for {
2021-08-21 16:54:24 +02:00
select {
case reg_msg := <-events.Event_server_register:
var should_push_peer bool
var should_push_nh bool
2021-12-05 22:36:50 +01:00
var should_push_superparams bool
2021-12-02 18:13:48 +01:00
NodeID := reg_msg.Node_id
httpobj.RLock()
PubKey := httpobj.http_PeerID2Info[NodeID].PubKey
2021-12-09 08:46:15 +01:00
if reg_msg.Node_id < mtypes.NodeID_Special {
2021-12-04 04:51:50 +01:00
httpobj.http_PeerState[PubKey].LastSeen.Store(time.Now())
httpobj.http_PeerState[PubKey].JETSecret.Store(reg_msg.JWTSecret)
httpobj.http_PeerState[PubKey].httpPostCount.Store(reg_msg.HttpPostCount)
2021-12-09 08:46:15 +01:00
if httpobj.http_PeerState[PubKey].NhTableState.Load().(string) != reg_msg.NhStateHash {
2021-12-04 04:51:50 +01:00
httpobj.http_PeerState[PubKey].NhTableState.Store(reg_msg.NhStateHash)
should_push_nh = true
}
2021-12-09 08:46:15 +01:00
if httpobj.http_PeerState[PubKey].PeerInfoState.Load().(string) != reg_msg.PeerStateHash {
2021-12-04 04:51:50 +01:00
httpobj.http_PeerState[PubKey].PeerInfoState.Store(reg_msg.PeerStateHash)
should_push_peer = true
}
2021-12-09 08:46:15 +01:00
if httpobj.http_PeerState[PubKey].SuperParamStateClient.Load().(string) != reg_msg.SuperParamStateHash {
2021-12-05 22:36:50 +01:00
httpobj.http_PeerState[PubKey].SuperParamStateClient.Store(reg_msg.SuperParamStateHash)
should_push_superparams = true
}
2021-08-21 16:54:24 +02:00
}
var peer_state_changed bool
2021-12-02 18:13:48 +01:00
httpobj.http_PeerInfo, httpobj.http_PeerInfo_hash, peer_state_changed = get_api_peers(httpobj.http_PeerInfo_hash)
if should_push_peer || peer_state_changed {
PushPeerinfo(false)
2021-08-21 16:54:24 +02:00
}
if should_push_nh {
PushNhTable(false)
}
2021-12-05 22:36:50 +01:00
if should_push_superparams {
PushServerParams(false)
}
2021-12-02 18:13:48 +01:00
httpobj.RUnlock()
2021-08-21 16:54:24 +02:00
case pong_msg := <-events.Event_server_pong:
2021-10-27 03:02:44 +02:00
var changed bool
2021-12-02 18:13:48 +01:00
httpobj.RLock()
2021-12-09 08:46:15 +01:00
if pong_msg.Src_nodeID < mtypes.NodeID_Special && pong_msg.Dst_nodeID < mtypes.NodeID_Special {
2021-12-02 18:13:48 +01:00
AdditionalCost_use := httpobj.http_PeerID2Info[pong_msg.Dst_nodeID].AdditionalCost
if AdditionalCost_use < 0 {
2021-12-09 08:46:15 +01:00
pong_msg.AdditionalCost = AdditionalCost_use
2021-12-02 18:13:48 +01:00
}
2021-12-09 08:46:15 +01:00
changed = httpobj.http_graph.UpdateLatencyMulti([]mtypes.PongMsg{pong_msg}, true, true)
2021-10-27 03:02:44 +02:00
} else {
2021-12-09 08:46:15 +01:00
changed = httpobj.http_graph.RecalculateNhTable(true)
2021-10-27 03:02:44 +02:00
}
2021-08-21 16:54:24 +02:00
if changed {
2021-10-12 10:05:23 +02:00
NhTable := graph.GetNHTable(true)
2021-08-21 16:54:24 +02:00
NhTablestr, _ := json.Marshal(NhTable)
2021-12-04 03:32:59 +01:00
md5_hash_raw := md5.Sum(append(NhTablestr, httpobj.http_HashSalt...))
2021-08-21 16:54:24 +02:00
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
2021-12-04 03:32:59 +01:00
httpobj.http_NhTable_Hash = new_hash_str
2021-12-02 18:13:48 +01:00
httpobj.http_NhTableStr = NhTablestr
PushNhTable(false)
2021-08-20 19:32:50 +02:00
}
2021-12-02 18:13:48 +01:00
httpobj.RUnlock()
2021-08-20 19:32:50 +02:00
}
}
}
2021-08-21 16:54:24 +02:00
func RoutinePushSettings(interval time.Duration) {
force := false
var lastforce time.Time
2021-08-20 19:32:50 +02:00
for {
if time.Now().After(lastforce.Add(interval)) {
lastforce = time.Now()
force = true
} else {
force = false
}
PushNhTable(force)
2021-12-04 03:32:59 +01:00
PushPeerinfo(false)
PushServerParams(false)
2021-12-03 23:46:58 +01:00
time.Sleep(mtypes.S2TD(1))
2021-08-21 16:54:24 +02:00
}
}
2021-10-27 03:02:44 +02:00
func RoutineTimeoutCheck() {
for {
2021-12-02 18:13:48 +01:00
httpobj.http_super_chains.Event_server_register <- mtypes.RegisterMsg{
2021-12-09 08:46:15 +01:00
Node_id: mtypes.NodeID_SuperNode,
2021-10-27 03:02:44 +02:00
Version: "dummy",
}
2021-12-02 18:13:48 +01:00
httpobj.http_super_chains.Event_server_pong <- mtypes.PongMsg{
2021-10-27 03:02:44 +02:00
RequestID: 0,
2021-12-09 08:46:15 +01:00
Src_nodeID: mtypes.NodeID_SuperNode,
Dst_nodeID: mtypes.NodeID_SuperNode,
2021-10-27 03:02:44 +02:00
}
2021-12-02 18:13:48 +01:00
time.Sleep(httpobj.http_graph.TimeoutCheckInterval)
2021-10-27 03:02:44 +02:00
}
}
func PushNhTable(force bool) {
2021-12-02 18:13:48 +01:00
// No lock
2021-12-04 03:32:59 +01:00
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
2021-12-09 08:46:15 +01:00
Node_id: mtypes.NodeID_SuperNode,
2021-12-04 03:32:59 +01:00
Action: mtypes.UpdateNhTable,
Code: 0,
Params: string(httpobj.http_NhTable_Hash[:]),
2021-08-21 16:54:24 +02:00
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
2021-12-11 20:33:01 +01:00
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen], device.DefaultMTU)
2021-12-09 08:46:15 +01:00
header.SetDst(mtypes.NodeID_SuperNode)
header.SetSrc(mtypes.NodeID_SuperNode)
2021-08-21 16:54:24 +02:00
copy(buf[path.EgHeaderLen:], body)
2021-12-02 18:13:48 +01:00
for pkstr, peerstate := range httpobj.http_PeerState {
2021-12-04 04:51:50 +01:00
isAlive := peerstate.LastSeen.Load().(time.Time).Add(mtypes.S2TD(httpobj.http_sconfig.PeerAliveTimeout)).After(time.Now())
2021-12-15 11:34:49 +01:00
if !isAlive && !force {
2021-10-12 10:05:23 +02:00
continue
}
2021-12-04 04:51:50 +01:00
if force || peerstate.NhTableState.Load().(string) != httpobj.http_NhTable_Hash {
2021-12-02 18:13:48 +01:00
if peer := httpobj.http_device4.LookupPeerByStr(pkstr); peer != nil && peer.GetEndpointDstStr() != "" {
httpobj.http_device4.SendPacket(peer, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
}
2021-12-02 18:13:48 +01:00
if peer := httpobj.http_device6.LookupPeerByStr(pkstr); peer != nil && peer.GetEndpointDstStr() != "" {
httpobj.http_device6.SendPacket(peer, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
}
}
2021-08-21 16:54:24 +02:00
}
}
func PushPeerinfo(force bool) {
2021-12-02 18:13:48 +01:00
//No lock
2021-12-04 03:32:59 +01:00
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
2021-12-09 08:46:15 +01:00
Node_id: mtypes.NodeID_SuperNode,
2021-12-04 03:32:59 +01:00
Action: mtypes.UpdatePeer,
Code: 0,
Params: string(httpobj.http_PeerInfo_hash[:]),
2021-08-21 16:54:24 +02:00
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
2021-12-11 20:33:01 +01:00
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen], device.DefaultMTU)
2021-12-09 08:46:15 +01:00
header.SetDst(mtypes.NodeID_SuperNode)
header.SetSrc(mtypes.NodeID_SuperNode)
2021-08-21 16:54:24 +02:00
copy(buf[path.EgHeaderLen:], body)
2021-12-02 18:13:48 +01:00
for pkstr, peerstate := range httpobj.http_PeerState {
2021-12-04 04:51:50 +01:00
isAlive := peerstate.LastSeen.Load().(time.Time).Add(mtypes.S2TD(httpobj.http_sconfig.PeerAliveTimeout)).After(time.Now())
2021-12-15 11:34:49 +01:00
if !isAlive && !force {
2021-10-12 10:05:23 +02:00
continue
}
2021-12-04 04:51:50 +01:00
if force || peerstate.PeerInfoState.Load().(string) != httpobj.http_PeerInfo_hash {
2021-12-02 18:13:48 +01:00
if peer := httpobj.http_device4.LookupPeerByStr(pkstr); peer != nil {
httpobj.http_device4.SendPacket(peer, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
2021-12-04 03:32:59 +01:00
}
if peer := httpobj.http_device6.LookupPeerByStr(pkstr); peer != nil {
httpobj.http_device6.SendPacket(peer, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
2021-12-04 03:32:59 +01:00
}
}
}
}
func PushServerParams(force bool) {
//No lock
for pkstr, peerstate := range httpobj.http_PeerState {
2021-12-04 04:51:50 +01:00
isAlive := peerstate.LastSeen.Load().(time.Time).Add(mtypes.S2TD(httpobj.http_sconfig.PeerAliveTimeout)).After(time.Now())
2021-12-15 11:34:49 +01:00
if !isAlive && !force {
2021-12-04 03:32:59 +01:00
continue
}
2021-12-04 15:46:36 +01:00
if force || peerstate.SuperParamState.Load().(string) != peerstate.SuperParamStateClient.Load().(string) {
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
2021-12-09 08:46:15 +01:00
Node_id: mtypes.NodeID_SuperNode,
2021-12-04 15:46:36 +01:00
Action: mtypes.UpdateSuperParams,
Code: 0,
Params: peerstate.SuperParamState.Load().(string),
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
2021-12-11 20:33:01 +01:00
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen], device.DefaultMTU)
2021-12-09 08:46:15 +01:00
header.SetDst(mtypes.NodeID_SuperNode)
header.SetSrc(mtypes.NodeID_SuperNode)
2021-12-04 15:46:36 +01:00
copy(buf[path.EgHeaderLen:], body)
2021-12-04 03:32:59 +01:00
if peer := httpobj.http_device4.LookupPeerByStr(pkstr); peer != nil {
httpobj.http_device4.SendPacket(peer, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
2021-08-20 19:32:50 +02:00
}
2021-12-02 18:13:48 +01:00
if peer := httpobj.http_device6.LookupPeerByStr(pkstr); peer != nil {
httpobj.http_device6.SendPacket(peer, path.ServerUpdate, 0, buf, device.MessageTransportOffsetContent)
2021-08-20 19:32:50 +02:00
}
}
}
}
func startUAPI(interfaceName string, logger *device.Logger, the_device *device.Device, errs chan error) (net.Listener, error) {
fileUAPI, err := func() (*os.File, error) {
2021-08-24 10:43:55 +02:00
uapiFdStr := os.Getenv(ENV_EG_UAPI_FD)
2021-08-20 19:32:50 +02:00
if uapiFdStr == "" {
return ipc.UAPIOpen(interfaceName)
}
// use supplied fd
fd, err := strconv.ParseUint(uapiFdStr, 10, 32)
if err != nil {
return nil, err
}
return os.NewFile(uintptr(fd), ""), nil
}()
2021-08-24 10:43:55 +02:00
if err != nil {
fmt.Printf("Error create UAPI socket \n")
return nil, err
}
2021-08-20 19:32:50 +02:00
uapi, err := ipc.UAPIListen(interfaceName, fileUAPI)
if err != nil {
logger.Errorf("Failed to listen on uapi socket: %v", err)
2021-08-24 10:43:55 +02:00
return nil, err
2021-08-20 19:32:50 +02:00
}
go func() {
for {
conn, err := uapi.Accept()
if err != nil {
errs <- err
return
}
go the_device.IpcHandle(conn)
}
}()
logger.Verbosef("UAPI listener started")
return uapi, err
2021-08-16 20:58:15 +02:00
}