static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { isc_result_t result; int pf; isc_sockettype_t type; char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, socktext, sizeof(socktext)); notify("using server %s (%s)", servername, socktext); pf = isc_sockaddr_pf(addr); if (pf == AF_INET || pf == AF_INET6) type = isc_sockettype_tcp; else type = isc_sockettype_unix; DO("create socket", isc_socket_create(socketmgr, pf, type, &sock)); switch (isc_sockaddr_pf(addr)) { case AF_INET: DO("bind socket", isc_socket_bind(sock, &local4)); break; case AF_INET6: DO("bind socket", isc_socket_bind(sock, &local6)); break; default: break; } DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, NULL)); connects++; }
static isc_result_t ns_interface_listenudp(ns_interface_t *ifp) { isc_result_t result; unsigned int attrs; unsigned int attrmask; int disp, i; attrs = 0; attrs |= DNS_DISPATCHATTR_UDP; if (isc_sockaddr_pf(&ifp->addr) == AF_INET) attrs |= DNS_DISPATCHATTR_IPV4; else attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_NOLISTEN; attrmask = 0; attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; ifp->nudpdispatch = ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH); for (disp = 0; disp < ifp->nudpdispatch; disp++) { result = dns_dispatch_getudp_dup(ifp->mgr->dispatchmgr, ns_g_socketmgr, ns_g_taskmgr, &ifp->addr, 4096, 1000, 32768, 8219, 8237, attrs, attrmask, &ifp->udpdispatch[disp], disp == 0 ? NULL : ifp->udpdispatch[0]); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "could not listen on UDP socket: %s", isc_result_totext(result)); goto udp_dispatch_failure; } } result = ns_clientmgr_createclients(ifp->clientmgr, ifp->nudpdispatch, ifp, ISC_FALSE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "UDP ns_clientmgr_createclients(): %s", isc_result_totext(result)); goto addtodispatch_failure; } return (ISC_R_SUCCESS); addtodispatch_failure: for (i = disp - 1; i <= 0; i--) { dns_dispatch_changeattributes(ifp->udpdispatch[i], 0, DNS_DISPATCHATTR_NOLISTEN); dns_dispatch_detach(&(ifp->udpdispatch[i])); } ifp->nudpdispatch = 0; udp_dispatch_failure: return (result); }
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); }
void perf_net_parseserver(int family, const char *name, unsigned int port, isc_sockaddr_t *addr) { isc_sockaddr_t addrs[8]; int count, i; isc_result_t result; if (port == 0) { fprintf(stderr, "server port cannot be 0\n"); perf_opt_usage(); exit(1); } count = 0; result = bind9_getaddresses(name, port, addrs, 8, &count); if (result == ISC_R_SUCCESS) { for (i = 0; i < count; i++) { if (isc_sockaddr_pf(&addrs[i]) == family || family == AF_UNSPEC) { *addr = addrs[i]; return; } } } fprintf(stderr, "invalid server address %s\n", name); perf_opt_usage(); exit(1); }
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 rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { isc_result_t result; char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, socktext, sizeof(socktext)); notify("using server %s (%s)", servername, socktext); DO("create socket", isc_socket_create(socketmgr, isc_sockaddr_pf(addr), isc_sockettype_tcp, &sock)); DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, NULL)); connects++; }
static isc_result_t ns_interface_listenudp(ns_interface_t *ifp) { isc_result_t result; unsigned int attrs; unsigned int attrmask; attrs = 0; attrs |= DNS_DISPATCHATTR_UDP; if (isc_sockaddr_pf(&ifp->addr) == AF_INET) attrs |= DNS_DISPATCHATTR_IPV4; else attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_NOLISTEN; attrmask = 0; attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr, ns_g_taskmgr, &ifp->addr, 4096, 1000, 32768, 8219, 8237, attrs, attrmask, &ifp->udpdispatch); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "could not listen on UDP socket: %s", isc_result_totext(result)); goto udp_dispatch_failure; } result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, ifp, ISC_FALSE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "UDP ns_clientmgr_createclients(): %s", isc_result_totext(result)); goto addtodispatch_failure; } return (ISC_R_SUCCESS); addtodispatch_failure: dns_dispatch_changeattributes(ifp->udpdispatch, 0, DNS_DISPATCHATTR_NOLISTEN); dns_dispatch_detach(&ifp->udpdispatch); udp_dispatch_failure: return (result); }
static void add_listener(ns_controls_t *cp, controllistener_t **listenerp, const cfg_obj_t *control, const cfg_obj_t *config, isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, const char *socktext, isc_sockettype_t type) { isc_mem_t *mctx = cp->server->mctx; controllistener_t *listener; const cfg_obj_t *allow; const cfg_obj_t *global_keylist = NULL; const cfg_obj_t *control_keylist = NULL; dns_acl_t *new_acl = NULL; isc_result_t result = ISC_R_SUCCESS; listener = isc_mem_get(mctx, sizeof(*listener)); if (listener == NULL) result = ISC_R_NOMEMORY; if (result == ISC_R_SUCCESS) { listener->mctx = NULL; isc_mem_attach(mctx, &listener->mctx); listener->controls = cp; listener->task = cp->server->task; listener->address = *addr; listener->sock = NULL; listener->listening = ISC_FALSE; listener->exiting = ISC_FALSE; listener->acl = NULL; listener->type = type; listener->perm = 0; listener->owner = 0; listener->group = 0; ISC_LINK_INIT(listener, link); ISC_LIST_INIT(listener->keys); ISC_LIST_INIT(listener->connections); /* * Make the acl. */ if (control != NULL && type == isc_sockettype_tcp) { allow = cfg_tuple_get(control, "allow"); result = cfg_acl_fromconfig(allow, config, ns_g_lctx, aclconfctx, mctx, 0, &new_acl); } else { result = dns_acl_any(mctx, &new_acl); } } if (result == ISC_R_SUCCESS) { dns_acl_attach(new_acl, &listener->acl); dns_acl_detach(&new_acl); if (config != NULL) get_key_info(config, control, &global_keylist, &control_keylist); if (control_keylist != NULL) { result = controlkeylist_fromcfg(control_keylist, listener->mctx, &listener->keys); if (result == ISC_R_SUCCESS) register_keys(control, global_keylist, &listener->keys, listener->mctx, socktext); } else result = get_rndckey(mctx, &listener->keys); if (result != ISC_R_SUCCESS && control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't install keys for " "command channel %s: %s", socktext, isc_result_totext(result)); } if (result == ISC_R_SUCCESS) { int pf = isc_sockaddr_pf(&listener->address); if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || #ifdef ISC_PLATFORM_HAVESYSUNH (pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) || #endif (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) result = ISC_R_FAMILYNOSUPPORT; } if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) isc_socket_cleanunix(&listener->address, ISC_FALSE); if (result == ISC_R_SUCCESS) result = isc_socket_create(ns_g_socketmgr, isc_sockaddr_pf(&listener->address), type, &listener->sock); if (result == ISC_R_SUCCESS) isc_socket_setname(listener->sock, "control", NULL); #ifndef ISC_ALLOW_MAPPED if (result == ISC_R_SUCCESS) isc_socket_ipv6only(listener->sock, ISC_TRUE); #endif if (result == ISC_R_SUCCESS) result = isc_socket_bind(listener->sock, &listener->address, ISC_SOCKET_REUSEADDRESS); if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); listener->owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); listener->group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); result = isc_socket_permunix(&listener->address, listener->perm, listener->owner, listener->group); } if (result == ISC_R_SUCCESS) result = control_listen(listener); if (result == ISC_R_SUCCESS) result = control_accept(listener); if (result == ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, "command channel listening on %s", socktext); *listenerp = listener; } else { if (listener != NULL) { listener->exiting = ISC_TRUE; free_listener(listener); } if (control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't add command channel %s: %s", socktext, isc_result_totext(result)); else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, "couldn't add command channel %s: %s", socktext, isc_result_totext(result)); *listenerp = NULL; } /* XXXDCL return error results? fail hard? */ }
int perf_net_opensocket(const isc_sockaddr_t *server, const isc_sockaddr_t *local, unsigned int offset, int bufsize) { int family; int sock; isc_sockaddr_t tmp; int port; int ret; int flags; family = isc_sockaddr_pf(server); if (isc_sockaddr_pf(local) != family) perf_log_fatal("server and local addresses have " "different families"); sock = socket(family, SOCK_DGRAM, 0); if (sock == -1) perf_log_fatal("Error: socket: %s\n", strerror(errno)); #if defined(AF_INET6) && defined(IPV6_V6ONLY) if (family == AF_INET6) { int on = 1; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) { perf_log_warning("setsockopt(IPV6_V6ONLY) failed"); } } #endif tmp = *local; port = isc_sockaddr_getport(&tmp); if (port != 0 && offset != 0) { port += offset; if (port >= 0xFFFF) perf_log_fatal("port %d out of range", port); isc_sockaddr_setport(&tmp, port); } if (bind(sock, &tmp.type.sa, tmp.length) == -1) perf_log_fatal("bind: %s\n", strerror(errno)); if (bufsize > 0) { bufsize *= 1024; ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); if (ret < 0) perf_log_warning("setsockbuf(SO_RCVBUF) failed"); ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); if (ret < 0) perf_log_warning("setsockbuf(SO_SNDBUF) failed"); } flags = fcntl(sock, F_GETFL, 0); if (flags < 0) perf_log_fatal("fcntl(F_GETFL)"); ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK); if (ret < 0) perf_log_fatal("fcntl(F_SETFL)"); return sock; }
int main(int argc, char *argv[]) { isc_task_t *t1, *t2; isc_timermgr_t *timgr; isc_time_t expires; isc_interval_t interval; isc_timer_t *ti1; unsigned int workers; isc_socketmgr_t *socketmgr; isc_socket_t *so1, *so2; isc_sockaddr_t sockaddr; struct in_addr ina; struct in6_addr in6a; isc_result_t result; int pf; if (argc > 1) workers = atoi(argv[1]); else workers = 2; printf("%d workers\n", workers); if (isc_net_probeipv6() == ISC_R_SUCCESS) pf = PF_INET6; else pf = PF_INET; /* * EVERYTHING needs a memory context. */ mctx = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); /* * The task manager is independent (other than memory context) */ manager = NULL; RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) == ISC_R_SUCCESS); /* * Timer manager depends only on the memory context as well. */ timgr = NULL; RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS); t1 = NULL; RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS); t2 = NULL; RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, "1") == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, "2") == ISC_R_SUCCESS); printf("task 1 = %p\n", t1); printf("task 2 = %p\n", t2); socketmgr = NULL; RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); /* * Open up a listener socket. */ so1 = NULL; if (pf == PF_INET6) { in6a = in6addr_any; isc_sockaddr_fromin6(&sockaddr, &in6a, 5544); } else { ina.s_addr = INADDR_ANY; isc_sockaddr_fromin(&sockaddr, &ina, 5544); } RUNTIME_CHECK(isc_socket_create(socketmgr, pf, isc_sockettype_tcp, &so1) == ISC_R_SUCCESS); result = isc_socket_bind(so1, &sockaddr, ISC_SOCKET_REUSEADDRESS); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(isc_socket_listen(so1, 0) == ISC_R_SUCCESS); /* * Queue up the first accept event. */ RUNTIME_CHECK(isc_socket_accept(so1, t1, my_listen, "so1") == ISC_R_SUCCESS); isc_time_settoepoch(&expires); isc_interval_set(&interval, 10, 0); ti1 = NULL; RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_once, &expires, &interval, t1, timeout, so1, &ti1) == ISC_R_SUCCESS); /* * Open up a socket that will connect to www.flame.org, port 80. * Why not. :) */ so2 = NULL; ina.s_addr = inet_addr("204.152.184.97"); if (0 && pf == PF_INET6) isc_sockaddr_v6fromin(&sockaddr, &ina, 80); else isc_sockaddr_fromin(&sockaddr, &ina, 80); RUNTIME_CHECK(isc_socket_create(socketmgr, isc_sockaddr_pf(&sockaddr), isc_sockettype_tcp, &so2) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_socket_connect(so2, &sockaddr, t2, my_connect, "so2") == ISC_R_SUCCESS); /* * Detaching these is safe, since the socket will attach to the * task for any outstanding requests. */ isc_task_detach(&t1); isc_task_detach(&t2); /* * Wait a short while. */ sleep(10); fprintf(stderr, "Destroying socket manager\n"); isc_socketmgr_destroy(&socketmgr); fprintf(stderr, "Destroying timer manager\n"); isc_timermgr_destroy(&timgr); fprintf(stderr, "Destroying task manager\n"); isc_taskmgr_destroy(&manager); isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }
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); }