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); }
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); }
static void control_senddone (isc_task_t * task, isc_event_t * event) { isc_socketevent_t *sevent = (isc_socketevent_t *) event; controlconnection_t *conn = event->ev_arg; controllistener_t *listener = conn->listener; isc_socket_t *sock = (isc_socket_t *) sevent->ev_sender; isc_result_t result; REQUIRE (conn->sending); UNUSED (task); conn->sending = ISC_FALSE; if (sevent->result != ISC_R_SUCCESS && sevent->result != ISC_R_CANCELED) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t peeraddr; (void) isc_socket_getpeername (sock, &peeraddr); isc_sockaddr_format (&peeraddr, socktext, sizeof (socktext)); isc_log_write (ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, "error sending command response to %s: %s", socktext, isc_result_totext (sevent->result)); } isc_event_free (&event); result = isccc_ccmsg_readmessage (&conn->ccmsg, listener->task, control_recvmessage, conn); if (result != ISC_R_SUCCESS) { isc_socket_detach (&conn->sock); maybe_free_connection (conn); maybe_free_listener (listener); } }
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; }
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; }