Browse Source

adding ipv6 details. Need to test now

afeiszli 4 years ago
parent
commit
a0dd5929cb

+ 35 - 13
controllers/common.go

@@ -62,21 +62,26 @@ func ValidateNodeCreate(networkName string, node models.Node) error {
 
 
 	v := validator.New()
 	v := validator.New()
 	_ = v.RegisterValidation("address_check", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("address_check", func(fl validator.FieldLevel) bool {
-		isIpv4 := functions.IsIpv4Net(node.Address)
+		isIpv4 := functions.IsIpNet(node.Address)
 		empty := node.Address == ""
 		empty := node.Address == ""
 		return (empty || isIpv4)
 		return (empty || isIpv4)
 	})
 	})
+        _ = v.RegisterValidation("address6_check", func(fl validator.FieldLevel) bool {
+                isIpv6 := functions.IsIpNet(node.Address6)
+                empty := node.Address6 == ""
+                return (empty || isIpv6)
+        })
 	_ = v.RegisterValidation("endpoint_check", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("endpoint_check", func(fl validator.FieldLevel) bool {
 		//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
 		//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
-		isIpv4 := functions.IsIpv4Net(node.Endpoint)
+		isIp := functions.IsIpNet(node.Endpoint)
 		notEmptyCheck := node.Endpoint != ""
 		notEmptyCheck := node.Endpoint != ""
-		return (notEmptyCheck && isIpv4)
+		return (notEmptyCheck && isIp)
 	})
 	})
 	_ = v.RegisterValidation("localaddress_check", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("localaddress_check", func(fl validator.FieldLevel) bool {
 		//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
 		//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
-		isIpv4 := functions.IsIpv4Net(node.LocalAddress)
+		isIp := functions.IsIpNet(node.LocalAddress)
 		empty := node.LocalAddress == ""
 		empty := node.LocalAddress == ""
-		return (empty || isIpv4)
+		return (empty || isIp)
 	})
 	})
 
 
 	_ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
@@ -123,23 +128,27 @@ func ValidateNodeUpdate(networkName string, node models.Node) error {
 
 
         v := validator.New()
         v := validator.New()
         _ = v.RegisterValidation("address_check", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("address_check", func(fl validator.FieldLevel) bool {
-                isIpv4 := functions.IsIpv4Net(node.Address)
+                isIpv4 := functions.IsIpNet(node.Address)
                 empty := node.Address == ""
                 empty := node.Address == ""
                 return (empty || isIpv4)
                 return (empty || isIpv4)
         })
         })
+        _ = v.RegisterValidation("address6_check", func(fl validator.FieldLevel) bool {
+                isIpv6 := functions.IsIpNet(node.Address6)
+                empty := node.Address6 == ""
+                return (empty || isIpv6)
+        })
         _ = v.RegisterValidation("endpoint_check", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("endpoint_check", func(fl validator.FieldLevel) bool {
                 //var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
                 //var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
-                isIpv4 := functions.IsIpv4Net(node.Endpoint)
-                empty := node.Endpoint == ""
-                return (empty || isIpv4)
+                isIp := functions.IsIpNet(node.Address)
+		empty := node.Endpoint == ""
+                return (empty || isIp)
         })
         })
         _ = v.RegisterValidation("localaddress_check", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("localaddress_check", func(fl validator.FieldLevel) bool {
                 //var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
                 //var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
-                isIpv4 := functions.IsIpv4Net(node.LocalAddress)
+                isIp := functions.IsIpNet(node.LocalAddress)
                 empty := node.LocalAddress == ""
                 empty := node.LocalAddress == ""
-                return (empty || isIpv4)
+                return (empty || isIp )
         })
         })
-
         _ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
                 return true
                 return true
         })
         })
@@ -190,6 +199,10 @@ func UpdateNode(nodechange models.Node, node models.Node) (models.Node, error) {
 		node.Address = nodechange.Address
 		node.Address = nodechange.Address
 		notifynetwork = true
 		notifynetwork = true
 	}
 	}
+        if nodechange.Address6 != "" {
+                node.Address6 = nodechange.Address6
+                notifynetwork = true
+        }
 	if nodechange.Name != "" {
 	if nodechange.Name != "" {
 		node.Name = nodechange.Name
 		node.Name = nodechange.Name
 	}
 	}
@@ -258,6 +271,7 @@ func UpdateNode(nodechange models.Node, node models.Node) (models.Node, error) {
 	update := bson.D{
 	update := bson.D{
 		{"$set", bson.D{
 		{"$set", bson.D{
 			{"address", node.Address},
 			{"address", node.Address},
+			{"address6", node.Address6},
 			{"name", node.Name},
 			{"name", node.Name},
 			{"password", node.Password},
 			{"password", node.Password},
 			{"listenport", node.ListenPort},
 			{"listenport", node.ListenPort},
@@ -355,7 +369,6 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
 	//Umm, why am I doing this again?
 	//Umm, why am I doing this again?
 	//TODO: Why am I using a local function instead of the struct function? I really dont know.
 	//TODO: Why am I using a local function instead of the struct function? I really dont know.
 	//I think I thought it didn't work but uhhh...idk
 	//I think I thought it didn't work but uhhh...idk
-	//anyways, this sets some sensible variables for unset params.
 	node.SetDefaults()
 	node.SetDefaults()
 
 
 	//Another DB call here...Inefficient
 	//Another DB call here...Inefficient
@@ -366,6 +379,15 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
 	if err != nil {
 	if err != nil {
 		return node, err
 		return node, err
 	}
 	}
+        fmt.Println("Setting node address: " + node.Address)
+
+        node.Address6, err = functions.UniqueAddress6(networkName)
+        if node.Address6 != "" {
+		fmt.Println("Setting node ipv6 address: " + node.Address6)
+	}
+	if err != nil {
+                return node, err
+        }
 
 
 	//IDK why these aren't a part of "set defaults. Pretty dumb.
 	//IDK why these aren't a part of "set defaults. Pretty dumb.
 	//TODO: This is dumb. Consolidate and fix.
 	//TODO: This is dumb. Consolidate and fix.

+ 3 - 3
controllers/dnsHttpController.go

@@ -465,8 +465,8 @@ func ValidateDNSCreate(entry models.DNSEntry) error {
 
 
 	_ = v.RegisterValidation("address_valid", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("address_valid", func(fl validator.FieldLevel) bool {
 		notEmptyCheck := len(entry.Address) > 0
 		notEmptyCheck := len(entry.Address) > 0
-                isIpv4 := functions.IsIpv4Net(entry.Address)
-		return notEmptyCheck && isIpv4
+                isIp := functions.IsIpNet(entry.Address)
+		return notEmptyCheck && isIp
 	})
 	})
         _ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
                 _, err := functions.GetParentNetwork(entry.Network)
                 _, err := functions.GetParentNetwork(entry.Network)
@@ -507,7 +507,7 @@ func ValidateDNSUpdate(change models.DNSEntry, entry models.DNSEntry) error {
         _ = v.RegisterValidation("address_valid", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("address_valid", func(fl validator.FieldLevel) bool {
 		isValid := true
 		isValid := true
 		if entry.Address != "" {
 		if entry.Address != "" {
-			isValid = functions.IsIpv4Net(entry.Address)
+			isValid = functions.IsIpNet(entry.Address)
 		}
 		}
 		return isValid
 		return isValid
         })
         })

+ 37 - 15
controllers/networkHttpController.go

@@ -109,12 +109,16 @@ func validateNetworkUpdate(network models.Network) error {
 	v := validator.New()
 	v := validator.New()
 
 
 	_ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool {
-		isvalid := fl.Field().String() == "" || functions.IsIpv4CIDR(fl.Field().String())
+		isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String())
 		return isvalid
 		return isvalid
 	})
 	})
+        _ = v.RegisterValidation("addressrange6_valid", func(fl validator.FieldLevel) bool {
+                isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String())
+                return isvalid
+        })
 
 
 	_ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
-		isvalid := fl.Field().String() == "" || functions.IsIpv4CIDR(fl.Field().String())
+		isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String())
 		return isvalid
 		return isvalid
 	})
 	})
 
 
@@ -141,12 +145,17 @@ func validateNetworkCreate(network models.Network) error {
 	v := validator.New()
 	v := validator.New()
 
 
 	_ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool {
-		isvalid := functions.IsIpv4CIDR(fl.Field().String())
+		isvalid := functions.IsIpCIDR(fl.Field().String())
 		return isvalid
 		return isvalid
 	})
 	})
+        _ = v.RegisterValidation("addressrange6_valid", func(fl validator.FieldLevel) bool {
+                isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String())
+                return isvalid
+        })
+
 
 
 	_ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
 	_ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
-		isvalid := fl.Field().String() == "" || functions.IsIpv4CIDR(fl.Field().String())
+		isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String())
 		return isvalid
 		return isvalid
 	})
 	})
 
 
@@ -223,19 +232,20 @@ func keyUpdate(w http.ResponseWriter, r *http.Request) {
         update := bson.D{
         update := bson.D{
                 {"$set", bson.D{
                 {"$set", bson.D{
                         {"addressrange", network.AddressRange},
                         {"addressrange", network.AddressRange},
+                        {"addressrange6", network.AddressRange6},
                         {"displayname", network.DisplayName},
                         {"displayname", network.DisplayName},
                         {"defaultlistenport", network.DefaultListenPort},
                         {"defaultlistenport", network.DefaultListenPort},
                         {"defaultpostup", network.DefaultPostUp},
                         {"defaultpostup", network.DefaultPostUp},
                         {"defaultpostdown", network.DefaultPostDown},
                         {"defaultpostdown", network.DefaultPostDown},
-                  			{"defaultkeepalive", network.DefaultKeepalive},
-			                  {"keyupdatetimestamp", network.KeyUpdateTimeStamp},
-			                  {"defaultsaveconfig", network.DefaultSaveConfig},
-                  			{"defaultinterface", network.DefaultInterface},
-			                  {"nodeslastmodified", network.NodesLastModified},
-                  			{"networklastmodified", network.NetworkLastModified},
-			                  {"allowmanualsignup", network.AllowManualSignUp},
-			                  {"checkininterval", network.DefaultCheckInInterval},
-		            }},
+			{"defaultkeepalive", network.DefaultKeepalive},
+			{"keyupdatetimestamp", network.KeyUpdateTimeStamp},
+			{"defaultsaveconfig", network.DefaultSaveConfig},
+			{"defaultinterface", network.DefaultInterface},
+			{"nodeslastmodified", network.NodesLastModified},
+			{"networklastmodified", network.NetworkLastModified},
+			{"allowmanualsignup", network.AllowManualSignUp},
+			{"checkininterval", network.DefaultCheckInInterval},
+		        }},
 	      }
 	      }
 
 
 	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
 	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
@@ -304,6 +314,9 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 	if networkChange.AddressRange == "" {
 	if networkChange.AddressRange == "" {
 		networkChange.AddressRange = network.AddressRange
 		networkChange.AddressRange = network.AddressRange
 	}
 	}
+        if networkChange.AddressRange6 == "" {
+                networkChange.AddressRange6 = network.AddressRange6
+        }
 	if networkChange.NetID == "" {
 	if networkChange.NetID == "" {
 		networkChange.NetID = network.NetID
 		networkChange.NetID = network.NetID
 	}
 	}
@@ -325,7 +338,7 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 
 
 		network.AddressRange = networkChange.AddressRange
 		network.AddressRange = networkChange.AddressRange
 
 
-		var isAddressOK bool = functions.IsIpv4CIDR(networkChange.AddressRange)
+		var isAddressOK bool = functions.IsIpCIDR(networkChange.AddressRange)
 		if !isAddressOK {
 		if !isAddressOK {
 			err := errors.New("Invalid Range of " + networkChange.AddressRange + " for addresses.")
 			err := errors.New("Invalid Range of " + networkChange.AddressRange + " for addresses.")
 			returnErrorResponse(w, r, formatError(err, "internal"))
 			returnErrorResponse(w, r, formatError(err, "internal"))
@@ -338,7 +351,7 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 	if networkChange.LocalRange != "" {
 	if networkChange.LocalRange != "" {
 		network.LocalRange = networkChange.LocalRange
 		network.LocalRange = networkChange.LocalRange
 
 
-		var isAddressOK bool = functions.IsIpv4CIDR(networkChange.LocalRange)
+		var isAddressOK bool = functions.IsIpCIDR(networkChange.LocalRange)
 		if !isAddressOK {
 		if !isAddressOK {
 			err := errors.New("Invalid Range of " + networkChange.LocalRange + " for internal addresses.")
 			err := errors.New("Invalid Range of " + networkChange.LocalRange + " for internal addresses.")
 			returnErrorResponse(w, r, formatError(err, "internal"))
 			returnErrorResponse(w, r, formatError(err, "internal"))
@@ -350,6 +363,9 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 	if networkChange.IsLocal != nil {
 	if networkChange.IsLocal != nil {
 		network.IsLocal = networkChange.IsLocal
 		network.IsLocal = networkChange.IsLocal
 	}
 	}
+        if networkChange.IsDualStack != nil {
+                network.IsDualStack = networkChange.IsDualStack
+        }
 	if networkChange.DefaultListenPort != 0 {
 	if networkChange.DefaultListenPort != 0 {
 		network.DefaultListenPort = networkChange.DefaultListenPort
 		network.DefaultListenPort = networkChange.DefaultListenPort
 		haschange = true
 		haschange = true
@@ -394,6 +410,7 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
         update := bson.D{
         update := bson.D{
                 {"$set", bson.D{
                 {"$set", bson.D{
                         {"addressrange", network.AddressRange},
                         {"addressrange", network.AddressRange},
+                        {"addressrange6", network.AddressRange6},
                         {"displayname", network.DisplayName},
                         {"displayname", network.DisplayName},
                         {"defaultlistenport", network.DefaultListenPort},
                         {"defaultlistenport", network.DefaultListenPort},
                         {"defaultpostup", network.DefaultPostUp},
                         {"defaultpostup", network.DefaultPostUp},
@@ -406,6 +423,7 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
                         {"allowmanualsignup", network.AllowManualSignUp},
                         {"allowmanualsignup", network.AllowManualSignUp},
                         {"localrange", network.LocalRange},
                         {"localrange", network.LocalRange},
                         {"islocal", network.IsLocal},
                         {"islocal", network.IsLocal},
+                        {"isdualstack", network.IsDualStack},
                         {"checkininterval", network.DefaultCheckInInterval},
                         {"checkininterval", network.DefaultCheckInInterval},
 		              }},
 		              }},
 	}
 	}
@@ -505,6 +523,10 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
 		falsevar := false
 		falsevar := false
 		network.IsLocal = &falsevar
 		network.IsLocal = &falsevar
 	}
 	}
+        if network.IsDualStack == nil {
+                falsevar := false
+                network.IsDualStack = &falsevar
+        }
 
 
 	err = validateNetworkCreate(network)
 	err = validateNetworkCreate(network)
 	if err != nil {
 	if err != nil {

+ 2 - 2
controllers/nodeHttpController.go

@@ -661,9 +661,9 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
 
 
 func validateGateway(gateway models.GatewayRequest) error {
 func validateGateway(gateway models.GatewayRequest) error {
 	var err error
 	var err error
-	isIpv4 := functions.IsIpv4CIDR(gateway.RangeString)
+	isIp := functions.IsIpCIDR(gateway.RangeString)
 	empty := gateway.RangeString == ""
 	empty := gateway.RangeString == ""
-	if empty || !isIpv4 {
+	if empty || !isIp {
 		err = errors.New("IP Range Not Valid")
 		err = errors.New("IP Range Not Valid")
 	}
 	}
 	empty = gateway.Interface == ""
 	empty = gateway.Interface == ""

+ 31 - 5
functions/helpers.go

@@ -378,17 +378,14 @@ func GetParentNetwork(networkname string) (models.Network, error) {
 	return network, nil
 	return network, nil
 }
 }
 
 
-//Check for valid IPv4 address
-//Note: We dont handle IPv6 AT ALL!!!!! This definitely is needed at some point
-//But for iteration 1, lets just stick to IPv4. Keep it simple stupid.
-func IsIpv4Net(host string) bool {
+func IsIpNet(host string) bool {
 	return net.ParseIP(host) != nil
 	return net.ParseIP(host) != nil
 }
 }
 
 
 //Similar to above but checks if Cidr range is valid
 //Similar to above but checks if Cidr range is valid
 //At least this guy's got some print statements
 //At least this guy's got some print statements
 //still not good error handling
 //still not good error handling
-func IsIpv4CIDR(host string) bool {
+func IsIpCIDR(host string) bool {
 
 
 	ip, ipnet, err := net.ParseCIDR(host)
 	ip, ipnet, err := net.ParseCIDR(host)
 
 
@@ -529,6 +526,35 @@ func UniqueAddress(networkName string) (string, error) {
 	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
 	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
 }
 }
 
 
+func UniqueAddress6(networkName string) (string, error) {
+
+        var network models.Network
+        network, err := GetParentNetwork(networkName)
+        if err != nil {
+                fmt.Println("UniqueAddress6 encountered  an error")
+                return "666", err
+        }
+
+        offset := true
+        ip, ipnet, err := net.ParseCIDR(network.AddressRange)
+        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
+                }
+                if IsIPUnique(networkName, ip.String()) {
+                        return ip.String(), err
+                }
+        }
+        //TODO
+        err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
+        return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
+}
+
 //pretty simple get
 //pretty simple get
 func GetGlobalConfig() (bool, models.GlobalConfig, error) {
 func GetGlobalConfig() (bool, models.GlobalConfig, error) {
 
 

+ 2 - 0
models/network.go

@@ -11,6 +11,7 @@ import (
 type Network struct {
 type Network struct {
 	ID	primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
 	ID	primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
 	AddressRange	string `json:"addressrange" bson:"addressrange" validate:"required,addressrange_valid"`
 	AddressRange	string `json:"addressrange" bson:"addressrange" validate:"required,addressrange_valid"`
+	AddressRange6	string `json:"addressrange6" bson:"addressrange6" validate:"required,addressrange6_valid"`
 	DisplayName string `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,displayname_unique,min=1,max=100"`
 	DisplayName string `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,displayname_unique,min=1,max=100"`
 	NetID string `json:"netid" bson:"netid" validate:"required,netid_valid,min=1,max=12"`
 	NetID string `json:"netid" bson:"netid" validate:"required,netid_valid,min=1,max=12"`
 	NodesLastModified	int64 `json:"nodeslastmodified" bson:"nodeslastmodified"`
 	NodesLastModified	int64 `json:"nodeslastmodified" bson:"nodeslastmodified"`
@@ -25,6 +26,7 @@ type Network struct {
 	AccessKeys	[]AccessKey `json:"accesskeys" bson:"accesskeys"`
 	AccessKeys	[]AccessKey `json:"accesskeys" bson:"accesskeys"`
 	AllowManualSignUp *bool `json:"allowmanualsignup" bson:"allowmanualsignup"`
 	AllowManualSignUp *bool `json:"allowmanualsignup" bson:"allowmanualsignup"`
 	IsLocal *bool `json:"islocal" bson:"islocal"`
 	IsLocal *bool `json:"islocal" bson:"islocal"`
+	IsDualStack *bool `json:"isdualstack" bson:"isdualstack"`
 	LocalRange string `json:"localrange" bson:"localrange" validate:"localrange_valid"`
 	LocalRange string `json:"localrange" bson:"localrange" validate:"localrange_valid"`
 	DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=1,max=100000"`
 	DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=1,max=100000"`
 }
 }

+ 1 - 0
models/node.go

@@ -20,6 +20,7 @@ var seededRand *rand.Rand = rand.New(
 type Node struct {
 type Node struct {
 	ID                  primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
 	ID                  primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
 	Address             string             `json:"address" bson:"address" validate:"address_check"`
 	Address             string             `json:"address" bson:"address" validate:"address_check"`
+	Address6             string             `json:"address6" bson:"address6" validate:"address6_check"`
 	LocalAddress        string             `json:"localaddress" bson:"localaddress" validate:"localaddress_check"`
 	LocalAddress        string             `json:"localaddress" bson:"localaddress" validate:"localaddress_check"`
 	Name                string             `json:"name" bson:"name" validate:"omitempty,name_valid,max=12"`
 	Name                string             `json:"name" bson:"name" validate:"omitempty,name_valid,max=12"`
 	ListenPort          int32              `json:"listenport" bson:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
 	ListenPort          int32              `json:"listenport" bson:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`