Пример #1
0
  /**
   * Adds all data from a Message into the Cache. Each record is added with the appropriate
   * credibility, and negative answers are cached as such.
   *
   * @param in The Message to be added
   * @see Message
   */
  public void addMessage(Message in) {
    boolean isAuth = in.getHeader().getFlag(Flags.AA);
    Name qname = in.getQuestion().getName();
    Name curname = qname;
    short qtype = in.getQuestion().getType();
    short qclass = in.getQuestion().getDClass();
    byte cred;
    short rcode = in.getHeader().getRcode();
    boolean haveAnswer = false;
    boolean completed = false;
    boolean restart = false;
    RRset[] answers, auth, addl;

    if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) return;

    if (secure) {
      Cache c = new Cache(dclass);
      c.addMessage(in);
      verifyRecords(c);
      return;
    }

    answers = in.getSectionRRsets(Section.ANSWER);
    for (int i = 0; i < answers.length; i++) {
      if (answers[i].getDClass() != qclass) continue;
      short type = answers[i].getType();
      Name name = answers[i].getName();
      cred = getCred(Section.ANSWER, isAuth);
      if (type == Type.CNAME && name.equals(curname)) {
        CNAMERecord cname;
        addRRset(answers[i], cred);
        cname = (CNAMERecord) answers[i].first();
        curname = cname.getTarget();
        restart = true;
        haveAnswer = true;
      } else if (type == Type.DNAME && curname.subdomain(name)) {
        DNAMERecord dname;
        addRRset(answers[i], cred);
        dname = (DNAMERecord) answers[i].first();
        try {
          curname = curname.fromDNAME(dname);
        } catch (NameTooLongException e) {
          break;
        }
        restart = true;
        haveAnswer = true;
      } else if ((type == qtype || qtype == Type.ANY) && name.equals(curname)) {
        addRRset(answers[i], cred);
        completed = true;
        haveAnswer = true;
      }
      if (restart) {
        restart = false;
        i = 0;
      }
    }

    auth = in.getSectionRRsets(Section.AUTHORITY);
    if (!completed) {
      /* This is a negative response or a referral. */
      RRset soa = null, ns = null;
      for (int i = 0; i < auth.length; i++) {
        if (auth[i].getType() == Type.SOA && curname.subdomain(auth[i].getName())) soa = auth[i];
        else if (auth[i].getType() == Type.NS && curname.subdomain(auth[i].getName())) ns = auth[i];
      }
      short cachetype = (rcode == Rcode.NXDOMAIN) ? (short) 0 : qtype;
      if (soa != null || ns == null) {
        /* Negative response */
        cred = getCred(Section.AUTHORITY, isAuth);
        SOARecord soarec = null;
        if (soa != null) soarec = (SOARecord) soa.first();
        addNegative(curname, cachetype, soarec, cred);
        /* NXT records are not cached yet. */
      } else {
        /* Referral response */
        cred = getCred(Section.AUTHORITY, isAuth);
        addRRset(ns, cred);
      }
    }

    addl = in.getSectionRRsets(Section.ADDITIONAL);
    for (int i = 0; i < addl.length; i++) {
      short type = addl[i].getType();
      if (type != Type.A && type != Type.AAAA && type != Type.A6) continue;
      /* XXX check the name */
      Name name = addl[i].getName();
      cred = getCred(Section.ADDITIONAL, isAuth);
      addRRset(addl[i], cred);
    }
  }
Пример #2
0
  public static Record[] getRecords(String namestr, short type, short dclass, byte cred) {
    Message query;
    Message response;
    Record question;
    Record[] answers;
    int answerCount = 0, i = 0;
    Enumeration e;
    Name name = new Name(namestr);

    /*System.out.println("lookup of " + name + " " + Type.string(type));*/
    if (!Type.isRR(type) && type != Type.ANY) return null;

    if (res == null) {
      try {
        eres = new ExtendedResolver();
      } catch (UnknownHostException uhe) {
        System.out.println("Failed to initialize resolver");
        System.exit(-1);
      }
    }
    if (cache == null) cache = new Cache();

    CacheResponse cached = cache.lookupRecords(name, type, dclass, cred);
    /*System.out.println(cached);*/
    if (cached.isSuccessful()) {
      RRset rrset = cached.answer();
      answerCount = rrset.size();
      e = rrset.rrs();
    } else if (cached.isNegative()) {
      answerCount = 0;
      e = null;
    } else {
      question = Record.newRecord(name, type, dclass);
      query = Message.newQuery(question);

      if (res != null) response = res.send(query);
      else response = eres.send(query);

      short rcode = response.getHeader().getRcode();
      if (rcode == Rcode.NOERROR || rcode == Rcode.NXDOMAIN) cache.addMessage(response);

      if (rcode != Rcode.NOERROR) return null;

      e = response.getSection(Section.ANSWER);
      while (e.hasMoreElements()) {
        Record r = (Record) e.nextElement();
        if (matchType(r.getType(), type)) answerCount++;
      }

      e = response.getSection(Section.ANSWER);
    }

    if (answerCount == 0) return null;

    answers = new Record[answerCount];

    while (e.hasMoreElements()) {
      Record r = (Record) e.nextElement();
      if (matchType(r.getType(), type)) answers[i++] = r;
    }

    return answers;
  }