mirror of
https://github.com/KusakabeShi/EtherGuard-VPN.git
synced 2025-08-08 23:21:27 +02:00
http based pong_msg
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -14,15 +15,18 @@ import (
|
||||
"time"
|
||||
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
"github.com/KusakabeSi/EtherGuardVPN/conn"
|
||||
"github.com/KusakabeSi/EtherGuardVPN/device"
|
||||
"github.com/KusakabeSi/EtherGuardVPN/path"
|
||||
"github.com/golang-jwt/jwt"
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuard-VPN/device"
|
||||
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
|
||||
"github.com/KusakabeSi/EtherGuard-VPN/path"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
type http_shared_objects struct {
|
||||
http_graph *path.IG
|
||||
http_device4 *device.Device
|
||||
http_device6 *device.Device
|
||||
@ -30,36 +34,41 @@ var (
|
||||
http_NhTable_Hash [32]byte
|
||||
http_PeerInfo_hash [32]byte
|
||||
http_NhTableStr []byte
|
||||
http_PeerInfo config.API_Peers
|
||||
http_super_chains *path.SUPER_Events
|
||||
http_PeerInfo mtypes.API_Peers
|
||||
http_super_chains *mtypes.SUPER_Events
|
||||
|
||||
http_passwords config.Passwords
|
||||
http_passwords mtypes.Passwords
|
||||
http_StateExpire time.Time
|
||||
http_StateString_tmp []byte
|
||||
|
||||
http_maps_lock sync.RWMutex
|
||||
http_PeerID2Info map[config.Vertex]config.SuperPeerInfo
|
||||
http_PeerID2Info map[mtypes.Vertex]mtypes.SuperPeerInfo
|
||||
http_PeerState map[string]*PeerState //the state hash reported by peer
|
||||
http_PeerIPs map[string]*HttpPeerLocalIP
|
||||
|
||||
http_sconfig *config.SuperConfig
|
||||
http_sconfig *mtypes.SuperConfig
|
||||
|
||||
http_sconfig_path string
|
||||
http_econfig_tmp *config.EdgeConfig
|
||||
http_econfig_tmp *mtypes.EdgeConfig
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
var (
|
||||
httpobj http_shared_objects
|
||||
)
|
||||
|
||||
type HttpPeerLocalIP struct {
|
||||
IPv4 net.UDPAddr
|
||||
IPv6 net.UDPAddr
|
||||
LocalIPv4 map[string]float64
|
||||
LocalIPv6 map[string]float64
|
||||
}
|
||||
|
||||
type HttpState struct {
|
||||
PeerInfo map[config.Vertex]HttpPeerInfo
|
||||
PeerInfo map[mtypes.Vertex]HttpPeerInfo
|
||||
Infinity float64
|
||||
Edges map[config.Vertex]map[config.Vertex]float64
|
||||
Edges_Nh map[config.Vertex]map[config.Vertex]float64
|
||||
NhTable config.NextHopTable
|
||||
Dist config.DistTable
|
||||
Edges map[mtypes.Vertex]map[mtypes.Vertex]float64
|
||||
Edges_Nh map[mtypes.Vertex]map[mtypes.Vertex]float64
|
||||
NhTable mtypes.NextHopTable
|
||||
Dist mtypes.DistTable
|
||||
}
|
||||
|
||||
type HttpPeerInfo struct {
|
||||
@ -70,6 +79,8 @@ type HttpPeerInfo struct {
|
||||
type PeerState struct {
|
||||
NhTableState [32]byte
|
||||
PeerInfoState [32]byte
|
||||
JETSecret mtypes.JWTSecret
|
||||
httpPostCount uint64
|
||||
LastSeen time.Time
|
||||
}
|
||||
|
||||
@ -82,38 +93,86 @@ type client struct {
|
||||
notify6 string
|
||||
}
|
||||
|
||||
func get_api_peers(old_State_hash [32]byte) (api_peerinfo config.API_Peers, StateHash [32]byte, changed bool) {
|
||||
api_peerinfo = make(config.API_Peers)
|
||||
for _, peerinfo := range http_sconfig.Peers {
|
||||
api_peerinfo[peerinfo.PubKey] = config.API_Peerinfo{
|
||||
func extractParamsStr(params url.Values, key string, w http.ResponseWriter) (string, error) {
|
||||
valA, has := params[key]
|
||||
if !has {
|
||||
errstr := fmt.Sprintf("Paramater %v: Missing paramater.", key)
|
||||
if w != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(errstr))
|
||||
}
|
||||
return "", fmt.Errorf(errstr)
|
||||
}
|
||||
return valA[0], nil
|
||||
}
|
||||
|
||||
func extractParamsFloat(params url.Values, key string, bitSize int, w http.ResponseWriter) (float64, error) {
|
||||
val, err := extractParamsStr(params, key, w)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
ret, err := strconv.ParseFloat(val, 64)
|
||||
if err != nil {
|
||||
errstr := fmt.Sprintf("Paramater %v: Can't convert to type float%v", key, bitSize)
|
||||
if w != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(errstr))
|
||||
}
|
||||
return 0, fmt.Errorf(errstr)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func extractParamsUint(params url.Values, key string, bitSize int, w http.ResponseWriter) (uint64, error) {
|
||||
val, err := extractParamsStr(params, key, w)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
ret, err := strconv.ParseUint(val, 10, bitSize)
|
||||
if err != nil {
|
||||
errstr := fmt.Sprintf("Paramater %v: Can't convert to type uint%v", key, bitSize)
|
||||
if w != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(errstr))
|
||||
}
|
||||
return 0, fmt.Errorf(errstr)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func extractParamsVertex(params url.Values, key string, w http.ResponseWriter) (mtypes.Vertex, error) {
|
||||
val, err := extractParamsUint(params, key, 16, w)
|
||||
if err != nil {
|
||||
return mtypes.BrokenMessage, err
|
||||
}
|
||||
return mtypes.Vertex(val), nil
|
||||
}
|
||||
|
||||
func get_api_peers(old_State_hash [32]byte) (api_peerinfo mtypes.API_Peers, StateHash [32]byte, changed bool) {
|
||||
// No lock
|
||||
api_peerinfo = make(mtypes.API_Peers)
|
||||
for _, peerinfo := range httpobj.http_sconfig.Peers {
|
||||
api_peerinfo[peerinfo.PubKey] = mtypes.API_Peerinfo{
|
||||
NodeID: peerinfo.NodeID,
|
||||
PSKey: peerinfo.PSKey,
|
||||
Connurl: make(map[string]float64),
|
||||
Connurl: &mtypes.API_connurl{},
|
||||
}
|
||||
http_maps_lock.RLock()
|
||||
if http_PeerState[peerinfo.PubKey].LastSeen.Add(path.S2TD(http_sconfig.GraphRecalculateSetting.NodeReportTimeout)).After(time.Now()) {
|
||||
connV4 := http_device4.GetConnurl(peerinfo.NodeID)
|
||||
connV6 := http_device6.GetConnurl(peerinfo.NodeID)
|
||||
api_peerinfo[peerinfo.PubKey].Connurl[connV4] = 4
|
||||
api_peerinfo[peerinfo.PubKey].Connurl[connV6] = 6
|
||||
L4Addr := http_PeerIPs[peerinfo.PubKey].IPv4
|
||||
L4IP := L4Addr.IP
|
||||
L4str := L4Addr.String()
|
||||
if L4str != connV4 && conn.ValidIP(L4IP) {
|
||||
api_peerinfo[peerinfo.PubKey].Connurl[L4str] = 14
|
||||
if httpobj.http_PeerState[peerinfo.PubKey].LastSeen.Add(path.S2TD(httpobj.http_sconfig.GraphRecalculateSetting.NodeReportTimeout)).After(time.Now()) {
|
||||
connV4 := httpobj.http_device4.GetConnurl(peerinfo.NodeID)
|
||||
connV6 := httpobj.http_device6.GetConnurl(peerinfo.NodeID)
|
||||
if connV4 != "" {
|
||||
api_peerinfo[peerinfo.PubKey].Connurl.ExternalV4 = map[string]float64{connV4: 4}
|
||||
}
|
||||
L6Addr := http_PeerIPs[peerinfo.PubKey].IPv6
|
||||
L6IP := L6Addr.IP
|
||||
L6str := L6Addr.String()
|
||||
if L6str != connV6 && conn.ValidIP(L6IP) {
|
||||
api_peerinfo[peerinfo.PubKey].Connurl[L6str] = 16
|
||||
if connV6 != "" {
|
||||
api_peerinfo[peerinfo.PubKey].Connurl.ExternalV6 = map[string]float64{connV6: 6}
|
||||
}
|
||||
delete(api_peerinfo[peerinfo.PubKey].Connurl, "")
|
||||
api_peerinfo[peerinfo.PubKey].Connurl.LocalV4 = httpobj.http_PeerIPs[peerinfo.PubKey].LocalIPv4
|
||||
api_peerinfo[peerinfo.PubKey].Connurl.LocalV6 = httpobj.http_PeerIPs[peerinfo.PubKey].LocalIPv6
|
||||
}
|
||||
http_maps_lock.RUnlock()
|
||||
|
||||
}
|
||||
api_peerinfo_str_byte, _ := json.Marshal(&api_peerinfo)
|
||||
hash_raw := md5.Sum(append(api_peerinfo_str_byte, http_HashSalt...))
|
||||
hash_raw := md5.Sum(append(api_peerinfo_str_byte, httpobj.http_HashSalt...))
|
||||
hash_str := hex.EncodeToString(hash_raw[:])
|
||||
copy(StateHash[:], []byte(hash_str))
|
||||
if bytes.Equal(old_State_hash[:], StateHash[:]) == false {
|
||||
@ -124,48 +183,33 @@ func get_api_peers(old_State_hash [32]byte) (api_peerinfo config.API_Peers, Stat
|
||||
|
||||
func get_peerinfo(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
PubKeyA, has := params["PubKey"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require PubKey."))
|
||||
return
|
||||
}
|
||||
StateA, has := params["State"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require State."))
|
||||
return
|
||||
}
|
||||
NIDA, has := params["NodeID"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require NodeID."))
|
||||
return
|
||||
}
|
||||
NID2, err := strconv.ParseUint(NIDA[0], 10, 16)
|
||||
PubKey, err := extractParamsStr(params, "PubKey", w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(fmt.Sprintf("%v", err)))
|
||||
return
|
||||
}
|
||||
PubKey := PubKeyA[0]
|
||||
State := StateA[0]
|
||||
NodeID := config.Vertex(NID2)
|
||||
http_maps_lock.RLock()
|
||||
defer http_maps_lock.RUnlock()
|
||||
if http_PeerID2Info[NodeID].PubKey != PubKey {
|
||||
State, err := extractParamsStr(params, "State", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
NodeID, err := extractParamsVertex(params, "NodeID", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
httpobj.RLock()
|
||||
defer httpobj.RUnlock()
|
||||
if httpobj.http_PeerID2Info[NodeID].PubKey != PubKey {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("NodeID and PunKey are not match"))
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Equal(http_PeerInfo_hash[:], []byte(State)) {
|
||||
if state := http_PeerState[PubKey]; state != nil {
|
||||
copy(http_PeerState[PubKey].PeerInfoState[:], State)
|
||||
http_PeerInfo_2peer := make(config.API_Peers)
|
||||
if bytes.Equal(httpobj.http_PeerInfo_hash[:], []byte(State)) {
|
||||
if state := httpobj.http_PeerState[PubKey]; state != nil {
|
||||
copy(httpobj.http_PeerState[PubKey].PeerInfoState[:], State)
|
||||
http_PeerInfo_2peer := make(mtypes.API_Peers)
|
||||
|
||||
for PeerPubKey, peerinfo := range http_PeerInfo {
|
||||
if http_sconfig.UsePSKForInterEdge {
|
||||
for PeerPubKey, peerinfo := range httpobj.http_PeerInfo {
|
||||
if httpobj.http_sconfig.UsePSKForInterEdge {
|
||||
h := sha256.New()
|
||||
if NodeID > peerinfo.NodeID {
|
||||
h.Write([]byte(PubKey))
|
||||
@ -176,7 +220,7 @@ func get_peerinfo(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
h.Write(http_HashSalt)
|
||||
h.Write(httpobj.http_HashSalt)
|
||||
bs := h.Sum(nil)
|
||||
var psk device.NoisePresharedKey
|
||||
copy(psk[:], bs[:])
|
||||
@ -200,47 +244,32 @@ func get_peerinfo(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func get_nhtable(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
PubKeyA, has := params["PubKey"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require PubKey."))
|
||||
return
|
||||
}
|
||||
StateA, has := params["State"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require State."))
|
||||
return
|
||||
}
|
||||
NIDA, has := params["NodeID"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require NodeID."))
|
||||
return
|
||||
}
|
||||
NID2, err := strconv.ParseUint(NIDA[0], 10, 16)
|
||||
PubKey, err := extractParamsStr(params, "PubKey", w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(fmt.Sprintf("%v", err)))
|
||||
return
|
||||
}
|
||||
PubKey := PubKeyA[0]
|
||||
State := StateA[0]
|
||||
NodeID := config.Vertex(NID2)
|
||||
http_maps_lock.RLock()
|
||||
defer http_maps_lock.RUnlock()
|
||||
if http_PeerID2Info[NodeID].PubKey != PubKey {
|
||||
State, err := extractParamsStr(params, "State", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
NodeID, err := extractParamsVertex(params, "NodeID", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
httpobj.RLock()
|
||||
defer httpobj.RUnlock()
|
||||
if httpobj.http_PeerID2Info[NodeID].PubKey != PubKey {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("NodeID and PunKey are not match"))
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Equal(http_NhTable_Hash[:], []byte(State)) {
|
||||
if state := http_PeerState[PubKey]; state != nil {
|
||||
copy(http_PeerState[PubKey].NhTableState[:], State)
|
||||
if bytes.Equal(httpobj.http_NhTable_Hash[:], []byte(State)) {
|
||||
if state := httpobj.http_PeerState[PubKey]; state != nil {
|
||||
copy(httpobj.http_PeerState[PubKey].NhTableState[:], State)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(http_NhTableStr))
|
||||
w.Write([]byte(httpobj.http_NhTableStr))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -248,103 +277,205 @@ func get_nhtable(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("State not correct"))
|
||||
}
|
||||
|
||||
func get_info(w http.ResponseWriter, r *http.Request) {
|
||||
func get_peerstate(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
PasswordA, has := params["Password"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require Password"))
|
||||
password, err := extractParamsStr(params, "Password", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
password := PasswordA[0]
|
||||
if password != http_passwords.ShowState {
|
||||
if password != httpobj.http_passwords.ShowState {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Wrong password"))
|
||||
return
|
||||
}
|
||||
if time.Now().After(http_StateExpire) {
|
||||
httpobj.RLock()
|
||||
defer httpobj.RUnlock()
|
||||
if time.Now().After(httpobj.http_StateExpire) {
|
||||
hs := HttpState{
|
||||
PeerInfo: make(map[config.Vertex]HttpPeerInfo),
|
||||
NhTable: http_graph.GetNHTable(false),
|
||||
PeerInfo: make(map[mtypes.Vertex]HttpPeerInfo),
|
||||
NhTable: httpobj.http_graph.GetNHTable(false),
|
||||
Infinity: path.Infinity,
|
||||
Edges: http_graph.GetEdges(false, false),
|
||||
Edges_Nh: http_graph.GetEdges(true, true),
|
||||
Dist: http_graph.GetDtst(),
|
||||
Edges: httpobj.http_graph.GetEdges(false, false),
|
||||
Edges_Nh: httpobj.http_graph.GetEdges(true, true),
|
||||
Dist: httpobj.http_graph.GetDtst(),
|
||||
}
|
||||
http_maps_lock.RLock()
|
||||
for _, peerinfo := range http_sconfig.Peers {
|
||||
LastSeenStr := http_PeerState[peerinfo.PubKey].LastSeen.String()
|
||||
|
||||
for _, peerinfo := range httpobj.http_sconfig.Peers {
|
||||
LastSeenStr := httpobj.http_PeerState[peerinfo.PubKey].LastSeen.String()
|
||||
hs.PeerInfo[peerinfo.NodeID] = HttpPeerInfo{
|
||||
Name: peerinfo.Name,
|
||||
LastSeen: LastSeenStr,
|
||||
}
|
||||
}
|
||||
http_maps_lock.RUnlock()
|
||||
http_StateExpire = time.Now().Add(5 * time.Second)
|
||||
http_StateString_tmp, _ = json.Marshal(hs)
|
||||
httpobj.http_StateExpire = time.Now().Add(5 * time.Second)
|
||||
httpobj.http_StateString_tmp, _ = json.Marshal(hs)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(http_StateString_tmp)
|
||||
w.Write(httpobj.http_StateString_tmp)
|
||||
return
|
||||
}
|
||||
|
||||
func post_nodeinfo(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
|
||||
NodeID, err := extractParamsVertex(params, "NodeID", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
JWTSig, err := extractParamsStr(params, "JWTSig", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if NodeID >= mtypes.Special_NodeID {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
|
||||
return
|
||||
}
|
||||
|
||||
httpobj.RLock()
|
||||
defer httpobj.RUnlock()
|
||||
var PubKey string
|
||||
if peerconf, has := httpobj.http_PeerID2Info[NodeID]; has {
|
||||
PubKey = peerconf.PubKey
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Paramater NodeID: NodeID not exists."))
|
||||
return
|
||||
}
|
||||
JWTSecret := httpobj.http_PeerState[PubKey].JETSecret
|
||||
httpPostCount := httpobj.http_PeerState[PubKey].httpPostCount
|
||||
|
||||
client_body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Request body: Error reading request body: %v", err)))
|
||||
return
|
||||
}
|
||||
|
||||
token_claims := mtypes.API_report_peerinfo_jwt_claims{}
|
||||
|
||||
token, err := jwt.ParseWithClaims(string(JWTSig), &token_claims, func(token *jwt.Token) (interface{}, error) {
|
||||
// Don't forget to validate the alg is what you expect:
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return JWTSecret[:], nil
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater JWTSig: Signature verification failed: %v", err)))
|
||||
return
|
||||
}
|
||||
if !token.Valid {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater JWTSig: Signature verification failed: Invalid token")))
|
||||
return
|
||||
}
|
||||
|
||||
client_PostCount := token_claims.PostCount
|
||||
client_body_hash := token_claims.BodyHash
|
||||
|
||||
if client_PostCount < httpPostCount {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Request body: postcount too small: %v", httpPostCount)))
|
||||
return
|
||||
}
|
||||
|
||||
calculated_body_hash := sha3.Sum512(client_body)
|
||||
if base64.StdEncoding.EncodeToString(calculated_body_hash[:]) == client_body_hash {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Request body: hash not match: %v", client_body_hash)))
|
||||
return
|
||||
}
|
||||
|
||||
client_body, err = mtypes.GUzip(client_body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Request body: gzip unzip failed")))
|
||||
return
|
||||
}
|
||||
client_report, err := mtypes.ParseAPI_report_peerinfo(client_body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Request body: Error parsing request body: %v", err)))
|
||||
return
|
||||
}
|
||||
|
||||
httpobj.http_PeerIPs[PubKey].LocalIPv4 = client_report.LocalV4s
|
||||
httpobj.http_PeerIPs[PubKey].LocalIPv6 = client_report.LocalV6s
|
||||
httpobj.http_PeerState[PubKey].httpPostCount = client_PostCount + 1
|
||||
|
||||
applied_pones := make([]mtypes.PongMsg, 0, len(client_report.Pongs))
|
||||
for _, pong_msg := range client_report.Pongs {
|
||||
if pong_msg.Src_nodeID != NodeID {
|
||||
continue
|
||||
}
|
||||
|
||||
if info, has := httpobj.http_PeerID2Info[pong_msg.Dst_nodeID]; !has {
|
||||
AdditionalCost_use := info.AdditionalCost
|
||||
|
||||
if AdditionalCost_use >= 0 {
|
||||
pong_msg.AdditionalCost = AdditionalCost_use
|
||||
}
|
||||
applied_pones = append(applied_pones, pong_msg)
|
||||
}
|
||||
}
|
||||
changed := httpobj.http_graph.UpdateLatencyMulti(client_report.Pongs, true, true)
|
||||
if changed {
|
||||
NhTable := httpobj.http_graph.GetNHTable(true)
|
||||
NhTablestr, _ := json.Marshal(NhTable)
|
||||
md5_hash_raw := md5.Sum(append(httpobj.http_NhTableStr, httpobj.http_HashSalt...))
|
||||
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
|
||||
new_hash_str_byte := []byte(new_hash_str)
|
||||
copy(httpobj.http_NhTable_Hash[:], new_hash_str_byte)
|
||||
copy(httpobj.http_graph.NhTableHash[:], new_hash_str_byte)
|
||||
httpobj.http_NhTableStr = NhTablestr
|
||||
PushNhTable(false)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(fmt.Sprintf("OK")))
|
||||
return
|
||||
}
|
||||
|
||||
func peeradd(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
params := r.URL.Query()
|
||||
PasswordA, has := params["Password"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Require Password"))
|
||||
password, err := extractParamsStr(params, "Password", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
password := PasswordA[0]
|
||||
if password != http_passwords.AddPeer {
|
||||
if password != httpobj.http_passwords.AddPeer {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Wrong password"))
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
NID, err := strconv.ParseUint(r.Form.Get("nodeid"), 10, 16)
|
||||
NodeID, err := extractParamsVertex(r.Form, "nodeid", w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater nodeid: Error parse uint16: \"%v\", %v", NID, err)))
|
||||
return
|
||||
}
|
||||
NodeID := config.Vertex(NID)
|
||||
if NodeID >= config.Special_NodeID {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Paramater nodeid: Can't use special nodeID."))
|
||||
Name, err := extractParamsStr(r.Form, "name", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Name := r.Form.Get("name")
|
||||
if len(Name) <= 0 || len(Name) >= 15 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Paramater name: Name too long or too short."))
|
||||
return
|
||||
}
|
||||
AdditionalCostStr := r.Form.Get("additionalcost")
|
||||
AdditionalCost, err := strconv.ParseFloat(AdditionalCostStr, 64)
|
||||
AdditionalCost, err := extractParamsFloat(r.Form, "additionalcost", 64, w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater additionalcost: Error parse float64: \"%v\", %v", AdditionalCostStr, err)))
|
||||
return
|
||||
}
|
||||
PubKey := r.Form.Get("pubkey")
|
||||
_, err = device.Str2PubKey(PubKey)
|
||||
|
||||
PubKey, err := extractParamsStr(r.Form, "pubkey", w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater pubkey: Error parse pubkey: \"%v\", %v", PubKey, err)))
|
||||
return
|
||||
}
|
||||
PSKey := r.Form.Get("pskey")
|
||||
_, err = device.Str2PSKey(PSKey)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater pskey: Error parse pskey: \"%v\", %v", PSKey, err)))
|
||||
return
|
||||
}
|
||||
for _, peerinfo := range http_sconfig.Peers {
|
||||
|
||||
PSKey, err := extractParamsStr(r.Form, "pskey", nil)
|
||||
|
||||
httpobj.Lock()
|
||||
defer httpobj.Unlock()
|
||||
|
||||
for _, peerinfo := range httpobj.http_sconfig.Peers {
|
||||
if peerinfo.NodeID == NodeID {
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
w.Write([]byte("Paramater nodeid: NodeID exists"))
|
||||
@ -361,21 +492,21 @@ func peeradd(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
return
|
||||
}
|
||||
}
|
||||
if http_sconfig.GraphRecalculateSetting.StaticMode == true {
|
||||
if httpobj.http_sconfig.GraphRecalculateSetting.StaticMode == true {
|
||||
NhTableStr := r.Form.Get("nexthoptable")
|
||||
if NhTableStr == "" {
|
||||
w.WriteHeader(http.StatusExpectationFailed)
|
||||
w.Write([]byte("Paramater nexthoptable: Your NextHopTable is in static mode.\nPlease provide your new NextHopTable in \"nexthoptable\" parmater in json format"))
|
||||
return
|
||||
}
|
||||
var NewNhTable config.NextHopTable
|
||||
var NewNhTable mtypes.NextHopTable
|
||||
err := json.Unmarshal([]byte(NhTableStr), &NewNhTable)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusExpectationFailed)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater nexthoptable: \"%v\", %v", NhTableStr, err)))
|
||||
return
|
||||
}
|
||||
err = checkNhTable(NewNhTable, append(http_sconfig.Peers, config.SuperPeerInfo{
|
||||
err = checkNhTable(NewNhTable, append(httpobj.http_sconfig.Peers, mtypes.SuperPeerInfo{
|
||||
NodeID: NodeID,
|
||||
Name: Name,
|
||||
PubKey: PubKey,
|
||||
@ -387,9 +518,9 @@ func peeradd(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
w.Write([]byte(fmt.Sprintf("Paramater nexthoptable: \"%v\", %v", NhTableStr, err)))
|
||||
return
|
||||
}
|
||||
http_graph.SetNHTable(NewNhTable, [32]byte{})
|
||||
httpobj.http_graph.SetNHTable(NewNhTable, [32]byte{})
|
||||
}
|
||||
err = super_peeradd(config.SuperPeerInfo{
|
||||
err = super_peeradd(mtypes.SuperPeerInfo{
|
||||
NodeID: NodeID,
|
||||
Name: Name,
|
||||
PubKey: PubKey,
|
||||
@ -401,20 +532,20 @@ func peeradd(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
w.Write([]byte(fmt.Sprintf("Error creating peer: %v", err)))
|
||||
return
|
||||
}
|
||||
http_sconfig.Peers = append(http_sconfig.Peers, config.SuperPeerInfo{
|
||||
httpobj.http_sconfig.Peers = append(httpobj.http_sconfig.Peers, mtypes.SuperPeerInfo{
|
||||
NodeID: NodeID,
|
||||
Name: Name,
|
||||
PubKey: PubKey,
|
||||
PSKey: PSKey,
|
||||
AdditionalCost: AdditionalCost,
|
||||
})
|
||||
configbytes, _ := yaml.Marshal(http_sconfig)
|
||||
ioutil.WriteFile(http_sconfig_path, configbytes, 0644)
|
||||
http_econfig_tmp.NodeID = NodeID
|
||||
http_econfig_tmp.NodeName = Name
|
||||
http_econfig_tmp.PrivKey = "Your_Private_Key"
|
||||
http_econfig_tmp.DynamicRoute.SuperNode.PSKey = PSKey
|
||||
ret_str_byte, _ := yaml.Marshal(&http_econfig_tmp)
|
||||
mtypesBytes, _ := yaml.Marshal(httpobj.http_sconfig)
|
||||
ioutil.WriteFile(httpobj.http_sconfig_path, mtypesBytes, 0644)
|
||||
httpobj.http_econfig_tmp.NodeID = NodeID
|
||||
httpobj.http_econfig_tmp.NodeName = Name
|
||||
httpobj.http_econfig_tmp.PrivKey = "Your_Private_Key"
|
||||
httpobj.http_econfig_tmp.DynamicRoute.SuperNode.PSKey = PSKey
|
||||
ret_str_byte, _ := yaml.Marshal(&httpobj.http_econfig_tmp)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(ret_str_byte)
|
||||
return
|
||||
@ -422,55 +553,59 @@ func peeradd(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
|
||||
func peerdel(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
params := r.URL.Query()
|
||||
toDelete := config.Broadcast
|
||||
toDelete := mtypes.Broadcast
|
||||
|
||||
PasswordA, has := params["Password"]
|
||||
PubKey := ""
|
||||
if has {
|
||||
password := PasswordA[0]
|
||||
if password == http_passwords.DelPeer {
|
||||
NodeIDA, has := params["nodeid"]
|
||||
if !has {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Need NodeID"))
|
||||
return
|
||||
}
|
||||
NID, err := strconv.ParseUint(NodeIDA[0], 10, 16)
|
||||
var err error
|
||||
var NodeID mtypes.Vertex
|
||||
var PrivKey string
|
||||
var PubKey string
|
||||
password, pwderr := extractParamsStr(params, "Password", nil)
|
||||
httpobj.Lock()
|
||||
defer httpobj.Unlock()
|
||||
if pwderr == nil { // user provide the password
|
||||
if password == httpobj.http_passwords.DelPeer {
|
||||
NodeID, err = extractParamsVertex(params, "nodeid", w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprint(err)))
|
||||
return
|
||||
}
|
||||
NodeID := config.Vertex(NID)
|
||||
toDelete = NodeID
|
||||
if _, has := httpobj.http_PeerID2Info[toDelete]; !has {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater nodeid: \"%v\" not found", PubKey)))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Paramater Password: Wrong password"))
|
||||
return
|
||||
}
|
||||
} else { // user don't provide the password
|
||||
PrivKey, err = extractParamsStr(params, "privkey", w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
PriKeyA, has := params["privkey"]
|
||||
if has && PriKeyA[0] != "" {
|
||||
PrivKey := PriKeyA[0]
|
||||
privk, err := device.Str2PriKey(PrivKey)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprint(err)))
|
||||
w.Write([]byte(fmt.Sprintf("Paramater privkey: %v", err)))
|
||||
return
|
||||
}
|
||||
pubk := privk.PublicKey()
|
||||
PubKey = pubk.ToString()
|
||||
for _, peerinfo := range http_sconfig.Peers {
|
||||
for _, peerinfo := range httpobj.http_sconfig.Peers {
|
||||
if peerinfo.PubKey == PubKey {
|
||||
toDelete = peerinfo.NodeID
|
||||
}
|
||||
}
|
||||
}
|
||||
if toDelete == config.Broadcast {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Wrong password or private key."))
|
||||
return
|
||||
if toDelete == mtypes.Broadcast {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater privkey: \"%v\" not found", PubKey)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var peers_new []config.SuperPeerInfo
|
||||
for _, peerinfo := range http_sconfig.Peers {
|
||||
var peers_new []mtypes.SuperPeerInfo
|
||||
for _, peerinfo := range httpobj.http_sconfig.Peers {
|
||||
if peerinfo.NodeID == toDelete {
|
||||
super_peerdel(peerinfo.NodeID)
|
||||
} else {
|
||||
@ -478,9 +613,9 @@ func peerdel(w http.ResponseWriter, r *http.Request) { //Waiting for test
|
||||
}
|
||||
}
|
||||
|
||||
http_sconfig.Peers = peers_new
|
||||
configbytes, _ := yaml.Marshal(http_sconfig)
|
||||
ioutil.WriteFile(http_sconfig_path, configbytes, 0644)
|
||||
httpobj.http_sconfig.Peers = peers_new
|
||||
mtypesBytes, _ := yaml.Marshal(httpobj.http_sconfig)
|
||||
ioutil.WriteFile(httpobj.http_sconfig_path, mtypesBytes, 0644)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Node ID: " + toDelete.ToString() + " deleted."))
|
||||
return
|
||||
@ -493,7 +628,8 @@ func HttpServer(http_port int, apiprefix string) {
|
||||
}
|
||||
mux.HandleFunc(apiprefix+"/peerinfo", get_peerinfo)
|
||||
mux.HandleFunc(apiprefix+"/nhtable", get_nhtable)
|
||||
mux.HandleFunc(apiprefix+"/peerstate", get_info)
|
||||
mux.HandleFunc(apiprefix+"/peerstate", get_peerstate)
|
||||
mux.HandleFunc(apiprefix+"/post/nodeinfo", post_nodeinfo)
|
||||
mux.HandleFunc(apiprefix+"/peer/add", peeradd) //Waiting for test
|
||||
mux.HandleFunc(apiprefix+"/peer/del", peerdel) //Waiting for test
|
||||
http.ListenAndServe(":"+strconv.Itoa(http_port), mux)
|
||||
|
Reference in New Issue
Block a user