コード例 #1
0
        public EtcdClient(string connectionString, int port         = 2379,
                          HttpClientHandler handler                 = null, bool ssl = false,
                          bool useLegacyRpcExceptionForCancellation = false)
        {
            if (string.IsNullOrWhiteSpace(connectionString))
            {
                throw new Exception("etcd connection string is empty.");
            }

            string[] hosts;

            if (connectionString.ToLowerInvariant().StartsWith("discovery-srv://"))
            {
                // Expecting it to be discovery-srv://{domain}/{name}
                // Examples:
                // discovery-srv://my-domain.local/ would expect entries for either _etcd-client-ssl._tcp.my-domain.local or _etcd-client._tcp.my-domain.local
                // discovery-srv://my-domain.local/project1 would expect entries for either _etcd-client-ssl-project1._tcp.my-domain.local or _etcd-client-project1._tcp.my-domain.local
                Uri          discoverySrv = new Uri(connectionString);
                LookupClient client       = new LookupClient(new LookupClientOptions
                {
                    UseCache = true
                });

                // SSL first ...
                string serviceName = "/".Equals(discoverySrv.AbsolutePath)
                    ? ""
                    : $"-{discoverySrv.AbsolutePath.Substring(startIndex: 1, length: discoverySrv.AbsolutePath.Length - 1)}";
                IDnsQueryResponse result = client.Query($"_etcd-client-ssl{serviceName}._tcp.{discoverySrv.Host}", QueryType.SRV);
                string            scheme = "https";
                if (result.HasError)
                {
                    scheme = "http";
                    // No SSL ...
                    result = client.Query($"_etcd-client{serviceName}._tcp.{discoverySrv.Host}", QueryType.SRV);
                    if (result.HasError)
                    {
                        throw new InvalidOperationException(result.ErrorMessage);
                    }
                }

                List <SrvRecord> results = result.Answers.OfType <SrvRecord>().OrderBy(a => a.Priority)
                                           .ThenByDescending(a => a.Weight).ToList();
                hosts = new string[results.Count];
                for (int index = 0; index < results.Count; index++)
                {
                    SrvRecord         srvRecord        = results[index];
                    DnsResourceRecord additionalRecord =
                        result.Additionals.FirstOrDefault(p => p.DomainName.Equals(srvRecord.Target));
                    string host = srvRecord.Target.Value;

                    if (additionalRecord is ARecord aRecord)
                    {
                        host = aRecord.Address.ToString();
                    }
                    else if (additionalRecord is CNameRecord cname)
                    {
                        host = cname.CanonicalName;
                    }

                    if (host.EndsWith("."))
                    {
                        host = host.Substring(startIndex: 0, host.Length - 1);
                    }

                    hosts[index] = $"{scheme}://{host}:{srvRecord.Port}";
                }
            }
            else
            {
                hosts = connectionString.Split(',');
            }

            List <Uri> nodes = new List <Uri>();

            for (int i = 0; i < hosts.Length; i++)
            {
                string host = hosts[i];
                if (host.Split(':').Length < 3)
                {
                    host += $":{Convert.ToString(port)}";
                }

                if (!(host.StartsWith(InsecurePrefix) || host.StartsWith(SecurePrefix)))
                {
                    if (ssl)
                    {
                        host = $"{SecurePrefix}{host}";
                    }
                    else
                    {
                        host = $"{InsecurePrefix}{host}";
                    }
                }

                nodes.Add(new Uri(host));
            }

            _balancer = new Balancer(nodes, handler, ssl, useLegacyRpcExceptionForCancellation);
        }
コード例 #2
0
        public override int Compare(DnsRecord x, DnsRecord y)
        {
            if (x == y)
            {
                return(0);
            }
            if (x == null)
            {
                return(-1);
            }
            if (y == null)
            {
                return(1);
            }

            int res = 0;

            if ((res = x.Type.ToString().CompareTo(y.Type.ToString())) == 0 &&
                (res = x.Owner.CompareTo(y.Owner)) == 0)
            {
                switch (x.Type)
                {
                case DnsRecordType.NS:
                    res = ((NSRecord)x).Domain.CompareTo(((NSRecord)y).Domain);
                    break;

                case DnsRecordType.CName:
                    res = ((CNameRecord)x).Canonical.CompareTo(((CNameRecord)y).Canonical);
                    break;

                case DnsRecordType.DN:
                    res = ((DNRecord)x).Target.CompareTo(((DNRecord)y).Target);
                    break;

                case DnsRecordType.Ptr:
                    res = ((PtrRecord)x).Domain.CompareTo(((PtrRecord)y).Domain);
                    break;

                case DnsRecordType.HInfo:
                    HInfoRecord xHInfo = (HInfoRecord)x;
                    HInfoRecord yHInfo = (HInfoRecord)y;

                    if ((res = xHInfo.Cpu.CompareTo(yHInfo.Cpu)) == 0)
                    {
                        res = xHInfo.Os.CompareTo(yHInfo.Os);
                    }
                    break;

                case DnsRecordType.MInfo:
                    MInfoRecord xMInfo = (MInfoRecord)x;
                    MInfoRecord yMInfo = (MInfoRecord)y;

                    if ((res = xMInfo.RMbox.CompareTo(yMInfo.RMbox)) == 0)
                    {
                        res = xMInfo.EMbox.CompareTo(yMInfo.EMbox);
                    }
                    break;

                case DnsRecordType.MX:
                    MXRecord xMx = (MXRecord)x;
                    MXRecord yMx = (MXRecord)y;

                    if ((res = xMx.CompareTo(yMx)) == 0)
                    {
                        res = xMx.Exchange.CompareTo(yMx.Exchange);
                    }
                    break;

                case DnsRecordType.MB:
                    res = ((MBRecord)x).Mailbox.CompareTo(((MBRecord)y).Mailbox);
                    break;

                case DnsRecordType.MG:
                    res = ((MGRecord)x).Mailbox.CompareTo(((MGRecord)y).Mailbox);
                    break;

                case DnsRecordType.MR:
                    res = ((MRRecord)x).NewMailbox.CompareTo(((MRRecord)y).NewMailbox);
                    break;

                case DnsRecordType.Txt:
                    res = ((TxtRecord)x).Text.CompareTo(((TxtRecord)y).Text);
                    break;

                case DnsRecordType.Spf:
                    res = ((SpfRecord)x).Specification.CompareTo(((SpfRecord)y).Specification);
                    break;

                case DnsRecordType.Srv:
                    SrvRecord xSrv = (SrvRecord)x;
                    SrvRecord ySrv = (SrvRecord)y;

                    if ((res = xSrv.CompareTo(ySrv)) == 0)
                    {
                        res = xSrv.Target.CompareTo(ySrv.Target);
                    }
                    break;

                default:
                    res = 0;
                    break;
                }
            }

            return(res);
        }
コード例 #3
0
        public ServiceData getServiceData(ServiceName service)
        {
            DomainName serviceName = service.toDnsName();

            DnsMessage dnsMessage = DNSClientUtil.GetDefaultClient().Resolve(serviceName, RecordType.Srv);

            if ((dnsMessage == null) || dnsMessage.AnswerRecords.Count == 0 || ((dnsMessage.ReturnCode != ReturnCode.NoError) && (dnsMessage.ReturnCode != ReturnCode.NxDomain)))
            {
                return(null);
            }

            ServiceData data = new ServiceData();

            data.setName(service);
            foreach (DnsRecordBase record in dnsMessage.AnswerRecords)
            {
                // TODO Handle priority and weight correctly in case of multiple SRV record.
                SrvRecord srv = record as SrvRecord;
                data.setHost(srv.Target.ToString());
                data.setPort(srv.Port);
                break;
            }

            dnsMessage = DNSClientUtil.GetDefaultClient().Resolve(serviceName, RecordType.Txt);


            if ((dnsMessage == null) || dnsMessage.AnswerRecords.Count == 0 || ((dnsMessage.ReturnCode != ReturnCode.NoError) && (dnsMessage.ReturnCode != ReturnCode.NxDomain)))
            {
                return(data);
            }
            foreach (DnsRecordBase record in dnsMessage.AnswerRecords)
            {
                // TODO Handle multiple TXT records as different variants of same service
                TxtRecord txt = record as TxtRecord;
                foreach (String str in txt.TextParts)
                {
                    // Safe cast
                    int    i = str.IndexOf('=');
                    String key;
                    String value;
                    if (i == 0 || str.Equals(""))
                    {
                        continue;                           // Invalid empty key, should be ignored
                    }
                    else if (i > 0)
                    {
                        key   = str.Substring(0, i).ToLower();
                        value = str.Substring(i + 1);
                    }
                    else
                    {
                        key   = str;
                        value = null;
                    }

                    if (!data.getProperties().ContainsKey(key))                         // Ignore all but the first
                    {
                        data.getProperties()[key] = value;
                    }
                }
                break;
            }
            return(data);
        }
コード例 #4
0
        internal static SrvRecordSetData DeserializeSrvRecordSetData(JsonElement element)
        {
            Optional <string>  etag       = default;
            ResourceIdentifier id         = default;
            string             name       = default;
            ResourceType       type       = default;
            SystemData         systemData = default;
            Optional <IDictionary <string, string> > metadata = default;
            Optional <long>   ttl  = default;
            Optional <string> fqdn = default;
            Optional <string> provisioningState           = default;
            Optional <WritableSubResource> targetResource = default;
            Optional <IList <SrvRecord> >  srvRecords     = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("etag"))
                {
                    etag = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("systemData"))
                {
                    systemData = JsonSerializer.Deserialize <SystemData>(property.Value.ToString());
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("metadata"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            Dictionary <string, string> dictionary = new Dictionary <string, string>();
                            foreach (var property1 in property0.Value.EnumerateObject())
                            {
                                dictionary.Add(property1.Name, property1.Value.GetString());
                            }
                            metadata = dictionary;
                            continue;
                        }
                        if (property0.NameEquals("TTL"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            ttl = property0.Value.GetInt64();
                            continue;
                        }
                        if (property0.NameEquals("fqdn"))
                        {
                            fqdn = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("provisioningState"))
                        {
                            provisioningState = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("targetResource"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            targetResource = JsonSerializer.Deserialize <WritableSubResource>(property0.Value.ToString());
                            continue;
                        }
                        if (property0.NameEquals("SRVRecords"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            List <SrvRecord> array = new List <SrvRecord>();
                            foreach (var item in property0.Value.EnumerateArray())
                            {
                                array.Add(SrvRecord.DeserializeSrvRecord(item));
                            }
                            srvRecords = array;
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new SrvRecordSetData(id, name, type, systemData, etag.Value, Optional.ToDictionary(metadata), Optional.ToNullable(ttl), fqdn.Value, provisioningState.Value, targetResource, Optional.ToList(srvRecords)));
        }
コード例 #5
0
        public override void ExecuteCmdlet()
        {
            DnsRecordBase result = null;
            switch (this.ParameterSetName)
            {
                case ParameterSetA:
                    {
                        result = new ARecord { Ipv4Address = this.Ipv4Address };
                        break;
                    }

                case ParameterSetAaaa:
                    {
                        result = new AaaaRecord { Ipv6Address = this.Ipv6Address };
                        break;
                    }

                case ParameterSetMx:
                    {
                        result = new MxRecord { Preference = this.Preference, Exchange = this.Exchange };
                        break;
                    }

                case ParameterSetNs:
                    {
                        result = new NsRecord { Nsdname = this.Nsdname };
                        break;
                    }
                case ParameterSetSrv:
                    {
                        result = new SrvRecord { Priority = this.Priority, Port = this.Port, Target = this.Target, Weight = this.Weight };
                        break;
                    }
                case ParameterSetTxt:
                    {
                        result = new TxtRecord { Value = this.Value };
                        break;
                    }
                case ParameterSetCName:
                    {
                        result = new CnameRecord { Cname = this.Cname };
                        break;
                    }
                case ParameterSetPtr:
                    {
                        result = new PtrRecord {Ptrdname = this.Ptrdname};
                        break;
                    }
                default:
                    {
                        throw new PSArgumentException(string.Format(ProjectResources.Error_UnknownParameterSetName, this.ParameterSetName));
                    }
            }

            WriteObject(result);
        }
コード例 #6
0
        private void RegisterTrunk(Trunk trunk)
        {
            trunk.State = Trunk.States.WaitingDns;

            var match = Regex.Match(trunk.OutgoingProxy, "(?<url>[^:]+)(:(?<port>[0-9]*))?");

            if (match.Success == false)
            {
                trunk.ErrorMessage = @"Invalid outgouing proxy URL";
            }
            else
            {
                var hostname = match.Groups["url"].Value;
                int?port     = null;
                if (match.Groups["port"].Success)
                {
                    port = int.Parse(match.Groups["port"].Value);
                }

                IPAddress address;
                if (IPAddress.TryParse(hostname, out address))
                {
                    trunk.SetServerEndPoint(address, port ?? 5060);
                    trunk.State = Trunk.States.Waiting200or401;
                    SendRegister(trunk, trunk.RegisterDuration);
                }
                else
                {
                    try
                    {
                        var prefixes = new string[] { @"_sip._tcp.", @"_sip._udp." };

                        Transports transport = Transports.None;
                        SrvRecord  record    = null;
                        foreach (var prefix in prefixes)
                        {
                            var request  = new DnsQueryRequest();
                            var response = request.Resolve(prefix + hostname, NsType.SRV, NsClass.INET, ProtocolType.Udp);

                            if (response.Answers.Length > 0)
                            {
                                record = response.Answers[0] as SrvRecord;
                            }

                            if (record != null)
                            {
                                if (prefix.Contains(@"tcp"))
                                {
                                    transport = Transports.Tcp;
                                }
                                if (prefix.Contains(@"udp"))
                                {
                                    transport = Transports.Udp;
                                }
                                break;
                            }
                        }

                        if (record == null)
                        {
                            trunk.ErrorMessage = @"Failed to get SRV record";
                        }
                        else
                        {
                            var addresses = Dns.GetHostAddresses(record.HostName);
                            if (addresses.Length < 0)
                            {
                                trunk.ErrorMessage = @"Failed to get DNS A record for " + record.HostName;
                            }
                            else
                            {
                                trunk.SetServerEndPoint(transport, addresses[0], port ?? record.Port);
                                trunk.State = Trunk.States.Waiting200or401;
                                SendRegister(trunk, trunk.RegisterDuration);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        trunk.ErrorMessage = ex.Message;
                    }
                }
            }
        }