예제 #1
0
파일: rndc.c 프로젝트: 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);
}
예제 #2
0
static isc_result_t
newconnection(controllistener_t *listener, isc_socket_t *sock) {
	controlconnection_t *conn;
	isc_interval_t interval;
	isc_result_t result;

	conn = isc_mem_get(listener->mctx, sizeof(*conn));
	if (conn == NULL)
		return (ISC_R_NOMEMORY);

	conn->sock = 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,
				  NULL, &interval, listener->task,
				  control_timeout, conn, &conn->timer);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	conn->listener = listener;
	conn->nonce = 0;
	ISC_LINK_INIT(conn, link);

	result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task,
					 control_recvmessage, conn);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	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);
	isc_mem_put(listener->mctx, conn, sizeof(*conn));
	return (result);
}