| 1 |  |  | 
            
  
    | 2 |  |  | 
            
  
    | 3 |  |  | 
            
  
    | 4 |  |  | 
            
  
    | 5 |  | package javax.jmdns.impl; | 
            
  
    | 6 |  |  | 
            
  
    | 7 |  | import java.io.ByteArrayInputStream; | 
            
  
    | 8 |  | import java.io.IOException; | 
            
  
    | 9 |  | import java.net.DatagramPacket; | 
            
  
    | 10 |  | import java.net.InetAddress; | 
            
  
    | 11 |  | import java.util.HashMap; | 
            
  
    | 12 |  | import java.util.Map; | 
            
  
    | 13 |  | import java.util.logging.Level; | 
            
  
    | 14 |  | import java.util.logging.Logger; | 
            
  
    | 15 |  |  | 
            
  
    | 16 |  | import javax.jmdns.impl.constants.DNSConstants; | 
            
  
    | 17 |  | import javax.jmdns.impl.constants.DNSLabel; | 
            
  
    | 18 |  | import javax.jmdns.impl.constants.DNSOptionCode; | 
            
  
    | 19 |  | import javax.jmdns.impl.constants.DNSRecordClass; | 
            
  
    | 20 |  | import javax.jmdns.impl.constants.DNSRecordType; | 
            
  
    | 21 |  | import javax.jmdns.impl.constants.DNSResultCode; | 
            
  
    | 22 |  |  | 
            
  
    | 23 |  |  | 
            
  
    | 24 |  |  | 
            
  
    | 25 |  |  | 
            
  
    | 26 |  | @author | 
            
  
    | 27 |  |  | 
               
        |  |  | 
           
           |  | 36.2% | Uncovered Elements: 224 (351) | Complexity: 79 | Complexity Density: 0.33 |  | 
  
  
    | 28 |  | public final class DNSIncoming extends DNSMessage { | 
            
  
    | 29 |  | private static Logger logger                                = Logger.getLogger(DNSIncoming.class.getName()); | 
            
  
    | 30 |  |  | 
            
  
    | 31 |  |  | 
            
  
    | 32 |  |  | 
            
  
    | 33 |  | public static boolean USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET = true; | 
            
  
    | 34 |  |  | 
               
        |  |  | 
           
           |  | 65.3% | Uncovered Elements: 34 (98) | Complexity: 30 | Complexity Density: 0.38 |  | 
  
  
    | 35 |  | public static class MessageInputStream extends ByteArrayInputStream { | 
            
  
    | 36 |  | private static Logger      logger1 = Logger.getLogger(MessageInputStream.class.getName()); | 
            
  
    | 37 |  |  | 
            
  
    | 38 |  | final Map<Integer, String> _names; | 
            
  
    | 39 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 40 | 1004 |  public MessageInputStream(byte[] buffer, int length) {... | 
            
  
    | 41 | 993 | this(buffer, 0, length); | 
            
  
    | 42 |  | } | 
            
  
    | 43 |  |  | 
            
  
    | 44 |  |  | 
            
  
    | 45 |  | @param | 
            
  
    | 46 |  | @param | 
            
  
    | 47 |  | @param | 
            
  
    | 48 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (2) | Complexity: 1 | Complexity Density: 0.5 |  | 
  
  
    | 49 | 999 |  public MessageInputStream(byte[] buffer, int offset, int length) {... | 
            
  
    | 50 | 979 | super(buffer, offset, length); | 
            
  
    | 51 | 1001 | _names = new HashMap<Integer, String>(); | 
            
  
    | 52 |  | } | 
            
  
    | 53 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 54 | 0 |  public int readByte() {... | 
            
  
    | 55 | 0 | return this.read(); | 
            
  
    | 56 |  | } | 
            
  
    | 57 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 58 | 10592 |  public int readUnsignedShort() {... | 
            
  
    | 59 | 10655 | return (this.read() << 8) | this.read(); | 
            
  
    | 60 |  | } | 
            
  
    | 61 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 62 | 1058 |  public int readInt() {... | 
            
  
    | 63 | 1073 | return (this.readUnsignedShort() << 16) | this.readUnsignedShort(); | 
            
  
    | 64 |  | } | 
            
  
    | 65 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (3) | Complexity: 1 | Complexity Density: 0.33 |  | 
  
  
    | 66 | 579 |  public byte[] readBytes(int len) {... | 
            
  
    | 67 | 587 | byte bytes[] = new byte[len]; | 
            
  
    | 68 | 583 | this.read(bytes, 0, len); | 
            
  
    | 69 | 574 | return bytes; | 
            
  
    | 70 |  | } | 
            
  
    | 71 |  |  | 
               
        |  |  | 
           
           |  | 48.4% | Uncovered Elements: 16 (31) | Complexity: 13 | Complexity Density: 0.45 |  | 
  
  
    | 72 | 2508 |  public String readUTF(int len) {... | 
            
  
    | 73 | 2517 | StringBuilder buffer = new StringBuilder(len); | 
            
  
    | 74 | 18536 | for (int index = 0; index < len; index++) { | 
            
  
    | 75 | 16017 | int ch = this.read(); | 
            
  
    | 76 | 16115 | switch (ch >> 4) { | 
            
  
    | 77 | 0 | case 0: | 
            
  
    | 78 | 0 | case 1: | 
            
  
    | 79 | 276 | case 2: | 
            
  
    | 80 | 393 | case 3: | 
            
  
    | 81 | 226 | case 4: | 
            
  
    | 82 | 852 | case 5: | 
            
  
    | 83 | 10836 | case 6: | 
            
  
    | 84 | 3650 | case 7: | 
            
  
    | 85 |  |  | 
            
  
    | 86 | 16136 | break; | 
            
  
    | 87 | 0 | case 12: | 
            
  
    | 88 | 0 | case 13: | 
            
  
    | 89 |  |  | 
            
  
    | 90 | 0 | ch = ((ch & 0x1F) << 6) | (this.read() & 0x3F); | 
            
  
    | 91 | 0 | index++; | 
            
  
    | 92 | 0 | break; | 
            
  
    | 93 | 0 | case 14: | 
            
  
    | 94 |  |  | 
            
  
    | 95 | 0 | ch = ((ch & 0x0f) << 12) | ((this.read() & 0x3F) << 6) | (this.read() & 0x3F); | 
            
  
    | 96 | 0 | index++; | 
            
  
    | 97 | 0 | index++; | 
            
  
    | 98 | 0 | break; | 
            
  
    | 99 | 0 | default: | 
            
  
    | 100 |  |  | 
            
  
    | 101 | 0 | ch = ((ch & 0x3F) << 4) | (this.read() & 0x0f); | 
            
  
    | 102 | 0 | index++; | 
            
  
    | 103 | 0 | break; | 
            
  
    | 104 |  | } | 
            
  
    | 105 | 16046 | buffer.append((char) ch); | 
            
  
    | 106 |  | } | 
            
  
    | 107 | 2531 | return buffer.toString(); | 
            
  
    | 108 |  | } | 
            
  
    | 109 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 3 (3) | Complexity: 2 | Complexity Density: 2 |  | 
  
  
    | 110 | 0 |  protected synchronized int peek() {... | 
            
  
    | 111 | 0 | return (pos < count) ? (buf[pos] & 0xff) : -1; | 
            
  
    | 112 |  | } | 
            
  
    | 113 |  |  | 
               
        |  |  | 
           
           |  | 79.1% | Uncovered Elements: 9 (43) | Complexity: 8 | Complexity Density: 0.22 |  | 
  
  
    | 114 | 1761 |  public String readName() {... | 
            
  
    | 115 | 1780 | Map<Integer, StringBuilder> names = new HashMap<Integer, StringBuilder>(); | 
            
  
    | 116 | 1774 | StringBuilder buffer = new StringBuilder(); | 
            
  
    | 117 | 1780 | boolean finished = false; | 
            
  
    | 118 | 5398 | while (!finished) { | 
            
  
    | 119 | 4316 | int len = this.read(); | 
            
  
    | 120 | 4320 | if (len == 0) { | 
            
  
    | 121 | 688 | finished = true; | 
            
  
    | 122 | 693 | break; | 
            
  
    | 123 |  | } | 
            
  
    | 124 | 3617 | switch (DNSLabel.labelForByte(len)) { | 
            
  
    | 125 | 2530 | case Standard: | 
            
  
    | 126 | 2539 | int offset = pos - 1; | 
            
  
    | 127 | 2528 | String label = this.readUTF(len) + "."; | 
            
  
    | 128 | 2523 | buffer.append(label); | 
            
  
    | 129 | 2536 | for (StringBuilder previousLabel : names.values()) { | 
            
  
    | 130 | 6944 | previousLabel.append(label); | 
            
  
    | 131 |  | } | 
            
  
    | 132 | 2524 | names.put(Integer.valueOf(offset), new StringBuilder(label)); | 
            
  
    | 133 | 2514 | break; | 
            
  
    | 134 | 1099 | case Compressed: | 
            
  
    | 135 | 1101 | int index = (DNSLabel.labelValue(len) << 8) | this.read(); | 
            
  
    | 136 | 1100 | String compressedLabel = _names.get(Integer.valueOf(index)); | 
            
  
    | 137 | 1099 | if (compressedLabel == null) { | 
            
  
    | 138 | 0 | logger1.severe("bad domain name: possible circular name detected. Bad offset: 0x" + Integer.toHexString(index) + " at 0x" + Integer.toHexString(pos - 2)); | 
            
  
    | 139 | 0 | compressedLabel = ""; | 
            
  
    | 140 |  | } | 
            
  
    | 141 | 1097 | buffer.append(compressedLabel); | 
            
  
    | 142 | 1102 | for (StringBuilder previousLabel : names.values()) { | 
            
  
    | 143 | 433 | previousLabel.append(compressedLabel); | 
            
  
    | 144 |  | } | 
            
  
    | 145 | 1098 | finished = true; | 
            
  
    | 146 | 1100 | break; | 
            
  
    | 147 | 0 | case Extended: | 
            
  
    | 148 |  |  | 
            
  
    | 149 | 0 | logger1.severe("Extended label are not currently supported."); | 
            
  
    | 150 | 0 | break; | 
            
  
    | 151 | 0 | case Unknown: | 
            
  
    | 152 | 0 | default: | 
            
  
    | 153 | 0 | logger1.severe("unsupported dns label type: '" + Integer.toHexString(len & 0xC0) + "'"); | 
            
  
    | 154 |  | } | 
            
  
    | 155 |  | } | 
            
  
    | 156 | 1778 | for (Integer index : names.keySet()) { | 
            
  
    | 157 | 2529 | _names.put(index, names.get(index).toString()); | 
            
  
    | 158 |  | } | 
            
  
    | 159 | 1803 | return buffer.toString(); | 
            
  
    | 160 |  | } | 
            
  
    | 161 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 2 (2) | Complexity: 1 | Complexity Density: 0.5 |  | 
  
  
    | 162 | 0 |  public String readNonNameString() {... | 
            
  
    | 163 | 0 | int len = this.read(); | 
            
  
    | 164 | 0 | return this.readUTF(len); | 
            
  
    | 165 |  | } | 
            
  
    | 166 |  |  | 
            
  
    | 167 |  | } | 
            
  
    | 168 |  |  | 
            
  
    | 169 |  | private final DatagramPacket     _packet; | 
            
  
    | 170 |  |  | 
            
  
    | 171 |  | private final long               _receivedTime; | 
            
  
    | 172 |  |  | 
            
  
    | 173 |  | private final MessageInputStream _messageInputStream; | 
            
  
    | 174 |  |  | 
            
  
    | 175 |  | private int                      _senderUDPPayload; | 
            
  
    | 176 |  |  | 
            
  
    | 177 |  |  | 
            
  
    | 178 |  |  | 
            
  
    | 179 |  |  | 
            
  
    | 180 |  | @param | 
            
  
    | 181 |  | @exception | 
            
  
    | 182 |  |  | 
               
        |  |  | 
           
           |  | 86% | Uncovered Elements: 8 (57) | Complexity: 13 | Complexity Density: 0.37 |  | 
  
  
    | 183 | 642 |  public DNSIncoming(DatagramPacket packet) throws IOException {... | 
            
  
    | 184 | 635 | super(0, 0, packet.getPort() == DNSConstants.MDNS_PORT); | 
            
  
    | 185 | 651 | this._packet = packet; | 
            
  
    | 186 | 651 | InetAddress source = packet.getAddress(); | 
            
  
    | 187 | 651 | this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength()); | 
            
  
    | 188 | 649 | this._receivedTime = System.currentTimeMillis(); | 
            
  
    | 189 | 649 | this._senderUDPPayload = DNSConstants.MAX_MSG_TYPICAL; | 
            
  
    | 190 |  |  | 
            
  
    | 191 | 652 | try { | 
            
  
    | 192 | 653 | this.setId(_messageInputStream.readUnsignedShort()); | 
            
  
    | 193 | 656 | this.setFlags(_messageInputStream.readUnsignedShort()); | 
            
  
    | 194 | 653 | int numQuestions = _messageInputStream.readUnsignedShort(); | 
            
  
    | 195 | 656 | int numAnswers = _messageInputStream.readUnsignedShort(); | 
            
  
    | 196 | 654 | int numAuthorities = _messageInputStream.readUnsignedShort(); | 
            
  
    | 197 | 663 | int numAdditionals = _messageInputStream.readUnsignedShort(); | 
            
  
    | 198 |  |  | 
            
  
    | 199 |  |  | 
            
  
    | 200 | 649 | if (numQuestions > 0) { | 
            
  
    | 201 | 689 | for (int i = 0; i < numQuestions; i++) { | 
            
  
    | 202 | 352 | _questions.add(this.readQuestion()); | 
            
  
    | 203 |  | } | 
            
  
    | 204 |  | } | 
            
  
    | 205 |  |  | 
            
  
    | 206 |  |  | 
            
  
    | 207 | 651 | if (numAnswers > 0) { | 
            
  
    | 208 | 1046 | for (int i = 0; i < numAnswers; i++) { | 
            
  
    | 209 | 720 | DNSRecord rec = this.readAnswer(source); | 
            
  
    | 210 | 724 | if (rec != null) { | 
            
  
    | 211 |  |  | 
            
  
    | 212 | 718 | _answers.add(rec); | 
            
  
    | 213 |  | } | 
            
  
    | 214 |  | } | 
            
  
    | 215 |  | } | 
            
  
    | 216 |  |  | 
            
  
    | 217 | 652 | if (numAuthorities > 0) { | 
            
  
    | 218 | 443 | for (int i = 0; i < numAuthorities; i++) { | 
            
  
    | 219 | 228 | DNSRecord rec = this.readAnswer(source); | 
            
  
    | 220 | 228 | if (rec != null) { | 
            
  
    | 221 |  |  | 
            
  
    | 222 | 223 | _authoritativeAnswers.add(rec); | 
            
  
    | 223 |  | } | 
            
  
    | 224 |  | } | 
            
  
    | 225 |  | } | 
            
  
    | 226 |  |  | 
            
  
    | 227 | 653 | if (numAdditionals > 0) { | 
            
  
    | 228 | 214 | for (int i = 0; i < numAdditionals; i++) { | 
            
  
    | 229 | 117 | DNSRecord rec = this.readAnswer(source); | 
            
  
    | 230 | 119 | if (rec != null) { | 
            
  
    | 231 |  |  | 
            
  
    | 232 | 0 | _additionals.add(rec); | 
            
  
    | 233 |  | } | 
            
  
    | 234 |  | } | 
            
  
    | 235 |  | } | 
            
  
    | 236 |  | } catch (Exception e) { | 
            
  
    | 237 | 0 | logger.log(Level.WARNING, "DNSIncoming() dump " + print(true) + "\n exception ", e); | 
            
  
    | 238 |  |  | 
            
  
    | 239 | 0 | IOException ioe = new IOException("DNSIncoming corrupted message"); | 
            
  
    | 240 | 0 | ioe.initCause(e); | 
            
  
    | 241 | 0 | throw ioe; | 
            
  
    | 242 |  | } | 
            
  
    | 243 |  | } | 
            
  
    | 244 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (4) | Complexity: 1 | Complexity Density: 0.25 |  | 
  
  
    | 245 | 344 |  private DNSIncoming(int flags, int id, boolean multicast, DatagramPacket packet, long receivedTime) {... | 
            
  
    | 246 | 345 | super(flags, id, multicast); | 
            
  
    | 247 | 347 | this._packet = packet; | 
            
  
    | 248 | 349 | this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength()); | 
            
  
    | 249 | 347 | this._receivedTime = receivedTime; | 
            
  
    | 250 |  | } | 
            
  
    | 251 |  |  | 
            
  
    | 252 |  |  | 
            
  
    | 253 |  |  | 
            
  
    | 254 |  |  | 
            
  
    | 255 |  |  | 
            
  
    | 256 |  | @see | 
            
  
    | 257 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (7) | Complexity: 1 | Complexity Density: 0.14 |  | 
  
  
    | 258 | 340 |  @Override... | 
            
  
    | 259 |  | public DNSIncoming clone() { | 
            
  
    | 260 | 345 | DNSIncoming in = new DNSIncoming(this.getFlags(), this.getId(), this.isMulticast(), this._packet, this._receivedTime); | 
            
  
    | 261 | 348 | in._senderUDPPayload = this._senderUDPPayload; | 
            
  
    | 262 | 349 | in._questions.addAll(this._questions); | 
            
  
    | 263 | 341 | in._answers.addAll(this._answers); | 
            
  
    | 264 | 341 | in._authoritativeAnswers.addAll(this._authoritativeAnswers); | 
            
  
    | 265 | 347 | in._additionals.addAll(this._additionals); | 
            
  
    | 266 | 350 | return in; | 
            
  
    | 267 |  | } | 
            
  
    | 268 |  |  | 
            
  
    | 269 |  |  | 
               
        |  |  | 
           
           |  | 80% | Uncovered Elements: 2 (10) | Complexity: 2 | Complexity Density: 0.25 |  | 
  
  
    | 270 | 340 |  private DNSQuestion readQuestion() {... | 
            
  
    | 271 | 351 | String domain = _messageInputStream.readName(); | 
            
  
    | 272 | 354 | DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort()); | 
            
  
    | 273 | 351 | if (type == DNSRecordType.TYPE_IGNORE) { | 
            
  
    | 274 | 0 | logger.log(Level.SEVERE, "Could not find record type: " + this.print(true)); | 
            
  
    | 275 |  | } | 
            
  
    | 276 | 347 | int recordClassIndex = _messageInputStream.readUnsignedShort(); | 
            
  
    | 277 | 354 | DNSRecordClass recordClass = DNSRecordClass.classForIndex(recordClassIndex); | 
            
  
    | 278 | 354 | boolean unique = recordClass.isUnique(recordClassIndex); | 
            
  
    | 279 | 349 | return DNSQuestion.newQuestion(domain, type, recordClass, unique); | 
            
  
    | 280 |  | } | 
            
  
    | 281 |  |  | 
               
        |  |  | 
           
           |  | 32.5% | Uncovered Elements: 104 (154) | Complexity: 37 | Complexity Density: 0.33 |  | 
  
  
    | 282 | 1061 |  private DNSRecord readAnswer(InetAddress source) {... | 
            
  
    | 283 | 1073 | String domain = _messageInputStream.readName(); | 
            
  
    | 284 | 1068 | DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort()); | 
            
  
    | 285 | 1064 | if (type == DNSRecordType.TYPE_IGNORE) { | 
            
  
    | 286 | 0 | logger.log(Level.SEVERE, "Could not find record type. domain: " + domain + "\n" + this.print(true)); | 
            
  
    | 287 |  | } | 
            
  
    | 288 | 1065 | int recordClassIndex = _messageInputStream.readUnsignedShort(); | 
            
  
    | 289 | 1066 | DNSRecordClass recordClass = (type == DNSRecordType.TYPE_OPT ? DNSRecordClass.CLASS_UNKNOWN : DNSRecordClass.classForIndex(recordClassIndex)); | 
            
  
    | 290 | 1064 | if ((recordClass == DNSRecordClass.CLASS_UNKNOWN) && (type != DNSRecordType.TYPE_OPT)) { | 
            
  
    | 291 | 0 | logger.log(Level.SEVERE, "Could not find record class. domain: " + domain + " type: " + type + "\n" + this.print(true)); | 
            
  
    | 292 |  | } | 
            
  
    | 293 | 1062 | boolean unique = recordClass.isUnique(recordClassIndex); | 
            
  
    | 294 | 1061 | int ttl = _messageInputStream.readInt(); | 
            
  
    | 295 | 1072 | int len = _messageInputStream.readUnsignedShort(); | 
            
  
    | 296 | 1077 | DNSRecord rec = null; | 
            
  
    | 297 |  |  | 
            
  
    | 298 | 1077 | switch (type) { | 
            
  
    | 299 | 347 | case TYPE_A: | 
            
  
    | 300 | 347 | rec = new DNSRecord.IPv4Address(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len)); | 
            
  
    | 301 | 346 | break; | 
            
  
    | 302 | 105 | case TYPE_AAAA: | 
            
  
    | 303 | 104 | rec = new DNSRecord.IPv6Address(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len)); | 
            
  
    | 304 | 103 | break; | 
            
  
    | 305 | 0 | case TYPE_CNAME: | 
            
  
    | 306 | 148 | case TYPE_PTR: | 
            
  
    | 307 | 150 | String service = ""; | 
            
  
    | 308 | 154 | service = _messageInputStream.readName(); | 
            
  
    | 309 | 158 | if (service.length() > 0) { | 
            
  
    | 310 | 157 | rec = new DNSRecord.Pointer(domain, recordClass, unique, ttl, service); | 
            
  
    | 311 |  | } else { | 
            
  
    | 312 | 0 | logger.log(Level.WARNING, "PTR record of class: " + recordClass + ", there was a problem reading the service name of the answer for domain:" + domain); | 
            
  
    | 313 |  | } | 
            
  
    | 314 | 156 | break; | 
            
  
    | 315 | 127 | case TYPE_TXT: | 
            
  
    | 316 | 129 | rec = new DNSRecord.Text(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len)); | 
            
  
    | 317 | 128 | break; | 
            
  
    | 318 | 207 | case TYPE_SRV: | 
            
  
    | 319 | 210 | int priority = _messageInputStream.readUnsignedShort(); | 
            
  
    | 320 | 211 | int weight = _messageInputStream.readUnsignedShort(); | 
            
  
    | 321 | 211 | int port = _messageInputStream.readUnsignedShort(); | 
            
  
    | 322 | 211 | String target = ""; | 
            
  
    | 323 |  |  | 
            
  
    | 324 |  |  | 
            
  
    | 325 | 208 | if (USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) { | 
            
  
    | 326 | 210 | target = _messageInputStream.readName(); | 
            
  
    | 327 |  | } else { | 
            
  
    | 328 |  |  | 
            
  
    | 329 | 0 | target = _messageInputStream.readNonNameString(); | 
            
  
    | 330 |  | } | 
            
  
    | 331 | 210 | rec = new DNSRecord.Service(domain, recordClass, unique, ttl, priority, weight, port, target); | 
            
  
    | 332 | 211 | break; | 
            
  
    | 333 | 0 | case TYPE_HINFO: | 
            
  
    | 334 | 0 | StringBuilder buf = new StringBuilder(); | 
            
  
    | 335 | 0 | buf.append(_messageInputStream.readUTF(len)); | 
            
  
    | 336 | 0 | int index = buf.indexOf(" "); | 
            
  
    | 337 | 0 | String cpu = (index > 0 ? buf.substring(0, index) : buf.toString()).trim(); | 
            
  
    | 338 | 0 | String os = (index > 0 ? buf.substring(index + 1) : "").trim(); | 
            
  
    | 339 | 0 | rec = new DNSRecord.HostInformation(domain, recordClass, unique, ttl, cpu, os); | 
            
  
    | 340 | 0 | break; | 
            
  
    | 341 | 0 | case TYPE_OPT: | 
            
  
    | 342 | 0 | DNSResultCode extendedResultCode = DNSResultCode.resultCodeForFlags(this.getFlags(), ttl); | 
            
  
    | 343 | 0 | int version = (ttl & 0x00ff0000) >> 16; | 
            
  
    | 344 | 0 | if (version == 0) { | 
            
  
    | 345 | 0 | _senderUDPPayload = recordClassIndex; | 
            
  
    | 346 | 0 | while (_messageInputStream.available() > 0) { | 
            
  
    | 347 |  |  | 
            
  
    | 348 | 0 | int optionCodeInt = 0; | 
            
  
    | 349 | 0 | DNSOptionCode optionCode = null; | 
            
  
    | 350 | 0 | if (_messageInputStream.available() >= 2) { | 
            
  
    | 351 | 0 | optionCodeInt = _messageInputStream.readUnsignedShort(); | 
            
  
    | 352 | 0 | optionCode = DNSOptionCode.resultCodeForFlags(optionCodeInt); | 
            
  
    | 353 |  | } else { | 
            
  
    | 354 | 0 | logger.log(Level.WARNING, "There was a problem reading the OPT record. Ignoring."); | 
            
  
    | 355 | 0 | break; | 
            
  
    | 356 |  | } | 
            
  
    | 357 | 0 | int optionLength = 0; | 
            
  
    | 358 | 0 | if (_messageInputStream.available() >= 2) { | 
            
  
    | 359 | 0 | optionLength = _messageInputStream.readUnsignedShort(); | 
            
  
    | 360 |  | } else { | 
            
  
    | 361 | 0 | logger.log(Level.WARNING, "There was a problem reading the OPT record. Ignoring."); | 
            
  
    | 362 | 0 | break; | 
            
  
    | 363 |  | } | 
            
  
    | 364 | 0 | byte[] optiondata = new byte[0]; | 
            
  
    | 365 | 0 | if (_messageInputStream.available() >= optionLength) { | 
            
  
    | 366 | 0 | optiondata = _messageInputStream.readBytes(optionLength); | 
            
  
    | 367 |  | } | 
            
  
    | 368 |  |  | 
            
  
    | 369 |  |  | 
            
  
    | 370 | 0 | switch (optionCode) { | 
            
  
    | 371 | 0 | case Owner: | 
            
  
    | 372 |  |  | 
            
  
    | 373 |  |  | 
            
  
    | 374 |  |  | 
            
  
    | 375 |  |  | 
            
  
    | 376 |  |  | 
            
  
    | 377 | 0 | int ownerVersion = 0; | 
            
  
    | 378 | 0 | int ownerSequence = 0; | 
            
  
    | 379 | 0 | byte[] ownerPrimaryMacAddress = null; | 
            
  
    | 380 | 0 | byte[] ownerWakeupMacAddress = null; | 
            
  
    | 381 | 0 | byte[] ownerPassword = null; | 
            
  
    | 382 | 0 | try { | 
            
  
    | 383 | 0 | ownerVersion = optiondata[0]; | 
            
  
    | 384 | 0 | ownerSequence = optiondata[1]; | 
            
  
    | 385 | 0 | ownerPrimaryMacAddress = new byte[] { optiondata[2], optiondata[3], optiondata[4], optiondata[5], optiondata[6], optiondata[7] }; | 
            
  
    | 386 | 0 | ownerWakeupMacAddress = ownerPrimaryMacAddress; | 
            
  
    | 387 | 0 | if (optiondata.length > 8) { | 
            
  
    | 388 |  |  | 
            
  
    | 389 | 0 | ownerWakeupMacAddress = new byte[] { optiondata[8], optiondata[9], optiondata[10], optiondata[11], optiondata[12], optiondata[13] }; | 
            
  
    | 390 |  | } | 
            
  
    | 391 | 0 | if (optiondata.length == 18) { | 
            
  
    | 392 |  |  | 
            
  
    | 393 | 0 | ownerPassword = new byte[] { optiondata[14], optiondata[15], optiondata[16], optiondata[17] }; | 
            
  
    | 394 |  | } | 
            
  
    | 395 | 0 | if (optiondata.length == 22) { | 
            
  
    | 396 |  |  | 
            
  
    | 397 | 0 | ownerPassword = new byte[] { optiondata[14], optiondata[15], optiondata[16], optiondata[17], optiondata[18], optiondata[19], optiondata[20], optiondata[21] }; | 
            
  
    | 398 |  | } | 
            
  
    | 399 |  | } catch (Exception exception) { | 
            
  
    | 400 | 0 | logger.warning("Malformed OPT answer. Option code: Owner data: " + this._hexString(optiondata)); | 
            
  
    | 401 |  | } | 
            
  
    | 402 | 0 | if (logger.isLoggable(Level.FINE)) { | 
            
  
    | 403 | 0 | logger.fine("Unhandled Owner OPT version: " + ownerVersion + " sequence: " + ownerSequence + " MAC address: " + this._hexString(ownerPrimaryMacAddress) | 
            
  
    | 404 | 0 | + (ownerWakeupMacAddress != ownerPrimaryMacAddress ? " wakeup MAC address: " + this._hexString(ownerWakeupMacAddress) : "") + (ownerPassword != null ? " password: " + this._hexString(ownerPassword) : "")); | 
            
  
    | 405 |  | } | 
            
  
    | 406 | 0 | break; | 
            
  
    | 407 | 0 | case LLQ: | 
            
  
    | 408 | 0 | case NSID: | 
            
  
    | 409 | 0 | case UL: | 
            
  
    | 410 | 0 | if (logger.isLoggable(Level.FINE)) { | 
            
  
    | 411 | 0 | logger.log(Level.FINE, "There was an OPT answer. Option code: " + optionCode + " data: " + this._hexString(optiondata)); | 
            
  
    | 412 |  | } | 
            
  
    | 413 | 0 | break; | 
            
  
    | 414 | 0 | case Unknown: | 
            
  
    | 415 | 0 | logger.log(Level.WARNING, "There was an OPT answer. Not currently handled. Option code: " + optionCodeInt + " data: " + this._hexString(optiondata)); | 
            
  
    | 416 | 0 | break; | 
            
  
    | 417 | 0 | default: | 
            
  
    | 418 |  |  | 
            
  
    | 419 | 0 | break; | 
            
  
    | 420 |  | } | 
            
  
    | 421 |  | } | 
            
  
    | 422 |  | } else { | 
            
  
    | 423 | 0 | logger.log(Level.WARNING, "There was an OPT answer. Wrong version number: " + version + " result code: " + extendedResultCode); | 
            
  
    | 424 |  | } | 
            
  
    | 425 | 0 | break; | 
            
  
    | 426 | 118 | default: | 
            
  
    | 427 | 118 | if (logger.isLoggable(Level.FINER)) { | 
            
  
    | 428 | 0 | logger.finer("DNSIncoming() unknown type:" + type); | 
            
  
    | 429 |  | } | 
            
  
    | 430 | 117 | _messageInputStream.skip(len); | 
            
  
    | 431 | 116 | break; | 
            
  
    | 432 |  | } | 
            
  
    | 433 | 1059 | if (rec != null) { | 
            
  
    | 434 | 952 | rec.setRecordSource(source); | 
            
  
    | 435 |  | } | 
            
  
    | 436 | 1050 | return rec; | 
            
  
    | 437 |  | } | 
            
  
    | 438 |  |  | 
            
  
    | 439 |  |  | 
            
  
    | 440 |  |  | 
            
  
    | 441 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 9 (9) | Complexity: 2 | Complexity Density: 0.29 |  | 
  
  
    | 442 | 0 |  String print(boolean dump) {... | 
            
  
    | 443 | 0 | StringBuilder buf = new StringBuilder(); | 
            
  
    | 444 | 0 | buf.append(this.print()); | 
            
  
    | 445 | 0 | if (dump) { | 
            
  
    | 446 | 0 | byte[] data = new byte[_packet.getLength()]; | 
            
  
    | 447 | 0 | System.arraycopy(_packet.getData(), 0, data, 0, data.length); | 
            
  
    | 448 | 0 | buf.append(this.print(data)); | 
            
  
    | 449 |  | } | 
            
  
    | 450 | 0 | return buf.toString(); | 
            
  
    | 451 |  | } | 
            
  
    | 452 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 81 (81) | Complexity: 15 | Complexity Density: 0.28 |  | 
  
  
    | 453 | 0 |  @Override... | 
            
  
    | 454 |  | public String toString() { | 
            
  
    | 455 | 0 | StringBuilder buf = new StringBuilder(); | 
            
  
    | 456 | 0 | buf.append(isQuery() ? "dns[query," : "dns[response,"); | 
            
  
    | 457 | 0 | if (_packet.getAddress() != null) { | 
            
  
    | 458 | 0 | buf.append(_packet.getAddress().getHostAddress()); | 
            
  
    | 459 |  | } | 
            
  
    | 460 | 0 | buf.append(':'); | 
            
  
    | 461 | 0 | buf.append(_packet.getPort()); | 
            
  
    | 462 | 0 | buf.append(", length="); | 
            
  
    | 463 | 0 | buf.append(_packet.getLength()); | 
            
  
    | 464 | 0 | buf.append(", id=0x"); | 
            
  
    | 465 | 0 | buf.append(Integer.toHexString(this.getId())); | 
            
  
    | 466 | 0 | if (this.getFlags() != 0) { | 
            
  
    | 467 | 0 | buf.append(", flags=0x"); | 
            
  
    | 468 | 0 | buf.append(Integer.toHexString(this.getFlags())); | 
            
  
    | 469 | 0 | if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) { | 
            
  
    | 470 | 0 | buf.append(":r"); | 
            
  
    | 471 |  | } | 
            
  
    | 472 | 0 | if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) { | 
            
  
    | 473 | 0 | buf.append(":aa"); | 
            
  
    | 474 |  | } | 
            
  
    | 475 | 0 | if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) { | 
            
  
    | 476 | 0 | buf.append(":tc"); | 
            
  
    | 477 |  | } | 
            
  
    | 478 |  | } | 
            
  
    | 479 | 0 | if (this.getNumberOfQuestions() > 0) { | 
            
  
    | 480 | 0 | buf.append(", questions="); | 
            
  
    | 481 | 0 | buf.append(this.getNumberOfQuestions()); | 
            
  
    | 482 |  | } | 
            
  
    | 483 | 0 | if (this.getNumberOfAnswers() > 0) { | 
            
  
    | 484 | 0 | buf.append(", answers="); | 
            
  
    | 485 | 0 | buf.append(this.getNumberOfAnswers()); | 
            
  
    | 486 |  | } | 
            
  
    | 487 | 0 | if (this.getNumberOfAuthorities() > 0) { | 
            
  
    | 488 | 0 | buf.append(", authorities="); | 
            
  
    | 489 | 0 | buf.append(this.getNumberOfAuthorities()); | 
            
  
    | 490 |  | } | 
            
  
    | 491 | 0 | if (this.getNumberOfAdditionals() > 0) { | 
            
  
    | 492 | 0 | buf.append(", additionals="); | 
            
  
    | 493 | 0 | buf.append(this.getNumberOfAdditionals()); | 
            
  
    | 494 |  | } | 
            
  
    | 495 | 0 | if (this.getNumberOfQuestions() > 0) { | 
            
  
    | 496 | 0 | buf.append("\nquestions:"); | 
            
  
    | 497 | 0 | for (DNSQuestion question : _questions) { | 
            
  
    | 498 | 0 | buf.append("\n\t"); | 
            
  
    | 499 | 0 | buf.append(question); | 
            
  
    | 500 |  | } | 
            
  
    | 501 |  | } | 
            
  
    | 502 | 0 | if (this.getNumberOfAnswers() > 0) { | 
            
  
    | 503 | 0 | buf.append("\nanswers:"); | 
            
  
    | 504 | 0 | for (DNSRecord record : _answers) { | 
            
  
    | 505 | 0 | buf.append("\n\t"); | 
            
  
    | 506 | 0 | buf.append(record); | 
            
  
    | 507 |  | } | 
            
  
    | 508 |  | } | 
            
  
    | 509 | 0 | if (this.getNumberOfAuthorities() > 0) { | 
            
  
    | 510 | 0 | buf.append("\nauthorities:"); | 
            
  
    | 511 | 0 | for (DNSRecord record : _authoritativeAnswers) { | 
            
  
    | 512 | 0 | buf.append("\n\t"); | 
            
  
    | 513 | 0 | buf.append(record); | 
            
  
    | 514 |  | } | 
            
  
    | 515 |  | } | 
            
  
    | 516 | 0 | if (this.getNumberOfAdditionals() > 0) { | 
            
  
    | 517 | 0 | buf.append("\nadditionals:"); | 
            
  
    | 518 | 0 | for (DNSRecord record : _additionals) { | 
            
  
    | 519 | 0 | buf.append("\n\t"); | 
            
  
    | 520 | 0 | buf.append(record); | 
            
  
    | 521 |  | } | 
            
  
    | 522 |  | } | 
            
  
    | 523 | 0 | buf.append("]"); | 
            
  
    | 524 | 0 | return buf.toString(); | 
            
  
    | 525 |  | } | 
            
  
    | 526 |  |  | 
            
  
    | 527 |  |  | 
            
  
    | 528 |  |  | 
            
  
    | 529 |  |  | 
            
  
    | 530 |  | @exception | 
            
  
    | 531 |  |  | 
            
  
    | 532 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 8 (8) | Complexity: 4 | Complexity Density: 0.67 |  | 
  
  
    | 533 | 0 |  void append(DNSIncoming that) {... | 
            
  
    | 534 | 0 | if (this.isQuery() && this.isTruncated() && that.isQuery()) { | 
            
  
    | 535 | 0 | this._questions.addAll(that.getQuestions()); | 
            
  
    | 536 | 0 | this._answers.addAll(that.getAnswers()); | 
            
  
    | 537 | 0 | this._authoritativeAnswers.addAll(that.getAuthorities()); | 
            
  
    | 538 | 0 | this._additionals.addAll(that.getAdditionals()); | 
            
  
    | 539 |  | } else { | 
            
  
    | 540 | 0 | throw new IllegalArgumentException(); | 
            
  
    | 541 |  | } | 
            
  
    | 542 |  | } | 
            
  
    | 543 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 544 | 158 |  public int elapseSinceArrival() {... | 
            
  
    | 545 | 161 | return (int) (System.currentTimeMillis() - _receivedTime); | 
            
  
    | 546 |  | } | 
            
  
    | 547 |  |  | 
            
  
    | 548 |  |  | 
            
  
    | 549 |  |  | 
            
  
    | 550 |  |  | 
            
  
    | 551 |  | @return | 
            
  
    | 552 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 553 | 33 |  public int getSenderUDPPayload() {... | 
            
  
    | 554 | 33 | return this._senderUDPPayload; | 
            
  
    | 555 |  | } | 
            
  
    | 556 |  |  | 
            
  
    | 557 |  | private static final char[] _nibbleToHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; | 
            
  
    | 558 |  |  | 
            
  
    | 559 |  |  | 
            
  
    | 560 |  |  | 
            
  
    | 561 |  |  | 
            
  
    | 562 |  | @param | 
            
  
    | 563 |  | @return | 
            
  
    | 564 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 8 (8) | Complexity: 2 | Complexity Density: 0.33 |  | 
  
  
    | 565 | 0 |  private String _hexString(byte[] bytes) {... | 
            
  
    | 566 |  |  | 
            
  
    | 567 | 0 | StringBuilder result = new StringBuilder(2 * bytes.length); | 
            
  
    | 568 |  |  | 
            
  
    | 569 | 0 | for (int i = 0; i < bytes.length; i++) { | 
            
  
    | 570 | 0 | int b = bytes[i] & 0xFF; | 
            
  
    | 571 | 0 | result.append(_nibbleToHex[b / 16]); | 
            
  
    | 572 | 0 | result.append(_nibbleToHex[b % 16]); | 
            
  
    | 573 |  | } | 
            
  
    | 574 |  |  | 
            
  
    | 575 | 0 | return result.toString(); | 
            
  
    | 576 |  | } | 
            
  
    | 577 |  |  | 
            
  
    | 578 |  | } |