/earlyDev/EddnServer/DispatchDnsServer.cs
C# | 385 lines | 287 code | 82 blank | 16 comment | 55 complexity | 9d6b357c596591be1bba3b854962e743 MD5 | raw file
Possible License(s): AGPL-1.0
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net.Sockets;
- using System.Net;
- using System.Configuration;
- using Intreza.Net.Dns.Configuration;
- using System.Reflection;
-
- namespace Intreza.Net.Dns
- {
- public class DispatchDnsServer
- {
- private static string defaultTypeNamespace = "Intreza.Net.Dns";
- private static string defaultTypeAssembly = "EddnServer";
-
- private Dictionary<string, TypeDefinition> extensionTypes;
- private Dictionary<string, IDnsDispatch> dispatcherObjects;
- private Dictionary<string, IFilter> filterObjects;
-
- private Dictionary<string, Handler> handlers;
- private Handler defaultHandler;
-
- private List<UdpClient> listeners;
- public event DnsEventHandler Query;
-
- public DispatchDnsServer()
- {
- extensionTypes = new Dictionary<string, TypeDefinition>();
- dispatcherObjects = new Dictionary<string, IDnsDispatch>();
- filterObjects = new Dictionary<string, IFilter>();
- handlers = new Dictionary<string, Handler>();
- listeners = new List<UdpClient>();
-
- Query += new DnsEventHandler(DispatchDnsServer_Query);
- loadConfig();
- }
-
- void DispatchDnsServer_Query(object sender, DnsEventArgs e)
- {
- // Find a handler
- foreach (KeyValuePair<string, Handler> handler in handlers)
- {
- if (handler.Value.Filter == null || handler.Value.Filter.Evaluate(e))
- {
- Console.WriteLine("Using handler: {0}", handler.Key);
-
- e.Response = handler.Value.Process(e);
-
- return;
- }
- }
-
- // default handler
- e.Response = defaultHandler.Process(e);
- }
-
- private void loadConfig()
- {
- // Load config
- System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
- HandlerConfigurationSection handlerConfig = (HandlerConfigurationSection)config.GetSection("handlerConfig");
- BindingConfigurationSection bindingConfig = (BindingConfigurationSection)config.GetSection("bindingConfig");
-
- #region Bindings Config
- // Register bindings
-
- if (bindingConfig != null && bindingConfig.Bindings.Count == 0)
- {
- Console.WriteLine("No bindings specified");
-
- var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\services\\DNS\\Parameters");
-
- if (key != null)
- {
- // msft dns
- object addrs = key.GetValue("ListenAddresses");
-
- if (addrs == null)
- {
- addrs = new string[] { "0.0.0.0" };
- }
-
- Console.WriteLine("Microsoft DNS Binding Mode");
-
- foreach (var addr in addrs as string[])
- {
- Console.WriteLine("\tRead binding {0} from registry service config.", addr);
- Binding binding = new Binding();
- binding.IP = addr;
- binding.Port = 54;
- binding.Protocol = BindingProtocol.Udp;
-
- UdpClient listener = new UdpClient(new IPEndPoint(IPAddress.Parse(binding.IP), binding.Port));
-
- listeners.Add(listener);
-
- listener.BeginReceive(listenerData, new ListenerState { Binding = binding, Listener = listener });
- }
- }
-
- }
- else
- {
- // load config
- foreach (Binding binding in bindingConfig.Bindings)
- {
- Console.WriteLine("Binding: {0} {1} {2}", binding.Protocol, binding.IP, binding.Port);
-
- if (binding.Protocol == BindingProtocol.Udp)
- {
- UdpClient listener = new UdpClient(new IPEndPoint(IPAddress.Parse(binding.IP), binding.Port));
-
- listeners.Add(listener);
-
- listener.BeginReceive(listenerData, new ListenerState { Binding = binding, Listener = listener });
-
- }
- else
- {
- throw new NotImplementedException();
- }
- }
- }
- #endregion
-
- #region Extension Types
- // Register Extension types
- foreach (ExtensionType extensionType in handlerConfig.Types)
- {
- Type found = Type.GetType(extensionType.Type);
-
- if (found == null)
- {
- found = Type.GetType(defaultTypeNamespace + "." + extensionType.Type + ", " + defaultTypeAssembly);
- }
-
- if (found != null)
- {
- Type intType = Type.GetType(extensionType.Interface);
-
- if (intType == null)
- {
- intType = Type.GetType(defaultTypeNamespace + "." + extensionType.Interface + ", " + defaultTypeAssembly);
- }
-
- if (intType != null)
- {
- Dictionary<string, string> cfg = new Dictionary<string, string>();
-
- foreach (PropertyValue prop in extensionType.HandlerProperties)
- {
- cfg.Add(prop.Name, prop.Value);
- }
-
- extensionTypes.Add(extensionType.Name, new TypeDefinition(found, intType, cfg));
-
- ConstructorInfo ci = found.GetConstructor(Type.EmptyTypes);
-
- if (ci == null)
- {
- Console.WriteLine("Error finding constructor for type " + found.FullName);
- }
- else
- {
- // Create base objects
- if (intType == typeof(IDnsDispatch))
- {
- IDnsDispatch dispObj = (IDnsDispatch)ci.Invoke(null);
-
- if (dispObj != null)
- {
- dispObj.Initialize(cfg);
-
- dispatcherObjects.Add(extensionType.Name, dispObj);
- }
- else
- {
- throw new Exception("Constructor failed for " + found.ToString());
- }
- }
- else if (intType == typeof(IFilter))
- {
- IFilter filtObj = (IFilter)ci.Invoke(null);
-
- if (filtObj != null)
- {
- filtObj.Initialize(cfg);
-
- filterObjects.Add(extensionType.Name, filtObj);
- }
- }
- }
-
- Console.WriteLine("Type: {0} {1}", found, intType);
- }
- }
- else
- {
- Console.WriteLine("Failed to load type {0}", extensionType.Type);
- }
- }
-
- #endregion
-
- #region Handler Policies
-
- // Create instances of handlers
- string defaultPolicy = handlerConfig.HandlerPolicies.DefaultPolicy;
-
- Console.WriteLine("Default Handler: {0}", defaultPolicy);
-
- foreach (HandlerPolicy policy in handlerConfig.HandlerPolicies)
- {
- FilterInstance filter = null;
- if (policy.FilterPolicy != null)
- {
- filter = loadFilterPolicy(policy.FilterPolicy);
- }
-
- List<RequestDispatcher> dispatchers = new List<RequestDispatcher>();
-
- foreach (Dispatcher dispatcher in policy.DispatchPolicy)
- {
- string dispatcherType = dispatcher.Type;
-
- if (extensionTypes.ContainsKey(dispatcherType) && extensionTypes[dispatcherType].Interface == typeof(IDnsDispatch))
- {
- if (dispatcherObjects.ContainsKey(dispatcherType))
- {
- IDnsDispatch dispObj = dispatcherObjects[dispatcherType];
-
- Dictionary<string, string> dispProps = new Dictionary<string, string>();
-
- foreach (PropertyValue prop in dispatcher.DispatcherProperties)
- {
- dispProps.Add(prop.Name, prop.Value);
- }
-
- RequestDispatcher req = new RequestDispatcher(dispatcher.Reprocess, dispObj, dispProps);
- dispatchers.Add(req);
-
- }
- }
- }
-
- Handler handler = new Handler(policy.Name, filter, dispatchers.ToArray());
-
- if (defaultPolicy == policy.Name)
- {
- defaultHandler = handler;
- }
-
- handlers.Add(handler.Name, handler);
- }
-
- #endregion
- }
-
- private FilterInstance loadFilterPolicy(FilterPolicy filterPolicy)
- {
- if (filterPolicy.Operator != FilterOperators.none)
- {
- FilterInstance instance = null;
-
- if (filterPolicy.Operator == FilterOperators.ifilter)
- {
- if (filterObjects.ContainsKey(filterPolicy.Type))
- {
- IFilterInstance iInst = filterObjects[filterPolicy.Type].CreateInstance(filterPolicy.Field, filterPolicy.Value);
-
- instance = new FilterInstance(iInst);
- }
- else
- {
- Console.WriteLine("Could not find filter type: {0}", filterPolicy.Type);
- }
- }
- else
- {
- instance = new FilterInstance(filterPolicy.Operator, filterPolicy.Field, filterPolicy.Value);
- }
-
- if (instance == null)
- {
- return null;
- }
-
- foreach (FilterPolicy childPolicy in filterPolicy)
- {
- FilterInstance childInst = loadFilterPolicy(childPolicy);
-
- if (childInst != null)
- {
- instance.AddChild(childInst);
- }
- }
-
- return instance;
- }
-
- return null;
- }
-
- public static Message CreateResponse(Message request)
- {
- Message resp = new Message(request.ID);
- resp.QueryResponse = QueryResponse.Response;
- resp.ResponseCode = ResponseCode.NoError;
- resp.OperationCode = OperationCode.Query;
-
- foreach (Question q in request.Questions)
- {
- resp.Questions.Add(q);
- }
-
- return resp;
- }
-
- private void onQuery(DnsEventArgs e)
- {
- if (Query != null)
- {
- Query.Invoke(this, e);
-
- if (e.Response != null)
- {
- Console.WriteLine("Reply: {0}", e.Response.AnswerCount);
-
- byte[] tmp = e.Response.GetBytes();
- e.Client.Send(tmp, tmp.Length, e.RemoteEndPoint);
- }
- }
- }
-
- private void listenerData(IAsyncResult ar)
- {
- ListenerState state = (ListenerState)ar.AsyncState;
-
- UdpClient listener = state.Listener;
-
- IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
-
- int offset;
- Message msg = null;
-
- try
- {
- byte[] data = listener.EndReceive(ar, ref remote);
- listener.BeginReceive(listenerData, state);
-
- offset = 0;
-
- msg = new Message(data, ref offset);
-
- }
- catch (Exception ex)
- {
- Console.WriteLine("Exception: {0}", ex.Message);
-
- listener.BeginReceive(listenerData, state);
- /*
- IPEndPoint local = (IPEndPoint)state.Listener.Client.LocalEndPoint;
-
- listener = new UdpClient(local);
- state.Listener = listener;
-
- listener.BeginReceive(listenerData, state);*/
- }
-
- if (msg != null)
- {
- onQuery(new DnsEventArgs(remote, (IPEndPoint)listener.Client.LocalEndPoint, listener, msg));
-
- Console.WriteLine("end rec");
- }
- else
- {
- Console.WriteLine("end rec 2");
- }
-
- }
- }
- }