[master] allow arbitrary-size rndc output
4005. [func] The buffer used for returning text from rndc commands is now dynamically resizable, allowing arbitrarily large amounts of text to be sent back to the client. (Prior to this change, it was possible for the output of "rndc tsig-list" to be truncated.) [RT #37731]
This commit is contained in:
7
CHANGES
7
CHANGES
@@ -1,3 +1,10 @@
|
||||
4005. [func] The buffer used for returning text from rndc
|
||||
commands is now dynamically resizable, allowing
|
||||
arbitrarily large amounts of text to be sent back
|
||||
to the client. (Prior to this change, it was
|
||||
possible for the output of "rndc tsig-list" to be
|
||||
truncated.) [RT #37731]
|
||||
|
||||
4004. [bug] When delegations had AAAA glue but not A, a
|
||||
reference could be leaked causing an assertion
|
||||
failure on shutdown. [RT #37796]
|
||||
|
||||
@@ -59,7 +59,7 @@ command_compare(const char *text, const char *command) {
|
||||
* when a control channel message is received.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
|
||||
ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text) {
|
||||
isccc_sexpr_t *data;
|
||||
char *command = NULL;
|
||||
isc_result_t result;
|
||||
@@ -132,7 +132,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
|
||||
#endif
|
||||
/* Do not flush master files */
|
||||
ns_server_flushonshutdown(ns_g_server, ISC_FALSE);
|
||||
ns_os_shutdownmsg(command, text);
|
||||
ns_os_shutdownmsg(command, *text);
|
||||
isc_app_shutdown();
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (command_compare(command, NS_COMMAND_STOP)) {
|
||||
@@ -149,7 +149,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
|
||||
ns_smf_want_disable = 1;
|
||||
#endif
|
||||
ns_server_flushonshutdown(ns_g_server, ISC_TRUE);
|
||||
ns_os_shutdownmsg(command, text);
|
||||
ns_os_shutdownmsg(command, *text);
|
||||
isc_app_shutdown();
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (command_compare(command, NS_COMMAND_DUMPSTATS)) {
|
||||
@@ -215,6 +215,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
|
||||
result = ns_server_zonestatus(ns_g_server, command, text);
|
||||
} else if (command_compare(command, NS_COMMAND_NTA)) {
|
||||
result = ns_server_nta(ns_g_server, command, text);
|
||||
} else if (command_compare(command, NS_COMMAND_TESTGEN)) {
|
||||
result = ns_server_testgen(command, text);
|
||||
} else {
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
|
||||
|
||||
@@ -83,7 +83,7 @@ struct controlconnection {
|
||||
isc_boolean_t ccmsg_valid;
|
||||
isc_boolean_t sending;
|
||||
isc_timer_t * timer;
|
||||
unsigned char buffer[2048];
|
||||
isc_buffer_t * buffer;
|
||||
controllistener_t * listener;
|
||||
isc_uint32_t nonce;
|
||||
ISC_LINK(controlconnection_t) link;
|
||||
@@ -166,6 +166,9 @@ static void
|
||||
maybe_free_connection(controlconnection_t *conn) {
|
||||
controllistener_t *listener = conn->listener;
|
||||
|
||||
if (conn->buffer != NULL)
|
||||
isc_buffer_free(&conn->buffer);
|
||||
|
||||
if (conn->timer != NULL)
|
||||
isc_timer_detach(&conn->timer);
|
||||
|
||||
@@ -326,15 +329,12 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
controlkey_t *key;
|
||||
isccc_sexpr_t *request = NULL;
|
||||
isccc_sexpr_t *response = NULL;
|
||||
isccc_region_t ccregion;
|
||||
isc_uint32_t algorithm;
|
||||
isccc_region_t secret;
|
||||
isc_stdtime_t now;
|
||||
isc_buffer_t b;
|
||||
isc_region_t r;
|
||||
isc_uint32_t len;
|
||||
isc_buffer_t text;
|
||||
char textarray[2*1024];
|
||||
isc_buffer_t *text;
|
||||
isc_result_t result;
|
||||
isc_result_t eresult;
|
||||
isccc_sexpr_t *_ctrl;
|
||||
@@ -348,6 +348,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
listener = conn->listener;
|
||||
algorithm = DST_ALG_UNKNOWN;
|
||||
secret.rstart = NULL;
|
||||
text = NULL;
|
||||
|
||||
/* Is the server shutting down? */
|
||||
if (listener->controls->shuttingdown)
|
||||
@@ -366,6 +367,8 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
key != NULL;
|
||||
key = ISC_LIST_NEXT(key, link))
|
||||
{
|
||||
isccc_region_t ccregion;
|
||||
|
||||
ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer);
|
||||
ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer);
|
||||
secret.rstart = isc_mem_get(listener->mctx, key->secret.length);
|
||||
@@ -445,7 +448,9 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
goto cleanup_request;
|
||||
}
|
||||
|
||||
isc_buffer_init(&text, textarray, sizeof(textarray));
|
||||
result = isc_buffer_allocate(listener->mctx, &text, 2 * 2048);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_request;
|
||||
|
||||
/*
|
||||
* Establish nonce.
|
||||
@@ -471,12 +476,12 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isc_buffer_usedlength(&text) > 0) {
|
||||
if (isc_buffer_usedlength(text) > 0) {
|
||||
isccc_sexpr_t *data;
|
||||
|
||||
data = isccc_alist_lookup(response, "_data");
|
||||
if (data != NULL) {
|
||||
char *str = (char *)isc_buffer_base(&text);
|
||||
char *str = (char *)isc_buffer_base(text);
|
||||
if (isccc_cc_definestring(data, "text", str) == NULL)
|
||||
goto cleanup_response;
|
||||
}
|
||||
@@ -487,16 +492,26 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL)
|
||||
goto cleanup_response;
|
||||
|
||||
ccregion.rstart = conn->buffer + 4;
|
||||
ccregion.rend = conn->buffer + sizeof(conn->buffer);
|
||||
result = isccc_cc_towire(response, &ccregion, algorithm, &secret);
|
||||
if (conn->buffer == NULL) {
|
||||
result = isc_buffer_allocate(listener->mctx,
|
||||
&conn->buffer, 2 * 2048);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_response;
|
||||
}
|
||||
|
||||
isc_buffer_clear(conn->buffer);
|
||||
/* Skip the length field (4 bytes) */
|
||||
isc_buffer_add(conn->buffer, 4);
|
||||
|
||||
result = isccc_cc_towire(response, &conn->buffer, algorithm, &secret);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_response;
|
||||
isc_buffer_init(&b, conn->buffer, 4);
|
||||
len = sizeof(conn->buffer) - REGION_SIZE(ccregion);
|
||||
isc_buffer_putuint32(&b, len - 4);
|
||||
r.base = conn->buffer;
|
||||
r.length = len;
|
||||
|
||||
isc_buffer_init(&b, conn->buffer->base, 4);
|
||||
isc_buffer_putuint32(&b, conn->buffer->used - 4);
|
||||
|
||||
r.base = conn->buffer->base;
|
||||
r.length = conn->buffer->used;
|
||||
|
||||
result = isc_socket_send(conn->sock, &r, task, control_senddone, conn);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -506,6 +521,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));
|
||||
isccc_sexpr_free(&request);
|
||||
isccc_sexpr_free(&response);
|
||||
isc_buffer_free(&text);
|
||||
return;
|
||||
|
||||
cleanup_response:
|
||||
@@ -514,6 +530,8 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
|
||||
cleanup_request:
|
||||
isccc_sexpr_free(&request);
|
||||
isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));
|
||||
if (text != NULL)
|
||||
isc_buffer_free(&text);
|
||||
|
||||
cleanup:
|
||||
isc_socket_detach(&conn->sock);
|
||||
@@ -549,6 +567,7 @@ newconnection(controllistener_t *listener, isc_socket_t *sock) {
|
||||
isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg);
|
||||
conn->ccmsg_valid = ISC_TRUE;
|
||||
conn->sending = ISC_FALSE;
|
||||
conn->buffer = NULL;
|
||||
conn->timer = NULL;
|
||||
isc_interval_set(&interval, 60, 0);
|
||||
result = isc_timer_create(ns_g_timermgr, isc_timertype_once,
|
||||
@@ -565,12 +584,13 @@ newconnection(controllistener_t *listener, isc_socket_t *sock) {
|
||||
control_recvmessage, conn);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
isccc_ccmsg_setmaxsize(&conn->ccmsg, 2048);
|
||||
|
||||
ISC_LIST_APPEND(listener->connections, conn, link);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
if (conn->buffer != NULL)
|
||||
isc_buffer_free(&conn->buffer);
|
||||
isccc_ccmsg_invalidate(&conn->ccmsg);
|
||||
if (conn->timer != NULL)
|
||||
isc_timer_detach(&conn->timer);
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#define NS_COMMAND_SIGNING "signing"
|
||||
#define NS_COMMAND_ZONESTATUS "zonestatus"
|
||||
#define NS_COMMAND_NTA "nta"
|
||||
#define NS_COMMAND_TESTGEN "testgen"
|
||||
|
||||
isc_result_t
|
||||
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
|
||||
@@ -101,6 +102,6 @@ ns_controls_shutdown(ns_controls_t *controls);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text);
|
||||
ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text);
|
||||
|
||||
#endif /* NAMED_CONTROL_H */
|
||||
|
||||
@@ -235,7 +235,7 @@ ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
/*%<
|
||||
* Act on a "reload" command from the command channel.
|
||||
*/
|
||||
@@ -247,20 +247,20 @@ ns_server_reconfigcommand(ns_server_t *server, char *args);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
/*%<
|
||||
* Act on a "notify" command from the command channel.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
/*%<
|
||||
* Act on a "refresh" command from the command channel.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_server_retransfercommand(ns_server_t *server, char *args,
|
||||
isc_buffer_t *text);
|
||||
isc_buffer_t **text);
|
||||
/*%<
|
||||
* Act on a "retransfer" command from the command channel.
|
||||
*/
|
||||
@@ -314,32 +314,32 @@ ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree);
|
||||
* Report the server's status.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_status(ns_server_t *server, isc_buffer_t *text);
|
||||
ns_server_status(ns_server_t *server, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Report a list of dynamic and static tsig keys, per view.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text);
|
||||
ns_server_tsiglist(ns_server_t *server, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Delete a specific key (with optional view).
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text);
|
||||
ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Enable or disable updates for a zone.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
|
||||
isc_buffer_t *text);
|
||||
isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Dump zone updates to disk, optionally removing the journal file
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_sync(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Update a zone's DNSKEY set from the key repository. If
|
||||
@@ -349,7 +349,7 @@ ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
* take place incrementally.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_rekey(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_rekey(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Dump the current recursive queries.
|
||||
@@ -367,37 +367,44 @@ ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr);
|
||||
* Enable or disable dnssec validation.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_validation(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_validation(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Add a zone to a running process
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Deletes a zone from a running process
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Lists the status of the signing records for a given zone.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_signing(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Lists status information for a given zone (e.g., name, type, files,
|
||||
* load time, expiry, etc).
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Adds a Negative Trust Anchor (NTA) for a specified name and
|
||||
* duration, in a particular view if specified, or in all views.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text);
|
||||
ns_server_nta(ns_server_t *server, char *args, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Generates a test sequence that is only for use in system tests. The
|
||||
* argument is the size of required output in bytes.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_testgen(char *args, isc_buffer_t **text);
|
||||
#endif /* NAMED_SERVER_H */
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
#define TCHECK(op) \
|
||||
do { tresult = (op); \
|
||||
if (tresult != ISC_R_SUCCESS) { \
|
||||
isc_buffer_clear(text); \
|
||||
isc_buffer_clear(*text); \
|
||||
goto cleanup; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -418,10 +418,16 @@ static void
|
||||
newzone_cfgctx_destroy(void **cfgp);
|
||||
|
||||
static isc_result_t
|
||||
putstr(isc_buffer_t *b, const char *str);
|
||||
putstr(isc_buffer_t **b, const char *str);
|
||||
|
||||
static isc_result_t
|
||||
putnull(isc_buffer_t *b);
|
||||
putmem(isc_buffer_t **b, const char *str, size_t len);
|
||||
|
||||
static isc_result_t
|
||||
putuint8(isc_buffer_t **b, isc_uint8_t val);
|
||||
|
||||
static isc_result_t
|
||||
putnull(isc_buffer_t **b);
|
||||
|
||||
isc_result_t
|
||||
add_comment(FILE *fp, const char *viewname);
|
||||
@@ -7138,7 +7144,7 @@ next_token(char **stringp, const char *delim) {
|
||||
static isc_result_t
|
||||
zone_from_args(ns_server_t *server, char *args, const char *zonetxt,
|
||||
dns_zone_t **zonep, const char **zonename,
|
||||
isc_buffer_t *text, isc_boolean_t skip)
|
||||
isc_buffer_t **text, isc_boolean_t skip)
|
||||
{
|
||||
char *input, *ptr;
|
||||
char *classtxt;
|
||||
@@ -7243,7 +7249,7 @@ zone_from_args(ns_server_t *server, char *args, const char *zonetxt,
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_retransfercommand(ns_server_t *server, char *args,
|
||||
isc_buffer_t *text)
|
||||
isc_buffer_t **text)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
@@ -7275,7 +7281,7 @@ ns_server_retransfercommand(ns_server_t *server, char *args,
|
||||
* Act on a "reload" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zonetype_t type;
|
||||
@@ -7316,9 +7322,10 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text))
|
||||
isc_buffer_putmem(text, (const unsigned char *)msg,
|
||||
strlen(msg) + 1);
|
||||
if (msg != NULL) {
|
||||
putstr(text, msg);
|
||||
putnull(text);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -7337,10 +7344,10 @@ ns_server_reconfigcommand(ns_server_t *server, char *args) {
|
||||
* Act on a "notify" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
const unsigned char msg[] = "zone notify queued";
|
||||
const char msg[] = "zone notify queued";
|
||||
|
||||
result = zone_from_args(server, args, NULL, &zone, NULL,
|
||||
text, ISC_TRUE);
|
||||
@@ -7351,8 +7358,8 @@ ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
|
||||
dns_zone_notify(zone);
|
||||
dns_zone_detach(&zone);
|
||||
if (sizeof(msg) <= isc_buffer_availablelength(text))
|
||||
isc_buffer_putmem(text, msg, sizeof(msg));
|
||||
putstr(text, msg);
|
||||
putnull(text);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -7361,11 +7368,12 @@ ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
* Act on a "refresh" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t **text)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL, *raw = NULL;
|
||||
const unsigned char msg1[] = "zone refresh queued";
|
||||
const unsigned char msg2[] = "not a slave or stub zone";
|
||||
const char msg1[] = "zone refresh queued";
|
||||
const char msg2[] = "not a slave or stub zone";
|
||||
dns_zonetype_t type;
|
||||
|
||||
result = zone_from_args(server, args, NULL, &zone, NULL,
|
||||
@@ -7386,14 +7394,14 @@ ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
if (type == dns_zone_slave || type == dns_zone_stub) {
|
||||
dns_zone_refresh(zone);
|
||||
dns_zone_detach(&zone);
|
||||
if (sizeof(msg1) <= isc_buffer_availablelength(text))
|
||||
isc_buffer_putmem(text, msg1, sizeof(msg1));
|
||||
putstr(text, msg1);
|
||||
putnull(text);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_zone_detach(&zone);
|
||||
if (sizeof(msg2) <= isc_buffer_availablelength(text))
|
||||
isc_buffer_putmem(text, msg2, sizeof(msg2));
|
||||
putstr(text, msg2);
|
||||
putnull(text);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
@@ -7969,7 +7977,7 @@ ns_server_setdebuglevel(ns_server_t *server, char *args) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_validation(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_validation(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
char *ptr, *viewname;
|
||||
dns_view_t *view;
|
||||
isc_boolean_t changed = ISC_FALSE;
|
||||
@@ -8016,29 +8024,16 @@ ns_server_validation(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
view->enablevalidation = enable;
|
||||
changed = ISC_TRUE;
|
||||
} else {
|
||||
unsigned int n;
|
||||
if (!first) {
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"\n");
|
||||
if (n >= isc_buffer_availablelength(text)) {
|
||||
result = ISC_R_NOSPACE;
|
||||
goto out;
|
||||
}
|
||||
isc_buffer_add(text, n);
|
||||
}
|
||||
if (!first)
|
||||
putstr(text, "\n");
|
||||
putstr(text, "DNSSEC validation is ");
|
||||
putstr(text, view->enablevalidation
|
||||
? "enabled" : "disabled");
|
||||
putstr(text, " (view ");
|
||||
putstr(text, view->name);
|
||||
putstr(text, ")");
|
||||
putnull(text);
|
||||
first = ISC_FALSE;
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"DNSSEC validation is %s (view %s)",
|
||||
view->enablevalidation ?
|
||||
"enabled" : "disabled",
|
||||
view->name);
|
||||
if (n >= isc_buffer_availablelength(text)) {
|
||||
result = ISC_R_NOSPACE;
|
||||
goto out;
|
||||
}
|
||||
isc_buffer_add(text, n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8280,12 +8275,12 @@ ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_status(ns_server_t *server, isc_buffer_t *text) {
|
||||
ns_server_status(ns_server_t *server, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
unsigned int zonecount, xferrunning, xferdeferred, soaqueries;
|
||||
unsigned int automatic;
|
||||
unsigned int n;
|
||||
const char *ob = "", *cb = "", *alt = "";
|
||||
char boottime[80], configtime[80];
|
||||
char boottime[80], configtime[80], line[1024];
|
||||
|
||||
if (ns_g_server->version_set) {
|
||||
ob = " (";
|
||||
@@ -8310,40 +8305,93 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
|
||||
isc_time_formathttptimestamp(&ns_g_configtime, configtime,
|
||||
sizeof(configtime));
|
||||
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"version: %s%s%s%s <id:%s>\n"
|
||||
"boot time: %s\n"
|
||||
"last configured: %s\n"
|
||||
snprintf(line, sizeof(line), "version: %s%s%s%s <id:%s>\n",
|
||||
ns_g_version, ob, alt, cb, ns_g_srcid);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "boot time: %s\n", boottime);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "last configured: %s\n", configtime);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
"CPUs found: %u\n"
|
||||
"worker threads: %u\n"
|
||||
"UDP listeners per interface: %u\n"
|
||||
snprintf(line, sizeof(line), "CPUs found: %u\n", ns_g_cpus_detected);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "worker threads: %u\n", ns_g_cpus);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "UDP listeners per interface: %u\n",
|
||||
ns_g_udpdisp);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
#endif
|
||||
"number of zones: %u (%u automatic)\n"
|
||||
"debug level: %d\n"
|
||||
"xfers running: %u\n"
|
||||
"xfers deferred: %u\n"
|
||||
"soa queries in progress: %u\n"
|
||||
"query logging is %s\n"
|
||||
"recursive clients: %d/%d/%d\n"
|
||||
"tcp clients: %d/%d\n"
|
||||
"server is up and running",
|
||||
ns_g_version, ob, alt, cb, ns_g_srcid,
|
||||
boottime, configtime,
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
ns_g_cpus_detected, ns_g_cpus, ns_g_udpdisp,
|
||||
#endif
|
||||
zonecount, automatic, ns_g_debuglevel, xferrunning,
|
||||
xferdeferred, soaqueries,
|
||||
server->log_queries ? "ON" : "OFF",
|
||||
snprintf(line, sizeof(line), "number of zones: %u (%u automatic)\n",
|
||||
zonecount, automatic);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "debug level: %d\n", ns_g_debuglevel);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "xfers running: %u\n", xferrunning);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "xfers deferred: %u\n", xferdeferred);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "soa queries in progress: %u\n",
|
||||
soaqueries);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "query logging is %s\n",
|
||||
server->log_queries ? "ON" : "OFF");
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "recursive clients: %d/%d/%d\n",
|
||||
server->recursionquota.used, server->recursionquota.soft,
|
||||
server->recursionquota.max,
|
||||
server->recursionquota.max);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "tcp clients: %d/%d\n",
|
||||
server->tcpquota.used, server->tcpquota.max);
|
||||
if (n >= isc_buffer_availablelength(text))
|
||||
return (ISC_R_NOSPACE);
|
||||
isc_buffer_add(text, n);
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
CHECK(putstr(text, "server is up and running"));
|
||||
CHECK(putnull(text));
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_testgen(char *args, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
char *ptr;
|
||||
unsigned long count;
|
||||
unsigned long i;
|
||||
const unsigned char chars[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
/* Skip the command name. */
|
||||
ptr = next_token(&args, " \t");
|
||||
if (ptr == NULL)
|
||||
return (ISC_R_UNEXPECTEDEND);
|
||||
|
||||
ptr = next_token(&args, " \t");
|
||||
if (ptr == NULL)
|
||||
count = 26;
|
||||
else
|
||||
count = strtoul(ptr, NULL, 10);
|
||||
|
||||
CHECK(isc_buffer_reserve(text, count));
|
||||
for (i = 0; i < count; i++)
|
||||
CHECK(putuint8(text, chars[i % (sizeof(chars) - 1)]));
|
||||
|
||||
CHECK(putnull(text));
|
||||
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -8410,13 +8458,12 @@ delete_keynames(dns_tsig_keyring_t *ring, char *target,
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text) {
|
||||
ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
unsigned int n;
|
||||
dns_view_t *view;
|
||||
unsigned int foundkeys = 0;
|
||||
char *target;
|
||||
char *viewname;
|
||||
char *target, *viewname;
|
||||
char fbuf[16];
|
||||
|
||||
(void)next_token(&command, " \t"); /* skip command name */
|
||||
target = next_token(&command, " \t");
|
||||
@@ -8443,19 +8490,19 @@ ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text) {
|
||||
}
|
||||
isc_task_endexclusive(server->task);
|
||||
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"%d tsig keys deleted.\n", foundkeys);
|
||||
if (n >= isc_buffer_availablelength(text))
|
||||
return (ISC_R_NOSPACE);
|
||||
isc_buffer_add(text, n);
|
||||
snprintf(fbuf, sizeof(fbuf), "%d", foundkeys);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
CHECK(putstr(text, fbuf));
|
||||
CHECK(putstr(text, " tsig keys deleted."));
|
||||
CHECK(putnull(text));
|
||||
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t *text,
|
||||
unsigned int *foundkeys)
|
||||
list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t **text,
|
||||
unsigned int *foundkeys)
|
||||
{
|
||||
char namestr[DNS_NAME_FORMATSIZE];
|
||||
char creatorstr[DNS_NAME_FORMATSIZE];
|
||||
@@ -8466,7 +8513,6 @@ list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t *text,
|
||||
dns_name_t *origin;
|
||||
dns_rbtnode_t *node;
|
||||
dns_tsigkey_t *tkey;
|
||||
unsigned int n;
|
||||
const char *viewname;
|
||||
|
||||
if (view != NULL)
|
||||
@@ -8495,43 +8541,46 @@ list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t *text,
|
||||
tkey = node->data;
|
||||
|
||||
if (tkey != NULL) {
|
||||
(*foundkeys)++;
|
||||
dns_name_format(&tkey->name, namestr, sizeof(namestr));
|
||||
if (tkey->generated) {
|
||||
dns_name_format(tkey->creator, creatorstr,
|
||||
sizeof(creatorstr));
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"view \"%s\"; type \"dynamic\"; key \"%s\"; creator \"%s\";\n",
|
||||
viewname, namestr, creatorstr);
|
||||
if (*foundkeys != 0)
|
||||
putstr(text, "\n");
|
||||
CHECK(putstr(text, "view \""));
|
||||
CHECK(putstr(text, viewname));
|
||||
CHECK(putstr(text,
|
||||
"\"; type \"dynamic\"; key \""));
|
||||
CHECK(putstr(text, namestr));
|
||||
CHECK(putstr(text, "\"; creator \""));
|
||||
CHECK(putstr(text, creatorstr));
|
||||
CHECK(putstr(text, "\";"));
|
||||
} else {
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"view \"%s\"; type \"static\"; key \"%s\";\n",
|
||||
viewname, namestr);
|
||||
if (*foundkeys != 0)
|
||||
putstr(text, "\n");
|
||||
CHECK(putstr(text, "view \""));
|
||||
CHECK(putstr(text, viewname));
|
||||
CHECK(putstr(text,
|
||||
"\"; type \"static\"; key \""));
|
||||
CHECK(putstr(text, namestr));
|
||||
CHECK(putstr(text, "\";"));
|
||||
}
|
||||
if (n >= isc_buffer_availablelength(text)) {
|
||||
dns_rbtnodechain_invalidate(&chain);
|
||||
return (ISC_R_NOSPACE);
|
||||
}
|
||||
isc_buffer_add(text, n);
|
||||
(*foundkeys)++;
|
||||
}
|
||||
result = dns_rbtnodechain_next(&chain, &foundname, origin);
|
||||
if (result == ISC_R_NOMORE)
|
||||
if (result == ISC_R_NOMORE || result == DNS_R_NEWORIGIN)
|
||||
break;
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
||||
dns_rbtnodechain_invalidate(&chain);
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
cleanup:
|
||||
dns_rbtnodechain_invalidate(&chain);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
|
||||
ns_server_tsiglist(ns_server_t *server, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
unsigned int n;
|
||||
dns_view_t *view;
|
||||
unsigned int foundkeys = 0;
|
||||
|
||||
@@ -8559,14 +8608,11 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
|
||||
}
|
||||
isc_task_endexclusive(server->task);
|
||||
|
||||
if (foundkeys == 0) {
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"no tsig keys found.\n");
|
||||
if (n >= isc_buffer_availablelength(text))
|
||||
return (ISC_R_NOSPACE);
|
||||
isc_buffer_add(text, n);
|
||||
}
|
||||
if (foundkeys == 0)
|
||||
putstr(text, "no tsig keys found.");
|
||||
|
||||
if (isc_buffer_usedlength(*text) > 0)
|
||||
putnull(text);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -8575,7 +8621,7 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
|
||||
* Act on a "sign" or "loadkeys" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_rekey(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_rekey(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zonetype_t type;
|
||||
@@ -8641,7 +8687,7 @@ synczone(dns_zone_t *zone, void *uap) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_sync(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result, tresult;
|
||||
dns_view_t *view;
|
||||
dns_zone_t *zone = NULL;
|
||||
@@ -8691,9 +8737,10 @@ ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
result = synczone(zone, &cleanup);
|
||||
isc_task_endexclusive(server->task);
|
||||
|
||||
if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text))
|
||||
isc_buffer_putmem(text, (const unsigned char *)msg,
|
||||
strlen(msg) + 1);
|
||||
if (msg != NULL) {
|
||||
putstr(text, msg);
|
||||
putnull(text);
|
||||
}
|
||||
|
||||
view = dns_zone_getview(zone);
|
||||
if (strcmp(view->name, "_default") == 0 ||
|
||||
@@ -8724,7 +8771,7 @@ ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
|
||||
isc_buffer_t *text)
|
||||
isc_buffer_t **text)
|
||||
{
|
||||
isc_result_t result, tresult;
|
||||
dns_zone_t *zone = NULL, *raw = NULL;
|
||||
@@ -8815,9 +8862,10 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
|
||||
}
|
||||
isc_task_endexclusive(server->task);
|
||||
|
||||
if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text))
|
||||
isc_buffer_putmem(text, (const unsigned char *)msg,
|
||||
strlen(msg) + 1);
|
||||
if (msg != NULL) {
|
||||
putstr(text, msg);
|
||||
putnull(text);
|
||||
}
|
||||
|
||||
view = dns_zone_getview(zone);
|
||||
if (strcmp(view->name, "_default") == 0 ||
|
||||
@@ -8849,16 +8897,8 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
|
||||
* is managed by smf and is also running chroot.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_smf_add_message(isc_buffer_t *text) {
|
||||
unsigned int n;
|
||||
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"use svcadm(1M) to manage named");
|
||||
if (n >= isc_buffer_availablelength(text))
|
||||
return (ISC_R_NOSPACE);
|
||||
isc_buffer_add(text, n);
|
||||
return (ISC_R_SUCCESS);
|
||||
ns_smf_add_message(isc_buffer_t **text) {
|
||||
return (putstr(text, "use svcadm(1M) to manage named"));
|
||||
}
|
||||
#endif /* HAVE_LIBSCF */
|
||||
|
||||
@@ -8883,7 +8923,7 @@ add_comment(FILE *fp, const char *viewname) {
|
||||
* Act on an "addzone" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result, tresult;
|
||||
isc_buffer_t argbuf;
|
||||
size_t arglen;
|
||||
@@ -9042,7 +9082,7 @@ ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
/* Emit the zone name, quoted and escaped */
|
||||
isc_buffer_init(&buf, namebuf, sizeof(namebuf));
|
||||
CHECK(dns_name_totext(dnsname, ISC_TRUE, &buf));
|
||||
putnull(&buf);
|
||||
isc_buffer_putuint8(&buf, 0);
|
||||
CHECK(isc_stdio_write("zone \"", 6, 1, fp, NULL));
|
||||
CHECK(isc_stdio_write(namebuf, strlen(namebuf), 1, fp, NULL));
|
||||
CHECK(isc_stdio_write("\" ", 2, 1, fp, NULL));
|
||||
@@ -9081,7 +9121,7 @@ ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (isc_buffer_usedlength(text) > 0)
|
||||
if (isc_buffer_usedlength(*text) > 0)
|
||||
putnull(text);
|
||||
if (fp != NULL)
|
||||
isc_stdio_close(fp);
|
||||
@@ -9099,18 +9139,16 @@ ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
inuse(const char* file, isc_boolean_t first, isc_buffer_t *text) {
|
||||
inuse(const char* file, isc_boolean_t first, isc_buffer_t **text) {
|
||||
#define INUSEMSG "The following files were in use and may now be removed:\n"
|
||||
|
||||
if (file != NULL && isc_file_exists(file) &&
|
||||
isc_buffer_availablelength(text) >
|
||||
strlen(file) + (first ? sizeof(INUSEMSG) : sizeof("\n")))
|
||||
{
|
||||
if (file != NULL && isc_file_exists(file)) {
|
||||
if (first)
|
||||
(void) putstr(text, INUSEMSG);
|
||||
else
|
||||
(void) putstr(text, "\n");
|
||||
(void) putstr(text, file);
|
||||
putnull(text);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
return (first);
|
||||
@@ -9120,7 +9158,7 @@ inuse(const char* file, isc_boolean_t first, isc_buffer_t *text) {
|
||||
* Act on a "delzone" command from the command channel.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zone_t *raw = NULL;
|
||||
@@ -9346,7 +9384,7 @@ ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (isc_buffer_usedlength(text) > 0)
|
||||
if (isc_buffer_usedlength(*text) > 0)
|
||||
putnull(text);
|
||||
if (exclusive)
|
||||
isc_task_endexclusive(server->task);
|
||||
@@ -9429,7 +9467,7 @@ generate_salt(unsigned char *salt, size_t saltlen) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_signing(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_name_t *origin;
|
||||
@@ -9576,21 +9614,13 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
|
||||
isc_buffer_init(&buf, output, sizeof(output));
|
||||
CHECK(dns_private_totext(&priv, &buf));
|
||||
|
||||
if (!first)
|
||||
putstr(text, "\n");
|
||||
CHECK(putstr(text, "\n"));
|
||||
CHECK(putstr(text, output));
|
||||
first = ISC_FALSE;
|
||||
|
||||
n = snprintf((char *)isc_buffer_used(text),
|
||||
isc_buffer_availablelength(text),
|
||||
"%s", output);
|
||||
if (n >= isc_buffer_availablelength(text))
|
||||
CHECK(ISC_R_NOSPACE);
|
||||
|
||||
isc_buffer_add(text, (unsigned int)n);
|
||||
}
|
||||
if (!first)
|
||||
putnull(text);
|
||||
CHECK(putnull(text));
|
||||
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
@@ -9612,30 +9642,41 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
putstr(isc_buffer_t *b, const char *str) {
|
||||
unsigned int l = strlen(str);
|
||||
putmem(isc_buffer_t **b, const char *str, size_t len) {
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* Use >= to leave space for NUL termination.
|
||||
*/
|
||||
if (l >= isc_buffer_availablelength(b))
|
||||
result = isc_buffer_reserve(b, len);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
isc_buffer_putmem(b, (const unsigned char *)str, l);
|
||||
isc_buffer_putmem(*b, (const unsigned char *)str, len);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
putstr(isc_buffer_t **b, const char *str) {
|
||||
return (putmem(b, str, strlen(str)));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
putnull(isc_buffer_t *b) {
|
||||
if (isc_buffer_availablelength(b) == 0)
|
||||
putuint8(isc_buffer_t **b, isc_uint8_t val) {
|
||||
isc_result_t result;
|
||||
|
||||
result = isc_buffer_reserve(b, 1);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
isc_buffer_putuint8(b, 0);
|
||||
isc_buffer_putuint8(*b, val);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
putnull(isc_buffer_t **b) {
|
||||
return (putuint8(b, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_zone_t *zone = NULL, *raw = NULL;
|
||||
const char *type, *file, *zonename = NULL;
|
||||
@@ -9907,7 +9948,7 @@ argcheck(char *cmd, const char *full) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
ns_server_nta(ns_server_t *server, char *args, isc_buffer_t **text) {
|
||||
dns_view_t *view;
|
||||
dns_ntatable_t *ntatable = NULL;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
@@ -10083,10 +10124,7 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
|
||||
nametext, view->name);
|
||||
}
|
||||
|
||||
if (isc_buffer_availablelength(text) == 0)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
isc_buffer_putuint8(text, 0);
|
||||
CHECK(putnull(text));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
@@ -73,7 +73,7 @@ static int nserveraddrs;
|
||||
static int currentaddr = 0;
|
||||
static unsigned int remoteport = 0;
|
||||
static isc_socketmgr_t *socketmgr = NULL;
|
||||
static unsigned char databuf[2048];
|
||||
static isc_buffer_t *databuf;
|
||||
static isccc_ccmsg_t ccmsg;
|
||||
static isc_uint32_t algorithm;
|
||||
static isccc_region_t secret;
|
||||
@@ -306,8 +306,6 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
|
||||
isccc_time_t now;
|
||||
isc_region_t r;
|
||||
isccc_sexpr_t *data;
|
||||
isccc_region_t message;
|
||||
isc_uint32_t len;
|
||||
isc_buffer_t b;
|
||||
|
||||
recvs--;
|
||||
@@ -354,15 +352,19 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
|
||||
if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL)
|
||||
fatal("out of memory");
|
||||
}
|
||||
message.rstart = databuf + 4;
|
||||
message.rend = databuf + sizeof(databuf);
|
||||
|
||||
isc_buffer_clear(databuf);
|
||||
/* Skip the length field (4 bytes) */
|
||||
isc_buffer_add(databuf, 4);
|
||||
|
||||
DO("render message",
|
||||
isccc_cc_towire(request, &message, algorithm, &secret));
|
||||
len = sizeof(databuf) - REGION_SIZE(message);
|
||||
isc_buffer_init(&b, databuf, 4);
|
||||
isc_buffer_putuint32(&b, len - 4);
|
||||
r.length = len;
|
||||
r.base = databuf;
|
||||
isccc_cc_towire(request, &databuf, algorithm, &secret));
|
||||
|
||||
isc_buffer_init(&b, databuf->base, 4);
|
||||
isc_buffer_putuint32(&b, databuf->used - 4);
|
||||
|
||||
r.base = databuf->base;
|
||||
r.length = databuf->used;
|
||||
|
||||
isccc_ccmsg_cancelread(&ccmsg);
|
||||
DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task,
|
||||
@@ -384,9 +386,7 @@ rndc_connected(isc_task_t *task, isc_event_t *event) {
|
||||
isccc_sexpr_t *request = NULL;
|
||||
isccc_sexpr_t *data;
|
||||
isccc_time_t now;
|
||||
isccc_region_t message;
|
||||
isc_region_t r;
|
||||
isc_uint32_t len;
|
||||
isc_buffer_t b;
|
||||
isc_result_t result;
|
||||
|
||||
@@ -417,15 +417,19 @@ rndc_connected(isc_task_t *task, isc_event_t *event) {
|
||||
fatal("_data section missing");
|
||||
if (isccc_cc_definestring(data, "type", "null") == NULL)
|
||||
fatal("out of memory");
|
||||
message.rstart = databuf + 4;
|
||||
message.rend = databuf + sizeof(databuf);
|
||||
|
||||
isc_buffer_clear(databuf);
|
||||
/* Skip the length field (4 bytes) */
|
||||
isc_buffer_add(databuf, 4);
|
||||
|
||||
DO("render message",
|
||||
isccc_cc_towire(request, &message, algorithm, &secret));
|
||||
len = sizeof(databuf) - REGION_SIZE(message);
|
||||
isc_buffer_init(&b, databuf, 4);
|
||||
isc_buffer_putuint32(&b, len - 4);
|
||||
r.length = len;
|
||||
r.base = databuf;
|
||||
isccc_cc_towire(request, &databuf, algorithm, &secret));
|
||||
|
||||
isc_buffer_init(&b, databuf->base, 4);
|
||||
isc_buffer_putuint32(&b, databuf->used - 4);
|
||||
|
||||
r.base = databuf->base;
|
||||
r.length = databuf->used;
|
||||
|
||||
isccc_ccmsg_init(mctx, sock, &ccmsg);
|
||||
isccc_ccmsg_setmaxsize(&ccmsg, 1024 * 1024);
|
||||
@@ -875,6 +879,9 @@ main(int argc, char **argv) {
|
||||
|
||||
command = *argv;
|
||||
|
||||
DO("allocate data buffer",
|
||||
isc_buffer_allocate(mctx, &databuf, 2048));
|
||||
|
||||
/*
|
||||
* Convert argc/argv into a space-delimited command string
|
||||
* similar to what the user might enter in interactive mode
|
||||
@@ -931,6 +938,8 @@ main(int argc, char **argv) {
|
||||
|
||||
dns_name_destroy();
|
||||
|
||||
isc_buffer_free(&databuf);
|
||||
|
||||
if (show_final_mem)
|
||||
isc_mem_stats(mctx, stderr);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ top_srcdir = @top_srcdir@
|
||||
|
||||
@BIND9_MAKE_INCLUDES@
|
||||
|
||||
SUBDIRS = builtin dlzexternal filter-aaaa geoip lwresd resolver rpz \
|
||||
SUBDIRS = builtin dlzexternal filter-aaaa geoip lwresd resolver rndc rpz \
|
||||
rsabigexponent tkey tsiggss
|
||||
TARGETS =
|
||||
|
||||
|
||||
55
bin/tests/system/rndc/Makefile.in
Normal file
55
bin/tests/system/rndc/Makefile.in
Normal file
@@ -0,0 +1,55 @@
|
||||
# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id$
|
||||
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@BIND9_VERSION@
|
||||
|
||||
@BIND9_MAKE_INCLUDES@
|
||||
|
||||
CINCLUDES =
|
||||
|
||||
CDEFINES =
|
||||
CWARNINGS =
|
||||
|
||||
DNSLIBS =
|
||||
ISCLIBS = .
|
||||
|
||||
DNSDEPLIBS =
|
||||
ISCDEPLIBS =
|
||||
|
||||
DEPLIBS =
|
||||
|
||||
LIBS = @LIBS@
|
||||
|
||||
TARGETS = gencheck@EXEEXT@
|
||||
|
||||
GENCHECKOBJS = gencheck.@O@
|
||||
|
||||
SRCS = gencheck.c
|
||||
|
||||
@BIND9_MAKE_RULES@
|
||||
|
||||
all: gencheck@EXEEXT@
|
||||
|
||||
gencheck@EXEEXT@: ${GENCHECKOBJS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${GENCHECKOBJS} ${LIBS}
|
||||
|
||||
clean distclean::
|
||||
rm -f ${TARGETS}
|
||||
@@ -22,3 +22,4 @@ rm -f ns*/named.memstats
|
||||
rm -f ns*/named.run
|
||||
rm -f ns4/*.conf
|
||||
rm -f rndc.status
|
||||
rm -f rndc.output
|
||||
|
||||
88
bin/tests/system/rndc/gencheck.c
Normal file
88
bin/tests/system/rndc/gencheck.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define USAGE "usage: gencheck <filename>\n"
|
||||
|
||||
static int
|
||||
check(const char *buf, ssize_t count, size_t *start) {
|
||||
const char chars[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
ssize_t i;
|
||||
|
||||
for (i = 0; i < count; i++, *start = (*start + 1) % (sizeof(chars) - 1)) {
|
||||
/* Just ignore the trailing newline */
|
||||
if (buf[i] == '\n')
|
||||
continue;
|
||||
if (buf[i] != chars[*start])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
ssize_t count;
|
||||
char buf[1024];
|
||||
size_t start;
|
||||
size_t length;
|
||||
|
||||
ret = EXIT_FAILURE;
|
||||
fd = -1;
|
||||
length = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
fputs(USAGE, stderr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = open(argv[1], O_RDONLY);
|
||||
if (fd == -1)
|
||||
goto out;
|
||||
|
||||
start = 0;
|
||||
while ((count = read(fd, buf, sizeof(buf))) != 0) {
|
||||
if (count < 0)
|
||||
goto out;
|
||||
|
||||
if (!check(buf, count, &start))
|
||||
goto out;
|
||||
|
||||
length += count;
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
out:
|
||||
printf("%zu\n", length);
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -384,5 +384,24 @@ $RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf nta -l 2h nta1.example 2>&1 | grep "
|
||||
$RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf nta -l 1d nta2.example 2>&1 | grep "Negative trust anchor added" > /dev/null || ret=1
|
||||
$RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf nta -l 1w nta3.example 2>&1 | grep "Negative trust anchor added" > /dev/null || ret=1
|
||||
$RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf nta -l 8d nta4.example 2>&1 | grep "NTA lifetime cannot exceed one week" > /dev/null || ret=1
|
||||
echo "I:exit status: $status"
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
for i in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288
|
||||
do
|
||||
echo "I:testing rndc buffer size limits (size=${i})"
|
||||
ret=0
|
||||
$RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf testgen ${i} 2>&1 > rndc.output || ret=1
|
||||
actual_size=`./gencheck rndc.output`
|
||||
if [ "$?" = "0" ]; then
|
||||
expected_size=`expr $i + 1`
|
||||
if [ $actual_size != $expected_size ]; then ret=1; fi
|
||||
else
|
||||
ret=1
|
||||
fi
|
||||
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
done
|
||||
|
||||
exit $status
|
||||
|
||||
3
configure
vendored
3
configure
vendored
@@ -21724,7 +21724,7 @@ ac_config_commands="$ac_config_commands chmod"
|
||||
# elsewhere if there's a good reason for doing so.
|
||||
#
|
||||
|
||||
ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/builtin/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/resolver/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-latex.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/tests/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh"
|
||||
ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/builtin/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/resolver/Makefile bin/tests/system/rndc/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-latex.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/tests/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh"
|
||||
|
||||
|
||||
#
|
||||
@@ -22777,6 +22777,7 @@ do
|
||||
"bin/tests/system/inline/checkdsa.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/inline/checkdsa.sh" ;;
|
||||
"bin/tests/system/lwresd/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/lwresd/Makefile" ;;
|
||||
"bin/tests/system/resolver/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/resolver/Makefile" ;;
|
||||
"bin/tests/system/rndc/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rndc/Makefile" ;;
|
||||
"bin/tests/system/rpz/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rpz/Makefile" ;;
|
||||
"bin/tests/system/rsabigexponent/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rsabigexponent/Makefile" ;;
|
||||
"bin/tests/system/sit/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/sit/prereq.sh" ;;
|
||||
|
||||
@@ -4535,6 +4535,7 @@ AC_CONFIG_FILES([
|
||||
bin/tests/system/inline/checkdsa.sh
|
||||
bin/tests/system/lwresd/Makefile
|
||||
bin/tests/system/resolver/Makefile
|
||||
bin/tests/system/rndc/Makefile
|
||||
bin/tests/system/rpz/Makefile
|
||||
bin/tests/system/rsabigexponent/Makefile
|
||||
bin/tests/system/sit/prereq.sh
|
||||
|
||||
@@ -275,6 +275,14 @@
|
||||
name format is found to exist, it will continue to be used.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
"rndc" can now return text output of arbitrary size to
|
||||
the caller. (Prior to this, certain commands such as
|
||||
"rndc tsig-list" and "rndc zonestatus" could return
|
||||
truncated output.)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="relnotes_bugs">
|
||||
|
||||
@@ -199,9 +199,9 @@ dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now,
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t *buf);
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf);
|
||||
/*%<
|
||||
* Dump the NTA table to buffer 'buf'
|
||||
* Dump the NTA table to buffer at 'buf'
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
|
||||
@@ -501,7 +501,7 @@ dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now,
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t *buf) {
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node;
|
||||
dns_rbtnodechain_t chain;
|
||||
@@ -539,11 +539,12 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t *buf) {
|
||||
n->expiry < now ? "expired" : "expiry",
|
||||
tbuf);
|
||||
first = ISC_FALSE;
|
||||
if (strlen(obuf) >= isc_buffer_availablelength(buf)) {
|
||||
result = isc_buffer_reserve(buf, strlen(obuf));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
result = ISC_R_NOSPACE;
|
||||
goto cleanup;
|
||||
} else
|
||||
isc_buffer_putstr(buf, obuf);
|
||||
}
|
||||
isc_buffer_putstr(*buf, obuf);
|
||||
}
|
||||
result = dns_rbtnodechain_next(&chain, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
||||
@@ -553,8 +554,9 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t *buf) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isc_buffer_availablelength(buf) != 0)
|
||||
isc_buffer_putuint8(buf, 0);
|
||||
isc_buffer_reserve(buf, 1);
|
||||
if (isc_buffer_availablelength(*buf) != 0)
|
||||
isc_buffer_putuint8(*buf, 0);
|
||||
|
||||
cleanup:
|
||||
dns_rbtnodechain_invalidate(&chain);
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: buffer.c,v 1.49 2008/09/25 04:02:39 tbox Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <config.h>
|
||||
@@ -467,6 +465,63 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
|
||||
isc_buffer_t *dbuf;
|
||||
|
||||
REQUIRE(dynbuffer != NULL);
|
||||
REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
|
||||
|
||||
if ((*dynbuffer)->length > length)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
/*
|
||||
* XXXMUKS: This is far more expensive than plain realloc() as
|
||||
* it doesn't remap pages, but does ordinary copy. So is
|
||||
* isc_mem_reallocate(), which has additional issues.
|
||||
*/
|
||||
dbuf = isc_mem_get((*dynbuffer)->mctx, length + sizeof(isc_buffer_t));
|
||||
if (dbuf == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
memmove(dbuf, *dynbuffer, (*dynbuffer)->length + sizeof(isc_buffer_t));
|
||||
isc_mem_put(dbuf->mctx, *dynbuffer,
|
||||
(*dynbuffer)->length + sizeof(isc_buffer_t));
|
||||
|
||||
dbuf->base = ((unsigned char *)dbuf) + sizeof(isc_buffer_t);
|
||||
dbuf->length = length;
|
||||
|
||||
INSIST(ISC_BUFFER_VALID(dbuf));
|
||||
|
||||
*dynbuffer = dbuf;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) {
|
||||
isc_uint64_t len;
|
||||
|
||||
REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
|
||||
|
||||
len = (*dynbuffer)->length;
|
||||
if ((len - (*dynbuffer)->used) > size)
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/* Round to nearest buffer size increment */
|
||||
len += size;
|
||||
len = (len + ISC_BUFFER_INCR - 1 - ((len - 1) % ISC_BUFFER_INCR));
|
||||
|
||||
/* Cap at UINT_MAX */
|
||||
if (len > UINT_MAX) {
|
||||
len = UINT_MAX;
|
||||
if ((len - (*dynbuffer)->used) < size)
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
return (isc_buffer_reallocate(dynbuffer, (unsigned int) len));
|
||||
}
|
||||
|
||||
void
|
||||
isc_buffer_free(isc_buffer_t **dynbuffer) {
|
||||
unsigned int real_length;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: buffer.h,v 1.55 2010/12/20 23:47:21 tbox Exp $ */
|
||||
|
||||
#ifndef ISC_BUFFER_H
|
||||
#define ISC_BUFFER_H 1
|
||||
|
||||
@@ -127,6 +125,13 @@ ISC_LANG_BEGINDECLS
|
||||
#define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC)
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* Size granularity for dynamically resizeable buffers; when reserving
|
||||
* space in a buffer, we round the allocated buffer length up to the
|
||||
* nearest * multiple of this value.
|
||||
*/
|
||||
#define ISC_BUFFER_INCR 2048
|
||||
|
||||
/*
|
||||
* The following macros MUST be used only on valid buffers. It is the
|
||||
* caller's responsibility to ensure this by using the ISC_BUFFER_VALID
|
||||
@@ -205,6 +210,50 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
|
||||
*\li Changing the buffer's length field is not permitted.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length);
|
||||
/*!<
|
||||
* \brief Reallocate the buffer to be "length" bytes long. The buffer
|
||||
* pointer may move when you call this function.
|
||||
*
|
||||
* Requires:
|
||||
*\li "dynbuffer" is not NULL.
|
||||
*
|
||||
*\li "*dynbuffer" is a valid dynamic buffer.
|
||||
*
|
||||
*\li 'length' > current length of buffer.
|
||||
*
|
||||
* Returns:
|
||||
*\li ISC_R_SUCCESS - success
|
||||
*\li ISC_R_NOMEMORY - no memory available
|
||||
*
|
||||
* Ensures:
|
||||
*\li "*dynbuffer" will be valid on return and will contain all the
|
||||
* original data. However, the buffer pointer may be moved during
|
||||
* reallocation.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size);
|
||||
/*!<
|
||||
* \brief Make "size" bytes of space available in the buffer. The buffer
|
||||
* pointer may move when you call this function.
|
||||
*
|
||||
* Requires:
|
||||
*\li "dynbuffer" is not NULL.
|
||||
*
|
||||
*\li "*dynbuffer" is a valid dynamic buffer.
|
||||
*
|
||||
* Returns:
|
||||
*\li ISC_R_SUCCESS - success
|
||||
*\li ISC_R_NOMEMORY - no memory available
|
||||
*
|
||||
* Ensures:
|
||||
*\li "*dynbuffer" will be valid on return and will contain all the
|
||||
* original data. However, the buffer pointer may be moved during
|
||||
* reallocation.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_buffer_free(isc_buffer_t **dynbuffer);
|
||||
/*!<
|
||||
|
||||
@@ -40,7 +40,7 @@ SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \
|
||||
sockaddr_test.c symtab_test.c task_test.c queue_test.c \
|
||||
parse_test.c pool_test.c print_test.c regex_test.c \
|
||||
socket_test.c safe_test.c time_test.c aes_test.c \
|
||||
file_test.c
|
||||
file_test.c buffer_test.c
|
||||
|
||||
SUBDIRS =
|
||||
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
|
||||
@@ -49,7 +49,7 @@ TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
|
||||
queue_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \
|
||||
print_test@EXEEXT@ regex_test@EXEEXT@ socket_test@EXEEXT@ \
|
||||
safe_test@EXEEXT@ time_test@EXEEXT@ aes_test@EXEEXT@ \
|
||||
file_test@EXEEXT@
|
||||
file_test@EXEEXT@ buffer_test@EXEEXT@
|
||||
|
||||
@BIND9_MAKE_RULES@
|
||||
|
||||
@@ -125,6 +125,10 @@ file_test@EXEEXT@: file_test.@O@ ${ISCDEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||
file_test.@O@ ${ISCLIBS} ${LIBS}
|
||||
|
||||
buffer_test@EXEEXT@: buffer_test.@O@ ${ISCDEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||
buffer_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
|
||||
|
||||
unit::
|
||||
sh ${top_srcdir}/unit/unittest.sh
|
||||
|
||||
|
||||
144
lib/isc/tests/buffer_test.c
Normal file
144
lib/isc/tests/buffer_test.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#include "isctest.h"
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/result.h>
|
||||
|
||||
ATF_TC(isc_buffer_reserve);
|
||||
ATF_TC_HEAD(isc_buffer_reserve, tc) {
|
||||
atf_tc_set_md_var(tc, "descr", "reserve space in dynamic buffers");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(isc_buffer_reserve, tc) {
|
||||
isc_result_t result;
|
||||
isc_buffer_t *b;
|
||||
|
||||
result = isc_test_begin(NULL, ISC_TRUE);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
b = NULL;
|
||||
result = isc_buffer_allocate(mctx, &b, 1024);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
ATF_CHECK_EQ(b->length, 1024);
|
||||
|
||||
/*
|
||||
* 1024 bytes should already be available, so this call does
|
||||
* nothing.
|
||||
*/
|
||||
result = isc_buffer_reserve(&b, 1024);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 1024);
|
||||
|
||||
/*
|
||||
* This call should grow it to 2048 bytes as only 1024 bytes are
|
||||
* available in the buffer.
|
||||
*/
|
||||
result = isc_buffer_reserve(&b, 1025);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 2048);
|
||||
|
||||
/*
|
||||
* 2048 bytes should already be available, so this call does
|
||||
* nothing.
|
||||
*/
|
||||
result = isc_buffer_reserve(&b, 2048);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 2048);
|
||||
|
||||
/*
|
||||
* This call should grow it to 4096 bytes as only 2048 bytes are
|
||||
* available in the buffer.
|
||||
*/
|
||||
result = isc_buffer_reserve(&b, 2049);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 4096);
|
||||
|
||||
/* Consume some of the buffer so we can run the next test. */
|
||||
isc_buffer_add(b, 4096);
|
||||
|
||||
/*
|
||||
* This call should fail and leave buffer untouched.
|
||||
*/
|
||||
result = isc_buffer_reserve(&b, UINT_MAX);
|
||||
ATF_CHECK_EQ(result, ISC_R_NOMEMORY);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 4096);
|
||||
|
||||
isc_buffer_free(&b);
|
||||
|
||||
isc_test_end();
|
||||
}
|
||||
|
||||
ATF_TC(isc_buffer_reallocate);
|
||||
ATF_TC_HEAD(isc_buffer_reallocate, tc) {
|
||||
atf_tc_set_md_var(tc, "descr", "reallocate dynamic buffers");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(isc_buffer_reallocate, tc) {
|
||||
isc_result_t result;
|
||||
isc_buffer_t *b;
|
||||
|
||||
result = isc_test_begin(NULL, ISC_TRUE);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
b = NULL;
|
||||
result = isc_buffer_allocate(mctx, &b, 1024);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
ATF_CHECK_EQ(b->length, 1024);
|
||||
|
||||
result = isc_buffer_reallocate(&b, 512);
|
||||
ATF_CHECK_EQ(result, ISC_R_NOSPACE);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 1024);
|
||||
|
||||
result = isc_buffer_reallocate(&b, 1536);
|
||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
ATF_CHECK(ISC_BUFFER_VALID(b));
|
||||
ATF_CHECK_EQ(b->length, 1536);
|
||||
|
||||
isc_buffer_free(&b);
|
||||
|
||||
isc_test_end();
|
||||
}
|
||||
|
||||
/*
|
||||
* Main
|
||||
*/
|
||||
ATF_TP_ADD_TCS(tp) {
|
||||
ATF_TP_ADD_TC(tp, isc_buffer_reserve);
|
||||
ATF_TP_ADD_TC(tp, isc_buffer_reallocate);
|
||||
return (atf_no_error());
|
||||
}
|
||||
@@ -159,6 +159,8 @@ isc_buffer_getuint16
|
||||
isc_buffer_getuint32
|
||||
isc_buffer_getuint8
|
||||
isc_buffer_reinit
|
||||
isc_buffer_reallocate
|
||||
isc_buffer_reserve
|
||||
isc_bufferlist_availablecount
|
||||
isc_bufferlist_usedcount
|
||||
isc_commandline_parse
|
||||
|
||||
136
lib/isccc/cc.c
136
lib/isccc/cc.c
@@ -108,84 +108,102 @@ static unsigned char auth_hsha[] = {
|
||||
#define HSHA_LENGTH 88
|
||||
|
||||
static isc_result_t
|
||||
table_towire(isccc_sexpr_t *alist, isccc_region_t *target);
|
||||
table_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer);
|
||||
|
||||
static isc_result_t
|
||||
list_towire(isccc_sexpr_t *alist, isccc_region_t *target);
|
||||
list_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer);
|
||||
|
||||
static isc_result_t
|
||||
value_towire(isccc_sexpr_t *elt, isccc_region_t *target)
|
||||
value_towire(isccc_sexpr_t *elt, isc_buffer_t **buffer)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned char *lenp;
|
||||
isccc_region_t *vr;
|
||||
isc_result_t result;
|
||||
|
||||
if (isccc_sexpr_binaryp(elt)) {
|
||||
vr = isccc_sexpr_tobinary(elt);
|
||||
len = REGION_SIZE(*vr);
|
||||
if (REGION_SIZE(*target) < 1 + 4 + len)
|
||||
result = isc_buffer_reserve(buffer, 1 + 4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
PUT8(ISCCC_CCMSGTYPE_BINARYDATA, target->rstart);
|
||||
PUT32(len, target->rstart);
|
||||
if (REGION_SIZE(*target) < len)
|
||||
isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_BINARYDATA);
|
||||
isc_buffer_putuint32(*buffer, len);
|
||||
|
||||
result = isc_buffer_reserve(buffer, len);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
PUT_MEM(vr->rstart, len, target->rstart);
|
||||
isc_buffer_putmem(*buffer, vr->rstart, len);
|
||||
} else if (isccc_alist_alistp(elt)) {
|
||||
if (REGION_SIZE(*target) < 1 + 4)
|
||||
unsigned int used;
|
||||
isc_buffer_t b;
|
||||
|
||||
result = isc_buffer_reserve(buffer, 1 + 4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
PUT8(ISCCC_CCMSGTYPE_TABLE, target->rstart);
|
||||
isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_TABLE);
|
||||
/*
|
||||
* Emit a placeholder length.
|
||||
*/
|
||||
lenp = target->rstart;
|
||||
PUT32(0, target->rstart);
|
||||
used = (*buffer)->used;
|
||||
isc_buffer_putuint32(*buffer, 0);
|
||||
|
||||
/*
|
||||
* Emit the table.
|
||||
*/
|
||||
result = table_towire(elt, target);
|
||||
result = table_towire(elt, buffer);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
len = (unsigned int)(target->rstart - lenp);
|
||||
|
||||
len = (*buffer)->used - used;
|
||||
/*
|
||||
* 'len' is 4 bytes too big, since it counts
|
||||
* the placeholder length too. Adjust and
|
||||
* the placeholder length too. Adjust and
|
||||
* emit.
|
||||
*/
|
||||
INSIST(len >= 4U);
|
||||
len -= 4;
|
||||
PUT32(len, lenp);
|
||||
|
||||
isc_buffer_init(&b, (unsigned char *) (*buffer)->base + used, 4);
|
||||
isc_buffer_putuint32(&b, len);
|
||||
} else if (isccc_sexpr_listp(elt)) {
|
||||
if (REGION_SIZE(*target) < 1 + 4)
|
||||
unsigned int used;
|
||||
isc_buffer_t b;
|
||||
|
||||
result = isc_buffer_reserve(buffer, 1 + 4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
PUT8(ISCCC_CCMSGTYPE_LIST, target->rstart);
|
||||
isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_LIST);
|
||||
/*
|
||||
* Emit a placeholder length and count.
|
||||
* Emit a placeholder length.
|
||||
*/
|
||||
lenp = target->rstart;
|
||||
PUT32(0, target->rstart);
|
||||
used = (*buffer)->used;
|
||||
isc_buffer_putuint32(*buffer, 0);
|
||||
|
||||
/*
|
||||
* Emit the list.
|
||||
*/
|
||||
result = list_towire(elt, target);
|
||||
result = list_towire(elt, buffer);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
len = (unsigned int)(target->rstart - lenp);
|
||||
|
||||
len = (*buffer)->used - used;
|
||||
/*
|
||||
* 'len' is 4 bytes too big, since it counts
|
||||
* the placeholder length. Adjust and emit.
|
||||
* the placeholder length too. Adjust and
|
||||
* emit.
|
||||
*/
|
||||
INSIST(len >= 4U);
|
||||
len -= 4;
|
||||
PUT32(len, lenp);
|
||||
|
||||
isc_buffer_init(&b, (unsigned char *) (*buffer)->base + used, 4);
|
||||
isc_buffer_putuint32(&b, len);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
table_towire(isccc_sexpr_t *alist, isccc_region_t *target)
|
||||
{
|
||||
table_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer) {
|
||||
isccc_sexpr_t *kv, *elt, *k, *v;
|
||||
char *ks;
|
||||
isc_result_t result;
|
||||
@@ -203,14 +221,15 @@ table_towire(isccc_sexpr_t *alist, isccc_region_t *target)
|
||||
/*
|
||||
* Emit the key name.
|
||||
*/
|
||||
if (REGION_SIZE(*target) < 1 + len)
|
||||
result = isc_buffer_reserve(buffer, 1 + len);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
PUT8(len, target->rstart);
|
||||
PUT_MEM(ks, len, target->rstart);
|
||||
isc_buffer_putuint8(*buffer, len);
|
||||
isc_buffer_putmem(*buffer, (const unsigned char *) ks, len);
|
||||
/*
|
||||
* Emit the value.
|
||||
*/
|
||||
result = value_towire(v, target);
|
||||
result = value_towire(v, buffer);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
@@ -219,12 +238,11 @@ table_towire(isccc_sexpr_t *alist, isccc_region_t *target)
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
list_towire(isccc_sexpr_t *list, isccc_region_t *target)
|
||||
{
|
||||
list_towire(isccc_sexpr_t *list, isc_buffer_t **buffer) {
|
||||
isc_result_t result;
|
||||
|
||||
while (list != NULL) {
|
||||
result = value_towire(ISCCC_SEXPR_CAR(list), target);
|
||||
result = value_towire(ISCCC_SEXPR_CAR(list), buffer);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
list = ISCCC_SEXPR_CDR(list);
|
||||
@@ -324,24 +342,24 @@ sign(unsigned char *data, unsigned int length, unsigned char *hmac,
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target,
|
||||
isccc_cc_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer,
|
||||
isc_uint32_t algorithm, isccc_region_t *secret)
|
||||
{
|
||||
unsigned char *hmac_rstart, *signed_rstart;
|
||||
unsigned int hmac_size, signed_size;
|
||||
isc_result_t result;
|
||||
|
||||
if (algorithm == ISCCC_ALG_HMACMD5) {
|
||||
if (REGION_SIZE(*target) < 4 + sizeof(auth_hmd5))
|
||||
return (ISC_R_NOSPACE);
|
||||
} else {
|
||||
if (REGION_SIZE(*target) < 4 + sizeof(auth_hsha))
|
||||
return (ISC_R_NOSPACE);
|
||||
}
|
||||
result = isc_buffer_reserve(buffer,
|
||||
4 + ((algorithm == ISCCC_ALG_HMACMD5) ?
|
||||
sizeof(auth_hmd5) :
|
||||
sizeof(auth_hsha)));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
/*
|
||||
* Emit protocol version.
|
||||
*/
|
||||
PUT32(1, target->rstart);
|
||||
isc_buffer_putuint32(*buffer, 1);
|
||||
|
||||
if (secret != NULL) {
|
||||
/*
|
||||
* Emit _auth section with zeroed HMAC signature.
|
||||
@@ -349,19 +367,21 @@ isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target,
|
||||
* we know what it is.
|
||||
*/
|
||||
if (algorithm == ISCCC_ALG_HMACMD5) {
|
||||
hmac_rstart = target->rstart + HMD5_OFFSET;
|
||||
PUT_MEM(auth_hmd5, sizeof(auth_hmd5), target->rstart);
|
||||
hmac_size = (*buffer)->used + HMD5_OFFSET;
|
||||
isc_buffer_putmem(*buffer,
|
||||
auth_hmd5, sizeof(auth_hmd5));
|
||||
} else {
|
||||
unsigned char *hmac_alg;
|
||||
|
||||
hmac_rstart = target->rstart + HSHA_OFFSET;
|
||||
hmac_alg = hmac_rstart - 1;
|
||||
PUT_MEM(auth_hsha, sizeof(auth_hsha), target->rstart);
|
||||
PUT8(algorithm, hmac_alg);
|
||||
hmac_size = (*buffer)->used + HSHA_OFFSET;
|
||||
hmac_alg = (unsigned char *) isc_buffer_used(*buffer) + HSHA_OFFSET - 1;
|
||||
isc_buffer_putmem(*buffer,
|
||||
auth_hsha, sizeof(auth_hsha));
|
||||
*hmac_alg = algorithm;
|
||||
}
|
||||
} else
|
||||
hmac_rstart = NULL;
|
||||
signed_rstart = target->rstart;
|
||||
hmac_size = 0;
|
||||
signed_size = (*buffer)->used;
|
||||
/*
|
||||
* Delete any existing _auth section so that we don't try
|
||||
* to encode it.
|
||||
@@ -370,13 +390,15 @@ isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target,
|
||||
/*
|
||||
* Emit the message.
|
||||
*/
|
||||
result = table_towire(alist, target);
|
||||
result = table_towire(alist, buffer);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
if (secret != NULL)
|
||||
return (sign(signed_rstart,
|
||||
(unsigned int)(target->rstart - signed_rstart),
|
||||
hmac_rstart, algorithm, secret));
|
||||
return (sign((unsigned char *) (*buffer)->base + signed_size,
|
||||
(*buffer)->used - signed_size,
|
||||
(hmac_size == 0 ? NULL :
|
||||
(unsigned char *) (*buffer)->base + hmac_size),
|
||||
algorithm, secret));
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
/*! \file isccc/cc.h */
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isccc/types.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
@@ -65,7 +66,7 @@ ISC_LANG_BEGINDECLS
|
||||
|
||||
/*% Send to Wire */
|
||||
isc_result_t
|
||||
isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target,
|
||||
isccc_cc_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer,
|
||||
isc_uint32_t algorithm, isccc_region_t *secret);
|
||||
|
||||
/*% Get From Wire */
|
||||
|
||||
Reference in New Issue
Block a user