public int parseSection(int off, byte qtype, int sectiontype, int rrcnt, java.net.InetSocketAddress remote_addr, MessageCallback handler)
	{
		boolean skip = false;
		for (int idx = 0; idx != rrcnt; idx++) {
			// This initial NAME field will be overwritten by parseRDATA() below in most circumstances, but since we
			// don't yet know rrtype, we can't tell at this stage and it's not really worth calling decodeName() with
			// a null buffer and then going back to this offset to repeat it if needed.
			if (off > msglmt) return -1;
			if (skip) return skipSection(off, sectiontype, rrcnt - idx);
			rr_name.ar_len = 0;
			off = decodeName(off, rr_name);
			byte rrtype = (byte)decodeInt(off, FLDSIZ_RRTYPE);
			off += FLDSIZ_RRTYPE;
			byte rrclass = (byte)decodeInt(off, FLDSIZ_RRCLASS);
			off += FLDSIZ_RRCLASS;

			if (sectiontype == SECT_QUESTIONS) {
				if (handler != null && !handler.handleMessageQuestion(hdr_qid, idx, rrcnt, rrtype, rrclass, rr_name, remote_addr)) return -1;
			} else {
				int ttl = decodeInt(off, FLDSIZ_RRTTL);
				off += FLDSIZ_RRTTL;
				int rrlen = decodeInt(off, FLDSIZ_RRLEN);
				off += FLDSIZ_RRLEN;
				ResourceData rr = parseRDATA(off, qtype, rrlen, rrtype, rrclass, ttl, handler);
				if (rr != null && handler != null) skip = handler.handleMessageRR(hdr_qid, sectiontype, idx, rrcnt, rr_name, rr, remote_addr);
				off += rrlen;
			}
		}
		if (off > msglmt) return -1;
		return off;
	}