/// <summary> /// Parses a specified DNS stamp string (<seealso cref="dnsStampStr"/>) /// </summary> /// <param name="dnsStampStr">DNS stamp string</param> /// <returns>DNS stamp as a <see cref="DnsStamp"/> instance</returns> internal static DnsStamp ParseDnsStamp(string dnsStampStr) { LOG.InfoFormat("Start parsing DNS stamp {0}", dnsStampStr); IntPtr pDnsStampResult = IntPtr.Zero; try { pDnsStampResult = AGDnsApi.ag_parse_dns_stamp(dnsStampStr); AGDnsApi.ag_parse_dns_stamp_result dnsStampResult = MarshalUtils.PtrToStructure <AGDnsApi.ag_parse_dns_stamp_result>(pDnsStampResult); if (dnsStampResult.error != IntPtr.Zero) { string error = MarshalUtils.PtrToString(dnsStampResult.error); LOG.InfoFormat("Parsing DNS stamp {0} failed with an error {1}", dnsStampStr, error); return(null); } LOG.Info("Parsing DNS stamp has been completed successfully"); DnsStamp dnsStamp = DnsApiConverter.FromNativeObject(dnsStampResult.stamp); return(dnsStamp); } catch (Exception ex) { LOG.InfoException("Parsing DNS stamp failed with an error {0}", ex); return(null); } finally { AGDnsApi.ag_parse_dns_stamp_result_free(pDnsStampResult); } }
/// <summary> /// Gets the DNS stamp pretty url specified by <see cref="DnsStamp"/> object /// </summary> /// <param name="dnsStamp">DNS stamp object /// (<seealso cref="DnsStamp"/>)</param> /// <returns>DNS stamp as a string</returns> public static string GetDnsStampPrettyUrl(DnsStamp dnsStamp) { IntPtr pPrettyUrl = IntPtr.Zero; Queue <IntPtr> allocatedPointers = new Queue <IntPtr>(); try { AGDnsApi.ag_dns_stamp dnsStampC = DnsApiConverter.ToNativeObject(dnsStamp, allocatedPointers); IntPtr pDnsStampC = MarshalUtils.StructureToPtr(dnsStampC, allocatedPointers); pPrettyUrl = AGDnsApi.ag_dns_stamp_pretty_url(pDnsStampC); string prettyUrl = MarshalUtils.PtrToString(pPrettyUrl); return(prettyUrl); } catch (Exception ex) { Logger.Verbose("Getting DNS stamp pretty url failed with an error {0}", ex); return(null); } finally { MarshalUtils.SafeFreeHGlobal(allocatedPointers); AGDnsApi.ag_str_free(pPrettyUrl); } }
/// <summary> /// Gets current DNS proxy version /// </summary> /// <returns></returns> public static string GetDnsProxyVersion() { IntPtr pDnsProxyVersion = AGDnsApi.ag_dnsproxy_version(); string dnsProxyVersion = MarshalUtils.PtrToString(pDnsProxyVersion); return(dnsProxyVersion); }
/// <summary> /// Gets the DNS stamp string specified by <see cref="DnsStamp"/> object /// </summary> /// <param name="dnsStamp">DNS stamp object /// (<seealso cref="DnsStamp"/>)</param> /// <returns>DNS stamp as a string</returns> public static string GetDnsStampString(DnsStamp dnsStamp) { // Don't invoke "dnsStamp.ToString()" within this method to prevent infinite recursion Logger.Verbose("Start getting DNS stamp string from {0}", dnsStamp.ServerAddress); IntPtr pDnsStampString = IntPtr.Zero; Queue <IntPtr> allocatedPointers = new Queue <IntPtr>(); try { AGDnsApi.ag_dns_stamp dnsStampC = DnsApiConverter.ToNativeObject(dnsStamp, allocatedPointers); IntPtr pDnsStampC = MarshalUtils.StructureToPtr(dnsStampC, allocatedPointers); pDnsStampString = AGDnsApi.ag_dns_stamp_to_str(pDnsStampC); string dnsStampString = MarshalUtils.PtrToString(pDnsStampString); Logger.Verbose("Getting DNS stamp string has been successfully completed"); return(dnsStampString); } catch (Exception ex) { Logger.Verbose("Getting DNS stamp string failed with an error {0}", ex); return(null); } finally { MarshalUtils.SafeFreeHGlobal(allocatedPointers); AGDnsApi.ag_str_free(pDnsStampString); } }
/// <summary> /// Stops the proxy server /// If it is not started yet, does nothing. /// </summary> /// <exception cref="InvalidOperationException">Thrown, if cannot closing the proxy server /// via native method</exception> public void Stop() { lock (m_SyncRoot) { try { Logger.Info("Stopping the DnsProxyServer"); if (!IsStarted) { Logger.Info("DnsProxyServer is not started, doing nothing"); return; } AGDnsApi.ag_dnsproxy_deinit(m_pProxyServer); m_IsStarted = false; Logger.Info("Finished stopping the DnsProxyServer"); } catch (Exception ex) { throw new InvalidOperationException("error while stopping the DnsProxyServer: {0}", ex); } finally { Dispose(); } } }
/// <summary> /// Gets the default DNS proxy settings as a <see cref="DnsProxySettings"/> object /// </summary> /// <returns>Current DNS proxy settings /// (<seealso cref="DnsProxySettings"/>)</returns> /// <exception cref="InvalidOperationException">Thrown, /// if cannot get the default dns proxy settings via native method</exception> public static DnsProxySettings GetDefaultDnsProxySettings() { Logger.Info("Get default DnsProxyServer settings"); IntPtr pSettings = AGDnsApi.ag_dnsproxy_settings_get_default(); DnsProxySettings defaultDnsProxySettings = GetDnsProxySettings(pSettings); return(defaultDnsProxySettings); }
/// <summary> /// Sets an stored unhandled exception configuration for the specified Dll /// </summary> internal static void SetUnhandledExceptionConfiguration() { lock (SYNC_ROOT) { AGDnsApi.ag_enable_SetUnhandledExceptionFilter(); SetUnhandledExceptionFilter(m_UnhandledNativeExceptionFilterCallback); AGDnsApi.ag_disable_SetUnhandledExceptionFilter(); } }
/// <summary> /// Initializes the new instance of the DnsProxyServer /// </summary> /// <param name="dnsProxySettings">Dns proxy settings /// (<seealso cref="DnsProxySettings"/>)</param> /// <param name="callbackConfiguration">Callback config configuration /// (<seealso cref="IDnsProxyServerCallbackConfiguration"/>)</param> /// <exception cref="NotSupportedException">Thrown if current API version is not supported</exception> public DnsProxyServer( DnsProxySettings dnsProxySettings, IDnsProxyServerCallbackConfiguration callbackConfiguration) { lock (m_SyncRoot) { Logger.Info("Creating the DnsProxyServer"); AGDnsApi.ValidateApi(); m_DnsProxySettings = dnsProxySettings; m_CallbackConfiguration = callbackConfiguration; } }
/// <summary> /// Sets the previously initialized logger for the specified Dll /// </summary> internal static void SetLogger() { lock (SYNC_ROOT) { AGDnsApi.ag_set_default_log_level(m_LoggerLogLevel); if (m_LoggerCallback == null) { LOG.WarnFormat("Logger callback hasn't been initialized before"); return; } AGDnsApi.ag_logger_set_default_callback(m_LoggerCallback, IntPtr.Zero); LOG.InfoFormat("Logger callback has been set successfully"); } }
/// <summary> /// Sets the previously initialized logger for the specified Dll /// </summary> public static void SetLogger() { lock (SYNC_ROOT) { AGDnsApi.ag_set_log_level(m_LoggerLogLevel); if (m_LoggerCallback == null) { Logger.Warn("Logger callback hasn't been initialized before"); return; } AGDnsApi.ag_set_log_callback(m_LoggerCallback, IntPtr.Zero); Logger.Info("Logger callback has been set successfully"); } }
/// <summary> /// Gets the current DNS proxy settings as a <see cref="DnsProxySettings"/> object /// </summary> /// <returns>Current DNS proxy settings /// (<seealso cref="DnsProxySettings"/>)</returns> /// <exception cref="InvalidOperationException">Thrown, /// if cannot get the current dns proxy settings via native method</exception> public DnsProxySettings GetCurrentDnsProxySettings() { LOG.Info("Get current DnsProxyServer settings"); lock (m_SyncRoot) { if (!IsStarted) { LOG.Info("DnsProxyServer is not started, doing nothing"); return(null); } DnsProxySettings currentDnsProxySettings = GetDnsProxySettings(() => AGDnsApi.ag_dnsproxy_get_settings(m_pProxyServer)); return(currentDnsProxySettings); } }
/// <summary> /// Starts the proxy server /// </summary> /// <exception cref="InvalidOperationException">Thrown, if cannot starting the proxy server /// for any reason</exception> public void Start() { lock (m_SyncRoot) { LOG.Info("Starting the DnsProxyServer"); if (IsStarted) { LOG.Info("DnsProxyServer is already started, doing nothing"); return; } Queue <IntPtr> allocatedPointers = new Queue <IntPtr>(); try { AGDnsApi.ag_dnsproxy_settings dnsProxySettingsC = DnsApiConverter.ToNativeObject(m_DnsProxySettings, allocatedPointers); m_callbackConfigurationC = DnsApiConverter.ToNativeObject(m_CallbackConfiguration, this); IntPtr pDnsProxySettingsC = MarshalUtils.StructureToPtr(dnsProxySettingsC, allocatedPointers); m_pCallbackConfigurationC = MarshalUtils.StructureToPtr(m_callbackConfigurationC); m_pProxyServer = AGDnsApi.ag_dnsproxy_init( pDnsProxySettingsC, m_pCallbackConfigurationC); if (m_pProxyServer == IntPtr.Zero) { const string errorMessage = "Failed to start the DnsProxyServer due to an error"; throw new InvalidOperationException(errorMessage); } m_IsStarted = true; LOG.Info("Finished starting the DnsProxyServer"); } catch (Exception ex) { Dispose(); throw new InvalidOperationException("error while starting the DnsProxyServer", ex); } finally { MarshalUtils.SafeFreeHGlobal(allocatedPointers); } } }
/// <summary> /// Parses a specified DNS stamp string (<seealso cref="dnsStampStr"/>) /// into the <see cref="DnsStamp"/> object. /// </summary> /// <param name="dnsStampStr">DNS stamp string</param> /// <returns>DNS stamp as a <see cref="DnsStamp"/> instance or null if smth went wrong</returns> public static DnsStamp ParseDnsStamp(string dnsStampStr) { Logger.Info("Start parsing DNS stamp {0}", dnsStampStr); IntPtr ppError = IntPtr.Zero; IntPtr pError = IntPtr.Zero; IntPtr pDnsStampResult = IntPtr.Zero; try { ppError = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); pDnsStampResult = AGDnsApi.ag_dns_stamp_from_str(dnsStampStr, ppError); if (pDnsStampResult == IntPtr.Zero) { pError = MarshalUtils.SafeReadIntPtr(ppError); string error = MarshalUtils.PtrToString(pError); Logger.Info("Parsing DNS stamp {0} failed with an error {1}", dnsStampStr, error); return(null); } AGDnsApi.ag_dns_stamp dnsStampResult = MarshalUtils.PtrToStructure <AGDnsApi.ag_dns_stamp>(pDnsStampResult); DnsStamp dnsStamp = DnsApiConverter.FromNativeObject(dnsStampResult); Logger.Info("Parsing DNS stamp has been completed successfully"); return(dnsStamp); } catch (Exception ex) { Logger.Info("Parsing DNS stamp failed with an error {0}", ex); return(null); } finally { AGDnsApi.ag_dns_stamp_free(pDnsStampResult); AGDnsApi.ag_str_free(pError); MarshalUtils.SafeFreeHGlobal(ppError); } }
/// <summary> /// Checks if upstream is valid and available /// </summary> /// <param name="upstreamOptions">Upstream options /// (<seealso cref="UpstreamOptions"/>)</param> /// <param name="ipv6Available">Whether IPv6 is available (i.e., bootstrapper is allowed to make AAAA queries)</param> /// <param name="offline">Don't perform online upstream check</param> public static bool TestUpstream(UpstreamOptions upstreamOptions, bool ipv6Available, bool offline) { IntPtr pUpstreamOptionsC = IntPtr.Zero; Queue <IntPtr> allocatedPointers = new Queue <IntPtr>(); IntPtr pError = IntPtr.Zero; try { Logger.Info("Start testing upstream {0}", upstreamOptions); CertificateVerificationCallback certificateVerificationCallback = new CertificateVerificationCallback(); AGDnsApi.ag_upstream_options upstreamOptionsC = DnsApiConverter.ToNativeObject(upstreamOptions, allocatedPointers); AGDnsApi.cbd_onCertificateVerification testUpstreamCallbackC = DnsApiConverter.ToNativeObject(certificateVerificationCallback); pUpstreamOptionsC = MarshalUtils.StructureToPtr(upstreamOptionsC); pError = AGDnsApi.ag_test_upstream(pUpstreamOptionsC, ipv6Available, testUpstreamCallbackC, offline); string error = MarshalUtils.PtrToString(pError); if (string.IsNullOrEmpty(error)) { Logger.Info("Testing upstream has been completed successfully"); return(true); } Logger.Info("Testing upstream failed with an error {0}", error); return(false); } catch (Exception ex) { Logger.Info("Testing upstream failed with an error {0}", ex); return(false); } finally { AGDnsApi.ag_str_free(pError); MarshalUtils.SafeFreeHGlobal(allocatedPointers); MarshalUtils.SafeFreeHGlobal(pUpstreamOptionsC); } }
/// <summary> /// Starts the proxy server /// </summary> /// <exception cref="InvalidOperationException">Thrown, if cannot starting the proxy server /// for any reason</exception> public void Start() { lock (m_SyncRoot) { Logger.Info("Starting the DnsProxyServer"); if (IsStarted) { Logger.Info("DnsProxyServer is already started, doing nothing"); return; } Queue <IntPtr> allocatedPointers = new Queue <IntPtr>(); IntPtr ppOutMessage = IntPtr.Zero; IntPtr pOutMessage = IntPtr.Zero; IntPtr pOutResult = IntPtr.Zero; try { AGDnsApi.ag_dnsproxy_settings dnsProxySettingsC = DnsApiConverter.ToNativeObject(m_DnsProxySettings, allocatedPointers); m_callbackConfigurationC = DnsApiConverter.ToNativeObject(m_CallbackConfiguration, this); IntPtr pDnsProxySettingsC = MarshalUtils.StructureToPtr(dnsProxySettingsC, allocatedPointers); m_pCallbackConfigurationC = MarshalUtils.StructureToPtr(m_callbackConfigurationC); pOutResult = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); ppOutMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); m_pProxyServer = AGDnsApi.ag_dnsproxy_init( pDnsProxySettingsC, m_pCallbackConfigurationC, pOutResult, ppOutMessage); AGDnsApi.ag_dnsproxy_init_result outResultEnum = AGDnsApi.ag_dnsproxy_init_result.AGDPIR_OK; if (m_pProxyServer == IntPtr.Zero) { int?outResult = MarshalUtils.PtrToNullableInt(pOutResult); if (outResult.HasValue) { outResultEnum = (AGDnsApi.ag_dnsproxy_init_result)outResult.Value; } pOutMessage = MarshalUtils.SafeReadIntPtr(ppOutMessage); string outMessage = MarshalUtils.PtrToString(pOutMessage); string errorMessage = $"Failed to start the DnsProxyServer with the result {outResultEnum} and message {outMessage}"; throw new InvalidOperationException(errorMessage); } m_IsStarted = true; Logger.Info("Finished starting the DnsProxyServer"); } catch (Exception ex) { Dispose(); throw new InvalidOperationException("error while starting the DnsProxyServer: ", ex); } finally { MarshalUtils.SafeFreeHGlobal(allocatedPointers); AGDnsApi.ag_str_free(pOutMessage); MarshalUtils.SafeFreeHGlobal(ppOutMessage); MarshalUtils.SafeFreeHGlobal(pOutResult); } } }