1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20
21 package org.apache.directory.server.dns.io.encoder;
22
23
24 import org.apache.directory.server.dns.messages.ResourceRecord;
25 import org.apache.directory.server.dns.store.DnsAttribute;
26 import org.apache.mina.common.ByteBuffer;
27
28
29 /**
30 * The format of the SRV RR
31 *
32 * Here is the format of the SRV RR, whose DNS type code is 33:
33 *
34 * _Service._Proto.Name TTL Class SRV Priority Weight Port Target
35 *
36 * (There is an example near the end of this document.)
37 *
38 * Service
39 * The symbolic name of the desired service, as defined in Assigned
40 * Numbers [STD 2] or locally. An underscore (_) is prepended to
41 * the service identifier to avoid collisions with DNS labels that
42 * occur in nature.
43 *
44 * Some widely used services, notably POP, don't have a single
45 * universal name. If Assigned Numbers names the service
46 * indicated, that name is the only name which is legal for SRV
47 * lookups. The Service is case insensitive.
48 *
49 * Proto
50 * The symbolic name of the desired protocol, with an underscore
51 * (_) prepended to prevent collisions with DNS labels that occur
52 * in nature. _TCP and _UDP are at present the most useful values
53 * for this field, though any name defined by Assigned Numbers or
54 * locally may be used (as for Service). The Proto is case
55 * insensitive.
56 *
57 * Name
58 * The domain this RR refers to. The SRV RR is unique in that the
59 * name one searches for is not this name; the example near the end
60 * shows this clearly.
61 *
62 * TTL
63 * Standard DNS meaning [RFC 1035].
64 *
65 * Class
66 * Standard DNS meaning [RFC 1035]. SRV records occur in the IN
67 * Class.
68 *
69 * Priority
70 * The priority of this target host. A client MUST attempt to
71 * contact the target host with the lowest-numbered priority it can
72 * reach; target hosts with the same priority SHOULD be tried in an
73 * order defined by the weight field. The range is 0-65535. This
74 * is a 16 bit unsigned integer in network byte order.
75 *
76 * Weight
77 * A server selection mechanism. The weight field specifies a
78 * relative weight for entries with the same priority. Larger
79 * weights SHOULD be given a proportionately higher probability of
80 * being selected. The range of this number is 0-65535. This is a
81 * 16 bit unsigned integer in network byte order. Domain
82 * administrators SHOULD use Weight 0 when there isn't any server
83 * selection to do, to make the RR easier to read for humans (less
84 * noisy). In the presence of records containing weights greater
85 * than 0, records with weight 0 should have a very small chance of
86 * being selected.
87 *
88 * In the absence of a protocol whose specification calls for the
89 * use of other weighting information, a client arranges the SRV
90 * RRs of the same Priority in the order in which target hosts,
91 * specified by the SRV RRs, will be contacted. The following
92 * algorithm SHOULD be used to order the SRV RRs of the same
93 * priority:
94 *
95 * To select a target to be contacted next, arrange all SRV RRs
96 * (that have not been ordered yet) in any order, except that all
97 * those with weight 0 are placed at the beginning of the list.
98 *
99 * 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: 507387 $, $Date: 2007-02-14 05:54:05 +0100 (Mi, 14 Feb 2007) $
130 */
131 public class ServerSelectionRecordEncoder extends ResourceRecordEncoder
132 {
133 protected void putResourceRecordData( ByteBuffer 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 }