* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsupdate.c,v 1.120 2002/08/06 03:21:59 marka Exp $ */
+/* $Id: nsupdate.c,v 1.121 2002/11/12 23:58:13 explorer Exp $ */
#include <config.h>
static isc_boolean_t seenerror = ISC_FALSE;
static const dns_master_style_t *style;
static int requests = 0;
+static unsigned int timeout = 300;
+static unsigned int udp_timeout = 3;
+static unsigned int udp_retries = 3;
typedef struct nsu_requestinfo {
dns_message_t *msg;
isc_result_t result;
debug("parse_args");
- while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:")) != -1) {
+ while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:r:t:u:")) != -1)
+ {
switch (ch) {
case 'd':
debugging = ISC_TRUE;
case 'k':
keyfile = isc_commandline_argument;
break;
+ case 't':
+ result = isc_parse_uint32(&timeout,
+ isc_commandline_argument, 10);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "bad timeout '%s'\n", isc_commandline_argument);
+ exit(1);
+ }
+ if (timeout == 0)
+ timeout = ULONG_MAX;
+ break;
+ case 'u':
+ result = isc_parse_uint32(&udp_timeout,
+ isc_commandline_argument, 10);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "bad udp timeout '%s'\n", isc_commandline_argument);
+ exit(1);
+ }
+ if (udp_timeout == 0)
+ udp_timeout = ULONG_MAX;
+ break;
+ case 'r':
+ result = isc_parse_uint32(&udp_retries,
+ isc_commandline_argument, 10);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "bad udp retries '%s'\n", isc_commandline_argument);
+ exit(1);
+ }
+ break;
default:
fprintf(stderr, "%s: invalid argument -%c\n",
argv[0], ch);
if (tsigkey != NULL)
dns_tsigkey_detach(&tsigkey);
result = dns_tsigkey_create(keyname, dns_tsig_hmacmd5_name,
- secret, secretlen, ISC_TRUE, NULL, 0, 0,
- mctx, NULL, &tsigkey);
+ secret, secretlen, ISC_TRUE, NULL, 0, 0,
+ mctx, NULL, &tsigkey);
isc_mem_free(mctx, secret);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not create key from %s %s: %s\n",
isc_sockaddr_format(master, addrbuf, sizeof(addrbuf));
fprintf(stderr, "Sending update to %s\n", addrbuf);
}
- result = dns_request_createvia(requestmgr, updatemsg, srcaddr,
- master, options, tsigkey,
- FIND_TIMEOUT, global_task,
- update_completed, NULL, &request);
- check_result(result, "dns_request_createvia");
+ result = dns_request_createvia3(requestmgr, updatemsg, srcaddr,
+ master, options, tsigkey, timeout,
+ udp_timeout, udp_retries, global_task,
+ update_completed, NULL, &request);
+ check_result(result, "dns_request_createvia3");
if (debugging)
show_message(updatemsg);
fatal("out of memory");
reqinfo->msg = msg;
reqinfo->addr = destaddr;
- result = dns_request_createvia(requestmgr, msg, srcaddr, destaddr,
- 0, NULL, FIND_TIMEOUT, global_task,
- recvsoa, reqinfo, request);
+ result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr,
+ 0, NULL, FIND_TIMEOUT * 20,
+ FIND_TIMEOUT, 3, global_task, recvsoa,
+ reqinfo, request);
check_result(result, "dns_request_createvia");
requests++;
}
- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nsupdate.docbook,v 1.11 2002/02/20 03:33:38 marka Exp $ -->
+<!-- $Id: nsupdate.docbook,v 1.12 2002/11/12 23:58:13 explorer Exp $ -->
<refentry>
<refentryinfo>
<arg><option>-y <replaceable class="parameter">keyname:secret</replaceable></option></arg>
<arg><option>-k <replaceable class="parameter">keyfile</replaceable></option></arg>
</group>
+<arg><option>-t <replaceable class="parameter">timeout</replaceable></option></arg>
+<arg><option>-u <replaceable class="parameter">udptimeout</replaceable></option></arg>
+<arg><option>-r <replaceable class="parameter">udpretries</replaceable></option></arg>
<arg><option>-v</option></arg>
<arg>filename</arg>
</cmdsynopsis>
<para>
By default
<command>nsupdate</command>
-uses UDP to send update requests to the name server.
+uses UDP to send update requests to the name server unless they are too
+large to fit in a UDP request in which case TCP will be used.
The
<option>-v</option>
option makes
use a TCP connection.
This may be preferable when a batch of update requests is made.
</para>
+<para>The <option>-t</option> option sets the maximum time a update request can
+take before it is aborted. The default is 300 seconds. Zero can be used
+to disable the timeout.
+</para>
+<para>The <option>-u</option> option sets the UDP retry interval. The default is
+3 seconds. If zero the interval will be computed from the timeout interval
+and number of UDP retries.
+</para>
+<para>The <option>-r</option> option sets the number of UDP retries. The default is
+3. If zero only one update request will be made.
+</para>
</refsect1>
<refsect1>
rt4090 closed explorer
rt4112 closed explorer
adb_race review explorer
-rt4319 review explorer
+rt4319 closed explorer
rt3907 closed explorer
rt3507 closed ogud (pull down by explorer)
v6source
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: request.h,v 1.19 2001/11/30 01:59:27 gson Exp $ */
+/* $Id: request.h,v 1.20 2002/11/12 23:58:14 explorer Exp $ */
#ifndef DNS_REQUEST_H
#define DNS_REQUEST_H 1
dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udpretry,
+ unsigned int timeout, unsigned int udptimeout,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp);
+
+isc_result_t
+dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
+ isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
+ unsigned int options, dns_tsigkey_t *key,
+ unsigned int timeout, unsigned int udptimeout,
+ unsigned int udpretries, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_request_t **requestp);
/*
* Create and send a request.
*
* 'message' will be rendered and sent to 'address'. If the
* DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
* will timeout after 'timeout' seconds. UDP requests will be resent
- * at 'udpretry' intervals if non-zero.
+ * at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero.
*
* When the request completes, successfully, due to a timeout, or
* because it was canceled, a completion event will be sent to 'task'.
dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
unsigned int options, unsigned int timeout,
- unsigned int udpretry, isc_task_t *task,
+ unsigned int udptimeout, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_request_t **requestp);
+
+isc_result_t
+dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
+ isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
+ unsigned int options, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_request_t **requestp);
/*
* Create and send a request.
*
* 'msgbuf' will be sent to 'destaddr' after setting the id. If the
* DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
* will timeout after 'timeout' seconds. UDP requests will be resent
- * at 'udpretry' intervals if non-zero.
- *
+ * at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero.
+ *
* When the request completes, successfully, due to a timeout, or
* because it was canceled, a completion event will be sent to 'task'.
*
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: request.c,v 1.70 2001/11/30 01:59:16 gson Exp $ */
+/* $Id: request.c,v 1.71 2002/11/12 23:58:14 explorer Exp $ */
#include <config.h>
isc_event_t ctlevent;
isc_boolean_t canceling; /* ctlevent outstanding */
isc_sockaddr_t destaddr;
+ unsigned int udpcount;
};
#define DNS_REQUEST_F_CONNECTING 0x0001
DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL,
NULL, NULL);
request->canceling = ISC_FALSE;
+ request->udpcount = 0;
isc_mem_attach(mctx, &request->mctx);
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
- return(dns_request_createraw2(requestmgr, msgbuf, srcaddr, destaddr,
- options, timeout, 0, task, action, arg,
- requestp));
+ return(dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
+ options, timeout, 0, 0, task, action,
+ arg, requestp));
}
isc_result_t
dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout, unsigned int udpretry, isc_task_t *task,
+ unsigned int options, unsigned int timeout,
+ unsigned int udptimeout, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
+{
+ unsigned int udpretries = 0;
+
+ if (udptimeout != 0)
+ udpretries = timeout / udptimeout;
+
+ return (dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
+ options, timeout, udptimeout,
+ udpretries, task, action, arg,
+ requestp));
+}
+
+isc_result_t
+dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
+ isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
+ unsigned int options, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_request_t **requestp)
{
dns_request_t *request = NULL;
isc_task_t *tclone = NULL;
if (result != ISC_R_SUCCESS)
return (result);
+ if (udptimeout == 0 && udpretries != 0) {
+ udptimeout = timeout / (udpretries + 1);
+ if (udptimeout == 0)
+ udptimeout = 1;
+ }
+
/*
* Create timer now. We will set it below once.
*/
ISC_LIST_APPEND(requestmgr->requests, request, link);
UNLOCK(&requestmgr->lock);
- result = set_timer(request->timer, timeout, tcp ? 0 : udpretry);
+ result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
if (result != ISC_R_SUCCESS)
goto unlink;
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
- return (dns_request_createvia2(requestmgr, message, NULL, address,
- options, key, timeout, 0, task, action,
- arg, requestp));
+ return (dns_request_createvia3(requestmgr, message, NULL, address,
+ options, key, timeout, 0, 0, task,
+ action, arg, requestp));
}
isc_result_t
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
- return(dns_request_createvia2(requestmgr, message, srcaddr, destaddr,
- options, key, timeout, 0, task, action,
- arg, requestp));
+ return(dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
+ options, key, timeout, 0, 0, task,
+ action, arg, requestp));
}
isc_result_t
dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udpretry,
+ unsigned int timeout, unsigned int udptimeout,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp)
+{
+ unsigned int udpretries = 0;
+
+ if (udptimeout != 0)
+ udpretries = timeout / udptimeout;
+ return (dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
+ options, key, timeout, udptimeout,
+ udpretries, task, action, arg,
+ requestp));
+}
+
+isc_result_t
+dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
+ isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
+ unsigned int options, dns_tsigkey_t *key,
+ unsigned int timeout, unsigned int udptimeout,
+ unsigned int udpretries, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_request_t **requestp)
{
dns_request_t *request = NULL;
isc_task_t *tclone = NULL;
if (result != ISC_R_SUCCESS)
return (result);
+ if (udptimeout == 0 && udpretries != 0) {
+ udptimeout = timeout / (udpretries + 1);
+ if (udptimeout == 0)
+ udptimeout = 1;
+ }
+
/*
* Create timer now. We will set it below once.
*/
ISC_LIST_APPEND(requestmgr->requests, request, link);
UNLOCK(&requestmgr->lock);
- result = set_timer(request->timer, timeout, tcp ? 0 : udpretry);
+ result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
if (result != ISC_R_SUCCESS)
goto unlink;
UNUSED(task);
LOCK(&request->requestmgr->locks[request->hash]);
- if (event->ev_type == ISC_TIMEREVENT_TICK) {
+ if (event->ev_type == ISC_TIMEREVENT_TICK &&
+ request->udpcount-- != 0) {
if (! DNS_REQUEST_SENDING(request)) {
result = req_send(request, task, &request->destaddr);
if (result != ISC_R_SUCCESS) {