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; }
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; }
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; }