/// <summary> /// Applies a set of NAPTR rules obtained from an ENUM lookup to attempt to get a SIP URI. /// This functionality should be moved closer to the DNS classes once it becomes more mature and universal. /// See RFC 2915. /// </summary> /// <param name="naptrRecords"></param> /// <returns></returns> private string ApplyENUMRules(string number, RecordNAPTR[] naptrRecords) { try { RecordNAPTR priorityRecord = null; foreach (RecordNAPTR naptrRecord in naptrRecords) { if (naptrRecord.Service != null && naptrRecord.Service.ToUpper() == RecordNAPTR.SIP_SERVICE_KEY) { if (priorityRecord == null) { priorityRecord = naptrRecord; } else if (naptrRecord.Order < priorityRecord.Order) { priorityRecord = naptrRecord; } else if (naptrRecord.Order == priorityRecord.Order && naptrRecord.Preference < priorityRecord.Preference) { priorityRecord = naptrRecord; } } } if (priorityRecord != null && priorityRecord.Rule != null && Regex.Match(priorityRecord.Rule, "!.+!.+!").Success) { //logger.Debug("rule=" + priorityRecord.Rule + "."); Match match = Regex.Match(priorityRecord.Rule, "!(?<pattern>.+?)!(?<substitute>.+?)!(?<options>.*)"); if (match.Success) { string pattern = match.Result("${pattern}"); //logger.Debug("pattern=" + pattern + "."); string substitute = Regex.Replace(match.Result("${substitute}"), @"\\(?<digit>\d)", @"${${digit}}"); string options = match.Result("${options}"); logger.Debug("ENUM rule: s/" + pattern + "/" + substitute + "/" + options); string domainlessNumber = number.Substring(0, number.IndexOf('.')); Regex enumRegex = new Regex(pattern); if (enumRegex.Match(domainlessNumber).Success) { //{ // Log("enum substitute /" + number + "/" + pattern + "/" + substitute + "/"); // return Regex.Replace(number, pattern, substitute); //} //else //{ // Remove the domain from number and match. Log("enum substitute /" + domainlessNumber + "/" + pattern + "/" + substitute + "/"); return Regex.Replace(domainlessNumber, pattern, substitute); } else if (enumRegex.Match("+" + domainlessNumber).Success) { // Remove the domain from number and match. Log("enum substitute /+" + domainlessNumber + "/" + pattern + "/" + substitute + "/"); return Regex.Replace("+" + domainlessNumber, pattern, substitute); } } else { logger.Warn("Priority rule for an ENUM lookup was not recognised: " + priorityRecord.Rule + "."); } } return null; } catch (Exception excp) { logger.Error("Exception ApplyENUMRules. " + excp.Message); return null; } }
public void AddNAPTRResult(RecordNAPTR naptrRecord) { //logger.Debug("Checking NAPTR record for " + URI.ToString() + " " + naptrRecord.ToString() + "."); SIPServicesEnum sipServicesEnum = SIPServicesEnum.none; if (naptrRecord.Service == SIPDNSManager.NAPTR_SIP_UDP_SERVICE) { sipServicesEnum = SIPServicesEnum.sipudp; } else if (naptrRecord.Service == SIPDNSManager.NAPTR_SIP_TCP_SERVICE) { sipServicesEnum = SIPServicesEnum.siptcp; } else if (naptrRecord.Service == SIPDNSManager.NAPTR_SIPS_TCP_SERVICE) { sipServicesEnum = SIPServicesEnum.sipstcp; } if(sipServicesEnum != SIPServicesEnum.none) { //logger.Debug(" adding NAPTR lookup result for " + URI.ToString() + " of " + naptrRecord.ToString() + "."); SIPDNSServiceResult sipNAPTRResult = new SIPDNSServiceResult(sipServicesEnum, naptrRecord.Order, naptrRecord.RR.TTL, naptrRecord.Replacement, 0, DateTime.Now); if (SIPNAPTRResults == null) { SIPNAPTRResults = new Dictionary<SIPServicesEnum, SIPDNSServiceResult>() { { sipServicesEnum, sipNAPTRResult } }; } else { SIPNAPTRResults.Add(sipServicesEnum, sipNAPTRResult); } } }