001/* 002 * Copyright 2015-2024 the original author or authors 003 * 004 * This software is licensed under the Apache License, Version 2.0, 005 * the GNU Lesser General Public License version 2 or later ("LGPL") 006 * and the WTFPL. 007 * You may choose either license to govern your use of this software only 008 * upon the condition that you accept all of the terms of either 009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 010 */ 011package org.minidns.edns; 012 013import java.io.DataOutputStream; 014import java.io.IOException; 015 016import org.minidns.edns.Edns.OptionCode; 017 018public abstract class EdnsOption { 019 020 public final int optionCode; 021 public final int optionLength; 022 023 protected final byte[] optionData; 024 025 protected EdnsOption(int optionCode, byte[] optionData) { 026 this.optionCode = optionCode; 027 this.optionLength = optionData.length; 028 this.optionData = optionData; 029 } 030 031 @SuppressWarnings("this-escape") 032 protected EdnsOption(byte[] optionData) { 033 this.optionCode = getOptionCode().asInt; 034 this.optionLength = optionData.length; 035 this.optionData = optionData; 036 } 037 038 public final void writeToDos(DataOutputStream dos) throws IOException { 039 dos.writeShort(optionCode); 040 dos.writeShort(optionLength); 041 dos.write(optionData); 042 } 043 044 public abstract OptionCode getOptionCode(); 045 046 private String toStringCache; 047 048 @Override 049 public final String toString() { 050 if (toStringCache == null) { 051 toStringCache = toStringInternal().toString(); 052 } 053 return toStringCache; 054 } 055 056 protected abstract CharSequence toStringInternal(); 057 058 private String terminalOutputCache; 059 060 public final String asTerminalOutput() { 061 if (terminalOutputCache == null) { 062 terminalOutputCache = asTerminalOutputInternal().toString(); 063 } 064 return terminalOutputCache; 065 } 066 067 protected abstract CharSequence asTerminalOutputInternal(); 068 069 public static EdnsOption parse(int intOptionCode, byte[] optionData) { 070 OptionCode optionCode = OptionCode.from(intOptionCode); 071 EdnsOption res; 072 switch (optionCode) { 073 case NSID: 074 res = new Nsid(optionData); 075 break; 076 default: 077 res = new UnknownEdnsOption(intOptionCode, optionData); 078 break; 079 } 080 return res; 081 } 082 083}