static void tcp_timeout_handler(void *arg) { struct dns_query *q = arg; query_handler(q, ETIMEDOUT, NULL, NULL, NULL, NULL); mem_deref(q); }
static bool tcpconn_fail_handler(struct le *le, void *arg) { struct dns_query *q = le->data; int err = *((int *)arg); list_unlink(&q->le_tc); q->tc = mem_deref(q->tc); if (q->ntx >= *q->srvc) { DEBUG_WARNING("all servers failed, giving up!!\n"); err = err ? err : ECONNREFUSED; goto out; } /* try next server(s) */ err = send_tcp(q); if (err) { DEBUG_WARNING("all servers failed, giving up\n"); goto out; } out: if (err) { query_handler(q, err, NULL, NULL, NULL, NULL); mem_deref(q); } return false; }
static bool query_close_handler(struct le *le, void *arg) { struct dns_query *q = le->data; (void)arg; query_handler(q, ECONNABORTED, NULL, NULL, NULL, NULL); mem_deref(q); return false; }
static void udp_timeout_handler(void *arg) { struct dns_query *q = arg; int err = ETIMEDOUT; if (q->ntx >= NTX_MAX) goto out; err = send_udp(q); if (err) goto out; tmr_start(&q->tmr, 1000<<MIN(2, q->ntx - 2), udp_timeout_handler, q); out: if (err) { query_handler(q, err, NULL, NULL, NULL, NULL); mem_deref(q); } }
static int reply_recv(struct dnsc *dnsc, struct mbuf *mb) { struct dns_query *q = NULL; uint32_t i, j, nv[3]; struct dnsquery dq; int err = 0; if (!dnsc || !mb) return EINVAL; dq.name = NULL; if (dns_hdr_decode(mb, &dq.hdr) || !dq.hdr.qr) { err = EBADMSG; goto out; } err = dns_dname_decode(mb, &dq.name, 0); if (err) goto out; if (mbuf_get_left(mb) < 4) { err = EBADMSG; goto out; } dq.type = ntohs(mbuf_read_u16(mb)); dq.dnsclass = ntohs(mbuf_read_u16(mb)); q = list_ledata(hash_lookup(dnsc->ht_query, hash_joaat_str_ci(dq.name), query_cmp_handler, &dq)); if (!q) { err = ENOENT; goto out; } /* try next server */ if (dq.hdr.rcode == DNS_RCODE_SRV_FAIL && q->ntx < *q->srvc) { if (!q->tc) /* try next UDP server immediately */ tmr_start(&q->tmr, 0, udp_timeout_handler, q); err = EPROTO; goto out; } nv[0] = dq.hdr.nans; nv[1] = dq.hdr.nauth; nv[2] = dq.hdr.nadd; for (i=0; i<ARRAY_SIZE(nv); i++) { for (j=0; j<nv[i]; j++) { struct dnsrr *rr = NULL; err = dns_rr_decode(mb, &rr, 0); if (err) { query_handler(q, err, NULL, NULL, NULL, NULL); mem_deref(q); goto out; } list_append(&q->rrlv[i], &rr->le_priv, rr); } } if (q->type == DNS_QTYPE_AXFR) { struct dnsrr *rrh, *rrt; rrh = list_ledata(list_head(&q->rrlv[0])); rrt = list_ledata(list_tail(&q->rrlv[0])); /* Wait for last AXFR reply with terminating SOA record */ if (dq.hdr.rcode == DNS_RCODE_OK && dq.hdr.nans > 0 && (!rrt || rrt->type != DNS_TYPE_SOA || rrh == rrt)) { DEBUG_INFO("waiting for last SOA record in reply\n"); goto out; } } query_handler(q, 0, &dq.hdr, &q->rrlv[0], &q->rrlv[1], &q->rrlv[2]); mem_deref(q); out: mem_deref(dq.name); return err; }
int main(void) { initialize(); while (FCGI_Accept() >= 0) { query_name = getenv("SQL_NAME"); /* Environment variables */ env_node = xmlNewChild(root_node, NULL, BAD_CAST "ENV", NULL); xmlNewChild(env_node, NULL, BAD_CAST "SERVER_HOSTNAME", BAD_CAST getenv("SERVER_HOSTNAME")); xmlNewChild(env_node, NULL, BAD_CAST "SCRIPT_FILENAME", BAD_CAST getenv("SCRIPT_FILENAME")); xmlNewChild(env_node, NULL, BAD_CAST "QUERY_STRING", BAD_CAST qEncodeUrl(getenv("SCRIPT_FILENAME"))); xmlNewChild(env_node, NULL, BAD_CAST "REQUEST_METHOD", BAD_CAST getenv("REQUEST_METHOD")); xmlNewChild(env_node, NULL, BAD_CAST "CONTENT_TYPE", BAD_CAST getenv("CONTENT_TYPE")); xmlNewChild(env_node, NULL, BAD_CAST "CONTENT_LENGTH", BAD_CAST getenv("CONTENT_LENGTH")); /* Get variables */ get_node = xmlNewChild(root_node, NULL, BAD_CAST "GET", NULL); /* Parse queries. */ qget = qCgiRequestParseQueries(NULL, "GET"); qnum = qEntryGetNum(qget); /* Create children */ for(i=0; i<qnum; i++) { qname = (char *)qEntryGetName(qget); qvalue = (char *)qEntryGetValue(qget); xmlNewChild(get_node, NULL, BAD_CAST qname, BAD_CAST qvalue); } /* Post variables */ post_node = xmlNewChild(root_node, NULL, BAD_CAST "POST", NULL); /* Parse queries. */ qget = qCgiRequestParseQueries(NULL, "POST"); qnum = qEntryGetNum(qget); /* Create children */ for(i=0; i<qnum; i++) { qname = (char *)qEntryGetName(qget); qvalue = (char *)qEntryGetValue(qget); xmlNewChild(post_node, NULL, BAD_CAST qname, BAD_CAST qvalue); } /* Cookie variables */ cookie_node = xmlNewChild(root_node, NULL, BAD_CAST "COOKIE", NULL); /* Parse queries. */ qget = qCgiRequestParseCookies(NULL); qnum = qEntryGetNum(qget); /* Create children */ for(i=0; i<qnum; i++) { qname = (char *)qEntryGetName(qget); qvalue = (char *)qEntryGetValue(qget); xmlNewChild(cookie_node, NULL, BAD_CAST qname, BAD_CAST qvalue); } sql_node = xmlNewChild(root_node, NULL, BAD_CAST "SQL", NULL); myq = getenv("SQL_QUERY"); query_handler(query_name,myq); /* Output XML */ mylen = xmlStrlen(myxml); xmlDocDumpMemoryEnc(doc, &myxml, &mylen, "UTF-8"); printf("Content-type: application/xhtml+xml\r\n\r\n%s",myxml); /* Free everything under the root */ xmlUnlinkNode(env_node); xmlFreeNode(env_node); xmlUnlinkNode(get_node); xmlFreeNode(get_node); xmlUnlinkNode(post_node); xmlFreeNode(post_node); xmlUnlinkNode(cookie_node); xmlFreeNode(cookie_node); xmlUnlinkNode(sql_node); xmlFreeNode(sql_node); } xmlFreeDoc(doc); xmlCleanupParser(); return 0; }