001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020
021 package org.apache.directory.server.dns.io.encoder;
022
023
024 import org.apache.directory.server.dns.messages.ResourceRecord;
025 import org.apache.directory.server.dns.store.DnsAttribute;
026 import org.apache.mina.core.buffer.IoBuffer;
027
028
029 /**
030 * The format of the SRV RR
031 *
032 * Here is the format of the SRV RR, whose DNS type code is 33:
033 *
034 * _Service._Proto.Name TTL Class SRV Priority Weight Port Target
035 *
036 * (There is an example near the end of this document.)
037 *
038 * Service
039 * The symbolic name of the desired service, as defined in Assigned
040 * Numbers [STD 2] or locally. An underscore (_) is prepended to
041 * the service identifier to avoid collisions with DNS labels that
042 * occur in nature.
043 *
044 * Some widely used services, notably POP, don't have a single
045 * universal name. If Assigned Numbers names the service
046 * indicated, that name is the only name which is legal for SRV
047 * lookups. The Service is case insensitive.
048 *
049 * Proto
050 * The symbolic name of the desired protocol, with an underscore
051 * (_) prepended to prevent collisions with DNS labels that occur
052 * in nature. _TCP and _UDP are at present the most useful values
053 * for this field, though any name defined by Assigned Numbers or
054 * locally may be used (as for Service). The Proto is case
055 * insensitive.
056 *
057 * Name
058 * The domain this RR refers to. The SRV RR is unique in that the
059 * name one searches for is not this name; the example near the end
060 * shows this clearly.
061 *
062 * TTL
063 * Standard DNS meaning [RFC 1035].
064 *
065 * Class
066 * Standard DNS meaning [RFC 1035]. SRV records occur in the IN
067 * Class.
068 *
069 * Priority
070 * The priority of this target host. A client MUST attempt to
071 * contact the target host with the lowest-numbered priority it can
072 * reach; target hosts with the same priority SHOULD be tried in an
073 * order defined by the weight field. The range is 0-65535. This
074 * is a 16 bit unsigned integer in network byte order.
075 *
076 * Weight
077 * A server selection mechanism. The weight field specifies a
078 * relative weight for entries with the same priority. Larger
079 * weights SHOULD be given a proportionately higher probability of
080 * being selected. The range of this number is 0-65535. This is a
081 * 16 bit unsigned integer in network byte order. Domain
082 * administrators SHOULD use Weight 0 when there isn't any server
083 * selection to do, to make the RR easier to read for humans (less
084 * noisy). In the presence of records containing weights greater
085 * than 0, records with weight 0 should have a very small chance of
086 * being selected.
087 *
088 * In the absence of a protocol whose specification calls for the
089 * use of other weighting information, a client arranges the SRV
090 * RRs of the same Priority in the order in which target hosts,
091 * specified by the SRV RRs, will be contacted. The following
092 * algorithm SHOULD be used to order the SRV RRs of the same
093 * priority:
094 *
095 * To select a target to be contacted next, arrange all SRV RRs
096 * (that have not been ordered yet) in any order, except that all
097 * those with weight 0 are placed at the beginning of the list.
098 *
099 * Compute the sum of the weights of those RRs, and with each RR
100 * associate the running sum in the selected order. Then choose a
101 * uniform random number between 0 and the sum computed
102 * (inclusive), and select the RR whose running sum value is the
103 * first in the selected order which is greater than or equal to
104 * the random number selected. The target host specified in the
105 * selected SRV RR is the next one to be contacted by the client.
106 * Remove this SRV RR from the set of the unordered SRV RRs and
107 * apply the described algorithm to the unordered SRV RRs to select
108 * the next target host. Continue the ordering process until there
109 * are no unordered SRV RRs. This process is repeated for each
110 * Priority.
111 *
112 * Port
113 * The port on this target host of this service. The range is 0-
114 * 65535. This is a 16 bit unsigned integer in network byte order.
115 * This is often as specified in Assigned Numbers but need not be.
116 *
117 * Target
118 * The domain name of the target host. There MUST be one or more
119 * address records for this name, the name MUST NOT be an alias (in
120 * the sense of RFC 1034 or RFC 2181). Implementors are urged, but
121 * not required, to return the address record(s) in the Additional
122 * Data section. Unless and until permitted by future standards
123 * action, name compression is not to be used for this field.
124 *
125 * A Target of "." means that the service is decidedly not
126 * available at this domain.
127 *
128 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
129 * @version $Rev: 725712 $, $Date: 2008-12-11 17:32:04 +0200 (Thu, 11 Dec 2008) $
130 */
131 public class ServerSelectionRecordEncoder extends ResourceRecordEncoder
132 {
133 protected void putResourceRecordData( IoBuffer byteBuffer, ResourceRecord record )
134 {
135 byteBuffer.putShort( Short.parseShort( record.get( DnsAttribute.SERVICE_PRIORITY ) ) );
136 byteBuffer.putShort( Short.parseShort( record.get( DnsAttribute.SERVICE_WEIGHT ) ) );
137 byteBuffer.putShort( Short.parseShort( record.get( DnsAttribute.SERVICE_PORT ) ) );
138 putDomainName( byteBuffer, record.get( DnsAttribute.DOMAIN_NAME ) );
139 }
140 }