Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
+ improvement
  • Loading branch information
Davoud Eshtehari committed May 11, 2021
1 parent 4a1d7f7 commit 7939ea3
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Microsoft.Data.SqlClient;

Expand Down Expand Up @@ -401,66 +402,41 @@ internal static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(st
#endregion

#region <<IPAddressPreference Utility>>

/// <summary>
/// IP Address Preference.
/// </summary>
const string IPAddrPreference46 = "IPv4First";
const string IPAddrPreference64 = "IPv6First";
const string IPAddrPreferenceOS = "UsePlatformDefault";

private readonly static Type s_IPAddressPreferenceType = typeof(SqlConnectionIPAddressPreference);
private readonly static string[] s_PreferenceNames = Enum.GetNames(s_IPAddressPreferenceType);

/// <summary>
/// Convert a string value to the corresponding IPAddressPreference
/// Convert a string value to the corresponding IPAddressPreference.
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <returns></returns>
/// <param name="value">The string representation of the enumeration name to convert.</param>
/// <param name="result">When this method returns, `result` contains an object of type `SqlConnectionIPAddressPreference` whose value is represented by `value` if the operation succeeds.
/// If the parse operation fails, `result` contains the default value of the `SqlConnectionIPAddressPreference` type.</param>
/// <returns>`true` if the value parameter was converted successfully; otherwise, `false`.</returns>
internal static bool TryConvertToIPAddressPreference(string value, out SqlConnectionIPAddressPreference result)
{
if (StringComparer.InvariantCultureIgnoreCase.Equals(value, IPAddrPreference46))
{
result = SqlConnectionIPAddressPreference.IPv4First;
return true;
}
else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, IPAddrPreference64))
{
result = SqlConnectionIPAddressPreference.IPv6First;
return true;
}
else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, IPAddrPreferenceOS))
{
result = SqlConnectionIPAddressPreference.UsePlatformDefault;
return true;
}
else
string temp = s_PreferenceNames.FirstOrDefault(x => x.Equals(value, StringComparison.InvariantCultureIgnoreCase));
if (temp is not null)
{
result = DbConnectionStringDefaults.IPAddressPreference;
return false;
return Enum.TryParse(temp, true, out result);
}

result = DbConnectionStringDefaults.IPAddressPreference;
return false;
}

/// <summary>
/// Verifies if the `value` is defined in the expected Enum.
/// </summary>
internal static bool IsValidIPAddressPreference(SqlConnectionIPAddressPreference value)
{
Debug.Assert(Enum.GetNames(typeof(SqlConnectionIPAddressPreference)).Length == 3, "SqlConnectionIPAddressPreference enum has changed, update needed");
return value == SqlConnectionIPAddressPreference.IPv4First
=> value == SqlConnectionIPAddressPreference.IPv4First
|| value == SqlConnectionIPAddressPreference.IPv6First
|| value == SqlConnectionIPAddressPreference.UsePlatformDefault;
}

internal static string IPAddressPreferenceToString(SqlConnectionIPAddressPreference value)
{
Debug.Assert(IsValidIPAddressPreference(value), "value is not a valid IP address preference");

switch (value)
{
case SqlConnectionIPAddressPreference.UsePlatformDefault:
return IPAddrPreferenceOS;
case SqlConnectionIPAddressPreference.IPv6First:
return IPAddrPreference64;
default:
return IPAddrPreference46;
}
}
=> Enum.GetName(s_IPAddressPreferenceType, value);

internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(string keyword, object value)
{
Expand Down Expand Up @@ -496,20 +472,20 @@ internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(st
// explicitly block scenarios in which user tries to use wrong enum types, like:
// builder["SqlConnectionIPAddressPreference"] = EnvironmentVariableTarget.Process;
// workaround: explicitly cast non-SqlConnectionIPAddressPreference enums to int
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), null);
throw ADP.ConvertFailed(value.GetType(), s_IPAddressPreferenceType, null);
}
else
{
try
{
// Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
eValue = (SqlConnectionIPAddressPreference)Enum.ToObject(typeof(SqlConnectionIPAddressPreference), value);
eValue = (SqlConnectionIPAddressPreference)Enum.ToObject(s_IPAddressPreferenceType, value);
}
catch (ArgumentException e)
{
// to be consistent with the messages we send in case of wrong type usage, replace
// the error with our exception, and keep the original one as inner one for troubleshooting
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), e);
throw ADP.ConvertFailed(value.GetType(), s_IPAddressPreferenceType, e);
}
}

Expand All @@ -519,12 +495,10 @@ internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(st
}
else
{
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionIPAddressPreference), (int)eValue);
throw ADP.InvalidEnumerationValue(s_IPAddressPreferenceType, (int)eValue);
}
}
}


#endregion

internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,26 +176,26 @@ public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel
int portRetry = string.IsNullOrEmpty(cachedDNSInfo.Port) ? port : int.Parse(cachedDNSInfo.Port);
SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, Retrying with cached DNS IP Address {1} and port {2}", args0: _connectionId, args1: cachedDNSInfo.AddrIPv4, args2: cachedDNSInfo.Port);

string cachedIPA;
string cachedIPB;
string firstCachedIP;
string secondCachedIP;

if (SqlConnectionIPAddressPreference.IPv6First == ipPreference) {
cachedIPA = cachedDNSInfo.AddrIPv6;
cachedIPB = cachedDNSInfo.AddrIPv4;
firstCachedIP = cachedDNSInfo.AddrIPv6;
secondCachedIP = cachedDNSInfo.AddrIPv4;
} else {
cachedIPA = cachedDNSInfo.AddrIPv4;
cachedIPB = cachedDNSInfo.AddrIPv6;
firstCachedIP = cachedDNSInfo.AddrIPv4;
secondCachedIP = cachedDNSInfo.AddrIPv6;
}

try
{
if (parallel)
{
_socket = TryConnectParallel(cachedIPA, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo);
_socket = TryConnectParallel(firstCachedIP, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo);
}
else
{
_socket = Connect(cachedIPA, portRetry, ts, isInfiniteTimeOut, ipPreference, cachedFQDN, ref pendingDNSInfo);
_socket = Connect(firstCachedIP, portRetry, ts, isInfiniteTimeOut, ipPreference, cachedFQDN, ref pendingDNSInfo);
}
}
catch (Exception exRetry)
Expand All @@ -206,11 +206,11 @@ public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel
SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, Retrying exception {1}", args0: _connectionId, args1: exRetry?.Message);
if (parallel)
{
_socket = TryConnectParallel(cachedIPB, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo);
_socket = TryConnectParallel(secondCachedIP, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo);
}
else
{
_socket = Connect(cachedIPB, portRetry, ts, isInfiniteTimeOut, ipPreference, cachedFQDN, ref pendingDNSInfo);
_socket = Connect(secondCachedIP, portRetry, ts, isInfiniteTimeOut, ipPreference, cachedFQDN, ref pendingDNSInfo);
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.Data.SqlClient;

namespace Microsoft.Data.Common
Expand Down Expand Up @@ -999,82 +1000,55 @@ internal static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(st
#endregion

#region <<IPAddressPreference Utility>>

/// <summary>
/// IP Address Preference.
/// </summary>
const string IPAddrPreference46 = "IPv4First";
const string IPAddrPreference64 = "IPv6First";
const string IPAddrPreferenceOS = "UsePlatformDefault";

private readonly static Type s_IPAddressPreferenceType = typeof(SqlConnectionIPAddressPreference);
private readonly static string[] s_PreferenceNames = Enum.GetNames(s_IPAddressPreferenceType);

/// <summary>
/// Convert a string value to the corresponding IPAddressPreference
/// Convert a string value to the corresponding IPAddressPreference.
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <returns></returns>
/// <param name="value">The string representation of the enumeration name to convert.</param>
/// <param name="result">When this method returns, `result` contains an object of type `SqlConnectionIPAddressPreference` whose value is represented by `value` if the operation succeeds.
/// If the parse operation fails, `result` contains the default value of the `SqlConnectionIPAddressPreference` type.</param>
/// <returns>`true` if the value parameter was converted successfully; otherwise, `false`.</returns>
internal static bool TryConvertToIPAddressPreference(string value, out SqlConnectionIPAddressPreference result)
{
if (StringComparer.InvariantCultureIgnoreCase.Equals(value, IPAddrPreference46))
{
result = SqlConnectionIPAddressPreference.IPv4First;
return true;
}
else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, IPAddrPreference64))
string temp = s_PreferenceNames.FirstOrDefault(x => x.Equals(value, StringComparison.InvariantCultureIgnoreCase));
if (temp is not null)
{
result = SqlConnectionIPAddressPreference.IPv6First;
return true;
}
else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, IPAddrPreferenceOS))
{
result = SqlConnectionIPAddressPreference.UsePlatformDefault;
return true;
}
else
{
result = DbConnectionStringDefaults.IPAddressPreference;
return false;
return Enum.TryParse(temp, true, out result);
}

result = DbConnectionStringDefaults.IPAddressPreference;
return false;
}

/// <summary>
/// Verifies if the `value` is defined in the expected Enum.
/// </summary>
internal static bool IsValidIPAddressPreference(SqlConnectionIPAddressPreference value)
{
Debug.Assert(Enum.GetNames(typeof(SqlConnectionIPAddressPreference)).Length == 3, "SqlConnectionIPAddressPreference enum has changed, update needed");
return value == SqlConnectionIPAddressPreference.IPv4First
=> value == SqlConnectionIPAddressPreference.IPv4First
|| value == SqlConnectionIPAddressPreference.IPv6First
|| value == SqlConnectionIPAddressPreference.UsePlatformDefault;
}

internal static string IPAddressPreferenceToString(SqlConnectionIPAddressPreference value)
{
Debug.Assert(IsValidIPAddressPreference(value), "value is not a valid IP address preference");

switch (value)
{
case SqlConnectionIPAddressPreference.UsePlatformDefault:
return IPAddrPreferenceOS;
case SqlConnectionIPAddressPreference.IPv6First:
return IPAddrPreference64;
default:
return IPAddrPreference46;
}
}
=> Enum.GetName(s_IPAddressPreferenceType, value);

internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(string keyword, object value)
{
if (null == value)
if (value is null)
{
return DbConnectionStringDefaults.IPAddressPreference; // IPv4First
}

string sValue = (value as string);
SqlConnectionIPAddressPreference result;

if (null != sValue)
if (sValue is not null)
{
// try again after remove leading & trailing whitespaces.
sValue = sValue.Trim();
if (TryConvertToIPAddressPreference(sValue, out result))
if (TryConvertToIPAddressPreference(sValue, out SqlConnectionIPAddressPreference result))
{
return result;
}
Expand All @@ -1087,29 +1061,29 @@ internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(st
// the value is not string, try other options
SqlConnectionIPAddressPreference eValue;

if (value is SqlConnectionIPAddressPreference)
if (value is SqlConnectionIPAddressPreference preference)
{
eValue = (SqlConnectionIPAddressPreference)value;
eValue = preference;
}
else if (value.GetType().IsEnum)
{
// explicitly block scenarios in which user tries to use wrong enum types, like:
// builder["SqlConnectionIPAddressPreference"] = EnvironmentVariableTarget.Process;
// workaround: explicitly cast non-SqlConnectionIPAddressPreference enums to int
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), null);
throw ADP.ConvertFailed(value.GetType(), s_IPAddressPreferenceType, null);
}
else
{
try
{
// Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
eValue = (SqlConnectionIPAddressPreference)Enum.ToObject(typeof(SqlConnectionIPAddressPreference), value);
eValue = (SqlConnectionIPAddressPreference)Enum.ToObject(s_IPAddressPreferenceType, value);
}
catch (ArgumentException e)
{
// to be consistent with the messages we send in case of wrong type usage, replace
// the error with our exception, and keep the original one as inner one for troubleshooting
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), e);
throw ADP.ConvertFailed(value.GetType(), s_IPAddressPreferenceType, e);
}
}

Expand All @@ -1119,11 +1093,10 @@ internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(st
}
else
{
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionIPAddressPreference), (int)eValue);
throw ADP.InvalidEnumerationValue(s_IPAddressPreferenceType, (int)eValue);
}
}
}

#endregion

internal static bool IsValidCertificateValue(string value)
Expand Down

0 comments on commit 7939ea3

Please sign in to comment.