1*00b67f09SDavid van Moolenbroek /* $NetBSD: main.c,v 1.18 2015/07/08 17:28:55 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 1999-2003 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /*! \file */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <ctype.h>
25*00b67f09SDavid van Moolenbroek #include <stdlib.h>
26*00b67f09SDavid van Moolenbroek #include <string.h>
27*00b67f09SDavid van Moolenbroek
28*00b67f09SDavid van Moolenbroek #include <isc/app.h>
29*00b67f09SDavid van Moolenbroek #include <isc/backtrace.h>
30*00b67f09SDavid van Moolenbroek #include <isc/commandline.h>
31*00b67f09SDavid van Moolenbroek #include <isc/dir.h>
32*00b67f09SDavid van Moolenbroek #include <isc/entropy.h>
33*00b67f09SDavid van Moolenbroek #include <isc/file.h>
34*00b67f09SDavid van Moolenbroek #include <isc/hash.h>
35*00b67f09SDavid van Moolenbroek #include <isc/os.h>
36*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
37*00b67f09SDavid van Moolenbroek #include <isc/print.h>
38*00b67f09SDavid van Moolenbroek #include <isc/resource.h>
39*00b67f09SDavid van Moolenbroek #include <isc/stdio.h>
40*00b67f09SDavid van Moolenbroek #include <isc/string.h>
41*00b67f09SDavid van Moolenbroek #include <isc/task.h>
42*00b67f09SDavid van Moolenbroek #include <isc/timer.h>
43*00b67f09SDavid van Moolenbroek #include <isc/util.h>
44*00b67f09SDavid van Moolenbroek
45*00b67f09SDavid van Moolenbroek #include <isccc/result.h>
46*00b67f09SDavid van Moolenbroek
47*00b67f09SDavid van Moolenbroek #include <dns/dispatch.h>
48*00b67f09SDavid van Moolenbroek #include <dns/name.h>
49*00b67f09SDavid van Moolenbroek #include <dns/result.h>
50*00b67f09SDavid van Moolenbroek #include <dns/view.h>
51*00b67f09SDavid van Moolenbroek
52*00b67f09SDavid van Moolenbroek #include <dst/result.h>
53*00b67f09SDavid van Moolenbroek #ifdef PKCS11CRYPTO
54*00b67f09SDavid van Moolenbroek #include <pk11/result.h>
55*00b67f09SDavid van Moolenbroek #endif
56*00b67f09SDavid van Moolenbroek
57*00b67f09SDavid van Moolenbroek #include <dlz/dlz_dlopen_driver.h>
58*00b67f09SDavid van Moolenbroek
59*00b67f09SDavid van Moolenbroek #ifdef HAVE_GPERFTOOLS_PROFILER
60*00b67f09SDavid van Moolenbroek #include <gperftools/profiler.h>
61*00b67f09SDavid van Moolenbroek #endif
62*00b67f09SDavid van Moolenbroek
63*00b67f09SDavid van Moolenbroek
64*00b67f09SDavid van Moolenbroek /*
65*00b67f09SDavid van Moolenbroek * Defining NS_MAIN provides storage declarations (rather than extern)
66*00b67f09SDavid van Moolenbroek * for variables in named/globals.h.
67*00b67f09SDavid van Moolenbroek */
68*00b67f09SDavid van Moolenbroek #define NS_MAIN 1
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek #include <named/builtin.h>
71*00b67f09SDavid van Moolenbroek #include <named/control.h>
72*00b67f09SDavid van Moolenbroek #include <named/globals.h> /* Explicit, though named/log.h includes it. */
73*00b67f09SDavid van Moolenbroek #include <named/interfacemgr.h>
74*00b67f09SDavid van Moolenbroek #include <named/log.h>
75*00b67f09SDavid van Moolenbroek #include <named/os.h>
76*00b67f09SDavid van Moolenbroek #include <named/server.h>
77*00b67f09SDavid van Moolenbroek #include <named/lwresd.h>
78*00b67f09SDavid van Moolenbroek #include <named/main.h>
79*00b67f09SDavid van Moolenbroek #include <named/seccomp.h>
80*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSCF
81*00b67f09SDavid van Moolenbroek #include <named/ns_smf_globals.h>
82*00b67f09SDavid van Moolenbroek #endif
83*00b67f09SDavid van Moolenbroek
84*00b67f09SDavid van Moolenbroek #ifdef OPENSSL
85*00b67f09SDavid van Moolenbroek #include <openssl/opensslv.h>
86*00b67f09SDavid van Moolenbroek #include <openssl/crypto.h>
87*00b67f09SDavid van Moolenbroek #endif
88*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBXML2
89*00b67f09SDavid van Moolenbroek #include <libxml/xmlversion.h>
90*00b67f09SDavid van Moolenbroek #endif
91*00b67f09SDavid van Moolenbroek
92*00b67f09SDavid van Moolenbroek #include "pfilter.h"
93*00b67f09SDavid van Moolenbroek
94*00b67f09SDavid van Moolenbroek /*
95*00b67f09SDavid van Moolenbroek * Include header files for database drivers here.
96*00b67f09SDavid van Moolenbroek */
97*00b67f09SDavid van Moolenbroek /* #include "xxdb.h" */
98*00b67f09SDavid van Moolenbroek
99*00b67f09SDavid van Moolenbroek #ifdef CONTRIB_DLZ
100*00b67f09SDavid van Moolenbroek /*
101*00b67f09SDavid van Moolenbroek * Include contributed DLZ drivers if appropriate.
102*00b67f09SDavid van Moolenbroek */
103*00b67f09SDavid van Moolenbroek #include <dlz/dlz_drivers.h>
104*00b67f09SDavid van Moolenbroek #endif
105*00b67f09SDavid van Moolenbroek
106*00b67f09SDavid van Moolenbroek /*
107*00b67f09SDavid van Moolenbroek * The maximum number of stack frames to dump on assertion failure.
108*00b67f09SDavid van Moolenbroek */
109*00b67f09SDavid van Moolenbroek #ifndef BACKTRACE_MAXFRAME
110*00b67f09SDavid van Moolenbroek #define BACKTRACE_MAXFRAME 128
111*00b67f09SDavid van Moolenbroek #endif
112*00b67f09SDavid van Moolenbroek
113*00b67f09SDavid van Moolenbroek extern int isc_dscp_check_value;
114*00b67f09SDavid van Moolenbroek extern unsigned int dns_zone_mkey_hour;
115*00b67f09SDavid van Moolenbroek extern unsigned int dns_zone_mkey_day;
116*00b67f09SDavid van Moolenbroek extern unsigned int dns_zone_mkey_month;
117*00b67f09SDavid van Moolenbroek
118*00b67f09SDavid van Moolenbroek static isc_boolean_t want_stats = ISC_FALSE;
119*00b67f09SDavid van Moolenbroek static char program_name[ISC_DIR_NAMEMAX] = "named";
120*00b67f09SDavid van Moolenbroek static char absolute_conffile[ISC_DIR_PATHMAX];
121*00b67f09SDavid van Moolenbroek static char saved_command_line[512];
122*00b67f09SDavid van Moolenbroek static char version[512];
123*00b67f09SDavid van Moolenbroek static unsigned int maxsocks = 0;
124*00b67f09SDavid van Moolenbroek static int maxudp = 0;
125*00b67f09SDavid van Moolenbroek
126*00b67f09SDavid van Moolenbroek void
ns_main_earlywarning(const char * format,...)127*00b67f09SDavid van Moolenbroek ns_main_earlywarning(const char *format, ...) {
128*00b67f09SDavid van Moolenbroek va_list args;
129*00b67f09SDavid van Moolenbroek
130*00b67f09SDavid van Moolenbroek va_start(args, format);
131*00b67f09SDavid van Moolenbroek if (ns_g_lctx != NULL) {
132*00b67f09SDavid van Moolenbroek isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
133*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
134*00b67f09SDavid van Moolenbroek format, args);
135*00b67f09SDavid van Moolenbroek } else {
136*00b67f09SDavid van Moolenbroek fprintf(stderr, "%s: ", program_name);
137*00b67f09SDavid van Moolenbroek vfprintf(stderr, format, args);
138*00b67f09SDavid van Moolenbroek fprintf(stderr, "\n");
139*00b67f09SDavid van Moolenbroek fflush(stderr);
140*00b67f09SDavid van Moolenbroek }
141*00b67f09SDavid van Moolenbroek va_end(args);
142*00b67f09SDavid van Moolenbroek }
143*00b67f09SDavid van Moolenbroek
144*00b67f09SDavid van Moolenbroek void
ns_main_earlyfatal(const char * format,...)145*00b67f09SDavid van Moolenbroek ns_main_earlyfatal(const char *format, ...) {
146*00b67f09SDavid van Moolenbroek va_list args;
147*00b67f09SDavid van Moolenbroek
148*00b67f09SDavid van Moolenbroek va_start(args, format);
149*00b67f09SDavid van Moolenbroek if (ns_g_lctx != NULL) {
150*00b67f09SDavid van Moolenbroek isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
151*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
152*00b67f09SDavid van Moolenbroek format, args);
153*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
154*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
155*00b67f09SDavid van Moolenbroek "exiting (due to early fatal error)");
156*00b67f09SDavid van Moolenbroek } else {
157*00b67f09SDavid van Moolenbroek fprintf(stderr, "%s: ", program_name);
158*00b67f09SDavid van Moolenbroek vfprintf(stderr, format, args);
159*00b67f09SDavid van Moolenbroek fprintf(stderr, "\n");
160*00b67f09SDavid van Moolenbroek fflush(stderr);
161*00b67f09SDavid van Moolenbroek }
162*00b67f09SDavid van Moolenbroek va_end(args);
163*00b67f09SDavid van Moolenbroek
164*00b67f09SDavid van Moolenbroek exit(1);
165*00b67f09SDavid van Moolenbroek }
166*00b67f09SDavid van Moolenbroek
167*00b67f09SDavid van Moolenbroek ISC_PLATFORM_NORETURN_PRE static void
168*00b67f09SDavid van Moolenbroek assertion_failed(const char *file, int line, isc_assertiontype_t type,
169*00b67f09SDavid van Moolenbroek const char *cond) ISC_PLATFORM_NORETURN_POST;
170*00b67f09SDavid van Moolenbroek
171*00b67f09SDavid van Moolenbroek static void
assertion_failed(const char * file,int line,isc_assertiontype_t type,const char * cond)172*00b67f09SDavid van Moolenbroek assertion_failed(const char *file, int line, isc_assertiontype_t type,
173*00b67f09SDavid van Moolenbroek const char *cond)
174*00b67f09SDavid van Moolenbroek {
175*00b67f09SDavid van Moolenbroek void *tracebuf[BACKTRACE_MAXFRAME];
176*00b67f09SDavid van Moolenbroek int i, nframes;
177*00b67f09SDavid van Moolenbroek isc_result_t result;
178*00b67f09SDavid van Moolenbroek const char *logsuffix = "";
179*00b67f09SDavid van Moolenbroek const char *fname;
180*00b67f09SDavid van Moolenbroek
181*00b67f09SDavid van Moolenbroek /*
182*00b67f09SDavid van Moolenbroek * Handle assertion failures.
183*00b67f09SDavid van Moolenbroek */
184*00b67f09SDavid van Moolenbroek
185*00b67f09SDavid van Moolenbroek if (ns_g_lctx != NULL) {
186*00b67f09SDavid van Moolenbroek /*
187*00b67f09SDavid van Moolenbroek * Reset the assertion callback in case it is the log
188*00b67f09SDavid van Moolenbroek * routines causing the assertion.
189*00b67f09SDavid van Moolenbroek */
190*00b67f09SDavid van Moolenbroek isc_assertion_setcallback(NULL);
191*00b67f09SDavid van Moolenbroek
192*00b67f09SDavid van Moolenbroek result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME,
193*00b67f09SDavid van Moolenbroek &nframes);
194*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS && nframes > 0)
195*00b67f09SDavid van Moolenbroek logsuffix = ", back trace";
196*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
197*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
198*00b67f09SDavid van Moolenbroek "%s:%d: %s(%s) failed%s", file, line,
199*00b67f09SDavid van Moolenbroek isc_assertion_typetotext(type), cond, logsuffix);
200*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
201*00b67f09SDavid van Moolenbroek for (i = 0; i < nframes; i++) {
202*00b67f09SDavid van Moolenbroek unsigned long offset;
203*00b67f09SDavid van Moolenbroek
204*00b67f09SDavid van Moolenbroek fname = NULL;
205*00b67f09SDavid van Moolenbroek result = isc_backtrace_getsymbol(tracebuf[i],
206*00b67f09SDavid van Moolenbroek &fname,
207*00b67f09SDavid van Moolenbroek &offset);
208*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
209*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx,
210*00b67f09SDavid van Moolenbroek NS_LOGCATEGORY_GENERAL,
211*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN,
212*00b67f09SDavid van Moolenbroek ISC_LOG_CRITICAL,
213*00b67f09SDavid van Moolenbroek "#%d %p in %s()+0x%lx", i,
214*00b67f09SDavid van Moolenbroek tracebuf[i], fname,
215*00b67f09SDavid van Moolenbroek offset);
216*00b67f09SDavid van Moolenbroek } else {
217*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx,
218*00b67f09SDavid van Moolenbroek NS_LOGCATEGORY_GENERAL,
219*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN,
220*00b67f09SDavid van Moolenbroek ISC_LOG_CRITICAL,
221*00b67f09SDavid van Moolenbroek "#%d %p in ??", i,
222*00b67f09SDavid van Moolenbroek tracebuf[i]);
223*00b67f09SDavid van Moolenbroek }
224*00b67f09SDavid van Moolenbroek }
225*00b67f09SDavid van Moolenbroek }
226*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
227*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
228*00b67f09SDavid van Moolenbroek "exiting (due to assertion failure)");
229*00b67f09SDavid van Moolenbroek } else {
230*00b67f09SDavid van Moolenbroek fprintf(stderr, "%s:%d: %s(%s) failed\n",
231*00b67f09SDavid van Moolenbroek file, line, isc_assertion_typetotext(type), cond);
232*00b67f09SDavid van Moolenbroek fflush(stderr);
233*00b67f09SDavid van Moolenbroek }
234*00b67f09SDavid van Moolenbroek
235*00b67f09SDavid van Moolenbroek if (ns_g_coreok)
236*00b67f09SDavid van Moolenbroek abort();
237*00b67f09SDavid van Moolenbroek exit(1);
238*00b67f09SDavid van Moolenbroek }
239*00b67f09SDavid van Moolenbroek
240*00b67f09SDavid van Moolenbroek ISC_PLATFORM_NORETURN_PRE static void
241*00b67f09SDavid van Moolenbroek library_fatal_error(const char *file, int line, const char *format,
242*00b67f09SDavid van Moolenbroek va_list args)
243*00b67f09SDavid van Moolenbroek ISC_FORMAT_PRINTF(3, 0) ISC_PLATFORM_NORETURN_POST;
244*00b67f09SDavid van Moolenbroek
245*00b67f09SDavid van Moolenbroek static void
library_fatal_error(const char * file,int line,const char * format,va_list args)246*00b67f09SDavid van Moolenbroek library_fatal_error(const char *file, int line, const char *format,
247*00b67f09SDavid van Moolenbroek va_list args)
248*00b67f09SDavid van Moolenbroek {
249*00b67f09SDavid van Moolenbroek /*
250*00b67f09SDavid van Moolenbroek * Handle isc_error_fatal() calls from our libraries.
251*00b67f09SDavid van Moolenbroek */
252*00b67f09SDavid van Moolenbroek
253*00b67f09SDavid van Moolenbroek if (ns_g_lctx != NULL) {
254*00b67f09SDavid van Moolenbroek /*
255*00b67f09SDavid van Moolenbroek * Reset the error callback in case it is the log
256*00b67f09SDavid van Moolenbroek * routines causing the assertion.
257*00b67f09SDavid van Moolenbroek */
258*00b67f09SDavid van Moolenbroek isc_error_setfatal(NULL);
259*00b67f09SDavid van Moolenbroek
260*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
261*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
262*00b67f09SDavid van Moolenbroek "%s:%d: fatal error:", file, line);
263*00b67f09SDavid van Moolenbroek isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
264*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
265*00b67f09SDavid van Moolenbroek format, args);
266*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
267*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
268*00b67f09SDavid van Moolenbroek "exiting (due to fatal error in library)");
269*00b67f09SDavid van Moolenbroek } else {
270*00b67f09SDavid van Moolenbroek fprintf(stderr, "%s:%d: fatal error: ", file, line);
271*00b67f09SDavid van Moolenbroek vfprintf(stderr, format, args);
272*00b67f09SDavid van Moolenbroek fprintf(stderr, "\n");
273*00b67f09SDavid van Moolenbroek fflush(stderr);
274*00b67f09SDavid van Moolenbroek }
275*00b67f09SDavid van Moolenbroek
276*00b67f09SDavid van Moolenbroek if (ns_g_coreok)
277*00b67f09SDavid van Moolenbroek abort();
278*00b67f09SDavid van Moolenbroek exit(1);
279*00b67f09SDavid van Moolenbroek }
280*00b67f09SDavid van Moolenbroek
281*00b67f09SDavid van Moolenbroek static void
282*00b67f09SDavid van Moolenbroek library_unexpected_error(const char *file, int line, const char *format,
283*00b67f09SDavid van Moolenbroek va_list args) ISC_FORMAT_PRINTF(3, 0);
284*00b67f09SDavid van Moolenbroek
285*00b67f09SDavid van Moolenbroek static void
library_unexpected_error(const char * file,int line,const char * format,va_list args)286*00b67f09SDavid van Moolenbroek library_unexpected_error(const char *file, int line, const char *format,
287*00b67f09SDavid van Moolenbroek va_list args)
288*00b67f09SDavid van Moolenbroek {
289*00b67f09SDavid van Moolenbroek /*
290*00b67f09SDavid van Moolenbroek * Handle isc_error_unexpected() calls from our libraries.
291*00b67f09SDavid van Moolenbroek */
292*00b67f09SDavid van Moolenbroek
293*00b67f09SDavid van Moolenbroek if (ns_g_lctx != NULL) {
294*00b67f09SDavid van Moolenbroek char fmt[2048];
295*00b67f09SDavid van Moolenbroek snprintf(fmt, sizeof(fmt),
296*00b67f09SDavid van Moolenbroek "%s:%d: unexpected error: %s", file, line, format);
297*00b67f09SDavid van Moolenbroek isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
298*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_ERROR,
299*00b67f09SDavid van Moolenbroek fmt, args);
300*00b67f09SDavid van Moolenbroek } else {
301*00b67f09SDavid van Moolenbroek fprintf(stderr, "%s:%d: fatal error: ", file, line);
302*00b67f09SDavid van Moolenbroek vfprintf(stderr, format, args);
303*00b67f09SDavid van Moolenbroek fprintf(stderr, "\n");
304*00b67f09SDavid van Moolenbroek fflush(stderr);
305*00b67f09SDavid van Moolenbroek }
306*00b67f09SDavid van Moolenbroek }
307*00b67f09SDavid van Moolenbroek
308*00b67f09SDavid van Moolenbroek static void
lwresd_usage(void)309*00b67f09SDavid van Moolenbroek lwresd_usage(void) {
310*00b67f09SDavid van Moolenbroek fprintf(stderr,
311*00b67f09SDavid van Moolenbroek "usage: lwresd [-4|-6] [-c conffile | -C resolvconffile] "
312*00b67f09SDavid van Moolenbroek "[-d debuglevel]\n"
313*00b67f09SDavid van Moolenbroek " [-f|-g] [-n number_of_cpus] [-p port] "
314*00b67f09SDavid van Moolenbroek "[-P listen-port] [-s]\n"
315*00b67f09SDavid van Moolenbroek " [-t chrootdir] [-u username] [-i pidfile]\n"
316*00b67f09SDavid van Moolenbroek " [-m {usage|trace|record|size|mctx}]\n");
317*00b67f09SDavid van Moolenbroek }
318*00b67f09SDavid van Moolenbroek
319*00b67f09SDavid van Moolenbroek static void
usage(void)320*00b67f09SDavid van Moolenbroek usage(void) {
321*00b67f09SDavid van Moolenbroek if (ns_g_lwresdonly) {
322*00b67f09SDavid van Moolenbroek lwresd_usage();
323*00b67f09SDavid van Moolenbroek return;
324*00b67f09SDavid van Moolenbroek }
325*00b67f09SDavid van Moolenbroek fprintf(stderr,
326*00b67f09SDavid van Moolenbroek "usage: named [-4|-6] [-c conffile] [-d debuglevel] "
327*00b67f09SDavid van Moolenbroek "[-E engine] [-f|-g]\n"
328*00b67f09SDavid van Moolenbroek " [-n number_of_cpus] [-p port] [-s] "
329*00b67f09SDavid van Moolenbroek "[-t chrootdir] [-u username]\n"
330*00b67f09SDavid van Moolenbroek " [-m {usage|trace|record|size|mctx}]\n");
331*00b67f09SDavid van Moolenbroek }
332*00b67f09SDavid van Moolenbroek
333*00b67f09SDavid van Moolenbroek static void
save_command_line(int argc,char * argv[])334*00b67f09SDavid van Moolenbroek save_command_line(int argc, char *argv[]) {
335*00b67f09SDavid van Moolenbroek int i;
336*00b67f09SDavid van Moolenbroek char *src;
337*00b67f09SDavid van Moolenbroek char *dst;
338*00b67f09SDavid van Moolenbroek char *eob;
339*00b67f09SDavid van Moolenbroek const char truncated[] = "...";
340*00b67f09SDavid van Moolenbroek isc_boolean_t quoted = ISC_FALSE;
341*00b67f09SDavid van Moolenbroek
342*00b67f09SDavid van Moolenbroek dst = saved_command_line;
343*00b67f09SDavid van Moolenbroek eob = saved_command_line + sizeof(saved_command_line);
344*00b67f09SDavid van Moolenbroek
345*00b67f09SDavid van Moolenbroek for (i = 1; i < argc && dst < eob; i++) {
346*00b67f09SDavid van Moolenbroek *dst++ = ' ';
347*00b67f09SDavid van Moolenbroek
348*00b67f09SDavid van Moolenbroek src = argv[i];
349*00b67f09SDavid van Moolenbroek while (*src != '\0' && dst < eob) {
350*00b67f09SDavid van Moolenbroek /*
351*00b67f09SDavid van Moolenbroek * This won't perfectly produce a shell-independent
352*00b67f09SDavid van Moolenbroek * pastable command line in all circumstances, but
353*00b67f09SDavid van Moolenbroek * comes close, and for practical purposes will
354*00b67f09SDavid van Moolenbroek * nearly always be fine.
355*00b67f09SDavid van Moolenbroek */
356*00b67f09SDavid van Moolenbroek if (quoted || isalnum(*src & 0xff) ||
357*00b67f09SDavid van Moolenbroek *src == '-' || *src == '_' ||
358*00b67f09SDavid van Moolenbroek *src == '.' || *src == '/') {
359*00b67f09SDavid van Moolenbroek *dst++ = *src++;
360*00b67f09SDavid van Moolenbroek quoted = ISC_FALSE;
361*00b67f09SDavid van Moolenbroek } else {
362*00b67f09SDavid van Moolenbroek *dst++ = '\\';
363*00b67f09SDavid van Moolenbroek quoted = ISC_TRUE;
364*00b67f09SDavid van Moolenbroek }
365*00b67f09SDavid van Moolenbroek }
366*00b67f09SDavid van Moolenbroek }
367*00b67f09SDavid van Moolenbroek
368*00b67f09SDavid van Moolenbroek INSIST(sizeof(saved_command_line) >= sizeof(truncated));
369*00b67f09SDavid van Moolenbroek
370*00b67f09SDavid van Moolenbroek if (dst == eob)
371*00b67f09SDavid van Moolenbroek strcpy(eob - sizeof(truncated), truncated);
372*00b67f09SDavid van Moolenbroek else
373*00b67f09SDavid van Moolenbroek *dst = '\0';
374*00b67f09SDavid van Moolenbroek }
375*00b67f09SDavid van Moolenbroek
376*00b67f09SDavid van Moolenbroek static int
parse_int(char * arg,const char * desc)377*00b67f09SDavid van Moolenbroek parse_int(char *arg, const char *desc) {
378*00b67f09SDavid van Moolenbroek char *endp;
379*00b67f09SDavid van Moolenbroek int tmp;
380*00b67f09SDavid van Moolenbroek long int ltmp;
381*00b67f09SDavid van Moolenbroek
382*00b67f09SDavid van Moolenbroek ltmp = strtol(arg, &endp, 10);
383*00b67f09SDavid van Moolenbroek tmp = (int) ltmp;
384*00b67f09SDavid van Moolenbroek if (*endp != '\0')
385*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("%s '%s' must be numeric", desc, arg);
386*00b67f09SDavid van Moolenbroek if (tmp < 0 || tmp != ltmp)
387*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("%s '%s' out of range", desc, arg);
388*00b67f09SDavid van Moolenbroek return (tmp);
389*00b67f09SDavid van Moolenbroek }
390*00b67f09SDavid van Moolenbroek
391*00b67f09SDavid van Moolenbroek static struct flag_def {
392*00b67f09SDavid van Moolenbroek const char *name;
393*00b67f09SDavid van Moolenbroek unsigned int value;
394*00b67f09SDavid van Moolenbroek } mem_debug_flags[] = {
395*00b67f09SDavid van Moolenbroek { "trace", ISC_MEM_DEBUGTRACE },
396*00b67f09SDavid van Moolenbroek { "record", ISC_MEM_DEBUGRECORD },
397*00b67f09SDavid van Moolenbroek { "usage", ISC_MEM_DEBUGUSAGE },
398*00b67f09SDavid van Moolenbroek { "size", ISC_MEM_DEBUGSIZE },
399*00b67f09SDavid van Moolenbroek { "mctx", ISC_MEM_DEBUGCTX },
400*00b67f09SDavid van Moolenbroek { NULL, 0 }
401*00b67f09SDavid van Moolenbroek };
402*00b67f09SDavid van Moolenbroek
403*00b67f09SDavid van Moolenbroek static void
set_flags(const char * arg,struct flag_def * defs,unsigned int * ret)404*00b67f09SDavid van Moolenbroek set_flags(const char *arg, struct flag_def *defs, unsigned int *ret) {
405*00b67f09SDavid van Moolenbroek for (;;) {
406*00b67f09SDavid van Moolenbroek const struct flag_def *def;
407*00b67f09SDavid van Moolenbroek const char *end = strchr(arg, ',');
408*00b67f09SDavid van Moolenbroek int arglen;
409*00b67f09SDavid van Moolenbroek if (end == NULL)
410*00b67f09SDavid van Moolenbroek end = arg + strlen(arg);
411*00b67f09SDavid van Moolenbroek arglen = (int)(end - arg);
412*00b67f09SDavid van Moolenbroek for (def = defs; def->name != NULL; def++) {
413*00b67f09SDavid van Moolenbroek if (arglen == (int)strlen(def->name) &&
414*00b67f09SDavid van Moolenbroek memcmp(arg, def->name, arglen) == 0) {
415*00b67f09SDavid van Moolenbroek *ret |= def->value;
416*00b67f09SDavid van Moolenbroek goto found;
417*00b67f09SDavid van Moolenbroek }
418*00b67f09SDavid van Moolenbroek }
419*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("unrecognized flag '%.*s'", arglen, arg);
420*00b67f09SDavid van Moolenbroek found:
421*00b67f09SDavid van Moolenbroek if (*end == '\0')
422*00b67f09SDavid van Moolenbroek break;
423*00b67f09SDavid van Moolenbroek arg = end + 1;
424*00b67f09SDavid van Moolenbroek }
425*00b67f09SDavid van Moolenbroek }
426*00b67f09SDavid van Moolenbroek
427*00b67f09SDavid van Moolenbroek static void
parse_command_line(int argc,char * argv[])428*00b67f09SDavid van Moolenbroek parse_command_line(int argc, char *argv[]) {
429*00b67f09SDavid van Moolenbroek int ch;
430*00b67f09SDavid van Moolenbroek int port;
431*00b67f09SDavid van Moolenbroek const char *p;
432*00b67f09SDavid van Moolenbroek
433*00b67f09SDavid van Moolenbroek save_command_line(argc, argv);
434*00b67f09SDavid van Moolenbroek
435*00b67f09SDavid van Moolenbroek /* PLEASE keep options synchronized when main is hooked! */
436*00b67f09SDavid van Moolenbroek #define CMDLINE_FLAGS "46c:C:d:D:E:fFgi:lm:n:N:p:P:sS:t:T:U:u:vVx:"
437*00b67f09SDavid van Moolenbroek isc_commandline_errprint = ISC_FALSE;
438*00b67f09SDavid van Moolenbroek while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
439*00b67f09SDavid van Moolenbroek switch (ch) {
440*00b67f09SDavid van Moolenbroek case '4':
441*00b67f09SDavid van Moolenbroek if (ns_g_disable4)
442*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("cannot specify -4 and -6");
443*00b67f09SDavid van Moolenbroek if (isc_net_probeipv4() != ISC_R_SUCCESS)
444*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("IPv4 not supported by OS");
445*00b67f09SDavid van Moolenbroek isc_net_disableipv6();
446*00b67f09SDavid van Moolenbroek ns_g_disable6 = ISC_TRUE;
447*00b67f09SDavid van Moolenbroek break;
448*00b67f09SDavid van Moolenbroek case '6':
449*00b67f09SDavid van Moolenbroek if (ns_g_disable6)
450*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("cannot specify -4 and -6");
451*00b67f09SDavid van Moolenbroek if (isc_net_probeipv6() != ISC_R_SUCCESS)
452*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("IPv6 not supported by OS");
453*00b67f09SDavid van Moolenbroek isc_net_disableipv4();
454*00b67f09SDavid van Moolenbroek ns_g_disable4 = ISC_TRUE;
455*00b67f09SDavid van Moolenbroek break;
456*00b67f09SDavid van Moolenbroek case 'c':
457*00b67f09SDavid van Moolenbroek ns_g_conffile = isc_commandline_argument;
458*00b67f09SDavid van Moolenbroek lwresd_g_conffile = isc_commandline_argument;
459*00b67f09SDavid van Moolenbroek if (lwresd_g_useresolvconf)
460*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("cannot specify -c and -C");
461*00b67f09SDavid van Moolenbroek ns_g_conffileset = ISC_TRUE;
462*00b67f09SDavid van Moolenbroek break;
463*00b67f09SDavid van Moolenbroek case 'C':
464*00b67f09SDavid van Moolenbroek lwresd_g_resolvconffile = isc_commandline_argument;
465*00b67f09SDavid van Moolenbroek if (ns_g_conffileset)
466*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("cannot specify -c and -C");
467*00b67f09SDavid van Moolenbroek lwresd_g_useresolvconf = ISC_TRUE;
468*00b67f09SDavid van Moolenbroek break;
469*00b67f09SDavid van Moolenbroek case 'd':
470*00b67f09SDavid van Moolenbroek ns_g_debuglevel = parse_int(isc_commandline_argument,
471*00b67f09SDavid van Moolenbroek "debug level");
472*00b67f09SDavid van Moolenbroek break;
473*00b67f09SDavid van Moolenbroek case 'D':
474*00b67f09SDavid van Moolenbroek /* Descriptive comment for 'ps'. */
475*00b67f09SDavid van Moolenbroek break;
476*00b67f09SDavid van Moolenbroek case 'E':
477*00b67f09SDavid van Moolenbroek ns_g_engine = isc_commandline_argument;
478*00b67f09SDavid van Moolenbroek break;
479*00b67f09SDavid van Moolenbroek case 'f':
480*00b67f09SDavid van Moolenbroek ns_g_foreground = ISC_TRUE;
481*00b67f09SDavid van Moolenbroek break;
482*00b67f09SDavid van Moolenbroek case 'g':
483*00b67f09SDavid van Moolenbroek ns_g_foreground = ISC_TRUE;
484*00b67f09SDavid van Moolenbroek ns_g_logstderr = ISC_TRUE;
485*00b67f09SDavid van Moolenbroek break;
486*00b67f09SDavid van Moolenbroek /* XXXBEW -i should be removed */
487*00b67f09SDavid van Moolenbroek case 'i':
488*00b67f09SDavid van Moolenbroek lwresd_g_defaultpidfile = isc_commandline_argument;
489*00b67f09SDavid van Moolenbroek break;
490*00b67f09SDavid van Moolenbroek case 'l':
491*00b67f09SDavid van Moolenbroek ns_g_lwresdonly = ISC_TRUE;
492*00b67f09SDavid van Moolenbroek break;
493*00b67f09SDavid van Moolenbroek case 'm':
494*00b67f09SDavid van Moolenbroek set_flags(isc_commandline_argument, mem_debug_flags,
495*00b67f09SDavid van Moolenbroek &isc_mem_debugging);
496*00b67f09SDavid van Moolenbroek break;
497*00b67f09SDavid van Moolenbroek case 'N': /* Deprecated. */
498*00b67f09SDavid van Moolenbroek case 'n':
499*00b67f09SDavid van Moolenbroek ns_g_cpus = parse_int(isc_commandline_argument,
500*00b67f09SDavid van Moolenbroek "number of cpus");
501*00b67f09SDavid van Moolenbroek if (ns_g_cpus == 0)
502*00b67f09SDavid van Moolenbroek ns_g_cpus = 1;
503*00b67f09SDavid van Moolenbroek break;
504*00b67f09SDavid van Moolenbroek case 'p':
505*00b67f09SDavid van Moolenbroek port = parse_int(isc_commandline_argument, "port");
506*00b67f09SDavid van Moolenbroek if (port < 1 || port > 65535)
507*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("port '%s' out of range",
508*00b67f09SDavid van Moolenbroek isc_commandline_argument);
509*00b67f09SDavid van Moolenbroek ns_g_port = port;
510*00b67f09SDavid van Moolenbroek break;
511*00b67f09SDavid van Moolenbroek /* XXXBEW Should -P be removed? */
512*00b67f09SDavid van Moolenbroek case 'P':
513*00b67f09SDavid van Moolenbroek port = parse_int(isc_commandline_argument, "port");
514*00b67f09SDavid van Moolenbroek if (port < 1 || port > 65535)
515*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("port '%s' out of range",
516*00b67f09SDavid van Moolenbroek isc_commandline_argument);
517*00b67f09SDavid van Moolenbroek lwresd_g_listenport = port;
518*00b67f09SDavid van Moolenbroek break;
519*00b67f09SDavid van Moolenbroek case 's':
520*00b67f09SDavid van Moolenbroek /* XXXRTH temporary syntax */
521*00b67f09SDavid van Moolenbroek want_stats = ISC_TRUE;
522*00b67f09SDavid van Moolenbroek break;
523*00b67f09SDavid van Moolenbroek case 'S':
524*00b67f09SDavid van Moolenbroek maxsocks = parse_int(isc_commandline_argument,
525*00b67f09SDavid van Moolenbroek "max number of sockets");
526*00b67f09SDavid van Moolenbroek break;
527*00b67f09SDavid van Moolenbroek case 't':
528*00b67f09SDavid van Moolenbroek /* XXXJAB should we make a copy? */
529*00b67f09SDavid van Moolenbroek ns_g_chrootdir = isc_commandline_argument;
530*00b67f09SDavid van Moolenbroek break;
531*00b67f09SDavid van Moolenbroek case 'T': /* NOT DOCUMENTED */
532*00b67f09SDavid van Moolenbroek /*
533*00b67f09SDavid van Moolenbroek * force the server to behave (or misbehave) in
534*00b67f09SDavid van Moolenbroek * specified ways for testing purposes.
535*00b67f09SDavid van Moolenbroek *
536*00b67f09SDavid van Moolenbroek * clienttest: make clients single shot with their
537*00b67f09SDavid van Moolenbroek * own memory context.
538*00b67f09SDavid van Moolenbroek * delay=xxxx: delay client responses by xxxx ms to
539*00b67f09SDavid van Moolenbroek * simulate remote servers.
540*00b67f09SDavid van Moolenbroek * dscp=x: check that dscp values are as
541*00b67f09SDavid van Moolenbroek * expected and assert otherwise.
542*00b67f09SDavid van Moolenbroek */
543*00b67f09SDavid van Moolenbroek if (!strcmp(isc_commandline_argument, "clienttest"))
544*00b67f09SDavid van Moolenbroek ns_g_clienttest = ISC_TRUE;
545*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "nosoa"))
546*00b67f09SDavid van Moolenbroek ns_g_nosoa = ISC_TRUE;
547*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "noaa"))
548*00b67f09SDavid van Moolenbroek ns_g_noaa = ISC_TRUE;
549*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "maxudp512"))
550*00b67f09SDavid van Moolenbroek maxudp = 512;
551*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "maxudp1460"))
552*00b67f09SDavid van Moolenbroek maxudp = 1460;
553*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "dropedns"))
554*00b67f09SDavid van Moolenbroek ns_g_dropedns = ISC_TRUE;
555*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "noedns"))
556*00b67f09SDavid van Moolenbroek ns_g_noedns = ISC_TRUE;
557*00b67f09SDavid van Moolenbroek else if (!strncmp(isc_commandline_argument,
558*00b67f09SDavid van Moolenbroek "maxudp=", 7))
559*00b67f09SDavid van Moolenbroek maxudp = atoi(isc_commandline_argument + 7);
560*00b67f09SDavid van Moolenbroek else if (!strncmp(isc_commandline_argument,
561*00b67f09SDavid van Moolenbroek "delay=", 6))
562*00b67f09SDavid van Moolenbroek ns_g_delay = atoi(isc_commandline_argument + 6);
563*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "nosyslog"))
564*00b67f09SDavid van Moolenbroek ns_g_nosyslog = ISC_TRUE;
565*00b67f09SDavid van Moolenbroek else if (!strcmp(isc_commandline_argument, "nonearest"))
566*00b67f09SDavid van Moolenbroek ns_g_nonearest = ISC_TRUE;
567*00b67f09SDavid van Moolenbroek else if (!strncmp(isc_commandline_argument, "dscp=", 5))
568*00b67f09SDavid van Moolenbroek isc_dscp_check_value =
569*00b67f09SDavid van Moolenbroek atoi(isc_commandline_argument + 5);
570*00b67f09SDavid van Moolenbroek else if (!strncmp(isc_commandline_argument,
571*00b67f09SDavid van Moolenbroek "mkeytimers=", 11))
572*00b67f09SDavid van Moolenbroek {
573*00b67f09SDavid van Moolenbroek p = strtok(isc_commandline_argument + 11, "/");
574*00b67f09SDavid van Moolenbroek if (p == NULL)
575*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("bad mkeytimer");
576*00b67f09SDavid van Moolenbroek dns_zone_mkey_hour = atoi(p);
577*00b67f09SDavid van Moolenbroek if (dns_zone_mkey_hour == 0)
578*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("bad mkeytimer");
579*00b67f09SDavid van Moolenbroek
580*00b67f09SDavid van Moolenbroek p = strtok(NULL, "/");
581*00b67f09SDavid van Moolenbroek if (p == NULL) {
582*00b67f09SDavid van Moolenbroek dns_zone_mkey_day =
583*00b67f09SDavid van Moolenbroek (24 * dns_zone_mkey_hour);
584*00b67f09SDavid van Moolenbroek dns_zone_mkey_month =
585*00b67f09SDavid van Moolenbroek (30 * dns_zone_mkey_day);
586*00b67f09SDavid van Moolenbroek break;
587*00b67f09SDavid van Moolenbroek }
588*00b67f09SDavid van Moolenbroek dns_zone_mkey_day = atoi(p);
589*00b67f09SDavid van Moolenbroek if (dns_zone_mkey_day < dns_zone_mkey_hour)
590*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("bad mkeytimer");
591*00b67f09SDavid van Moolenbroek
592*00b67f09SDavid van Moolenbroek p = strtok(NULL, "/");
593*00b67f09SDavid van Moolenbroek if (p == NULL) {
594*00b67f09SDavid van Moolenbroek dns_zone_mkey_month =
595*00b67f09SDavid van Moolenbroek (30 * dns_zone_mkey_day);
596*00b67f09SDavid van Moolenbroek break;
597*00b67f09SDavid van Moolenbroek }
598*00b67f09SDavid van Moolenbroek dns_zone_mkey_month = atoi(p);
599*00b67f09SDavid van Moolenbroek if (dns_zone_mkey_month < dns_zone_mkey_day)
600*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("bad mkeytimer");
601*00b67f09SDavid van Moolenbroek } else if (!strcmp(isc_commandline_argument, "notcp"))
602*00b67f09SDavid van Moolenbroek ns_g_notcp = ISC_TRUE;
603*00b67f09SDavid van Moolenbroek else
604*00b67f09SDavid van Moolenbroek fprintf(stderr, "unknown -T flag '%s\n",
605*00b67f09SDavid van Moolenbroek isc_commandline_argument);
606*00b67f09SDavid van Moolenbroek break;
607*00b67f09SDavid van Moolenbroek case 'U':
608*00b67f09SDavid van Moolenbroek ns_g_udpdisp = parse_int(isc_commandline_argument,
609*00b67f09SDavid van Moolenbroek "number of UDP listeners "
610*00b67f09SDavid van Moolenbroek "per interface");
611*00b67f09SDavid van Moolenbroek break;
612*00b67f09SDavid van Moolenbroek case 'u':
613*00b67f09SDavid van Moolenbroek ns_g_username = isc_commandline_argument;
614*00b67f09SDavid van Moolenbroek break;
615*00b67f09SDavid van Moolenbroek case 'v':
616*00b67f09SDavid van Moolenbroek printf("%s %s", ns_g_product, ns_g_version);
617*00b67f09SDavid van Moolenbroek if (*ns_g_description != 0)
618*00b67f09SDavid van Moolenbroek printf(" %s", ns_g_description);
619*00b67f09SDavid van Moolenbroek printf("\n");
620*00b67f09SDavid van Moolenbroek exit(0);
621*00b67f09SDavid van Moolenbroek case 'V':
622*00b67f09SDavid van Moolenbroek printf("%s %s", ns_g_product, ns_g_version);
623*00b67f09SDavid van Moolenbroek if (*ns_g_description != 0)
624*00b67f09SDavid van Moolenbroek printf(" %s", ns_g_description);
625*00b67f09SDavid van Moolenbroek printf(" <id:%s> built by %s with %s\n", ns_g_srcid,
626*00b67f09SDavid van Moolenbroek ns_g_builder, ns_g_configargs);
627*00b67f09SDavid van Moolenbroek #ifdef __clang__
628*00b67f09SDavid van Moolenbroek printf("compiled by CLANG %s\n", __VERSION__);
629*00b67f09SDavid van Moolenbroek #else
630*00b67f09SDavid van Moolenbroek #if defined(__ICC) || defined(__INTEL_COMPILER)
631*00b67f09SDavid van Moolenbroek printf("compiled by ICC %s\n", __VERSION__);
632*00b67f09SDavid van Moolenbroek #else
633*00b67f09SDavid van Moolenbroek #ifdef __GNUC__
634*00b67f09SDavid van Moolenbroek printf("compiled by GCC %s\n", __VERSION__);
635*00b67f09SDavid van Moolenbroek #endif
636*00b67f09SDavid van Moolenbroek #endif
637*00b67f09SDavid van Moolenbroek #endif
638*00b67f09SDavid van Moolenbroek #ifdef _MSC_VER
639*00b67f09SDavid van Moolenbroek printf("compiled by MSVC %d\n", _MSC_VER);
640*00b67f09SDavid van Moolenbroek #endif
641*00b67f09SDavid van Moolenbroek #ifdef __SUNPRO_C
642*00b67f09SDavid van Moolenbroek printf("compiled by Solaris Studio %x\n", __SUNPRO_C);
643*00b67f09SDavid van Moolenbroek #endif
644*00b67f09SDavid van Moolenbroek #ifdef OPENSSL
645*00b67f09SDavid van Moolenbroek printf("compiled with OpenSSL version: %s\n",
646*00b67f09SDavid van Moolenbroek OPENSSL_VERSION_TEXT);
647*00b67f09SDavid van Moolenbroek #ifndef WIN32
648*00b67f09SDavid van Moolenbroek printf("linked to OpenSSL version: %s\n",
649*00b67f09SDavid van Moolenbroek SSLeay_version(SSLEAY_VERSION));
650*00b67f09SDavid van Moolenbroek #endif
651*00b67f09SDavid van Moolenbroek #endif
652*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBXML2
653*00b67f09SDavid van Moolenbroek printf("compiled with libxml2 version: %s\n",
654*00b67f09SDavid van Moolenbroek LIBXML_DOTTED_VERSION);
655*00b67f09SDavid van Moolenbroek #ifndef WIN32
656*00b67f09SDavid van Moolenbroek printf("linked to libxml2 version: %s\n",
657*00b67f09SDavid van Moolenbroek xmlParserVersion);
658*00b67f09SDavid van Moolenbroek #endif
659*00b67f09SDavid van Moolenbroek #endif
660*00b67f09SDavid van Moolenbroek exit(0);
661*00b67f09SDavid van Moolenbroek case 'F':
662*00b67f09SDavid van Moolenbroek /* Reserved for FIPS mode */
663*00b67f09SDavid van Moolenbroek /* FALLTHROUGH */
664*00b67f09SDavid van Moolenbroek case '?':
665*00b67f09SDavid van Moolenbroek usage();
666*00b67f09SDavid van Moolenbroek if (isc_commandline_option == '?')
667*00b67f09SDavid van Moolenbroek exit(0);
668*00b67f09SDavid van Moolenbroek p = strchr(CMDLINE_FLAGS, isc_commandline_option);
669*00b67f09SDavid van Moolenbroek if (p == NULL || *++p != ':')
670*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("unknown option '-%c'",
671*00b67f09SDavid van Moolenbroek isc_commandline_option);
672*00b67f09SDavid van Moolenbroek else
673*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("option '-%c' requires "
674*00b67f09SDavid van Moolenbroek "an argument",
675*00b67f09SDavid van Moolenbroek isc_commandline_option);
676*00b67f09SDavid van Moolenbroek /* FALLTHROUGH */
677*00b67f09SDavid van Moolenbroek default:
678*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("parsing options returned %d", ch);
679*00b67f09SDavid van Moolenbroek }
680*00b67f09SDavid van Moolenbroek }
681*00b67f09SDavid van Moolenbroek
682*00b67f09SDavid van Moolenbroek argc -= isc_commandline_index;
683*00b67f09SDavid van Moolenbroek argv += isc_commandline_index;
684*00b67f09SDavid van Moolenbroek POST(argv);
685*00b67f09SDavid van Moolenbroek
686*00b67f09SDavid van Moolenbroek if (argc > 0) {
687*00b67f09SDavid van Moolenbroek usage();
688*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("extra command line arguments");
689*00b67f09SDavid van Moolenbroek }
690*00b67f09SDavid van Moolenbroek }
691*00b67f09SDavid van Moolenbroek
692*00b67f09SDavid van Moolenbroek static isc_result_t
create_managers(void)693*00b67f09SDavid van Moolenbroek create_managers(void) {
694*00b67f09SDavid van Moolenbroek isc_result_t result;
695*00b67f09SDavid van Moolenbroek unsigned int socks;
696*00b67f09SDavid van Moolenbroek
697*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
698*00b67f09SDavid van Moolenbroek if (ns_g_cpus == 0)
699*00b67f09SDavid van Moolenbroek ns_g_cpus = ns_g_cpus_detected;
700*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
701*00b67f09SDavid van Moolenbroek ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s",
702*00b67f09SDavid van Moolenbroek ns_g_cpus_detected, ns_g_cpus_detected == 1 ? "" : "s",
703*00b67f09SDavid van Moolenbroek ns_g_cpus, ns_g_cpus == 1 ? "" : "s");
704*00b67f09SDavid van Moolenbroek #else
705*00b67f09SDavid van Moolenbroek ns_g_cpus = 1;
706*00b67f09SDavid van Moolenbroek #endif
707*00b67f09SDavid van Moolenbroek #ifdef WIN32
708*00b67f09SDavid van Moolenbroek ns_g_udpdisp = 1;
709*00b67f09SDavid van Moolenbroek #else
710*00b67f09SDavid van Moolenbroek if (ns_g_udpdisp == 0) {
711*00b67f09SDavid van Moolenbroek if (ns_g_cpus_detected == 1)
712*00b67f09SDavid van Moolenbroek ns_g_udpdisp = 1;
713*00b67f09SDavid van Moolenbroek else if (ns_g_cpus_detected < 4)
714*00b67f09SDavid van Moolenbroek ns_g_udpdisp = 2;
715*00b67f09SDavid van Moolenbroek else
716*00b67f09SDavid van Moolenbroek ns_g_udpdisp = ns_g_cpus_detected / 2;
717*00b67f09SDavid van Moolenbroek }
718*00b67f09SDavid van Moolenbroek if (ns_g_udpdisp > ns_g_cpus)
719*00b67f09SDavid van Moolenbroek ns_g_udpdisp = ns_g_cpus;
720*00b67f09SDavid van Moolenbroek #endif
721*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
722*00b67f09SDavid van Moolenbroek ISC_LOG_INFO, "using %u UDP listener%s per interface",
723*00b67f09SDavid van Moolenbroek ns_g_udpdisp, ns_g_udpdisp == 1 ? "" : "s");
724*00b67f09SDavid van Moolenbroek
725*00b67f09SDavid van Moolenbroek result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr);
726*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
727*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
728*00b67f09SDavid van Moolenbroek "isc_taskmgr_create() failed: %s",
729*00b67f09SDavid van Moolenbroek isc_result_totext(result));
730*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
731*00b67f09SDavid van Moolenbroek }
732*00b67f09SDavid van Moolenbroek
733*00b67f09SDavid van Moolenbroek result = isc_timermgr_create(ns_g_mctx, &ns_g_timermgr);
734*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
735*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
736*00b67f09SDavid van Moolenbroek "isc_timermgr_create() failed: %s",
737*00b67f09SDavid van Moolenbroek isc_result_totext(result));
738*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
739*00b67f09SDavid van Moolenbroek }
740*00b67f09SDavid van Moolenbroek
741*00b67f09SDavid van Moolenbroek result = isc_socketmgr_create2(ns_g_mctx, &ns_g_socketmgr, maxsocks);
742*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
743*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
744*00b67f09SDavid van Moolenbroek "isc_socketmgr_create() failed: %s",
745*00b67f09SDavid van Moolenbroek isc_result_totext(result));
746*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
747*00b67f09SDavid van Moolenbroek }
748*00b67f09SDavid van Moolenbroek isc__socketmgr_maxudp(ns_g_socketmgr, maxudp);
749*00b67f09SDavid van Moolenbroek result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &socks);
750*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
751*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
752*00b67f09SDavid van Moolenbroek NS_LOGMODULE_SERVER,
753*00b67f09SDavid van Moolenbroek ISC_LOG_INFO, "using up to %u sockets", socks);
754*00b67f09SDavid van Moolenbroek }
755*00b67f09SDavid van Moolenbroek
756*00b67f09SDavid van Moolenbroek result = isc_entropy_create(ns_g_mctx, &ns_g_entropy);
757*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
758*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
759*00b67f09SDavid van Moolenbroek "isc_entropy_create() failed: %s",
760*00b67f09SDavid van Moolenbroek isc_result_totext(result));
761*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
762*00b67f09SDavid van Moolenbroek }
763*00b67f09SDavid van Moolenbroek
764*00b67f09SDavid van Moolenbroek result = isc_hash_create(ns_g_mctx, ns_g_entropy, DNS_NAME_MAXWIRE);
765*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
766*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
767*00b67f09SDavid van Moolenbroek "isc_hash_create() failed: %s",
768*00b67f09SDavid van Moolenbroek isc_result_totext(result));
769*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
770*00b67f09SDavid van Moolenbroek }
771*00b67f09SDavid van Moolenbroek
772*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
773*00b67f09SDavid van Moolenbroek }
774*00b67f09SDavid van Moolenbroek
775*00b67f09SDavid van Moolenbroek static void
destroy_managers(void)776*00b67f09SDavid van Moolenbroek destroy_managers(void) {
777*00b67f09SDavid van Moolenbroek ns_lwresd_shutdown();
778*00b67f09SDavid van Moolenbroek
779*00b67f09SDavid van Moolenbroek isc_entropy_detach(&ns_g_entropy);
780*00b67f09SDavid van Moolenbroek if (ns_g_fallbackentropy != NULL)
781*00b67f09SDavid van Moolenbroek isc_entropy_detach(&ns_g_fallbackentropy);
782*00b67f09SDavid van Moolenbroek
783*00b67f09SDavid van Moolenbroek /*
784*00b67f09SDavid van Moolenbroek * isc_taskmgr_destroy() will block until all tasks have exited,
785*00b67f09SDavid van Moolenbroek */
786*00b67f09SDavid van Moolenbroek isc_taskmgr_destroy(&ns_g_taskmgr);
787*00b67f09SDavid van Moolenbroek isc_timermgr_destroy(&ns_g_timermgr);
788*00b67f09SDavid van Moolenbroek isc_socketmgr_destroy(&ns_g_socketmgr);
789*00b67f09SDavid van Moolenbroek
790*00b67f09SDavid van Moolenbroek /*
791*00b67f09SDavid van Moolenbroek * isc_hash_destroy() cannot be called as long as a resolver may be
792*00b67f09SDavid van Moolenbroek * running. Calling this after isc_taskmgr_destroy() ensures the
793*00b67f09SDavid van Moolenbroek * call is safe.
794*00b67f09SDavid van Moolenbroek */
795*00b67f09SDavid van Moolenbroek isc_hash_destroy();
796*00b67f09SDavid van Moolenbroek }
797*00b67f09SDavid van Moolenbroek
798*00b67f09SDavid van Moolenbroek static void
dump_symboltable(void)799*00b67f09SDavid van Moolenbroek dump_symboltable(void) {
800*00b67f09SDavid van Moolenbroek int i;
801*00b67f09SDavid van Moolenbroek isc_result_t result;
802*00b67f09SDavid van Moolenbroek const char *fname;
803*00b67f09SDavid van Moolenbroek const void *addr;
804*00b67f09SDavid van Moolenbroek
805*00b67f09SDavid van Moolenbroek if (isc__backtrace_nsymbols == 0)
806*00b67f09SDavid van Moolenbroek return;
807*00b67f09SDavid van Moolenbroek
808*00b67f09SDavid van Moolenbroek if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(99)))
809*00b67f09SDavid van Moolenbroek return;
810*00b67f09SDavid van Moolenbroek
811*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
812*00b67f09SDavid van Moolenbroek ISC_LOG_DEBUG(99), "Symbol table:");
813*00b67f09SDavid van Moolenbroek
814*00b67f09SDavid van Moolenbroek for (i = 0, result = ISC_R_SUCCESS; result == ISC_R_SUCCESS; i++) {
815*00b67f09SDavid van Moolenbroek addr = NULL;
816*00b67f09SDavid van Moolenbroek fname = NULL;
817*00b67f09SDavid van Moolenbroek result = isc_backtrace_getsymbolfromindex(i, &addr, &fname);
818*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
819*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
820*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(99),
821*00b67f09SDavid van Moolenbroek "[%d] %p %s", i, addr, fname);
822*00b67f09SDavid van Moolenbroek }
823*00b67f09SDavid van Moolenbroek }
824*00b67f09SDavid van Moolenbroek }
825*00b67f09SDavid van Moolenbroek
826*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSECCOMP
827*00b67f09SDavid van Moolenbroek static void
setup_seccomp()828*00b67f09SDavid van Moolenbroek setup_seccomp() {
829*00b67f09SDavid van Moolenbroek scmp_filter_ctx ctx;
830*00b67f09SDavid van Moolenbroek unsigned int i;
831*00b67f09SDavid van Moolenbroek int ret;
832*00b67f09SDavid van Moolenbroek
833*00b67f09SDavid van Moolenbroek /* Make sure the lists are in sync */
834*00b67f09SDavid van Moolenbroek INSIST((sizeof(scmp_syscalls) / sizeof(int)) ==
835*00b67f09SDavid van Moolenbroek (sizeof(scmp_syscall_names) / sizeof(const char *)));
836*00b67f09SDavid van Moolenbroek
837*00b67f09SDavid van Moolenbroek ctx = seccomp_init(SCMP_ACT_KILL);
838*00b67f09SDavid van Moolenbroek if (ctx == NULL) {
839*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
840*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
841*00b67f09SDavid van Moolenbroek "libseccomp activation failed");
842*00b67f09SDavid van Moolenbroek return;
843*00b67f09SDavid van Moolenbroek }
844*00b67f09SDavid van Moolenbroek
845*00b67f09SDavid van Moolenbroek for (i = 0 ; i < sizeof(scmp_syscalls)/sizeof(*(scmp_syscalls)); i++) {
846*00b67f09SDavid van Moolenbroek ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
847*00b67f09SDavid van Moolenbroek scmp_syscalls[i], 0);
848*00b67f09SDavid van Moolenbroek if (ret < 0)
849*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
850*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
851*00b67f09SDavid van Moolenbroek "libseccomp rule failed: %s",
852*00b67f09SDavid van Moolenbroek scmp_syscall_names[i]);
853*00b67f09SDavid van Moolenbroek
854*00b67f09SDavid van Moolenbroek else
855*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
856*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(9),
857*00b67f09SDavid van Moolenbroek "added libseccomp rule: %s",
858*00b67f09SDavid van Moolenbroek scmp_syscall_names[i]);
859*00b67f09SDavid van Moolenbroek }
860*00b67f09SDavid van Moolenbroek
861*00b67f09SDavid van Moolenbroek ret = seccomp_load(ctx);
862*00b67f09SDavid van Moolenbroek if (ret < 0) {
863*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
864*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
865*00b67f09SDavid van Moolenbroek "libseccomp unable to load filter");
866*00b67f09SDavid van Moolenbroek } else {
867*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
868*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_NOTICE,
869*00b67f09SDavid van Moolenbroek "libseccomp sandboxing active");
870*00b67f09SDavid van Moolenbroek }
871*00b67f09SDavid van Moolenbroek
872*00b67f09SDavid van Moolenbroek /*
873*00b67f09SDavid van Moolenbroek * Release filter in ctx. Filters already loaded are not
874*00b67f09SDavid van Moolenbroek * affected.
875*00b67f09SDavid van Moolenbroek */
876*00b67f09SDavid van Moolenbroek seccomp_release(ctx);
877*00b67f09SDavid van Moolenbroek }
878*00b67f09SDavid van Moolenbroek #endif /* HAVE_LIBSECCOMP */
879*00b67f09SDavid van Moolenbroek
880*00b67f09SDavid van Moolenbroek static void
setup(void)881*00b67f09SDavid van Moolenbroek setup(void) {
882*00b67f09SDavid van Moolenbroek isc_result_t result;
883*00b67f09SDavid van Moolenbroek isc_resourcevalue_t old_openfiles;
884*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSCF
885*00b67f09SDavid van Moolenbroek char *instance = NULL;
886*00b67f09SDavid van Moolenbroek #endif
887*00b67f09SDavid van Moolenbroek
888*00b67f09SDavid van Moolenbroek /*
889*00b67f09SDavid van Moolenbroek * Get the user and group information before changing the root
890*00b67f09SDavid van Moolenbroek * directory, so the administrator does not need to keep a copy
891*00b67f09SDavid van Moolenbroek * of the user and group databases in the chroot'ed environment.
892*00b67f09SDavid van Moolenbroek */
893*00b67f09SDavid van Moolenbroek ns_os_inituserinfo(ns_g_username);
894*00b67f09SDavid van Moolenbroek
895*00b67f09SDavid van Moolenbroek /*
896*00b67f09SDavid van Moolenbroek * Initialize time conversion information
897*00b67f09SDavid van Moolenbroek */
898*00b67f09SDavid van Moolenbroek ns_os_tzset();
899*00b67f09SDavid van Moolenbroek
900*00b67f09SDavid van Moolenbroek ns_os_opendevnull();
901*00b67f09SDavid van Moolenbroek
902*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSCF
903*00b67f09SDavid van Moolenbroek /* Check if named is under smf control, before chroot. */
904*00b67f09SDavid van Moolenbroek result = ns_smf_get_instance(&instance, 0, ns_g_mctx);
905*00b67f09SDavid van Moolenbroek /* We don't care about instance, just check if we got one. */
906*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
907*00b67f09SDavid van Moolenbroek ns_smf_got_instance = 1;
908*00b67f09SDavid van Moolenbroek else
909*00b67f09SDavid van Moolenbroek ns_smf_got_instance = 0;
910*00b67f09SDavid van Moolenbroek if (instance != NULL)
911*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, instance);
912*00b67f09SDavid van Moolenbroek #endif /* HAVE_LIBSCF */
913*00b67f09SDavid van Moolenbroek
914*00b67f09SDavid van Moolenbroek #ifdef PATH_RANDOMDEV
915*00b67f09SDavid van Moolenbroek /*
916*00b67f09SDavid van Moolenbroek * Initialize system's random device as fallback entropy source
917*00b67f09SDavid van Moolenbroek * if running chroot'ed.
918*00b67f09SDavid van Moolenbroek */
919*00b67f09SDavid van Moolenbroek if (ns_g_chrootdir != NULL) {
920*00b67f09SDavid van Moolenbroek result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy);
921*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
922*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("isc_entropy_create() failed: %s",
923*00b67f09SDavid van Moolenbroek isc_result_totext(result));
924*00b67f09SDavid van Moolenbroek
925*00b67f09SDavid van Moolenbroek result = isc_entropy_createfilesource(ns_g_fallbackentropy,
926*00b67f09SDavid van Moolenbroek PATH_RANDOMDEV);
927*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
928*00b67f09SDavid van Moolenbroek ns_main_earlywarning("could not open pre-chroot "
929*00b67f09SDavid van Moolenbroek "entropy source %s: %s",
930*00b67f09SDavid van Moolenbroek PATH_RANDOMDEV,
931*00b67f09SDavid van Moolenbroek isc_result_totext(result));
932*00b67f09SDavid van Moolenbroek isc_entropy_detach(&ns_g_fallbackentropy);
933*00b67f09SDavid van Moolenbroek }
934*00b67f09SDavid van Moolenbroek }
935*00b67f09SDavid van Moolenbroek #endif
936*00b67f09SDavid van Moolenbroek
937*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
938*00b67f09SDavid van Moolenbroek /*
939*00b67f09SDavid van Moolenbroek * Check for the number of cpu's before ns_os_chroot().
940*00b67f09SDavid van Moolenbroek */
941*00b67f09SDavid van Moolenbroek ns_g_cpus_detected = isc_os_ncpus();
942*00b67f09SDavid van Moolenbroek #endif
943*00b67f09SDavid van Moolenbroek
944*00b67f09SDavid van Moolenbroek ns_os_chroot(ns_g_chrootdir);
945*00b67f09SDavid van Moolenbroek
946*00b67f09SDavid van Moolenbroek /*
947*00b67f09SDavid van Moolenbroek * For operating systems which have a capability mechanism, now
948*00b67f09SDavid van Moolenbroek * is the time to switch to minimal privs and change our user id.
949*00b67f09SDavid van Moolenbroek * On traditional UNIX systems, this call will be a no-op, and we
950*00b67f09SDavid van Moolenbroek * will change the user ID after reading the config file the first
951*00b67f09SDavid van Moolenbroek * time. (We need to read the config file to know which possibly
952*00b67f09SDavid van Moolenbroek * privileged ports to bind() to.)
953*00b67f09SDavid van Moolenbroek */
954*00b67f09SDavid van Moolenbroek ns_os_minprivs();
955*00b67f09SDavid van Moolenbroek
956*00b67f09SDavid van Moolenbroek result = ns_log_init(ISC_TF(ns_g_username != NULL));
957*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
958*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("ns_log_init() failed: %s",
959*00b67f09SDavid van Moolenbroek isc_result_totext(result));
960*00b67f09SDavid van Moolenbroek
961*00b67f09SDavid van Moolenbroek /*
962*00b67f09SDavid van Moolenbroek * Now is the time to daemonize (if we're not running in the
963*00b67f09SDavid van Moolenbroek * foreground). We waited until now because we wanted to get
964*00b67f09SDavid van Moolenbroek * a valid logging context setup. We cannot daemonize any later,
965*00b67f09SDavid van Moolenbroek * because calling create_managers() will create threads, which
966*00b67f09SDavid van Moolenbroek * would be lost after fork().
967*00b67f09SDavid van Moolenbroek */
968*00b67f09SDavid van Moolenbroek if (!ns_g_foreground)
969*00b67f09SDavid van Moolenbroek ns_os_daemonize();
970*00b67f09SDavid van Moolenbroek
971*00b67f09SDavid van Moolenbroek /*
972*00b67f09SDavid van Moolenbroek * We call isc_app_start() here as some versions of FreeBSD's fork()
973*00b67f09SDavid van Moolenbroek * destroys all the signal handling it sets up.
974*00b67f09SDavid van Moolenbroek */
975*00b67f09SDavid van Moolenbroek result = isc_app_start();
976*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
977*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("isc_app_start() failed: %s",
978*00b67f09SDavid van Moolenbroek isc_result_totext(result));
979*00b67f09SDavid van Moolenbroek
980*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
981*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE, "starting %s %s%s", ns_g_product,
982*00b67f09SDavid van Moolenbroek ns_g_version, saved_command_line);
983*00b67f09SDavid van Moolenbroek
984*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
985*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE, "built with %s", ns_g_configargs);
986*00b67f09SDavid van Moolenbroek
987*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
988*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE,
989*00b67f09SDavid van Moolenbroek "----------------------------------------------------");
990*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
991*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE,
992*00b67f09SDavid van Moolenbroek "BIND 9 is maintained by Internet Systems Consortium,");
993*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
994*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE,
995*00b67f09SDavid van Moolenbroek "Inc. (ISC), a non-profit 501(c)(3) public-benefit ");
996*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
997*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE,
998*00b67f09SDavid van Moolenbroek "corporation. Support and training for BIND 9 are ");
999*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
1000*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE,
1001*00b67f09SDavid van Moolenbroek "available at https://www.isc.org/support");
1002*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
1003*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE,
1004*00b67f09SDavid van Moolenbroek "----------------------------------------------------");
1005*00b67f09SDavid van Moolenbroek
1006*00b67f09SDavid van Moolenbroek dump_symboltable();
1007*00b67f09SDavid van Moolenbroek
1008*00b67f09SDavid van Moolenbroek /*
1009*00b67f09SDavid van Moolenbroek * Get the initial resource limits.
1010*00b67f09SDavid van Moolenbroek */
1011*00b67f09SDavid van Moolenbroek (void)isc_resource_getlimit(isc_resource_stacksize,
1012*00b67f09SDavid van Moolenbroek &ns_g_initstacksize);
1013*00b67f09SDavid van Moolenbroek (void)isc_resource_getlimit(isc_resource_datasize,
1014*00b67f09SDavid van Moolenbroek &ns_g_initdatasize);
1015*00b67f09SDavid van Moolenbroek (void)isc_resource_getlimit(isc_resource_coresize,
1016*00b67f09SDavid van Moolenbroek &ns_g_initcoresize);
1017*00b67f09SDavid van Moolenbroek (void)isc_resource_getlimit(isc_resource_openfiles,
1018*00b67f09SDavid van Moolenbroek &ns_g_initopenfiles);
1019*00b67f09SDavid van Moolenbroek
1020*00b67f09SDavid van Moolenbroek /*
1021*00b67f09SDavid van Moolenbroek * System resources cannot effectively be tuned on some systems.
1022*00b67f09SDavid van Moolenbroek * Raise the limit in such cases for safety.
1023*00b67f09SDavid van Moolenbroek */
1024*00b67f09SDavid van Moolenbroek old_openfiles = ns_g_initopenfiles;
1025*00b67f09SDavid van Moolenbroek ns_os_adjustnofile();
1026*00b67f09SDavid van Moolenbroek (void)isc_resource_getlimit(isc_resource_openfiles,
1027*00b67f09SDavid van Moolenbroek &ns_g_initopenfiles);
1028*00b67f09SDavid van Moolenbroek if (old_openfiles != ns_g_initopenfiles) {
1029*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
1030*00b67f09SDavid van Moolenbroek NS_LOGMODULE_MAIN, ISC_LOG_NOTICE,
1031*00b67f09SDavid van Moolenbroek "adjusted limit on open files from "
1032*00b67f09SDavid van Moolenbroek "%" ISC_PRINT_QUADFORMAT "u to "
1033*00b67f09SDavid van Moolenbroek "%" ISC_PRINT_QUADFORMAT "u",
1034*00b67f09SDavid van Moolenbroek old_openfiles, ns_g_initopenfiles);
1035*00b67f09SDavid van Moolenbroek }
1036*00b67f09SDavid van Moolenbroek
1037*00b67f09SDavid van Moolenbroek /*
1038*00b67f09SDavid van Moolenbroek * If the named configuration filename is relative, prepend the current
1039*00b67f09SDavid van Moolenbroek * directory's name before possibly changing to another directory.
1040*00b67f09SDavid van Moolenbroek */
1041*00b67f09SDavid van Moolenbroek if (! isc_file_isabsolute(ns_g_conffile)) {
1042*00b67f09SDavid van Moolenbroek result = isc_file_absolutepath(ns_g_conffile,
1043*00b67f09SDavid van Moolenbroek absolute_conffile,
1044*00b67f09SDavid van Moolenbroek sizeof(absolute_conffile));
1045*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1046*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("could not construct absolute path "
1047*00b67f09SDavid van Moolenbroek "of configuration file: %s",
1048*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1049*00b67f09SDavid van Moolenbroek ns_g_conffile = absolute_conffile;
1050*00b67f09SDavid van Moolenbroek }
1051*00b67f09SDavid van Moolenbroek
1052*00b67f09SDavid van Moolenbroek /*
1053*00b67f09SDavid van Moolenbroek * Record the server's startup time.
1054*00b67f09SDavid van Moolenbroek */
1055*00b67f09SDavid van Moolenbroek result = isc_time_now(&ns_g_boottime);
1056*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1057*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("isc_time_now() failed: %s",
1058*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1059*00b67f09SDavid van Moolenbroek
1060*00b67f09SDavid van Moolenbroek result = create_managers();
1061*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1062*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("create_managers() failed: %s",
1063*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1064*00b67f09SDavid van Moolenbroek
1065*00b67f09SDavid van Moolenbroek ns_builtin_init();
1066*00b67f09SDavid van Moolenbroek
1067*00b67f09SDavid van Moolenbroek /*
1068*00b67f09SDavid van Moolenbroek * Add calls to register sdb drivers here.
1069*00b67f09SDavid van Moolenbroek */
1070*00b67f09SDavid van Moolenbroek /* xxdb_init(); */
1071*00b67f09SDavid van Moolenbroek
1072*00b67f09SDavid van Moolenbroek #ifdef ISC_DLZ_DLOPEN
1073*00b67f09SDavid van Moolenbroek /*
1074*00b67f09SDavid van Moolenbroek * Register the DLZ "dlopen" driver.
1075*00b67f09SDavid van Moolenbroek */
1076*00b67f09SDavid van Moolenbroek result = dlz_dlopen_init(ns_g_mctx);
1077*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1078*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("dlz_dlopen_init() failed: %s",
1079*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1080*00b67f09SDavid van Moolenbroek #endif
1081*00b67f09SDavid van Moolenbroek
1082*00b67f09SDavid van Moolenbroek #if CONTRIB_DLZ
1083*00b67f09SDavid van Moolenbroek /*
1084*00b67f09SDavid van Moolenbroek * Register any other contributed DLZ drivers.
1085*00b67f09SDavid van Moolenbroek */
1086*00b67f09SDavid van Moolenbroek result = dlz_drivers_init();
1087*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1088*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("dlz_drivers_init() failed: %s",
1089*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1090*00b67f09SDavid van Moolenbroek #endif
1091*00b67f09SDavid van Moolenbroek
1092*00b67f09SDavid van Moolenbroek ns_server_create(ns_g_mctx, &ns_g_server);
1093*00b67f09SDavid van Moolenbroek
1094*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSECCOMP
1095*00b67f09SDavid van Moolenbroek setup_seccomp();
1096*00b67f09SDavid van Moolenbroek #endif /* HAVE_LIBSECCOMP */
1097*00b67f09SDavid van Moolenbroek }
1098*00b67f09SDavid van Moolenbroek
1099*00b67f09SDavid van Moolenbroek static void
cleanup(void)1100*00b67f09SDavid van Moolenbroek cleanup(void) {
1101*00b67f09SDavid van Moolenbroek destroy_managers();
1102*00b67f09SDavid van Moolenbroek
1103*00b67f09SDavid van Moolenbroek ns_server_destroy(&ns_g_server);
1104*00b67f09SDavid van Moolenbroek
1105*00b67f09SDavid van Moolenbroek ns_builtin_deinit();
1106*00b67f09SDavid van Moolenbroek
1107*00b67f09SDavid van Moolenbroek /*
1108*00b67f09SDavid van Moolenbroek * Add calls to unregister sdb drivers here.
1109*00b67f09SDavid van Moolenbroek */
1110*00b67f09SDavid van Moolenbroek /* xxdb_clear(); */
1111*00b67f09SDavid van Moolenbroek
1112*00b67f09SDavid van Moolenbroek #ifdef CONTRIB_DLZ
1113*00b67f09SDavid van Moolenbroek /*
1114*00b67f09SDavid van Moolenbroek * Unregister contributed DLZ drivers.
1115*00b67f09SDavid van Moolenbroek */
1116*00b67f09SDavid van Moolenbroek dlz_drivers_clear();
1117*00b67f09SDavid van Moolenbroek #endif
1118*00b67f09SDavid van Moolenbroek #ifdef ISC_DLZ_DLOPEN
1119*00b67f09SDavid van Moolenbroek /*
1120*00b67f09SDavid van Moolenbroek * Unregister "dlopen" DLZ driver.
1121*00b67f09SDavid van Moolenbroek */
1122*00b67f09SDavid van Moolenbroek dlz_dlopen_clear();
1123*00b67f09SDavid van Moolenbroek #endif
1124*00b67f09SDavid van Moolenbroek
1125*00b67f09SDavid van Moolenbroek dns_name_destroy();
1126*00b67f09SDavid van Moolenbroek
1127*00b67f09SDavid van Moolenbroek isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
1128*00b67f09SDavid van Moolenbroek ISC_LOG_NOTICE, "exiting");
1129*00b67f09SDavid van Moolenbroek ns_log_shutdown();
1130*00b67f09SDavid van Moolenbroek }
1131*00b67f09SDavid van Moolenbroek
1132*00b67f09SDavid van Moolenbroek static char *memstats = NULL;
1133*00b67f09SDavid van Moolenbroek
1134*00b67f09SDavid van Moolenbroek void
ns_main_setmemstats(const char * filename)1135*00b67f09SDavid van Moolenbroek ns_main_setmemstats(const char *filename) {
1136*00b67f09SDavid van Moolenbroek /*
1137*00b67f09SDavid van Moolenbroek * Caller has to ensure locking.
1138*00b67f09SDavid van Moolenbroek */
1139*00b67f09SDavid van Moolenbroek
1140*00b67f09SDavid van Moolenbroek if (memstats != NULL) {
1141*00b67f09SDavid van Moolenbroek free(memstats);
1142*00b67f09SDavid van Moolenbroek memstats = NULL;
1143*00b67f09SDavid van Moolenbroek }
1144*00b67f09SDavid van Moolenbroek if (filename == NULL)
1145*00b67f09SDavid van Moolenbroek return;
1146*00b67f09SDavid van Moolenbroek memstats = malloc(strlen(filename) + 1);
1147*00b67f09SDavid van Moolenbroek if (memstats)
1148*00b67f09SDavid van Moolenbroek strcpy(memstats, filename);
1149*00b67f09SDavid van Moolenbroek }
1150*00b67f09SDavid van Moolenbroek
1151*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSCF
1152*00b67f09SDavid van Moolenbroek /*
1153*00b67f09SDavid van Moolenbroek * Get FMRI for the named process.
1154*00b67f09SDavid van Moolenbroek */
1155*00b67f09SDavid van Moolenbroek isc_result_t
ns_smf_get_instance(char ** ins_name,int debug,isc_mem_t * mctx)1156*00b67f09SDavid van Moolenbroek ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) {
1157*00b67f09SDavid van Moolenbroek scf_handle_t *h = NULL;
1158*00b67f09SDavid van Moolenbroek int namelen;
1159*00b67f09SDavid van Moolenbroek char *instance;
1160*00b67f09SDavid van Moolenbroek
1161*00b67f09SDavid van Moolenbroek REQUIRE(ins_name != NULL && *ins_name == NULL);
1162*00b67f09SDavid van Moolenbroek
1163*00b67f09SDavid van Moolenbroek if ((h = scf_handle_create(SCF_VERSION)) == NULL) {
1164*00b67f09SDavid van Moolenbroek if (debug)
1165*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1166*00b67f09SDavid van Moolenbroek "scf_handle_create() failed: %s",
1167*00b67f09SDavid van Moolenbroek scf_strerror(scf_error()));
1168*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1169*00b67f09SDavid van Moolenbroek }
1170*00b67f09SDavid van Moolenbroek
1171*00b67f09SDavid van Moolenbroek if (scf_handle_bind(h) == -1) {
1172*00b67f09SDavid van Moolenbroek if (debug)
1173*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1174*00b67f09SDavid van Moolenbroek "scf_handle_bind() failed: %s",
1175*00b67f09SDavid van Moolenbroek scf_strerror(scf_error()));
1176*00b67f09SDavid van Moolenbroek scf_handle_destroy(h);
1177*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1178*00b67f09SDavid van Moolenbroek }
1179*00b67f09SDavid van Moolenbroek
1180*00b67f09SDavid van Moolenbroek if ((namelen = scf_myname(h, NULL, 0)) == -1) {
1181*00b67f09SDavid van Moolenbroek if (debug)
1182*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1183*00b67f09SDavid van Moolenbroek "scf_myname() failed: %s",
1184*00b67f09SDavid van Moolenbroek scf_strerror(scf_error()));
1185*00b67f09SDavid van Moolenbroek scf_handle_destroy(h);
1186*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1187*00b67f09SDavid van Moolenbroek }
1188*00b67f09SDavid van Moolenbroek
1189*00b67f09SDavid van Moolenbroek if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) {
1190*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1191*00b67f09SDavid van Moolenbroek "ns_smf_get_instance memory "
1192*00b67f09SDavid van Moolenbroek "allocation failed: %s",
1193*00b67f09SDavid van Moolenbroek isc_result_totext(ISC_R_NOMEMORY));
1194*00b67f09SDavid van Moolenbroek scf_handle_destroy(h);
1195*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1196*00b67f09SDavid van Moolenbroek }
1197*00b67f09SDavid van Moolenbroek
1198*00b67f09SDavid van Moolenbroek if (scf_myname(h, instance, namelen + 1) == -1) {
1199*00b67f09SDavid van Moolenbroek if (debug)
1200*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1201*00b67f09SDavid van Moolenbroek "scf_myname() failed: %s",
1202*00b67f09SDavid van Moolenbroek scf_strerror(scf_error()));
1203*00b67f09SDavid van Moolenbroek scf_handle_destroy(h);
1204*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, instance);
1205*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1206*00b67f09SDavid van Moolenbroek }
1207*00b67f09SDavid van Moolenbroek
1208*00b67f09SDavid van Moolenbroek scf_handle_destroy(h);
1209*00b67f09SDavid van Moolenbroek *ins_name = instance;
1210*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1211*00b67f09SDavid van Moolenbroek }
1212*00b67f09SDavid van Moolenbroek #endif /* HAVE_LIBSCF */
1213*00b67f09SDavid van Moolenbroek
1214*00b67f09SDavid van Moolenbroek /* main entry point, possibly hooked */
1215*00b67f09SDavid van Moolenbroek
1216*00b67f09SDavid van Moolenbroek int
main(int argc,char * argv[])1217*00b67f09SDavid van Moolenbroek main(int argc, char *argv[]) {
1218*00b67f09SDavid van Moolenbroek isc_result_t result;
1219*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSCF
1220*00b67f09SDavid van Moolenbroek char *instance = NULL;
1221*00b67f09SDavid van Moolenbroek #endif
1222*00b67f09SDavid van Moolenbroek
1223*00b67f09SDavid van Moolenbroek #ifdef HAVE_GPERFTOOLS_PROFILER
1224*00b67f09SDavid van Moolenbroek (void) ProfilerStart(NULL);
1225*00b67f09SDavid van Moolenbroek #endif
1226*00b67f09SDavid van Moolenbroek
1227*00b67f09SDavid van Moolenbroek /*
1228*00b67f09SDavid van Moolenbroek * Record version in core image.
1229*00b67f09SDavid van Moolenbroek * strings named.core | grep "named version:"
1230*00b67f09SDavid van Moolenbroek */
1231*00b67f09SDavid van Moolenbroek strlcat(version,
1232*00b67f09SDavid van Moolenbroek #if defined(NO_VERSION_DATE) || !defined(__DATE__)
1233*00b67f09SDavid van Moolenbroek "named version: BIND " VERSION " <" SRCID ">",
1234*00b67f09SDavid van Moolenbroek #else
1235*00b67f09SDavid van Moolenbroek "named version: BIND " VERSION " <" SRCID "> (" __DATE__ ")",
1236*00b67f09SDavid van Moolenbroek #endif
1237*00b67f09SDavid van Moolenbroek sizeof(version));
1238*00b67f09SDavid van Moolenbroek result = isc_file_progname(*argv, program_name, sizeof(program_name));
1239*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1240*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("program name too long");
1241*00b67f09SDavid van Moolenbroek
1242*00b67f09SDavid van Moolenbroek if (strcmp(program_name, "lwresd") == 0)
1243*00b67f09SDavid van Moolenbroek ns_g_lwresdonly = ISC_TRUE;
1244*00b67f09SDavid van Moolenbroek
1245*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1246*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("failed to build internal symbol table");
1247*00b67f09SDavid van Moolenbroek
1248*00b67f09SDavid van Moolenbroek isc_assertion_setcallback(assertion_failed);
1249*00b67f09SDavid van Moolenbroek isc_error_setfatal(library_fatal_error);
1250*00b67f09SDavid van Moolenbroek isc_error_setunexpected(library_unexpected_error);
1251*00b67f09SDavid van Moolenbroek
1252*00b67f09SDavid van Moolenbroek ns_os_init(program_name);
1253*00b67f09SDavid van Moolenbroek
1254*00b67f09SDavid van Moolenbroek dns_result_register();
1255*00b67f09SDavid van Moolenbroek dst_result_register();
1256*00b67f09SDavid van Moolenbroek isccc_result_register();
1257*00b67f09SDavid van Moolenbroek #ifdef PKCS11CRYPTO
1258*00b67f09SDavid van Moolenbroek pk11_result_register();
1259*00b67f09SDavid van Moolenbroek #endif
1260*00b67f09SDavid van Moolenbroek
1261*00b67f09SDavid van Moolenbroek parse_command_line(argc, argv);
1262*00b67f09SDavid van Moolenbroek
1263*00b67f09SDavid van Moolenbroek pfilter_open();
1264*00b67f09SDavid van Moolenbroek
1265*00b67f09SDavid van Moolenbroek /*
1266*00b67f09SDavid van Moolenbroek * Warn about common configuration error.
1267*00b67f09SDavid van Moolenbroek */
1268*00b67f09SDavid van Moolenbroek if (ns_g_chrootdir != NULL) {
1269*00b67f09SDavid van Moolenbroek int len = strlen(ns_g_chrootdir);
1270*00b67f09SDavid van Moolenbroek if (strncmp(ns_g_chrootdir, ns_g_conffile, len) == 0 &&
1271*00b67f09SDavid van Moolenbroek (ns_g_conffile[len] == '/' || ns_g_conffile[len] == '\\'))
1272*00b67f09SDavid van Moolenbroek ns_main_earlywarning("config filename (-c %s) contains "
1273*00b67f09SDavid van Moolenbroek "chroot path (-t %s)",
1274*00b67f09SDavid van Moolenbroek ns_g_conffile, ns_g_chrootdir);
1275*00b67f09SDavid van Moolenbroek }
1276*00b67f09SDavid van Moolenbroek
1277*00b67f09SDavid van Moolenbroek result = isc_mem_create(0, 0, &ns_g_mctx);
1278*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1279*00b67f09SDavid van Moolenbroek ns_main_earlyfatal("isc_mem_create() failed: %s",
1280*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1281*00b67f09SDavid van Moolenbroek isc_mem_setname(ns_g_mctx, "main", NULL);
1282*00b67f09SDavid van Moolenbroek
1283*00b67f09SDavid van Moolenbroek setup();
1284*00b67f09SDavid van Moolenbroek
1285*00b67f09SDavid van Moolenbroek /*
1286*00b67f09SDavid van Moolenbroek * Start things running and then wait for a shutdown request
1287*00b67f09SDavid van Moolenbroek * or reload.
1288*00b67f09SDavid van Moolenbroek */
1289*00b67f09SDavid van Moolenbroek do {
1290*00b67f09SDavid van Moolenbroek result = isc_app_run();
1291*00b67f09SDavid van Moolenbroek
1292*00b67f09SDavid van Moolenbroek if (result == ISC_R_RELOAD) {
1293*00b67f09SDavid van Moolenbroek ns_server_reloadwanted(ns_g_server);
1294*00b67f09SDavid van Moolenbroek } else if (result != ISC_R_SUCCESS) {
1295*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1296*00b67f09SDavid van Moolenbroek "isc_app_run(): %s",
1297*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1298*00b67f09SDavid van Moolenbroek /*
1299*00b67f09SDavid van Moolenbroek * Force exit.
1300*00b67f09SDavid van Moolenbroek */
1301*00b67f09SDavid van Moolenbroek result = ISC_R_SUCCESS;
1302*00b67f09SDavid van Moolenbroek }
1303*00b67f09SDavid van Moolenbroek } while (result != ISC_R_SUCCESS);
1304*00b67f09SDavid van Moolenbroek
1305*00b67f09SDavid van Moolenbroek #ifdef HAVE_LIBSCF
1306*00b67f09SDavid van Moolenbroek if (ns_smf_want_disable == 1) {
1307*00b67f09SDavid van Moolenbroek result = ns_smf_get_instance(&instance, 1, ns_g_mctx);
1308*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS && instance != NULL) {
1309*00b67f09SDavid van Moolenbroek if (smf_disable_instance(instance, 0) != 0)
1310*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
1311*00b67f09SDavid van Moolenbroek "smf_disable_instance() "
1312*00b67f09SDavid van Moolenbroek "failed for %s : %s",
1313*00b67f09SDavid van Moolenbroek instance,
1314*00b67f09SDavid van Moolenbroek scf_strerror(scf_error()));
1315*00b67f09SDavid van Moolenbroek }
1316*00b67f09SDavid van Moolenbroek if (instance != NULL)
1317*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, instance);
1318*00b67f09SDavid van Moolenbroek }
1319*00b67f09SDavid van Moolenbroek #endif /* HAVE_LIBSCF */
1320*00b67f09SDavid van Moolenbroek
1321*00b67f09SDavid van Moolenbroek cleanup();
1322*00b67f09SDavid van Moolenbroek
1323*00b67f09SDavid van Moolenbroek if (want_stats) {
1324*00b67f09SDavid van Moolenbroek isc_mem_stats(ns_g_mctx, stdout);
1325*00b67f09SDavid van Moolenbroek isc_mutex_stats(stdout);
1326*00b67f09SDavid van Moolenbroek }
1327*00b67f09SDavid van Moolenbroek
1328*00b67f09SDavid van Moolenbroek if (ns_g_memstatistics && memstats != NULL) {
1329*00b67f09SDavid van Moolenbroek FILE *fp = NULL;
1330*00b67f09SDavid van Moolenbroek result = isc_stdio_open(memstats, "w", &fp);
1331*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
1332*00b67f09SDavid van Moolenbroek isc_mem_stats(ns_g_mctx, fp);
1333*00b67f09SDavid van Moolenbroek isc_mutex_stats(fp);
1334*00b67f09SDavid van Moolenbroek isc_stdio_close(fp);
1335*00b67f09SDavid van Moolenbroek }
1336*00b67f09SDavid van Moolenbroek }
1337*00b67f09SDavid van Moolenbroek isc_mem_destroy(&ns_g_mctx);
1338*00b67f09SDavid van Moolenbroek isc_mem_checkdestroyed(stderr);
1339*00b67f09SDavid van Moolenbroek
1340*00b67f09SDavid van Moolenbroek ns_main_setmemstats(NULL);
1341*00b67f09SDavid van Moolenbroek
1342*00b67f09SDavid van Moolenbroek isc_app_finish();
1343*00b67f09SDavid van Moolenbroek
1344*00b67f09SDavid van Moolenbroek ns_os_closedevnull();
1345*00b67f09SDavid van Moolenbroek
1346*00b67f09SDavid van Moolenbroek ns_os_shutdown();
1347*00b67f09SDavid van Moolenbroek
1348*00b67f09SDavid van Moolenbroek #ifdef HAVE_GPERFTOOLS_PROFILER
1349*00b67f09SDavid van Moolenbroek ProfilerStop();
1350*00b67f09SDavid van Moolenbroek #endif
1351*00b67f09SDavid van Moolenbroek
1352*00b67f09SDavid van Moolenbroek return (0);
1353*00b67f09SDavid van Moolenbroek }
1354