Esempio n. 1
0
ptr<mxlist>
dnsparse::tomxlist ()
{
  const u_char *cp = getanp ();
  nameset nset;
  str name;
  char *nameptr = NULL;

  if (!cp)
    return NULL;

  vec<mxrec> mxes;
  for (u_int i = 0; i < ancount; i++) {
    resrec rr;
    if (!rrparse (&cp, &rr)) {
      error = ARERR_BADRESP;
      return NULL;
    }
    if (rr.rr_class == C_IN && rr.rr_type == T_MX) {
      u_int16_t pr = rr.rr_mx.mx_pref;

      if (!name) {
	name = rr.rr_name;
	nameptr = nset.store (name);
      }
      else if (strcasecmp (name, rr.rr_name))
	continue;

      char *xp = nset.store (rr.rr_mx.mx_exch);
      mxrec *mp;
      for (mp = mxes.base (); mp < mxes.lim () && mp->name != xp; mp++)
	;
      if (mp < mxes.lim ()) {
	if (pr < mp->pref)
	  mp->pref = pr;
      }
      else {
	mxes.push_back ().pref = pr;
	mxes.back ().name = xp;
      }
    }
  }
  if (mxes.empty ()) {
    error = ARERR_NXREC;
    return NULL;
  }

  vec<addrhint> hints;
  if (!gethints (&hints, nset))
    return NULL;

  ref <mxlist> mxl = refcounted<mxlist, vsize>::alloc
    (xoffsetof (mxlist, m_mxes[mxes.size ()])
     + hintsize (hints.size ()) + nset.size ());
  char *hintp = reinterpret_cast<char *> (&mxl->m_mxes[mxes.size ()]);
  char *namebase = hintp + hintsize (hints.size ());
  nset.put (namebase);
  mxl->m_name = nset.xlat (namebase, nameptr);
  mxl->m_hints = puthints (hintp, hints, namebase);
  mxl->m_nmx = mxes.size ();
  for (u_int i = 0; i < mxl->m_nmx; i++) {
    mxl->m_mxes[i].pref = mxes[i].pref;
    mxl->m_mxes[i].name = nset.xlat (namebase, mxes[i].name);
  }
  if (mxl->m_nmx > 1)
    qsort (mxl->m_mxes, mxl->m_nmx, sizeof (mxrec), mxrec_cmp);

  return mxl;
}
Esempio n. 2
0
ptr<srvlist>
dnsparse::tosrvlist ()
{
  const u_char *cp = getanp ();
  nameset nset;
  str name;
  char *nameptr = NULL;

  if (!cp)
    return NULL;

  vec<srvrec> recs;
  for (u_int i = 0; i < ancount; i++) {
    resrec rr;
    if (!rrparse (&cp, &rr)) {
      error = ARERR_BADRESP;
      return NULL;
    }
    if (rr.rr_class != C_IN || rr.rr_type != T_SRV)
      continue;
    if (!name) {
      name = rr.rr_name;
      nameptr = nset.store (name);
    }
    else if (strcasecmp (name, rr.rr_name))
      continue;

    char *tp = nset.store (rr.rr_srv.srv_target);
    for (int i = recs.size (); i-- > 0;)
      if (recs[i].prio == rr.rr_srv.srv_prio
	  && recs[i].port == rr.rr_srv.srv_port
	  && tp == recs[i].name) {
	rr.rr_srv.srv_weight += recs[i].weight;
	continue;
      }

    srvrec &sr = recs.push_back ();
    sr.prio = rr.rr_srv.srv_prio;
    sr.weight = rr.rr_srv.srv_weight;
    sr.port = rr.rr_srv.srv_port;
    sr.name = tp;
  }

  if (!name) {
    error = ARERR_NXREC;
    return NULL;
  }

  vec<addrhint> hints;
  if (!gethints (&hints, nset))
    return NULL;

  srvrec_randomize (recs.base (), recs.lim ());

  ref<srvlist> s = refcounted<srvlist, vsize>::alloc
    (xoffsetof (srvlist, s_srvs[recs.size ()])
     + hintsize (hints.size ()) + nset.size ());

  char *hintp = reinterpret_cast<char *> (&s->s_srvs[recs.size ()]);
  char *namebase = hintp + hintsize (hints.size ());
  nset.put (namebase);
  s->s_name = nset.xlat (namebase, nameptr);
  s->s_hints = puthints (hintp, hints, namebase);
  s->s_nsrv = recs.size ();

  for (u_int i = 0; i < s->s_nsrv; i++) {
    s->s_srvs[i] = recs[i];
    s->s_srvs[i].name = nset.xlat (namebase, s->s_srvs[i].name);
  }
  
  return s;
}
Esempio n. 3
0
static int str2vdpnl(char *argvalue, struct vdpnl_vsi *vsi)
{
	int rc = -ENOMEM;
	unsigned int no;
	unsigned short idx;
	char *cmdstring, *token;

	cmdstring = strdup(argvalue);
	if (!cmdstring)
		goto out_free;
	rc = -EINVAL;
	/* 1st field is VSI command */
	token = strtok(cmdstring, ",");
	if (!token || !getmode(vsi, token))
		goto out_free;

	/* 2nd field is VSI Manager Identifer (16 bytes maximum) */
	token = strtok(NULL, ",");
	if (!token || !getmgr2id(vsi, token))
		goto out_free;

	/* 3rd field is type identifier */
	token = strtok(NULL, ",");
	if (!token || !getnumber(token, 0, 0xffffff, &no))
		goto out_free;
	vsi->vsi_typeid = no;

	/* 4th field is type version identifier */
	token = strtok(NULL, ",");
	if (!token || !getnumber(token, 0, 0xff, &no))
		goto out_free;
	vsi->vsi_typeversion = no;

	/* 5th field is filter VSI UUID */
	token = strtok(NULL, ",");
	if (!token || vdp_str2uuid(vsi->vsi_uuid, token, sizeof(vsi->vsi_uuid)))
		goto out_free;
	vsi->vsi_idfmt = VDP22_ID_UUID;

	/* 6th field is migration hints */
	token = strtok(NULL, ",");
	if (!token || !gethints(vsi, token))
		goto out_free;

	/*
	 * 7th and remaining fields are filter information format data.
	 * All fields must have the same format. The first fid field determines
	 * the format.
	 */
	for (idx = 0, token = strtok(NULL, ","); token != NULL;
					++idx, token = strtok(NULL, ",")) {
		if (idx < vsi->macsz && !getfid(vsi, token, idx))
			goto out_free;
	}

	/* Return error if no filter information provided */
	if (idx)
		rc = 0;
out_free:
	free(cmdstring);
	return rc;
}