Example #1
0
File: rndc.c Project: OPSF/uClinux
static void
rndc_connected(isc_task_t *task, isc_event_t *event) {
	char socktext[ISC_SOCKADDR_FORMATSIZE];
	isc_socketevent_t *sevent = (isc_socketevent_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;

	connects--;

	if (sevent->result != ISC_R_SUCCESS) {
		isc_sockaddr_format(&serveraddrs[currentaddr], socktext,
				    sizeof(socktext));
		if (sevent->result != ISC_R_CANCELED &&
		    ++currentaddr < nserveraddrs)
		{
			notify("connection failed: %s: %s", socktext,
			       isc_result_totext(sevent->result));
			isc_socket_detach(&sock);
			isc_event_free(&event);
			rndc_startconnect(&serveraddrs[currentaddr], task);
			return;
		} else
			fatal("connect failed: %s: %s", socktext,
			      isc_result_totext(sevent->result));
	}

	isc_stdtime_get(&now);
	DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial,
						    now, now + 60, &request));
	data = isccc_alist_lookup(request, "_data");
	if (data == NULL)
		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);
	DO("render message", isccc_cc_towire(request, &message, &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_ccmsg_init(mctx, sock, &ccmsg);
	isccc_ccmsg_setmaxsize(&ccmsg, 1024 * 1024);

	DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task,
						    rndc_recvnonce, NULL));
	recvs++;
	DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
					   NULL));
	sends++;
	isc_event_free(&event);
}
Example #2
0
isc_result_t
isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now,
			isccc_time_t expires, isccc_sexpr_t **alistp)
{
	char *_frm, *_to, *type = NULL;
	isc_uint32_t serial;
	isccc_sexpr_t *alist, *_ctrl, *_data;
	isc_result_t result;

	REQUIRE(alistp != NULL && *alistp == NULL);

	_ctrl = isccc_alist_lookup(message, "_ctrl");
	_data = isccc_alist_lookup(message, "_data");
	if (!isccc_alist_alistp(_ctrl) || !isccc_alist_alistp(_data) ||
	    isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS ||
	    isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS)
		return (ISC_R_FAILURE);
	/*
	 * _frm and _to are optional.
	 */
	_frm = NULL;
	(void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm);
	_to = NULL;
	(void)isccc_cc_lookupstring(_ctrl, "_to", &_to);
	/*
	 * Create the response.
	 */
	alist = NULL;
	result = isccc_cc_createmessage(1, _to, _frm, serial, now, expires,
					 &alist);
	if (result != ISC_R_SUCCESS)
		return (result);

	_ctrl = isccc_alist_lookup(alist, "_ctrl");
	if (_ctrl == NULL) {
		result = ISC_R_FAILURE;
		goto bad;
	}

	_data = isccc_alist_lookup(alist, "_data");
	if (_data == NULL) {
		result = ISC_R_FAILURE;
		goto bad;
	}

	if (isccc_cc_definestring(_ctrl, "_rpl", "1") == NULL ||
	    isccc_cc_definestring(_data, "type", type) == NULL)
	{
		result = ISC_R_NOMEMORY;
		goto bad;
	}

	*alistp = alist;

	return (ISC_R_SUCCESS);

 bad:
	isccc_sexpr_free(&alist);
	return (result);
}
Example #3
0
static void
rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
	isccc_sexpr_t *response = NULL;
	isccc_sexpr_t *_ctrl;
	isccc_region_t source;
	isc_result_t result;
	isc_uint32_t nonce;
	isccc_sexpr_t *request = NULL;
	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--;

	if (ccmsg.result == ISC_R_EOF)
		fatal("connection to remote host closed\n"
		      "This may indicate that the remote server is using "
		      "an older version of \n"
		      "the command protocol, this host is not authorized "
		      "to connect,\nor the key is invalid.");

	if (ccmsg.result != ISC_R_SUCCESS)
		fatal("recv failed: %s", isc_result_totext(ccmsg.result));

	source.rstart = isc_buffer_base(&ccmsg.buffer);
	source.rend = isc_buffer_used(&ccmsg.buffer);

	DO("parse message", isccc_cc_fromwire(&source, &response, &secret));

	_ctrl = isccc_alist_lookup(response, "_ctrl");
	if (_ctrl == NULL)
		fatal("_ctrl section missing");
	nonce = 0;
	if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS)
		nonce = 0;

	isc_stdtime_get(&now);

	DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial,
						    now, now + 60, &request));
	data = isccc_alist_lookup(request, "_data");
	if (data == NULL)
		fatal("_data section missing");
	if (isccc_cc_definestring(data, "type", args) == NULL)
		fatal("out of memory");
	if (nonce != 0) {
		_ctrl = isccc_alist_lookup(request, "_ctrl");
		if (_ctrl == NULL)
			fatal("_ctrl section missing");
		if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL)
			fatal("out of memory");
	}
	message.rstart = databuf + 4;
	message.rend = databuf + sizeof(databuf);
	DO("render message", isccc_cc_towire(request, &message, &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_ccmsg_cancelread(&ccmsg);
	DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task,
						    rndc_recvdone, NULL));
	recvs++;
	DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
					   NULL));
	sends++;

	isc_event_free(&event);
	isccc_sexpr_free(&response);
	return;
}
Example #4
0
static void
rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
	isccc_sexpr_t *response = NULL;
	isccc_sexpr_t *_ctrl;
	isccc_region_t source;
	isc_result_t result;
	isc_uint32_t nonce;
	isccc_sexpr_t *request = NULL;
	isccc_time_t now;
	isc_region_t r;
	isccc_sexpr_t *data;
	isc_buffer_t b;

	recvs--;

	if (ccmsg.result == ISC_R_EOF)
		fatal("connection to remote host closed\n"
		      "This may indicate that\n"
		      "* the remote server is using an older version of"
		      " the command protocol,\n"
		      "* this host is not authorized to connect,\n"
		      "* the clocks are not synchronized,\n"
		      "* the key signing algorithm is incorrect, or\n"
		      "* the key is invalid.");

	if (ccmsg.result != ISC_R_SUCCESS)
		fatal("recv failed: %s", isc_result_totext(ccmsg.result));

	source.rstart = isc_buffer_base(&ccmsg.buffer);
	source.rend = isc_buffer_used(&ccmsg.buffer);

	DO("parse message",
	   isccc_cc_fromwire(&source, &response, algorithm, &secret));

	_ctrl = isccc_alist_lookup(response, "_ctrl");
	if (!isccc_alist_alistp(_ctrl))
		fatal("bad or missing ctrl section in response");
	nonce = 0;
	if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS)
		nonce = 0;

	isc_stdtime_get(&now);

	DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial,
						    now, now + 60, &request));
	data = isccc_alist_lookup(request, "_data");
	if (data == NULL)
		fatal("_data section missing");
	if (isccc_cc_definestring(data, "type", args) == NULL)
		fatal("out of memory");
	if (nonce != 0) {
		_ctrl = isccc_alist_lookup(request, "_ctrl");
		if (_ctrl == NULL)
			fatal("_ctrl section missing");
		if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL)
			fatal("out of memory");
	}

	isc_buffer_clear(databuf);
	/* Skip the length field (4 bytes) */
	isc_buffer_add(databuf, 4);

	DO("render message",
	   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,
						    rndc_recvdone, NULL));
	recvs++;
	DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
					   NULL));
	sends++;

	isc_event_free(&event);
	isccc_sexpr_free(&response);
	return;
}