Mercurial > hg > freeDiameter
comparison freeDiameterd/main.c @ 658:f198d16fa7f4
Initial commit for 1.1.0:
* Restructuring:
* libfreeDiameter:
- renamed folder & binary into libfdproto
- renamed libfD.h into fdproto-internal.h
- removed signals management (replaced by triggers in libfdcore)
* freeDiameter split into:
- libfdcore (most contents)
- renamed fD.h into fdcore-internal.h
- added core.c for framework init/shutdown.
- new triggers mechanism in events.c.
- freeDiameterd (main, command line parsing, signals management)
* tests:
- now in top-level directory tests.
* other changes:
- fd_dict_new now returns 0 on duplicate identical entries.
- fixes in dict_legacy_xml
- fixes in some dictionaries
- moved FD_DEFAULT_CONF_FILENAME definition to freeDiameter-host.h
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Fri, 14 Jan 2011 15:15:23 +0900 |
parents | freeDiameter/main.c@e1c6f45f5fcd |
children | 2e94ef0515d7 |
comparison
equal
deleted
inserted
replaced
656:5b05d85682f1 | 658:f198d16fa7f4 |
---|---|
1 /********************************************************************************************************* | |
2 * Software License Agreement (BSD License) * | |
3 * Author: Sebastien Decugis <sdecugis@nict.go.jp> * | |
4 * * | |
5 * Copyright (c) 2010, WIDE Project and NICT * | |
6 * All rights reserved. * | |
7 * * | |
8 * Redistribution and use of this software in source and binary forms, with or without modification, are * | |
9 * permitted provided that the following conditions are met: * | |
10 * * | |
11 * * Redistributions of source code must retain the above * | |
12 * copyright notice, this list of conditions and the * | |
13 * following disclaimer. * | |
14 * * | |
15 * * Redistributions in binary form must reproduce the above * | |
16 * copyright notice, this list of conditions and the * | |
17 * following disclaimer in the documentation and/or other * | |
18 * materials provided with the distribution. * | |
19 * * | |
20 * * Neither the name of the WIDE Project or NICT nor the * | |
21 * names of its contributors may be used to endorse or * | |
22 * promote products derived from this software without * | |
23 * specific prior written permission of WIDE Project and * | |
24 * NICT. * | |
25 * * | |
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * | |
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * | |
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * | |
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * | |
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * | |
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * | |
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * | |
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * | |
34 *********************************************************************************************************/ | |
35 | |
36 #include <freeDiameter/freeDiameter-host.h> | |
37 #include <freeDiameter/libfdcore.h> | |
38 | |
39 #include <signal.h> | |
40 #include <getopt.h> | |
41 #include <locale.h> | |
42 | |
43 | |
44 /* forward declarations */ | |
45 static int main_cmdline(int argc, char *argv[]); | |
46 static void * catch_signals(void * arg); | |
47 static pthread_t signals_thr; | |
48 | |
49 static char *conffile = NULL; | |
50 static int gnutls_debug = 0; | |
51 | |
52 /* gnutls debug */ | |
53 static void fd_gnutls_debug(int level, const char * str) { | |
54 fd_log_debug(" [gnutls:%d] %s", level, str); | |
55 } | |
56 | |
57 | |
58 /* freeDiameter starting point */ | |
59 int main(int argc, char * argv[]) | |
60 { | |
61 int ret; | |
62 sigset_t sig_all; | |
63 | |
64 /* Block all signals from the current thread and all its future children */ | |
65 sigfillset(&sig_all); | |
66 ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL); | |
67 ASSERT(ret == 0); | |
68 | |
69 /* Parse the command-line */ | |
70 ret = main_cmdline(argc, argv); | |
71 if (ret != 0) { | |
72 return ret; | |
73 } | |
74 | |
75 /* Initialize the core library */ | |
76 ret = fd_core_initialize(); | |
77 if (ret != 0) { | |
78 fprintf(stderr, "An error occurred during freeDiameter core library initialization.\n"); | |
79 return ret; | |
80 } | |
81 | |
82 /* Set gnutls debug level ? */ | |
83 if (gnutls_debug) { | |
84 gnutls_global_set_log_function((gnutls_log_func)fd_gnutls_debug); | |
85 gnutls_global_set_log_level (gnutls_debug); | |
86 TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug); | |
87 } | |
88 | |
89 /* Allow SIGINT and SIGTERM from this point to terminate the application */ | |
90 CHECK_POSIX( pthread_create(&signals_thr, NULL, catch_signals, NULL) ); | |
91 | |
92 /* Parse the configuration file */ | |
93 CHECK_FCT( fd_core_parseconf(conffile) ); | |
94 | |
95 /* Start the servers */ | |
96 CHECK_FCT( fd_core_start() ); | |
97 | |
98 TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized."); | |
99 | |
100 /* Now, just wait for termination */ | |
101 CHECK_FCT( fd_core_wait_shutdown_complete() ); | |
102 | |
103 /* Just in case it was not the result of a signal, we cancel signals_thr */ | |
104 fd_thr_term(&signals_thr); | |
105 | |
106 return 0; | |
107 } | |
108 | |
109 | |
110 /* Display package version */ | |
111 static void main_version_core(void) | |
112 { | |
113 printf("%s, version %d.%d.%d" | |
114 #ifdef HG_VERSION | |
115 " (r%s" | |
116 # ifdef PACKAGE_HG_REVISION | |
117 "/%s" | |
118 # endif /* PACKAGE_HG_VERSION */ | |
119 ")" | |
120 #endif /* HG_VERSION */ | |
121 " (libfdcore: %s)\n", | |
122 FD_PROJECT_NAME, FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, FD_PROJECT_VERSION_REV | |
123 #ifdef HG_VERSION | |
124 , HG_VERSION | |
125 # ifdef PACKAGE_HG_REVISION | |
126 , PACKAGE_HG_REVISION | |
127 # endif /* PACKAGE_HG_VERSION */ | |
128 #endif /* HG_VERSION */ | |
129 , fd_core_version()); | |
130 } | |
131 | |
132 /* Display package version and general info */ | |
133 static void main_version(void) | |
134 { | |
135 main_version_core(); | |
136 printf( "%s\n", FD_PROJECT_COPYRIGHT); | |
137 printf( "\nSee " FD_PROJECT_NAME " homepage at http://www.freediameter.net/\n" | |
138 " for information, updates and bug reports on this software.\n"); | |
139 } | |
140 | |
141 /* Print command-line options */ | |
142 static void main_help( void ) | |
143 { | |
144 main_version_core(); | |
145 printf( " This daemon is an implementation of the Diameter protocol\n" | |
146 " used for Authentication, Authorization, and Accounting (AAA).\n"); | |
147 printf("\nUsage: " FD_PROJECT_BINARY " [OPTIONS]...\n"); | |
148 printf( " -h, --help Print help and exit\n" | |
149 " -V, --version Print version and exit\n" | |
150 " -c, --config=filename Read configuration from this file instead of the \n" | |
151 " default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n"); | |
152 printf( "\nDebug:\n" | |
153 " These options are mostly useful for developers\n" | |
154 " -l, --dbglocale Set the locale for error messages\n" | |
155 " -d, --debug Increase verbosity of debug messages\n" | |
156 " -q, --quiet Decrease verbosity then remove debug messages\n" | |
157 " --dbg_gnutls <int> Enable GNU TLS debug at level <int>\n"); | |
158 } | |
159 | |
160 /* Parse the command-line */ | |
161 static int main_cmdline(int argc, char *argv[]) | |
162 { | |
163 int c; | |
164 int option_index = 0; | |
165 char * locale; | |
166 | |
167 struct option long_options[] = { | |
168 { "help", no_argument, NULL, 'h' }, | |
169 { "version", no_argument, NULL, 'V' }, | |
170 { "config", required_argument, NULL, 'c' }, | |
171 { "debug", no_argument, NULL, 'd' }, | |
172 { "quiet", no_argument, NULL, 'q' }, | |
173 { "dbglocale", optional_argument, NULL, 'l' }, | |
174 { "dbg_func", required_argument, NULL, 'f' }, | |
175 { "dbg_file", required_argument, NULL, 'F' }, | |
176 { "dbg_gnutls", required_argument, NULL, 'g' }, | |
177 { NULL, 0, NULL, 0 } | |
178 }; | |
179 | |
180 /* Loop on arguments */ | |
181 while (1) { | |
182 c = getopt_long (argc, argv, "hVc:dql:", long_options, &option_index); | |
183 if (c == -1) | |
184 break; /* Exit from the loop. */ | |
185 | |
186 switch (c) { | |
187 case 'h': /* Print help and exit. */ | |
188 main_help(); | |
189 exit(0); | |
190 | |
191 case 'V': /* Print version and exit. */ | |
192 main_version(); | |
193 exit(0); | |
194 | |
195 case 'c': /* Read configuration from this file instead of the default location.. */ | |
196 if (optarg == NULL ) { | |
197 fprintf(stderr, "Missing argument with --config directive\n"); | |
198 return EINVAL; | |
199 } | |
200 conffile = optarg; | |
201 break; | |
202 | |
203 case 'l': /* Change the locale. */ | |
204 locale = setlocale(LC_ALL, optarg?:""); | |
205 if (!locale) { | |
206 fprintf(stderr, "Unable to set locale (%s)\n", optarg); | |
207 return EINVAL; | |
208 } | |
209 break; | |
210 | |
211 case 'd': /* Increase verbosity of debug messages. */ | |
212 fd_g_debug_lvl++; | |
213 break; | |
214 | |
215 case 'f': /* Full debug for the function with this name. */ | |
216 #ifdef DEBUG | |
217 fd_debug_one_function = optarg; | |
218 #else /* DEBUG */ | |
219 fprintf(stderr, "Error: must compile with DEBUG support to use --dbg_func feature!\n"); | |
220 return EINVAL; | |
221 #endif /* DEBUG */ | |
222 break; | |
223 | |
224 case 'F': /* Full debug for the file with this name. */ | |
225 #ifdef DEBUG | |
226 fd_debug_one_file = basename(optarg); | |
227 #else /* DEBUG */ | |
228 fprintf(stderr, "Error: must compile with DEBUG support to use --dbg_file feature!\n"); | |
229 return EINVAL; | |
230 #endif /* DEBUG */ | |
231 break; | |
232 | |
233 case 'g': /* Set a debug level and function for GNU TLS calls. */ | |
234 gnutls_debug = (int)atoi(optarg); | |
235 break; | |
236 | |
237 case 'q': /* Decrease verbosity then remove debug messages. */ | |
238 fd_g_debug_lvl--; | |
239 break; | |
240 | |
241 case '?': /* Invalid option. */ | |
242 /* `getopt_long' already printed an error message. */ | |
243 fprintf(stderr, "getopt_long found an invalid character\n"); | |
244 return EINVAL; | |
245 | |
246 default: /* bug: option not considered. */ | |
247 fprintf(stderr, "A command-line option is missing in parser: %c\n", c); | |
248 ASSERT(0); | |
249 return EINVAL; | |
250 } | |
251 } | |
252 | |
253 return 0; | |
254 } | |
255 | |
256 /* Handle some signals */ | |
257 static void * catch_signals(void * arg) | |
258 { | |
259 sigset_t ss; | |
260 fd_log_threadname ( "signals catcher" ); | |
261 | |
262 sigemptyset(&ss); | |
263 | |
264 /* Signals that terminate the daemon */ | |
265 sigaddset(&ss, SIGTERM); | |
266 sigaddset(&ss, SIGINT); | |
267 | |
268 /* Signals that send an event */ | |
269 sigaddset(&ss, SIGUSR1); | |
270 sigaddset(&ss, SIGUSR2); | |
271 | |
272 /* Now loop on the reception of the signal */ | |
273 while (1) { | |
274 int sig, *ps; | |
275 | |
276 /* Wait to receive the next signal */ | |
277 CHECK_POSIX_DO( sigwait(&ss, &sig), break ); | |
278 | |
279 TRACE_DEBUG(FULL, "Signal %d caught", sig); | |
280 | |
281 switch (sig) { | |
282 case SIGUSR1: | |
283 case SIGUSR2: | |
284 CHECK_MALLOC_DO( ps = malloc(sizeof(int)), goto out); | |
285 *ps = sig; | |
286 CHECK_FCT_DO( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TRIGGER, sizeof(int), ps), goto out ); | |
287 break; | |
288 | |
289 case SIGINT: | |
290 case SIGTERM: | |
291 CHECK_FCT_DO( fd_core_shutdown(), goto out ); | |
292 | |
293 } | |
294 } | |
295 out: | |
296 /* Better way to handle this ? */ | |
297 ASSERT(0); | |
298 return NULL; | |
299 } |