Navigation


source: freeDiameter/libfdcore/extensions.c @ 706:4ffbc9f1e922

Last change on this file since 706:4ffbc9f1e922 was 706:4ffbc9f1e922, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 11 years ago

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File size: 6.8 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2011, 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 "fdcore-internal.h"
37
38#include <dlfcn.h>      /* We may use libtool's <ltdl.h> later for better portability.... */
39
40/* plugins management */
41
42/* List of extensions to load, from the configuration parsing */
43struct fd_ext_info {
44        struct fd_list  chain;          /* link in the list */
45        char            *filename;      /* extension filename. must be a dynamic library with fd_ext_init symbol. */
46        char            *conffile;      /* optional configuration file name for the extension */
47        void            *handler;       /* object returned by dlopen() */
48        void            (*fini)(void);  /* optional address of the fd_ext_fini callback */
49};
50
51/* list of extensions */
52static struct fd_list ext_list = FD_LIST_INITIALIZER(ext_list);
53
54/* Add new extension */
55int fd_ext_add( char * filename, char * conffile )
56{
57        struct fd_ext_info * new;
58       
59        TRACE_ENTRY("%p %p", filename, conffile);
60       
61        /* Check the filename is valid */
62        CHECK_PARAMS( filename );
63       
64        /* Create a new object in the list */
65        CHECK_MALLOC(  new = malloc( sizeof(struct fd_ext_info) )  );
66        memset(new, 0, sizeof(struct fd_ext_info));
67        fd_list_init(&new->chain, NULL);
68        new->filename = filename;
69        new->conffile = conffile;
70        fd_list_insert_before( &ext_list, &new->chain );
71        TRACE_DEBUG (FULL, "Extension %s added to the list.", filename);
72        return 0;
73}
74
75/* Dump the list */
76void fd_ext_dump(void)
77{
78        struct fd_list * li;
79       
80        fd_log_debug("Dumping extensions list :\n");
81       
82        for (li = ext_list.next; li != &ext_list; li = li->next)
83        {
84                struct fd_ext_info * ext = (struct fd_ext_info *)li;
85                fd_log_debug(" - '%s'[%s] is %sloaded\n", ext->filename, ext->conffile?:"no conf", ext->handler ? "" : "not ");
86        }
87}
88
89/* Load all extensions in the list */
90int fd_ext_load()
91{
92        int ret;
93        int (*fd_ext_init)(int, int, char *) = NULL;
94        struct fd_list * li;
95       
96        TRACE_ENTRY();
97       
98        /* Loop on all extensions */
99        for (li = ext_list.next; li != &ext_list; li = li->next)
100        {
101                struct fd_ext_info * ext = (struct fd_ext_info *)li;
102                TRACE_DEBUG (INFO, "Loading : %s", ext->filename);
103               
104                /* Load the extension */
105#ifndef DEBUG
106                ext->handler = dlopen(ext->filename, RTLD_LAZY | RTLD_GLOBAL);
107#else /* DEBUG */
108                /* We resolve symbols immediatly so it's easier to find problems in ABI */
109                ext->handler = dlopen(ext->filename, RTLD_NOW | RTLD_GLOBAL);
110#endif /* DEBUG */
111                if (ext->handler == NULL) {
112                        /* An error occured */
113                        TRACE_DEBUG( NONE, "Loading of extension %s failed:\n %s\n", ext->filename, dlerror());
114                        return EINVAL;
115                }
116               
117                /* Resolve the entry point of the extension */
118                fd_ext_init = ( int (*) (int, int, char *) )dlsym( ext->handler, "fd_ext_init" );
119               
120                if (fd_ext_init == NULL) {
121                        /* An error occured */
122                        TRACE_DEBUG( NONE, "Unable to resolve symbol 'fd_ext_init' for extension %s:\n %s\n", ext->filename, dlerror());
123                        return EINVAL;
124                }
125               
126                /* Resolve the exit point of the extension, which is optional for extensions */
127                ext->fini = ( void (*) (void) )dlsym( ext->handler, "fd_ext_fini" );
128               
129                if (ext->fini == NULL) {
130                        /* Not provided */
131                        TRACE_DEBUG (FULL, "Extension [%s] has no fd_ext_fini function.", ext->filename);
132                } else {
133                        /* Provided */
134                        TRACE_DEBUG (FULL, "Extension [%s] fd_ext_fini has been resolved successfully.", ext->filename);
135                }
136               
137                /* Now call the entry point to initialize the extension */
138                ret = (*fd_ext_init)( FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, ext->conffile );
139                if (ret != 0) {
140                        /* The extension was unable to load cleanly */
141                        TRACE_DEBUG( NONE, "Extension %s returned an error during initialization: %s\n", ext->filename, strerror(ret));
142                        return ret;
143                }
144               
145                /* Proceed to the next extension */
146        }
147
148        TRACE_DEBUG (INFO, "All extensions loaded.");
149       
150        /* We have finished. */
151        return 0;
152}
153
154/* Now unload the extensions and free the memory */
155int fd_ext_term( void ) 
156{
157        TRACE_ENTRY();
158       
159        /* Loop on all extensions, in FIFO order */
160        while (!FD_IS_LIST_EMPTY(&ext_list))
161        {
162                struct fd_list * li = ext_list.next;
163                struct fd_ext_info * ext = (struct fd_ext_info *)li;
164       
165                /* Unlink this element from the list */
166                fd_list_unlink(li);
167               
168                /* Call the exit point of the extension, if it was resolved */
169                if (ext->fini != NULL) {
170                        TRACE_DEBUG (FULL, "Calling [%s]->fd_ext_fini function.", ext->filename);
171                        (*ext->fini)();
172                }
173               
174#ifndef SKIP_DLCLOSE
175                /* Now unload the extension */
176                if (ext->handler) {
177                        TRACE_DEBUG (FULL, "Unloading %s", ext->filename);
178                        if ( dlclose(ext->handler) != 0 ) {
179                                TRACE_DEBUG (INFO, "Unloading [%s] failed : %s\n", ext->filename, dlerror());
180                        }
181                }
182#endif /* SKIP_DLCLOSE */
183               
184                /* Free the object and continue */
185                free(ext->filename);
186                free(ext->conffile);
187                free(ext);
188        }
189       
190        /* We always return 0 since we would not handle an error anyway... */
191        return 0;
192}
193
Note: See TracBrowser for help on using the repository browser.