Navigation


source: freeDiameter/freeDiameter/main.c @ 20:277ec00d793e

Last change on this file since 20:277ec00d793e was 20:277ec00d793e, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 12 years ago

Backup before typhoon... Progress on server side

File size: 10.2 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2009, 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 "fD.h"
37
38#include <signal.h>
39#include <getopt.h>
40#include <locale.h>
41#include <gcrypt.h>
42
43/* forward declarations */
44static void * sig_hdl(void * arg);
45static int main_cmdline(int argc, char *argv[]);
46static void main_version(void);
47static void main_help( void );
48
49/* The static configuration structure */
50static struct fd_config conf;
51struct fd_config * fd_g_config = &conf;
52
53GCRY_THREAD_OPTION_PTHREAD_IMPL;
54
55/* freeDiameter starting point */
56int main(int argc, char * argv[])
57{
58        int ret;
59        pthread_t sig_th;
60        sigset_t sig_all;
61       
62        memset(fd_g_config, 0, sizeof(struct fd_config));
63        sigfillset(&sig_all);
64        CHECK_POSIX(  pthread_sigmask(SIG_BLOCK, &sig_all, NULL)  );
65       
66        /* Initialize the library */
67        CHECK_FCT( fd_lib_init() );
68        TRACE_DEBUG(INFO, "libfreeDiameter initialized.");
69       
70        /* Name this thread */
71        fd_log_threadname("Main");
72       
73        /* Initialize the config */
74        CHECK_FCT( fd_conf_init() );
75
76        /* Parse the command-line */
77        CHECK_FCT(  main_cmdline(argc, argv)  );
78       
79        /* Initialize gcrypt and gnutls */
80        (void) gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
81        (void) gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
82        CHECK_GNUTLS_DO( gnutls_global_init(), return EINVAL );
83        if ( ! gnutls_check_version(GNUTLS_VERSION) ) {
84                fprintf(stderr, "The GNUTLS library is too old; found '%s', need '" GNUTLS_VERSION "'\n", gnutls_check_version(NULL));
85                return EINVAL;
86        } else {
87                TRACE_DEBUG(INFO, "GNUTLS library '%s' initialized.", gnutls_check_version(NULL));
88        }
89       
90        /* Allow SIGINT and SIGTERM from this point */
91        CHECK_POSIX(  pthread_create(&sig_th, NULL, sig_hdl, NULL)  );
92       
93        /* Add definitions of the base protocol */
94        CHECK_FCT( fd_dict_base_protocol(fd_g_config->cnf_dict) );
95       
96        /* Initialize other modules */
97        CHECK_FCT(  fd_queues_init()  );
98        CHECK_FCT(  fd_msg_init()  );
99        CHECK_FCT(  fd_p_expi_init()  );
100       
101        /* Parse the configuration file */
102        CHECK_FCT( fd_conf_parse() );
103       
104        /* Load the dynamic extensions */
105        CHECK_FCT(  fd_ext_load()  );
106       
107        /* Start the peer state machines */
108        CHECK_FCT( fd_psm_start() );
109       
110        /* Now, just wait for events */
111        TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
112        fd_conf_dump();
113        while (1) {
114                int code;
115                CHECK_FCT_DO(  fd_event_get(fd_g_config->cnf_main_ev, &code, NULL),  break  );
116                switch (code) {
117                        case FDEV_DUMP_DICT:
118                                fd_dict_dump(fd_g_config->cnf_dict);
119                                break;
120                       
121                        case FDEV_DUMP_EXT:
122                                fd_ext_dump();
123                                break;
124                       
125                        case FDEV_DUMP_SERV:
126                                fd_servers_dump();
127                                break;
128                       
129                        case FDEV_DUMP_QUEUES:
130                                fd_fifo_dump(0, "Incoming messages", fd_g_incoming, fd_msg_dump_walk);
131                                fd_fifo_dump(0, "Outgoing messages", fd_g_outgoing, fd_msg_dump_walk);
132                                fd_fifo_dump(0, "Local messages",    fd_g_local,    fd_msg_dump_walk);
133                                break;
134                       
135                        case FDEV_DUMP_CONFIG:
136                                fd_conf_dump();
137                                break;
138                       
139                        case FDEV_DUMP_PEERS:
140                                fd_peer_dump_list(FULL);
141                                break;
142                       
143                        case FDEV_TERMINATE:
144                                ret = 0;
145                                goto end;
146                       
147                        default:
148                                TRACE_DEBUG(INFO, "Unexpected event in the daemon (%d), ignored.\n", code);
149                }
150        }
151       
152end:
153        TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon is stopping...");
154       
155        /* cleanups */
156        TODO("Stop dispatch thread(s) properly (no cancel yet)");
157        CHECK_FCT_DO( fd_peer_fini(), /* Stop all connections */ );
158        TODO("Stop dispatch & routing threads");
159        CHECK_FCT_DO( fd_ext_fini(), /* Cleaup all extensions */ );
160        TODO("Cleanup queues (dump all remaining messages ?)");
161       
162        CHECK_FCT_DO( fd_thr_term(&sig_th), /* continue */ );
163       
164        gnutls_global_deinit();
165       
166        return ret;
167}
168
169const char * fd_ev_str(int event)
170{
171        switch (event) {
172        #define case_str( _val )\
173                case _val : return #_val
174                case_str(FDEV_TERMINATE);
175                case_str(FDEV_DUMP_DICT);
176                case_str(FDEV_DUMP_EXT);
177                case_str(FDEV_DUMP_SERV);
178                case_str(FDEV_DUMP_QUEUES);
179                case_str(FDEV_DUMP_CONFIG);
180                case_str(FDEV_DUMP_PEERS);
181               
182                default:
183                        TRACE_DEBUG(FULL, "Unknown event : %d", event);
184                        return "Unknown event";
185        }
186}
187
188/* Parse the command-line */
189static int main_cmdline(int argc, char *argv[])
190{
191        int c;
192        int option_index = 0;
193        char * locale;
194       
195        struct option long_options[] = {
196                { "help",       no_argument,            NULL, 'h' },
197                { "version",    no_argument,            NULL, 'V' },
198                { "config",     required_argument,      NULL, 'c' },
199                { "debug",      no_argument,            NULL, 'd' },
200                { "quiet",      no_argument,            NULL, 'q' },
201                { "dbglocale",  optional_argument,      NULL, 'l' },
202                { NULL,         0,                      NULL, 0 }
203        };
204       
205        TRACE_ENTRY("%d %p", argc, argv);
206       
207        /* Loop on arguments */
208        while (1) {
209                c = getopt_long (argc, argv, "hVc:dql:", long_options, &option_index);
210                if (c == -1) 
211                        break;  /* Exit from the loop.  */
212               
213                switch (c) {
214                        case 'h':       /* Print help and exit.  */
215                                main_help();
216                                exit(0);
217
218                        case 'V':       /* Print version and exit.  */
219                                main_version();
220                                exit(0);
221
222                        case 'c':       /* Read configuration from this file instead of the default location..  */
223                                CHECK_PARAMS( optarg );
224                                fd_g_config->cnf_file = optarg;
225                                break;
226
227                        case 'l':       /* Change the locale.  */
228                                locale = setlocale(LC_ALL, optarg?:"");
229                                if (locale) {
230                                        TRACE_DEBUG(INFO, "Locale set to: %s", optarg ?: locale);
231                                } else {
232                                        TRACE_DEBUG(INFO, "Unable to set locale (%s)", optarg);
233                                        return EINVAL;
234                                }
235                                break;
236
237                        case 'd':       /* Increase verbosity of debug messages.  */
238                                fd_g_debug_lvl++;
239                                break;
240                               
241                        case 'q':       /* Decrease verbosity then remove debug messages.  */
242                                fd_g_debug_lvl--;
243                                break;
244
245                        case '?':       /* Invalid option.  */
246                                /* `getopt_long' already printed an error message.  */
247                                TRACE_DEBUG(INFO, "getopt_long found an invalid character");
248                                return EINVAL;
249
250                        default:        /* bug: option not considered.  */
251                                TRACE_DEBUG(INFO, "A command-line option is missing in parser: %c", c);
252                                ASSERT(0);
253                                return EINVAL;
254                }
255        }
256               
257        return 0;
258}
259
260/* Display package version */
261static void main_version_core(void)
262{
263        printf("%s, version %d.%d.%d"
264#ifdef HG_VERSION
265                " (r%s"
266# ifdef PACKAGE_HG_REVISION
267                "/%s"
268# endif /* PACKAGE_HG_VERSION */
269                ")"
270#endif /* HG_VERSION */
271                "\n", 
272                FD_PROJECT_NAME, FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, FD_PROJECT_VERSION_REV
273#ifdef HG_VERSION
274                , HG_VERSION
275# ifdef PACKAGE_HG_REVISION
276                , PACKAGE_HG_REVISION
277# endif /* PACKAGE_HG_VERSION */
278#endif /* HG_VERSION */
279                );
280}
281
282/* Display package version and general info */
283static void main_version(void)
284{
285        main_version_core();
286        printf( "%s\n", FD_PROJECT_COPYRIGHT);
287        printf( "\nSee " FD_PROJECT_NAME " homepage at http://aaa.koganei.wide.ad.jp/\n"
288                " for information, updates and bug reports on this software.\n");
289}
290
291/* Print command-line options */
292static void main_help( void )
293{
294        main_version_core();
295        printf( "  This daemon is an implementation of the Diameter protocol\n"
296                "  used for Authentication, Authorization, and Accounting (AAA).\n");
297        printf("\nUsage:  " FD_PROJECT_BINARY " [OPTIONS]...\n");
298        printf( "  -h, --help             Print help and exit\n"
299                "  -V, --version          Print version and exit\n"
300                "  -c, --config=filename  Read configuration from this file instead of the \n"
301                "                           default location (%s).\n", DEFAULT_CONF_FILE);
302        printf( "\nDebug:\n"
303                "  These options are mostly useful for developers\n"
304                "  -l, --dbglocale        Set the locale for error messages\n"
305                "  -d, --debug            Increase verbosity of debug messages\n"
306                "  -q, --quiet            Decrease verbosity then remove debug messages\n");
307}
308
309#ifdef HAVE_SIGNALENT_H
310const char *const signalstr[] = {
311# include "signalent.h"
312};
313const int nsignalstr = sizeof signalstr / sizeof signalstr[0];
314# define SIGNALSTR(sig) (((sig) < nsignalstr) ? signalstr[(sig)] : "unknown")
315#else /* HAVE_SIGNALENT_H */
316# define SIGNALSTR(sig) ("")
317#endif /* HAVE_SIGNALENT_H */
318
319/* signal handler */
320static void * sig_hdl(void * arg)
321{
322        sigset_t sig_main;
323        int sig = 0;
324       
325        TRACE_ENTRY();
326        fd_log_threadname("Main signal handler");
327       
328        sigemptyset(&sig_main);
329        sigaddset(&sig_main, SIGINT);
330        sigaddset(&sig_main, SIGTERM);
331       
332        CHECK_SYS_DO(  sigwait(&sig_main, &sig), TRACE_DEBUG(INFO, "Error in sigwait function") );
333       
334        TRACE_DEBUG(INFO, "Received signal %s (%d), exiting", SIGNALSTR(sig), sig);
335        CHECK_FCT_DO( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), exit(2) );
336        return NULL;
337}
338       
Note: See TracBrowser for help on using the repository browser.