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 16:32:04 +0100 (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    }