mirror of
https://github.com/KusakabeShi/EtherGuard-VPN.git
synced 2024-11-22 07:13:09 +01:00
bunch of bugfix, supermode OK
This commit is contained in:
parent
4939f9f0c4
commit
19fe84cf0c
2
Makefile
2
Makefile
@ -8,6 +8,8 @@ all: generate-version-and-build
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
generate-version-and-build:
|
||||
go mod download && \
|
||||
go mod tidy && \
|
||||
@export GIT_CEILING_DIRECTORIES="$(realpath $(CURDIR)/..)" && \
|
||||
tag="$$(git describe --dirty 2>/dev/null)" && \
|
||||
ver="$$(printf 'package main\n\nconst Version = "%s"\n' "$$tag")" && \
|
||||
|
@ -18,6 +18,7 @@ type SuperConfig struct {
|
||||
PrivKeyV6 string
|
||||
ListenPort int
|
||||
LogLevel LoggerInfo
|
||||
RePushConfigInterval float64
|
||||
GraphRecalculateSetting GraphRecalculateSetting
|
||||
Peers []PeerInfo
|
||||
}
|
||||
@ -36,6 +37,7 @@ type InterfaceConf struct {
|
||||
type PeerInfo struct {
|
||||
NodeID Vertex
|
||||
PubKey string
|
||||
PSKey string
|
||||
EndPoint string
|
||||
Static bool
|
||||
}
|
||||
@ -43,6 +45,7 @@ type PeerInfo struct {
|
||||
type LoggerInfo struct {
|
||||
LogLevel string
|
||||
LogTransit bool
|
||||
LogControl bool
|
||||
}
|
||||
|
||||
// Nonnegative integer ID of vertex
|
||||
@ -100,4 +103,3 @@ type HTTP_Peerinfo struct {
|
||||
type HTTP_Peers struct {
|
||||
Peers map[string]HTTP_Peerinfo
|
||||
}
|
||||
|
||||
|
@ -155,11 +155,11 @@ again:
|
||||
}
|
||||
}
|
||||
var fns []ReceiveFunc
|
||||
if sock4 != -1 {
|
||||
if sock4 != -1 && bind.use4 {
|
||||
bind.sock4 = sock4
|
||||
fns = append(fns, bind.receiveIPv4)
|
||||
}
|
||||
if sock6 != -1 {
|
||||
if sock6 != -1 && bind.use6 {
|
||||
bind.sock6 = sock6
|
||||
fns = append(fns, bind.receiveIPv6)
|
||||
}
|
||||
|
@ -81,11 +81,13 @@ type Device struct {
|
||||
indexTable IndexTable
|
||||
cookieChecker CookieChecker
|
||||
|
||||
MsgCount uint32
|
||||
IsSuperNode bool
|
||||
ID config.Vertex
|
||||
graph *path.IG
|
||||
l2fib map[tap.MacAddress]config.Vertex
|
||||
LogTransit bool
|
||||
LogControl bool
|
||||
DRoute config.DynamicRouteInfo
|
||||
DupData fixed_time_cache.Cache
|
||||
|
||||
@ -302,7 +304,7 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *Logger, graph *path.IG, IsSuperNode bool, theconfigpath string, theconfig *config.EdgeConfig, superevents *path.SUPER_Events) *Device {
|
||||
func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *Logger, graph *path.IG, IsSuperNode bool, theconfigpath string, econfig *config.EdgeConfig, sconfig *config.SuperConfig, superevents *path.SUPER_Events) *Device {
|
||||
device := new(Device)
|
||||
device.state.state = uint32(deviceStateDown)
|
||||
device.closed = make(chan struct{})
|
||||
@ -317,6 +319,7 @@ func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *L
|
||||
device.tap.mtu = int32(mtu)
|
||||
device.peers.keyMap = make(map[NoisePublicKey]*Peer)
|
||||
device.peers.IDMap = make(map[config.Vertex]*Peer)
|
||||
device.peers.SuperPeer = make(map[NoisePublicKey]*Peer)
|
||||
device.IsSuperNode = IsSuperNode
|
||||
device.ID = id
|
||||
device.graph = graph
|
||||
@ -329,14 +332,18 @@ func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *L
|
||||
device.Event_server_pong = superevents.Event_server_pong
|
||||
device.Event_server_register = superevents.Event_server_register
|
||||
device.Event_server_NhTable_changed = superevents.Event_server_NhTable_changed
|
||||
device.LogTransit = sconfig.LogLevel.LogTransit
|
||||
device.LogControl = sconfig.LogLevel.LogControl
|
||||
go device.RoutineRecalculateNhTable()
|
||||
} else {
|
||||
device.EdgeConfigPath = theconfigpath
|
||||
device.EdgeConfig = theconfig
|
||||
device.DRoute = theconfig.DynamicRoute
|
||||
device.DupData = *fixed_time_cache.NewCache(path.S2TD(theconfig.DynamicRoute.DupCheckTimeout))
|
||||
device.EdgeConfig = econfig
|
||||
device.DRoute = econfig.DynamicRoute
|
||||
device.DupData = *fixed_time_cache.NewCache(path.S2TD(econfig.DynamicRoute.DupCheckTimeout))
|
||||
device.event_tryendpoint = make(chan struct{}, 1<<6)
|
||||
device.Event_save_config = make(chan struct{}, 1<<5)
|
||||
device.LogTransit = econfig.LogLevel.LogTransit
|
||||
device.LogControl = econfig.LogLevel.LogControl
|
||||
go device.RoutineSetEndpoint()
|
||||
go device.RoutineRegister()
|
||||
go device.RoutineSendPing()
|
||||
|
@ -7,8 +7,10 @@ package device
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -88,6 +90,9 @@ func (device *Device) NewPeer(pk NoisePublicKey, id config.Vertex) (*Peer, error
|
||||
}
|
||||
|
||||
// create peer
|
||||
if device.LogControl {
|
||||
fmt.Println("Create peer with ID : " + strconv.Itoa(int(id)) + " and PubKey:" + base64.StdEncoding.EncodeToString(pk[:]))
|
||||
}
|
||||
peer := new(Peer)
|
||||
peer.Lock()
|
||||
defer peer.Unlock()
|
||||
@ -97,6 +102,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id config.Vertex) (*Peer, error
|
||||
peer.queue.outbound = newAutodrainingOutboundQueue(device)
|
||||
peer.queue.inbound = newAutodrainingInboundQueue(device)
|
||||
peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize)
|
||||
peer.endpoint_trylist = make(map[string]time.Time)
|
||||
|
||||
// map public key
|
||||
_, ok := device.peers.keyMap[pk]
|
||||
@ -122,8 +128,8 @@ func (device *Device) NewPeer(pk NoisePublicKey, id config.Vertex) (*Peer, error
|
||||
// add
|
||||
if id == path.SuperNodeMessage { // To communicate with supernode
|
||||
device.peers.SuperPeer[pk] = peer
|
||||
device.peers.keyMap[pk] = peer
|
||||
} else { // Regular peer, other edgenodes
|
||||
_, ok = device.peers.IDMap[id]
|
||||
device.peers.keyMap[pk] = peer
|
||||
device.peers.IDMap[id] = peer
|
||||
}
|
||||
@ -288,6 +294,12 @@ func (peer *Peer) Stop() {
|
||||
peer.ZeroAndFlushAll()
|
||||
}
|
||||
|
||||
func (peer *Peer) SetPSK(psk NoisePresharedKey) {
|
||||
peer.handshake.mutex.Lock()
|
||||
peer.handshake.presharedKey = psk
|
||||
peer.handshake.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
|
||||
if peer.disableRoaming {
|
||||
return
|
||||
@ -298,9 +310,15 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
|
||||
}
|
||||
|
||||
func (peer *Peer) GetEndpointSrcStr() string {
|
||||
if peer.endpoint == nil {
|
||||
return ""
|
||||
}
|
||||
return peer.endpoint.SrcToString()
|
||||
}
|
||||
|
||||
func (peer *Peer) GetEndpointDstStr() string {
|
||||
if peer.endpoint == nil {
|
||||
return ""
|
||||
}
|
||||
return peer.endpoint.DstToString()
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -410,7 +411,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
if elem == nil {
|
||||
return
|
||||
}
|
||||
var EgBody path.EgHeader
|
||||
var EgHeader path.EgHeader
|
||||
var err error
|
||||
var src_nodeID config.Vertex
|
||||
var dst_nodeID config.Vertex
|
||||
@ -445,11 +446,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
}
|
||||
peer.timersDataReceived()
|
||||
|
||||
EgBody, err = path.NewEgHeader(elem.packet[0:path.EgHeaderLen])
|
||||
src_nodeID = EgBody.GetSrc()
|
||||
dst_nodeID = EgBody.GetDst()
|
||||
elem.packet = elem.packet[:EgBody.GetPacketLength()]
|
||||
packet_type = EgBody.GetUsage()
|
||||
EgHeader, err = path.NewEgHeader(elem.packet[0:path.EgHeaderLen]) // EG header
|
||||
src_nodeID = EgHeader.GetSrc()
|
||||
dst_nodeID = EgHeader.GetDst()
|
||||
elem.packet = elem.packet[:EgHeader.GetPacketLength()+path.EgHeaderLen] // EG header + true packet
|
||||
packet_type = EgHeader.GetUsage()
|
||||
|
||||
if device.IsSuperNode {
|
||||
peer.LastPingReceived = time.Now()
|
||||
@ -472,7 +473,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
case path.SuperNodeMessage:
|
||||
should_process = true
|
||||
case path.ControlMessage:
|
||||
packet := elem.packet[path.EgHeaderLen:]
|
||||
packet := elem.packet[path.EgHeaderLen:] //true packet
|
||||
if device.CheckNoDup(packet) {
|
||||
should_process = true
|
||||
should_transfer = true
|
||||
@ -498,11 +499,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
}
|
||||
}
|
||||
if should_transfer {
|
||||
l2ttl := EgBody.GetTTL()
|
||||
l2ttl := EgHeader.GetTTL()
|
||||
if l2ttl == 0 {
|
||||
device.log.Verbosef("TTL is 0 %v", dst_nodeID)
|
||||
} else {
|
||||
EgBody.SetTTL(l2ttl - 1)
|
||||
EgHeader.SetTTL(l2ttl - 1)
|
||||
if dst_nodeID == path.Boardcast { //Regular transfer algorithm
|
||||
device.TransitBoardcastPacket(src_nodeID, peer.ID, elem.packet, MessageTransportOffsetContent)
|
||||
} else if dst_nodeID == path.ControlMessage { // Control Message will try send to every know node regardless the connectivity
|
||||
@ -524,7 +525,15 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
|
||||
if should_process {
|
||||
if packet_type != path.NornalPacket {
|
||||
device.process_received(packet_type, elem.packet[path.EgHeaderLen:])
|
||||
if device.LogControl {
|
||||
if peer.GetEndpointDstStr() != "" {
|
||||
fmt.Printf("Received MID:" + strconv.Itoa(int(EgHeader.GetMessageID())) + " From:" + peer.GetEndpointDstStr() + " " + device.sprint_received(packet_type, elem.packet[path.EgHeaderLen:]) + "\n")
|
||||
}
|
||||
}
|
||||
err = device.process_received(packet_type, elem.packet[path.EgHeaderLen:])
|
||||
if err != nil {
|
||||
device.log.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"hash/crc32"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
@ -19,6 +21,16 @@ func (device *Device) SendPacket(peer *Peer, packet []byte, offset int) {
|
||||
if peer == nil {
|
||||
return
|
||||
}
|
||||
if device.LogControl {
|
||||
EgHeader, _ := path.NewEgHeader(packet[:path.EgHeaderLen])
|
||||
if EgHeader.GetUsage() != path.NornalPacket {
|
||||
device.MsgCount += 1
|
||||
EgHeader.SetMessageID(device.MsgCount)
|
||||
if peer.GetEndpointDstStr() != "" {
|
||||
fmt.Printf("Send MID:" + strconv.Itoa(int(device.MsgCount)) + " To:" + peer.GetEndpointDstStr() + " " + device.sprint_received(EgHeader.GetUsage(), packet[path.EgHeaderLen:]) + "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
var elem *QueueOutboundElement
|
||||
elem = device.NewOutboundElement()
|
||||
copy(elem.buffer[offset:offset+len(packet)], packet)
|
||||
@ -135,6 +147,42 @@ func (device *Device) process_received(msg_type path.Usage, body []byte) (err er
|
||||
return
|
||||
}
|
||||
|
||||
func (device *Device) sprint_received(msg_type path.Usage, body []byte) (ret string) {
|
||||
switch msg_type {
|
||||
case path.Register:
|
||||
if content, err := path.ParseRegisterMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
case path.UpdatePeer:
|
||||
if content, err := path.ParseUpdatePeerMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
case path.UpdateNhTable:
|
||||
if content, err := path.ParseUpdateNhTableMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
case path.PingPacket:
|
||||
if content, err := path.ParsePingMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
case path.PongPacket:
|
||||
if content, err := path.ParsePongMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
case path.RequestPeer:
|
||||
if content, err := path.ParseRequestPeerMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
case path.BoardcastPeer:
|
||||
if content, err := path.ParseBoardcastPeerMsg(body); err == nil {
|
||||
ret = content.ToString()
|
||||
}
|
||||
default:
|
||||
ret = "Not a valid msg_type"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (device *Device) server_process_RegisterMsg(content path.RegisterMsg) error {
|
||||
device.Event_server_register <- content
|
||||
return nil
|
||||
@ -161,6 +209,7 @@ func (device *Device) process_ping(content path.PingMsg) error {
|
||||
header.SetTTL(200)
|
||||
header.SetUsage(path.PongPacket)
|
||||
header.SetPacketLength(uint16(len(body)))
|
||||
copy(buf[path.EgHeaderLen:], body)
|
||||
if device.DRoute.SuperNode.UseSuperNode {
|
||||
header.SetDst(path.SuperNodeMessage)
|
||||
device.Send2Super(buf, MessageTransportOffsetContent)
|
||||
@ -186,7 +235,12 @@ func (device *Device) process_UpdatePeerMsg(content path.UpdatePeerMsg) error {
|
||||
if bytes.Equal(device.peers.Peer_state[:], content.State_hash[:]) {
|
||||
return nil
|
||||
}
|
||||
resp, err := http.Get(device.DRoute.SuperNode.APIUrl + "/peerinfo?PubKey=" + PubKey2Str(device.staticIdentity.publicKey) + "?State=" + string(content.State_hash[:]))
|
||||
|
||||
downloadurl := device.DRoute.SuperNode.APIUrl + "/peerinfo?PubKey=" + url.QueryEscape(PubKey2Str(device.staticIdentity.publicKey)) + "&State=" + url.QueryEscape(string(content.State_hash[:]))
|
||||
if device.LogControl {
|
||||
fmt.Println("Download peerinfo from :" + downloadurl)
|
||||
}
|
||||
resp, err := http.Get(downloadurl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -263,6 +317,9 @@ func (device *Device) RoutineSetEndpoint() {
|
||||
device.log.Errorf("Can't bind " + url)
|
||||
delete(thepeer.endpoint_trylist, url)
|
||||
}
|
||||
if device.LogControl {
|
||||
fmt.Println("Set endpoint to " + endpoint.DstToString() + " for NodeID:" + strconv.Itoa(int(thepeer.ID)))
|
||||
}
|
||||
thepeer.SetEndpointFromPacket(endpoint)
|
||||
NextRun = true
|
||||
thepeer.endpoint_trylist[url] = time.Now()
|
||||
@ -312,9 +369,11 @@ func (device *Device) RoutineRegister() {
|
||||
if !(device.DRoute.SuperNode.UseSuperNode) {
|
||||
return
|
||||
}
|
||||
first := true
|
||||
for {
|
||||
body, _ := path.GetByte(path.RegisterMsg{
|
||||
Node_id: device.ID,
|
||||
Init: first,
|
||||
})
|
||||
buf := make([]byte, path.EgHeaderLen+len(body))
|
||||
header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen])
|
||||
@ -326,6 +385,7 @@ func (device *Device) RoutineRegister() {
|
||||
copy(buf[path.EgHeaderLen:], body)
|
||||
device.Send2Super(buf, MessageTransportOffsetContent)
|
||||
time.Sleep(path.S2TD(device.DRoute.SendPingInterval))
|
||||
first = false
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,7 +403,6 @@ func (device *Device) RoutineRecalculateNhTable() {
|
||||
return
|
||||
}
|
||||
for {
|
||||
|
||||
device.graph.RecalculateNhTable(false)
|
||||
time.Sleep(device.graph.NodeReportTimeout)
|
||||
}
|
||||
@ -382,7 +441,11 @@ func (device *Device) process_UpdateNhTableMsg(content path.UpdateNhTableMsg) er
|
||||
if bytes.Equal(device.graph.NhTableHash[:], content.State_hash[:]) {
|
||||
return nil
|
||||
}
|
||||
resp, err := http.Get(device.DRoute.SuperNode.APIUrl + "/nhtable?PubKey=" + PubKey2Str(device.staticIdentity.publicKey) + "?State=" + string(content.State_hash[:]))
|
||||
downloadurl := device.DRoute.SuperNode.APIUrl + "/nhtable?PubKey=" + url.QueryEscape(PubKey2Str(device.staticIdentity.publicKey)) + "&State=" + url.QueryEscape(string(content.State_hash[:]))
|
||||
if device.LogControl {
|
||||
fmt.Println("Download NhTable from :" + downloadurl)
|
||||
}
|
||||
resp, err := http.Get(downloadurl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -407,7 +470,7 @@ func (device *Device) process_RequestPeerMsg(content path.RequestPeerMsg) error
|
||||
}
|
||||
|
||||
response := path.BoardcastPeerMsg{
|
||||
RequestID: content.Request_ID,
|
||||
Request_ID: content.Request_ID,
|
||||
NodeID: peer.ID,
|
||||
PubKey: pubkey,
|
||||
PSKey: peer.handshake.presharedKey,
|
||||
|
@ -183,8 +183,7 @@ func Edge(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
graph := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting)
|
||||
graph.SetNHTable(tconfig.NextHopTable, [32]byte{})
|
||||
|
||||
the_device := device.NewDevice(thetap, tconfig.NodeID, conn.NewDefaultBind(), logger, &graph, false, configPath, &tconfig, nil)
|
||||
the_device.LogTransit = tconfig.LogLevel.LogTransit
|
||||
the_device := device.NewDevice(thetap, tconfig.NodeID, conn.NewDefaultBind(), logger, graph, false, configPath, &tconfig, nil, nil)
|
||||
defer the_device.Close()
|
||||
var sk [32]byte
|
||||
sk_slice, _ := base64.StdEncoding.DecodeString(tconfig.PrivKey)
|
||||
|
@ -15,8 +15,8 @@ var (
|
||||
http_graph *path.IG
|
||||
http_device4 *device.Device
|
||||
http_device6 *device.Device
|
||||
http_NhTable_Hash string
|
||||
http_PeerInfo_hash string
|
||||
http_NhTable_Hash [32]byte
|
||||
http_PeerInfo_hash [32]byte
|
||||
http_NhTableStr []byte
|
||||
http_PeerInfoStr []byte
|
||||
http_PeerState map[string]*PeerState
|
||||
@ -25,8 +25,8 @@ var (
|
||||
)
|
||||
|
||||
type PeerState struct {
|
||||
NhTableState string
|
||||
PeerInfoState string
|
||||
NhTableState [32]byte
|
||||
PeerInfoState [32]byte
|
||||
}
|
||||
|
||||
type client struct {
|
||||
@ -43,7 +43,7 @@ func get_peerinfo(w http.ResponseWriter, r *http.Request) {
|
||||
PubKey, _ := params["PubKey"]
|
||||
State, _ := params["State"]
|
||||
if state := http_PeerState[PubKey[0]]; state != nil {
|
||||
http_PeerState[PubKey[0]].PeerInfoState = State[0]
|
||||
copy(http_PeerState[PubKey[0]].PeerInfoState[:], State[0])
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(http_PeerInfoStr))
|
||||
@ -54,19 +54,18 @@ func get_nhtable(w http.ResponseWriter, r *http.Request) {
|
||||
PubKey, _ := params["PubKey"]
|
||||
State, _ := params["State"]
|
||||
if state := http_PeerState[PubKey[0]]; state != nil {
|
||||
http_PeerState[PubKey[0]].NhTableState = State[0]
|
||||
copy(http_PeerState[PubKey[0]].NhTableState[:], State[0])
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(http_NhTableStr))
|
||||
}
|
||||
|
||||
func HttpServer(http_port int, apiprefix string, graph *path.IG, device4 *device.Device, device6 *device.Device) {
|
||||
http_graph = graph
|
||||
http_device4 = device4
|
||||
http_device6 = device6
|
||||
http_PeerState = make(map[string]*PeerState)
|
||||
func HttpServer(http_port int, apiprefix string) {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/"+apiprefix+"/peerinfo", get_peerinfo)
|
||||
mux.HandleFunc("/"+apiprefix+"/nhtable", get_nhtable)
|
||||
go http.ListenAndServe(":"+strconv.Itoa(http_port), mux)
|
||||
if apiprefix[0] != '/' {
|
||||
apiprefix = "/" + apiprefix
|
||||
}
|
||||
mux.HandleFunc(apiprefix+"/peerinfo", get_peerinfo)
|
||||
mux.HandleFunc(apiprefix+"/nhtable", get_nhtable)
|
||||
http.ListenAndServe(":"+strconv.Itoa(http_port), mux)
|
||||
}
|
||||
|
173
main_super.go
173
main_super.go
@ -8,6 +8,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
@ -19,6 +20,7 @@ import (
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
"github.com/KusakabeSi/EtherGuardVPN/conn"
|
||||
@ -92,6 +94,10 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
fmt.Sprintf("(%s) ", interfaceName+"_v6"),
|
||||
)
|
||||
|
||||
http_PeerState = make(map[string]*PeerState)
|
||||
http_PeerID2Map = make(map[config.Vertex]string)
|
||||
http_PeerInfos.Peers = make(map[string]config.HTTP_Peerinfo)
|
||||
|
||||
super_chains := path.SUPER_Events{
|
||||
Event_server_pong: make(chan path.PongMsg, 1<<5),
|
||||
Event_server_register: make(chan path.RegisterMsg, 1<<5),
|
||||
@ -99,31 +105,55 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
}
|
||||
|
||||
thetap, _ := tap.CreateDummyTAP()
|
||||
graph := path.NewGraph(3, true, sconfig.GraphRecalculateSetting)
|
||||
device_v4 := device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(true, false), logger4, &graph, true, "", nil, &super_chains)
|
||||
device_v6 := device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(false, true), logger6, &graph, true, "", nil, &super_chains)
|
||||
defer device_v4.Close()
|
||||
defer device_v6.Close()
|
||||
http_graph = path.NewGraph(3, true, sconfig.GraphRecalculateSetting)
|
||||
http_device4 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(true, false), logger4, http_graph, true, "", nil, &sconfig, &super_chains)
|
||||
http_device6 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(false, true), logger6, http_graph, true, "", nil, &sconfig, &super_chains)
|
||||
defer http_device4.Close()
|
||||
defer http_device6.Close()
|
||||
var sk [32]byte
|
||||
sk_slice, _ := base64.StdEncoding.DecodeString(sconfig.PrivKeyV4)
|
||||
copy(sk[:], sk_slice)
|
||||
device_v4.SetPrivateKey(sk)
|
||||
http_device4.SetPrivateKey(sk)
|
||||
sk_slice, _ = base64.StdEncoding.DecodeString(sconfig.PrivKeyV6)
|
||||
copy(sk[:], sk_slice)
|
||||
device_v6.SetPrivateKey(sk)
|
||||
device_v4.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
|
||||
device_v6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
|
||||
device_v4.IpcSet("replace_peers=true\n")
|
||||
device_v6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
|
||||
http_device6.SetPrivateKey(sk)
|
||||
http_device4.IpcSet("fwmark=0\n")
|
||||
http_device6.IpcSet("fwmark=0\n")
|
||||
http_device4.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
|
||||
http_device6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort-1) + "\n")
|
||||
http_device4.IpcSet("replace_peers=true\n")
|
||||
http_device6.IpcSet("replace_peers=true\n")
|
||||
|
||||
for _, peerconf := range sconfig.Peers {
|
||||
sk_slice, _ = base64.StdEncoding.DecodeString(peerconf.PubKey)
|
||||
copy(sk[:], sk_slice)
|
||||
var pk device.NoisePublicKey
|
||||
|
||||
pk_slice, err := base64.StdEncoding.DecodeString(peerconf.PubKey)
|
||||
if err != nil {
|
||||
fmt.Println("Error decode base64 ", err)
|
||||
}
|
||||
copy(pk[:], pk_slice)
|
||||
if peerconf.NodeID >= path.SuperNodeMessage {
|
||||
return errors.New(fmt.Sprintf("Invalid Node_id at peer %s\n", peerconf.PubKey))
|
||||
}
|
||||
device_v4.NewPeer(sk, peerconf.NodeID)
|
||||
device_v6.NewPeer(sk, peerconf.NodeID)
|
||||
http_PeerID2Map[peerconf.NodeID] = peerconf.PubKey
|
||||
http_PeerInfos.Peers[peerconf.PubKey] = config.HTTP_Peerinfo{
|
||||
NodeID: peerconf.NodeID,
|
||||
PubKey: peerconf.PubKey,
|
||||
PSKey: peerconf.PSKey,
|
||||
Connurl: make(map[string]bool),
|
||||
}
|
||||
peer4, _ := http_device4.NewPeer(pk, peerconf.NodeID)
|
||||
peer6, _ := http_device6.NewPeer(pk, peerconf.NodeID)
|
||||
if peerconf.PSKey != "" {
|
||||
var psk device.NoisePresharedKey
|
||||
psk_slice, err := base64.StdEncoding.DecodeString(peerconf.PSKey)
|
||||
if err != nil {
|
||||
fmt.Println("Error decode base64 ", err)
|
||||
}
|
||||
copy(psk[:], psk_slice)
|
||||
peer4.SetPSK(psk)
|
||||
peer6.SetPSK(psk)
|
||||
}
|
||||
http_PeerState[peerconf.PubKey] = &PeerState{}
|
||||
}
|
||||
logger4.Verbosef("Device started")
|
||||
@ -131,12 +161,12 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
errs := make(chan error, 1<<3)
|
||||
term := make(chan os.Signal, 1)
|
||||
if useUAPI {
|
||||
uapi4, err := startUAPI(interfaceName+"_v4", logger4, device_v4, errs)
|
||||
uapi4, err := startUAPI(interfaceName+"_v4", logger4, http_device4, errs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer uapi4.Close()
|
||||
uapi6, err := startUAPI(interfaceName+"_v6", logger6, device_v6, errs)
|
||||
uapi6, err := startUAPI(interfaceName+"_v6", logger6, http_device6, errs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -145,36 +175,87 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
signal.Notify(term, syscall.SIGTERM)
|
||||
signal.Notify(term, os.Interrupt)
|
||||
|
||||
go Event_server_event_hendler(http_graph, super_chains)
|
||||
go RoutinePushSettings(path.S2TD(sconfig.RePushConfigInterval))
|
||||
go HttpServer(sconfig.ListenPort, "/api")
|
||||
|
||||
select {
|
||||
case <-term:
|
||||
case <-errs:
|
||||
case <-device_v4.Wait():
|
||||
case <-device_v6.Wait():
|
||||
case <-http_device4.Wait():
|
||||
case <-http_device6.Wait():
|
||||
}
|
||||
logger4.Verbosef("Shutting down")
|
||||
return
|
||||
}
|
||||
|
||||
func Event_server_pong_hendler(graph path.IG, events path.SUPER_Events) {
|
||||
func Event_server_event_hendler(graph *path.IG, events path.SUPER_Events) {
|
||||
for {
|
||||
pongmsg := <-events.Event_server_pong
|
||||
changed := graph.UpdateLentancy(pongmsg.Src_nodeID, pongmsg.Dst_nodeID, pongmsg.Timediff, true)
|
||||
select {
|
||||
case reg_msg := <-events.Event_server_register:
|
||||
if reg_msg.Init == true {
|
||||
copy(http_PeerState[http_PeerID2Map[reg_msg.Node_id]].NhTableState[:], make([]byte, 32))
|
||||
copy(http_PeerState[http_PeerID2Map[reg_msg.Node_id]].PeerInfoState[:], make([]byte, 32))
|
||||
}
|
||||
PubKey := http_PeerID2Map[reg_msg.Node_id]
|
||||
if peer := http_device4.LookupPeerByStr(PubKey); peer != nil {
|
||||
if connstr := peer.GetEndpointDstStr(); connstr != "" {
|
||||
http_PeerInfos.Peers[PubKey].Connurl[connstr] = true
|
||||
}
|
||||
}
|
||||
if peer := http_device6.LookupPeerByStr(PubKey); peer != nil {
|
||||
if connstr := peer.GetEndpointDstStr(); connstr != "" {
|
||||
http_PeerInfos.Peers[PubKey].Connurl[connstr] = true
|
||||
}
|
||||
}
|
||||
http_PeerInfoStr, _ = json.Marshal(&http_PeerInfos)
|
||||
PeerInfo_hash_raw := md5.Sum(http_PeerInfoStr)
|
||||
PeerInfo_hash_str := hex.EncodeToString(PeerInfo_hash_raw[:])
|
||||
PeerInfo_hash_str_byte := []byte(PeerInfo_hash_str)
|
||||
if bytes.Equal(http_PeerInfo_hash[:], PeerInfo_hash_str_byte) == false {
|
||||
copy(http_PeerInfo_hash[:], PeerInfo_hash_str_byte)
|
||||
PushUpdate()
|
||||
}
|
||||
case <-events.Event_server_NhTable_changed:
|
||||
NhTable := graph.GetNHTable(false)
|
||||
NhTablestr, _ := json.Marshal(NhTable)
|
||||
md5_hash_raw := md5.Sum(http_NhTableStr)
|
||||
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
|
||||
new_hash_str_byte := []byte(new_hash_str)
|
||||
copy(http_NhTable_Hash[:], new_hash_str_byte)
|
||||
http_NhTableStr = NhTablestr
|
||||
PushUpdate()
|
||||
case pong_msg := <-events.Event_server_pong:
|
||||
changed := graph.UpdateLentancy(pong_msg.Src_nodeID, pong_msg.Dst_nodeID, pong_msg.Timediff, true)
|
||||
if changed {
|
||||
NhTable := graph.GetNHTable(false)
|
||||
NhTablestr, _ := json.Marshal(NhTable)
|
||||
md5_hash_raw := md5.Sum(http_NhTableStr)
|
||||
new_hash := hex.EncodeToString(md5_hash_raw[:])
|
||||
if http_NhTable_Hash != new_hash {
|
||||
http_NhTable_Hash = new_hash
|
||||
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
|
||||
new_hash_str_byte := []byte(new_hash_str)
|
||||
copy(http_NhTable_Hash[:], new_hash_str_byte)
|
||||
http_NhTableStr = NhTablestr
|
||||
NhTable_Hash_fixbyte := [32]byte{}
|
||||
copy(NhTable_Hash_fixbyte[:], []byte(http_NhTable_Hash))
|
||||
PushNhTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RoutinePushSettings(interval time.Duration) {
|
||||
for {
|
||||
time.Sleep(interval)
|
||||
PushNhTable()
|
||||
PushUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
func PushNhTable() {
|
||||
body, err := path.GetByte(path.UpdateNhTableMsg{
|
||||
State_hash: NhTable_Hash_fixbyte,
|
||||
State_hash: http_NhTable_Hash,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("Error get byte")
|
||||
continue
|
||||
return
|
||||
}
|
||||
buf := make([]byte, path.EgHeaderLen+len(body))
|
||||
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
|
||||
@ -193,40 +274,16 @@ func Event_server_pong_hendler(graph path.IG, events path.SUPER_Events) {
|
||||
http_device6.SendPacket(peer, buf, device.MessageTransportOffsetContent)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Event_server_register_hendler(raph path.IG, events path.SUPER_Events) {
|
||||
for {
|
||||
reg_msg := <-events.Event_server_register
|
||||
PubKey := http_PeerID2Map[reg_msg.Node_id]
|
||||
if peer := http_device4.LookupPeerByStr(PubKey); peer != nil {
|
||||
if connstr := peer.GetEndpointDstStr(); connstr != "" {
|
||||
http_PeerInfos.Peers[PubKey].Connurl[connstr] = true
|
||||
}
|
||||
}
|
||||
if peer := http_device6.LookupPeerByStr(PubKey); peer != nil {
|
||||
if connstr := peer.GetEndpointDstStr(); connstr != "" {
|
||||
http_PeerInfos.Peers[PubKey].Connurl[connstr] = true
|
||||
}
|
||||
}
|
||||
http_PeerInfoStr, _ = json.Marshal(&http_PeerInfos)
|
||||
PeerInfo_hash_raw := md5.Sum(http_PeerInfoStr)
|
||||
PeerInfo_hash := hex.EncodeToString(PeerInfo_hash_raw[:])
|
||||
http_PeerInfo_hash_fixbyte := [32]byte{}
|
||||
copy(http_PeerInfo_hash_fixbyte[:], []byte(PeerInfo_hash))
|
||||
if http_PeerInfo_hash != PeerInfo_hash {
|
||||
http_PeerInfo_hash = PeerInfo_hash
|
||||
func PushUpdate() {
|
||||
body, err := path.GetByte(path.UpdatePeerMsg{
|
||||
State_hash: http_PeerInfo_hash_fixbyte,
|
||||
State_hash: http_PeerInfo_hash,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("Error get byte")
|
||||
continue
|
||||
return
|
||||
}
|
||||
buf := make([]byte, path.EgHeaderLen+len(body))
|
||||
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
|
||||
@ -237,7 +294,7 @@ func Event_server_register_hendler(raph path.IG, events path.SUPER_Events) {
|
||||
header.SetUsage(path.UpdatePeer)
|
||||
copy(buf[path.EgHeaderLen:], body)
|
||||
for pkstr, peerstate := range http_PeerState {
|
||||
if peerstate.PeerInfoState != PeerInfo_hash {
|
||||
if peerstate.PeerInfoState != http_PeerInfo_hash {
|
||||
if peer := http_device4.LookupPeerByStr(pkstr); peer != nil {
|
||||
http_device4.SendPacket(peer, buf, device.MessageTransportOffsetContent)
|
||||
}
|
||||
@ -247,8 +304,6 @@ func Event_server_register_hendler(raph path.IG, events path.SUPER_Events) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func startUAPI(interfaceName string, logger *device.Logger, the_device *device.Device, errs chan error) (net.Listener, error) {
|
||||
fileUAPI, err := func() (*os.File, error) {
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
)
|
||||
|
||||
const EgHeaderLen = 12
|
||||
const EgHeaderLen = 16
|
||||
|
||||
type EgHeader struct {
|
||||
buf []byte
|
||||
@ -72,3 +72,10 @@ func (e EgHeader) GetPacketLength() uint16 {
|
||||
func (e EgHeader) SetPacketLength(length uint16) {
|
||||
binary.BigEndian.PutUint16(e.buf[10:12], length)
|
||||
}
|
||||
|
||||
func (e EgHeader) GetMessageID() uint32 {
|
||||
return binary.BigEndian.Uint32(e.buf[12:16])
|
||||
}
|
||||
func (e EgHeader) SetMessageID(MessageID uint32) {
|
||||
binary.BigEndian.PutUint32(e.buf[12:16], MessageID)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package path
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
@ -19,94 +20,125 @@ func GetByte(structIn interface{}) (bb []byte, err error) {
|
||||
}
|
||||
|
||||
type RegisterMsg struct {
|
||||
Node_id config.Vertex
|
||||
Node_id config.Vertex `struc:"uint32"`
|
||||
Init bool
|
||||
}
|
||||
|
||||
func ParseRegisterMsg(bin []byte) (RegisterMsg, error) {
|
||||
var StructPlace RegisterMsg
|
||||
func (c *RegisterMsg) ToString() string {
|
||||
return "RegisterMsg Node_id:" + strconv.Itoa(int(c.Node_id))
|
||||
}
|
||||
|
||||
func ParseRegisterMsg(bin []byte) (StructPlace RegisterMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type UpdatePeerMsg struct {
|
||||
State_hash [32]byte
|
||||
State_hash [32]byte `struc:"[32]uint8"`
|
||||
}
|
||||
|
||||
func ParseUpdatePeerMsg(bin []byte) (UpdatePeerMsg, error) {
|
||||
var StructPlace UpdatePeerMsg
|
||||
func (c *UpdatePeerMsg) ToString() string {
|
||||
return "UpdatePeerMsg State_hash:" + string(c.State_hash[:])
|
||||
}
|
||||
|
||||
func ParseUpdatePeerMsg(bin []byte) (StructPlace UpdatePeerMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type UpdateNhTableMsg struct {
|
||||
State_hash [32]byte
|
||||
State_hash [32]byte `struc:"[32]uint8"`
|
||||
}
|
||||
|
||||
func ParseUpdateNhTableMsg(bin []byte) (UpdateNhTableMsg, error) {
|
||||
var StructPlace UpdateNhTableMsg
|
||||
func (c *UpdateNhTableMsg) ToString() string {
|
||||
return "UpdateNhTableMsg State_hash:" + string(c.State_hash[:])
|
||||
}
|
||||
|
||||
func ParseUpdateNhTableMsg(bin []byte) (StructPlace UpdateNhTableMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type PingMsg struct {
|
||||
Src_nodeID config.Vertex
|
||||
Time time.Time
|
||||
RequestID uint32 `struc:"uint32"`
|
||||
Src_nodeID config.Vertex `struc:"uint32"`
|
||||
Time time.Time `struc:"uint64"`
|
||||
}
|
||||
|
||||
func ParsePingMsg(bin []byte) (PingMsg, error) {
|
||||
var StructPlace PingMsg
|
||||
func (c *PingMsg) ToString() string {
|
||||
return "PingMsg SID:" + strconv.Itoa(int(c.Src_nodeID)) + " Time:" + c.Time.String() + " RequestID:" + strconv.Itoa(int(c.RequestID))
|
||||
}
|
||||
|
||||
func ParsePingMsg(bin []byte) (StructPlace PingMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type PongMsg struct {
|
||||
Src_nodeID config.Vertex
|
||||
Dst_nodeID config.Vertex
|
||||
Timediff time.Duration
|
||||
RequestID uint32
|
||||
Src_nodeID config.Vertex `struc:"uint32"`
|
||||
Dst_nodeID config.Vertex `struc:"uint32"`
|
||||
Timediff time.Duration `struc:"int64"`
|
||||
}
|
||||
|
||||
func ParsePongMsg(bin []byte) (PongMsg, error) {
|
||||
var StructPlace PongMsg
|
||||
func (c *PongMsg) ToString() string {
|
||||
return "PongMsg SID:" + strconv.Itoa(int(c.Src_nodeID)) + " DID:" + strconv.Itoa(int(c.Dst_nodeID)) + " Timediff:" + c.Timediff.String() + " RequestID:" + strconv.Itoa(int(c.RequestID))
|
||||
}
|
||||
|
||||
func ParsePongMsg(bin []byte) (StructPlace PongMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type RequestPeerMsg struct {
|
||||
Request_ID uint32
|
||||
Request_ID uint32 `struc:"uint32"`
|
||||
}
|
||||
|
||||
func ParseRequestPeerMsg(bin []byte) (RequestPeerMsg, error) {
|
||||
var StructPlace RequestPeerMsg
|
||||
func (c *RequestPeerMsg) ToString() string {
|
||||
return "RequestPeerMsg Request_ID:" + strconv.Itoa(int(c.Request_ID))
|
||||
}
|
||||
|
||||
func ParseRequestPeerMsg(bin []byte) (StructPlace RequestPeerMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type BoardcastPeerMsg struct {
|
||||
RequestID uint32
|
||||
NodeID config.Vertex
|
||||
PubKey [32]byte
|
||||
PSKey [32]byte
|
||||
Request_ID uint32 `struc:"uint32"`
|
||||
NodeID config.Vertex `struc:"uint32"`
|
||||
PubKey [32]byte `struc:"[32]uint8"`
|
||||
PSKey [32]byte `struc:"[32]uint8"`
|
||||
ConnURL string
|
||||
}
|
||||
|
||||
func ParseBoardcastPeerMsg(bin []byte) (BoardcastPeerMsg, error) {
|
||||
var StructPlace BoardcastPeerMsg
|
||||
func (c *BoardcastPeerMsg) ToString() string {
|
||||
return "BoardcastPeerMsg Request_ID:" + strconv.Itoa(int(c.Request_ID)) + " NodeID:" + strconv.Itoa(int(c.NodeID)) + " ConnURL:" + c.ConnURL
|
||||
}
|
||||
|
||||
func ParseBoardcastPeerMsg(bin []byte) (StructPlace BoardcastPeerMsg, err error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(bin)
|
||||
d := gob.NewDecoder(&b)
|
||||
err := d.Decode(&StructPlace)
|
||||
return StructPlace, err
|
||||
err = d.Decode(&StructPlace)
|
||||
return
|
||||
}
|
||||
|
||||
type SUPER_Events struct {
|
||||
|
49
path/path.go
49
path/path.go
@ -3,6 +3,7 @@ package path
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
@ -20,7 +21,7 @@ const (
|
||||
)
|
||||
|
||||
func (g *IG) GetCurrentTime() time.Time {
|
||||
return time.Now()
|
||||
return time.Now().Round(0)
|
||||
}
|
||||
|
||||
// A Graph is the interface implemented by graphs that
|
||||
@ -44,7 +45,8 @@ type Fullroute struct {
|
||||
// IG is a graph of integers that satisfies the Graph interface.
|
||||
type IG struct {
|
||||
Vert map[config.Vertex]bool
|
||||
Edges map[config.Vertex]map[config.Vertex]Latency
|
||||
edges map[config.Vertex]map[config.Vertex]Latency
|
||||
edgelock sync.RWMutex
|
||||
JitterTolerance float64
|
||||
JitterToleranceMultiplier float64
|
||||
NodeReportTimeout time.Duration
|
||||
@ -62,7 +64,7 @@ func S2TD(secs float64) time.Duration {
|
||||
return time.Duration(secs * float64(time.Second))
|
||||
}
|
||||
|
||||
func NewGraph(num_node int, IsSuperMode bool, theconfig config.GraphRecalculateSetting) IG {
|
||||
func NewGraph(num_node int, IsSuperMode bool, theconfig config.GraphRecalculateSetting) *IG {
|
||||
g := IG{
|
||||
JitterTolerance: theconfig.JitterTolerance,
|
||||
JitterToleranceMultiplier: theconfig.JitterToleranceMultiplier,
|
||||
@ -70,10 +72,10 @@ func NewGraph(num_node int, IsSuperMode bool, theconfig config.GraphRecalculateS
|
||||
RecalculateCoolDown: S2TD(theconfig.RecalculateCoolDown),
|
||||
}
|
||||
g.Vert = make(map[config.Vertex]bool, num_node)
|
||||
g.Edges = make(map[config.Vertex]map[config.Vertex]Latency, num_node)
|
||||
g.edges = make(map[config.Vertex]map[config.Vertex]Latency, num_node)
|
||||
g.IsSuperMode = IsSuperMode
|
||||
|
||||
return g
|
||||
return &g
|
||||
}
|
||||
|
||||
func (g *IG) GetWeightType(x float64) float64 {
|
||||
@ -91,7 +93,7 @@ func (g *IG) ShouldUpdate(u config.Vertex, v config.Vertex, newval float64) bool
|
||||
oldval := g.Weight(u, v) * 1000
|
||||
newval *= 1000
|
||||
if g.IsSuperMode {
|
||||
return (oldval-newval)*(oldval*g.JitterToleranceMultiplier) <= g.JitterTolerance
|
||||
return (oldval-newval)*(oldval*g.JitterToleranceMultiplier) >= g.JitterTolerance
|
||||
} else {
|
||||
return g.GetWeightType(oldval) == g.GetWeightType(newval)
|
||||
}
|
||||
@ -100,20 +102,19 @@ func (g *IG) ShouldUpdate(u config.Vertex, v config.Vertex, newval float64) bool
|
||||
func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
|
||||
if g.RecalculateTime.Add(g.RecalculateCoolDown).Before(time.Now()) {
|
||||
dist, next := FloydWarshall(g)
|
||||
changed = false
|
||||
if checkchange {
|
||||
CheckLoop:
|
||||
for src, dsts := range next {
|
||||
for dst, cost := range dsts {
|
||||
for dst, old_next := range dsts {
|
||||
nexthop := g.Next(src, dst)
|
||||
if nexthop != nil {
|
||||
changed = cost == nexthop
|
||||
if changed {
|
||||
if old_next != nexthop {
|
||||
changed = true
|
||||
break CheckLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g.dlTable, g.NhTable = dist, next
|
||||
g.nhTableExpire = time.Now().Add(g.NodeReportTimeout)
|
||||
g.RecalculateTime = time.Now()
|
||||
@ -122,26 +123,32 @@ func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
|
||||
}
|
||||
|
||||
func (g *IG) UpdateLentancy(u, v config.Vertex, dt time.Duration, checkchange bool) (changed bool) {
|
||||
g.edgelock.Lock()
|
||||
g.Vert[u] = true
|
||||
g.Vert[v] = true
|
||||
g.edgelock.Unlock()
|
||||
w := float64(dt) / float64(time.Second)
|
||||
if _, ok := g.Edges[u]; !ok {
|
||||
g.Edges[u] = make(map[config.Vertex]Latency)
|
||||
if _, ok := g.edges[u]; !ok {
|
||||
g.edgelock.Lock()
|
||||
g.edges[u] = make(map[config.Vertex]Latency)
|
||||
g.edgelock.Unlock()
|
||||
}
|
||||
if g.ShouldUpdate(u, v, w) {
|
||||
changed = g.RecalculateNhTable(checkchange)
|
||||
}
|
||||
g.Edges[u][v] = Latency{
|
||||
g.edgelock.Lock()
|
||||
g.edges[u][v] = Latency{
|
||||
ping: w,
|
||||
time: time.Now(),
|
||||
}
|
||||
g.edgelock.Unlock()
|
||||
return
|
||||
}
|
||||
func (g IG) Vertices() map[config.Vertex]bool {
|
||||
return g.Vert
|
||||
}
|
||||
func (g IG) Neighbors(v config.Vertex) (vs []config.Vertex) {
|
||||
for k := range g.Edges[v] {
|
||||
for k := range g.edges[v] {
|
||||
vs = append(vs, k)
|
||||
}
|
||||
return vs
|
||||
@ -158,17 +165,19 @@ func (g IG) Next(u, v config.Vertex) *config.Vertex {
|
||||
}
|
||||
|
||||
func (g IG) Weight(u, v config.Vertex) float64 {
|
||||
if _, ok := g.Edges[u]; !ok {
|
||||
g.Edges[u] = make(map[config.Vertex]Latency)
|
||||
if _, ok := g.edges[u]; !ok {
|
||||
g.edgelock.Lock()
|
||||
g.edges[u] = make(map[config.Vertex]Latency)
|
||||
g.edgelock.Unlock()
|
||||
return Infinity
|
||||
}
|
||||
if _, ok := g.Edges[u][v]; !ok {
|
||||
if _, ok := g.edges[u][v]; !ok {
|
||||
return Infinity
|
||||
}
|
||||
if time.Now().After(g.Edges[u][v].time.Add(g.NodeReportTimeout)) {
|
||||
if time.Now().After(g.edges[u][v].time.Add(g.NodeReportTimeout)) {
|
||||
return Infinity
|
||||
}
|
||||
return g.Edges[u][v].ping
|
||||
return g.edges[u][v].ping
|
||||
}
|
||||
|
||||
func FloydWarshall(g Graph) (dist config.DistTable, next config.NextHopTable) {
|
||||
|
Loading…
Reference in New Issue
Block a user