static void control_newconn (isc_task_t * task, isc_event_t * event) { isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *) event; controllistener_t *listener = event->ev_arg; isc_socket_t *sock; isc_sockaddr_t peeraddr; isc_result_t result; UNUSED (task); listener->listening = ISC_FALSE; if (nevent->result != ISC_R_SUCCESS) { if (nevent->result == ISC_R_CANCELED) { shutdown_listener (listener); goto cleanup; } goto restart; } sock = nevent->newsocket; isc_socket_setname (sock, "control", NULL); (void) isc_socket_getpeername (sock, &peeraddr); if (listener->type == isc_sockettype_tcp && !address_ok (&peeraddr, listener->acl)) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format (&peeraddr, socktext, sizeof (socktext)); isc_log_write (ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, "rejected command channel message from %s", socktext); isc_socket_detach (&sock); goto restart; } result = newconnection (listener, sock); if (result != ISC_R_SUCCESS) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format (&peeraddr, socktext, sizeof (socktext)); isc_log_write (ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, "dropped command channel from %s: %s", socktext, isc_result_totext (result)); isc_socket_detach (&sock); goto restart; } restart: control_next (listener); cleanup: isc_event_free (&event); }
static void my_connect(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socket_connev_t *dev; isc_region_t region; char buf[1024]; sock = event->ev_sender; dev = (isc_socket_connev_t *)event; printf("%s: Connection result: %d\n", (char *)(event->ev_arg), dev->result); if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_event_free(&event); isc_task_shutdown(task); return; } /* * Send a GET string, and set up to receive (and just display) * the result. */ strcpy(buf, "GET / HTTP/1.1\r\nHost: www.flame.org\r\n" "Connection: Close\r\n\r\n"); region.base = isc_mem_get(mctx, strlen(buf) + 1); region.length = strlen(buf) + 1; strcpy((char *)region.base, buf); /* This strcpy is safe. */ isc_socket_send(sock, ®ion, task, my_http_get, event->ev_arg); isc_event_free(&event); }
static void my_http_get(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socketevent_t *dev; sock = event->ev_sender; dev = (isc_socketevent_t *)event; printf("my_http_get: %s task %p\n\t(sock %p, base %p, length %d, " "n %d, result %d)\n", (char *)(event->ev_arg), task, sock, dev->region.base, dev->region.length, dev->n, dev->result); if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_task_shutdown(task); isc_event_free(&event); return; } isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->ev_arg); isc_event_free(&event); }
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); }
void ns_lwreslistener_detach(ns_lwreslistener_t **listenerp) { ns_lwreslistener_t *listener; isc_mem_t *mctx; isc_boolean_t done = ISC_FALSE; INSIST(listenerp != NULL && *listenerp != NULL); INSIST(VALID_LWRESLISTENER(*listenerp)); listener = *listenerp; LOCK(&listener->lock); INSIST(listener->refs > 0); listener->refs--; if (listener->refs == 0) done = ISC_TRUE; UNLOCK(&listener->lock); if (!done) return; if (listener->manager != NULL) ns_lwdmanager_detach(&listener->manager); if (listener->sock != NULL) isc_socket_detach(&listener->sock); listener->magic = 0; mctx = listener->mctx; isc_mem_put(mctx, listener, sizeof(*listener)); isc_mem_detach(&mctx); listenerp = NULL; }
static void ns_interface_destroy(ns_interface_t *ifp) { isc_mem_t *mctx = ifp->mgr->mctx; int disp; REQUIRE(NS_INTERFACE_VALID(ifp)); ns_interface_shutdown(ifp); for (disp = 0; disp < ifp->nudpdispatch; disp++) if (ifp->udpdispatch[disp] != NULL) { dns_dispatch_changeattributes(ifp->udpdispatch[disp], 0, DNS_DISPATCHATTR_NOLISTEN); dns_dispatch_detach(&(ifp->udpdispatch[disp])); } if (ifp->tcpsocket != NULL) isc_socket_detach(&ifp->tcpsocket); DESTROYLOCK(&ifp->lock); ns_interfacemgr_detach(&ifp->mgr); ifp->magic = 0; isc_mem_put(mctx, ifp, sizeof(*ifp)); }
static isc_result_t ns_interface_accepttcp(ns_interface_t *ifp) { isc_result_t result; /* * Open a TCP socket. */ result = isc_socket_create(ifp->mgr->socketmgr, isc_sockaddr_pf(&ifp->addr), isc_sockettype_tcp, &ifp->tcpsocket); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "creating TCP socket: %s", isc_result_totext(result)); goto tcp_socket_failure; } isc_socket_setname(ifp->tcpsocket, "dispatcher", NULL); #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE); #endif result = isc_socket_bind(ifp->tcpsocket, &ifp->addr); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "binding TCP socket: %s", isc_result_totext(result)); goto tcp_bind_failure; } result = isc_socket_listen(ifp->tcpsocket, ns_g_listen); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "listening on TCP socket: %s", isc_result_totext(result)); goto tcp_listen_failure; } /* * If/when there a multiple filters listen to the * result. */ (void)isc_socket_filter(ifp->tcpsocket, "dataready"); result = ns_clientmgr_createclients(ifp->clientmgr, ifp->ntcptarget, ifp, ISC_TRUE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "TCP ns_clientmgr_createclients(): %s", isc_result_totext(result)); goto accepttcp_failure; } return (ISC_R_SUCCESS); accepttcp_failure: tcp_listen_failure: tcp_bind_failure: isc_socket_detach(&ifp->tcpsocket); tcp_socket_failure: return (ISC_R_SUCCESS); }
static void my_recv(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socketevent_t *dev; isc_region_t region; char buf[1024]; char host[256]; sock = event->ev_sender; dev = (isc_socketevent_t *)event; printf("Socket %s (sock %p, base %p, length %d, n %d, result %d)\n", (char *)(event->ev_arg), sock, dev->region.base, dev->region.length, dev->n, dev->result); if (dev->address.type.sa.sa_family == AF_INET6) { inet_ntop(AF_INET6, &dev->address.type.sin6.sin6_addr, host, sizeof(host)); printf("\tFrom: %s port %d\n", host, ntohs(dev->address.type.sin6.sin6_port)); } else { inet_ntop(AF_INET, &dev->address.type.sin.sin_addr, host, sizeof(host)); printf("\tFrom: %s port %d\n", host, ntohs(dev->address.type.sin.sin_port)); } if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_mem_put(mctx, dev->region.base, dev->region.length); isc_event_free(&event); isc_task_shutdown(task); return; } /* * Echo the data back. */ if (strcmp(event->ev_arg, "so2") != 0) { region = dev->region; sprintf(buf, "\r\nReceived: %.*s\r\n\r\n", (int)dev->n, (char *)region.base); region.base = isc_mem_get(mctx, strlen(buf) + 1); region.length = strlen(buf) + 1; strcpy((char *)region.base, buf); /* strcpy is safe */ isc_socket_send(sock, ®ion, task, my_send, event->ev_arg); } else { region = dev->region; printf("\r\nReceived: %.*s\r\n\r\n", (int)dev->n, (char *)region.base); } isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->ev_arg); isc_event_free(&event); }
static void rndc_recvdone(isc_task_t *task, isc_event_t *event) { isccc_sexpr_t *response = NULL; isccc_sexpr_t *data; isccc_region_t source; char *errormsg = NULL; char *textmsg = NULL; isc_result_t result; 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, 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)); data = isccc_alist_lookup(response, "_data"); if (data == NULL) fatal("no data section in response"); result = isccc_cc_lookupstring(data, "err", &errormsg); if (result == ISC_R_SUCCESS) { failed = ISC_TRUE; fprintf(stderr, "%s: '%s' failed: %s\n", progname, command, errormsg); } else if (result != ISC_R_NOTFOUND) fprintf(stderr, "%s: parsing response failed: %s\n", progname, isc_result_totext(result)); result = isccc_cc_lookupstring(data, "text", &textmsg); if (result == ISC_R_SUCCESS) { if ((!quiet || failed) && strlen(textmsg) != 0U) fprintf(failed ? stderr : stdout, "%s\n", textmsg); } else if (result != ISC_R_NOTFOUND) fprintf(stderr, "%s: parsing response failed: %s\n", progname, isc_result_totext(result)); isc_event_free(&event); isccc_sexpr_free(&response); if (sends == 0 && recvs == 0) { isc_socket_detach(&sock); isc_task_shutdown(task); RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); } }
static void httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) { isc_mem_t *mctx; isc_httpdurl_t *url; ENTER("httpdmgr_destroy"); LOCK(&httpdmgr->lock); if (!MSHUTTINGDOWN(httpdmgr)) { NOTICE("httpdmgr_destroy not shutting down yet"); UNLOCK(&httpdmgr->lock); return; } /* * If all clients are not shut down, don't do anything yet. */ if (!ISC_LIST_EMPTY(httpdmgr->running)) { NOTICE("httpdmgr_destroy clients still active"); UNLOCK(&httpdmgr->lock); return; } NOTICE("httpdmgr_destroy detaching socket, task, and timermgr"); isc_socket_detach(&httpdmgr->sock); isc_task_detach(&httpdmgr->task); httpdmgr->timermgr = NULL; /* * Clear out the list of all actions we know about. Just free the * memory. */ url = ISC_LIST_HEAD(httpdmgr->urls); while (url != NULL) { isc_mem_free(httpdmgr->mctx, url->url); ISC_LIST_UNLINK(httpdmgr->urls, url, link); isc_mem_put(httpdmgr->mctx, url, sizeof(isc_httpdurl_t)); url = ISC_LIST_HEAD(httpdmgr->urls); } UNLOCK(&httpdmgr->lock); isc_mutex_destroy(&httpdmgr->lock); if (httpdmgr->ondestroy != NULL) (httpdmgr->ondestroy)(httpdmgr->cb_arg); mctx = httpdmgr->mctx; isc_mem_putanddetach(&mctx, httpdmgr, sizeof(isc_httpdmgr_t)); EXIT("httpdmgr_destroy"); }
static void flush_lookup_list (void) { dig_lookup_t *l, *lp; dig_query_t *q, *qp; dig_server_t *s, *sp; lookup_counter = 0; l = ISC_LIST_HEAD (lookup_list); while (l != NULL) { q = ISC_LIST_HEAD (l->q); while (q != NULL) { if (q->sock != NULL) { isc_socket_cancel (q->sock, NULL, ISC_SOCKCANCEL_ALL); isc_socket_detach (&q->sock); } if (ISC_LINK_LINKED (&q->recvbuf, link)) ISC_LIST_DEQUEUE (q->recvlist, &q->recvbuf, link); if (ISC_LINK_LINKED (&q->lengthbuf, link)) ISC_LIST_DEQUEUE (q->lengthlist, &q->lengthbuf, link); isc_buffer_invalidate (&q->recvbuf); isc_buffer_invalidate (&q->lengthbuf); qp = q; q = ISC_LIST_NEXT (q, link); ISC_LIST_DEQUEUE (l->q, qp, link); isc_mem_free (mctx, qp); } s = ISC_LIST_HEAD (l->my_server_list); while (s != NULL) { sp = s; s = ISC_LIST_NEXT (s, link); ISC_LIST_DEQUEUE (l->my_server_list, sp, link); isc_mem_free (mctx, sp); } if (l->sendmsg != NULL) dns_message_destroy (&l->sendmsg); if (l->timer != NULL) isc_timer_detach (&l->timer); lp = l; l = ISC_LIST_NEXT (l, link); ISC_LIST_DEQUEUE (lookup_list, lp, link); isc_mem_free (mctx, lp); } }
static void my_listen(isc_task_t *task, isc_event_t *event) { char *name = event->ev_arg; isc_socket_newconnev_t *dev; isc_region_t region; isc_socket_t *oldsock; isc_task_t *newtask; dev = (isc_socket_newconnev_t *)event; printf("newcon %s (task %p, oldsock %p, newsock %p, result %d)\n", name, task, event->ev_sender, dev->newsocket, dev->result); fflush(stdout); if (dev->result == ISC_R_SUCCESS) { /* * Queue another listen on this socket. */ RUNTIME_CHECK(isc_socket_accept(event->ev_sender, task, my_listen, event->ev_arg) == ISC_R_SUCCESS); region.base = isc_mem_get(mctx, 20); region.length = 20; /* * Create a new task for this socket, and queue up a * recv on it. */ newtask = NULL; RUNTIME_CHECK(isc_task_create(manager, 0, &newtask) == ISC_R_SUCCESS); isc_socket_recv(dev->newsocket, ®ion, 1, newtask, my_recv, event->ev_arg); isc_task_detach(&newtask); } else { printf("detaching from socket %p\n", event->ev_sender); oldsock = event->ev_sender; isc_socket_detach(&oldsock); isc_event_free(&event); isc_task_shutdown(task); return; } isc_event_free(&event); }
static isc_result_t listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { isc_socket_t *sock = NULL; isc_result_t result = ISC_R_SUCCESS; int pf; pf = isc_sockaddr_pf(address); if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) return (ISC_R_FAMILYNOSUPPORT); listener->address = *address; if (isc_sockaddr_getport(&listener->address) == 0) { in_port_t port; port = lwresd_g_listenport; if (port == 0) port = LWRES_UDP_PORT; isc_sockaddr_setport(&listener->address, port); } sock = NULL; result = isc_socket_create(ns_g_socketmgr, pf, isc_sockettype_udp, &sock); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, "failed to create lwres socket: %s", isc_result_totext(result)); return (result); } result = isc_socket_bind(sock, &listener->address, ISC_SOCKET_REUSEADDRESS); if (result != ISC_R_SUCCESS) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&listener->address, socktext, sizeof(socktext)); isc_socket_detach(&sock); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, "failed to add lwres socket: %s: %s", socktext, isc_result_totext(result)); return (result); } listener->sock = sock; return (ISC_R_SUCCESS); }
static void free_listener(controllistener_t *listener) { INSIST(listener->exiting); INSIST(!listener->listening); INSIST(ISC_LIST_EMPTY(listener->connections)); if (listener->sock != NULL) isc_socket_detach(&listener->sock); free_controlkeylist(&listener->keys, listener->mctx); if (listener->acl != NULL) dns_acl_detach(&listener->acl); isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener)); }
static void rndc_senddone(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; UNUSED(task); sends--; if (sevent->result != ISC_R_SUCCESS) fatal("send failed: %s", isc_result_totext(sevent->result)); isc_event_free(&event); if (sends == 0 && recvs == 0) { isc_socket_detach(&sock); isc_task_shutdown(task); RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); } }
static void lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { ns_lwdclient_t *client; ns_lwreslistener_t *listener; LOCK(&cm->lock); if (!SHUTTINGDOWN(cm)) { UNLOCK(&cm->lock); return; } /* * Run through the idle list and free the clients there. Idle * clients do not have a recv running nor do they have any finds * or similar running. */ client = ISC_LIST_HEAD(cm->idle); while (client != NULL) { ns_lwdclient_log(50, "destroying client %p, manager %p", client, cm); ISC_LIST_UNLINK(cm->idle, client, link); isc_mem_put(cm->mctx, client, sizeof(*client)); client = ISC_LIST_HEAD(cm->idle); } if (!ISC_LIST_EMPTY(cm->running)) { UNLOCK(&cm->lock); return; } UNLOCK(&cm->lock); lwres_context_destroy(&cm->lwctx); cm->view = NULL; isc_socket_detach(&cm->sock); isc_task_detach(&cm->task); DESTROYLOCK(&cm->lock); listener = cm->listener; ns_lwreslistener_unlinkcm(listener, cm); ns_lwdclient_log(50, "destroying manager %p", cm); isc_mem_put(cm->mctx, cm, sizeof(*cm)); ns_lwreslistener_detach(&listener); }
static void ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { REQUIRE(NS_INTERFACEMGR_VALID(mgr)); #ifdef USE_ROUTE_SOCKET if (mgr->route != NULL) isc_socket_detach(&mgr->route); if (mgr->task != NULL) isc_task_detach(&mgr->task); #endif dns_aclenv_destroy(&mgr->aclenv); ns_listenlist_detach(&mgr->listenon4); ns_listenlist_detach(&mgr->listenon6); clearlistenon(mgr); DESTROYLOCK(&mgr->lock); mgr->magic = 0; isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); }
void ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { REQUIRE(NS_INTERFACEMGR_VALID(mgr)); /*% * Shut down and detach all interfaces. * By incrementing the generation count, we make purge_old_interfaces() * consider all interfaces "old". */ mgr->generation++; #ifdef USE_ROUTE_SOCKET LOCK(&mgr->lock); if (mgr->route != NULL) { isc_socket_cancel(mgr->route, mgr->task, ISC_SOCKCANCEL_RECV); isc_socket_detach(&mgr->route); isc_task_detach(&mgr->task); } UNLOCK(&mgr->lock); #endif purge_old_interfaces(mgr); }
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 destroy_client(isc_httpd_t **httpdp) { isc_httpd_t *httpd = *httpdp; isc_httpdmgr_t *httpdmgr = httpd->mgr; *httpdp = NULL; LOCK(&httpdmgr->lock); isc_socket_detach(&httpd->sock); ISC_LIST_UNLINK(httpdmgr->running, httpd, link); if (httpd->headerlen > 0) isc_mem_put(httpdmgr->mctx, httpd->headerdata, httpd->headerlen); isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); UNLOCK(&httpdmgr->lock); httpdmgr_destroy(httpdmgr); }
static void my_send(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socketevent_t *dev; sock = event->ev_sender; dev = (isc_socketevent_t *)event; printf("my_send: %s task %p\n\t(sock %p, base %p, length %d, n %d, " "result %d)\n", (char *)(event->ev_arg), task, sock, dev->region.base, dev->region.length, dev->n, dev->result); if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_task_shutdown(task); } isc_mem_put(mctx, dev->region.base, dev->region.length); isc_event_free(&event); }
static void isc_httpd_accept(isc_task_t *task, isc_event_t *ev) { isc_result_t result; isc_httpdmgr_t *httpdmgr = ev->ev_arg; isc_httpd_t *httpd; isc_region_t r; isc_socket_newconnev_t *nev = (isc_socket_newconnev_t *)ev; isc_sockaddr_t peeraddr; ENTER("accept"); LOCK(&httpdmgr->lock); if (MSHUTTINGDOWN(httpdmgr)) { NOTICE("accept shutting down, goto out"); goto out; } if (nev->result == ISC_R_CANCELED) { NOTICE("accept canceled, goto out"); goto out; } if (nev->result != ISC_R_SUCCESS) { /* XXXMLG log failure */ NOTICE("accept returned failure, goto requeue"); goto requeue; } (void)isc_socket_getpeername(nev->newsocket, &peeraddr); if (httpdmgr->client_ok != NULL && !(httpdmgr->client_ok)(&peeraddr, httpdmgr->cb_arg)) { isc_socket_detach(&nev->newsocket); goto requeue; } httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t)); if (httpd == NULL) { /* XXXMLG log failure */ NOTICE("accept failed to allocate memory, goto requeue"); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->mgr = httpdmgr; ISC_LINK_INIT(httpd, link); ISC_LIST_APPEND(httpdmgr->running, httpd, link); ISC_HTTPD_SETRECV(httpd); httpd->sock = nev->newsocket; isc_socket_setname(httpd->sock, "httpd", NULL); httpd->flags = 0; /* * Initialize the buffer for our headers. */ httpd->headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW); if (httpd->headerdata == NULL) { isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->headerlen = HTTP_SENDGROW; isc_buffer_init(&httpd->headerbuffer, httpd->headerdata, httpd->headerlen); ISC_LIST_INIT(httpd->bufflist); isc_buffer_initnull(&httpd->bodybuffer); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; result = isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); /* FIXME!!! */ POST(result); NOTICE("accept queued recv on socket"); requeue: result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept, httpdmgr); if (result != ISC_R_SUCCESS) { /* XXXMLG what to do? Log failure... */ NOTICE("accept could not reaccept due to failure"); } out: UNLOCK(&httpdmgr->lock); httpdmgr_destroy(httpdmgr); isc_event_free(&ev); EXIT("accept"); }
isc_result_t isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, isc_httpdclientok_t *client_ok, isc_httpdondestroy_t *ondestroy, void *cb_arg, isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdp) { isc_result_t result; isc_httpdmgr_t *httpd; REQUIRE(mctx != NULL); REQUIRE(sock != NULL); REQUIRE(task != NULL); REQUIRE(tmgr != NULL); REQUIRE(httpdp != NULL && *httpdp == NULL); httpd = isc_mem_get(mctx, sizeof(isc_httpdmgr_t)); if (httpd == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&httpd->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t)); return (result); } httpd->mctx = NULL; isc_mem_attach(mctx, &httpd->mctx); httpd->sock = NULL; isc_socket_attach(sock, &httpd->sock); httpd->task = NULL; isc_task_attach(task, &httpd->task); httpd->timermgr = tmgr; /* XXXMLG no attach function? */ httpd->client_ok = client_ok; httpd->ondestroy = ondestroy; httpd->cb_arg = cb_arg; ISC_LIST_INIT(httpd->running); ISC_LIST_INIT(httpd->urls); /* XXXMLG ignore errors on isc_socket_listen() */ result = isc_socket_listen(sock, SOMAXCONN); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_socket_listen() failed: %s", isc_result_totext(result)); goto cleanup; } (void)isc_socket_filter(sock, "httpready"); result = isc_socket_accept(sock, task, isc_httpd_accept, httpd); if (result != ISC_R_SUCCESS) goto cleanup; httpd->render_404 = render_404; httpd->render_500 = render_500; *httpdp = httpd; return (ISC_R_SUCCESS); cleanup: isc_task_detach(&httpd->task); isc_socket_detach(&httpd->sock); isc_mem_detach(&httpd->mctx); (void)isc_mutex_destroy(&httpd->lock); isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t)); return (result); }
ATF_TC_BODY(udp_sendto, tc) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; isc_socket_t *s1 = NULL, *s2 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to * each other. */ in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 5444); isc_sockaddr_fromin(&addr2, &in, 5445); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); result = isc_socket_sendto(s1, &r, task, event_done, &completion, &addr2, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_test_end(); }
static isc_result_t add_listener(ns_server_t *server, ns_statschannel_t **listenerp, const cfg_obj_t *listen_params, const cfg_obj_t *config, isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, const char *socktext) { isc_result_t result; ns_statschannel_t *listener; isc_task_t *task = NULL; isc_socket_t *sock = NULL; const cfg_obj_t *allow; dns_acl_t *new_acl = NULL; listener = isc_mem_get(server->mctx, sizeof(*listener)); if (listener == NULL) return (ISC_R_NOMEMORY); listener->httpdmgr = NULL; listener->address = *addr; listener->acl = NULL; listener->mctx = NULL; ISC_LINK_INIT(listener, link); result = isc_mutex_init(&listener->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(server->mctx, listener, sizeof(*listener)); return (ISC_R_FAILURE); } isc_mem_attach(server->mctx, &listener->mctx); allow = cfg_tuple_get(listen_params, "allow"); if (allow != NULL && cfg_obj_islist(allow)) { result = cfg_acl_fromconfig(allow, config, ns_g_lctx, aclconfctx, listener->mctx, 0, &new_acl); } else result = dns_acl_any(listener->mctx, &new_acl); if (result != ISC_R_SUCCESS) goto cleanup; dns_acl_attach(new_acl, &listener->acl); dns_acl_detach(&new_acl); result = isc_task_create(ns_g_taskmgr, 0, &task); if (result != ISC_R_SUCCESS) goto cleanup; isc_task_setname(task, "statchannel", NULL); result = isc_socket_create(ns_g_socketmgr, isc_sockaddr_pf(addr), isc_sockettype_tcp, &sock); if (result != ISC_R_SUCCESS) goto cleanup; isc_socket_setname(sock, "statchannel", NULL); #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(sock, ISC_TRUE); #endif result = isc_socket_bind(sock, addr, ISC_SOCKET_REUSEADDRESS); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_httpdmgr_create(server->mctx, sock, task, client_ok, destroy_listener, listener, ns_g_timermgr, &listener->httpdmgr); if (result != ISC_R_SUCCESS) goto cleanup; #ifdef HAVE_LIBXML2 isc_httpdmgr_addurl(listener->httpdmgr, "/", render_index, server); #endif isc_httpdmgr_addurl(listener->httpdmgr, "/bind9.xsl", render_xsl, server); *listenerp = listener; isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, "statistics channel listening on %s", socktext); cleanup: if (result != ISC_R_SUCCESS) { if (listener->acl != NULL) dns_acl_detach(&listener->acl); DESTROYLOCK(&listener->lock); isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener)); } if (task != NULL) isc_task_detach(&task); if (sock != NULL) isc_socket_detach(&sock); return (result); }
int main(int argc, char *argv[]) { isc_taskmgr_t *taskmgr; isc_timermgr_t *timermgr; isc_socketmgr_t *socketmgr; isc_socket_t *sock; unsigned int attrs, attrmask; isc_sockaddr_t bind_any; dns_dispatchmgr_t *dispatchmgr; dns_dispatch_t *dispatchv4; dns_view_t *view; isc_entropy_t *ectx; isc_task_t *task; isc_log_t *lctx = NULL; isc_logconfig_t *lcfg = NULL; isc_logdestination_t destination; UNUSED(argv); UNUSED(argc); RUNCHECK(isc_app_start()); dns_result_register(); mctx = NULL; RUNCHECK(isc_mem_create(0, 0, &mctx)); RUNCHECK(isc_log_create(mctx, &lctx, &lcfg)); isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); /* * Create and install the default channel. */ destination.file.stream = stderr; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; RUNCHECK(isc_log_createchannel(lcfg, "_default", ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC, &destination, ISC_LOG_PRINTTIME)); RUNCHECK(isc_log_usechannel(lcfg, "_default", NULL, NULL)); isc_log_setdebuglevel(lctx, 9); ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); RUNCHECK(isc_entropy_createfilesource(ectx, "/dev/urandom")); RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); taskmgr = NULL; RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); task = NULL; RUNCHECK(isc_task_create(taskmgr, 0, &task)); timermgr = NULL; RUNCHECK(isc_timermgr_create(mctx, &timermgr)); socketmgr = NULL; RUNCHECK(isc_socketmgr_create(mctx, &socketmgr)); dispatchmgr = NULL; RUNCHECK(dns_dispatchmgr_create(mctx, ectx, &dispatchmgr)); isc_sockaddr_any(&bind_any); attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | DNS_DISPATCHATTR_IPV4; attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; dispatchv4 = NULL; RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, 4096, 4, 2, 3, 5, attrs, attrmask, &dispatchv4)); requestmgr = NULL; RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); ring = NULL; RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); dns_view_setkeyring(view, ring); sock = NULL; RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &sock)); setup(); RUNCHECK(isc_app_onrun(mctx, task, console, NULL)); (void)isc_app_run(); if (tsigkey) dns_tsigkey_detach(&tsigkey); dns_requestmgr_shutdown(requestmgr); dns_requestmgr_detach(&requestmgr); dns_dispatch_detach(&dispatchv4); dns_dispatchmgr_destroy(&dispatchmgr); isc_timermgr_destroy(&timermgr); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socket_detach(&sock); isc_socketmgr_destroy(&socketmgr); isc_mem_stats(mctx, stdout); dns_view_detach(&view); dst_lib_destroy(); isc_entropy_detach(&ectx); isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); isc_app_finish(); return (0); }
static void control_recvmessage(isc_task_t *task, isc_event_t *event) { controlconnection_t *conn; controllistener_t *listener; controlkey_t *key; isccc_sexpr_t *request = NULL; isccc_sexpr_t *response = NULL; isc_uint32_t algorithm; isccc_region_t secret; isc_stdtime_t now; isc_buffer_t b; isc_region_t r; isc_buffer_t *text; isc_result_t result; isc_result_t eresult; isccc_sexpr_t *_ctrl; isccc_time_t sent; isccc_time_t exp; isc_uint32_t nonce; isccc_sexpr_t *data; REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); conn = event->ev_arg; listener = conn->listener; algorithm = DST_ALG_UNKNOWN; secret.rstart = NULL; text = NULL; /* Is the server shutting down? */ if (listener->controls->shuttingdown) goto cleanup; if (conn->ccmsg.result != ISC_R_SUCCESS) { if (conn->ccmsg.result != ISC_R_CANCELED && conn->ccmsg.result != ISC_R_EOF) log_invalid(&conn->ccmsg, conn->ccmsg.result); goto cleanup; } request = NULL; for (key = ISC_LIST_HEAD(listener->keys); 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); if (secret.rstart == NULL) goto cleanup; memmove(secret.rstart, key->secret.base, key->secret.length); secret.rend = secret.rstart + key->secret.length; algorithm = key->algorithm; result = isccc_cc_fromwire(&ccregion, &request, algorithm, &secret); if (result == ISC_R_SUCCESS) break; isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); if (result != ISCCC_R_BADAUTH) { log_invalid(&conn->ccmsg, result); goto cleanup; } } if (key == NULL) { log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); goto cleanup; } /* We shouldn't be getting a reply. */ if (isccc_cc_isreply(request)) { log_invalid(&conn->ccmsg, ISC_R_FAILURE); goto cleanup_request; } isc_stdtime_get(&now); /* * Limit exposure to replay attacks. */ _ctrl = isccc_alist_lookup(request, "_ctrl"); if (_ctrl == NULL) { log_invalid(&conn->ccmsg, ISC_R_FAILURE); goto cleanup_request; } if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) { if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) { log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW); goto cleanup_request; } } else { log_invalid(&conn->ccmsg, ISC_R_FAILURE); goto cleanup_request; } /* * Expire messages that are too old. */ if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS && now > exp) { log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED); goto cleanup_request; } /* * Duplicate suppression (required for UDP). */ isccc_cc_cleansymtab(listener->controls->symtab, now); result = isccc_cc_checkdup(listener->controls->symtab, request, now); if (result != ISC_R_SUCCESS) { if (result == ISC_R_EXISTS) result = ISCCC_R_DUPLICATE; log_invalid(&conn->ccmsg, result); goto cleanup_request; } if (conn->nonce != 0 && (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS || conn->nonce != nonce)) { log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); goto cleanup_request; } result = isc_buffer_allocate(listener->mctx, &text, 2 * 2048); if (result != ISC_R_SUCCESS) goto cleanup_request; /* * Establish nonce. */ if (conn->nonce == 0) { while (conn->nonce == 0) isc_random_get(&conn->nonce); eresult = ISC_R_SUCCESS; } else eresult = ns_control_docommand(request, &text); result = isccc_cc_createresponse(request, now, now + 60, &response); if (result != ISC_R_SUCCESS) goto cleanup_request; data = isccc_alist_lookup(response, "_data"); if (data != NULL) { if (isccc_cc_defineuint32(data, "result", eresult) == NULL) goto cleanup_response; } if (eresult != ISC_R_SUCCESS) { if (data != NULL) { const char *estr = isc_result_totext(eresult); if (isccc_cc_definestring(data, "err", estr) == NULL) goto cleanup_response; } } if (isc_buffer_usedlength(text) > 0) { if (data != NULL) { char *str = (char *)isc_buffer_base(text); if (isccc_cc_definestring(data, "text", str) == NULL) goto cleanup_response; } } _ctrl = isccc_alist_lookup(response, "_ctrl"); if (_ctrl == NULL || isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL) goto cleanup_response; 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->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) goto cleanup_response; conn->sending = ISC_TRUE; 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: isccc_sexpr_free(&response); 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); isccc_ccmsg_invalidate(&conn->ccmsg); conn->ccmsg_valid = ISC_FALSE; maybe_free_connection(conn); maybe_free_listener(listener); }
isc_result_t ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, dns_dispatchmgr_t *dispatchmgr, isc_task_t *task, ns_interfacemgr_t **mgrp) { isc_result_t result; ns_interfacemgr_t *mgr; #ifndef USE_ROUTE_SOCKET UNUSED(task); #endif REQUIRE(mctx != NULL); REQUIRE(mgrp != NULL); REQUIRE(*mgrp == NULL); mgr = isc_mem_get(mctx, sizeof(*mgr)); if (mgr == NULL) return (ISC_R_NOMEMORY); mgr->mctx = NULL; isc_mem_attach(mctx, &mgr->mctx); result = isc_mutex_init(&mgr->lock); if (result != ISC_R_SUCCESS) goto cleanup_mem; mgr->taskmgr = taskmgr; mgr->socketmgr = socketmgr; mgr->dispatchmgr = dispatchmgr; mgr->generation = 1; mgr->listenon4 = NULL; mgr->listenon6 = NULL; ISC_LIST_INIT(mgr->interfaces); ISC_LIST_INIT(mgr->listenon); /* * The listen-on lists are initially empty. */ result = ns_listenlist_create(mctx, &mgr->listenon4); if (result != ISC_R_SUCCESS) goto cleanup_mem; ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); result = dns_aclenv_init(mctx, &mgr->aclenv); if (result != ISC_R_SUCCESS) goto cleanup_listenon; #ifdef HAVE_GEOIP mgr->aclenv.geoip = ns_g_geoip; #endif #ifdef USE_ROUTE_SOCKET mgr->route = NULL; result = isc_socket_create(mgr->socketmgr, ROUTE_SOCKET_PROTOCOL, isc_sockettype_raw, &mgr->route); switch (result) { case ISC_R_NOPERM: case ISC_R_SUCCESS: case ISC_R_NOTIMPLEMENTED: case ISC_R_FAMILYNOSUPPORT: break; default: goto cleanup_aclenv; } mgr->task = NULL; if (mgr->route != NULL) isc_task_attach(task, &mgr->task); mgr->references = (mgr->route != NULL) ? 2 : 1; #else mgr->references = 1; #endif mgr->magic = IFMGR_MAGIC; *mgrp = mgr; #ifdef USE_ROUTE_SOCKET if (mgr->route != NULL) { isc_region_t r = { mgr->buf, sizeof(mgr->buf) }; result = isc_socket_recv(mgr->route, &r, 1, mgr->task, route_event, mgr); if (result != ISC_R_SUCCESS) { isc_task_detach(&mgr->task); isc_socket_detach(&mgr->route); ns_interfacemgr_detach(&mgr); } } #endif return (ISC_R_SUCCESS); #ifdef USE_ROUTE_SOCKET cleanup_aclenv: dns_aclenv_destroy(&mgr->aclenv); #endif cleanup_listenon: ns_listenlist_detach(&mgr->listenon4); ns_listenlist_detach(&mgr->listenon6); cleanup_mem: isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); return (result); }
int main(int argc, char *argv[]) { isc_boolean_t verbose = ISC_FALSE; isc_socketmgr_t *socketmgr; isc_timermgr_t *timermgr; struct in_addr inaddr; dns_fixedname_t fname; dns_name_t *name; isc_buffer_t b; int ch; isc_result_t result; in_port_t port = 53; RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS); mctx = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); while ((ch = isc_commandline_parse(argc, argv, "vp:")) != -1) { switch (ch) { case 'v': verbose = ISC_TRUE; break; case 'p': port = (unsigned int)atoi(isc_commandline_argument); break; } } RUNTIME_CHECK(isc_entropy_create(mctx, &ent) == ISC_R_SUCCESS); RUNTIME_CHECK(dst_lib_init(mctx, ent, 0) == ISC_R_SUCCESS); dns_result_register(); dst_result_register(); taskmgr = NULL; RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) == ISC_R_SUCCESS); task1 = NULL; RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task1) == ISC_R_SUCCESS); timermgr = NULL; RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS); socketmgr = NULL; RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_log_create(mctx, &lctx, &logconfig) == ISC_R_SUCCESS); s = NULL; RUNTIME_CHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s) == ISC_R_SUCCESS); inaddr.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&address, &inaddr, port); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&b, "child.example.", strlen("child.example.")); isc_buffer_add(&b, strlen("child.example.")); result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); CHECK("dns_name_fromtext", result); key = NULL; result = dst_key_fromfile(name, 4017, DNS_KEYALG_DSA, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, NULL, mctx, &key); CHECK("dst_key_fromfile", result); buildquery(); (void)isc_app_run(); isc_task_shutdown(task1); isc_task_detach(&task1); isc_taskmgr_destroy(&taskmgr); isc_socket_detach(&s); isc_socketmgr_destroy(&socketmgr); isc_timermgr_destroy(&timermgr); dst_key_free(&key); dst_lib_destroy(); isc_entropy_detach(&ent); isc_log_destroy(&lctx); if (verbose) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); DESTROYLOCK(&lock); isc_app_finish(); return (0); }
int main(int argc, char *argv[]) { char *ourkeyname; isc_taskmgr_t *taskmgr; isc_timermgr_t *timermgr; isc_socketmgr_t *socketmgr; isc_socket_t *sock; unsigned int attrs, attrmask; isc_sockaddr_t bind_any; dns_dispatchmgr_t *dispatchmgr; dns_dispatch_t *dispatchv4; dns_view_t *view; isc_entropy_t *ectx; dns_tkeyctx_t *tctx; isc_log_t *log; isc_logconfig_t *logconfig; isc_task_t *task; isc_result_t result; int type; RUNCHECK(isc_app_start()); if (argc < 2) { fprintf(stderr, "I:no DH key provided\n"); exit(-1); } ourkeyname = argv[1]; if (argc >= 3) ownername_str = argv[2]; dns_result_register(); mctx = NULL; RUNCHECK(isc_mem_create(0, 0, &mctx)); ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); RUNCHECK(isc_entropy_createfilesource(ectx, "random.data")); RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); log = NULL; logconfig = NULL; RUNCHECK(isc_log_create(mctx, &log, &logconfig)); RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); taskmgr = NULL; RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); task = NULL; RUNCHECK(isc_task_create(taskmgr, 0, &task)); timermgr = NULL; RUNCHECK(isc_timermgr_create(mctx, &timermgr)); socketmgr = NULL; RUNCHECK(isc_socketmgr_create(mctx, &socketmgr)); dispatchmgr = NULL; RUNCHECK(dns_dispatchmgr_create(mctx, NULL, &dispatchmgr)); isc_sockaddr_any(&bind_any); attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | DNS_DISPATCHATTR_IPV4; attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; dispatchv4 = NULL; RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, 4096, 4, 2, 3, 5, attrs, attrmask, &dispatchv4)); requestmgr = NULL; RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); ring = NULL; RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); tctx = NULL; RUNCHECK(dns_tkeyctx_create(mctx, ectx, &tctx)); view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); dns_view_setkeyring(view, ring); dns_tsigkeyring_detach(&ring); sock = NULL; RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &sock)); RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL)); ourkey = NULL; type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY; result = dst_key_fromnamedfile(ourkeyname, NULL, type, mctx, &ourkey); CHECK("dst_key_fromnamedfile", result); isc_buffer_init(&nonce, noncedata, sizeof(noncedata)); result = isc_entropy_getdata(ectx, noncedata, sizeof(noncedata), NULL, ISC_ENTROPY_BLOCKING); CHECK("isc_entropy_getdata", result); isc_buffer_add(&nonce, sizeof(noncedata)); (void)isc_app_run(); dns_requestmgr_shutdown(requestmgr); dns_requestmgr_detach(&requestmgr); dns_dispatch_detach(&dispatchv4); dns_dispatchmgr_destroy(&dispatchmgr); isc_task_shutdown(task); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socket_detach(&sock); isc_socketmgr_destroy(&socketmgr); isc_timermgr_destroy(&timermgr); dst_key_free(&ourkey); dns_tsigkey_detach(&initialkey); dns_tsigkey_detach(&tsigkey); dns_tkeyctx_destroy(&tctx); dns_view_detach(&view); isc_log_destroy(&log); dst_lib_destroy(); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); isc_app_finish(); return (0); }