예제 #1
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);
        }
예제 #2
0
        public override bool registerService(ServiceData serviceData)
        {
            ServiceName       serviceName = serviceData.getName();
            DomainName        dnsName     = serviceName.toDnsName();
            DomainName        typeName    = DomainName.Parse(serviceName.getType().toDnsString()) + registrationDomain;
            List <DomainName> subtypes    = new List <DomainName>(serviceName.getType().getSubtypes().Count);

            foreach (String subtype in serviceName.getType().toDnsStringsWithSubtype())
            {
                subtypes.Add(DomainName.Parse(subtype) + registrationDomain);
            }
            DomainName target = DomainName.Parse(serviceData.getHost());

            List <String> strings = new List <String>();

            foreach (var entry in serviceData.getProperties())
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(entry.Key);
                if (entry.Key != null)
                {
                    sb.Append('=').Append(entry.Value);
                }
                strings.Add(sb.ToString());
            }
            if (strings.Count <= 0)
            {
                // Must not be empty
                strings.Add("");
            }

            DnsUpdateMessage msg = new DnsUpdateMessage();

            msg.ZoneName = registrationDomain; // XXX Should really be the zone (SOA) for the RRs we are about to add

            msg.Prequisites.Add(new RecordNotExistsPrequisite(dnsName, RecordType.Any));
            msg.Updates.Add(new AddRecordUpdate(new PtrRecord(servicesName, timeToLive, typeName)));
            msg.Updates.Add(new AddRecordUpdate(new PtrRecord(typeName, timeToLive, dnsName)));


            foreach (DomainName subtype in subtypes)
            {
                msg.Updates.Add(new AddRecordUpdate(new PtrRecord(subtype, timeToLive, dnsName)));
            }

            msg.Updates.Add(new AddRecordUpdate(new SrvRecord(dnsName, timeToLive, 0, 0, Convert.ToUInt16(serviceData.getPort()), target)));

            msg.Updates.Add(new AddRecordUpdate(new TxtRecord(dnsName, timeToLive, strings)));

            TSigRecord tsigRecord = generateTSigRecord(msg.TransactionID);

            if (tsigRecord != null)
            {
                msg.TSigOptions = tsigRecord;
            }


            DnsUpdateMessage response = resolver.SendUpdate(msg);


            if (response != null)
            {
                switch (response.ReturnCode)
                {
                case ReturnCode.NoError:
                    //flushCache(update);
                    return(true);

                case ReturnCode.YXDomain:        // Prerequisite failed, the service already exists.
                    return(false);

                default:
                    throw new DnsSDException("Failed to send DNS update to server. Server returned error code: " + response.ReturnCode.ToString());
                }
            }
            else
            {
                throw new DnsSDException("Failed to send DNS update to server. Server time out");
            }
        }