1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.connectivity.mdns; 18 19 import android.annotation.Nullable; 20 21 import com.android.net.module.util.DnsUtils; 22 23 import java.io.IOException; 24 import java.util.Arrays; 25 26 /** An mDNS "PTR" record, which holds a name (the "pointer"). */ 27 public class MdnsPointerRecord extends MdnsRecord { 28 private String[] pointer; 29 MdnsPointerRecord(String[] name, MdnsPacketReader reader)30 public MdnsPointerRecord(String[] name, MdnsPacketReader reader) throws IOException { 31 this(name, reader, false); 32 } 33 MdnsPointerRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)34 public MdnsPointerRecord(String[] name, MdnsPacketReader reader, boolean isQuestion) 35 throws IOException { 36 super(name, TYPE_PTR, reader, isQuestion); 37 } 38 MdnsPointerRecord(String[] name, boolean isUnicast)39 public MdnsPointerRecord(String[] name, boolean isUnicast) { 40 super(name, TYPE_PTR, 41 MdnsConstants.QCLASS_INTERNET | (isUnicast ? MdnsConstants.QCLASS_UNICAST : 0), 42 0L /* receiptTimeMillis */, false /* cacheFlush */, 0L /* ttlMillis */); 43 } 44 MdnsPointerRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis, String[] pointer)45 public MdnsPointerRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, 46 long ttlMillis, String[] pointer) { 47 super(name, TYPE_PTR, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush, 48 ttlMillis); 49 this.pointer = pointer; 50 } 51 52 /** Returns the pointer as an array of labels. */ getPointer()53 public String[] getPointer() { 54 return pointer; 55 } 56 57 @Override readData(MdnsPacketReader reader)58 protected void readData(MdnsPacketReader reader) throws IOException { 59 pointer = reader.readLabels(); 60 } 61 62 @Override writeData(MdnsPacketWriter writer)63 protected void writeData(MdnsPacketWriter writer) throws IOException { 64 writer.writeLabels(pointer); 65 } 66 hasSubtype()67 public boolean hasSubtype() { 68 return (name != null) && (name.length > 2) && DnsUtils.equalsIgnoreDnsCase(name[1], 69 MdnsConstants.SUBTYPE_LABEL); 70 } 71 getSubtype()72 public String getSubtype() { 73 return hasSubtype() ? name[0] : null; 74 } 75 76 @Override toString()77 public String toString() { 78 return "PTR: " + labelsToString(name) + " -> " + labelsToString(pointer); 79 } 80 81 @Override hashCode()82 public int hashCode() { 83 return (super.hashCode() * 31) + Arrays.hashCode(DnsUtils.toDnsLabelsUpperCase(pointer)); 84 } 85 86 @Override equals(@ullable Object other)87 public boolean equals(@Nullable Object other) { 88 if (this == other) { 89 return true; 90 } 91 if (!(other instanceof MdnsPointerRecord)) { 92 return false; 93 } 94 95 return super.equals(other) && DnsUtils.equalsDnsLabelIgnoreDnsCase(pointer, 96 ((MdnsPointerRecord) other).pointer); 97 } 98 }