2021-12-04 15:46:36 +01:00
/ * SPDX - License - Identifier : MIT
*
* Copyright ( C ) 2017 - 2021 Kusakabe Si . All Rights Reserved .
* /
2021-08-20 19:32:50 +02:00
package main
import (
2021-09-21 22:03:11 +02:00
"crypto/md5"
2021-12-02 18:13:48 +01:00
"encoding/base64"
2021-09-21 22:03:11 +02:00
"encoding/hex"
2021-08-24 20:16:21 +02:00
"encoding/json"
2021-09-21 22:03:11 +02:00
"fmt"
"io/ioutil"
2021-08-20 19:32:50 +02:00
"strconv"
2021-12-03 23:46:58 +01:00
"strings"
2021-09-29 01:32:51 +02:00
"sync"
2021-12-04 04:51:50 +01:00
"sync/atomic"
2021-08-24 20:16:21 +02:00
"time"
2021-08-20 19:32:50 +02:00
"net/http"
2021-12-02 18:13:48 +01:00
"net/url"
2021-08-20 19:32:50 +02:00
2021-12-02 18:13:48 +01:00
"github.com/golang-jwt/jwt"
"golang.org/x/crypto/sha3"
2021-12-16 03:56:02 +01:00
"github.com/KusakabeSi/EtherGuard-VPN/conn"
2021-12-02 18:13:48 +01:00
"github.com/KusakabeSi/EtherGuard-VPN/device"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
2021-09-21 22:03:11 +02:00
yaml "gopkg.in/yaml.v2"
2021-08-20 19:32:50 +02:00
)
2021-12-02 18:13:48 +01:00
type http_shared_objects struct {
2021-12-04 15:46:36 +01:00
http_graph * path . IG
http_device4 * device . Device
http_device6 * device . Device
http_HashSalt [ ] byte
http_NhTable_Hash string
http_PeerInfo_hash string
http_NhTableStr [ ] byte
http_PeerInfo mtypes . API_Peers
http_super_chains * mtypes . SUPER_Events
2021-12-09 08:46:15 +01:00
http_pskdb device . PSKDB
2021-09-21 22:03:11 +02:00
2021-12-02 18:13:48 +01:00
http_passwords mtypes . Passwords
2021-09-21 22:03:11 +02:00
http_StateExpire time . Time
http_StateString_tmp [ ] byte
2021-12-02 18:13:48 +01:00
http_PeerID2Info map [ mtypes . Vertex ] mtypes . SuperPeerInfo
2021-10-27 03:02:44 +02:00
http_PeerState map [ string ] * PeerState //the state hash reported by peer
http_PeerIPs map [ string ] * HttpPeerLocalIP
2021-10-06 10:33:14 +02:00
2021-12-02 18:13:48 +01:00
http_sconfig * mtypes . SuperConfig
2021-09-21 22:03:11 +02:00
http_sconfig_path string
2021-12-02 18:13:48 +01:00
http_econfig_tmp * mtypes . EdgeConfig
sync . RWMutex
}
var (
httpobj http_shared_objects
2021-08-20 19:32:50 +02:00
)
2021-09-23 13:31:01 +02:00
type HttpPeerLocalIP struct {
2021-12-02 18:13:48 +01:00
LocalIPv4 map [ string ] float64
LocalIPv6 map [ string ] float64
2021-09-23 13:31:01 +02:00
}
2021-08-24 20:16:21 +02:00
type HttpState struct {
2021-12-02 18:13:48 +01:00
PeerInfo map [ mtypes . Vertex ] HttpPeerInfo
2021-08-26 21:06:15 +02:00
Infinity float64
2021-12-02 18:13:48 +01:00
Edges map [ mtypes . Vertex ] map [ mtypes . Vertex ] float64
Edges_Nh map [ mtypes . Vertex ] map [ mtypes . Vertex ] float64
NhTable mtypes . NextHopTable
Dist mtypes . DistTable
2021-08-24 20:16:21 +02:00
}
2021-09-21 22:03:11 +02:00
type HttpPeerInfo struct {
2021-09-29 01:32:51 +02:00
Name string
LastSeen string
2021-09-21 22:03:11 +02:00
}
2021-08-20 19:32:50 +02:00
type PeerState struct {
2021-12-04 15:46:36 +01:00
NhTableState atomic . Value // string
PeerInfoState atomic . Value // string
SuperParamState atomic . Value // string
SuperParamStateClient atomic . Value // string
JETSecret atomic . Value // mtypes.JWTSecret
httpPostCount atomic . Value // uint64
LastSeen atomic . Value // time.Time
2021-08-20 19:32:50 +02:00
}
2021-12-02 18:13:48 +01:00
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 {
2021-12-09 08:46:15 +01:00
return mtypes . NodeID_Invalid , err
2021-12-02 18:13:48 +01:00
}
return mtypes . Vertex ( val ) , nil
}
2021-12-04 03:32:59 +01:00
func get_api_peers ( old_State_hash string ) ( api_peerinfo mtypes . API_Peers , StateHash string , changed bool ) {
2021-12-02 18:13:48 +01:00
// No lock
api_peerinfo = make ( mtypes . API_Peers )
for _ , peerinfo := range httpobj . http_sconfig . Peers {
2021-12-05 22:36:50 +01:00
connV4 := httpobj . http_device4 . GetConnurl ( peerinfo . NodeID )
connV6 := httpobj . http_device6 . GetConnurl ( peerinfo . NodeID )
2021-12-16 03:56:02 +01:00
if peerinfo . ExternalIP != "" {
ExternalIP := peerinfo . ExternalIP
if strings . Contains ( ExternalIP , ":" ) {
ExternalIP = fmt . Sprintf ( "[%v]" , ExternalIP )
}
if strings . Contains ( connV4 , ":" ) {
hostport := strings . Split ( connV4 , ":" )
ExternalIP = ExternalIP + ":" + hostport [ len ( hostport ) - 1 ]
2022-01-08 23:32:04 +01:00
_ , ExternalEndPoint_v4 , err := conn . LookupIP ( ExternalIP , conn . EnabledAf4 , 0 )
2021-12-16 03:56:02 +01:00
if err == nil {
connV4 = ExternalEndPoint_v4
}
}
if strings . Contains ( connV6 , ":" ) {
hostport := strings . Split ( connV6 , ":" )
ExternalIP = ExternalIP + ":" + hostport [ len ( hostport ) - 1 ]
2022-01-08 23:32:04 +01:00
_ , ExternalEndPoint_v6 , err := conn . LookupIP ( ExternalIP , conn . EnabledAf6 , 0 )
2021-12-16 03:56:02 +01:00
if err == nil {
connV6 = ExternalEndPoint_v6
}
}
}
2021-12-05 22:36:50 +01:00
if len ( connV4 ) + len ( connV6 ) == 0 {
continue
}
2021-12-02 18:13:48 +01:00
api_peerinfo [ peerinfo . PubKey ] = mtypes . API_Peerinfo {
2021-09-21 22:03:11 +02:00
NodeID : peerinfo . NodeID ,
PSKey : peerinfo . PSKey ,
2021-12-02 18:13:48 +01:00
Connurl : & mtypes . API_connurl { } ,
2021-09-21 22:03:11 +02:00
}
2021-12-04 04:51:50 +01:00
if httpobj . http_PeerState [ peerinfo . PubKey ] . LastSeen . Load ( ) . ( time . Time ) . Add ( mtypes . S2TD ( httpobj . http_sconfig . PeerAliveTimeout ) ) . After ( time . Now ( ) ) {
2021-12-02 18:13:48 +01:00
if connV4 != "" {
api_peerinfo [ peerinfo . PubKey ] . Connurl . ExternalV4 = map [ string ] float64 { connV4 : 4 }
2021-09-29 01:32:51 +02:00
}
2021-12-02 18:13:48 +01:00
if connV6 != "" {
api_peerinfo [ peerinfo . PubKey ] . Connurl . ExternalV6 = map [ string ] float64 { connV6 : 6 }
2021-09-29 01:32:51 +02:00
}
2021-12-03 23:46:58 +01:00
if ! peerinfo . SkipLocalIP {
api_peerinfo [ peerinfo . PubKey ] . Connurl . LocalV4 = httpobj . http_PeerIPs [ peerinfo . PubKey ] . LocalIPv4
api_peerinfo [ peerinfo . PubKey ] . Connurl . LocalV6 = httpobj . http_PeerIPs [ peerinfo . PubKey ] . LocalIPv6
}
2021-09-23 13:31:01 +02:00
}
2021-09-21 22:03:11 +02:00
}
2021-09-23 13:31:01 +02:00
api_peerinfo_str_byte , _ := json . Marshal ( & api_peerinfo )
2021-12-02 18:13:48 +01:00
hash_raw := md5 . Sum ( append ( api_peerinfo_str_byte , httpobj . http_HashSalt ... ) )
2021-09-21 22:03:11 +02:00
hash_str := hex . EncodeToString ( hash_raw [ : ] )
2021-12-04 03:32:59 +01:00
StateHash = hash_str
if old_State_hash != StateHash {
2021-09-21 22:03:11 +02:00
changed = true
}
return
}
2021-12-05 22:36:50 +01:00
func edge_get_superparams ( w http . ResponseWriter , r * http . Request ) {
2021-12-04 03:32:59 +01:00
// Read all params
params := r . URL . Query ( )
PubKey , err := extractParamsStr ( params , "PubKey" , w )
if err != nil {
return
}
State , err := extractParamsStr ( params , "State" , w )
if err != nil {
return
}
NodeID , err := extractParamsVertex ( params , "NodeID" , w )
if err != nil {
return
}
2021-12-09 08:46:15 +01:00
if NodeID >= mtypes . NodeID_Special {
2021-12-04 03:32:59 +01:00
w . WriteHeader ( http . StatusBadRequest )
w . Write ( [ ] byte ( "Paramater NodeID: Can't use special nodeID." ) )
return
}
// Authentication
httpobj . RLock ( )
defer httpobj . RUnlock ( )
if _ , has := httpobj . http_PeerID2Info [ NodeID ] ; ! has {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater PubKey: NodeID and PubKey are not match" ) )
return
}
if httpobj . http_PeerID2Info [ NodeID ] . PubKey != PubKey {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater PubKey: NodeID and PubKey are not match" ) )
return
}
2021-12-09 08:46:15 +01:00
if _ , has := httpobj . http_PeerState [ PubKey ] ; ! has {
2021-12-04 03:32:59 +01:00
w . WriteHeader ( http . StatusInternalServerError )
w . Write ( [ ] byte ( "Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author." ) )
return
}
2021-12-04 15:46:36 +01:00
if httpobj . http_PeerState [ PubKey ] . SuperParamState . Load ( ) . ( string ) != State {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater State: State not correct" ) )
return
}
2021-12-04 03:32:59 +01:00
// Do something
SuperParams := mtypes . API_SuperParams {
2021-12-26 17:06:25 +01:00
SendPingInterval : httpobj . http_sconfig . SendPingInterval ,
HttpPostInterval : httpobj . http_sconfig . HttpPostInterval ,
PeerAliveTimeout : httpobj . http_sconfig . PeerAliveTimeout ,
AdditionalCost : httpobj . http_PeerID2Info [ NodeID ] . AdditionalCost ,
DampingFilterRadius : httpobj . http_sconfig . DampingFilterRadius ,
2021-12-04 03:32:59 +01:00
}
SuperParamStr , _ := json . Marshal ( SuperParams )
2021-12-04 15:46:36 +01:00
httpobj . http_PeerState [ PubKey ] . SuperParamStateClient . Store ( State )
2021-12-04 03:32:59 +01:00
w . Header ( ) . Set ( "Content-Type" , "application/json" )
w . WriteHeader ( http . StatusOK )
w . Write ( [ ] byte ( SuperParamStr ) )
}
2021-12-05 22:36:50 +01:00
func edge_get_peerinfo ( w http . ResponseWriter , r * http . Request ) {
2021-12-04 03:32:59 +01:00
// Read all params
2021-08-20 19:32:50 +02:00
params := r . URL . Query ( )
2021-12-02 18:13:48 +01:00
PubKey , err := extractParamsStr ( params , "PubKey" , w )
if err != nil {
2021-08-23 21:11:01 +02:00
return
}
2021-12-02 18:13:48 +01:00
State , err := extractParamsStr ( params , "State" , w )
if err != nil {
2021-09-23 13:31:01 +02:00
return
}
2021-12-02 18:13:48 +01:00
NodeID , err := extractParamsVertex ( params , "NodeID" , w )
2021-09-23 13:31:01 +02:00
if err != nil {
return
}
2021-12-09 08:46:15 +01:00
if NodeID >= mtypes . NodeID_Special {
2021-12-04 03:32:59 +01:00
w . WriteHeader ( http . StatusBadRequest )
w . Write ( [ ] byte ( "Paramater NodeID: Can't use special nodeID." ) )
return
}
// Authentication
2021-12-02 18:13:48 +01:00
httpobj . RLock ( )
defer httpobj . RUnlock ( )
2021-12-04 03:32:59 +01:00
if _ , has := httpobj . http_PeerID2Info [ NodeID ] ; ! has {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater PubKey: NodeID and PubKey are not match" ) )
return
}
2021-12-02 18:13:48 +01:00
if httpobj . http_PeerID2Info [ NodeID ] . PubKey != PubKey {
2021-09-23 13:31:01 +02:00
w . WriteHeader ( http . StatusNotFound )
2021-12-04 03:32:59 +01:00
w . Write ( [ ] byte ( "Paramater PubKey: NodeID and PubKey are not match" ) )
return
}
if httpobj . http_PeerInfo_hash != State {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater State: State not correct" ) )
return
}
2021-12-09 08:46:15 +01:00
if _ , has := httpobj . http_PeerState [ PubKey ] ; ! has {
2021-12-04 03:32:59 +01:00
w . WriteHeader ( http . StatusInternalServerError )
w . Write ( [ ] byte ( "Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author." ) )
return
}
2021-09-23 13:31:01 +02:00
2021-12-04 03:32:59 +01:00
// Do something
2021-12-04 04:51:50 +01:00
httpobj . http_PeerState [ PubKey ] . PeerInfoState . Store ( State )
2021-12-04 03:32:59 +01:00
http_PeerInfo_2peer := make ( mtypes . API_Peers )
for PeerPubKey , peerinfo := range httpobj . http_PeerInfo {
if httpobj . http_sconfig . UsePSKForInterEdge {
2021-12-09 08:46:15 +01:00
if NodeID == peerinfo . NodeID {
2021-12-04 03:32:59 +01:00
continue
}
2021-12-09 08:46:15 +01:00
PSK := httpobj . http_pskdb . GetPSK ( NodeID , peerinfo . NodeID )
peerinfo . PSKey = PSK . ToString ( )
2021-12-04 03:32:59 +01:00
} else {
peerinfo . PSKey = ""
}
if httpobj . http_PeerID2Info [ NodeID ] . SkipLocalIP { // Clear all local IP
peerinfo . Connurl . LocalV4 = make ( map [ string ] float64 )
peerinfo . Connurl . LocalV6 = make ( map [ string ] float64 )
2021-08-23 21:11:01 +02:00
}
2021-12-04 03:32:59 +01:00
http_PeerInfo_2peer [ PeerPubKey ] = peerinfo
2021-08-23 21:11:01 +02:00
}
2021-12-04 03:32:59 +01:00
api_peerinfo_str_byte , _ := json . Marshal ( & http_PeerInfo_2peer )
w . Header ( ) . Set ( "Content-Type" , "application/json" )
w . WriteHeader ( http . StatusOK )
w . Write ( api_peerinfo_str_byte )
2021-08-20 19:32:50 +02:00
}
2021-12-05 22:36:50 +01:00
func edge_get_nhtable ( w http . ResponseWriter , r * http . Request ) {
2021-12-04 03:32:59 +01:00
// Read all params
2021-08-20 19:32:50 +02:00
params := r . URL . Query ( )
2021-12-02 18:13:48 +01:00
PubKey , err := extractParamsStr ( params , "PubKey" , w )
if err != nil {
2021-08-23 21:11:01 +02:00
return
}
2021-12-02 18:13:48 +01:00
State , err := extractParamsStr ( params , "State" , w )
if err != nil {
2021-09-23 13:31:01 +02:00
return
}
2021-12-02 18:13:48 +01:00
NodeID , err := extractParamsVertex ( params , "NodeID" , w )
2021-09-23 13:31:01 +02:00
if err != nil {
return
}
2021-12-09 08:46:15 +01:00
if NodeID >= mtypes . NodeID_Special {
2021-12-04 03:32:59 +01:00
w . WriteHeader ( http . StatusBadRequest )
w . Write ( [ ] byte ( "Paramater NodeID: Can't use special nodeID." ) )
return
}
// Authentication
2021-12-02 18:13:48 +01:00
httpobj . RLock ( )
defer httpobj . RUnlock ( )
2021-12-04 03:32:59 +01:00
if _ , has := httpobj . http_PeerID2Info [ NodeID ] ; ! has {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater PubKey: NodeID and PubKey are not match" ) )
return
}
2021-12-02 18:13:48 +01:00
if httpobj . http_PeerID2Info [ NodeID ] . PubKey != PubKey {
2021-09-23 13:31:01 +02:00
w . WriteHeader ( http . StatusNotFound )
2021-12-04 03:32:59 +01:00
w . Write ( [ ] byte ( "Paramater PubKey: NodeID and PubKey are not match" ) )
2021-09-23 13:31:01 +02:00
return
}
2021-12-04 03:32:59 +01:00
if httpobj . http_NhTable_Hash != State {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "Paramater State: State not correct" ) )
return
}
2021-12-09 08:46:15 +01:00
if _ , has := httpobj . http_PeerState [ PubKey ] ; ! has {
2021-12-04 03:32:59 +01:00
w . WriteHeader ( http . StatusInternalServerError )
w . Write ( [ ] byte ( "Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author." ) )
return
2021-08-20 19:32:50 +02:00
}
2021-12-04 03:32:59 +01:00
2021-12-04 04:51:50 +01:00
httpobj . http_PeerState [ PubKey ] . NhTableState . Store ( State )
2021-12-04 03:32:59 +01:00
w . Header ( ) . Set ( "Content-Type" , "application/json" )
w . WriteHeader ( http . StatusOK )
w . Write ( [ ] byte ( httpobj . http_NhTableStr ) )
2021-08-24 20:16:21 +02:00
}
2021-12-05 22:36:50 +01:00
func edge_post_nodeinfo ( w http . ResponseWriter , r * http . Request ) {
2021-09-21 22:03:11 +02:00
params := r . URL . Query ( )
2021-12-02 18:13:48 +01:00
NodeID , err := extractParamsVertex ( params , "NodeID" , w )
if err != nil {
2021-09-21 22:03:11 +02:00
return
}
2021-12-04 03:32:59 +01:00
PubKey , err := extractParamsStr ( params , "PubKey" , w )
2021-12-02 18:13:48 +01:00
if err != nil {
2021-09-21 22:03:11 +02:00
return
}
2021-12-09 08:46:15 +01:00
if NodeID >= mtypes . NodeID_Special {
2021-09-21 22:03:11 +02:00
w . WriteHeader ( http . StatusBadRequest )
2021-12-02 18:13:48 +01:00
w . Write ( [ ] byte ( "Paramater NodeID: Can't use special nodeID." ) )
2021-09-21 22:03:11 +02:00
return
}
2021-12-02 18:13:48 +01:00
2021-12-04 03:32:59 +01:00
JWTSig , err := extractParamsStr ( params , "JWTSig" , w )
if err != nil {
return
}
2021-12-02 18:13:48 +01:00
httpobj . RLock ( )
defer httpobj . RUnlock ( )
2021-12-04 03:32:59 +01:00
if _ , has := httpobj . http_PeerID2Info [ NodeID ] ; ! has {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "NodeID and PunKey are not match" ) )
2021-10-27 04:23:14 +02:00
return
}
2021-12-04 03:32:59 +01:00
if httpobj . http_PeerID2Info [ NodeID ] . PubKey != PubKey {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( "NodeID and PunKey are not match" ) )
return
}
2021-12-02 18:13:48 +01:00
JWTSecret := httpobj . http_PeerState [ PubKey ] . JETSecret
httpPostCount := httpobj . http_PeerState [ PubKey ] . httpPostCount
2021-10-27 04:23:14 +02:00
2021-12-02 18:13:48 +01:00
client_body , err := ioutil . ReadAll ( r . Body )
if err != nil {
2021-09-21 22:03:11 +02:00
w . WriteHeader ( http . StatusBadRequest )
2021-12-02 18:13:48 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Request body: Error reading request body: %v" , err ) ) )
2021-10-27 04:23:14 +02:00
return
}
2021-12-02 18:13:48 +01:00
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 {
2021-12-09 08:46:15 +01:00
return nil , fmt . Errorf ( "unexpected signing method: %v" , token . Header [ "alg" ] )
2021-12-02 18:13:48 +01:00
}
2021-12-04 04:51:50 +01:00
JWTSecretB := JWTSecret . Load ( ) . ( mtypes . JWTSecret )
return JWTSecretB [ : ] , nil
2021-12-02 18:13:48 +01:00
} )
2021-10-27 04:23:14 +02:00
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2021-12-02 18:13:48 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater JWTSig: Signature verification failed: %v" , err ) ) )
2021-09-21 22:03:11 +02:00
return
}
2021-12-02 18:13:48 +01:00
if ! token . Valid {
w . WriteHeader ( http . StatusBadRequest )
2021-12-09 08:46:15 +01:00
w . Write ( [ ] byte ( "Paramater JWTSig: Signature verification failed: Invalid token" ) )
2021-12-02 18:13:48 +01:00
return
}
client_PostCount := token_claims . PostCount
client_body_hash := token_claims . BodyHash
2021-12-04 04:51:50 +01:00
if client_PostCount < httpPostCount . Load ( ) . ( uint64 ) {
2021-12-02 18:13:48 +01:00
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 )
2021-09-21 22:03:11 +02:00
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2021-12-09 08:46:15 +01:00
w . Write ( [ ] byte ( "Request body: gzip unzip failed" ) )
2021-09-21 22:03:11 +02:00
return
}
2021-12-02 18:13:48 +01:00
client_report , err := mtypes . ParseAPI_report_peerinfo ( client_body )
2021-09-21 22:03:11 +02:00
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2021-12-02 18:13:48 +01:00
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
2021-12-04 04:51:50 +01:00
httpobj . http_PeerState [ PubKey ] . httpPostCount . Store ( client_PostCount + 1 )
2021-12-05 23:32:04 +01:00
httpobj . http_PeerState [ PubKey ] . LastSeen . Store ( time . Now ( ) )
2021-12-02 18:13:48 +01:00
applied_pones := make ( [ ] mtypes . PongMsg , 0 , len ( client_report . Pongs ) )
for _ , pong_msg := range client_report . Pongs {
2021-12-24 20:28:01 +01:00
if pong_msg . Dst_nodeID != NodeID {
if httpobj . http_sconfig . LogLevel . LogControl {
fmt . Printf ( "Control: Dropped because not correct dst: Recv %v S:%v D:%v From: %v IP:%v(HTTP)\n" , pong_msg . ToString ( ) , pong_msg . Src_nodeID . ToString ( ) , pong_msg . Dst_nodeID . ToString ( ) , NodeID . ToString ( ) , r . RemoteAddr )
}
2021-12-02 18:13:48 +01:00
continue
}
2021-12-12 09:29:05 +01:00
if info , has := httpobj . http_PeerID2Info [ pong_msg . Dst_nodeID ] ; has {
2021-12-02 18:13:48 +01:00
AdditionalCost_use := info . AdditionalCost
if AdditionalCost_use >= 0 {
pong_msg . AdditionalCost = AdditionalCost_use
}
applied_pones = append ( applied_pones , pong_msg )
2021-12-07 21:39:19 +01:00
if httpobj . http_sconfig . LogLevel . LogControl {
2021-12-24 20:28:01 +01:00
fmt . Printf ( "Control: Recv %v S:%v D:%v From: %v IP:%v(HTTP)\n" , pong_msg . ToString ( ) , pong_msg . Src_nodeID . ToString ( ) , pong_msg . Dst_nodeID . ToString ( ) , NodeID . ToString ( ) , r . RemoteAddr )
2021-12-07 21:39:19 +01:00
}
2021-12-02 18:13:48 +01:00
}
}
2021-12-07 21:39:19 +01:00
changed := httpobj . http_graph . UpdateLatencyMulti ( applied_pones , true , true )
2021-12-02 18:13:48 +01:00
if changed {
NhTable := httpobj . http_graph . GetNHTable ( true )
NhTablestr , _ := json . Marshal ( NhTable )
2021-12-04 03:32:59 +01:00
md5_hash_raw := md5 . Sum ( append ( NhTablestr , httpobj . http_HashSalt ... ) )
2021-12-02 18:13:48 +01:00
new_hash_str := hex . EncodeToString ( md5_hash_raw [ : ] )
2021-12-04 03:32:59 +01:00
httpobj . http_NhTable_Hash = new_hash_str
2021-12-02 18:13:48 +01:00
httpobj . http_NhTableStr = NhTablestr
PushNhTable ( false )
}
w . WriteHeader ( http . StatusOK )
2021-12-09 08:46:15 +01:00
w . Write ( [ ] byte ( "OK" ) )
2021-12-02 18:13:48 +01:00
}
2021-12-05 22:36:50 +01:00
func checkPassword ( s1 string , s2 string ) bool {
b1 := [ ] byte ( s1 )
b2 := [ ] byte ( s2 )
if len ( b1 ) == 0 || len ( b2 ) == 0 {
return false
}
if len ( b1 ) != len ( b2 ) {
aaa := 0
for _ , c := range b1 {
if c != b2 [ 0 ] {
aaa += 1
}
}
return false
}
pass := true
for i , c := range b1 {
if c != b2 [ i ] {
pass = false
}
}
return pass
}
func manage_get_peerstate ( w http . ResponseWriter , r * http . Request ) {
2021-12-02 18:13:48 +01:00
params := r . URL . Query ( )
password , err := extractParamsStr ( params , "Password" , w )
if err != nil {
2021-09-21 22:03:11 +02:00
return
}
2021-12-09 08:46:15 +01:00
if ! checkPassword ( password , httpobj . http_passwords . ShowState ) {
2021-12-05 22:36:50 +01:00
w . WriteHeader ( http . StatusUnauthorized )
2021-12-09 08:46:15 +01:00
w . Write ( [ ] byte ( "Paramater Password: Wrong password" ) )
2021-12-05 22:36:50 +01:00
return
}
httpobj . RLock ( )
defer httpobj . RUnlock ( )
if time . Now ( ) . After ( httpobj . http_StateExpire ) {
hs := HttpState {
PeerInfo : make ( map [ mtypes . Vertex ] HttpPeerInfo ) ,
NhTable : httpobj . http_graph . GetNHTable ( false ) ,
2021-12-09 08:46:15 +01:00
Infinity : mtypes . Infinity ,
2021-12-05 22:36:50 +01:00
Edges : httpobj . http_graph . GetEdges ( false , false ) ,
Edges_Nh : httpobj . http_graph . GetEdges ( true , true ) ,
Dist : httpobj . http_graph . GetDtst ( ) ,
}
for _ , peerinfo := range httpobj . http_sconfig . Peers {
LastSeenStr := httpobj . http_PeerState [ peerinfo . PubKey ] . LastSeen . Load ( ) . ( time . Time ) . String ( )
hs . PeerInfo [ peerinfo . NodeID ] = HttpPeerInfo {
Name : peerinfo . Name ,
LastSeen : LastSeenStr ,
}
}
httpobj . http_StateExpire = time . Now ( ) . Add ( 5 * time . Second )
httpobj . http_StateString_tmp , _ = json . Marshal ( hs )
}
w . WriteHeader ( http . StatusOK )
w . Write ( httpobj . http_StateString_tmp )
}
func manage_peeradd ( w http . ResponseWriter , r * http . Request ) {
params := r . URL . Query ( )
password , err := extractParamsStr ( params , "Password" , w )
if err != nil {
return
}
2021-12-09 08:46:15 +01:00
if ! checkPassword ( password , httpobj . http_passwords . AddPeer ) {
2021-12-02 18:13:48 +01:00
w . WriteHeader ( http . StatusUnauthorized )
2021-12-09 08:46:15 +01:00
w . Write ( [ ] byte ( "Paramater Password: Wrong password" ) )
2021-12-02 18:13:48 +01:00
return
}
r . ParseForm ( )
2021-12-03 23:46:58 +01:00
NodeID , err := extractParamsVertex ( r . Form , "NodeID" , w )
if err != nil {
return
}
Name , err := extractParamsStr ( r . Form , "Name" , w )
2021-12-02 18:13:48 +01:00
if err != nil {
return
}
2021-12-03 23:46:58 +01:00
AdditionalCost , err := extractParamsFloat ( r . Form , "AdditionalCost" , 64 , w )
2021-12-02 18:13:48 +01:00
if err != nil {
return
}
2021-12-03 23:46:58 +01:00
PubKey , err := extractParamsStr ( r . Form , "PubKey" , w )
2021-12-02 18:13:48 +01:00
if err != nil {
return
}
2021-12-03 23:46:58 +01:00
SkipLocalIPS , err := extractParamsStr ( r . Form , "SkipLocalIP" , w )
2021-12-02 18:13:48 +01:00
if err != nil {
return
}
2021-12-03 23:46:58 +01:00
SkipLocalIP := strings . EqualFold ( SkipLocalIPS , "true" )
2021-12-09 08:46:15 +01:00
PSKey , _ := extractParamsStr ( r . Form , "PSKey" , nil )
2021-12-02 18:13:48 +01:00
httpobj . Lock ( )
defer httpobj . Unlock ( )
for _ , peerinfo := range httpobj . http_sconfig . Peers {
2021-09-21 22:03:11 +02:00
if peerinfo . NodeID == NodeID {
2021-09-30 23:15:23 +02:00
w . WriteHeader ( http . StatusConflict )
2021-12-03 23:46:58 +01:00
w . Write ( [ ] byte ( "Paramater NodeID: NodeID exists" ) )
2021-09-21 22:03:11 +02:00
return
}
if peerinfo . Name == Name {
2021-09-30 23:15:23 +02:00
w . WriteHeader ( http . StatusConflict )
2021-12-03 23:46:58 +01:00
w . Write ( [ ] byte ( "Paramater Name: Node name exists" ) )
2021-09-21 22:03:11 +02:00
return
}
if peerinfo . PubKey == PubKey {
2021-09-30 23:15:23 +02:00
w . WriteHeader ( http . StatusConflict )
2021-12-03 23:46:58 +01:00
w . Write ( [ ] byte ( "Paramater PubKey: PubKey exists" ) )
2021-09-21 22:03:11 +02:00
return
}
}
2021-12-09 08:46:15 +01:00
if httpobj . http_sconfig . GraphRecalculateSetting . StaticMode {
2021-12-03 23:46:58 +01:00
NhTableStr := r . Form . Get ( "NextHopTable" )
2021-09-30 23:15:23 +02:00
if NhTableStr == "" {
w . WriteHeader ( http . StatusExpectationFailed )
2021-12-03 23:46:58 +01:00
w . Write ( [ ] byte ( "Paramater NextHopTable: Your NextHopTable is in static mode.\nPlease provide your new NextHopTable in \"NextHopTable\" parmater in json format" ) )
2021-09-30 23:15:23 +02:00
return
}
2021-12-02 18:13:48 +01:00
var NewNhTable mtypes . NextHopTable
2021-09-30 23:15:23 +02:00
err := json . Unmarshal ( [ ] byte ( NhTableStr ) , & NewNhTable )
if err != nil {
w . WriteHeader ( http . StatusExpectationFailed )
2021-12-03 23:46:58 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater NextHopTable: \"%v\", %v" , NhTableStr , err ) ) )
2021-09-30 23:15:23 +02:00
return
}
2021-12-02 18:13:48 +01:00
err = checkNhTable ( NewNhTable , append ( httpobj . http_sconfig . Peers , mtypes . SuperPeerInfo {
2021-10-27 04:23:14 +02:00
NodeID : NodeID ,
Name : Name ,
PubKey : PubKey ,
PSKey : PSKey ,
AdditionalCost : AdditionalCost ,
2021-12-03 23:46:58 +01:00
SkipLocalIP : SkipLocalIP ,
2021-09-30 23:15:23 +02:00
} ) )
if err != nil {
w . WriteHeader ( http . StatusExpectationFailed )
2021-10-27 04:23:14 +02:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater nexthoptable: \"%v\", %v" , NhTableStr , err ) ) )
2021-09-30 23:15:23 +02:00
return
}
2021-12-04 03:32:59 +01:00
httpobj . http_graph . SetNHTable ( NewNhTable )
2021-09-30 23:15:23 +02:00
}
2021-12-02 18:13:48 +01:00
err = super_peeradd ( mtypes . SuperPeerInfo {
2021-10-27 04:23:14 +02:00
NodeID : NodeID ,
Name : Name ,
PubKey : PubKey ,
PSKey : PSKey ,
AdditionalCost : AdditionalCost ,
2021-12-03 23:46:58 +01:00
SkipLocalIP : SkipLocalIP ,
2021-09-21 22:03:11 +02:00
} )
2021-11-06 10:14:13 +01:00
if err != nil {
w . WriteHeader ( http . StatusExpectationFailed )
w . Write ( [ ] byte ( fmt . Sprintf ( "Error creating peer: %v" , err ) ) )
return
}
2021-12-02 18:13:48 +01:00
httpobj . http_sconfig . Peers = append ( httpobj . http_sconfig . Peers , mtypes . SuperPeerInfo {
2021-10-27 04:23:14 +02:00
NodeID : NodeID ,
Name : Name ,
PubKey : PubKey ,
PSKey : PSKey ,
AdditionalCost : AdditionalCost ,
2021-12-03 23:46:58 +01:00
SkipLocalIP : SkipLocalIP ,
2021-09-23 13:31:01 +02:00
} )
2021-12-02 18:13:48 +01:00
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
2021-12-03 23:46:58 +01:00
httpobj . http_econfig_tmp . DynamicRoute . AdditionalCost = AdditionalCost
httpobj . http_econfig_tmp . DynamicRoute . SuperNode . SkipLocalIP = SkipLocalIP
2021-12-05 22:36:50 +01:00
httpobj . http_econfig_tmp . NextHopTable = make ( mtypes . NextHopTable )
httpobj . http_econfig_tmp . Peers = make ( [ ] mtypes . PeerInfo , 0 )
2021-12-02 18:13:48 +01:00
ret_str_byte , _ := yaml . Marshal ( & httpobj . http_econfig_tmp )
2021-09-23 13:31:01 +02:00
w . WriteHeader ( http . StatusOK )
w . Write ( ret_str_byte )
2021-09-21 22:03:11 +02:00
}
2021-12-05 22:36:50 +01:00
func manage_peerupdate ( w http . ResponseWriter , r * http . Request ) {
params := r . URL . Query ( )
2021-12-09 21:23:02 +01:00
toUpdate := mtypes . NodeID_Broadcast
2021-12-05 22:36:50 +01:00
var err error
var NodeID mtypes . Vertex
password , err := extractParamsStr ( params , "Password" , w )
if err != nil {
return
}
2021-12-09 08:46:15 +01:00
if ! checkPassword ( password , httpobj . http_passwords . UpdatePeer ) {
2021-12-05 22:36:50 +01:00
w . WriteHeader ( http . StatusUnauthorized )
w . Write ( [ ] byte ( "Paramater Password: Wrong password" ) )
return
}
NodeID , err = extractParamsVertex ( params , "NodeID" , w )
if err != nil {
return
}
toUpdate = NodeID
httpobj . Lock ( )
defer httpobj . Unlock ( )
if _ , has := httpobj . http_PeerID2Info [ toUpdate ] ; ! has {
w . WriteHeader ( http . StatusNotFound )
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater NodeID: \"%v\" not found" , NodeID ) ) )
return
}
PubKey := httpobj . http_PeerID2Info [ toUpdate ] . PubKey
Updated_params := make ( map [ string ] string )
new_superpeerinfo := httpobj . http_PeerID2Info [ toUpdate ]
r . ParseForm ( )
AdditionalCost , err := extractParamsFloat ( r . Form , "AdditionalCost" , 64 , nil )
if err == nil {
Updated_params [ "AdditionalCost" ] = fmt . Sprintf ( "%v" , AdditionalCost )
new_superpeerinfo . AdditionalCost = AdditionalCost
}
SkipLocalIP , err := extractParamsStr ( r . Form , "SkipLocalIP" , nil )
if err == nil {
SkipLocalIPVal := strings . EqualFold ( SkipLocalIP , "true" )
Updated_params [ "SkipLocalIP" ] = fmt . Sprintf ( "%v" , SkipLocalIPVal )
new_superpeerinfo . SkipLocalIP = SkipLocalIPVal
}
if len ( Updated_params ) == 0 {
w . WriteHeader ( http . StatusOK )
w . Write ( [ ] byte ( "NodeID: " + toUpdate . ToString ( ) + " , no any paramater updated.\n" ) )
return
}
httpobj . http_PeerID2Info [ toUpdate ] = new_superpeerinfo
SuperParams := mtypes . API_SuperParams {
2021-12-26 17:06:25 +01:00
SendPingInterval : httpobj . http_sconfig . SendPingInterval ,
HttpPostInterval : httpobj . http_sconfig . HttpPostInterval ,
PeerAliveTimeout : httpobj . http_sconfig . PeerAliveTimeout ,
DampingFilterRadius : httpobj . http_sconfig . DampingFilterRadius ,
AdditionalCost : new_superpeerinfo . AdditionalCost ,
2021-12-05 22:36:50 +01:00
}
SuperParamStr , _ := json . Marshal ( SuperParams )
md5_hash_raw := md5 . Sum ( append ( SuperParamStr , httpobj . http_HashSalt ... ) )
new_hash_str := hex . EncodeToString ( md5_hash_raw [ : ] )
httpobj . http_PeerState [ PubKey ] . SuperParamState . Store ( new_hash_str )
var peers_new [ ] mtypes . SuperPeerInfo
for _ , peerinfo := range httpobj . http_sconfig . Peers {
if peerinfo . NodeID == toUpdate {
peers_new = append ( peers_new , new_superpeerinfo )
} else {
peers_new = append ( peers_new , peerinfo )
}
}
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 ( "NodeID: " + toUpdate . ToString ( ) + " updated following values:\n" ) )
for k , v := range Updated_params {
w . Write ( [ ] byte ( fmt . Sprintf ( "%v = %v\n" , k , v ) ) )
}
}
func manage_superupdate ( w http . ResponseWriter , r * http . Request ) {
params := r . URL . Query ( )
var err error
password , err := extractParamsStr ( params , "Password" , w )
if err != nil {
return
}
2021-12-09 08:46:15 +01:00
if ! checkPassword ( password , httpobj . http_passwords . UpdateSuper ) {
2021-12-05 22:36:50 +01:00
w . WriteHeader ( http . StatusUnauthorized )
w . Write ( [ ] byte ( "Paramater Password: Wrong password" ) )
return
}
r . ParseForm ( )
Updated_params := make ( map [ string ] string )
sconfig_temp := mtypes . SuperConfig { }
sconfig_temp . PeerAliveTimeout = httpobj . http_sconfig . PeerAliveTimeout
sconfig_temp . SendPingInterval = httpobj . http_sconfig . SendPingInterval
sconfig_temp . HttpPostInterval = httpobj . http_sconfig . HttpPostInterval
2021-12-26 17:06:25 +01:00
sconfig_temp . DampingFilterRadius = httpobj . http_sconfig . DampingFilterRadius
2021-12-05 22:36:50 +01:00
PeerAliveTimeout , err := extractParamsFloat ( r . Form , "PeerAliveTimeout" , 64 , nil )
if err == nil {
if PeerAliveTimeout <= 0 {
w . WriteHeader ( http . StatusBadRequest )
2021-12-09 08:46:15 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater PeerAliveTimeout %v: Must > 0.\n" , PeerAliveTimeout ) ) )
2021-12-05 22:36:50 +01:00
return
}
Updated_params [ "PeerAliveTimeout" ] = fmt . Sprintf ( "%v" , PeerAliveTimeout )
sconfig_temp . PeerAliveTimeout = PeerAliveTimeout
}
2021-12-26 17:06:25 +01:00
DampingFilterRadius , err := extractParamsUint ( r . Form , "DampingFilterRadius" , 64 , nil )
2021-12-09 23:39:37 +01:00
if err == nil {
2021-12-26 17:06:25 +01:00
Updated_params [ "DampingFilterRadius" ] = fmt . Sprintf ( "%v" , DampingFilterRadius )
sconfig_temp . DampingFilterRadius = DampingFilterRadius
2021-12-09 23:39:37 +01:00
}
2021-12-05 22:36:50 +01:00
SendPingInterval , err := extractParamsFloat ( r . Form , "SendPingInterval" , 64 , nil )
if err == nil {
if SendPingInterval <= 0 || SendPingInterval >= sconfig_temp . PeerAliveTimeout {
w . WriteHeader ( http . StatusBadRequest )
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater SendPingInterval: Must > 0 and < %v(PeerAliveTimeout).\n" , sconfig_temp . PeerAliveTimeout ) ) )
return
}
Updated_params [ "SendPingInterval" ] = fmt . Sprintf ( "%v" , SendPingInterval )
sconfig_temp . SendPingInterval = SendPingInterval
}
HttpPostInterval , err := extractParamsFloat ( r . Form , "HttpPostInterval" , 64 , nil )
if err == nil {
if SendPingInterval <= 0 || SendPingInterval >= sconfig_temp . PeerAliveTimeout {
w . WriteHeader ( http . StatusBadRequest )
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater HttpPostInterval: Must > 0 and < %v(PeerAliveTimeout).\n" , sconfig_temp . PeerAliveTimeout ) ) )
return
}
Updated_params [ "HttpPostInterval" ] = fmt . Sprintf ( "%v" , HttpPostInterval )
sconfig_temp . HttpPostInterval = HttpPostInterval
}
if len ( Updated_params ) == 0 {
w . WriteHeader ( http . StatusOK )
w . Write ( [ ] byte ( "SuperNode: no any paramater updated.\n" ) )
return
}
httpobj . http_sconfig . PeerAliveTimeout = sconfig_temp . PeerAliveTimeout
httpobj . http_sconfig . SendPingInterval = sconfig_temp . SendPingInterval
httpobj . http_sconfig . HttpPostInterval = sconfig_temp . HttpPostInterval
2021-12-26 17:06:25 +01:00
httpobj . http_sconfig . DampingFilterRadius = sconfig_temp . DampingFilterRadius
2021-12-05 22:36:50 +01:00
SuperParams := mtypes . API_SuperParams {
2021-12-26 17:06:25 +01:00
SendPingInterval : httpobj . http_sconfig . SendPingInterval ,
HttpPostInterval : httpobj . http_sconfig . HttpPostInterval ,
PeerAliveTimeout : httpobj . http_sconfig . PeerAliveTimeout ,
DampingFilterRadius : httpobj . http_sconfig . DampingFilterRadius ,
AdditionalCost : 10 ,
2021-12-05 22:36:50 +01:00
}
httpobj . Lock ( )
defer httpobj . Unlock ( )
for _ , peerinfo := range httpobj . http_PeerID2Info {
SuperParams . AdditionalCost = peerinfo . AdditionalCost
PubKey := peerinfo . PubKey
SuperParamStr , _ := json . Marshal ( SuperParams )
md5_hash_raw := md5 . Sum ( append ( SuperParamStr , httpobj . http_HashSalt ... ) )
new_hash_str := hex . EncodeToString ( md5_hash_raw [ : ] )
httpobj . http_PeerState [ PubKey ] . SuperParamState . Store ( new_hash_str )
}
mtypesBytes , _ := yaml . Marshal ( httpobj . http_sconfig )
ioutil . WriteFile ( httpobj . http_sconfig_path , mtypesBytes , 0644 )
w . WriteHeader ( http . StatusOK )
w . Write ( [ ] byte ( "Supernode: updated following values:\n" ) )
for k , v := range Updated_params {
w . Write ( [ ] byte ( fmt . Sprintf ( "%v = %v\n" , k , v ) ) )
}
}
func manage_peerdel ( w http . ResponseWriter , r * http . Request ) {
2021-09-21 22:03:11 +02:00
params := r . URL . Query ( )
2021-12-09 21:23:02 +01:00
toDelete := mtypes . NodeID_Broadcast
2021-12-02 18:13:48 +01:00
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
2021-12-05 22:36:50 +01:00
if checkPassword ( password , httpobj . http_passwords . DelPeer ) {
2021-12-04 03:32:59 +01:00
NodeID , err = extractParamsVertex ( params , "NodeID" , w )
2021-09-21 22:03:11 +02:00
if err != nil {
return
}
toDelete = NodeID
2021-12-02 18:13:48 +01:00
if _ , has := httpobj . http_PeerID2Info [ toDelete ] ; ! has {
w . WriteHeader ( http . StatusNotFound )
2021-12-05 22:36:50 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater NodeID: \"%v\" not found" , NodeID ) ) )
2021-12-02 18:13:48 +01:00
return
}
} else {
w . WriteHeader ( http . StatusUnauthorized )
w . Write ( [ ] byte ( "Paramater Password: Wrong password" ) )
return
}
} else { // user don't provide the password
2021-12-04 03:32:59 +01:00
PrivKey , err = extractParamsStr ( params , "PrivKey" , w )
2021-12-02 18:13:48 +01:00
if err != nil {
return
2021-09-21 22:03:11 +02:00
}
privk , err := device . Str2PriKey ( PrivKey )
if err != nil {
w . WriteHeader ( http . StatusInternalServerError )
2021-12-04 03:32:59 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater PrivKey: %v" , err ) ) )
2021-09-21 22:03:11 +02:00
return
}
pubk := privk . PublicKey ( )
PubKey = pubk . ToString ( )
2021-12-02 18:13:48 +01:00
for _ , peerinfo := range httpobj . http_sconfig . Peers {
2021-09-21 22:03:11 +02:00
if peerinfo . PubKey == PubKey {
toDelete = peerinfo . NodeID
}
}
2021-12-09 21:23:02 +01:00
if toDelete == mtypes . NodeID_Broadcast {
2021-12-02 18:13:48 +01:00
w . WriteHeader ( http . StatusNotFound )
2021-12-04 03:32:59 +01:00
w . Write ( [ ] byte ( fmt . Sprintf ( "Paramater PrivKey: \"%v\" not found" , PubKey ) ) )
2021-12-02 18:13:48 +01:00
return
}
2021-09-21 22:03:11 +02:00
}
2021-12-02 18:13:48 +01:00
var peers_new [ ] mtypes . SuperPeerInfo
for _ , peerinfo := range httpobj . http_sconfig . Peers {
2021-09-21 22:03:11 +02:00
if peerinfo . NodeID == toDelete {
super_peerdel ( peerinfo . NodeID )
} else {
peers_new = append ( peers_new , peerinfo )
}
}
2021-09-30 23:15:23 +02:00
2021-12-02 18:13:48 +01:00
httpobj . http_sconfig . Peers = peers_new
mtypesBytes , _ := yaml . Marshal ( httpobj . http_sconfig )
ioutil . WriteFile ( httpobj . http_sconfig_path , mtypesBytes , 0644 )
2021-09-29 02:23:59 +02:00
w . WriteHeader ( http . StatusOK )
2021-12-04 03:32:59 +01:00
w . Write ( [ ] byte ( "NodeID: " + toDelete . ToString ( ) + " deleted." ) )
2021-09-21 22:03:11 +02:00
}
2021-12-10 19:30:45 +01:00
func HttpServer ( edgeListen string , manageListen string , apiprefix string , errchan chan error ) {
2021-12-04 15:46:36 +01:00
if len ( apiprefix ) > 0 && apiprefix [ 0 ] != '/' {
2021-08-21 16:54:24 +02:00
apiprefix = "/" + apiprefix
}
2021-12-04 15:46:36 +01:00
if len ( edgeListen ) > 0 && edgeListen [ 0 ] != ':' {
edgeListen = ":" + edgeListen
}
if len ( manageListen ) > 0 && manageListen [ 0 ] != ':' {
manageListen = ":" + manageListen
}
if edgeListen == manageListen {
mux := http . NewServeMux ( )
2021-12-05 22:36:50 +01:00
mux . HandleFunc ( apiprefix + "/edge/superparams" , edge_get_superparams )
mux . HandleFunc ( apiprefix + "/edge/peerinfo" , edge_get_peerinfo )
mux . HandleFunc ( apiprefix + "/edge/nhtable" , edge_get_nhtable )
mux . HandleFunc ( apiprefix + "/edge/post/nodeinfo" , edge_post_nodeinfo )
mux . HandleFunc ( apiprefix + "/manage/peer/add" , manage_peeradd )
mux . HandleFunc ( apiprefix + "/manage/peer/del" , manage_peerdel )
mux . HandleFunc ( apiprefix + "/manage/peer/update" , manage_peerupdate )
mux . HandleFunc ( apiprefix + "/manage/super/state" , manage_get_peerstate )
mux . HandleFunc ( apiprefix + "/manage/super/update" , manage_superupdate )
2021-12-10 19:30:45 +01:00
go func ( ) {
err := http . ListenAndServe ( edgeListen , mux )
if err != nil {
errchan <- err
}
} ( )
2021-12-04 15:46:36 +01:00
return
} else {
edgemux := http . NewServeMux ( )
managemux := http . NewServeMux ( )
2021-12-05 22:36:50 +01:00
edgemux . HandleFunc ( apiprefix + "/edge/superparams" , edge_get_superparams )
edgemux . HandleFunc ( apiprefix + "/edge/peerinfo" , edge_get_peerinfo )
edgemux . HandleFunc ( apiprefix + "/edge/nhtable" , edge_get_nhtable )
edgemux . HandleFunc ( apiprefix + "/edge/post/nodeinfo" , edge_post_nodeinfo )
managemux . HandleFunc ( apiprefix + "/manage/peer/add" , manage_peeradd )
managemux . HandleFunc ( apiprefix + "/manage/peer/del" , manage_peerdel )
managemux . HandleFunc ( apiprefix + "/manage/peer/update" , manage_peerupdate )
managemux . HandleFunc ( apiprefix + "/manage/super/state" , manage_get_peerstate )
managemux . HandleFunc ( apiprefix + "/manage/super/update" , manage_superupdate )
2021-12-10 19:30:45 +01:00
go func ( ) {
err := http . ListenAndServe ( edgeListen , edgemux )
if err != nil {
errchan <- err
}
} ( )
2021-12-04 15:46:36 +01:00
if manageListen != "" {
2021-12-10 19:30:45 +01:00
go func ( ) {
err := http . ListenAndServe ( manageListen , managemux )
if err != nil {
errchan <- err
}
} ( )
2021-12-04 15:46:36 +01:00
}
}
2021-08-20 19:32:50 +02:00
}