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.record; 012 013import org.minidns.edns.EdnsOption; 014import org.minidns.record.Record.TYPE; 015 016import java.io.DataInputStream; 017import java.io.DataOutputStream; 018import java.io.IOException; 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.List; 022 023/** 024 * OPT payload (see RFC 2671 for details). 025 */ 026public class OPT extends Data { 027 028 public final List<EdnsOption> variablePart; 029 030 public OPT() { 031 this(Collections.<EdnsOption>emptyList()); 032 } 033 034 public OPT(List<EdnsOption> variablePart) { 035 this.variablePart = Collections.unmodifiableList(variablePart); 036 } 037 038 public static OPT parse(DataInputStream dis, int payloadLength) throws IOException { 039 List<EdnsOption> variablePart; 040 if (payloadLength == 0) { 041 variablePart = Collections.emptyList(); 042 } else { 043 int payloadLeft = payloadLength; 044 variablePart = new ArrayList<>(4); 045 while (payloadLeft > 0) { 046 int optionCode = dis.readUnsignedShort(); 047 int optionLength = dis.readUnsignedShort(); 048 byte[] optionData = new byte[optionLength]; 049 dis.read(optionData); 050 EdnsOption ednsOption = EdnsOption.parse(optionCode, optionData); 051 variablePart.add(ednsOption); 052 payloadLeft -= 2 + 2 + optionLength; 053 // Assert that payloadLeft never becomes negative 054 assert payloadLeft >= 0; 055 } 056 } 057 return new OPT(variablePart); 058 } 059 060 @Override 061 public TYPE getType() { 062 return TYPE.OPT; 063 } 064 065 @Override 066 protected void serialize(DataOutputStream dos) throws IOException { 067 for (EdnsOption endsOption : variablePart) { 068 endsOption.writeToDos(dos); 069 } 070 } 071 072}