예제 #1
0
파일: author.c 프로젝트: cofyc/dnspod-sr
//databuffer format
//type.mvalue.data.type.mvalue.data...
int
// write_back_to_client(uchar * td, enum rrtype otype, uint8_t level, ushort id, int dlen,
write_back_to_client(mbuf_type *mbuf, uchar * fr, int vlen)
{
    struct setheader sh = { 0 };        //data in dns header
    int main_val = 0, dnslen = 0;
    uchar *msg = mbuf->buf, type;      //if bigger, use TCP
    uchar *from = fr, *to = msg;
    struct mvalue *mv = NULL;
    int jump = 0;
    uint16_t temp = 0;
    struct hlpc hlp[100];       //p domians to compression
    hlp[0].name = mbuf->td;
    hlp[0].off = sizeof(dnsheader);
    hlp[0].level = mbuf->lowerdomain.label_count;
    hlp[0].ref = -1;
    hlp[0].mt = 0;
    hlp[0].len = mbuf->dlen;
    if (mbuf->dlen == 2) // root
        jump = sizeof(dnsheader) + 1 + sizeof(qdns);
    else
        jump = sizeof(dnsheader) + mbuf->dlen + sizeof(qdns);
    to = to + jump;
    while (vlen > 1)            //vlen include type.mvalue.data.
    {
        type = from[0];
        mv = (struct mvalue *)(from + 1);
        to = fill_rrset_in_msg(hlp, from, to, &main_val, msg);
        if (to == NULL)
            return -1;
//         *to = 0;
        vlen = vlen - 1 - mv->len - sizeof(struct mvalue);
        sh.an += mv->num;
        from = from + mv->len + 1 + sizeof(struct mvalue);      // type.mv.len.
        /**
        * if previous record is CNAME(query type can't be ANY, that we don't support now),
        * next A & AAAA & CNAME use previous domain name (cname name).
        * We duplicate here to make it possible to refer previous one.
        */
        if (type == CNAME && vlen > 1 /*&& mbuf->qtype != ANY*/ && (from[0] == A || from[0] == AAAA || from[0] == CNAME))
        {
            main_val++;
            hlp[main_val].name = hlp[main_val - 1].name;
            hlp[main_val].off = hlp[main_val - 1].off;
            hlp[main_val].level = hlp[main_val - 1].level;
            hlp[main_val].len = hlp[main_val - 1].len;
            hlp[main_val].ref = -1;
            hlp[main_val].mt = 0;
        }
    }
    sh.itor = msg;
    sh.dlen = (mbuf->dlen == 2) ? 1: (mbuf->dlen);
    sh.od = mbuf->td;
    sh.id = mbuf->id;
    sh.type = mbuf->qtype;
    fill_header_in_msg(&sh);
    dnslen = to - msg;
    mbuf->buflen = dnslen;
    mbuf->addr = &(mbuf->caddr);
    if (mbuf->socktype == UDP) {
        if (dnslen > MAX_UDP_SIZE)
            send_tc_to_client(mbuf);
        else
            udp_write_info(mbuf, 0);     //ignore send error
    } else {
        temp = DNS_GET16(dnslen);
        memcpy(msg - 2, &temp, sizeof(uint16_t));
        mbuf->buflen = dnslen + 2;
        mbuf->buf = msg - 2;
        tcp_write_info(mbuf, 0);
    }
    ////////////////////////////////////////////////////////////
    //key, val, vallen, ttl offset
    //if now + TTL_UPDATE > ttl
    //return
    /* ret = transfer_record_to_msg(msgto, td, msg + 2, dnslen, ttloff); */
    /* if (ret < 0) */
        /* return -1; */
    return 0;
}
예제 #2
0
파일: author.c 프로젝트: Houfeng/dnspod-sr
//databuffer format
//type.mvalue.data.type.mvalue.data...
int
// write_back_to_client(uchar * td, enum rrtype otype, uint8_t level, ushort id, int dlen,
write_back_to_client(mbuf_type *mbuf, uchar * fr, int vlen)
{
    struct setheader sh = { 0 };        //data in dns header
    int main_val = 0, dnslen = 0;
    uchar *msg = mbuf->buf, type;      //if bigger, use TCP
    uchar *from = fr, *to = msg;
    struct mvalue *mv = NULL;
    int jump = 0;
    uint16_t temp = 0;
    struct hlpc hlp[100];       //p domians to compression
    hlp[0].name = mbuf->td;
    hlp[0].off = sizeof(dnsheader);
    hlp[0].level = mbuf->lowerdomain.label_count;
    hlp[0].ref = -1;
    hlp[0].mt = 0;
    hlp[0].len = mbuf->dlen;
    jump = sizeof(dnsheader) + mbuf->dlen + sizeof(qdns);
    to = to + jump;
    while (vlen > 1)            //vlen include type.mvalue.data.
    {
        type = from[0];
        mv = (struct mvalue *)(from + 1);
        to = fill_rrset_in_msg(hlp, from, to, main_val, msg);
        if (to == NULL)
            return -1;
//         *to = 0;
        vlen = vlen - 1 - mv->len - sizeof(struct mvalue);
        sh.an += mv->num;
        if (type == CNAME)      //cname must be 1
            main_val++;             //no all rdata is the cname's
        from = from + mv->len + 1 + sizeof(struct mvalue);      // type.mv.len.
    }
    sh.itor = msg;
    sh.dlen = mbuf->dlen;
    sh.od = mbuf->td;
    sh.id = mbuf->id;
    sh.type = mbuf->qtype;
    fill_header_in_msg(&sh);
    dnslen = to - msg;
    mbuf->buflen = dnslen;
    mbuf->addr = &(mbuf->caddr);
    if (mbuf->socktype == UDP) {
        if (dnslen > MAX_UDP_SIZE)
            send_tc_to_client(mbuf);
        else
            udp_write_info(mbuf, 0);     //ignore send error
    } else {
        temp = DNS_GET16(dnslen);
        memcpy(msg - 2, &temp, sizeof(uint16_t));
        mbuf->buflen = dnslen + 2;
        mbuf->buf = msg - 2;
        tcp_write_info(mbuf, 0);
    }
    ////////////////////////////////////////////////////////////
    //key, val, vallen, ttl offset
    //if now + TTL_UPDATE > ttl
    //return
    /* ret = transfer_record_to_msg(msgto, td, msg + 2, dnslen, ttloff); */
    /* if (ret < 0) */
        /* return -1; */
    return 0;
}