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}