You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by is...@apache.org on 2008/04/24 13:45:09 UTC
svn commit: r651222 [2/2] - in /httpd/sandbox/mod_domain: LICENSE NOTICE
README buckets.c errors.c mod_dns.c mod_dns.h protocol.c rr.h rr/ rr/rr.c
rr/rr_a.c rr/rr_cname.c rr/rr_mx.c
Added: httpd/sandbox/mod_domain/protocol.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_domain/protocol.c?rev=651222&view=auto
==============================================================================
--- httpd/sandbox/mod_domain/protocol.c (added)
+++ httpd/sandbox/mod_domain/protocol.c Thu Apr 24 04:44:55 2008
@@ -0,0 +1,527 @@
+/* Copyright 1999-2007 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Original Copyright (c) Netmask.IT!® 2006-2007
+ *
+ * DNS Protocol module for Apache 2.x
+ */
+
+#include "mod_dns.h"
+
+#define DNS_HEADER_SIZE 12
+
+/** TODO: Add serialize/unserialize for query + message and then consider
+ * reimplementing network I/O to work with character arrays */
+
+/** Helper network-read routines */
+/** WARNING: This will trash the contents of bb! */
+static apr_status_t dns_bb_read_byte(apr_bucket_brigade *bb,
+ ap_filter_t *filters_in,
+ apr_byte_t *rval)
+{
+ apr_status_t rv;
+ int dlen = 1;
+
+ apr_brigade_cleanup(bb);
+ rv = ap_get_brigade(filters_in, bb, AP_MODE_READBYTES, APR_BLOCK_READ, 1);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ if ((rv = apr_brigade_flatten(bb, (char *)rval,
+ &dlen)) != APR_SUCCESS)
+ return rv;
+
+ if (dlen != 1)
+ return APR_EGENERAL;
+
+ apr_brigade_cleanup(bb);
+ return APR_SUCCESS;
+}
+
+/** WARNING: This will trash the contents of bb! */
+static apr_status_t dns_bb_read_short(apr_bucket_brigade *bb,
+ ap_filter_t *filters_in,
+ apr_uint16_t *rval)
+{
+ apr_status_t rv;
+ int dlen = 2;
+
+ apr_brigade_cleanup(bb);
+ rv = ap_get_brigade(filters_in, bb, AP_MODE_READBYTES, APR_BLOCK_READ, 2);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ if ((rv = apr_brigade_flatten(bb, (char *)rval,
+ &dlen)) != APR_SUCCESS)
+ return rv;
+
+ if (dlen != 2)
+ return APR_EGENERAL;
+
+ apr_brigade_cleanup(bb);
+ *rval = ntohs(*rval);
+ return APR_SUCCESS;
+}
+
+/* The socket is hiding at:
+if (!csd) {
+ csd = ap_get_module_config(c->conn_config, &core_module);
+ }
+*/
+
+DNS_DECLARE(apr_status_t) dns_query_serialize(dns_query_t *q, char *data,
+ int *dlen)
+{
+ apr_byte_t llen;
+ char *ptr, *label, *last = NULL;
+ apr_uint16_t s;
+ apr_status_t rv = APR_SUCCESS;
+
+ /** The length byte takes the same space as a char, so we just need
+ * strlen(cname) of space (cname should have trailing .) */
+ *dlen = strlen(q->qname) + 1;
+ if (q->qname[*dlen-2] != '.')
+ (*dlen)++;
+
+ /* 2 bytes type, 2 bytes class */
+ *dlen += 4;
+
+ if (data == NULL)
+ return rv;
+
+ /** NAME */
+ ptr = data;
+ label = apr_strtok(q->qname, ".", &last);
+ while (label != NULL) {
+ llen = strlen(label);
+ if (llen == 0) {
+ /** Trailing . - Set NULL and break */
+ *ptr = 0;
+ ptr++;
+ break;
+ }
+ /** Write length token */
+ *ptr = llen;
+ ptr++;
+ /** Write label */
+ memcpy(ptr, label, llen);
+ /** Move pointer */
+ ptr+=llen;
+ /** Advance to next token */
+ label = apr_strtok(NULL, ".", &last);
+ }
+ *ptr = 0;
+ ptr++;
+
+ /** TYPE */
+ s = htons(q->qtype);
+ memcpy(ptr, (const void *)&s, 2);
+ ptr += 2;
+
+ /** CLASS */
+ s = htons(q->qclass);
+ memcpy(ptr, (const void *)&s, 2);
+ ptr += 2;
+
+ return rv;
+}
+
+DNS_DECLARE(apr_status_t) dns_query_pserialize(dns_query_t *q,
+ apr_pool_t *pool,
+ char **data, int *dlen)
+{
+ apr_status_t rv;
+ *dlen = 0;
+ if ((rv = dns_query_serialize(q, NULL, dlen)) != APR_SUCCESS)
+ return rv;
+ *data = apr_palloc(pool, *dlen);
+ return dns_query_serialize(q, *data, dlen);
+}
+
+
+DNS_DECLARE(apr_status_t) dns_write_response(dns_message_t *dns,
+ char **response,
+ apr_size_t *len)
+{
+ dns_header_t *h = dns->header;
+ dns_query_t *q;
+ dns_rr_t *rr;
+ apr_uint16_t s;
+ apr_uint32_t l;
+ char *data, *header;
+ char *label, *last = NULL;
+
+ apr_uint16_t flags = 0;
+
+
+ /** TODO: Move to fixup */
+ h->qr = DNS_FLAG_ON;
+ /** TODO: Can we be authorative? */
+ h->aa = DNS_FLAG_OFF;
+ /** TODO: Can we be recursive? Are we already? */
+ h->ra = DNS_FLAG_OFF;
+ /** Someone else should be setting rcode */
+
+ /** Create flags bitfield */
+ flags |= h->qr << 15;
+ flags |= h->opcode << 11;
+ flags |= h->aa << 10;
+ flags |= h->tc << 9;
+ flags |= h->rd << 8;
+ flags |= h->ra << 7;
+ flags |= h->z << 4;
+ flags |= h->rcode;
+
+ /** Prepare response */
+ header = data = malloc(DNS_HEADER_SIZE);
+ *len = DNS_HEADER_SIZE;
+
+ /** Header */
+ s = htons(h->id);
+ memcpy(data, &s, 2);
+ data += 2;
+ s = htons(flags);
+ memcpy(data, &s, 2);
+ data += 2;
+ s = htons(h->qdcount);
+ memcpy(data, &s, 2);
+ data += 2;
+ s = htons(h->ancount);
+ memcpy(data, &s, 2);
+ data += 2;
+ s = htons(h->nscount);
+ memcpy(data, &s, 2);
+ data += 2;
+ s = htons(h->arcount);
+ memcpy(data, &s, 2);
+ data += 2;
+
+ /** Queries */
+ while ((q = apr_array_pop(dns->query)) != NULL) {
+ dns_query_serialize(q, NULL, (int *)&l);
+ data = malloc(*len + l);
+ memcpy(data, header, *len);
+ free(header);
+ label = data + *len;
+ dns_query_serialize(q, label, (int *)&l);
+ header = data;
+ *len +=l;
+ }
+
+ /** Answers */
+ while ((rr = apr_array_pop(dns->answer)) != NULL) {
+ dns_rr_serialize(rr, NULL, (int *)&l);
+ data = malloc(*len + l);
+ memcpy(data, header, *len);
+ free(header);
+ label = data + *len;
+ dns_rr_serialize(rr, label, (int *)&l);
+ header = data;
+ *len +=l;
+ }
+
+ /** Authority */
+ while ((rr = apr_array_pop(dns->authority)) != NULL) {
+ dns_rr_serialize(rr, NULL, (int *)&l);
+ data = malloc(*len + l);
+ memcpy(data, header, *len);
+ free(header);
+ label = data + *len;
+ dns_rr_serialize(rr, label, (int *)&l);
+ header = data;
+ *len +=l;
+ }
+
+ /** Additional */
+ while ((rr = apr_array_pop(dns->additional)) != NULL) {
+ dns_rr_serialize(rr, NULL, (int *)&l);
+ data = malloc(*len + l);
+ memcpy(data, header, *len);
+ free(header);
+ label = data + *len;
+ dns_rr_serialize(rr, label, (int *)&l);
+ header = data;
+ *len +=l;
+ }
+
+ *response = header;
+ return APR_SUCCESS;
+}
+
+/** On return, q will point to the newly read query, and r to the newly
+ * created request_rec */
+DNS_DECLARE(apr_status_t) dns_read_request(dns_message_t *dns,
+ request_rec **r_in,
+ dns_query_t **q_in)
+{
+ apr_bucket_brigade *bb;
+ apr_byte_t llen;
+ apr_size_t dlen;
+ apr_status_t rv;
+ char *label;
+ request_rec *r;
+ dns_query_t *q;
+
+ *r_in = r = dns_create_request(dns);
+ if (!(r))
+ return APR_EGENERAL;
+
+ *q_in = q = apr_array_push(dns->query);
+
+ /* This is the only read we're going to get, so now's the time to do
+ * input filters */
+ ap_run_insert_filter(r);
+ rv = dns_invoke_filter_init(r->input_filters);
+ if (rv != OK) {
+ return rv;
+ }
+
+ /** Ensure qname has a pointee before we start reading the label */
+ q->qname = apr_pstrdup(dns->pool, "");
+
+ bb = apr_brigade_create(dns->pool, dns->conn->bucket_alloc);
+
+ /** Read in the label. TODO: input_compression filter */
+ rv = dns_bb_read_byte(bb, r->input_filters, &llen);
+ while (rv == APR_SUCCESS && llen > 0) {
+ dns->bytesread++;
+ rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+ APR_BLOCK_READ, llen);
+ if (rv != APR_SUCCESS)
+ return rv;
+ dns->bytesread += llen;
+ /** Allocate individual labels from request_rec pool, but qname should
+ * be allocated from dns pool */
+ dlen = llen;
+ rv = apr_brigade_pflatten(bb, &label, &dlen, r->pool);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ if (dlen != llen)
+ return APR_EGENERAL;
+
+ apr_cpystrn(label, (const char *)label, dlen + 1);
+ q->qname = apr_pstrcat(dns->pool, q->qname, label, ".", NULL);
+
+ rv = dns_bb_read_byte(bb, r->input_filters, &llen);
+ }
+ dns->bytesread++;
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ /** Read in qclass / qtype */
+ rv = dns_bb_read_short(bb, r->input_filters, &(q->qtype));
+ if (rv !=APR_SUCCESS)
+ return rv;
+ dns->bytesread += 2;
+ rv = dns_bb_read_short(bb, r->input_filters, &(q->qclass));
+ if (rv !=APR_SUCCESS)
+ return rv;
+ dns->bytesread += 2;
+
+ /** Populate request_rec */
+ r->the_request = apr_pstrcat(r->pool, "QUERY ", q->qname, " ",
+ dns_get_name_class(q->qclass), " ",
+ dns_get_name_type(q->qtype), NULL);
+ r->protocol = apr_pstrdup(r->pool, "DNS");
+ r->proto_num = 1000;
+ r->hostname = apr_pstrdup(r->pool, q->qname);
+ r->method = apr_pstrdup(r->pool, dns_get_name_type(q->qtype));
+ r->method_number = (int)q->qtype;
+ r->unparsed_uri = apr_pstrcat(r->pool, "dns://", q->qname, "/",
+ dns_get_name_class(q->qclass), "/",
+ dns_get_name_type(q->qtype), NULL);
+ r->uri = apr_pstrcat(r->pool, "/", dns_get_name_class(q->qclass), "/",
+ dns_get_name_type(q->qtype), NULL);
+ apr_uri_parse(r->pool, r->unparsed_uri, &(r->parsed_uri));
+ /** Set handler so modules like mod_dir don't try to pick this up */
+ r->handler = apr_pstrdup(r->pool, DNS_MAGIC_TYPE);
+ /** The virtualhost info is worthless, but we want to call fix_hostname
+ * and this is the only way to do it */
+ ap_update_vhost_from_headers(r);
+ ap_run_post_read_request(r);
+ return APR_SUCCESS;
+}
+
+/** Create a dns_message_t based on data in bb (via filters_in) */
+/** Only read the header at this point */
+DNS_DECLARE(dns_message_t *) dns_read_message_header(conn_rec *c)
+{
+ apr_pool_t *p;
+ apr_bucket_brigade *tmp_bb;
+ dns_message_t *dns;
+ dns_header_t *h;
+ apr_byte_t data[DNS_HEADER_SIZE];
+ int sd_type;
+ int dlen = 0;
+
+ apr_uint16_t flags;
+ apr_status_t rv;
+
+ if (apr_pool_create(&p, c->pool) != APR_SUCCESS)
+ return NULL;
+
+ dns = apr_pcalloc(p, sizeof(*dns));
+
+ if (!(dns))
+ return NULL;
+
+ dns->pool = p;
+ dns->conn = c;
+ dns->filters_in = c->input_filters;
+ dns->filters_out = c->output_filters;
+
+ h = dns->header = apr_pcalloc(dns->pool, sizeof(*h));
+ dns->query = apr_array_make(p, 0, sizeof(dns_query_t));
+ dns->answer = apr_array_make(p, 0, sizeof(dns_rr_t));
+ dns->authority = apr_array_make(p, 0, sizeof(dns_rr_t));
+ dns->additional = apr_array_make(p, 0, sizeof(dns_rr_t));
+
+ tmp_bb = apr_brigade_create(p, c->bucket_alloc);
+ apr_brigade_cleanup(tmp_bb);
+
+ /** If we have a TCP connection, we'll need to read h->length */
+ apr_socket_type_get(ap_get_module_config(c->conn_config, &core_module),
+ &sd_type);
+ if (sd_type == SOCK_STREAM) {
+ rv = dns_bb_read_short(tmp_bb, dns->filters_in, &(dns->length));
+ if (rv != APR_SUCCESS) {
+ apr_brigade_destroy(tmp_bb);
+ return NULL;
+ }
+ apr_brigade_cleanup(tmp_bb);
+ } else {
+ dns->length = 0;
+ }
+
+ rv = ap_get_brigade(dns->filters_in, tmp_bb, AP_MODE_READBYTES,
+ APR_BLOCK_READ, DNS_HEADER_SIZE);
+
+ if (rv != APR_SUCCESS) {
+ apr_brigade_destroy(tmp_bb);
+ return NULL;
+ }
+ dlen = DNS_HEADER_SIZE;
+ if (apr_brigade_flatten(tmp_bb, (char *)data, &dlen) != APR_SUCCESS) {
+ apr_brigade_destroy(tmp_bb);
+ return NULL;
+ }
+ if (dlen != DNS_HEADER_SIZE) {
+ apr_brigade_destroy(tmp_bb);
+ return NULL;
+ }
+
+ apr_brigade_destroy(tmp_bb);
+
+ memcpy(&(h->id), data, 2);
+ h->id = ntohs(h->id);
+ memcpy(&flags, data + 2, 2);
+ flags = ntohs(flags);
+
+ /** Seperate flags bitfield */
+ h->qr = (flags & 32768) >> 15;
+ h->opcode = (flags & 30720) >> 11;
+ h->aa = (flags & 1024) >> 10;
+ h->tc = (flags & 512) >> 9;
+ h->rd = (flags & 256) >> 8;
+ h->ra = (flags & 128) >> 7;
+ h->z = (flags & 112) >>4;
+ h->rcode = flags & 15;
+
+ memcpy(&(h->qdcount), data + 4, 2);
+ h->qdcount = ntohs(h->qdcount);
+ /** These should all be 0 anyway now... */
+ memcpy(&(h->ancount), data + 6, 2);
+ h->ancount = ntohs(h->ancount);
+ memcpy(&(h->nscount), data + 8, 2);
+ h->nscount = ntohs(h->nscount);
+ memcpy(&(h->arcount), data + 10, 2);
+ h->arcount = ntohs(h->arcount);
+
+ dns->bytesread = DNS_HEADER_SIZE;
+
+ /** Initialize rcode */
+ dns->header->rcode = DNS_SUCCESS;
+
+ return dns;
+}
+
+/** Output routines. We expect our generic buffered output filter to be
+ * in place to make this somewhat efficient */
+DNS_DECLARE(apr_status_t) dns_add_rr_answer(request_rec *r, dns_rr_t *rr)
+{
+ apr_bucket_brigade *bb;
+ apr_bucket *b;
+ apr_status_t rv;
+ apr_size_t len;
+ char *data;
+
+
+ if (rr == NULL)
+ return APR_SUCCESS;
+
+ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ dns_rr_pserialize(rr, r->pool, &data, &len);
+ b = dns_bucket_rr_answer_create((const char *)data, len,
+ r->pool, bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+ rv = ap_pass_brigade(r->output_filters, bb);
+ apr_brigade_destroy(bb);
+ return rv;
+}
+
+DNS_DECLARE(apr_status_t) dns_add_rr_authority(request_rec *r, dns_rr_t *rr)
+{
+ apr_bucket_brigade *bb;
+ apr_bucket *b;
+ apr_status_t rv;
+ apr_size_t len;
+ char *data;
+
+ if (rr == NULL)
+ return APR_SUCCESS;
+
+ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ dns_rr_pserialize(rr, r->pool, &data, &len);
+ b = dns_bucket_rr_answer_create((const char *)data, len,
+ r->pool, bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+ rv = ap_pass_brigade(r->output_filters, bb);
+ apr_brigade_destroy(bb);
+ return rv;
+}
+
+DNS_DECLARE(apr_status_t) dns_add_rr_additional(request_rec *r, dns_rr_t *rr)
+{
+ apr_bucket_brigade *bb;
+ apr_bucket *b;
+ apr_status_t rv;
+ apr_size_t len;
+ char *data;
+
+ if (rr == NULL)
+ return APR_SUCCESS;
+
+ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ dns_rr_pserialize(rr, r->pool, &data, &len);
+ b = dns_bucket_rr_answer_create((const char *)data, len,
+ r->pool, bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+ rv = ap_pass_brigade(r->output_filters, bb);
+ apr_brigade_destroy(bb);
+ return rv;
+}
Added: httpd/sandbox/mod_domain/rr.h
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_domain/rr.h?rev=651222&view=auto
==============================================================================
--- httpd/sandbox/mod_domain/rr.h (added)
+++ httpd/sandbox/mod_domain/rr.h Thu Apr 24 04:44:55 2008
@@ -0,0 +1,78 @@
+/* Copyright 1999-2007 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Original Copyright (c) Netmask.IT!® 2006-2007
+ *
+ * DNS Protocol module for Apache 2.x
+ */
+
+#ifndef RR_H
+#define RR_H
+
+#ifndef MOD_DNS_H
+#include "mod_dns.h"
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define DNS_RDATA_SERIALIZE(type) apr_status_t dns_rdata_##type##_serialize\
+ (void *rdata, char *data, int *dlen)
+#define DNS_RDATA_UNSERIALIZE(type) apr_status_t dns_rdata_##type##_unserialize\
+ (apr_pool_t *pool, const char *data, void **rdata)
+#define DNS_RDATA_PSERIALIZE(type) \
+apr_status_t dns_rdata_##type##_pserialize(void *rdata, apr_pool_t *pool,\
+ char **data, int *dlen)\
+{\
+ apr_status_t rv;\
+ *dlen = 0;\
+ if ((rv = dns_rdata_##type##_serialize(rdata, NULL, dlen)) != APR_SUCCESS)\
+ return rv;\
+ *data = apr_palloc(pool, *dlen);\
+ return dns_rdata_##type##_serialize(rdata, *data, dlen);\
+}
+
+#define dns_init_rdata_const(type,var) \
+ var->serialize = dns_rdata_##type.serialize;\
+ var->pserialize = dns_rdata_##type.pserialize;\
+ var->unserialize = dns_rdata_##type.unserialize
+
+#define dns_init_rdata(type,var) \
+ var->serialize = type->serialize;\
+ var->pserialize = type->pserialize;\
+ var->unserialize = type->unserialize
+
+#define dns_null_rdata {NULL,NULL,NULL}
+
+#define DNS_RDATA_DECLARE(type) DNS_DECLARE_DATA extern const dns_rdata_t dns_rdata_##type
+#define DNS_RDATA_IMPLEMENT(type) DNS_DECLARE_DATA const dns_rdata_t dns_rdata_##type = {\
+ NULL,\
+ dns_rdata_##type##_serialize,\
+ dns_rdata_##type##_pserialize,\
+ dns_rdata_##type##_unserialize\
+}
+
+DNS_RDATA_DECLARE(a);
+DNS_RDATA_DECLARE(cname);
+DNS_RDATA_DECLARE(mx);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
Added: httpd/sandbox/mod_domain/rr/rr.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_domain/rr/rr.c?rev=651222&view=auto
==============================================================================
--- httpd/sandbox/mod_domain/rr/rr.c (added)
+++ httpd/sandbox/mod_domain/rr/rr.c Thu Apr 24 04:44:55 2008
@@ -0,0 +1,208 @@
+/* Copyright 1999-2007 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Original Copyright (c) Netmask.IT!® 2006-2007
+ *
+ * DNS Protocol module for Apache 2.x
+ */
+
+#include "../rr.h"
+
+static dns_rdata_t *rr_list[255];
+
+DNS_DECLARE(void) dns_register_rr(dns_rdata_t *rdata, apr_uint16_t type) {
+ if (rr_list[0]!=NULL)
+ memset(*rr_list, 0, sizeof(*rr_list));
+
+ rr_list[type] = rdata;
+}
+
+DNS_DECLARE(dns_rr_t *) dns_create_rr(request_rec *r, const char *name,
+ dns_type_t rrtype,
+ dns_class_t rrclass,
+ apr_int32_t ttl)
+{
+ dns_module_config_t *conf;
+ dns_rr_t *rr;
+ apr_pool_t *pool;
+
+ conf = (dns_module_config_t *)ap_get_module_config(r->server->module_config,
+ &dns_module);
+ if (!conf) {
+ /* We're not configured. Something's very wrong. Abort. */
+ return NULL;
+ }
+
+ pool = r->pool;
+
+ rr = apr_palloc(pool, sizeof(*rr));
+ rr->name = apr_pstrdup(pool, name);
+ rr->type = rrtype;
+ rr->classtype = rrclass;
+ rr->ttl = (ttl ? ttl : conf->default_ttl);
+ rr->rdata = apr_palloc(pool, sizeof(*(rr->rdata)));
+ rr->rdlength = 0;
+ rr->rdata->rdata = NULL;
+ if (rr_list[rrtype]!=NULL) {
+ dns_init_rdata(rr_list[rrtype], rr->rdata);
+ } else {
+ rr->rdata = NULL;
+ }
+ return rr;
+}
+
+DNS_DECLARE(apr_status_t) dns_rr_serialize(dns_rr_t *rr, char *data, int *dlen) {
+ apr_byte_t llen;
+ char *ptr, *label, *last = NULL;
+ apr_uint32_t l;
+ apr_uint16_t s;
+ apr_status_t rv;
+ int rlen;
+
+ /** Get rdata length */
+ rv = rr->rdata->serialize(rr->rdata->rdata, NULL, (int *)&(rr->rdlength));
+
+ *dlen = strlen(rr->name) + 1;
+ if (rr->name[*dlen-2] != '.')
+ (*dlen)++;
+
+ /* 2 bytes type, 2 bytes class, 4 bytes ttl, 2 bytes rdlength */
+ *dlen += 10;
+ *dlen += rr->rdlength;
+
+ if (data == NULL)
+ return rv;
+
+ /** NAME */
+ ptr = data;
+ label = apr_strtok(rr->name, ".", &last);
+ while (label != NULL) {
+ llen = strlen(label);
+ if (llen == 0) {
+ /** Trailing . - Set NULL and break */
+ *ptr = 0;
+ ptr++;
+ break;
+ }
+ /** Write length token */
+ *ptr = llen;
+ ptr++;
+ /** Write label */
+ memcpy(ptr, label, llen);
+ /** Move pointer */
+ ptr+=llen;
+ /** Advance to next token */
+ label = apr_strtok(NULL, ".", &last);
+ }
+ *ptr = 0;
+ ptr++;
+
+
+ /** TYPE */
+ s = htons(rr->type);
+ memcpy(ptr, (const void *)&s, 2);
+ ptr += 2;
+
+ /** CLASS */
+ s = htons(rr->classtype);
+ memcpy(ptr, (const void *)&s, 2);
+ ptr += 2;
+
+ /** TTL */
+ l = htonl(rr->ttl);
+ memcpy(ptr, (const void *)&l, 4);
+ ptr += 4;
+
+ /** RDLENGTH */
+ s = htons(rr->rdlength);
+ memcpy(ptr, (const void *)&s, 2);
+ ptr += 2;
+
+ /** RDATA */
+ rv = rr->rdata->serialize(rr->rdata->rdata, ptr, &rlen);
+ if (rlen != rr->rdlength)
+ return APR_EGENERAL;
+ return rv;
+}
+
+DNS_DECLARE(apr_status_t) dns_rr_unserialize(apr_pool_t *pool,
+ const char *data,
+ dns_rr_t **rr)
+{
+ const char *ptr = data;
+ char label[63] = ""; /** RFC 1035 says label can only be 63 octets long */
+ apr_byte_t len;
+ dns_rr_t *rrr;
+ apr_uint32_t l;
+ apr_uint16_t s;
+
+ *rr = rrr = apr_pcalloc(pool, sizeof(dns_rr_t));
+ rrr->rdata = apr_pcalloc(pool, sizeof(dns_rdata_t));
+ rrr->name = apr_pstrdup(pool, "");
+
+ /** NAME **/
+ memcpy(&len, ptr, 1);
+ while (len > 0) {
+ ptr++;
+ apr_cpystrn(label, ptr, len + 1);
+ ptr += len;
+ rrr->name = apr_pstrcat(pool, rrr->name, label, ".", NULL);
+ memcpy(&len, ptr, 1);
+ }
+ ptr++;
+
+ /** TYPE **/
+ memcpy(&s, ptr, 2);
+ rrr->type = ntohs(s);
+ ptr +=2;
+
+ /** CLASS **/
+ memcpy(&s, ptr, 2);
+ rrr->classtype = ntohs(s);
+ ptr +=2;
+
+ /** TTL **/
+ memcpy(&l, ptr, 4);
+ rrr->ttl= ntohl(l);
+ ptr +=4;
+
+ /** RDLENGTH **/
+ memcpy(&s, ptr, 2);
+ rrr->rdlength = ntohs(s);
+ ptr +=2;
+
+ if (rr_list[rrr->type]!=NULL) {
+ dns_init_rdata(rr_list[rrr->type], rrr->rdata);
+ } else {
+ rrr->rdata = NULL;
+ }
+ if (rrr->rdata)
+ rrr->rdata->unserialize(pool, ptr, &(rrr->rdata));
+ return APR_SUCCESS;
+}
+
+DNS_DECLARE(apr_status_t) dns_rr_pserialize(dns_rr_t *rr, apr_pool_t *pool,
+ char **data, int *dlen)
+{
+ apr_status_t rv;
+ *dlen = 0;
+ if ((rv = dns_rr_serialize(rr, NULL, dlen)) != APR_SUCCESS)
+ return rv;
+ *data = apr_palloc(pool, *dlen);
+ return dns_rr_serialize(rr, *data, dlen);
+}
+
Added: httpd/sandbox/mod_domain/rr/rr_a.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_domain/rr/rr_a.c?rev=651222&view=auto
==============================================================================
--- httpd/sandbox/mod_domain/rr/rr_a.c (added)
+++ httpd/sandbox/mod_domain/rr/rr_a.c Thu Apr 24 04:44:55 2008
@@ -0,0 +1,53 @@
+/* Copyright 1999-2007 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Original Copyright (c) Netmask.IT!® 2006-2007
+ *
+ * DNS Protocol module for Apache 2.x
+ */
+
+#include "../rr.h"
+
+static DNS_RDATA_UNSERIALIZE(a) {
+ dns_rdata_t *rrdata;
+
+ dns_rdata_a_t *addr = apr_pcalloc(pool, sizeof(*addr));
+ *rdata = rrdata = apr_pcalloc(pool, sizeof(*rrdata));
+ dns_init_rdata_const(a, rrdata);
+ rrdata->rdata = addr;
+
+ memcpy(&(addr->address), data, sizeof(apr_uint32_t));
+ addr->address = ntohl(addr->address);
+
+ return APR_SUCCESS;
+}
+
+static DNS_RDATA_SERIALIZE(a) {
+ dns_rdata_a_t *addr;
+ *dlen = sizeof(apr_uint32_t);
+ if (data == NULL)
+ return APR_SUCCESS;
+ addr = (dns_rdata_a_t *)rdata;
+ addr->address = htonl(addr->address);
+ memcpy(data, (const void *)&(addr->address), *dlen);
+ return APR_SUCCESS;
+}
+
+static DNS_RDATA_PSERIALIZE(a)
+
+DNS_RDATA_IMPLEMENT(a);
+
Added: httpd/sandbox/mod_domain/rr/rr_cname.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_domain/rr/rr_cname.c?rev=651222&view=auto
==============================================================================
--- httpd/sandbox/mod_domain/rr/rr_cname.c (added)
+++ httpd/sandbox/mod_domain/rr/rr_cname.c Thu Apr 24 04:44:55 2008
@@ -0,0 +1,95 @@
+/* Copyright 1999-2007 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Original Copyright (c) Netmask.IT!® 2006-2007
+ *
+ * DNS Protocol module for Apache 2.x
+ */
+
+#include "../rr.h"
+#include "apr_strings.h"
+
+static DNS_RDATA_UNSERIALIZE(cname) {
+ const char *ptr = data;
+ char label[63] = ""; /** RFC 1035 says label can only be 63 octets long */
+ apr_byte_t len;
+ dns_rdata_t *rrdata;
+
+ dns_rdata_cname_t *cname = apr_pcalloc(pool, sizeof(*cname));
+ *rdata = rrdata = apr_pcalloc(pool, sizeof(*rrdata));
+ dns_init_rdata_const(cname, rrdata);
+ rrdata->rdata = cname;
+
+ /** initialize cname */
+ cname->cname = apr_pstrdup(pool, "");
+ ;
+ memcpy(&len, ptr, 1);
+ while (len > 0) {
+ ptr++;
+ apr_cpystrn(label, ptr, len + 1);
+ ptr += len;
+ cname->cname = apr_pstrcat(pool, cname->cname, label, ".", NULL);
+ memcpy(&len, ptr, 1);
+ }
+
+ return APR_SUCCESS;
+}
+
+static DNS_RDATA_SERIALIZE(cname) {
+ dns_rdata_cname_t *cname;
+ apr_byte_t llen;
+ char *ptr, *label, *last = NULL;
+ cname = (dns_rdata_cname_t *)rdata;
+ /** The length byte takes the same space as a char, so we just need
+ * strlen(cname) of space (cname should have trailing .) and room
+ * for the first length byte (other length bytes replace "." characters) */
+ *dlen = strlen(cname->cname) + 1;
+ if (cname->cname[*dlen-2] != '.')
+ (*dlen)++;
+
+ if (data == NULL)
+ return APR_SUCCESS;
+
+ /** Point to beginning of data */
+ ptr = data;
+ label = apr_strtok(cname->cname, ".", &last);
+ while (label != NULL) {
+ llen = strlen(label);
+ if (llen == 0) {
+ /** Trailing . - Set NULL and break */
+ *ptr = 0;
+ ptr++;
+ break;
+ }
+ /** Write length token */
+ *ptr = llen;
+ ptr++;
+ /** Write label */
+ memcpy(ptr, label, llen);
+ /** Move pointer */
+ ptr+=llen;
+ /** Advance to next token */
+ label = apr_strtok(NULL, ".", &last);
+ }
+ *ptr = 0;
+ ptr++;
+ return APR_SUCCESS;
+}
+
+static DNS_RDATA_PSERIALIZE(cname)
+
+DNS_RDATA_IMPLEMENT(cname);
Added: httpd/sandbox/mod_domain/rr/rr_mx.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_domain/rr/rr_mx.c?rev=651222&view=auto
==============================================================================
--- httpd/sandbox/mod_domain/rr/rr_mx.c (added)
+++ httpd/sandbox/mod_domain/rr/rr_mx.c Thu Apr 24 04:44:55 2008
@@ -0,0 +1,103 @@
+/* Copyright 1999-2007 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Original Copyright (c) Netmask.IT!® 2006-2007
+ *
+ * DNS Protocol module for Apache 2.x
+ */
+
+#include "../rr.h"
+
+static DNS_RDATA_UNSERIALIZE(mx) {
+ const char *ptr = data;
+ char label[63] = ""; /** RFC 1035 says label can only be 63 octets long */
+ apr_byte_t len;
+ dns_rdata_t *rrdata;
+
+ dns_rdata_mx_t *mx = apr_pcalloc(pool, sizeof(*mx));
+ *rdata = rrdata = apr_pcalloc(pool, sizeof(*rrdata));
+ dns_init_rdata_const(mx, rrdata);
+ rrdata->rdata = mx;
+
+ /** Grab preference */
+ memcpy(&(mx->preference), data, sizeof(apr_uint16_t));
+ data+=sizeof(apr_uint16_t);
+ /** initialize exchange */
+ mx->exchange = apr_pstrdup(pool, "");
+
+ memcpy(&len, ptr, 1);
+ while (len > 0) {
+ ptr++;
+ apr_cpystrn(label, ptr, len + 1);
+ ptr += len;
+ mx->exchange = apr_pstrcat(pool, mx->exchange, label, ".", NULL);
+ memcpy(&len, ptr, 1);
+ }
+
+ return APR_SUCCESS;
+}
+
+static DNS_RDATA_SERIALIZE(mx) {
+ dns_rdata_mx_t *mx;
+ apr_byte_t llen;
+ char *ptr, *label, *last = NULL;
+ mx = (dns_rdata_mx_t *)rdata;
+
+ /** The length byte takes the same space as a char, so we just need
+ * strlen(cname) of space (cname should have trailing .) and room
+ * for the first length byte (other length bytes replace "." characters) */
+
+ *dlen = sizeof(apr_uint16_t) + strlen(mx->exchange) + 1;
+ if (mx->exchange[*dlen-2] != '.')
+ (*dlen)++;
+
+ if (data == NULL)
+ return APR_SUCCESS;
+
+ mx = (dns_rdata_mx_t *)rdata;
+ memcpy(data, (const void *)&(mx->preference), sizeof(apr_uint16_t));
+
+ /** Point to beginning of data */
+ ptr = data;
+ label = apr_strtok(mx->exchange, ".", &last);
+ while (label != NULL) {
+ llen = strlen(label);
+ if (llen == 0) {
+ /** Trailing . - Set NULL and break */
+ *ptr = 0;
+ ptr++;
+ break;
+ }
+ /** Write length token */
+ *ptr = llen;
+ ptr++;
+ /** Write label */
+ memcpy(ptr, label, llen);
+ /** Move pointer */
+ ptr+=llen;
+ /** Advance to next token */
+ label = apr_strtok(NULL, ".", &last);
+ }
+ *ptr = 0;
+ ptr++;
+ return APR_SUCCESS;
+}
+
+static DNS_RDATA_PSERIALIZE(mx)
+
+DNS_RDATA_IMPLEMENT(mx);
+