PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/sipsorcery-core/SIPSorcery.SIP.App/SIPAssets/SIPDomain.cs

#
C# | 266 lines | 191 code | 33 blank | 42 comment | 21 complexity | b7de4dc8cd35d3996cf53b9403ba2e4c MD5 | raw file
  1. // ============================================================================
  2. // FileName: SIPDomain.cs
  3. //
  4. // Description:
  5. // Maintains a list of domains and domain aliases that can be used by various
  6. // SIP Server agents. For example allows a SIP Registrar or Proxy to check the
  7. // domain on an incoming request to see if it is serviced at this location.
  8. //
  9. // Author(s):
  10. // Aaron Clauson
  11. //
  12. // History:
  13. // 27 Jul 2008 Aaron Clauson Created.
  14. //
  15. // License:
  16. // This software is licensed under the BSD License http://www.opensource.org/licenses/bsd-license.php
  17. //
  18. // Copyright (c) 2006-2008 Aaron Clauson (aaronc@blueface.ie), Blue Face Ltd, Dublin, Ireland (www.blueface.ie)
  19. // All rights reserved.
  20. //
  21. // Redistribution and use in source and binary forms, with or without modification, are permitted provided that
  22. // the following conditions are met:
  23. //
  24. // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  25. // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
  26. // disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Blue Face Ltd.
  27. // nor the names of its contributors may be used to endorse or promote products derived from this software without specific
  28. // prior written permission.
  29. //
  30. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
  31. // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  32. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  33. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  34. // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  35. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. // POSSIBILITY OF SUCH DAMAGE.
  37. // ============================================================================
  38. using System;
  39. using System.Collections;
  40. using System.Collections.Generic;
  41. using System.IO;
  42. using System.Linq;
  43. using System.Net;
  44. using System.Net.Sockets;
  45. using System.Runtime.Serialization;
  46. using System.ServiceModel;
  47. using System.Text.RegularExpressions;
  48. using System.Threading;
  49. using System.Xml;
  50. using System.Xml.Serialization;
  51. using SIPSorcery.Persistence;
  52. using SIPSorcery.Sys;
  53. using log4net;
  54. #if !SILVERLIGHT
  55. using System.Data;
  56. using System.Data.Linq;
  57. using System.Data.Linq.Mapping;
  58. using System.Xml.Linq;
  59. #endif
  60. #if UNITTEST
  61. using NUnit.Framework;
  62. #endif
  63. namespace SIPSorcery.SIP.App
  64. {
  65. /// <remarks>
  66. /// The mechanism to load the SIP domain records differs for XML and SQL data stores. Because the domain and domain alias
  67. /// are hierarchical the XML stores the records in a nested node structure. With SQL the nested structure is not possible
  68. /// and instead a flat table is used where the domain alias are stored as a delimited list in a single column field.
  69. /// </remarks>
  70. [DataContractAttribute]
  71. [Table(Name = "sipdomains")]
  72. public class SIPDomain : ISIPAsset
  73. {
  74. private const char ALIAS_SEPERATOR_CHAR = ';';
  75. public const string XML_DOCUMENT_ELEMENT_NAME = "sipdomains";
  76. public const string XML_ELEMENT_NAME = "sipdomain";
  77. private static ILog logger = AppState.logger;
  78. private static string m_newLine = AppState.NewLine;
  79. [DataMember]
  80. [Column(Name = "id", DbType = "varchar(36)", IsPrimaryKey = true, CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  81. public Guid Id { get; set; }
  82. [DataMember]
  83. [Column(Name = "domain", DbType = "varchar(128)", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  84. public string Domain { get; set; }
  85. [DataMember]
  86. [Column(Name = "owner", DbType = "varchar(32)", CanBeNull = true, UpdateCheck = UpdateCheck.Never)]
  87. public string Owner { get; set; }
  88. private DateTimeOffset? m_inserted;
  89. [Column(Name = "inserted", DbType = "datetimeoffset", CanBeNull = false, UpdateCheck = UpdateCheck.Never)]
  90. public DateTimeOffset? Inserted
  91. {
  92. get { return m_inserted; }
  93. set
  94. {
  95. if (value != null)
  96. {
  97. m_inserted = value.Value.ToUniversalTime();
  98. }
  99. else
  100. {
  101. m_inserted = null;
  102. }
  103. }
  104. }
  105. [Column(Name = "aliaslist", DbType = "varchar(1024)", CanBeNull = true)]
  106. public string AliasList
  107. {
  108. get
  109. {
  110. if (Aliases != null && Aliases.Count > 0)
  111. {
  112. string aliasList = null;
  113. Aliases.ForEach(a => aliasList += a + ALIAS_SEPERATOR_CHAR);
  114. return aliasList;
  115. }
  116. else
  117. {
  118. return null;
  119. }
  120. }
  121. set
  122. {
  123. Aliases = ParseAliases(value);
  124. }
  125. }
  126. public List<string> Aliases = new List<string>();
  127. public SIPDomain()
  128. { }
  129. public SIPDomain(string domain, string owner, List<string> aliases)
  130. {
  131. Id = Guid.NewGuid();
  132. Domain = domain;
  133. Owner = owner;
  134. Aliases = aliases;
  135. Inserted = DateTime.UtcNow;
  136. }
  137. #if !SILVERLIGHT
  138. public SIPDomain(DataRow row)
  139. {
  140. Load(row);
  141. }
  142. public DataTable GetTable()
  143. {
  144. DataTable table = new DataTable();
  145. table.Columns.Add(new DataColumn("id", typeof(String)));
  146. table.Columns.Add(new DataColumn("domain", typeof(String)));
  147. table.Columns.Add(new DataColumn("owner", typeof(String)));
  148. table.Columns.Add(new DataColumn("inserted", typeof(DateTimeOffset)));
  149. table.Columns.Add(new DataColumn("aliaslist", typeof(String)));
  150. return table;
  151. }
  152. public void Load(DataRow row)
  153. {
  154. Id = (row.Table.Columns.Contains("id") && row["id"] != DBNull.Value) ? new Guid(row["id"] as string) : Guid.NewGuid();
  155. Domain = row["domain"] as string;
  156. Owner = (row.Table.Columns.Contains("owner") && row["owner"] != DBNull.Value) ? row["owner"] as string : null;
  157. if (row.Table.Columns.Contains("inserted") & row["inserted"] != DBNull.Value && !(row["inserted"] as string).IsNullOrBlank())
  158. {
  159. Inserted = DateTimeOffset.Parse(row["inserted"] as string);
  160. }
  161. string aliasList = (row.Table.Columns.Contains("aliaslist") & row["aliaslist"] != DBNull.Value) ? row["aliaslist"] as string : null;
  162. Aliases = ParseAliases(aliasList);
  163. }
  164. public Dictionary<Guid, object> Load(XmlDocument dom)
  165. {
  166. try
  167. {
  168. Dictionary<Guid, object> sipDomains = new Dictionary<Guid, object>();
  169. XDocument sipDomainsDoc = XDocument.Parse(dom.OuterXml);
  170. var xmlSIPDomains = from domain in sipDomainsDoc.Document.Descendants(XML_ELEMENT_NAME)
  171. select new SIPDomain()
  172. {
  173. Id = Guid.NewGuid(),
  174. Domain = domain.Element("domain").Value,
  175. Owner = (domain.Element("owner") != null && !domain.Element("owner").Value.IsNullOrBlank()) ? domain.Element("owner").Value : null,
  176. Aliases =
  177. (from alias in domain.Element("sipdomainaliases").Descendants("domainalias")
  178. select alias.Value).ToList()
  179. };
  180. foreach (SIPDomain xmlSIPDomain in xmlSIPDomains)
  181. {
  182. sipDomains.Add(xmlSIPDomain.Id, xmlSIPDomain);
  183. }
  184. return sipDomains;
  185. }
  186. catch (Exception excp)
  187. {
  188. logger.Error("Exception SIPDomain Load. " + excp.Message);
  189. throw;
  190. }
  191. }
  192. #endif
  193. public string ToXML()
  194. {
  195. string sipDomainXML =
  196. " <" + XML_ELEMENT_NAME + ">" + m_newLine +
  197. ToXMLNoParent() + m_newLine +
  198. " </" + XML_ELEMENT_NAME + ">" + m_newLine;
  199. return sipDomainXML;
  200. }
  201. public string ToXMLNoParent()
  202. {
  203. throw new NotImplementedException();
  204. }
  205. public string GetXMLElementName()
  206. {
  207. return XML_ELEMENT_NAME;
  208. }
  209. public string GetXMLDocumentElementName()
  210. {
  211. return XML_DOCUMENT_ELEMENT_NAME;
  212. }
  213. private List<string> ParseAliases(string aliasString)
  214. {
  215. List<string> aliasList = new List<string>();
  216. if (!aliasString.IsNullOrBlank())
  217. {
  218. string[] aliases = aliasString.Split(ALIAS_SEPERATOR_CHAR);
  219. if (aliases != null && aliases.Length > 0)
  220. {
  221. foreach (string alias in aliases)
  222. {
  223. if (!alias.IsNullOrBlank() && !aliasList.Contains(alias.ToLower()))
  224. {
  225. aliasList.Add(alias.ToLower());
  226. }
  227. }
  228. }
  229. }
  230. return aliasList;
  231. }
  232. }
  233. }