PageRenderTime 52ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/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
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net.Sockets;
  6. using System.Net;
  7. using System.Configuration;
  8. using Intreza.Net.Dns.Configuration;
  9. using System.Reflection;
  10. namespace Intreza.Net.Dns
  11. {
  12. public class DispatchDnsServer
  13. {
  14. private static string defaultTypeNamespace = "Intreza.Net.Dns";
  15. private static string defaultTypeAssembly = "EddnServer";
  16. private Dictionary<string, TypeDefinition> extensionTypes;
  17. private Dictionary<string, IDnsDispatch> dispatcherObjects;
  18. private Dictionary<string, IFilter> filterObjects;
  19. private Dictionary<string, Handler> handlers;
  20. private Handler defaultHandler;
  21. private List<UdpClient> listeners;
  22. public event DnsEventHandler Query;
  23. public DispatchDnsServer()
  24. {
  25. extensionTypes = new Dictionary<string, TypeDefinition>();
  26. dispatcherObjects = new Dictionary<string, IDnsDispatch>();
  27. filterObjects = new Dictionary<string, IFilter>();
  28. handlers = new Dictionary<string, Handler>();
  29. listeners = new List<UdpClient>();
  30. Query += new DnsEventHandler(DispatchDnsServer_Query);
  31. loadConfig();
  32. }
  33. void DispatchDnsServer_Query(object sender, DnsEventArgs e)
  34. {
  35. // Find a handler
  36. foreach (KeyValuePair<string, Handler> handler in handlers)
  37. {
  38. if (handler.Value.Filter == null || handler.Value.Filter.Evaluate(e))
  39. {
  40. Console.WriteLine("Using handler: {0}", handler.Key);
  41. e.Response = handler.Value.Process(e);
  42. return;
  43. }
  44. }
  45. // default handler
  46. e.Response = defaultHandler.Process(e);
  47. }
  48. private void loadConfig()
  49. {
  50. // Load config
  51. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  52. HandlerConfigurationSection handlerConfig = (HandlerConfigurationSection)config.GetSection("handlerConfig");
  53. BindingConfigurationSection bindingConfig = (BindingConfigurationSection)config.GetSection("bindingConfig");
  54. #region Bindings Config
  55. // Register bindings
  56. if (bindingConfig != null && bindingConfig.Bindings.Count == 0)
  57. {
  58. Console.WriteLine("No bindings specified");
  59. var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\services\\DNS\\Parameters");
  60. if (key != null)
  61. {
  62. // msft dns
  63. object addrs = key.GetValue("ListenAddresses");
  64. if (addrs == null)
  65. {
  66. addrs = new string[] { "0.0.0.0" };
  67. }
  68. Console.WriteLine("Microsoft DNS Binding Mode");
  69. foreach (var addr in addrs as string[])
  70. {
  71. Console.WriteLine("\tRead binding {0} from registry service config.", addr);
  72. Binding binding = new Binding();
  73. binding.IP = addr;
  74. binding.Port = 54;
  75. binding.Protocol = BindingProtocol.Udp;
  76. UdpClient listener = new UdpClient(new IPEndPoint(IPAddress.Parse(binding.IP), binding.Port));
  77. listeners.Add(listener);
  78. listener.BeginReceive(listenerData, new ListenerState { Binding = binding, Listener = listener });
  79. }
  80. }
  81. }
  82. else
  83. {
  84. // load config
  85. foreach (Binding binding in bindingConfig.Bindings)
  86. {
  87. Console.WriteLine("Binding: {0} {1} {2}", binding.Protocol, binding.IP, binding.Port);
  88. if (binding.Protocol == BindingProtocol.Udp)
  89. {
  90. UdpClient listener = new UdpClient(new IPEndPoint(IPAddress.Parse(binding.IP), binding.Port));
  91. listeners.Add(listener);
  92. listener.BeginReceive(listenerData, new ListenerState { Binding = binding, Listener = listener });
  93. }
  94. else
  95. {
  96. throw new NotImplementedException();
  97. }
  98. }
  99. }
  100. #endregion
  101. #region Extension Types
  102. // Register Extension types
  103. foreach (ExtensionType extensionType in handlerConfig.Types)
  104. {
  105. Type found = Type.GetType(extensionType.Type);
  106. if (found == null)
  107. {
  108. found = Type.GetType(defaultTypeNamespace + "." + extensionType.Type + ", " + defaultTypeAssembly);
  109. }
  110. if (found != null)
  111. {
  112. Type intType = Type.GetType(extensionType.Interface);
  113. if (intType == null)
  114. {
  115. intType = Type.GetType(defaultTypeNamespace + "." + extensionType.Interface + ", " + defaultTypeAssembly);
  116. }
  117. if (intType != null)
  118. {
  119. Dictionary<string, string> cfg = new Dictionary<string, string>();
  120. foreach (PropertyValue prop in extensionType.HandlerProperties)
  121. {
  122. cfg.Add(prop.Name, prop.Value);
  123. }
  124. extensionTypes.Add(extensionType.Name, new TypeDefinition(found, intType, cfg));
  125. ConstructorInfo ci = found.GetConstructor(Type.EmptyTypes);
  126. if (ci == null)
  127. {
  128. Console.WriteLine("Error finding constructor for type " + found.FullName);
  129. }
  130. else
  131. {
  132. // Create base objects
  133. if (intType == typeof(IDnsDispatch))
  134. {
  135. IDnsDispatch dispObj = (IDnsDispatch)ci.Invoke(null);
  136. if (dispObj != null)
  137. {
  138. dispObj.Initialize(cfg);
  139. dispatcherObjects.Add(extensionType.Name, dispObj);
  140. }
  141. else
  142. {
  143. throw new Exception("Constructor failed for " + found.ToString());
  144. }
  145. }
  146. else if (intType == typeof(IFilter))
  147. {
  148. IFilter filtObj = (IFilter)ci.Invoke(null);
  149. if (filtObj != null)
  150. {
  151. filtObj.Initialize(cfg);
  152. filterObjects.Add(extensionType.Name, filtObj);
  153. }
  154. }
  155. }
  156. Console.WriteLine("Type: {0} {1}", found, intType);
  157. }
  158. }
  159. else
  160. {
  161. Console.WriteLine("Failed to load type {0}", extensionType.Type);
  162. }
  163. }
  164. #endregion
  165. #region Handler Policies
  166. // Create instances of handlers
  167. string defaultPolicy = handlerConfig.HandlerPolicies.DefaultPolicy;
  168. Console.WriteLine("Default Handler: {0}", defaultPolicy);
  169. foreach (HandlerPolicy policy in handlerConfig.HandlerPolicies)
  170. {
  171. FilterInstance filter = null;
  172. if (policy.FilterPolicy != null)
  173. {
  174. filter = loadFilterPolicy(policy.FilterPolicy);
  175. }
  176. List<RequestDispatcher> dispatchers = new List<RequestDispatcher>();
  177. foreach (Dispatcher dispatcher in policy.DispatchPolicy)
  178. {
  179. string dispatcherType = dispatcher.Type;
  180. if (extensionTypes.ContainsKey(dispatcherType) && extensionTypes[dispatcherType].Interface == typeof(IDnsDispatch))
  181. {
  182. if (dispatcherObjects.ContainsKey(dispatcherType))
  183. {
  184. IDnsDispatch dispObj = dispatcherObjects[dispatcherType];
  185. Dictionary<string, string> dispProps = new Dictionary<string, string>();
  186. foreach (PropertyValue prop in dispatcher.DispatcherProperties)
  187. {
  188. dispProps.Add(prop.Name, prop.Value);
  189. }
  190. RequestDispatcher req = new RequestDispatcher(dispatcher.Reprocess, dispObj, dispProps);
  191. dispatchers.Add(req);
  192. }
  193. }
  194. }
  195. Handler handler = new Handler(policy.Name, filter, dispatchers.ToArray());
  196. if (defaultPolicy == policy.Name)
  197. {
  198. defaultHandler = handler;
  199. }
  200. handlers.Add(handler.Name, handler);
  201. }
  202. #endregion
  203. }
  204. private FilterInstance loadFilterPolicy(FilterPolicy filterPolicy)
  205. {
  206. if (filterPolicy.Operator != FilterOperators.none)
  207. {
  208. FilterInstance instance = null;
  209. if (filterPolicy.Operator == FilterOperators.ifilter)
  210. {
  211. if (filterObjects.ContainsKey(filterPolicy.Type))
  212. {
  213. IFilterInstance iInst = filterObjects[filterPolicy.Type].CreateInstance(filterPolicy.Field, filterPolicy.Value);
  214. instance = new FilterInstance(iInst);
  215. }
  216. else
  217. {
  218. Console.WriteLine("Could not find filter type: {0}", filterPolicy.Type);
  219. }
  220. }
  221. else
  222. {
  223. instance = new FilterInstance(filterPolicy.Operator, filterPolicy.Field, filterPolicy.Value);
  224. }
  225. if (instance == null)
  226. {
  227. return null;
  228. }
  229. foreach (FilterPolicy childPolicy in filterPolicy)
  230. {
  231. FilterInstance childInst = loadFilterPolicy(childPolicy);
  232. if (childInst != null)
  233. {
  234. instance.AddChild(childInst);
  235. }
  236. }
  237. return instance;
  238. }
  239. return null;
  240. }
  241. public static Message CreateResponse(Message request)
  242. {
  243. Message resp = new Message(request.ID);
  244. resp.QueryResponse = QueryResponse.Response;
  245. resp.ResponseCode = ResponseCode.NoError;
  246. resp.OperationCode = OperationCode.Query;
  247. foreach (Question q in request.Questions)
  248. {
  249. resp.Questions.Add(q);
  250. }
  251. return resp;
  252. }
  253. private void onQuery(DnsEventArgs e)
  254. {
  255. if (Query != null)
  256. {
  257. Query.Invoke(this, e);
  258. if (e.Response != null)
  259. {
  260. Console.WriteLine("Reply: {0}", e.Response.AnswerCount);
  261. byte[] tmp = e.Response.GetBytes();
  262. e.Client.Send(tmp, tmp.Length, e.RemoteEndPoint);
  263. }
  264. }
  265. }
  266. private void listenerData(IAsyncResult ar)
  267. {
  268. ListenerState state = (ListenerState)ar.AsyncState;
  269. UdpClient listener = state.Listener;
  270. IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
  271. int offset;
  272. Message msg = null;
  273. try
  274. {
  275. byte[] data = listener.EndReceive(ar, ref remote);
  276. listener.BeginReceive(listenerData, state);
  277. offset = 0;
  278. msg = new Message(data, ref offset);
  279. }
  280. catch (Exception ex)
  281. {
  282. Console.WriteLine("Exception: {0}", ex.Message);
  283. listener.BeginReceive(listenerData, state);
  284. /*
  285. IPEndPoint local = (IPEndPoint)state.Listener.Client.LocalEndPoint;
  286. listener = new UdpClient(local);
  287. state.Listener = listener;
  288. listener.BeginReceive(listenerData, state);*/
  289. }
  290. if (msg != null)
  291. {
  292. onQuery(new DnsEventArgs(remote, (IPEndPoint)listener.Client.LocalEndPoint, listener, msg));
  293. Console.WriteLine("end rec");
  294. }
  295. else
  296. {
  297. Console.WriteLine("end rec 2");
  298. }
  299. }
  300. }
  301. }