public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } ServiceName other = (ServiceName)obj; if ((this.name == null) ? (other.name != null) : !this.name.Equals(other.name)) { return(false); } if (this.type != other.type && (this.type == null || !this.type.Equals(other.type))) { return(false); } if ((this.domain == null) ? (other.domain != null) : !this.domain.Equals(other.domain)) { return(false); } return(true); }
/** * Set the name of the service. * @param name the new service name. */ public void setName(ServiceName name) { this.name = name; }
/** * Create a ServiceData object. * @param name the name of the service. * @param host the fully qualified name of the host providing the service. * @param port the TCP or UDP port number of the service. */ public ServiceData(ServiceName name, String host, int port) { this.name = name; this.host = host; this.port = port; }
/** * Remove a service from DNS-SD. * @param serviceName the name of the service to remove. * @return true if the service was removed, false if no service was found. * @throws DnsSDException if the service couldn't be unregistered due to some error. */ public abstract bool unregisterService(ServiceName serviceName);
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); }
public override bool unregisterService(ServiceName serviceName) { 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); } 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 RecordExistsPrequisite(dnsName, RecordType.Any)); msg.Updates.Add(new DeleteRecordUpdate(new PtrRecord(typeName, timeToLive, dnsName))); foreach (DomainName subtype in subtypes) { msg.Updates.Add(new DeleteRecordUpdate(new PtrRecord(subtype, timeToLive, dnsName))); } msg.Updates.Add(new DeleteAllRecordsUpdate(dnsName)); 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); break; 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"); } // Remove the service type if there are no instances left 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(typeName, RecordType.Any)); msg.Updates.Add(new DeleteRecordUpdate(new PtrRecord(servicesName, timeToLive, typeName))); tsigRecord = generateTSigRecord(msg.TransactionID); if (tsigRecord != null) { msg.TSigOptions = tsigRecord; } response = resolver.SendUpdate(msg); if (response != null) { switch (response.ReturnCode) { case ReturnCode.NoError: //flushCache(update); Log.Info(String.Format("Removed service type record {0}", typeName)); break; case ReturnCode.YXDomain: // Prerequisite failed, service instances exists Log.Info(String.Format("Did not remove service type record {0}, instances left.", typeName)); break; default: Log.Error(String.Format("Failed to remove service type {0}, server returned status {1}", typeName, response.ReturnCode.ToString())); break; } } else { throw new DnsSDException("Failed to send DNS update to server. Server time out"); } return(true); }
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"); } }