2021-03-26 00:17:52 +08:00
|
|
|
//TODO: Consider restructuring this file/folder "github.com/gorilla/handlers"
|
|
|
|
|
|
|
|
//It may make more sense to split into different files and not call it "helpers"
|
|
|
|
|
|
|
|
package functions
|
|
|
|
|
|
|
|
import (
|
2021-04-25 06:03:26 +08:00
|
|
|
"encoding/base64"
|
2021-07-14 11:08:10 +08:00
|
|
|
"encoding/json"
|
2021-04-25 06:03:26 +08:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2021-05-26 00:48:04 +08:00
|
|
|
"log"
|
2021-04-25 06:03:26 +08:00
|
|
|
"math/rand"
|
|
|
|
"net"
|
|
|
|
"strings"
|
|
|
|
"time"
|
2021-07-15 04:47:05 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
"github.com/gravitl/netmaker/database"
|
2021-04-25 06:03:26 +08:00
|
|
|
"github.com/gravitl/netmaker/models"
|
2021-05-06 08:41:28 +08:00
|
|
|
"github.com/gravitl/netmaker/servercfg"
|
2021-03-26 00:17:52 +08:00
|
|
|
)
|
|
|
|
|
2021-08-03 02:50:01 +08:00
|
|
|
func CheckEndpoint(endpoint string) bool {
|
2021-08-03 06:06:26 +08:00
|
|
|
endpointarr := strings.Split(endpoint, ":")
|
2021-08-07 00:15:44 +08:00
|
|
|
return len(endpointarr) == 2
|
2021-08-03 02:50:01 +08:00
|
|
|
}
|
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
func PrintUserLog(username string, message string, loglevel int) {
|
|
|
|
log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
|
|
|
|
if int32(loglevel) <= servercfg.GetVerbose() && servercfg.GetVerbose() != 0 {
|
|
|
|
log.Println(username, message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 06:55:19 +08:00
|
|
|
func ParseNetwork(value string) (models.Network, error) {
|
|
|
|
var network models.Network
|
|
|
|
err := json.Unmarshal([]byte(value), &network)
|
|
|
|
return network, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParseNode(value string) (models.Node, error) {
|
|
|
|
var node models.Node
|
|
|
|
err := json.Unmarshal([]byte(value), &node)
|
|
|
|
return node, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParseExtClient(value string) (models.ExtClient, error) {
|
|
|
|
var extClient models.ExtClient
|
|
|
|
err := json.Unmarshal([]byte(value), &extClient)
|
|
|
|
return extClient, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParseIntClient(value string) (models.IntClient, error) {
|
|
|
|
var intClient models.IntClient
|
|
|
|
err := json.Unmarshal([]byte(value), &intClient)
|
|
|
|
return intClient, err
|
|
|
|
}
|
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//Takes in an arbitrary field and value for field and checks to see if any other
|
2021-04-13 12:42:35 +08:00
|
|
|
//node has that value for the same field within the network
|
2021-04-07 07:13:34 +08:00
|
|
|
|
2021-07-24 06:24:34 +08:00
|
|
|
func GetUser(username string) (models.User, error) {
|
|
|
|
|
|
|
|
var user models.User
|
|
|
|
record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
|
|
|
|
if err != nil {
|
|
|
|
return user, err
|
|
|
|
}
|
|
|
|
if err = json.Unmarshal([]byte(record), &user); err != nil {
|
|
|
|
return models.User{}, err
|
|
|
|
}
|
|
|
|
return user, err
|
|
|
|
}
|
|
|
|
|
2021-07-02 12:03:46 +08:00
|
|
|
func SliceContains(slice []string, item string) bool {
|
2021-07-15 04:47:05 +08:00
|
|
|
set := make(map[string]struct{}, len(slice))
|
|
|
|
for _, s := range slice {
|
|
|
|
set[s] = struct{}{}
|
|
|
|
}
|
2021-07-02 12:03:46 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
_, ok := set[item]
|
|
|
|
return ok
|
2021-07-02 12:03:46 +08:00
|
|
|
}
|
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
func CreateServerToken(netID string) (string, error) {
|
2021-04-25 06:03:26 +08:00
|
|
|
var network models.Network
|
|
|
|
var accesskey models.AccessKey
|
2021-04-07 07:13:34 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
network, err := GetParentNetwork(netID)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2021-04-07 07:13:34 +08:00
|
|
|
|
2021-07-14 11:08:10 +08:00
|
|
|
var accessToken models.AccessToken
|
2021-07-15 04:49:57 +08:00
|
|
|
servervals := models.ServerConfig{
|
2021-07-27 02:15:58 +08:00
|
|
|
APIConnString: "127.0.0.1:" + servercfg.GetAPIPort(),
|
|
|
|
GRPCConnString: "127.0.0.1:" + servercfg.GetGRPCPort(),
|
2021-07-15 04:49:57 +08:00
|
|
|
GRPCSSL: "off",
|
2021-07-14 11:08:10 +08:00
|
|
|
}
|
2021-07-15 04:49:57 +08:00
|
|
|
accessToken.ServerConfig = servervals
|
|
|
|
accessToken.ClientConfig.Network = netID
|
|
|
|
accessToken.ClientConfig.Key = GenKey()
|
2021-07-14 11:08:10 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
accesskey.Name = GenKeyName()
|
2021-07-27 02:31:41 +08:00
|
|
|
accesskey.Value = accessToken.ClientConfig.Key
|
2021-04-25 06:03:26 +08:00
|
|
|
accesskey.Uses = 1
|
2021-04-15 21:48:14 +08:00
|
|
|
|
2021-07-15 04:49:57 +08:00
|
|
|
tokenjson, err := json.Marshal(accessToken)
|
|
|
|
if err != nil {
|
|
|
|
return accesskey.AccessString, err
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
2021-04-15 21:48:14 +08:00
|
|
|
|
2021-07-15 04:49:57 +08:00
|
|
|
accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(tokenjson))
|
2021-04-15 21:48:14 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
network.AccessKeys = append(network.AccessKeys, accesskey)
|
2021-07-21 05:18:45 +08:00
|
|
|
if data, err := json.Marshal(network); err != nil {
|
|
|
|
return "", err
|
|
|
|
} else {
|
|
|
|
database.Insert(netID, string(data), database.NETWORKS_TABLE_NAME)
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
2021-04-07 07:13:34 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
return accesskey.AccessString, nil
|
2021-04-07 07:13:34 +08:00
|
|
|
}
|
|
|
|
|
2021-05-26 00:48:04 +08:00
|
|
|
func GetPeersList(networkName string) ([]models.PeersResponse, error) {
|
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
var peers []models.PeersResponse
|
2021-07-21 05:18:45 +08:00
|
|
|
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
return peers, err
|
|
|
|
}
|
2021-05-26 00:48:04 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
for _, value := range collection {
|
2021-05-26 00:48:04 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
var peer models.PeersResponse
|
2021-07-21 05:18:45 +08:00
|
|
|
err := json.Unmarshal([]byte(value), &peer)
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
2021-07-21 05:18:45 +08:00
|
|
|
continue // try the rest
|
2021-07-15 04:47:05 +08:00
|
|
|
}
|
|
|
|
peers = append(peers, peer)
|
|
|
|
}
|
2021-05-26 00:48:04 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
return peers, err
|
2021-05-26 00:48:04 +08:00
|
|
|
}
|
|
|
|
|
2021-05-28 02:54:24 +08:00
|
|
|
func GetIntPeersList() ([]models.PeersResponse, error) {
|
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
var peers []models.PeersResponse
|
2021-07-21 05:18:45 +08:00
|
|
|
records, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
|
2021-05-28 02:54:24 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
return peers, err
|
|
|
|
}
|
2021-07-21 05:18:45 +08:00
|
|
|
// parse the peers
|
2021-05-28 02:54:24 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
for _, value := range records {
|
2021-05-28 02:54:24 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
var peer models.PeersResponse
|
2021-07-21 05:18:45 +08:00
|
|
|
err := json.Unmarshal([]byte(value), &peer)
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
// add the node to our node array
|
|
|
|
//maybe better to just return this? But then that's just GetNodes...
|
|
|
|
peers = append(peers, peer)
|
|
|
|
}
|
2021-05-28 02:54:24 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
return peers, err
|
2021-05-28 02:54:24 +08:00
|
|
|
}
|
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
func GetServerIntClient() (*models.IntClient, error) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
intClients, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
|
|
|
|
for _, value := range intClients {
|
|
|
|
var intClient models.IntClient
|
|
|
|
err = json.Unmarshal([]byte(value), &intClient)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if intClient.IsServer == "yes" && intClient.Network == "comms" {
|
|
|
|
return &intClient, nil
|
2021-07-15 04:47:05 +08:00
|
|
|
}
|
|
|
|
}
|
2021-07-21 05:18:45 +08:00
|
|
|
return nil, err
|
2021-05-28 02:54:24 +08:00
|
|
|
}
|
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
func NetworkExists(name string) (bool, error) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
var network string
|
|
|
|
var err error
|
|
|
|
if network, err = database.FetchRecord(database.NETWORKS_TABLE_NAME, name); err != nil {
|
|
|
|
return false, err
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-07-21 05:18:45 +08:00
|
|
|
return len(network) > 0, nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-07-22 06:55:19 +08:00
|
|
|
func GetRecordKey(id string, network string) (string, error) {
|
|
|
|
if id == "" || network == "" {
|
|
|
|
return "", errors.New("unable to get record key")
|
|
|
|
}
|
|
|
|
return id + "###" + network, nil
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
func UpdateNetworkNodeAddresses(networkName string) error {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
for _, value := range collections {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var node models.Node
|
2021-07-21 05:18:45 +08:00
|
|
|
err := json.Unmarshal([]byte(value), &node)
|
2021-03-26 00:17:52 +08:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
2021-04-25 06:03:26 +08:00
|
|
|
return err
|
|
|
|
}
|
2021-08-06 03:02:18 +08:00
|
|
|
if node.Network == networkName {
|
|
|
|
ipaddr, iperr := UniqueAddress(networkName)
|
|
|
|
if iperr != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
|
|
|
return iperr
|
|
|
|
}
|
|
|
|
|
|
|
|
node.Address = ipaddr
|
|
|
|
data, err := json.Marshal(&node)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
node.SetID()
|
|
|
|
database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
return nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-04-25 06:03:26 +08:00
|
|
|
|
2021-08-07 01:39:14 +08:00
|
|
|
func NetworkNodesUpdateAction(networkName string, action string) error {
|
2021-08-03 06:06:26 +08:00
|
|
|
|
|
|
|
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
|
|
|
if err != nil {
|
2021-08-06 03:02:18 +08:00
|
|
|
if database.IsEmptyRecord(err) {
|
|
|
|
return nil
|
|
|
|
}
|
2021-08-03 06:06:26 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, value := range collections {
|
|
|
|
var node models.Node
|
|
|
|
err := json.Unmarshal([]byte(value), &node)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
|
|
|
return err
|
|
|
|
}
|
2021-08-10 02:13:19 +08:00
|
|
|
if action == models.NODE_UPDATE_KEY && node.IsStatic == "yes" {
|
2021-08-10 00:43:09 +08:00
|
|
|
continue
|
|
|
|
}
|
2021-08-06 03:02:18 +08:00
|
|
|
if node.Network == networkName {
|
2021-08-07 01:39:14 +08:00
|
|
|
node.Action = action
|
2021-08-06 03:02:18 +08:00
|
|
|
data, err := json.Marshal(&node)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
node.SetID()
|
|
|
|
database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
|
2021-08-03 06:06:26 +08:00
|
|
|
}
|
2021-08-10 10:31:01 +08:00
|
|
|
}
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-07 01:47:39 +08:00
|
|
|
func NetworkNodesUpdatePullChanges(networkName string) error {
|
|
|
|
|
|
|
|
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
|
|
|
if err != nil {
|
|
|
|
if database.IsEmptyRecord(err) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, value := range collections {
|
|
|
|
var node models.Node
|
|
|
|
err := json.Unmarshal([]byte(value), &node)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if node.Network == networkName {
|
|
|
|
node.PullChanges = "yes"
|
|
|
|
data, err := json.Marshal(&node)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
node.SetID()
|
|
|
|
database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
func UpdateNetworkLocalAddresses(networkName string) error {
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
for _, value := range collection {
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var node models.Node
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
err := json.Unmarshal([]byte(value), &node)
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
|
|
|
return err
|
|
|
|
}
|
2021-08-06 03:02:18 +08:00
|
|
|
if node.Network == networkName {
|
|
|
|
ipaddr, iperr := UniqueAddress(networkName)
|
|
|
|
if iperr != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
|
|
|
return iperr
|
|
|
|
}
|
|
|
|
|
|
|
|
node.Address = ipaddr
|
|
|
|
newNodeData, err := json.Marshal(&node)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("error in node address assignment!")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
node.SetID()
|
|
|
|
database.Insert(node.ID, string(newNodeData), database.NODES_TABLE_NAME)
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
|
|
|
}
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
return nil
|
2021-04-13 11:19:01 +08:00
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
func IsNetworkDisplayNameUnique(name string) (bool, error) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
isunique := true
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-07-24 06:24:34 +08:00
|
|
|
dbs, err := models.GetNetworks()
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
2021-08-06 00:52:50 +08:00
|
|
|
return database.IsEmptyRecord(err), err
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
for i := 0; i < len(dbs); i++ {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
if name == dbs[i].DisplayName {
|
|
|
|
isunique = false
|
|
|
|
}
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
return isunique, nil
|
2021-04-13 11:19:01 +08:00
|
|
|
}
|
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
func IsMacAddressUnique(macaddress string, networkName string) (bool, error) {
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-08-06 00:52:50 +08:00
|
|
|
_, err := database.FetchRecord(database.NODES_TABLE_NAME, macaddress+"###"+networkName)
|
2021-07-21 05:18:45 +08:00
|
|
|
if err != nil {
|
2021-08-06 00:52:50 +08:00
|
|
|
return database.IsEmptyRecord(err), err
|
2021-07-21 05:18:45 +08:00
|
|
|
}
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
return true, nil
|
|
|
|
}
|
2021-04-13 11:19:01 +08:00
|
|
|
|
2021-08-06 01:11:21 +08:00
|
|
|
func GetNetworkNodeCount(networkName string) (int, error) {
|
|
|
|
|
|
|
|
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
|
|
|
count := 0
|
|
|
|
if err != nil && !database.IsEmptyRecord(err) {
|
|
|
|
return count, err
|
|
|
|
}
|
|
|
|
for _, value := range collection {
|
|
|
|
var node models.Node
|
|
|
|
if err = json.Unmarshal([]byte(value), &node); err != nil {
|
|
|
|
return count, err
|
|
|
|
} else {
|
|
|
|
if node.Network == networkName {
|
|
|
|
count++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return count, nil
|
|
|
|
}
|
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//Checks to see if access key is valid
|
|
|
|
//Does so by checking against all keys and seeing if any have the same value
|
|
|
|
//may want to hash values before comparing...consider this
|
|
|
|
//TODO: No error handling!!!!
|
2021-04-25 06:03:26 +08:00
|
|
|
func IsKeyValid(networkname string, keyvalue string) bool {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
network, _ := GetParentNetwork(networkname)
|
2021-03-26 00:17:52 +08:00
|
|
|
var key models.AccessKey
|
|
|
|
foundkey := false
|
|
|
|
isvalid := false
|
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
for i := len(network.AccessKeys) - 1; i >= 0; i-- {
|
2021-04-25 06:03:26 +08:00
|
|
|
currentkey := network.AccessKeys[i]
|
|
|
|
if currentkey.Value == keyvalue {
|
2021-03-26 00:17:52 +08:00
|
|
|
key = currentkey
|
|
|
|
foundkey = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if foundkey {
|
|
|
|
if key.Uses > 0 {
|
2021-04-25 06:03:26 +08:00
|
|
|
isvalid = true
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return isvalid
|
|
|
|
}
|
2021-04-25 06:03:26 +08:00
|
|
|
|
2021-05-26 00:48:04 +08:00
|
|
|
func IsKeyValidGlobal(keyvalue string) bool {
|
|
|
|
|
2021-07-24 06:24:34 +08:00
|
|
|
networks, _ := models.GetNetworks()
|
2021-07-15 04:47:05 +08:00
|
|
|
var key models.AccessKey
|
|
|
|
foundkey := false
|
|
|
|
isvalid := false
|
2021-05-26 00:48:04 +08:00
|
|
|
for _, network := range networks {
|
|
|
|
for i := len(network.AccessKeys) - 1; i >= 0; i-- {
|
2021-07-15 04:47:05 +08:00
|
|
|
currentkey := network.AccessKeys[i]
|
|
|
|
if currentkey.Value == keyvalue {
|
|
|
|
key = currentkey
|
|
|
|
foundkey = true
|
2021-05-26 00:48:04 +08:00
|
|
|
break
|
2021-07-15 04:47:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if foundkey {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if foundkey {
|
|
|
|
if key.Uses > 0 {
|
|
|
|
isvalid = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return isvalid
|
2021-05-26 00:48:04 +08:00
|
|
|
}
|
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//TODO: Contains a fatal error return. Need to change
|
2021-04-13 12:42:35 +08:00
|
|
|
//This just gets a network object from a network name
|
2021-04-25 06:03:26 +08:00
|
|
|
//Should probably just be GetNetwork. kind of a dumb name.
|
2021-04-13 12:42:35 +08:00
|
|
|
//Used in contexts where it's not the Parent network.
|
|
|
|
func GetParentNetwork(networkname string) (models.Network, error) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var network models.Network
|
2021-07-21 05:18:45 +08:00
|
|
|
networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
return network, err
|
|
|
|
}
|
2021-07-22 06:55:19 +08:00
|
|
|
if err = json.Unmarshal([]byte(networkData), &network); err != nil {
|
|
|
|
return models.Network{}, err
|
2021-07-21 05:18:45 +08:00
|
|
|
}
|
2021-04-25 06:03:26 +08:00
|
|
|
return network, nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
2021-04-28 11:17:59 +08:00
|
|
|
func IsIpNet(host string) bool {
|
2021-04-25 06:03:26 +08:00
|
|
|
return net.ParseIP(host) != nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//Similar to above but checks if Cidr range is valid
|
|
|
|
//At least this guy's got some print statements
|
|
|
|
//still not good error handling
|
2021-04-28 11:17:59 +08:00
|
|
|
func IsIpCIDR(host string) bool {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
ip, ipnet, err := net.ParseCIDR(host)
|
2021-03-26 00:17:52 +08:00
|
|
|
|
|
|
|
if err != nil {
|
2021-04-25 06:03:26 +08:00
|
|
|
fmt.Println(err)
|
|
|
|
fmt.Println("Address Range is not valid!")
|
|
|
|
return false
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
return ip != nil && ipnet != nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//This is used to validate public keys (make sure they're base64 encoded like all public keys should be).
|
|
|
|
func IsBase64(s string) bool {
|
|
|
|
_, err := base64.StdEncoding.DecodeString(s)
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
//This checks to make sure a network name is valid.
|
2021-03-26 00:17:52 +08:00
|
|
|
//Switch to REGEX?
|
2021-04-25 06:03:26 +08:00
|
|
|
func NameInNetworkCharSet(name string) bool {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-11 12:49:31 +08:00
|
|
|
charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
|
2021-03-26 00:17:52 +08:00
|
|
|
|
|
|
|
for _, char := range name {
|
|
|
|
if !strings.Contains(charset, strings.ToLower(string(char))) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-04-27 11:39:15 +08:00
|
|
|
func NameInDNSCharSet(name string) bool {
|
|
|
|
|
2021-05-01 19:57:49 +08:00
|
|
|
charset := "abcdefghijklmnopqrstuvwxyz1234567890-."
|
2021-04-27 11:39:15 +08:00
|
|
|
|
2021-05-01 19:57:49 +08:00
|
|
|
for _, char := range name {
|
|
|
|
if !strings.Contains(charset, strings.ToLower(string(char))) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
2021-04-27 11:39:15 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
func NameInNodeCharSet(name string) bool {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
charset := "abcdefghijklmnopqrstuvwxyz1234567890-"
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
for _, char := range name {
|
|
|
|
if !strings.Contains(charset, strings.ToLower(string(char))) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//This returns a node based on its mac address.
|
|
|
|
//The mac address acts as the Unique ID for nodes.
|
|
|
|
//Is this a dumb thing to do? I thought it was cool but maybe it's dumb.
|
|
|
|
//It doesn't really provide a tangible benefit over a random ID
|
2021-04-13 12:42:35 +08:00
|
|
|
func GetNodeByMacAddress(network string, macaddress string) (models.Node, error) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var node models.Node
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-24 06:24:34 +08:00
|
|
|
key, err := GetRecordKey(macaddress, network)
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
return node, err
|
|
|
|
}
|
2021-07-21 05:18:45 +08:00
|
|
|
|
2021-07-24 06:24:34 +08:00
|
|
|
record, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
|
|
|
|
if err != nil {
|
|
|
|
return models.Node{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = json.Unmarshal([]byte(record), &node); err != nil {
|
|
|
|
return models.Node{}, err
|
2021-07-21 05:18:45 +08:00
|
|
|
}
|
|
|
|
|
2021-07-24 06:24:34 +08:00
|
|
|
return node, nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
2021-08-10 10:31:01 +08:00
|
|
|
func GetDeletedNodeByMacAddress(network string, macaddress string) (models.Node, error) {
|
|
|
|
|
|
|
|
var node models.Node
|
|
|
|
|
|
|
|
key, err := GetRecordKey(macaddress, network)
|
|
|
|
if err != nil {
|
|
|
|
return node, err
|
|
|
|
}
|
|
|
|
|
|
|
|
record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
|
|
|
|
if err != nil {
|
|
|
|
return models.Node{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = json.Unmarshal([]byte(record), &node); err != nil {
|
|
|
|
return models.Node{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return node, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func RemoveDeletedNode(nodeid string) bool {
|
|
|
|
return database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, nodeid) == nil
|
|
|
|
}
|
|
|
|
|
2021-05-28 02:54:24 +08:00
|
|
|
func DeleteAllIntClients() error {
|
2021-07-21 05:18:45 +08:00
|
|
|
err := database.DeleteAllRecords(database.INT_CLIENTS_TABLE_NAME)
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2021-05-28 02:54:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func GetAllIntClients() ([]models.IntClient, error) {
|
2021-07-15 04:47:05 +08:00
|
|
|
var clients []models.IntClient
|
2021-07-21 05:18:45 +08:00
|
|
|
collection, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
|
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
2021-07-21 05:18:45 +08:00
|
|
|
return clients, err
|
2021-07-15 04:47:05 +08:00
|
|
|
}
|
2021-07-21 05:18:45 +08:00
|
|
|
|
|
|
|
for _, value := range collection {
|
|
|
|
var client models.IntClient
|
|
|
|
err := json.Unmarshal([]byte(value), &client)
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
return []models.IntClient{}, err
|
|
|
|
}
|
|
|
|
// add node to our array
|
|
|
|
clients = append(clients, client)
|
|
|
|
}
|
|
|
|
|
|
|
|
return clients, nil
|
2021-05-28 02:54:24 +08:00
|
|
|
}
|
|
|
|
|
2021-05-20 01:59:10 +08:00
|
|
|
func GetAllExtClients() ([]models.ExtClient, error) {
|
2021-07-15 04:47:05 +08:00
|
|
|
var extclients []models.ExtClient
|
2021-07-21 05:18:45 +08:00
|
|
|
collection, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
|
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
2021-07-21 05:18:45 +08:00
|
|
|
return extclients, err
|
2021-07-15 04:47:05 +08:00
|
|
|
}
|
2021-07-21 05:18:45 +08:00
|
|
|
|
|
|
|
for _, value := range collection {
|
|
|
|
var extclient models.ExtClient
|
|
|
|
err := json.Unmarshal([]byte(value), &extclient)
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
return []models.ExtClient{}, err
|
|
|
|
}
|
|
|
|
// add node to our array
|
|
|
|
extclients = append(extclients, extclient)
|
|
|
|
}
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
return extclients, nil
|
|
|
|
}
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//This returns a unique address for a node to use
|
|
|
|
//it iterates through the list of IP's in the subnet
|
|
|
|
//and checks against all nodes to see if it's taken, until it finds one.
|
|
|
|
//TODO: We do not handle a case where we run out of addresses.
|
|
|
|
//We will need to handle that eventually
|
2021-04-25 06:03:26 +08:00
|
|
|
func UniqueAddress(networkName string) (string, error) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
var network models.Network
|
|
|
|
network, err := GetParentNetwork(networkName)
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("UniqueAddress encountered an error")
|
|
|
|
return "666", err
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
|
|
|
offset := true
|
2021-04-13 12:42:35 +08:00
|
|
|
ip, ipnet, err := net.ParseCIDR(network.AddressRange)
|
2021-03-26 00:17:52 +08:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("UniqueAddress encountered an error")
|
|
|
|
return "666", err
|
|
|
|
}
|
|
|
|
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
|
|
|
|
if offset {
|
|
|
|
offset = false
|
|
|
|
continue
|
|
|
|
}
|
2021-07-15 04:47:05 +08:00
|
|
|
if networkName == "comms" {
|
2021-07-21 05:18:45 +08:00
|
|
|
if IsIPUnique(networkName, ip.String(), database.INT_CLIENTS_TABLE_NAME, false) {
|
2021-07-15 04:47:05 +08:00
|
|
|
return ip.String(), err
|
|
|
|
}
|
|
|
|
} else {
|
2021-07-21 05:18:45 +08:00
|
|
|
if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, false) && IsIPUnique(networkName, ip.String(), database.EXT_CLIENT_TABLE_NAME, false) {
|
2021-07-15 04:47:05 +08:00
|
|
|
return ip.String(), err
|
|
|
|
}
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-05-28 02:56:08 +08:00
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//TODO
|
2021-04-13 12:42:35 +08:00
|
|
|
err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
|
2021-03-26 00:17:52 +08:00
|
|
|
return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
|
|
|
|
}
|
|
|
|
|
2021-04-28 11:17:59 +08:00
|
|
|
func UniqueAddress6(networkName string) (string, error) {
|
|
|
|
|
2021-05-01 19:57:49 +08:00
|
|
|
var network models.Network
|
|
|
|
network, err := GetParentNetwork(networkName)
|
2021-04-28 11:40:01 +08:00
|
|
|
if err != nil {
|
2021-05-09 22:52:42 +08:00
|
|
|
fmt.Println("Network Not Found")
|
|
|
|
return "", err
|
|
|
|
}
|
2021-07-24 06:24:34 +08:00
|
|
|
if network.IsDualStack == "no" {
|
2021-08-11 01:32:35 +08:00
|
|
|
return "", nil
|
2021-05-01 19:57:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
offset := true
|
|
|
|
ip, ipnet, err := net.ParseCIDR(network.AddressRange6)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("UniqueAddress6 encountered an error")
|
|
|
|
return "666", err
|
|
|
|
}
|
|
|
|
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
|
|
|
|
if offset {
|
|
|
|
offset = false
|
|
|
|
continue
|
|
|
|
}
|
2021-08-11 01:32:35 +08:00
|
|
|
if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, true) {
|
|
|
|
return ip.String(), err
|
2021-05-01 19:57:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
//TODO
|
|
|
|
err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
|
|
|
|
return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
|
2021-04-28 11:17:59 +08:00
|
|
|
}
|
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//generate an access key value
|
|
|
|
func GenKey() string {
|
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var seededRand *rand.Rand = rand.New(
|
|
|
|
rand.NewSource(time.Now().UnixNano()))
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
length := 16
|
|
|
|
charset := "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
b := make([]byte, length)
|
|
|
|
for i := range b {
|
|
|
|
b[i] = charset[seededRand.Intn(len(charset))]
|
|
|
|
}
|
|
|
|
return string(b)
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//generate a key value
|
|
|
|
//we should probably just have 1 random string generator
|
|
|
|
//that can be used across all functions
|
|
|
|
//have a "base string" a "length" and a "charset"
|
|
|
|
func GenKeyName() string {
|
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var seededRand *rand.Rand = rand.New(
|
|
|
|
rand.NewSource(time.Now().UnixNano()))
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
length := 5
|
|
|
|
charset := "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
b := make([]byte, length)
|
|
|
|
for i := range b {
|
|
|
|
b[i] = charset[seededRand.Intn(len(charset))]
|
|
|
|
}
|
2021-05-01 19:57:49 +08:00
|
|
|
return "key" + string(b)
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
isunique := true
|
2021-07-21 05:18:45 +08:00
|
|
|
collection, err := database.FetchRecords(tableName)
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
if err != nil {
|
|
|
|
return isunique
|
|
|
|
}
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
for _, value := range collection { // filter
|
|
|
|
var node models.Node
|
|
|
|
if err = json.Unmarshal([]byte(value), &node); err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if isIpv6 {
|
|
|
|
if node.Address6 == ip && node.Network == network {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if node.Address == ip && node.Network == network {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
2021-07-15 04:47:05 +08:00
|
|
|
}
|
2021-05-30 03:06:35 +08:00
|
|
|
|
2021-07-15 04:47:05 +08:00
|
|
|
return isunique
|
2021-05-30 03:06:35 +08:00
|
|
|
}
|
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//called once key has been used by createNode
|
|
|
|
//reduces value by one and deletes if necessary
|
2021-04-13 12:42:35 +08:00
|
|
|
func DecrimentKey(networkName string, keyvalue string) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
var network models.Network
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
network, err := GetParentNetwork(networkName)
|
2021-04-25 06:03:26 +08:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
for i := len(network.AccessKeys) - 1; i >= 0; i-- {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-25 06:03:26 +08:00
|
|
|
currentkey := network.AccessKeys[i]
|
|
|
|
if currentkey.Value == keyvalue {
|
|
|
|
network.AccessKeys[i].Uses--
|
2021-04-13 12:42:35 +08:00
|
|
|
if network.AccessKeys[i].Uses < 1 {
|
2021-07-21 05:18:45 +08:00
|
|
|
network.AccessKeys = append(network.AccessKeys[:i],
|
|
|
|
network.AccessKeys[i+1:]...)
|
|
|
|
break
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
if newNetworkData, err := json.Marshal(&network); err != nil {
|
2021-08-10 00:43:09 +08:00
|
|
|
PrintUserLog(models.NODE_SERVER_NAME, "failed to decrement key", 2)
|
2021-04-25 06:03:26 +08:00
|
|
|
return
|
2021-07-21 05:18:45 +08:00
|
|
|
} else {
|
|
|
|
database.Insert(network.NetID, string(newNetworkData), database.NETWORKS_TABLE_NAME)
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-04-25 06:03:26 +08:00
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//takes the logic from controllers.deleteKey
|
2021-04-13 12:42:35 +08:00
|
|
|
func DeleteKey(network models.Network, i int) {
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-04-13 12:42:35 +08:00
|
|
|
network.AccessKeys = append(network.AccessKeys[:i],
|
2021-04-25 06:03:26 +08:00
|
|
|
network.AccessKeys[i+1:]...)
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2021-07-21 05:18:45 +08:00
|
|
|
if networkData, err := json.Marshal(&network); err != nil {
|
2021-04-25 06:03:26 +08:00
|
|
|
return
|
2021-07-21 05:18:45 +08:00
|
|
|
} else {
|
|
|
|
database.Insert(network.NetID, string(networkData), database.NETWORKS_TABLE_NAME)
|
2021-04-25 06:03:26 +08:00
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-04-25 06:03:26 +08:00
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
//increments an IP over the previous
|
|
|
|
func Inc(ip net.IP) {
|
2021-04-25 06:03:26 +08:00
|
|
|
for j := len(ip) - 1; j >= 0; j-- {
|
2021-03-26 00:17:52 +08:00
|
|
|
ip[j]++
|
|
|
|
if ip[j] > 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|