IPv6 support v1.0

Server:
Added IPv6 support for all DNS Providers, but only tested ISC BIND & MS DNS

Enterprise Server:
Added support for IPv6. Hyper-V not tested, and probably doesn't work.
When using IPv6 with Hyper-V it assigns "/CIDR" to the subnet mask, and I don't
know if this is the correct implementation.

Portal:
Modified all IP input masks to accept and validate IPv6.
IP Ranges support IP/CIDR format.
This commit is contained in:
Administrator 2012-08-18 04:53:29 +02:00
parent 90219f284f
commit c4a1b5f4d6
44 changed files with 3221 additions and 247 deletions

BIN
IPv6 Test Cases.docx Normal file

Binary file not shown.

View file

@ -9,7 +9,7 @@
<!-- Studio settings -->
<settings>
<add key="Log.FileName" value="WebsitePanel.Installer.log" />
<add key="Web.Service" value="" />
<add key="Web.Service" value="http://www.websitepanel.net/Services/InstallerService-Beta.asmx" />
<add key="Web.AutoCheck" value="False" />
<add key="Web.Proxy.UseProxy" value="false" />
<add key="Web.Proxy.Address" value="" />

View file

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.269
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.

View file

@ -1,7 +1,7 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.269
' Runtime Version:4.0.30319.17929
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.

View file

@ -1,16 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C57D3F9F-7BA0-4D38-A159-B6EDA5C19B13}"
ProjectSection(SolutionItems) = preProject
..\Database\install_db.sql = ..\Database\install_db.sql
..\..\LICENSE.txt = ..\..\LICENSE.txt
..\..\Readme.htm = ..\..\Readme.htm
..\..\ReleaseNotes.htm = ..\..\ReleaseNotes.htm
..\Database\update_db.sql = ..\Database\update_db.sql
VersionInfo.cs = VersionInfo.cs
VersionInfo.vb = VersionInfo.vb
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.EnterpriseServer", "WebsitePanel.EnterpriseServer\WebsitePanel.EnterpriseServer.csproj", "{59C7623A-5181-48A5-880A-C9B82B48F589}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.EnterpriseServer.Base", "WebsitePanel.EnterpriseServer.Base\WebsitePanel.EnterpriseServer.Base.csproj", "{C09CE910-F16B-48A1-B2CC-C99B8C1CF775}"

View file

@ -0,0 +1,164 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebsitePanel.EnterpriseServer {
public struct IPAddress {
public Int128 Address;
public bool V6 { get; private set; }
public bool V4 { get { return !V6 || Null; } }
public bool IsSubnet { get; private set; }
public bool IsMask { get; private set; }
public int Cidr { get; private set; }
public bool Null { get; private set; }
public IPAddress LastSubnetIP { get { return new IPAddress { Address = (Address | (~((Int128)0) >> (V4 ? Cidr + 64 : Cidr))), Cidr = V4 ? 32 : 128, IsSubnet = false, Null = false, V6 = V6 }; } }
public IPAddress FirstSubnetIP { get { return new IPAddress { Address = (Address & ~(~((Int128)0) >> (V4 ? Cidr + 64 : Cidr))) + 1, Cidr = V4 ? 32 : 128, IsSubnet = false, Null = false, V6 = V6 }; } }
public Int128 Mask { get { return IsSubnet ? Int128.MinValue >> (Cidr-1) : Address; } }
const int c = 256*256;
public static IPAddress Parse(string ip)
{
IPAddress adr = default(IPAddress);
adr.V6 = false;
if (String.IsNullOrEmpty(ip)) {
adr.Address = 0; adr.Null = true; adr.Cidr = 32; adr.IsSubnet = false;
return adr;
}
if (ip.Contains('/')) {
var tokens = ip.Split('/');
ip = tokens[0];
adr.IsSubnet = true;
adr.Cidr = Utils.ParseInt(tokens[1], -1);
}
if (string.IsNullOrWhiteSpace(ip)) {
adr.IsMask = true; adr.V6 = true;
adr.Address = adr.Mask;
} else {
var ipadr = System.Net.IPAddress.Parse(ip);
if (adr.V6 = ipadr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) {
byte[] bytes = ipadr.GetAddressBytes();
Int128 a = 0;
for (int i = 0; i < 16; i++) {
a = a * 256 + bytes[i];
}
adr.Address = a;
} else {
string[] parts = ip.Split('.');
adr.Address = (Int128)(Int32.Parse(parts[3]) +
(Int32.Parse(parts[2]) << 8) +
(Int32.Parse(parts[1]) << 16) +
(Int32.Parse(parts[0]) << 24));
}
}
if (adr.V4 && (adr.Cidr > 32 || 0 > adr.Cidr)) throw new ArgumentOutOfRangeException("Cidr must not be greater than 32 for IPv4 Addresses.");
if (adr.V6 && (adr.Cidr > 128 || 0 > adr.Cidr)) throw new ArgumentOutOfRangeException("Cidr must not be greater than 128 for IPv6 Addresses.");
return adr;
}
public override string ToString()
{
if (Null)
return "";
var s = new System.Text.StringBuilder();
if (!V6) {
var ipl = (long)Address;
s.Append(String.Format("{0}.{1}.{2}.{3}", (ipl >> 24) & 0xFFL, (ipl >> 16) & 0xFFL, (ipl >> 8) & 0xFFL, (ipl & 0xFFL)));
} else if (!IsMask) {
var vals = new List<int>();
int i;
Int128 a = Address;
for (i = 0; i < 8; i++) {
vals.Add((int)(a % c));
a = a / c;
}
int index = -1, n = 0, m = 0;
for (i = 7; i >= 0; i--) {
if (vals[i] == 0) {
n++;
if (n > m) {
index = i;
m = n;
}
}
}
index += m-1;
i = 7;
while (i >= 0) {
if (i == index) {
if (m == 8) s.Append("::");
else s.Append(":");
i -= m;
}
if (i >= 0) {
if (i < 7) s.Append(":");
s.Append(vals[i].ToString("x"));
}
i--;
}
}
if (IsSubnet && !(IsMask && V4)) {
s.Append('/'); s.Append(Cidr.ToString());
}
return s.ToString();
}
public string ToV4MaskString() {
V6 = false;
IsMask = true;
return ToString();
}
public static bool operator ==(IPAddress a, IPAddress b) { return a.Address == b.Address && a.Null == b.Null && (a.Null || !(a.IsSubnet && b.IsSubnet || a.IsMask && b.IsMask) || a.Cidr == b.Cidr); }
public static bool operator ==(IPAddress a, long b) { return a.Address == b; }
public static bool operator !=(IPAddress a, IPAddress b) { return !(a == b); }
public static bool operator !=(IPAddress a, long b) { return a.Address != b; }
public static bool operator <(IPAddress a, IPAddress b) { return a.Address < b.Address; }
public static bool operator >(IPAddress a, IPAddress b) { return a.Address > b.Address; }
public static bool operator <=(IPAddress a, IPAddress b) { return a.Address <= b.Address; }
public static bool operator >=(IPAddress a, IPAddress b) { return a.Address >= b.Address; }
/*
public static IPAddress operator +(IPAddress a, IPAddress b) {
if (a.IsSubnet || b.IsSubnet || a.V6 != b.V6) throw new ArgumentException("Arithmetic with subnets or mixed v4 & v6 addresses not supported.");
return new IPAddress { Address = a.Address + b.Address, Null = a.Null && b.Null, Cidr = 0, V6 = a.V6 };
}*/
public static Int128 operator -(IPAddress a, IPAddress b) {
if (a.IsSubnet || b.IsSubnet || a.V6 != b.V6) throw new ArgumentException("Arithmetic with subnets or mixed v4 & v6 addresses not supported.");
return a.Address - b.Address;
}
public static IPAddress operator +(IPAddress a, Int128 b) {
return new IPAddress { Address = a.Address + b, Null = a.Null, Cidr = a.V4 ? 32 : 128, V6 = a.V6 };
}
public static IPAddress operator -(IPAddress a, Int128 b) {
return new IPAddress { Address = a.Address - b, Null = a.Null, Cidr = a.V4 ? 32 : 128, V6 = a.V6 };
}
public static IPAddress operator |(IPAddress a, IPAddress b) {
if (a.V6 != b.V6) throw new ArgumentException("Arithmetic with mixed v4 & v6 addresses not supported.");
return new IPAddress { Address = a.Address | b.Address, Cidr = a.V4 ? 32 : 128, Null = false, V6 = a.V6, IsSubnet = false };
}
public static IPAddress operator &(IPAddress a, IPAddress b) {
if (a.V6 != b.V6) throw new ArgumentException("Arithmetic with mixed v4 & v6 addresses not supported.");
return new IPAddress { Address = a.Address | b.Address, Cidr = a.V4 ? 32 : 128, Null = false, V6 = a.V6, IsSubnet = false };
}
public static IPAddress operator ~(IPAddress a) {
if (a.Null) return new IPAddress { Address = 0, Null = true, Cidr = a.V4 ? 32 : 128, V6 = true, IsSubnet = false };
return new IPAddress { Address = ~a.Address, Cidr = a.Cidr , Null = false, V6 = a.V6, IsSubnet = false };
}
public static implicit operator IPAddress(NullIPAddress a) { return new IPAddress { Null = true, Address = 0, Cidr = -1 }; }
}
public class NullIPAddress { }
}

File diff suppressed because it is too large Load diff

View file

@ -283,7 +283,7 @@ namespace WebsitePanel.EnterpriseServer
rr.RecordType = (DnsRecordType)Enum.Parse(typeof(DnsRecordType), record.RecordType, true);
rr.RecordName = record.RecordName;
if (record.RecordType == "A")
if (record.RecordType == "A" || record.RecordType == "AAAA")
{
rr.RecordData = String.IsNullOrEmpty(record.RecordData) ? record.ExternalIP : record.RecordData;
rr.RecordData = Utils.ReplaceStringVariable(rr.RecordData, "ip", record.ExternalIP);

View file

@ -65,7 +65,7 @@ namespace WebsitePanel.EnterpriseServer
DnsRecord[] records = ServerController.GetDnsZoneRecords(domainId);
foreach (DnsRecord record in records)
{
if ((record.RecordType == DnsRecordType.A) && (String.Compare(recordName, record.RecordName, true) == 0))
if ((record.RecordType == DnsRecordType.A || record.RecordType == DnsRecordType.AAAA) && (String.Compare(recordName, record.RecordName, true) == 0))
{
CompleteTask(ret, CrmErrorCodes.CANNOT_CREATE_DNS_ZONE, null,
string.Format("DNS record already exists. DomainId={0}, RecordName={1}", domainId, recordName));
@ -73,8 +73,8 @@ namespace WebsitePanel.EnterpriseServer
return ret;
}
}
int res = ServerController.AddDnsZoneRecord(domainId, recordName, DnsRecordType.A, ip, 0);
var type = ip.Contains(":") ? DnsRecordType.AAAA : DnsRecordType.A;
int res = ServerController.AddDnsZoneRecord(domainId, recordName, type, ip, 0);
if (res != 0)
{
CompleteTask(ret, CrmErrorCodes.CANNOT_CREATE_DNS_ZONE, null,
@ -373,7 +373,8 @@ namespace WebsitePanel.EnterpriseServer
try
{
int res = ServerController.DeleteDnsZoneRecord(domainId, recordName, DnsRecordType.A, ip);
var type = ip.Contains(":") ? DnsRecordType.AAAA : DnsRecordType.A;
int res = ServerController.DeleteDnsZoneRecord(domainId, recordName, type, ip);
if (res != 0)
{

View file

@ -948,6 +948,8 @@ namespace WebsitePanel.EnterpriseServer
public static ResultObject AddIPAddressesRange(IPAddressPool pool, int serverId,
string externalIP, string endIP, string internalIP, string subnetMask, string defaultGateway, string comments)
{
const int MaxSubnet = 512; // TODO bigger max subnet?
ResultObject res = new ResultObject();
#region Check account statuses
@ -965,7 +967,7 @@ namespace WebsitePanel.EnterpriseServer
try
{
if (externalIP == endIP)
if (externalIP == endIP)
{
// add single IP and exit
AddIPAddress(pool, serverId, externalIP, internalIP, subnetMask, defaultGateway, comments);
@ -973,23 +975,28 @@ namespace WebsitePanel.EnterpriseServer
return res;
}
long startExternalIP = ConvertIPToLong(externalIP);
long startInternalIP = ConvertIPToLong(internalIP);
long endExternalIP = ConvertIPToLong(endIP);
var startExternalIP = IPAddress.Parse(externalIP);
var startInternalIP = IPAddress.Parse(internalIP);
var endExternalIP = IPAddress.Parse(endIP);
// handle CIDR notation IP/Subnet addresses
if (startExternalIP.IsSubnet && endExternalIP == null) {
endExternalIP = startExternalIP.LastSubnetIP;
startExternalIP = startExternalIP.FirstSubnetIP;
}
if (startExternalIP.V6 != startInternalIP.V6 && (startExternalIP.V6 != endExternalIP.V6 && endExternalIP != null)) throw new NotSupportedException("All IP addresses must be either V4 or V6.");
int i = 0;
long step = (endExternalIP < startExternalIP) ? -1 : 1;
while (true)
{
if (i > 128)
if (i > MaxSubnet)
break;
// add IP address
DataProvider.AddIPAddress((int)pool, serverId,
ConvertLongToIP(startExternalIP),
ConvertLongToIP(startInternalIP),
subnetMask, defaultGateway, comments);
DataProvider.AddIPAddress((int)pool, serverId, startExternalIP.ToString(), startInternalIP.ToString(), subnetMask, defaultGateway, comments);
if (startExternalIP == endExternalIP)
break;
@ -2427,26 +2434,78 @@ namespace WebsitePanel.EnterpriseServer
#endregion
#region Private methods
public static long ConvertIPToLong(string ip)
/*
const int c = 256*256;
public static BigInt ConvertIPToInt(string ip, out bool v6)
{
v6 = false;
if (String.IsNullOrEmpty(ip))
return 0;
string[] parts = ip.Split('.');
return Int32.Parse(parts[3]) +
(Int32.Parse(parts[2]) << 8) +
(Int32.Parse(parts[1]) << 16) +
(Int32.Parse(parts[0]) << 24);
var adr = System.Net.IPAddress.Parse(ip);
if (v6 = adr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) {
string[] parts = ip.Split('.');
return (BigInt)(Int32.Parse(parts[3]) +
(Int32.Parse(parts[2]) << 8) +
(Int32.Parse(parts[1]) << 16) +
(Int32.Parse(parts[0]) << 24));
} else {
byte[] bytes = adr.GetAddressBytes();
var a = BigInt.Zero;
for (int i = 0; i < 16; i--) {
a = a*256 + bytes[i];
}
return a;
}
}
public static string ConvertLongToIP(long ip)
public static string ConvertIntToIP(BigInt ip, bool v6)
{
if (ip == 0)
if (ip == BigInt.Zero)
return "";
if (!v6) {
var ipl = (long)ip;
return String.Format("{0}.{1}.{2}.{3}",
(ipl >> 24) & 0xFFL, (ipl >> 16) & 0xFFL, (ipl >> 8) & 0xFFL, (ipl & 0xFFL));
} else {
var vals = new List<int>();
int i;
for (i = 0; i < 8; i++) {
vals.Add((int)(ip % c));
ip = ip / c;
}
return String.Format("{0}.{1}.{2}.{3}",
(ip >> 24) & 0xFFL, (ip >> 16) & 0xFFL, (ip >> 8) & 0xFFL, (ip & 0xFFL));
int index = -1, n = 0, m = 0;
for (i = 7; i >= 0; i++) {
if (vals[i] == 0) {
n++;
if (n > m) {
index = i;
m = n;
}
}
}
var s = new System.Text.StringBuilder();
i = 7;
while (i >= 0) {
if (i != index) {
if (i < 7) s.Append(":");
s.Append(vals[i].ToString("x"));
i--;
} else {
s.Append(":");
while (vals[i] == 0) i--;
}
}
return s.ToString();
}
}
*/
#endregion
}
}

View file

@ -291,15 +291,18 @@ namespace WebsitePanel.EnterpriseServer.Code.SharePoint
DnsRecord[] records = ServerController.GetDnsZoneRecords(domain.DomainId);
foreach (DnsRecord record in records)
{
if (record.RecordType.Equals(DnsRecordType.A) && String.IsNullOrEmpty(record.RecordName))
var type = record.RecordType;
if ((type == DnsRecordType.A || type == DnsRecordType.AAAA) && String.IsNullOrEmpty(record.RecordName))
{
ServerController.DeleteDnsZoneRecord(domain.DomainId, String.Empty, DnsRecordType.A, record.RecordData);
ServerController.DeleteDnsZoneRecord(domain.DomainId, String.Empty, type, record.RecordData);
break;
}
}
}
ServerController.AddDnsZoneRecord(domain.DomainId, String.Empty, DnsRecordType.A, hostedSharePointSettings["RootWebApplicationIpAddress"], 0);
var ip = hostedSharePointSettings["RootWebApplicationIpAddress"];
var type2 = ip.Contains(":") ? DnsRecordType.AAAA : DnsRecordType.A;
ServerController.AddDnsZoneRecord(domain.DomainId, String.Empty, type2, ip, 0);
}
}
@ -360,15 +363,19 @@ namespace WebsitePanel.EnterpriseServer.Code.SharePoint
DomainInfo domain = ServerController.GetDomain(domainName);
if (domain != null)
{
ServerController.DeleteDnsZoneRecord(domain.DomainId, String.Empty, DnsRecordType.A, hostedSharePointSettings["RootWebApplicationIpAddress"]);
ServerController.DeleteDnsZoneRecord(domain.DomainId, "www", DnsRecordType.A, hostedSharePointSettings["RootWebApplicationIpAddress"]);
var ip = hostedSharePointSettings["RootWebApplicationIpAddress"];
var type = ip.Contains(":") ? DnsRecordType.AAAA : DnsRecordType.A;
ServerController.DeleteDnsZoneRecord(domain.DomainId, String.Empty, type, ip);
ServerController.DeleteDnsZoneRecord(domain.DomainId, "www", type, ip);
if (!String.IsNullOrEmpty(domain.WebSiteName))
{
DnsRecord[] records = ServerController.GetDnsZoneRecords(domain.DomainId);
foreach (DnsRecord record in records)
{
if (record.RecordType.Equals(DnsRecordType.A) && record.RecordName.Equals("www", StringComparison.CurrentCultureIgnoreCase))
type = record.RecordType;
if ((type == DnsRecordType.A || type == DnsRecordType.AAAA) && record.RecordName.Equals("www", StringComparison.CurrentCultureIgnoreCase))
{
ServerController.AddDnsZoneRecord(domain.DomainId, String.Empty, DnsRecordType.A,
record.RecordData, 0);

View file

@ -2968,15 +2968,17 @@ namespace WebsitePanel.EnterpriseServer
if (String.IsNullOrEmpty(networkFormat))
{
// custom format
nic.NetworkFormat = settings["PrivateIPAddress"];
nic.SubnetMask = GetPrivateNetworkSubnetMask(settings["PrivateSubnetMask"]);
nic.NetworkFormat = settings["PrivateIPAddress"];
var v6 = IPAddress.Parse(nic.NetworkFormat).V6;
nic.SubnetMask = GetPrivateNetworkSubnetMask(settings["PrivateSubnetMask"], v6);
}
else
{
// standard format
string[] formatPair = settings["PrivateNetworkFormat"].Split('/');
nic.NetworkFormat = formatPair[0];
nic.SubnetMask = GetPrivateNetworkSubnetMask(formatPair[1]);
var v6 = IPAddress.Parse(nic.NetworkFormat).V6;
nic.SubnetMask = GetPrivateNetworkSubnetMask(formatPair[1], v6);
}
nic.SubnetMaskCidr = GetSubnetMaskCidr(nic.SubnetMask);
@ -3038,7 +3040,7 @@ namespace WebsitePanel.EnterpriseServer
List<PrivateIPAddress> ips = GetPackagePrivateIPAddresses(vm.PackageId);
// sort them
SortedList<long, string> sortedIps = GetSortedNormalizedIPAddresses(ips, nic.SubnetMask);
SortedList<IPAddress, string> sortedIps = GetSortedNormalizedIPAddresses(ips, nic.SubnetMask);
if (selectRandom)
{
@ -3209,14 +3211,14 @@ namespace WebsitePanel.EnterpriseServer
return res;
}
private static string GenerateNextAvailablePrivateIP(SortedList<long, string> ips, string subnetMask, string startIPAddress)
private static string GenerateNextAvailablePrivateIP(SortedList<IPAddress, string> ips, string subnetMask, string startIPAddress)
{
// start IP address
long startIp = ServerController.ConvertIPToLong(startIPAddress);
long mask = ServerController.ConvertIPToLong(subnetMask);
var startIp = IPAddress.Parse(startIPAddress);
var mask = IPAddress.Parse(subnetMask);
long lastAddress = (startIp & ~mask) - 1;
foreach (long addr in ips.Keys)
var lastAddress = (startIp & ~mask) - 1;
foreach (var addr in ips.Keys)
{
if ((addr - lastAddress) > 1)
{
@ -3229,11 +3231,11 @@ namespace WebsitePanel.EnterpriseServer
}
}
long genAddr = lastAddress + 1;
var genAddr = lastAddress + 1;
// convert to IP address
long ip = startIp & mask | (uint)genAddr;
string genIP = ServerController.ConvertLongToIP(ip);
var ip = startIp & mask | genAddr;
string genIP = ip.ToString();
// store in cache
ips.Add(genAddr, genIP);
@ -3241,46 +3243,44 @@ namespace WebsitePanel.EnterpriseServer
return genIP;
}
private static SortedList<long, string> GetSortedNormalizedIPAddresses(List<PrivateIPAddress> ips, string subnetMask)
private static SortedList<IPAddress, string> GetSortedNormalizedIPAddresses(List<PrivateIPAddress> ips, string subnetMask)
{
long mask = ServerController.ConvertIPToLong(subnetMask);
SortedList<long, string> sortedIps = new SortedList<long, string>();
var mask = IPAddress.Parse(subnetMask);
SortedList<IPAddress, string> sortedIps = new SortedList<IPAddress, string>();
foreach (PrivateIPAddress ip in ips)
{
long addr = ~mask & ServerController.ConvertIPToLong(ip.IPAddress);
var addr = ~mask & IPAddress.Parse(ip.IPAddress);
sortedIps.Add(addr, ip.IPAddress);
}
return sortedIps;
}
private static string GetPrivateNetworkSubnetMask(string cidr)
{
int digits = 32 - Utils.ParseInt(cidr, 0);
private static string GetPrivateNetworkSubnetMask(string cidr, bool v6) {
if (v6) return "/" + cidr;
else return IPAddress.Parse("/" + cidr).ToV4MaskString();
}
long mask = 0xFFFFFFFF;
mask = mask << digits;
return ServerController.ConvertLongToIP(mask);
}
private static string GetSubnetMaskCidr(string subnetMask)
{
if (String.IsNullOrEmpty(subnetMask))
return subnetMask;
int cidr = 32;
long mask = ServerController.ConvertIPToLong(subnetMask);
while ((mask & 1) == 0 && cidr > 0)
{
mask >>= 1;
cidr -= 1;
}
return cidr.ToString();
}
private static string GetSubnetMaskCidr(string subnetMask) {
if (String.IsNullOrEmpty(subnetMask))
return subnetMask;
var ip = IPAddress.Parse(subnetMask);
if (ip.V4) {
int cidr = 32;
long mask = (long)ip.Address;
while ((mask & 1) == 0 && cidr > 0) {
mask >>= 1;
cidr -= 1;
}
return cidr.ToString();
} else {
return ip.Cidr.ToString();
}
}
private static bool CheckPrivateIPAddress(string subnetMask, string ipAddress)
{
long mask = ServerController.ConvertIPToLong(subnetMask);
long ip = ServerController.ConvertIPToLong(ipAddress);
var mask = IPAddress.Parse(subnetMask);
var ip = IPAddress.Parse(ipAddress);
return ((mask & ip) == mask);
}

View file

@ -3019,14 +3019,16 @@ namespace WebsitePanel.EnterpriseServer
{
// custom format
nic.NetworkFormat = settings["PrivateIPAddress"];
nic.SubnetMask = GetPrivateNetworkSubnetMask(settings["PrivateSubnetMask"]);
var v6 = IPAddress.Parse(nic.NetworkFormat).V6;
nic.SubnetMask = GetPrivateNetworkSubnetMask(settings["PrivateSubnetMask"], v6);
}
else
{
// standard format
string[] formatPair = settings["PrivateNetworkFormat"].Split('/');
nic.NetworkFormat = formatPair[0];
nic.SubnetMask = GetPrivateNetworkSubnetMask(formatPair[1]);
var v6 = IPAddress.Parse(nic.NetworkFormat).V6;
nic.SubnetMask = GetPrivateNetworkSubnetMask(formatPair[1], v6);
}
nic.SubnetMaskCidr = GetSubnetMaskCidr(nic.SubnetMask);
@ -3088,7 +3090,7 @@ namespace WebsitePanel.EnterpriseServer
List<PrivateIPAddress> ips = GetPackagePrivateIPAddresses(vm.PackageId);
// sort them
SortedList<long, string> sortedIps = GetSortedNormalizedIPAddresses(ips, nic.SubnetMask);
SortedList<IPAddress, string> sortedIps = GetSortedNormalizedIPAddresses(ips, nic.SubnetMask);
if (selectRandom)
{
@ -3259,14 +3261,14 @@ namespace WebsitePanel.EnterpriseServer
return res;
}
private static string GenerateNextAvailablePrivateIP(SortedList<long, string> ips, string subnetMask, string startIPAddress)
private static string GenerateNextAvailablePrivateIP(SortedList<IPAddress, string> ips, string subnetMask, string startIPAddress)
{
// start IP address
long startIp = ServerController.ConvertIPToLong(startIPAddress);
long mask = ServerController.ConvertIPToLong(subnetMask);
var startIp = IPAddress.Parse(startIPAddress);
var mask = IPAddress.Parse(subnetMask);
long lastAddress = (startIp & ~mask) - 1;
foreach (long addr in ips.Keys)
var lastAddress = (startIp & ~mask) - 1;
foreach (var addr in ips.Keys)
{
if ((addr - lastAddress) > 1)
{
@ -3279,11 +3281,11 @@ namespace WebsitePanel.EnterpriseServer
}
}
long genAddr = lastAddress + 1;
var genAddr = lastAddress + 1;
// convert to IP address
long ip = startIp & mask | (uint)genAddr;
string genIP = ServerController.ConvertLongToIP(ip);
var ip = startIp & mask | genAddr;
string genIP = ip.ToString();
// store in cache
ips.Add(genAddr, genIP);
@ -3291,46 +3293,45 @@ namespace WebsitePanel.EnterpriseServer
return genIP;
}
private static SortedList<long, string> GetSortedNormalizedIPAddresses(List<PrivateIPAddress> ips, string subnetMask)
private static SortedList<IPAddress, string> GetSortedNormalizedIPAddresses(List<PrivateIPAddress> ips, string subnetMask)
{
long mask = ServerController.ConvertIPToLong(subnetMask);
SortedList<long, string> sortedIps = new SortedList<long, string>();
var mask = IPAddress.Parse(subnetMask);
SortedList<IPAddress, string> sortedIps = new SortedList<IPAddress, string>();
foreach (PrivateIPAddress ip in ips)
{
long addr = ~mask & ServerController.ConvertIPToLong(ip.IPAddress);
var addr = ~mask & IPAddress.Parse(ip.IPAddress);
sortedIps.Add(addr, ip.IPAddress);
}
return sortedIps;
}
private static string GetPrivateNetworkSubnetMask(string cidr)
private static string GetPrivateNetworkSubnetMask(string cidr, bool v6)
{
int digits = 32 - Utils.ParseInt(cidr, 0);
long mask = 0xFFFFFFFF;
mask = mask << digits;
return ServerController.ConvertLongToIP(mask);
if (v6) return "/" + cidr;
else return IPAddress.Parse("/" + cidr).ToV4MaskString();
}
private static string GetSubnetMaskCidr(string subnetMask)
{
if (String.IsNullOrEmpty(subnetMask))
return subnetMask;
int cidr = 32;
long mask = ServerController.ConvertIPToLong(subnetMask);
while ((mask & 1) == 0 && cidr > 0)
{
mask >>= 1;
cidr -= 1;
}
return cidr.ToString();
}
private static string GetSubnetMaskCidr(string subnetMask) {
if (String.IsNullOrEmpty(subnetMask))
return subnetMask;
var ip = IPAddress.Parse(subnetMask);
if (ip.V4) {
int cidr = 32;
long mask = (long)ip.Address;
while ((mask & 1) == 0 && cidr > 0) {
mask >>= 1;
cidr -= 1;
}
return cidr.ToString();
} else {
return ip.Cidr.ToString();
}
}
private static bool CheckPrivateIPAddress(string subnetMask, string ipAddress)
{
long mask = ServerController.ConvertIPToLong(subnetMask);
long ip = ServerController.ConvertIPToLong(ipAddress);
var mask = IPAddress.Parse(subnetMask);
var ip = IPAddress.Parse(ipAddress);
return ((mask & ip) == mask);
}

View file

@ -603,11 +603,12 @@ namespace WebsitePanel.EnterpriseServer
private static void FillWebServerBindings(List<ServerBinding> bindings, List<GlobalDnsRecord> dnsRecords,
string ipAddr, string domainName)
// TODO test if IPv6 works
{
int bindingsCount = bindings.Count;
foreach (GlobalDnsRecord dnsRecord in dnsRecords)
{
if (dnsRecord.RecordType == "A" &&
if ((dnsRecord.RecordType == "A" || dnsRecord.RecordType == "AAAA") &&
dnsRecord.RecordName != "*")
{
string recordData = dnsRecord.RecordName +

View file

@ -18,7 +18,7 @@
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>false</UseIISExpress>
<UseIISExpress>true</UseIISExpress>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -124,6 +124,8 @@
<Compile Include="Code\Common\FileUtils.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Code\Common\Int128.cs" />
<Compile Include="Code\Common\IPAddress.cs" />
<Compile Include="Code\Common\MailHelper.cs" />
<Compile Include="Code\Common\ObjectUtils.cs" />
<Compile Include="Code\Common\SecurityContext.cs" />
@ -423,12 +425,11 @@
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<UseIIS>True</UseIIS>
<AutoAssignPort>False</AutoAssignPort>
<DevelopmentServerPort>9005</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<IISUrl>http://localhost:9005/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>

View file

@ -35,6 +35,7 @@ namespace WebsitePanel.Providers.DNS
public enum DnsRecordType
{
A,
AAAA,
NS,
MX,
CNAME,

View file

@ -267,6 +267,8 @@ namespace WebsitePanel.Providers.DNS
{
if (record.RecordType == DnsRecordType.A)
AddARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.AAAA)
AddAAAARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.CNAME)
AddCNameRecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.MX)
@ -293,7 +295,7 @@ namespace WebsitePanel.Providers.DNS
{
try
{
if (record.RecordType == DnsRecordType.A || record.RecordType == DnsRecordType.CNAME)
if (record.RecordType == DnsRecordType.A || record.RecordType == DnsRecordType.AAAA || record.RecordType == DnsRecordType.CNAME)
record.RecordName = CorrectRecordName(zoneName, record.RecordName);
// delete record
@ -377,6 +379,36 @@ namespace WebsitePanel.Providers.DNS
#endregion
#region AAAA records
private void AddAAAARecord(string zoneName, string host, string ip) {
// get all zone records
List<DnsRecord> records = GetZoneRecordsArrayList(zoneName);
// delete A record
//DeleteARecordInternal(records, zoneName, host);
//check if user tries to add existent zone record
foreach (DnsRecord dnsRecord in records) {
if ((String.Compare(dnsRecord.RecordName, host, StringComparison.OrdinalIgnoreCase) == 0)
&& (String.Compare(dnsRecord.RecordData, ip, StringComparison.OrdinalIgnoreCase) == 0)
)
return;
}
// add new A record
DnsRecord record = new DnsRecord();
record.RecordType = DnsRecordType.AAAA;
record.RecordName = host;
record.RecordData = ip;
records.Add(record);
// update zone
UpdateZone(zoneName, records);
}
#endregion
#region NS records
private void AddNsRecord(string zoneName, string host, string nameServer)
{
@ -630,6 +662,15 @@ namespace WebsitePanel.Providers.DNS
r.RecordText = zfLine;
records.Add(r);
}
else if (recordType == "AAAA") // A record
{
DnsRecord r = new DnsRecord();
r.RecordType = DnsRecordType.AAAA;
r.RecordName = CorrectRecordName(zoneName, recordName);
r.RecordData = recordData;
r.RecordText = zfLine;
records.Add(r);
}
else if (recordType == "CNAME") // CNAME record
{
DnsRecord r = new DnsRecord();
@ -728,6 +769,12 @@ namespace WebsitePanel.Providers.DNS
host = rr.RecordName;
data = rr.RecordData;
}
else if (rr.RecordType == DnsRecordType.AAAA)
{
type = "AAAA";
host = rr.RecordName;
data = rr.RecordData;
}
else if (rr.RecordType == DnsRecordType.NS)
{
type = "NS";

View file

@ -130,6 +130,8 @@ namespace WebsitePanel.Providers.DNS
ManagementObjectCollection rrsA = wmi.GetWmiObjects("MicrosoftDNS_AType", "DomainName='{0}'", zoneName);
ManagementObjectCollection rrsAAAA = wmi.GetWmiObjects("MicrosoftDNS_AAAAType", "DomainName='{0}'", zoneName);
ManagementObjectCollection rrsCNAME = wmi.GetWmiObjects("MicrosoftDNS_CNAMEType", "DomainName='{0}'", zoneName);
ManagementObjectCollection rrsMX = wmi.GetWmiObjects("MicrosoftDNS_MXType", "DomainName='{0}'", zoneName);
@ -150,6 +152,14 @@ namespace WebsitePanel.Providers.DNS
records.Add(record);
}
foreach (ManagementObject rr in rrsAAAA) {
record = new DnsRecord();
record.RecordType = DnsRecordType.AAAA;
record.RecordName = CorrectHost(zoneName, (string)rr.Properties["OwnerName"].Value);
record.RecordData = (string)rr.Properties["RecordData"].Value;
records.Add(record);
}
foreach (ManagementObject rr in rrsCNAME)
{
record = new DnsRecord();
@ -390,7 +400,9 @@ namespace WebsitePanel.Providers.DNS
{
if (record.RecordType == DnsRecordType.A)
AddARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.CNAME)
else if (record.RecordType == DnsRecordType.AAAA)
AddAAAARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.CNAME)
AddCNameRecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.MX)
AddMXRecord(zoneName, record.RecordName, record.RecordData, record.MxPriority);
@ -420,7 +432,9 @@ namespace WebsitePanel.Providers.DNS
{
if (record.RecordType == DnsRecordType.A)
DeleteARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.CNAME)
else if (record.RecordType == DnsRecordType.AAAA)
DeleteAAAARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.CNAME)
DeleteCNameRecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.MX)
DeleteMXRecord(zoneName, record.RecordName, record.RecordData);
@ -625,6 +639,57 @@ namespace WebsitePanel.Providers.DNS
}
#endregion
#region AAAA Record
/// <summary>
///
/// </summary>
/// <param name="zoneName"></param>
/// <param name="host"></param>
/// <param name="ip"></param>
/// <remarks>Supports managed resources disposal</remarks>
private void AddAAAARecord(string zoneName, string host, string ip) {
// add record
using (ManagementClass clsRR = wmi.GetClass("MicrosoftDNS_AAAAType")) {
clsRR.InvokeMethod("CreateInstanceFromPropertyData", new object[] {
GetDnsServerName(),
zoneName,
CorrectHostName(zoneName, host),
1,
MinimumTTL,
ip
});
}
// update SOA record
if (bulkRecords) return;
UpdateSoaRecord(zoneName);
}
/// <summary>
/// Supports managed resources disposal
/// </summary>
/// <param name="zoneName"></param>
/// <param name="host"></param>
/// <param name="ip"></param>
private void DeleteAAAARecord(string zoneName, string host, string ip) {
string query = String.Format("SELECT * FROM MicrosoftDNS_AAAAType " +
"WHERE ContainerName = '{0}' AND OwnerName = '{1}'",
zoneName, CorrectHostName(zoneName, host));
if (ip != null)
query += String.Format(" AND RecordData = '{0}'", ip);
using (ManagementObjectCollection objRRs = wmi.ExecuteQuery(query)) {
foreach (ManagementObject objRR in objRRs) using (objRR)
objRR.Delete();
}
// update SOA record
UpdateSoaRecord(zoneName);
}
#endregion
#region CNAME Record
/// <summary>
///

View file

@ -101,6 +101,9 @@ namespace WebsitePanel.Providers.DNS
case "A":
dnsRecord.RecordType = DnsRecordType.A;
break;
case "AAAA":
dnsRecord.RecordType = DnsRecordType.AAAA;
break;
case "MX":
dnsRecord.RecordType = DnsRecordType.MX;
break;

View file

@ -1060,7 +1060,11 @@ namespace WebsitePanel.Providers.DNS
result = DnsRecordType.A;
break;
case "CNAME":
case "AAAA":
result = DnsRecordType.AAAA;
break;
case "CNAME":
result = DnsRecordType.CNAME;
break;
@ -1098,6 +1102,10 @@ namespace WebsitePanel.Providers.DNS
result = "A";
break;
case DnsRecordType.AAAA:
result = "AAAA";
break;
case DnsRecordType.CNAME:
result = "CNAME";
break;

View file

@ -190,6 +190,8 @@ namespace WebsitePanel.Providers.DNS
{
if (record.RecordType == DnsRecordType.A)
AddARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.AAAA)
AddAAAARecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.CNAME)
AddCNameRecord(zoneName, record.RecordName, record.RecordData);
else if (record.RecordType == DnsRecordType.MX)
@ -225,7 +227,7 @@ namespace WebsitePanel.Providers.DNS
{
try
{
if (record.RecordType == DnsRecordType.A || record.RecordType == DnsRecordType.CNAME)
if (record.RecordType == DnsRecordType.A || record.RecordType == DnsRecordType.AAAA || record.RecordType == DnsRecordType.CNAME)
record.RecordName = CorrectRecordName(zoneName, record.RecordName);
// delete record
@ -254,7 +256,7 @@ namespace WebsitePanel.Providers.DNS
}
#endregion
#region A records
#region A & AAAA records
private void AddARecord(string zoneName, string host, string ip)
{
// get all zone records
@ -285,6 +287,34 @@ namespace WebsitePanel.Providers.DNS
UpdateZone(zoneName, records);
}
private void AddAAAARecord(string zoneName, string host, string ip) {
// get all zone records
List<DnsRecord> records = GetZoneRecordsArrayList(zoneName);
// delete AAAA record
//DeleteARecordInternal(records, zoneName, host);
//check if user tries to add existent zone record
foreach (DnsRecord dnsRecord in records) {
if ((String.Compare(dnsRecord.RecordName, host, StringComparison.OrdinalIgnoreCase) == 0)
&& (String.Compare(dnsRecord.RecordData, ip, StringComparison.OrdinalIgnoreCase) == 0)
)
return;
}
// add new AAAA record
DnsRecord record = new DnsRecord();
record.RecordType = DnsRecordType.AAAA;
record.RecordName = host;
record.RecordData = ip;
records.Add(record);
// update zone
UpdateZone(zoneName, records);
}
private void DeleteRecord(string zoneName, DnsRecordType recordType,
string recordName, string recordData)
{
@ -576,6 +606,15 @@ namespace WebsitePanel.Providers.DNS
r.RecordText = zfLine;
records.Add(r);
}
else if (recordType == "AAAA") // A record
{
DnsRecord r = new DnsRecord();
r.RecordType = DnsRecordType.AAAA;
r.RecordName = CorrectRecordName(zoneName, recordName);
r.RecordData = recordData;
r.RecordText = zfLine;
records.Add(r);
}
else if (recordType == "CNAME") // CNAME record
{
DnsRecord r = new DnsRecord();
@ -696,6 +735,12 @@ namespace WebsitePanel.Providers.DNS
data = rr.RecordData;
name = BuildRecordName(zoneName, host);
}
else if (rr.RecordType == DnsRecordType.AAAA) {
type = "AAAA";
host = rr.RecordName;
data = rr.RecordData;
name = BuildRecordName(zoneName, host);
}
else if (rr.RecordType == DnsRecordType.NS)
{
type = "NS";

View file

@ -89,6 +89,8 @@ namespace WebsitePanel.Providers.DNS
{
// A record
{ DnsRecordType.A, new BuildDnsRecordDataEventHandler(BuildRecordData_ARecord) },
// AAAA record
{ DnsRecordType.AAAA, new BuildDnsRecordDataEventHandler(BuildRecordData_AAAARecord) },
// NS record
{ DnsRecordType.NS, new BuildDnsRecordDataEventHandler(BuildRecordData_NSRecord) },
// CNAME
@ -148,6 +150,13 @@ namespace WebsitePanel.Providers.DNS
RecordData = record.DataFields[0]
};
break;
case "AAAA":
dnsRecord = new DnsRecord {
RecordName = recordName,
RecordType = DnsRecordType.AAAA,
RecordData = record.DataFields[0]
};
break;
case "NS":
dnsRecord = new DnsRecord
{
@ -531,6 +540,12 @@ namespace WebsitePanel.Providers.DNS
//
dnsZone.Records.Add(m_strRecordName, "A", rr.RecordData);
break;
case DnsRecordType.AAAA:
// cleanup DNS record if exists
dnsZone.Records.Remove(m_strRecordName, "AAAA");
//
dnsZone.Records.Add(m_strRecordName, "AAAA", rr.RecordData);
break;
case DnsRecordType.NS:
// cleanup DNS record if exists
dnsZone.Records.Remove(m_strRecordName, "NS");
@ -583,6 +598,8 @@ namespace WebsitePanel.Providers.DNS
{
if (r_type == DnsRecordType.A)
return "A";
else if (r_type == DnsRecordType.AAAA)
return "AAAA";
else if (r_type == DnsRecordType.CNAME)
return "CNAME";
else if (r_type == DnsRecordType.MX)
@ -610,6 +627,13 @@ namespace WebsitePanel.Providers.DNS
data.Add(record.RecordData);
}
static void BuildRecordData_AAAARecord(string zoneName, ref string type,
DnsRecord record, List<string> data)
{
type = "AAAA";
data.Add(record.RecordData);
}
static void BuildRecordData_NSRecord(string zoneName, ref string type,
DnsRecord record, List<string> data)
{

View file

@ -1,40 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<SiteSettings>
<!-- Display Settings -->
<PortalName>WebsitePanel</PortalName>
<!-- Enterprise Server -->
<EnterpriseServer>http://localhost:9002</EnterpriseServer>
<!-- General Settings -->
<CultureCookieName>UserCulture</CultureCookieName>
<ThemeCookieName>UserTheme</ThemeCookieName>
<!-- Mail Settings -->
<AdminEmail>
</AdminEmail>
<SmtpHost>
</SmtpHost>
<SmtpPort>
</SmtpPort>
<SmtpUsername>
</SmtpUsername>
<SmtpPassword>
</SmtpPassword>
<FromEmail>
</FromEmail>
<!-- Pages -->
<DefaultPage>Home</DefaultPage>
<LoginPage>Login</LoginPage>
<UserHomePage>Home</UserHomePage>
<UserCustomersPage>UserCustomers</UserCustomersPage>
<SpaceHomePage>SpaceHome</SpaceHomePage>
<NestedSpacesPage>NestedSpaces</NestedSpacesPage>
<UsersSearchPage>SearchUsers</UsersSearchPage>
<SpacesSearchPage>SearchSpaces</SpacesSearchPage>
<LoggedUserAccountPage>LoggedUserDetails</LoggedUserAccountPage>
<!-- Skins and Containers -->
<PortalSkin>Browse2.ascx</PortalSkin>
<PortalContainer>Browse.ascx</PortalContainer>
<AdminSkin>Edit.ascx</AdminSkin>
<AdminContainer>Edit.ascx</AdminContainer>
<!-- SSL Settings -->
<UseSSL>false</UseSSL>
<!-- Display Settings -->
<PortalName>WebsitePanel</PortalName>
<!-- Enterprise Server -->
<EnterpriseServer>http://localhost:9005</EnterpriseServer>
<!-- General Settings -->
<CultureCookieName>UserCulture</CultureCookieName>
<ThemeCookieName>UserTheme</ThemeCookieName>
<!-- Mail Settings -->
<AdminEmail>
</AdminEmail>
<SmtpHost>
</SmtpHost>
<SmtpPort>
</SmtpPort>
<SmtpUsername>
</SmtpUsername>
<SmtpPassword>
</SmtpPassword>
<FromEmail>
</FromEmail>
<!-- Pages -->
<DefaultPage>Home</DefaultPage>
<LoginPage>Login</LoginPage>
<UserHomePage>Home</UserHomePage>
<UserCustomersPage>UserCustomers</UserCustomersPage>
<SpaceHomePage>SpaceHome</SpaceHomePage>
<NestedSpacesPage>NestedSpaces</NestedSpacesPage>
<UsersSearchPage>SearchUsers</UsersSearchPage>
<SpacesSearchPage>SearchSpaces</SpacesSearchPage>
<LoggedUserAccountPage>LoggedUserDetails</LoggedUserAccountPage>
<!-- Skins and Containers -->
<PortalSkin>Browse2.ascx</PortalSkin>
<PortalContainer>Browse.ascx</PortalContainer>
<AdminSkin>Edit.ascx</AdminSkin>
<AdminContainer>Edit.ascx</AdminContainer>
<!-- SSL Settings -->
<UseSSL>false</UseSSL>
</SiteSettings>

View file

@ -112,36 +112,42 @@
</Compile>
<Compile Include="BillingCycles.ascx.cs">
<DependentUpon>BillingCycles.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="BillingCycles.ascx.designer.cs">
<DependentUpon>BillingCycles.ascx</DependentUpon>
</Compile>
<Compile Include="BillingCyclesAddCycle.ascx.cs">
<DependentUpon>BillingCyclesAddCycle.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="BillingCyclesAddCycle.ascx.designer.cs">
<DependentUpon>BillingCyclesAddCycle.ascx</DependentUpon>
</Compile>
<Compile Include="BillingCyclesEditCycle.ascx.cs">
<DependentUpon>BillingCyclesEditCycle.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="BillingCyclesEditCycle.ascx.designer.cs">
<DependentUpon>BillingCyclesEditCycle.ascx</DependentUpon>
</Compile>
<Compile Include="Categories.ascx.cs">
<DependentUpon>Categories.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Categories.ascx.designer.cs">
<DependentUpon>Categories.ascx</DependentUpon>
</Compile>
<Compile Include="CategoriesAddCategory.ascx.cs">
<DependentUpon>CategoriesAddCategory.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CategoriesAddCategory.ascx.designer.cs">
<DependentUpon>CategoriesAddCategory.ascx</DependentUpon>
</Compile>
<Compile Include="CategoriesEditCategory.ascx.cs">
<DependentUpon>CategoriesEditCategory.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CategoriesEditCategory.ascx.designer.cs">
<DependentUpon>CategoriesEditCategory.ascx</DependentUpon>
@ -153,8 +159,12 @@
<Compile Include="Code\Framework\CheckoutBasePage.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Code\Framework\ecControlBase.cs" />
<Compile Include="Code\Framework\ecModuleBase.cs" />
<Compile Include="Code\Framework\ecControlBase.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Code\Framework\ecModuleBase.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Code\Framework\ecPanelFormatter.cs" />
<Compile Include="Code\Framework\ecPanelGlobals.cs" />
<Compile Include="Code\Framework\ecPanelRequest.cs" />
@ -181,150 +191,175 @@
</Compile>
<Compile Include="CustomerPaymentProfile.ascx.cs">
<DependentUpon>CustomerPaymentProfile.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomerPaymentProfile.ascx.designer.cs">
<DependentUpon>CustomerPaymentProfile.ascx</DependentUpon>
</Compile>
<Compile Include="CustomersInvoices.ascx.cs">
<DependentUpon>CustomersInvoices.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomersInvoices.ascx.designer.cs">
<DependentUpon>CustomersInvoices.ascx</DependentUpon>
</Compile>
<Compile Include="CustomersInvoicesViewInvoice.ascx.cs">
<DependentUpon>CustomersInvoicesViewInvoice.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomersInvoicesViewInvoice.ascx.designer.cs">
<DependentUpon>CustomersInvoicesViewInvoice.ascx</DependentUpon>
</Compile>
<Compile Include="CustomersPayments.ascx.cs">
<DependentUpon>CustomersPayments.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomersPayments.ascx.designer.cs">
<DependentUpon>CustomersPayments.ascx</DependentUpon>
</Compile>
<Compile Include="CustomersServices.ascx.cs">
<DependentUpon>CustomersServices.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomersServices.ascx.designer.cs">
<DependentUpon>CustomersServices.ascx</DependentUpon>
</Compile>
<Compile Include="CustomersServicesUpgradeService.ascx.cs">
<DependentUpon>CustomersServicesUpgradeService.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomersServicesUpgradeService.ascx.designer.cs">
<DependentUpon>CustomersServicesUpgradeService.ascx</DependentUpon>
</Compile>
<Compile Include="CustomersServicesViewService.ascx.cs">
<DependentUpon>CustomersServicesViewService.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="CustomersServicesViewService.ascx.designer.cs">
<DependentUpon>CustomersServicesViewService.ascx</DependentUpon>
</Compile>
<Compile Include="DomainNames.ascx.cs">
<DependentUpon>DomainNames.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="DomainNames.ascx.designer.cs">
<DependentUpon>DomainNames.ascx</DependentUpon>
</Compile>
<Compile Include="DomainNamesAddDomain.ascx.cs">
<DependentUpon>DomainNamesAddDomain.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="DomainNamesAddDomain.ascx.designer.cs">
<DependentUpon>DomainNamesAddDomain.ascx</DependentUpon>
</Compile>
<Compile Include="DomainNamesEditDomain.ascx.cs">
<DependentUpon>DomainNamesEditDomain.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="DomainNamesEditDomain.ascx.designer.cs">
<DependentUpon>DomainNamesEditDomain.ascx</DependentUpon>
</Compile>
<Compile Include="DomainRegistrarDirecti.ascx.cs">
<DependentUpon>DomainRegistrarDirecti.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="DomainRegistrarDirecti.ascx.designer.cs">
<DependentUpon>DomainRegistrarDirecti.ascx</DependentUpon>
</Compile>
<Compile Include="DomainRegistrarEnom.ascx.cs">
<DependentUpon>DomainRegistrarEnom.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="DomainRegistrarEnom.ascx.designer.cs">
<DependentUpon>DomainRegistrarEnom.ascx</DependentUpon>
</Compile>
<Compile Include="EcommerceSystemSettings.ascx.cs">
<DependentUpon>EcommerceSystemSettings.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="EcommerceSystemSettings.ascx.designer.cs">
<DependentUpon>EcommerceSystemSettings.ascx</DependentUpon>
</Compile>
<Compile Include="HostingAddons.ascx.cs">
<DependentUpon>HostingAddons.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="HostingAddons.ascx.designer.cs">
<DependentUpon>HostingAddons.ascx</DependentUpon>
</Compile>
<Compile Include="HostingAddonsAddAddon.ascx.cs">
<DependentUpon>HostingAddonsAddAddon.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="HostingAddonsAddAddon.ascx.designer.cs">
<DependentUpon>HostingAddonsAddAddon.ascx</DependentUpon>
</Compile>
<Compile Include="HostingAddonsEditAddon.ascx.cs">
<DependentUpon>HostingAddonsEditAddon.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="HostingAddonsEditAddon.ascx.designer.cs">
<DependentUpon>HostingAddonsEditAddon.ascx</DependentUpon>
</Compile>
<Compile Include="HostingPlans.ascx.cs">
<DependentUpon>HostingPlans.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="HostingPlans.ascx.designer.cs">
<DependentUpon>HostingPlans.ascx</DependentUpon>
</Compile>
<Compile Include="HostingPlansAddPlan.ascx.cs">
<DependentUpon>HostingPlansAddPlan.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="HostingPlansAddPlan.ascx.designer.cs">
<DependentUpon>HostingPlansAddPlan.ascx</DependentUpon>
</Compile>
<Compile Include="HostingPlansEditPlan.ascx.cs">
<DependentUpon>HostingPlansEditPlan.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="HostingPlansEditPlan.ascx.designer.cs">
<DependentUpon>HostingPlansEditPlan.ascx</DependentUpon>
</Compile>
<Compile Include="NotificationNewInvoice.ascx.cs">
<DependentUpon>NotificationNewInvoice.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="NotificationNewInvoice.ascx.designer.cs">
<DependentUpon>NotificationNewInvoice.ascx</DependentUpon>
</Compile>
<Compile Include="NotificationPaymentReceived.ascx.cs">
<DependentUpon>NotificationPaymentReceived.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="NotificationPaymentReceived.ascx.designer.cs">
<DependentUpon>NotificationPaymentReceived.ascx</DependentUpon>
</Compile>
<Compile Include="NotificationServiceActivated.ascx.cs">
<DependentUpon>NotificationServiceActivated.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="NotificationServiceActivated.ascx.designer.cs">
<DependentUpon>NotificationServiceActivated.ascx</DependentUpon>
</Compile>
<Compile Include="NotificationServiceCancelled.ascx.cs">
<DependentUpon>NotificationServiceCancelled.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="NotificationServiceCancelled.ascx.designer.cs">
<DependentUpon>NotificationServiceCancelled.ascx</DependentUpon>
</Compile>
<Compile Include="NotificationServiceSuspended.ascx.cs">
<DependentUpon>NotificationServiceSuspended.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="NotificationServiceSuspended.ascx.designer.cs">
<DependentUpon>NotificationServiceSuspended.ascx</DependentUpon>
</Compile>
<Compile Include="OrderFailed.ascx.cs">
<DependentUpon>OrderFailed.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="OrderFailed.ascx.designer.cs">
<DependentUpon>OrderFailed.ascx</DependentUpon>
@ -338,48 +373,56 @@
</Compile>
<Compile Include="PaymentMethod2Checkout.ascx.cs">
<DependentUpon>PaymentMethod2Checkout.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethod2Checkout.ascx.designer.cs">
<DependentUpon>PaymentMethod2Checkout.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethodCreditCard.ascx.cs">
<DependentUpon>PaymentMethodCreditCard.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethodCreditCard.ascx.designer.cs">
<DependentUpon>PaymentMethodCreditCard.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethodOffline.ascx.cs">
<DependentUpon>PaymentMethodOffline.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethodOffline.ascx.designer.cs">
<DependentUpon>PaymentMethodOffline.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethodPayPalAccount.ascx.cs">
<DependentUpon>PaymentMethodPayPalAccount.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethodPayPalAccount.ascx.designer.cs">
<DependentUpon>PaymentMethodPayPalAccount.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethods\2CO_Payment.ascx.cs">
<DependentUpon>2CO_Payment.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethods\2CO_Payment.ascx.designer.cs">
<DependentUpon>2CO_Payment.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethods\CreditCard_Payment.ascx.cs">
<DependentUpon>CreditCard_Payment.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethods\CreditCard_Payment.ascx.designer.cs">
<DependentUpon>CreditCard_Payment.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethods\Offline_Payment.ascx.cs">
<DependentUpon>Offline_Payment.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethods\Offline_Payment.ascx.designer.cs">
<DependentUpon>Offline_Payment.ascx</DependentUpon>
</Compile>
<Compile Include="PaymentMethods\PPAccount_Payment.ascx.cs">
<DependentUpon>PPAccount_Payment.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="PaymentMethods\PPAccount_Payment.ascx.designer.cs">
<DependentUpon>PPAccount_Payment.ascx</DependentUpon>
@ -393,30 +436,35 @@
</Compile>
<Compile Include="ProductControls\DomainName_ServiceDetails.ascx.cs">
<DependentUpon>DomainName_ServiceDetails.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ProductControls\DomainName_ServiceDetails.ascx.designer.cs">
<DependentUpon>DomainName_ServiceDetails.ascx</DependentUpon>
</Compile>
<Compile Include="ProductControls\HostingAddon_ServiceDetails.ascx.cs">
<DependentUpon>HostingAddon_ServiceDetails.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ProductControls\HostingAddon_ServiceDetails.ascx.designer.cs">
<DependentUpon>HostingAddon_ServiceDetails.ascx</DependentUpon>
</Compile>
<Compile Include="ProductControls\HostingPlan_Brief.ascx.cs">
<DependentUpon>HostingPlan_Brief.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ProductControls\HostingPlan_Brief.ascx.designer.cs">
<DependentUpon>HostingPlan_Brief.ascx</DependentUpon>
</Compile>
<Compile Include="ProductControls\HostingPlan_Highlights.ascx.cs">
<DependentUpon>HostingPlan_Highlights.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ProductControls\HostingPlan_Highlights.ascx.designer.cs">
<DependentUpon>HostingPlan_Highlights.ascx</DependentUpon>
</Compile>
<Compile Include="ProductControls\HostingPlan_ServiceDetails.ascx.cs">
<DependentUpon>HostingPlan_ServiceDetails.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ProductControls\HostingPlan_ServiceDetails.ascx.designer.cs">
<DependentUpon>HostingPlan_ServiceDetails.ascx</DependentUpon>
@ -424,24 +472,28 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProvisioningSettingsEdit.ascx.cs">
<DependentUpon>ProvisioningSettingsEdit.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ProvisioningSettingsEdit.ascx.designer.cs">
<DependentUpon>ProvisioningSettingsEdit.ascx</DependentUpon>
</Compile>
<Compile Include="QuickSignup.ascx.cs">
<DependentUpon>QuickSignup.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="QuickSignup.ascx.designer.cs">
<DependentUpon>QuickSignup.ascx</DependentUpon>
</Compile>
<Compile Include="OrderComplete.ascx.cs">
<DependentUpon>OrderComplete.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="OrderComplete.ascx.designer.cs">
<DependentUpon>OrderComplete.ascx</DependentUpon>
</Compile>
<Compile Include="OrderCheckout.ascx.cs">
<DependentUpon>OrderCheckout.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="OrderCheckout.ascx.designer.cs">
<DependentUpon>OrderCheckout.ascx</DependentUpon>
@ -453,102 +505,119 @@
</Compile>
<Compile Include="SkinControls\CatalogBreadCrumb.ascx.cs">
<DependentUpon>CatalogBreadCrumb.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SkinControls\CatalogBreadCrumb.ascx.designer.cs">
<DependentUpon>CatalogBreadCrumb.ascx</DependentUpon>
</Compile>
<Compile Include="StorefrontMenu.ascx.cs">
<DependentUpon>StorefrontMenu.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="StorefrontMenu.ascx.designer.cs">
<DependentUpon>StorefrontMenu.ascx</DependentUpon>
</Compile>
<Compile Include="StorefrontOrderProduct.ascx.cs">
<DependentUpon>StorefrontOrderProduct.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="StorefrontOrderProduct.ascx.designer.cs">
<DependentUpon>StorefrontOrderProduct.ascx</DependentUpon>
</Compile>
<Compile Include="StorefrontViewCategory.ascx.cs">
<DependentUpon>StorefrontViewCategory.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="StorefrontViewCategory.ascx.designer.cs">
<DependentUpon>StorefrontViewCategory.ascx</DependentUpon>
</Compile>
<Compile Include="StorefrontWelcome.ascx.cs">
<DependentUpon>StorefrontWelcome.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="StorefrontWelcome.ascx.designer.cs">
<DependentUpon>StorefrontWelcome.ascx</DependentUpon>
</Compile>
<Compile Include="StorefrontWelcomeEdit.ascx.cs">
<DependentUpon>StorefrontWelcomeEdit.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="StorefrontWelcomeEdit.ascx.designer.cs">
<DependentUpon>StorefrontWelcomeEdit.ascx</DependentUpon>
</Compile>
<Compile Include="SupportedPlugins\2Checkout_Settings.ascx.cs">
<DependentUpon>2Checkout_Settings.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SupportedPlugins\2Checkout_Settings.ascx.designer.cs">
<DependentUpon>2Checkout_Settings.ascx</DependentUpon>
</Compile>
<Compile Include="SupportedPlugins\AuthorizeNet_Settings.ascx.cs">
<DependentUpon>AuthorizeNet_Settings.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SupportedPlugins\AuthorizeNet_Settings.ascx.designer.cs">
<DependentUpon>AuthorizeNet_Settings.ascx</DependentUpon>
</Compile>
<Compile Include="SupportedPlugins\OfflinePayment_Settings.ascx.cs">
<DependentUpon>OfflinePayment_Settings.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SupportedPlugins\OfflinePayment_Settings.ascx.designer.cs">
<DependentUpon>OfflinePayment_Settings.ascx</DependentUpon>
</Compile>
<Compile Include="SupportedPlugins\PayPalPro_Settings.ascx.cs">
<DependentUpon>PayPalPro_Settings.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SupportedPlugins\PayPalPro_Settings.ascx.designer.cs">
<DependentUpon>PayPalPro_Settings.ascx</DependentUpon>
</Compile>
<Compile Include="SupportedPlugins\PayPalStandard_Settings.ascx.cs">
<DependentUpon>PayPalStandard_Settings.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="SupportedPlugins\PayPalStandard_Settings.ascx.designer.cs">
<DependentUpon>PayPalStandard_Settings.ascx</DependentUpon>
</Compile>
<Compile Include="Taxations.ascx.cs">
<DependentUpon>Taxations.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Taxations.ascx.designer.cs">
<DependentUpon>Taxations.ascx</DependentUpon>
</Compile>
<Compile Include="TaxationsAddTax.ascx.cs">
<DependentUpon>TaxationsAddTax.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="TaxationsAddTax.ascx.designer.cs">
<DependentUpon>TaxationsAddTax.ascx</DependentUpon>
</Compile>
<Compile Include="TaxationsEditTax.ascx.cs">
<DependentUpon>TaxationsEditTax.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="TaxationsEditTax.ascx.designer.cs">
<DependentUpon>TaxationsEditTax.ascx</DependentUpon>
</Compile>
<Compile Include="TermsAndConditions.ascx.cs">
<DependentUpon>TermsAndConditions.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="TermsAndConditions.ascx.designer.cs">
<DependentUpon>TermsAndConditions.ascx</DependentUpon>
</Compile>
<Compile Include="TermsAndConditionsEdit.ascx.cs">
<DependentUpon>TermsAndConditionsEdit.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="TermsAndConditionsEdit.ascx.designer.cs">
<DependentUpon>TermsAndConditionsEdit.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\AddonProducts.ascx.cs">
<DependentUpon>AddonProducts.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\AddonProducts.ascx.designer.cs">
<DependentUpon>AddonProducts.ascx</DependentUpon>
@ -565,120 +634,140 @@
</Compile>
<Compile Include="UserControls\ChoosePaymentMethod.ascx.cs">
<DependentUpon>ChoosePaymentMethod.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\ChoosePaymentMethod.ascx.designer.cs">
<DependentUpon>ChoosePaymentMethod.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\CreateUserAccount.ascx.cs">
<DependentUpon>CreateUserAccount.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\CreateUserAccount.ascx.designer.cs">
<DependentUpon>CreateUserAccount.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\CustomerInvoiceTemplated.ascx.cs">
<DependentUpon>CustomerInvoiceTemplated.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\CustomerInvoiceTemplated.ascx.designer.cs">
<DependentUpon>CustomerInvoiceTemplated.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\DomainNameBillingCycles.ascx.cs">
<DependentUpon>DomainNameBillingCycles.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\DomainNameBillingCycles.ascx.designer.cs">
<DependentUpon>DomainNameBillingCycles.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\EmailNotificationEditor.ascx.cs">
<DependentUpon>EmailNotificationEditor.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\EmailNotificationEditor.ascx.designer.cs">
<DependentUpon>EmailNotificationEditor.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\HostingAddonOneTimeFee.ascx.cs">
<DependentUpon>HostingAddonOneTimeFee.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\HostingAddonOneTimeFee.ascx.designer.cs">
<DependentUpon>HostingAddonOneTimeFee.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\HostingPlanBillingCycles.ascx.cs">
<DependentUpon>HostingPlanBillingCycles.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\HostingPlanBillingCycles.ascx.designer.cs">
<DependentUpon>HostingPlanBillingCycles.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\HostingPlanQuotas.ascx.cs">
<DependentUpon>HostingPlanQuotas.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\HostingPlanQuotas.ascx.designer.cs">
<DependentUpon>HostingPlanQuotas.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\LoginUserAccount.ascx.cs">
<DependentUpon>LoginUserAccount.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\LoginUserAccount.ascx.designer.cs">
<DependentUpon>LoginUserAccount.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\ManualPaymentAdd.ascx.cs">
<DependentUpon>ManualPaymentAdd.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\ManualPaymentAdd.ascx.designer.cs">
<DependentUpon>ManualPaymentAdd.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\PlanDomainOption.ascx.cs">
<DependentUpon>PlanDomainOption.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\PlanDomainOption.ascx.designer.cs">
<DependentUpon>PlanDomainOption.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\PlanHostingAddons.ascx.cs">
<DependentUpon>PlanHostingAddons.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\PlanHostingAddons.ascx.designer.cs">
<DependentUpon>PlanHostingAddons.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\ProductHighlights.ascx.cs">
<DependentUpon>ProductHighlights.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\ProductHighlights.ascx.designer.cs">
<DependentUpon>ProductHighlights.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\QuickHostingAddon.ascx.cs">
<DependentUpon>QuickHostingAddon.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\QuickHostingAddon.ascx.designer.cs">
<DependentUpon>QuickHostingAddon.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\QuickHostingPlanCycles.ascx.cs">
<DependentUpon>QuickHostingPlanCycles.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\QuickHostingPlanCycles.ascx.designer.cs">
<DependentUpon>QuickHostingPlanCycles.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\QuickHostingPlans.ascx.cs">
<DependentUpon>QuickHostingPlans.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\QuickHostingPlans.ascx.designer.cs">
<DependentUpon>QuickHostingPlans.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\PathBreadCrumb.ascx.cs">
<DependentUpon>PathBreadCrumb.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\PathBreadCrumb.ascx.designer.cs">
<DependentUpon>PathBreadCrumb.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\ProductCategories.ascx.cs">
<DependentUpon>ProductCategories.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\ProductCategories.ascx.designer.cs">
<DependentUpon>ProductCategories.ascx</DependentUpon>
</Compile>
<Compile Include="UserControls\UserAccountDetails.ascx.cs">
<DependentUpon>UserAccountDetails.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UserControls\UserAccountDetails.ascx.designer.cs">
<DependentUpon>UserAccountDetails.ascx</DependentUpon>
</Compile>
<Compile Include="ViewProductDetails.ascx.cs">
<DependentUpon>ViewProductDetails.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="ViewProductDetails.ascx.designer.cs">
<DependentUpon>ViewProductDetails.ascx</DependentUpon>

View file

@ -73,6 +73,7 @@ function confirmation()
<td class="NormalBold">
<asp:DropDownList ID="ddlRecordType" runat="server" SelectedValue='<%# Bind("RecordType") %>' CssClass="NormalTextBox" AutoPostBack="True" OnSelectedIndexChanged="ddlRecordType_SelectedIndexChanged">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>AAAA</asp:ListItem>
<asp:ListItem>MX</asp:ListItem>
<asp:ListItem>NS</asp:ListItem>
<asp:ListItem>TXT</asp:ListItem>
@ -89,11 +90,11 @@ function confirmation()
<tr id="rowData" runat="server">
<td class="SubHead"><asp:Label ID="lblRecordData" runat="server" meta:resourcekey="lblRecordData" Text="Record Data:"></asp:Label></td>
<td class="NormalBold" nowrap>
<asp:TextBox ID="txtRecordData" runat="server" Width="200px" CssClass="NormalTextBox"></asp:TextBox>
<asp:TextBox ID="txtRecordData" runat="server" Width="260px" CssClass="NormalTextBox"></asp:TextBox>
<asp:RequiredFieldValidator ID="valRequireData" runat="server" ControlToValidate="txtRecordData"
ErrorMessage="*" ValidationGroup="DnsZoneRecord" Display="Dynamic"></asp:RequiredFieldValidator>
<asp:regularexpressionvalidator id="IPValidator" runat="server" ValidationExpression="^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$"
Display="Dynamic" ErrorMessage="Please enter a valid IP" ValidationGroup="DnsZoneRecord" ControlToValidate="txtRecordData" CssClass="NormalBold"></asp:regularexpressionvalidator>
<asp:CustomValidator ID="IPValidator" runat="server" ControlToValidate="txtRecordData" ValidationGroup="DnsZoneRecord" Display="Dynamic" CssClass="NormalBold"
Text="Please enter a valid IP" OnServerValidate="Validate" meta:resourcekey="IPValidator" />
</td>
</tr>
@ -102,14 +103,14 @@ function confirmation()
<td class="NormalBold">
<asp:TextBox ID="txtMXPriority" runat="server" Width="30" CssClass="NormalTextBox"></asp:TextBox>
<asp:RequiredFieldValidator ID="valRequireMxPriority" runat="server" ControlToValidate="txtMXPriority"
ErrorMessage="*" ValidationGroup="DnsZoneRecord" Display="Dynamic"></asp:RequiredFieldValidator>
ErrorMessage="*" ValidationGroup="DnsZoneRecord" Display="Dynamic" />
<asp:RegularExpressionValidator ID="valRequireCorrectPriority" runat="server" ControlToValidate="txtMXPriority"
ErrorMessage="*" ValidationExpression="\d{1,3}"></asp:RegularExpressionValidator></td>
ErrorMessage="*" ValidationExpression="\d{1,3}" ValidationGroup="DnsZoneRecord" /></td>
</tr>
</table>
</div>
<div class="FormFooter">
<asp:Button ID="btnSave" runat="server" meta:resourcekey="btnSave" Text="Save" CssClass="Button1" OnClick="btnSave_Click" OnClientClick = "ShowProgressDialog('Saving DNS Zone Record ...');" ValidationGroup="DnsZoneRecord" />
<asp:Button ID="btnCancel" runat="server" meta:resourcekey="btnCancel" Text="Cancel" CssClass="Button1" OnClick="btnCancel_Click" CausesValidation="False" /></td>
<asp:Button ID="btnCancel" runat="server" meta:resourcekey="btnCancel" Text="Cancel" CssClass="Button1" OnClick="btnCancel_Click" CausesValidation="False" />
</div>
</asp:Panel>

View file

@ -109,6 +109,11 @@ namespace WebsitePanel.Portal
lblRecordData.Text = "IP:";
IPValidator.Enabled = true;
}
else if (ddlRecordType.SelectedValue == "AAAA")
{
lblRecordData.Text = "IP (v6):";
IPValidator.Enabled = true;
}
else
{
lblRecordData.Text = "Record Data:";
@ -116,6 +121,14 @@ namespace WebsitePanel.Portal
}
}
protected void Validate(object source, ServerValidateEventArgs args) {
var ip = args.Value;
System.Net.IPAddress ipaddr;
args.IsValid = System.Net.IPAddress.TryParse(ip, out ipaddr) && (ip.Contains(":") || ip.Contains(".")) &&
((ddlRecordType.SelectedValue == "A" && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) ||
(ddlRecordType.SelectedValue == "AAAA" && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6));
}
private void SaveRecord()
{
if (Page.IsValid)

View file

@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3074
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -173,7 +172,7 @@ namespace WebsitePanel.Portal {
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator IPValidator;
protected global::System.Web.UI.WebControls.CustomValidator IPValidator;
/// <summary>
/// rowMXPriority control.

View file

@ -113,6 +113,7 @@
<td class="NormalBold" width="100%">
<asp:DropDownList ID="ddlRecordType" runat="server" SelectedValue='<%# Bind("RecordType") %>' CssClass="NormalTextBox" AutoPostBack="True" OnSelectedIndexChanged="ddlRecordType_SelectedIndexChanged">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>AAAA</asp:ListItem>
<asp:ListItem>MX</asp:ListItem>
<asp:ListItem>NS</asp:ListItem>
<asp:ListItem>TXT</asp:ListItem>
@ -129,14 +130,14 @@
<tr id="rowData" runat="server">
<td class="SubHead"><asp:Label ID="lblRecordData" runat="server" meta:resourcekey="lblRecordData" Text="Record Data:"></asp:Label></td>
<td class="NormalBold" nowrap>
<asp:TextBox ID="txtRecordData" runat="server" Width="200px" CssClass="NormalTextBox"></asp:TextBox>
<asp:TextBox ID="txtRecordData" runat="server" Width="260px" CssClass="NormalTextBox"></asp:TextBox>
<asp:RequiredFieldValidator ID="valRequireData" runat="server" ControlToValidate="txtRecordData"
ErrorMessage="*" ValidationGroup="DnsZoneRecord" Display="Dynamic"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<asp:regularexpressionvalidator id="IPValidator1" runat="server" ValidationExpression="^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$"
Display="Dynamic" ErrorMessage="Please enter a valid IP" ValidationGroup="DnsZoneRecord" ControlToValidate="txtRecordData" CssClass="NormalBold"></asp:regularexpressionvalidator>
<asp:CustomValidator ID="IPValidator" runat="server" ControlToValidate="txtRecordData" ValidationGroup="DnsZoneRecord" Display="Dynamic"
OnServerValidate="Validate" Text="Please enter a valid IP" meta:resourcekey="IPValidator" />
</tr>
<tr id="rowMXPriority" runat="server">
<td class="SubHead"><asp:Label ID="lblMXPriority" runat="server" meta:resourcekey="lblMXPriority" Text="MX Priority:"></asp:Label></td>

View file

@ -110,15 +110,27 @@ namespace WebsitePanel.Portal.ExchangeServer
if (ddlRecordType.SelectedValue == "A")
{
lblRecordData.Text = "IP:";
IPValidator1.Enabled = true;
}
IPValidator.Enabled = true;
}
else if (ddlRecordType.SelectedValue == "AAAA") {
lblRecordData.Text = "IPv6:";
IPValidator.Enabled = true;
}
else
{
lblRecordData.Text = "Record Data:";
IPValidator1.Enabled = false;
IPValidator.Enabled = false;
}
}
protected void Validate(object source, ServerValidateEventArgs args) {
var ip = args.Value;
System.Net.IPAddress ipaddr;
args.IsValid = System.Net.IPAddress.TryParse(ip, out ipaddr) && (ip.Contains(":") || ip.Contains(".")) &&
((ddlRecordType.SelectedValue == "A" && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) ||
(ddlRecordType.SelectedValue == "AAAA" && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6));
}
private void SaveRecord()
{
if (!Page.IsValid)

View file

@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -230,13 +229,13 @@ namespace WebsitePanel.Portal.ExchangeServer {
protected global::System.Web.UI.WebControls.RequiredFieldValidator valRequireData;
/// <summary>
/// IPValidator1 control.
/// IPValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator IPValidator1;
protected global::System.Web.UI.WebControls.CustomValidator IPValidator;
/// <summary>
/// rowMXPriority control.

View file

@ -35,6 +35,7 @@
<td class="Normal" width="100%">
<asp:DropDownList ID="ddlRecordType" runat="server" SelectedValue='<%# Bind("RecordType") %>' CssClass="NormalTextBox" AutoPostBack="True" OnSelectedIndexChanged="ddlRecordType_SelectedIndexChanged">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>AAAA</asp:ListItem>
<asp:ListItem>MX</asp:ListItem>
<asp:ListItem>NS</asp:ListItem>
<asp:ListItem>TXT</asp:ListItem>
@ -51,13 +52,21 @@
<tr id="rowData" runat="server">
<td class="SubHead"><asp:Label ID="lblRecordData" runat="server" meta:resourcekey="lblRecordData" Text="Record Data:"></asp:Label></td>
<td class="Normal" nowrap>
<asp:TextBox ID="txtRecordData" runat="server" Width="100px" CssClass="NormalTextBox"></asp:TextBox><uc1:SelectIPAddress ID="ipAddress" runat="server" />
<asp:TextBox ID="txtRecordData" runat="server" Width="260px" CssClass="NormalTextBox"></asp:TextBox><uc1:SelectIPAddress ID="ipAddress" runat="server" />
<asp:RequiredFieldValidator ID="valRequireData" runat="server" ControlToValidate="txtRecordData"
ErrorMessage="*" ValidationGroup="DnsRecord" Display="Dynamic"></asp:RequiredFieldValidator>
<asp:CustomValidator ID="IPValidator" runat="server" ControlToValidate="txtRecordData" ValidationGroup="DnsRecord" Display="Dynamic" CssClass="NormalBold"
OnServerValidate="Validate" Text="Please enter a valid IP" meta:resourcekey="IPValidator"/>
</td>
</tr>
<tr id="rowMXPriority" runat="server">
<td class="SubHead"><asp:Label ID="lblMXPriority" runat="server" meta:resourcekey="lblMXPriority" Text="MX Priority:"></asp:Label></td>
<td class="Normal">
<asp:TextBox ID="txtMXPriority" runat="server" Width="30" CssClass="NormalTextBox"></asp:TextBox>
<asp:RequiredFieldValidator ID="valRequireMxPriority" runat="server" ControlToValidate="txtMXPriority"
ErrorMessage="*" ValidationGroup="DnsRecord" Display="Dynamic"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="valRequireCorrectPriority" runat="server" ControlToValidate="txtMXPriority"
ErrorMessage="*" ValidationExpression="\d{1,3}" ValidationGroup="DnsRecord" />
</td>
</tr>
<tr>

View file

@ -138,13 +138,33 @@ namespace WebsitePanel.Portal
private void ToggleRecordControls()
{
ipAddress.Visible = (ddlRecordType.SelectedValue == "A");
//rowData.Visible = (ddlRecordType.SelectedValue != "A");
ipAddress.Visible = (ddlRecordType.SelectedValue == "A" || ddlRecordType.SelectedValue == "AAAA");
//rowData.Visible = (ddlRecordType.SelectedValue != "A" && ddlRecordType.SelectedValue != "AAAA");
rowMXPriority.Visible = (ddlRecordType.SelectedValue == "MX");
if (ddlRecordType.SelectedValue == "A") {
lblRecordData.Text = "IP:";
IPValidator.Enabled = true;
} else if (ddlRecordType.SelectedValue == "AAAA") {
lblRecordData.Text = "IP (v6):";
IPValidator.Enabled = true;
} else {
lblRecordData.Text = "Record Data:";
IPValidator.Enabled = false;
}
}
protected void Validate(object source, ServerValidateEventArgs args) {
var ip = args.Value;
System.Net.IPAddress ipaddr;
args.IsValid = System.Net.IPAddress.TryParse(ip, out ipaddr) && (ip.Contains(":") || ip.Contains(".")) &&
((ddlRecordType.SelectedValue == "A" && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) ||
(ddlRecordType.SelectedValue == "AAAA" && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6));
}
private void SaveRecord()
{
if (!Page.IsValid) return;
GlobalDnsRecord record = new GlobalDnsRecord();
record.RecordId = (int)ViewState["RecordID"];
record.RecordType = ddlRecordType.SelectedValue;

View file

@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.42
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -10,23 +9,196 @@
namespace WebsitePanel.Portal {
public partial class GlobalDnsRecordsControl {
protected System.Web.UI.WebControls.Panel pnlRecords;
protected System.Web.UI.WebControls.Button btnAdd;
protected System.Web.UI.WebControls.GridView gvRecords;
protected System.Web.UI.WebControls.Panel pnlEdit;
protected System.Web.UI.WebControls.Label lblRecordType;
protected System.Web.UI.WebControls.DropDownList ddlRecordType;
protected System.Web.UI.WebControls.Label lblRecordName;
protected System.Web.UI.WebControls.TextBox txtRecordName;
protected System.Web.UI.HtmlControls.HtmlTableRow rowData;
protected System.Web.UI.WebControls.Label lblRecordData;
protected System.Web.UI.WebControls.TextBox txtRecordData;
protected WebsitePanel.Portal.SelectIPAddress ipAddress;
protected System.Web.UI.HtmlControls.HtmlTableRow rowMXPriority;
protected System.Web.UI.WebControls.Label lblMXPriority;
protected System.Web.UI.WebControls.TextBox txtMXPriority;
protected System.Web.UI.WebControls.Button btnSave;
protected System.Web.UI.WebControls.Button btnCancel;
/// <summary>
/// pnlRecords control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel pnlRecords;
/// <summary>
/// btnAdd control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnAdd;
/// <summary>
/// gvRecords control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.GridView gvRecords;
/// <summary>
/// pnlEdit control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel pnlEdit;
/// <summary>
/// lblRecordType control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblRecordType;
/// <summary>
/// ddlRecordType control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.DropDownList ddlRecordType;
/// <summary>
/// lblRecordName control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblRecordName;
/// <summary>
/// txtRecordName control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtRecordName;
/// <summary>
/// rowData control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlTableRow rowData;
/// <summary>
/// lblRecordData control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblRecordData;
/// <summary>
/// txtRecordData control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtRecordData;
/// <summary>
/// ipAddress control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::WebsitePanel.Portal.SelectIPAddress ipAddress;
/// <summary>
/// valRequireData control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator valRequireData;
/// <summary>
/// IPValidator control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.CustomValidator IPValidator;
/// <summary>
/// rowMXPriority control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlTableRow rowMXPriority;
/// <summary>
/// lblMXPriority control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblMXPriority;
/// <summary>
/// txtMXPriority control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtMXPriority;
/// <summary>
/// valRequireMxPriority control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RequiredFieldValidator valRequireMxPriority;
/// <summary>
/// valRequireCorrectPriority control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator valRequireCorrectPriority;
/// <summary>
/// btnSave control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnSave;
/// <summary>
/// btnCancel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnCancel;
}
}

View file

@ -8,7 +8,9 @@
<asp:ValidationSummary ID="validatorsSummary" runat="server"
ValidationGroup="EditAddress" ShowMessageBox="True" ShowSummary="False" />
<table cellspacing="0" cellpadding="3">
<asp:CustomValidator ID="consistentAddresses" runat="server" ErrorMessage="You must not mix IPv4 and IPv6 addresses." ValidationGroup="EditAddress" Display="dynamic" ServerValidate="CheckIPAddresses" />
<table cellspacing="0" cellpadding="3">
<tr>
<td style="width:150px;">
<asp:Localize ID="locPool" runat="server" meta:resourcekey="locPool" Text="Pool:"></asp:Localize>
@ -33,7 +35,7 @@
<td><asp:Localize ID="lblExternalIP" runat="server" meta:resourcekey="lblExternalIP" Text="IP Address:"></asp:Localize></td>
<td>
<wsp:EditIPAddressControl id="startIP" runat="server" ValidationGroup="EditAddress" Required="true" />
<wsp:EditIPAddressControl id="startIP" runat="server" ValidationGroup="EditAddress" Required="true" AllowSubnet="true" />
&nbsp;<asp:Localize ID="locTo" runat="server" meta:resourcekey="locTo" Text="to"></asp:Localize>&nbsp;
@ -52,7 +54,7 @@
<tr id="SubnetRow" runat="server">
<td><asp:Localize ID="locSubnetMask" runat="server" meta:resourcekey="locSubnetMask" Text="Subnet Mask:"></asp:Localize></td>
<td class="NormalBold">
<wsp:EditIPAddressControl id="subnetMask" runat="server" ValidationGroup="EditAddress" Required="true" />
<wsp:EditIPAddressControl id="subnetMask" runat="server" ValidationGroup="EditAddress" Required="true" AllowSubnet="true" />
</td>
</tr>
<tr id="GatewayRow" runat="server">

View file

@ -49,6 +49,7 @@ namespace WebsitePanel.Portal
{
if (!IsPostBack)
{
// bind dropdowns
try
{
@ -96,7 +97,7 @@ namespace WebsitePanel.Portal
string comments = txtComments.Text.Trim();
// add ip address
if (endIP.Text != "")
if (endIP.Text != "" || startIP.Text.Contains("/"))
{
try
{
@ -162,5 +163,12 @@ namespace WebsitePanel.Portal
SubnetRow.Visible = vps;
GatewayRow.Visible = vps;
}
public void CheckIPAddresses(object sender, ServerValidateEventArgs args) {
startIP.Validate(sender, args);
endIP.Validate(sender, args);
subnetMask.Validate(sender, args);
args.IsValid = startIP.IsV6 == endIP.IsV6 && (startIP.IsV6 == subnetMask.IsV6 || subnetMask.IsMask);
}
}
}

View file

@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1434
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -31,6 +30,15 @@ namespace WebsitePanel.Portal {
/// </remarks>
protected global::System.Web.UI.WebControls.ValidationSummary validatorsSummary;
/// <summary>
/// consistent Addresses control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.CustomValidator consistentAddresses;
/// <summary>
/// locPool control.
/// </summary>

View file

@ -288,7 +288,7 @@
<td>
<wsp:EditIPAddressControl id="privateIPAddress" runat="server" Required="true" />
/
<asp:TextBox ID="privateSubnetMask" runat="server" MaxLength="2" Width="40px" CssClass="NormalTextBox"></asp:TextBox>
<asp:TextBox ID="privateSubnetMask" runat="server" MaxLength="3" Width="40px" CssClass="NormalTextBox"></asp:TextBox>
<asp:RequiredFieldValidator ID="privateSubnetMaskValidator" runat="server" ControlToValidate="privateSubnetMask"
Text="*" meta:resourcekey="privateSubnetMaskValidator" Display="Dynamic" SetFocusOnError="true" />
</td>

View file

@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.

View file

@ -1,8 +1,5 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EditIPAddressControl.ascx.cs" Inherits="WebsitePanel.Portal.UserControls.EditIPAddressControl" %>
<asp:TextBox ID="txtAddress" runat="server" Width="110px" MaxLength="15" CssClass="NormalTextBox"></asp:TextBox>
<asp:TextBox ID="txtAddress" runat="server" Width="260px" MaxLength="45" CssClass="NormalTextBox"></asp:TextBox>
<asp:RequiredFieldValidator ID="requireAddressValidator" runat="server" meta:resourcekey="requireAddressValidator"
ControlToValidate="txtAddress" SetFocusOnError="true" Text="*" Enabled="false" Display="Dynamic">
</asp:RequiredFieldValidator><asp:RegularExpressionValidator id="addressValidator" runat="server"
ValidationExpression="^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$"
Display="Dynamic" SetFocusOnError="true" ControlToValidate="txtAddress" Text="*" meta:resourcekey="addressValidator">
</asp:RegularExpressionValidator>
ControlToValidate="txtAddress" SetFocusOnError="true" Text="*" Enabled="false" Display="Dynamic" />
<asp:CustomValidator ID="addressValidator" runat="server" ControlToValidate="txtAddress" OnServerValidate="Validate" Text="*" meta:resourcekey="addressValidator"/>

View file

@ -34,8 +34,16 @@ using System.Web.UI.WebControls;
namespace WebsitePanel.Portal.UserControls
{
[Flags]
public enum IPValidationMode { V4 = 1, V6 = 2, V4AndV6 = 3 };
public partial class EditIPAddressControl : WebsitePanelControlBase
{
public IPValidationMode Validation { get; set; }
public EditIPAddressControl() { Validation = IPValidationMode.V4AndV6; AllowSubnet = false; }
public bool Required
{
get { return requireAddressValidator.Enabled; }
@ -86,5 +94,30 @@ namespace WebsitePanel.Portal.UserControls
{
}
public bool AllowSubnet { get; set; }
public bool IsV6 { get; private set; }
public bool IsMask { get; private set; }
public void Validate(object source, ServerValidateEventArgs args) {
IsMask = IsV6 = false;
var ip = args.Value;
int net = 0;
if (ip.Contains("/")) {
args.IsValid = AllowSubnet;
var tokens = ip.Split('/');
ip = tokens[0];
args.IsValid &= int.TryParse(tokens[1], out net) && net <= 128;
if (string.IsNullOrEmpty(ip)) {
IsMask = true;
return;
}
}
System.Net.IPAddress ipaddr;
args.IsValid &= System.Net.IPAddress.TryParse(ip, out ipaddr) && (ip.Contains(":") || ip.Contains(".")) &&
(((Validation & IPValidationMode.V6) != 0 && (IsV6 = ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)) ||
((Validation & IPValidationMode.V4) != 0 && ipaddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork));
args.IsValid &= ipaddr.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork || net < 32;
}
}
}

View file

@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1434
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -38,6 +37,6 @@ namespace WebsitePanel.Portal.UserControls {
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.RegularExpressionValidator addressValidator;
protected global::System.Web.UI.WebControls.CustomValidator addressValidator;
}
}

View file

@ -1,12 +1,11 @@
<?xml version="1.0"?>
<configuration>
<system.web>
<pages controlRenderingCompatibilityVersion="3.5">
<controls>
<add tagPrefix="ajaxToolkit" namespace="AjaxControlToolkit" assembly="AjaxControlToolkit"/>
</controls>
</pages>
<compilation targetFramework="4.0">
</compilation>
</system.web>
<system.web>
<pages controlRenderingCompatibilityVersion="3.5">
<controls>
<add tagPrefix="ajaxToolkit" namespace="AjaxControlToolkit" assembly="AjaxControlToolkit"/>
</controls>
</pages>
<compilation targetFramework="4.0" debug="true"/>
</system.web>
</configuration>

View file

@ -18,7 +18,7 @@
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>false</UseIISExpress>
<UseIISExpress>true</UseIISExpress>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -690,11 +690,11 @@
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<UseIIS>True</UseIIS>
<AutoAssignPort>False</AutoAssignPort>
<DevelopmentServerPort>9001</DevelopmentServerPort>
<DevelopmentServerPort>9021</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost/WebPortal</IISUrl>
<IISUrl>http://localhost:9021/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>