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
021package org.apache.directory.server.dns.io.encoder;
022
023
024import org.apache.directory.server.dns.messages.ResourceRecord;
025import org.apache.directory.server.dns.store.DnsAttribute;
026import 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 */
130public class ServerSelectionRecordEncoder extends ResourceRecordEncoder
131{
132    protected void putResourceRecordData( IoBuffer byteBuffer, ResourceRecord record )
133    {
134        byteBuffer.putShort( Short.parseShort( record.get( DnsAttribute.SERVICE_PRIORITY ) ) );
135        byteBuffer.putShort( Short.parseShort( record.get( DnsAttribute.SERVICE_WEIGHT ) ) );
136        byteBuffer.putShort( Short.parseShort( record.get( DnsAttribute.SERVICE_PORT ) ) );
137        putDomainName( byteBuffer, record.get( DnsAttribute.DOMAIN_NAME ) );
138    }
139}