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.record; 012 013import org.minidns.dnsname.DnsName; 014import org.minidns.record.Record.TYPE; 015 016import java.io.DataInputStream; 017import java.io.DataOutputStream; 018import java.io.IOException; 019 020/** 021 * SOA (start of authority) record payload. 022 */ 023public class SOA extends Data { 024 025 /** 026 * The domain name of the name server that was the original or primary source of data for this zone. 027 */ 028 public final DnsName mname; 029 030 /** 031 * A domain name which specifies the mailbox of the person responsible for this zone. 032 */ 033 public final DnsName rname; 034 035 /** 036 * The unsigned 32 bit version number of the original copy of the zone. Zone transfers preserve this value. This 037 * value wraps and should be compared using sequence space arithmetic. 038 */ 039 public final long /* unsigned int */ serial; 040 041 /** 042 * A 32 bit time interval before the zone should be refreshed. 043 */ 044 public final int refresh; 045 046 /** 047 * A 32 bit time interval that should elapse before a failed refresh should be retried. 048 */ 049 public final int retry; 050 051 /** 052 * A 32 bit time value that specifies the upper limit on the time interval that can elapse before the zone is no 053 * longer authoritative. 054 */ 055 public final int expire; 056 057 /** 058 * The unsigned 32 bit minimum TTL field that should be exported with any RR from this zone. 059 */ 060 public final long /* unsigned int */ minimum; 061 062 public static SOA parse(DataInputStream dis, byte[] data) 063 throws IOException { 064 DnsName mname = DnsName.parse(dis, data); 065 DnsName rname = DnsName.parse(dis, data); 066 long serial = dis.readInt() & 0xFFFFFFFFL; 067 int refresh = dis.readInt(); 068 int retry = dis.readInt(); 069 int expire = dis.readInt(); 070 long minimum = dis.readInt() & 0xFFFFFFFFL; 071 return new SOA(mname, rname, serial, refresh, retry, expire, minimum); 072 } 073 074 public SOA(String mname, String rname, long serial, int refresh, int retry, int expire, long minimum) { 075 this(DnsName.from(mname), DnsName.from(rname), serial, refresh, retry, expire, minimum); 076 } 077 078 public SOA(DnsName mname, DnsName rname, long serial, int refresh, int retry, int expire, long minimum) { 079 this.mname = mname; 080 this.rname = rname; 081 this.serial = serial; 082 this.refresh = refresh; 083 this.retry = retry; 084 this.expire = expire; 085 this.minimum = minimum; 086 } 087 088 @Override 089 public TYPE getType() { 090 return TYPE.SOA; 091 } 092 093 @Override 094 public void serialize(DataOutputStream dos) throws IOException { 095 mname.writeToStream(dos); 096 rname.writeToStream(dos); 097 dos.writeInt((int) serial); 098 dos.writeInt(refresh); 099 dos.writeInt(retry); 100 dos.writeInt(expire); 101 dos.writeInt((int) minimum); 102 } 103 104 @Override 105 public String toString() { 106 StringBuilder sb = new StringBuilder() 107 .append(mname).append(". ") 108 .append(rname).append(". ") 109 .append(serial).append(' ') 110 .append(refresh).append(' ') 111 .append(retry).append(' ') 112 .append(expire).append(' ') 113 .append(minimum); 114 return sb.toString(); 115 } 116}