001/* 002 * Copyright 2015-2020 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 protected EdnsOption(byte[] optionData) { 032 this.optionCode = getOptionCode().asInt; 033 this.optionLength = optionData.length; 034 this.optionData = optionData; 035 } 036 037 public final void writeToDos(DataOutputStream dos) throws IOException { 038 dos.writeShort(optionCode); 039 dos.writeShort(optionLength); 040 dos.write(optionData); 041 } 042 043 public abstract OptionCode getOptionCode(); 044 045 private String toStringCache; 046 047 @Override 048 public final String toString() { 049 if (toStringCache == null) { 050 toStringCache = toStringInternal().toString(); 051 } 052 return toStringCache; 053 } 054 055 protected abstract CharSequence toStringInternal(); 056 057 private String terminalOutputCache; 058 059 public final String asTerminalOutput() { 060 if (terminalOutputCache == null) { 061 terminalOutputCache = asTerminalOutputInternal().toString(); 062 } 063 return terminalOutputCache; 064 } 065 066 protected abstract CharSequence asTerminalOutputInternal(); 067 068 public static EdnsOption parse(int intOptionCode, byte[] optionData) { 069 OptionCode optionCode = OptionCode.from(intOptionCode); 070 EdnsOption res; 071 switch (optionCode) { 072 case NSID: 073 res = new Nsid(optionData); 074 break; 075 default: 076 res = new UnknownEdnsOption(intOptionCode, optionData); 077 break; 078 } 079 return res; 080 } 081 082}