bunch of bugfix, supermode OK

This commit is contained in:
KusakabeSi
2021-08-21 14:54:24 +00:00
parent 4939f9f0c4
commit 19fe84cf0c
13 changed files with 403 additions and 201 deletions

View File

@ -8,6 +8,8 @@ all: generate-version-and-build
MAKEFLAGS += --no-print-directory MAKEFLAGS += --no-print-directory
generate-version-and-build: generate-version-and-build:
go mod download && \
go mod tidy && \
@export GIT_CEILING_DIRECTORIES="$(realpath $(CURDIR)/..)" && \ @export GIT_CEILING_DIRECTORIES="$(realpath $(CURDIR)/..)" && \
tag="$$(git describe --dirty 2>/dev/null)" && \ tag="$$(git describe --dirty 2>/dev/null)" && \
ver="$$(printf 'package main\n\nconst Version = "%s"\n' "$$tag")" && \ ver="$$(printf 'package main\n\nconst Version = "%s"\n' "$$tag")" && \

View File

@ -18,6 +18,7 @@ type SuperConfig struct {
PrivKeyV6 string PrivKeyV6 string
ListenPort int ListenPort int
LogLevel LoggerInfo LogLevel LoggerInfo
RePushConfigInterval float64
GraphRecalculateSetting GraphRecalculateSetting GraphRecalculateSetting GraphRecalculateSetting
Peers []PeerInfo Peers []PeerInfo
} }
@ -36,6 +37,7 @@ type InterfaceConf struct {
type PeerInfo struct { type PeerInfo struct {
NodeID Vertex NodeID Vertex
PubKey string PubKey string
PSKey string
EndPoint string EndPoint string
Static bool Static bool
} }
@ -43,6 +45,7 @@ type PeerInfo struct {
type LoggerInfo struct { type LoggerInfo struct {
LogLevel string LogLevel string
LogTransit bool LogTransit bool
LogControl bool
} }
// Nonnegative integer ID of vertex // Nonnegative integer ID of vertex
@ -100,4 +103,3 @@ type HTTP_Peerinfo struct {
type HTTP_Peers struct { type HTTP_Peers struct {
Peers map[string]HTTP_Peerinfo Peers map[string]HTTP_Peerinfo
} }

View File

@ -155,11 +155,11 @@ again:
} }
} }
var fns []ReceiveFunc var fns []ReceiveFunc
if sock4 != -1 { if sock4 != -1 && bind.use4 {
bind.sock4 = sock4 bind.sock4 = sock4
fns = append(fns, bind.receiveIPv4) fns = append(fns, bind.receiveIPv4)
} }
if sock6 != -1 { if sock6 != -1 && bind.use6 {
bind.sock6 = sock6 bind.sock6 = sock6
fns = append(fns, bind.receiveIPv6) fns = append(fns, bind.receiveIPv6)
} }

View File

@ -81,11 +81,13 @@ type Device struct {
indexTable IndexTable indexTable IndexTable
cookieChecker CookieChecker cookieChecker CookieChecker
MsgCount uint32
IsSuperNode bool IsSuperNode bool
ID config.Vertex ID config.Vertex
graph *path.IG graph *path.IG
l2fib map[tap.MacAddress]config.Vertex l2fib map[tap.MacAddress]config.Vertex
LogTransit bool LogTransit bool
LogControl bool
DRoute config.DynamicRouteInfo DRoute config.DynamicRouteInfo
DupData fixed_time_cache.Cache DupData fixed_time_cache.Cache
@ -302,7 +304,7 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
return nil 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 := new(Device)
device.state.state = uint32(deviceStateDown) device.state.state = uint32(deviceStateDown)
device.closed = make(chan struct{}) 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.tap.mtu = int32(mtu)
device.peers.keyMap = make(map[NoisePublicKey]*Peer) device.peers.keyMap = make(map[NoisePublicKey]*Peer)
device.peers.IDMap = make(map[config.Vertex]*Peer) device.peers.IDMap = make(map[config.Vertex]*Peer)
device.peers.SuperPeer = make(map[NoisePublicKey]*Peer)
device.IsSuperNode = IsSuperNode device.IsSuperNode = IsSuperNode
device.ID = id device.ID = id
device.graph = graph 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_pong = superevents.Event_server_pong
device.Event_server_register = superevents.Event_server_register device.Event_server_register = superevents.Event_server_register
device.Event_server_NhTable_changed = superevents.Event_server_NhTable_changed device.Event_server_NhTable_changed = superevents.Event_server_NhTable_changed
device.LogTransit = sconfig.LogLevel.LogTransit
device.LogControl = sconfig.LogLevel.LogControl
go device.RoutineRecalculateNhTable() go device.RoutineRecalculateNhTable()
} else { } else {
device.EdgeConfigPath = theconfigpath device.EdgeConfigPath = theconfigpath
device.EdgeConfig = theconfig device.EdgeConfig = econfig
device.DRoute = theconfig.DynamicRoute device.DRoute = econfig.DynamicRoute
device.DupData = *fixed_time_cache.NewCache(path.S2TD(theconfig.DynamicRoute.DupCheckTimeout)) device.DupData = *fixed_time_cache.NewCache(path.S2TD(econfig.DynamicRoute.DupCheckTimeout))
device.event_tryendpoint = make(chan struct{}, 1<<6) device.event_tryendpoint = make(chan struct{}, 1<<6)
device.Event_save_config = make(chan struct{}, 1<<5) device.Event_save_config = make(chan struct{}, 1<<5)
device.LogTransit = econfig.LogLevel.LogTransit
device.LogControl = econfig.LogLevel.LogControl
go device.RoutineSetEndpoint() go device.RoutineSetEndpoint()
go device.RoutineRegister() go device.RoutineRegister()
go device.RoutineSendPing() go device.RoutineSendPing()

View File

@ -7,8 +7,10 @@ package device
import ( import (
"container/list" "container/list"
"encoding/base64"
"errors" "errors"
"fmt" "fmt"
"strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -88,6 +90,9 @@ func (device *Device) NewPeer(pk NoisePublicKey, id config.Vertex) (*Peer, error
} }
// create peer // 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 := new(Peer)
peer.Lock() peer.Lock()
defer peer.Unlock() 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.outbound = newAutodrainingOutboundQueue(device)
peer.queue.inbound = newAutodrainingInboundQueue(device) peer.queue.inbound = newAutodrainingInboundQueue(device)
peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize) peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize)
peer.endpoint_trylist = make(map[string]time.Time)
// map public key // map public key
_, ok := device.peers.keyMap[pk] _, ok := device.peers.keyMap[pk]
@ -122,8 +128,8 @@ func (device *Device) NewPeer(pk NoisePublicKey, id config.Vertex) (*Peer, error
// add // add
if id == path.SuperNodeMessage { // To communicate with supernode if id == path.SuperNodeMessage { // To communicate with supernode
device.peers.SuperPeer[pk] = peer device.peers.SuperPeer[pk] = peer
device.peers.keyMap[pk] = peer
} else { // Regular peer, other edgenodes } else { // Regular peer, other edgenodes
_, ok = device.peers.IDMap[id]
device.peers.keyMap[pk] = peer device.peers.keyMap[pk] = peer
device.peers.IDMap[id] = peer device.peers.IDMap[id] = peer
} }
@ -288,6 +294,12 @@ func (peer *Peer) Stop() {
peer.ZeroAndFlushAll() 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) { func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
if peer.disableRoaming { if peer.disableRoaming {
return return
@ -298,9 +310,15 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
} }
func (peer *Peer) GetEndpointSrcStr() string { func (peer *Peer) GetEndpointSrcStr() string {
if peer.endpoint == nil {
return ""
}
return peer.endpoint.SrcToString() return peer.endpoint.SrcToString()
} }
func (peer *Peer) GetEndpointDstStr() string { func (peer *Peer) GetEndpointDstStr() string {
if peer.endpoint == nil {
return ""
}
return peer.endpoint.DstToString() return peer.endpoint.DstToString()
} }

View File

@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
"strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -410,7 +411,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
if elem == nil { if elem == nil {
return return
} }
var EgBody path.EgHeader var EgHeader path.EgHeader
var err error var err error
var src_nodeID config.Vertex var src_nodeID config.Vertex
var dst_nodeID config.Vertex var dst_nodeID config.Vertex
@ -445,11 +446,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
} }
peer.timersDataReceived() peer.timersDataReceived()
EgBody, err = path.NewEgHeader(elem.packet[0:path.EgHeaderLen]) EgHeader, err = path.NewEgHeader(elem.packet[0:path.EgHeaderLen]) // EG header
src_nodeID = EgBody.GetSrc() src_nodeID = EgHeader.GetSrc()
dst_nodeID = EgBody.GetDst() dst_nodeID = EgHeader.GetDst()
elem.packet = elem.packet[:EgBody.GetPacketLength()] elem.packet = elem.packet[:EgHeader.GetPacketLength()+path.EgHeaderLen] // EG header + true packet
packet_type = EgBody.GetUsage() packet_type = EgHeader.GetUsage()
if device.IsSuperNode { if device.IsSuperNode {
peer.LastPingReceived = time.Now() peer.LastPingReceived = time.Now()
@ -472,7 +473,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
case path.SuperNodeMessage: case path.SuperNodeMessage:
should_process = true should_process = true
case path.ControlMessage: case path.ControlMessage:
packet := elem.packet[path.EgHeaderLen:] packet := elem.packet[path.EgHeaderLen:] //true packet
if device.CheckNoDup(packet) { if device.CheckNoDup(packet) {
should_process = true should_process = true
should_transfer = true should_transfer = true
@ -498,11 +499,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
} }
} }
if should_transfer { if should_transfer {
l2ttl := EgBody.GetTTL() l2ttl := EgHeader.GetTTL()
if l2ttl == 0 { if l2ttl == 0 {
device.log.Verbosef("TTL is 0 %v", dst_nodeID) device.log.Verbosef("TTL is 0 %v", dst_nodeID)
} else { } else {
EgBody.SetTTL(l2ttl - 1) EgHeader.SetTTL(l2ttl - 1)
if dst_nodeID == path.Boardcast { //Regular transfer algorithm if dst_nodeID == path.Boardcast { //Regular transfer algorithm
device.TransitBoardcastPacket(src_nodeID, peer.ID, elem.packet, MessageTransportOffsetContent) 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 } 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 should_process {
if packet_type != path.NornalPacket { 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())
}
} }
} }

View File

@ -8,6 +8,8 @@ import (
"hash/crc32" "hash/crc32"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url"
"strconv"
"time" "time"
"github.com/KusakabeSi/EtherGuardVPN/config" "github.com/KusakabeSi/EtherGuardVPN/config"
@ -19,6 +21,16 @@ func (device *Device) SendPacket(peer *Peer, packet []byte, offset int) {
if peer == nil { if peer == nil {
return 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 var elem *QueueOutboundElement
elem = device.NewOutboundElement() elem = device.NewOutboundElement()
copy(elem.buffer[offset:offset+len(packet)], packet) 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 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 { func (device *Device) server_process_RegisterMsg(content path.RegisterMsg) error {
device.Event_server_register <- content device.Event_server_register <- content
return nil return nil
@ -161,6 +209,7 @@ func (device *Device) process_ping(content path.PingMsg) error {
header.SetTTL(200) header.SetTTL(200)
header.SetUsage(path.PongPacket) header.SetUsage(path.PongPacket)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
copy(buf[path.EgHeaderLen:], body)
if device.DRoute.SuperNode.UseSuperNode { if device.DRoute.SuperNode.UseSuperNode {
header.SetDst(path.SuperNodeMessage) header.SetDst(path.SuperNodeMessage)
device.Send2Super(buf, MessageTransportOffsetContent) 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[:]) { if bytes.Equal(device.peers.Peer_state[:], content.State_hash[:]) {
return nil 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 { if err != nil {
return err return err
} }
@ -263,6 +317,9 @@ func (device *Device) RoutineSetEndpoint() {
device.log.Errorf("Can't bind " + url) device.log.Errorf("Can't bind " + url)
delete(thepeer.endpoint_trylist, 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) thepeer.SetEndpointFromPacket(endpoint)
NextRun = true NextRun = true
thepeer.endpoint_trylist[url] = time.Now() thepeer.endpoint_trylist[url] = time.Now()
@ -312,9 +369,11 @@ func (device *Device) RoutineRegister() {
if !(device.DRoute.SuperNode.UseSuperNode) { if !(device.DRoute.SuperNode.UseSuperNode) {
return return
} }
first := true
for { for {
body, _ := path.GetByte(path.RegisterMsg{ body, _ := path.GetByte(path.RegisterMsg{
Node_id: device.ID, Node_id: device.ID,
Init: first,
}) })
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen])
@ -326,6 +385,7 @@ func (device *Device) RoutineRegister() {
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)
device.Send2Super(buf, MessageTransportOffsetContent) device.Send2Super(buf, MessageTransportOffsetContent)
time.Sleep(path.S2TD(device.DRoute.SendPingInterval)) time.Sleep(path.S2TD(device.DRoute.SendPingInterval))
first = false
} }
} }
@ -343,7 +403,6 @@ func (device *Device) RoutineRecalculateNhTable() {
return return
} }
for { for {
device.graph.RecalculateNhTable(false) device.graph.RecalculateNhTable(false)
time.Sleep(device.graph.NodeReportTimeout) 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[:]) { if bytes.Equal(device.graph.NhTableHash[:], content.State_hash[:]) {
return nil 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 { if err != nil {
return err return err
} }
@ -407,11 +470,11 @@ func (device *Device) process_RequestPeerMsg(content path.RequestPeerMsg) error
} }
response := path.BoardcastPeerMsg{ response := path.BoardcastPeerMsg{
RequestID: content.Request_ID, Request_ID: content.Request_ID,
NodeID: peer.ID, NodeID: peer.ID,
PubKey: pubkey, PubKey: pubkey,
PSKey: peer.handshake.presharedKey, PSKey: peer.handshake.presharedKey,
ConnURL: peer.endpoint.DstToString(), ConnURL: peer.endpoint.DstToString(),
} }
body, err := path.GetByte(response) body, err := path.GetByte(response)
if err != nil { if err != nil {

View File

@ -183,8 +183,7 @@ func Edge(configPath string, useUAPI bool, printExample bool) (err error) {
graph := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting) graph := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting)
graph.SetNHTable(tconfig.NextHopTable, [32]byte{}) graph.SetNHTable(tconfig.NextHopTable, [32]byte{})
the_device := device.NewDevice(thetap, tconfig.NodeID, conn.NewDefaultBind(), logger, &graph, false, configPath, &tconfig, nil) the_device := device.NewDevice(thetap, tconfig.NodeID, conn.NewDefaultBind(), logger, graph, false, configPath, &tconfig, nil, nil)
the_device.LogTransit = tconfig.LogLevel.LogTransit
defer the_device.Close() defer the_device.Close()
var sk [32]byte var sk [32]byte
sk_slice, _ := base64.StdEncoding.DecodeString(tconfig.PrivKey) sk_slice, _ := base64.StdEncoding.DecodeString(tconfig.PrivKey)

View File

@ -15,8 +15,8 @@ var (
http_graph *path.IG http_graph *path.IG
http_device4 *device.Device http_device4 *device.Device
http_device6 *device.Device http_device6 *device.Device
http_NhTable_Hash string http_NhTable_Hash [32]byte
http_PeerInfo_hash string http_PeerInfo_hash [32]byte
http_NhTableStr []byte http_NhTableStr []byte
http_PeerInfoStr []byte http_PeerInfoStr []byte
http_PeerState map[string]*PeerState http_PeerState map[string]*PeerState
@ -25,8 +25,8 @@ var (
) )
type PeerState struct { type PeerState struct {
NhTableState string NhTableState [32]byte
PeerInfoState string PeerInfoState [32]byte
} }
type client struct { type client struct {
@ -43,7 +43,7 @@ func get_peerinfo(w http.ResponseWriter, r *http.Request) {
PubKey, _ := params["PubKey"] PubKey, _ := params["PubKey"]
State, _ := params["State"] State, _ := params["State"]
if state := http_PeerState[PubKey[0]]; state != nil { 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.WriteHeader(http.StatusOK)
w.Write([]byte(http_PeerInfoStr)) w.Write([]byte(http_PeerInfoStr))
@ -54,19 +54,18 @@ func get_nhtable(w http.ResponseWriter, r *http.Request) {
PubKey, _ := params["PubKey"] PubKey, _ := params["PubKey"]
State, _ := params["State"] State, _ := params["State"]
if state := http_PeerState[PubKey[0]]; state != nil { 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.WriteHeader(http.StatusOK)
w.Write([]byte(http_NhTableStr)) w.Write([]byte(http_NhTableStr))
} }
func HttpServer(http_port int, apiprefix string, graph *path.IG, device4 *device.Device, device6 *device.Device) { func HttpServer(http_port int, apiprefix string) {
http_graph = graph
http_device4 = device4
http_device6 = device6
http_PeerState = make(map[string]*PeerState)
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("/"+apiprefix+"/peerinfo", get_peerinfo) if apiprefix[0] != '/' {
mux.HandleFunc("/"+apiprefix+"/nhtable", get_nhtable) apiprefix = "/" + apiprefix
go http.ListenAndServe(":"+strconv.Itoa(http_port), mux) }
mux.HandleFunc(apiprefix+"/peerinfo", get_peerinfo)
mux.HandleFunc(apiprefix+"/nhtable", get_nhtable)
http.ListenAndServe(":"+strconv.Itoa(http_port), mux)
} }

View File

@ -8,6 +8,7 @@
package main package main
import ( import (
"bytes"
"crypto/md5" "crypto/md5"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
@ -19,6 +20,7 @@ import (
"os/signal" "os/signal"
"strconv" "strconv"
"syscall" "syscall"
"time"
"github.com/KusakabeSi/EtherGuardVPN/config" "github.com/KusakabeSi/EtherGuardVPN/config"
"github.com/KusakabeSi/EtherGuardVPN/conn" "github.com/KusakabeSi/EtherGuardVPN/conn"
@ -92,6 +94,10 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
fmt.Sprintf("(%s) ", interfaceName+"_v6"), 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{ super_chains := path.SUPER_Events{
Event_server_pong: make(chan path.PongMsg, 1<<5), Event_server_pong: make(chan path.PongMsg, 1<<5),
Event_server_register: make(chan path.RegisterMsg, 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() thetap, _ := tap.CreateDummyTAP()
graph := path.NewGraph(3, true, sconfig.GraphRecalculateSetting) http_graph = path.NewGraph(3, true, sconfig.GraphRecalculateSetting)
device_v4 := device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(true, false), logger4, &graph, true, "", nil, &super_chains) http_device4 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(true, false), logger4, http_graph, true, "", nil, &sconfig, &super_chains)
device_v6 := device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(false, true), logger6, &graph, true, "", nil, &super_chains) http_device6 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(false, true), logger6, http_graph, true, "", nil, &sconfig, &super_chains)
defer device_v4.Close() defer http_device4.Close()
defer device_v6.Close() defer http_device6.Close()
var sk [32]byte var sk [32]byte
sk_slice, _ := base64.StdEncoding.DecodeString(sconfig.PrivKeyV4) sk_slice, _ := base64.StdEncoding.DecodeString(sconfig.PrivKeyV4)
copy(sk[:], sk_slice) copy(sk[:], sk_slice)
device_v4.SetPrivateKey(sk) http_device4.SetPrivateKey(sk)
sk_slice, _ = base64.StdEncoding.DecodeString(sconfig.PrivKeyV6) sk_slice, _ = base64.StdEncoding.DecodeString(sconfig.PrivKeyV6)
copy(sk[:], sk_slice) copy(sk[:], sk_slice)
device_v6.SetPrivateKey(sk) http_device6.SetPrivateKey(sk)
device_v4.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n") http_device4.IpcSet("fwmark=0\n")
device_v6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n") http_device6.IpcSet("fwmark=0\n")
device_v4.IpcSet("replace_peers=true\n") http_device4.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
device_v6.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 { for _, peerconf := range sconfig.Peers {
sk_slice, _ = base64.StdEncoding.DecodeString(peerconf.PubKey) var pk device.NoisePublicKey
copy(sk[:], sk_slice)
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 { if peerconf.NodeID >= path.SuperNodeMessage {
return errors.New(fmt.Sprintf("Invalid Node_id at peer %s\n", peerconf.PubKey)) return errors.New(fmt.Sprintf("Invalid Node_id at peer %s\n", peerconf.PubKey))
} }
device_v4.NewPeer(sk, peerconf.NodeID) http_PeerID2Map[peerconf.NodeID] = peerconf.PubKey
device_v6.NewPeer(sk, peerconf.NodeID) 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{} http_PeerState[peerconf.PubKey] = &PeerState{}
} }
logger4.Verbosef("Device started") logger4.Verbosef("Device started")
@ -131,12 +161,12 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
errs := make(chan error, 1<<3) errs := make(chan error, 1<<3)
term := make(chan os.Signal, 1) term := make(chan os.Signal, 1)
if useUAPI { if useUAPI {
uapi4, err := startUAPI(interfaceName+"_v4", logger4, device_v4, errs) uapi4, err := startUAPI(interfaceName+"_v4", logger4, http_device4, errs)
if err != nil { if err != nil {
return err return err
} }
defer uapi4.Close() defer uapi4.Close()
uapi6, err := startUAPI(interfaceName+"_v6", logger6, device_v6, errs) uapi6, err := startUAPI(interfaceName+"_v6", logger6, http_device6, errs)
if err != nil { if err != nil {
return err return err
} }
@ -145,106 +175,131 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
signal.Notify(term, syscall.SIGTERM) signal.Notify(term, syscall.SIGTERM)
signal.Notify(term, os.Interrupt) 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 { select {
case <-term: case <-term:
case <-errs: case <-errs:
case <-device_v4.Wait(): case <-http_device4.Wait():
case <-device_v6.Wait(): case <-http_device6.Wait():
} }
logger4.Verbosef("Shutting down") logger4.Verbosef("Shutting down")
return 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 { for {
pongmsg := <-events.Event_server_pong select {
changed := graph.UpdateLentancy(pongmsg.Src_nodeID, pongmsg.Dst_nodeID, pongmsg.Timediff, true) case reg_msg := <-events.Event_server_register:
if changed { 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) NhTable := graph.GetNHTable(false)
NhTablestr, _ := json.Marshal(NhTable) NhTablestr, _ := json.Marshal(NhTable)
md5_hash_raw := md5.Sum(http_NhTableStr) md5_hash_raw := md5.Sum(http_NhTableStr)
new_hash := hex.EncodeToString(md5_hash_raw[:]) new_hash_str := hex.EncodeToString(md5_hash_raw[:])
if http_NhTable_Hash != new_hash { new_hash_str_byte := []byte(new_hash_str)
http_NhTable_Hash = new_hash 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_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 http_NhTableStr = NhTablestr
NhTable_Hash_fixbyte := [32]byte{} PushNhTable()
copy(NhTable_Hash_fixbyte[:], []byte(http_NhTable_Hash))
body, err := path.GetByte(path.UpdateNhTableMsg{
State_hash: NhTable_Hash_fixbyte,
})
if err != nil {
fmt.Println("Error get byte")
continue
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(path.SuperNodeMessage)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(path.SuperNodeMessage)
header.SetTTL(0)
header.SetUsage(path.UpdateNhTable)
copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range http_PeerState {
if peerstate.NhTableState != http_NhTable_Hash {
if peer := http_device4.LookupPeerByStr(pkstr); peer != nil {
http_device4.SendPacket(peer, buf, device.MessageTransportOffsetContent)
}
if peer := http_device6.LookupPeerByStr(pkstr); peer != nil {
http_device6.SendPacket(peer, buf, device.MessageTransportOffsetContent)
}
}
}
} }
} }
} }
} }
func Event_server_register_hendler(raph path.IG, events path.SUPER_Events) { func RoutinePushSettings(interval time.Duration) {
for { for {
reg_msg := <-events.Event_server_register time.Sleep(interval)
PubKey := http_PeerID2Map[reg_msg.Node_id] PushNhTable()
if peer := http_device4.LookupPeerByStr(PubKey); peer != nil { PushUpdate()
if connstr := peer.GetEndpointDstStr(); connstr != "" { }
http_PeerInfos.Peers[PubKey].Connurl[connstr] = true }
func PushNhTable() {
body, err := path.GetByte(path.UpdateNhTableMsg{
State_hash: http_NhTable_Hash,
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(path.SuperNodeMessage)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(path.SuperNodeMessage)
header.SetTTL(0)
header.SetUsage(path.UpdateNhTable)
copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range http_PeerState {
if peerstate.NhTableState != http_NhTable_Hash {
if peer := http_device4.LookupPeerByStr(pkstr); peer != nil {
http_device4.SendPacket(peer, buf, device.MessageTransportOffsetContent)
}
if peer := http_device6.LookupPeerByStr(pkstr); peer != nil {
http_device6.SendPacket(peer, buf, device.MessageTransportOffsetContent)
} }
} }
if peer := http_device6.LookupPeerByStr(PubKey); peer != nil { }
if connstr := peer.GetEndpointDstStr(); connstr != "" { }
http_PeerInfos.Peers[PubKey].Connurl[connstr] = true
func PushUpdate() {
body, err := path.GetByte(path.UpdatePeerMsg{
State_hash: http_PeerInfo_hash,
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(path.SuperNodeMessage)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(path.SuperNodeMessage)
header.SetTTL(0)
header.SetUsage(path.UpdatePeer)
copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range http_PeerState {
if peerstate.PeerInfoState != http_PeerInfo_hash {
if peer := http_device4.LookupPeerByStr(pkstr); peer != nil {
http_device4.SendPacket(peer, buf, device.MessageTransportOffsetContent)
} }
} if peer := http_device6.LookupPeerByStr(pkstr); peer != nil {
http_PeerInfoStr, _ = json.Marshal(&http_PeerInfos) http_device6.SendPacket(peer, buf, device.MessageTransportOffsetContent)
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
body, err := path.GetByte(path.UpdatePeerMsg{
State_hash: http_PeerInfo_hash_fixbyte,
})
if err != nil {
fmt.Println("Error get byte")
continue
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(path.SuperNodeMessage)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(path.SuperNodeMessage)
header.SetTTL(0)
header.SetUsage(path.UpdatePeer)
copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range http_PeerState {
if peerstate.PeerInfoState != PeerInfo_hash {
if peer := http_device4.LookupPeerByStr(pkstr); peer != nil {
http_device4.SendPacket(peer, buf, device.MessageTransportOffsetContent)
}
if peer := http_device6.LookupPeerByStr(pkstr); peer != nil {
http_device6.SendPacket(peer, buf, device.MessageTransportOffsetContent)
}
}
} }
} }
} }

View File

@ -7,7 +7,7 @@ import (
"github.com/KusakabeSi/EtherGuardVPN/config" "github.com/KusakabeSi/EtherGuardVPN/config"
) )
const EgHeaderLen = 12 const EgHeaderLen = 16
type EgHeader struct { type EgHeader struct {
buf []byte buf []byte
@ -72,3 +72,10 @@ func (e EgHeader) GetPacketLength() uint16 {
func (e EgHeader) SetPacketLength(length uint16) { func (e EgHeader) SetPacketLength(length uint16) {
binary.BigEndian.PutUint16(e.buf[10:12], length) 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)
}

View File

@ -3,6 +3,7 @@ package path
import ( import (
"bytes" "bytes"
"encoding/gob" "encoding/gob"
"strconv"
"time" "time"
"github.com/KusakabeSi/EtherGuardVPN/config" "github.com/KusakabeSi/EtherGuardVPN/config"
@ -19,94 +20,125 @@ func GetByte(structIn interface{}) (bb []byte, err error) {
} }
type RegisterMsg struct { type RegisterMsg struct {
Node_id config.Vertex Node_id config.Vertex `struc:"uint32"`
Init bool
} }
func ParseRegisterMsg(bin []byte) (RegisterMsg, error) { func (c *RegisterMsg) ToString() string {
var StructPlace RegisterMsg return "RegisterMsg Node_id:" + strconv.Itoa(int(c.Node_id))
}
func ParseRegisterMsg(bin []byte) (StructPlace RegisterMsg, err error) {
var b bytes.Buffer var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type UpdatePeerMsg struct { type UpdatePeerMsg struct {
State_hash [32]byte State_hash [32]byte `struc:"[32]uint8"`
} }
func ParseUpdatePeerMsg(bin []byte) (UpdatePeerMsg, error) { func (c *UpdatePeerMsg) ToString() string {
var StructPlace UpdatePeerMsg return "UpdatePeerMsg State_hash:" + string(c.State_hash[:])
}
func ParseUpdatePeerMsg(bin []byte) (StructPlace UpdatePeerMsg, err error) {
var b bytes.Buffer var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type UpdateNhTableMsg struct { type UpdateNhTableMsg struct {
State_hash [32]byte State_hash [32]byte `struc:"[32]uint8"`
} }
func ParseUpdateNhTableMsg(bin []byte) (UpdateNhTableMsg, error) { func (c *UpdateNhTableMsg) ToString() string {
var StructPlace UpdateNhTableMsg return "UpdateNhTableMsg State_hash:" + string(c.State_hash[:])
}
func ParseUpdateNhTableMsg(bin []byte) (StructPlace UpdateNhTableMsg, err error) {
var b bytes.Buffer var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type PingMsg struct { type PingMsg struct {
Src_nodeID config.Vertex RequestID uint32 `struc:"uint32"`
Time time.Time Src_nodeID config.Vertex `struc:"uint32"`
Time time.Time `struc:"uint64"`
} }
func ParsePingMsg(bin []byte) (PingMsg, error) { func (c *PingMsg) ToString() string {
var StructPlace PingMsg 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 var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type PongMsg struct { type PongMsg struct {
Src_nodeID config.Vertex RequestID uint32
Dst_nodeID config.Vertex Src_nodeID config.Vertex `struc:"uint32"`
Timediff time.Duration Dst_nodeID config.Vertex `struc:"uint32"`
Timediff time.Duration `struc:"int64"`
} }
func ParsePongMsg(bin []byte) (PongMsg, error) { func (c *PongMsg) ToString() string {
var StructPlace PongMsg 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 var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type RequestPeerMsg struct { type RequestPeerMsg struct {
Request_ID uint32 Request_ID uint32 `struc:"uint32"`
} }
func ParseRequestPeerMsg(bin []byte) (RequestPeerMsg, error) { func (c *RequestPeerMsg) ToString() string {
var StructPlace RequestPeerMsg return "RequestPeerMsg Request_ID:" + strconv.Itoa(int(c.Request_ID))
}
func ParseRequestPeerMsg(bin []byte) (StructPlace RequestPeerMsg, err error) {
var b bytes.Buffer var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type BoardcastPeerMsg struct { type BoardcastPeerMsg struct {
RequestID uint32 Request_ID uint32 `struc:"uint32"`
NodeID config.Vertex NodeID config.Vertex `struc:"uint32"`
PubKey [32]byte PubKey [32]byte `struc:"[32]uint8"`
PSKey [32]byte PSKey [32]byte `struc:"[32]uint8"`
ConnURL string ConnURL string
} }
func ParseBoardcastPeerMsg(bin []byte) (BoardcastPeerMsg, error) { func (c *BoardcastPeerMsg) ToString() string {
var StructPlace BoardcastPeerMsg 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 var b bytes.Buffer
b.Write(bin)
d := gob.NewDecoder(&b) d := gob.NewDecoder(&b)
err := d.Decode(&StructPlace) err = d.Decode(&StructPlace)
return StructPlace, err return
} }
type SUPER_Events struct { type SUPER_Events struct {

View File

@ -3,6 +3,7 @@ package path
import ( import (
"fmt" "fmt"
"math" "math"
"sync"
"time" "time"
"github.com/KusakabeSi/EtherGuardVPN/config" "github.com/KusakabeSi/EtherGuardVPN/config"
@ -20,7 +21,7 @@ const (
) )
func (g *IG) GetCurrentTime() time.Time { func (g *IG) GetCurrentTime() time.Time {
return time.Now() return time.Now().Round(0)
} }
// A Graph is the interface implemented by graphs that // 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. // IG is a graph of integers that satisfies the Graph interface.
type IG struct { type IG struct {
Vert map[config.Vertex]bool 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 JitterTolerance float64
JitterToleranceMultiplier float64 JitterToleranceMultiplier float64
NodeReportTimeout time.Duration NodeReportTimeout time.Duration
@ -62,7 +64,7 @@ func S2TD(secs float64) time.Duration {
return time.Duration(secs * float64(time.Second)) 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{ g := IG{
JitterTolerance: theconfig.JitterTolerance, JitterTolerance: theconfig.JitterTolerance,
JitterToleranceMultiplier: theconfig.JitterToleranceMultiplier, JitterToleranceMultiplier: theconfig.JitterToleranceMultiplier,
@ -70,10 +72,10 @@ func NewGraph(num_node int, IsSuperMode bool, theconfig config.GraphRecalculateS
RecalculateCoolDown: S2TD(theconfig.RecalculateCoolDown), RecalculateCoolDown: S2TD(theconfig.RecalculateCoolDown),
} }
g.Vert = make(map[config.Vertex]bool, num_node) 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 g.IsSuperMode = IsSuperMode
return g return &g
} }
func (g *IG) GetWeightType(x float64) float64 { 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 oldval := g.Weight(u, v) * 1000
newval *= 1000 newval *= 1000
if g.IsSuperMode { if g.IsSuperMode {
return (oldval-newval)*(oldval*g.JitterToleranceMultiplier) <= g.JitterTolerance return (oldval-newval)*(oldval*g.JitterToleranceMultiplier) >= g.JitterTolerance
} else { } else {
return g.GetWeightType(oldval) == g.GetWeightType(newval) return g.GetWeightType(oldval) == g.GetWeightType(newval)
} }
@ -100,16 +102,15 @@ func (g *IG) ShouldUpdate(u config.Vertex, v config.Vertex, newval float64) bool
func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) { func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
if g.RecalculateTime.Add(g.RecalculateCoolDown).Before(time.Now()) { if g.RecalculateTime.Add(g.RecalculateCoolDown).Before(time.Now()) {
dist, next := FloydWarshall(g) dist, next := FloydWarshall(g)
changed = false
if checkchange { if checkchange {
CheckLoop: CheckLoop:
for src, dsts := range next { for src, dsts := range next {
for dst, cost := range dsts { for dst, old_next := range dsts {
nexthop := g.Next(src, dst) nexthop := g.Next(src, dst)
if nexthop != nil { if old_next != nexthop {
changed = cost == nexthop changed = true
if changed { break CheckLoop
break CheckLoop
}
} }
} }
} }
@ -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) { func (g *IG) UpdateLentancy(u, v config.Vertex, dt time.Duration, checkchange bool) (changed bool) {
g.edgelock.Lock()
g.Vert[u] = true g.Vert[u] = true
g.Vert[v] = true g.Vert[v] = true
g.edgelock.Unlock()
w := float64(dt) / float64(time.Second) w := float64(dt) / float64(time.Second)
if _, ok := g.Edges[u]; !ok { if _, ok := g.edges[u]; !ok {
g.Edges[u] = make(map[config.Vertex]Latency) g.edgelock.Lock()
g.edges[u] = make(map[config.Vertex]Latency)
g.edgelock.Unlock()
} }
if g.ShouldUpdate(u, v, w) { if g.ShouldUpdate(u, v, w) {
changed = g.RecalculateNhTable(checkchange) changed = g.RecalculateNhTable(checkchange)
} }
g.Edges[u][v] = Latency{ g.edgelock.Lock()
g.edges[u][v] = Latency{
ping: w, ping: w,
time: time.Now(), time: time.Now(),
} }
g.edgelock.Unlock()
return return
} }
func (g IG) Vertices() map[config.Vertex]bool { func (g IG) Vertices() map[config.Vertex]bool {
return g.Vert return g.Vert
} }
func (g IG) Neighbors(v config.Vertex) (vs []config.Vertex) { 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) vs = append(vs, k)
} }
return vs 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 { func (g IG) Weight(u, v config.Vertex) float64 {
if _, ok := g.Edges[u]; !ok { if _, ok := g.edges[u]; !ok {
g.Edges[u] = make(map[config.Vertex]Latency) g.edgelock.Lock()
g.edges[u] = make(map[config.Vertex]Latency)
g.edgelock.Unlock()
return Infinity return Infinity
} }
if _, ok := g.Edges[u][v]; !ok { if _, ok := g.edges[u][v]; !ok {
return Infinity 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 Infinity
} }
return g.Edges[u][v].ping return g.edges[u][v].ping
} }
func FloydWarshall(g Graph) (dist config.DistTable, next config.NextHopTable) { func FloydWarshall(g Graph) (dist config.DistTable, next config.NextHopTable) {