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}