Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Knot DNS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
22
Issues
22
List
Boards
Labels
Service Desk
Milestones
Merge Requests
17
Merge Requests
17
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Knot projects
Knot DNS
Commits
65f6161a
Commit
65f6161a
authored
Mar 06, 2017
by
Daniel Salzman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
module: create new API with dynamic loading support
parent
c5a193a0
Changes
42
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
2141 additions
and
1022 deletions
+2141
-1022
Knot.files
Knot.files
+2
-0
src/Makefile.am
src/Makefile.am
+6
-0
src/knot/common/stats.c
src/knot/common/stats.c
+1
-1
src/knot/conf/base.c
src/knot/conf/base.c
+49
-134
src/knot/conf/base.h
src/knot/conf/base.h
+31
-33
src/knot/conf/confio.c
src/knot/conf/confio.c
+28
-9
src/knot/conf/module.c
src/knot/conf/module.c
+448
-0
src/knot/conf/module.h
src/knot/conf/module.h
+110
-0
src/knot/conf/scheme.c
src/knot/conf/scheme.c
+13
-39
src/knot/conf/tools.c
src/knot/conf/tools.c
+99
-49
src/knot/conf/tools.h
src/knot/conf/tools.h
+24
-21
src/knot/ctl/commands.c
src/knot/ctl/commands.c
+1
-1
src/knot/include/module.h
src/knot/include/module.h
+482
-0
src/knot/nameserver/axfr.c
src/knot/nameserver/axfr.c
+14
-14
src/knot/nameserver/axfr.h
src/knot/nameserver/axfr.h
+2
-2
src/knot/nameserver/internet.c
src/knot/nameserver/internet.c
+109
-112
src/knot/nameserver/internet.h
src/knot/nameserver/internet.h
+6
-19
src/knot/nameserver/ixfr.c
src/knot/nameserver/ixfr.c
+17
-17
src/knot/nameserver/ixfr.h
src/knot/nameserver/ixfr.h
+2
-2
src/knot/nameserver/notify.c
src/knot/nameserver/notify.c
+6
-6
src/knot/nameserver/notify.h
src/knot/nameserver/notify.h
+2
-13
src/knot/nameserver/nsec_proofs.c
src/knot/nameserver/nsec_proofs.c
+42
-42
src/knot/nameserver/nsec_proofs.h
src/knot/nameserver/nsec_proofs.h
+7
-7
src/knot/nameserver/process_query.c
src/knot/nameserver/process_query.c
+76
-84
src/knot/nameserver/process_query.h
src/knot/nameserver/process_query.h
+18
-70
src/knot/nameserver/query_module.c
src/knot/nameserver/query_module.c
+398
-103
src/knot/nameserver/query_module.h
src/knot/nameserver/query_module.h
+38
-167
src/knot/nameserver/update.c
src/knot/nameserver/update.c
+28
-23
src/knot/nameserver/update.h
src/knot/nameserver/update.h
+3
-14
src/knot/nameserver/xfr.c
src/knot/nameserver/xfr.c
+6
-7
src/knot/nameserver/xfr.h
src/knot/nameserver/xfr.h
+3
-3
src/knot/server/server.c
src/knot/server/server.c
+38
-11
src/knot/server/tcp-handler.c
src/knot/server/tcp-handler.c
+3
-2
src/knot/server/udp-handler.c
src/knot/server/udp-handler.c
+6
-6
src/knot/zone/zone.c
src/knot/zone/zone.c
+6
-4
src/knot/zone/zone.h
src/knot/zone/zone.h
+1
-1
src/knot/zone/zonedb-load.c
src/knot/zone/zonedb-load.c
+1
-0
src/utils/keymgr/main.c
src/utils/keymgr/main.c
+1
-1
src/utils/knotc/commands.c
src/utils/knotc/commands.c
+2
-2
src/utils/knotc/commands.h
src/utils/knotc/commands.h
+3
-1
src/utils/knotc/process.c
src/utils/knotc/process.c
+7
-1
src/utils/knotd/main.c
src/utils/knotd/main.c
+2
-1
No files found.
Knot.files
View file @
65f6161a
...
...
@@ -177,6 +177,8 @@ src/knot/conf/confio.c
src/knot/conf/confio.h
src/knot/conf/migration.c
src/knot/conf/migration.h
src/knot/conf/module.c
src/knot/conf/module.h
src/knot/conf/scheme.c
src/knot/conf/scheme.h
src/knot/conf/tools.c
...
...
src/Makefile.am
View file @
65f6161a
...
...
@@ -241,6 +241,8 @@ libknotd_la_SOURCES = \
knot/conf/confio.h
\
knot/conf/migration.c
\
knot/conf/migration.h
\
knot/conf/module.h
\
knot/conf/module.c
\
knot/conf/scheme.c
\
knot/conf/scheme.h
\
knot/conf/tools.c
\
...
...
@@ -424,6 +426,10 @@ if HAVE_DAEMON
sbin_PROGRAMS
=
knotc knotd keymgr
noinst_LTLIBRARIES
+=
libknotd.la libknotus.la
knotddir
=
$(includedir)
/knot
knotd_HEADERS
=
\
knot/include/module.h
knotc_SOURCES
=
\
utils/knotc/commands.c
\
utils/knotc/commands.h
\
...
...
src/knot/common/stats.c
View file @
65f6161a
...
...
@@ -79,7 +79,7 @@ static void dump_counters(FILE *fd, int level, mod_ctr_t *ctr)
static
void
dump_modules
(
dump_ctx_t
*
ctx
)
{
int
level
=
0
;
struct
query_module
*
mod
=
NULL
;
knotd_mod_t
*
mod
=
NULL
;
WALK_LIST
(
mod
,
*
ctx
->
query_modules
)
{
// Skip modules without statistics.
if
(
mod
->
stats_count
==
0
)
{
...
...
src/knot/conf/base.c
View file @
65f6161a
...
...
@@ -18,6 +18,7 @@
#include "knot/conf/base.h"
#include "knot/conf/confdb.h"
#include "knot/conf/module.h"
#include "knot/conf/tools.h"
#include "knot/common/log.h"
#include "knot/nameserver/query_module.h"
...
...
@@ -232,6 +233,27 @@ int conf_new(
// Initialize cached values.
init_cache
(
out
);
// Load module schemas.
if
(
flags
&
(
CONF_FREQMODULES
|
CONF_FOPTMODULES
))
{
ret
=
conf_mod_load_common
(
out
);
if
(
ret
!=
KNOT_EOK
&&
(
flags
&
CONF_FREQMODULES
))
{
goto
new_error
;
}
for
(
conf_iter_t
iter
=
conf_iter
(
out
,
C_MODULE
);
iter
.
code
==
KNOT_EOK
;
conf_iter_next
(
out
,
&
iter
))
{
conf_val_t
id
=
conf_iter_id
(
out
,
&
iter
);
conf_val_t
file
=
conf_id_get
(
out
,
C_MODULE
,
C_FILE
,
&
id
);
ret
=
conf_mod_load_extra
(
out
,
conf_str
(
&
id
),
conf_str
(
&
file
),
false
);
if
(
ret
!=
KNOT_EOK
&&
(
flags
&
CONF_FREQMODULES
))
{
conf_iter_finish
(
out
,
&
iter
);
goto
new_error
;
}
}
conf_mod_load_purge
(
out
,
false
);
}
*
conf
=
out
;
return
KNOT_EOK
;
...
...
@@ -297,7 +319,7 @@ int conf_clone(
return
KNOT_EOK
;
}
void
conf_update
(
conf_t
*
conf_update
(
conf_t
*
conf
,
conf_update_flag_t
flags
)
{
...
...
@@ -311,7 +333,7 @@ void conf_update(
}
if
((
flags
&
CONF_UPD_FMODULES
)
&&
s_conf
!=
NULL
)
{
list_dup
(
&
conf
->
query_modules
,
&
s_conf
->
query_modules
,
sizeof
(
struct
query_module
));
sizeof
(
knotd_mod_t
));
conf
->
query_plan
=
s_conf
->
query_plan
;
}
}
...
...
@@ -332,9 +354,13 @@ void conf_update(
WALK_LIST_FREE
(
old_conf
->
query_modules
);
old_conf
->
query_plan
=
NULL
;
}
conf_free
(
old_conf
);
if
(
!
(
flags
&
CONF_UPD_FNOFREE
))
{
conf_free
(
old_conf
);
old_conf
=
NULL
;
}
}
return
old_conf
;
}
void
conf_free
(
...
...
@@ -359,7 +385,9 @@ void conf_free(
mm_free
(
conf
->
mm
,
conf
->
io
.
zones
);
}
conf_mod_load_purge
(
conf
,
false
);
conf_deactivate_modules
(
&
conf
->
query_modules
,
&
conf
->
query_plan
);
conf_mod_unload_shared
(
conf
);
if
(
!
conf
->
is_clone
)
{
if
(
conf
->
api
!=
NULL
)
{
...
...
@@ -374,126 +402,6 @@ void conf_free(
free
(
conf
);
}
#define LOG_ARGS(mod_id, msg, ...) "module '%s%s%.*s', " msg, \
mod_id->name + 1, (mod_id->len > 0) ? "/" : "", (int)mod_id->len, \
mod_id->data
void
conf_activate_modules
(
conf_t
*
conf
,
const
knot_dname_t
*
zone_name
,
list_t
*
query_modules
,
struct
query_plan
**
query_plan
)
{
int
ret
=
KNOT_EOK
;
if
(
conf
==
NULL
||
query_modules
==
NULL
||
query_plan
==
NULL
)
{
ret
=
KNOT_EINVAL
;
goto
activate_error
;
}
conf_val_t
val
;
// Get list of associated modules.
if
(
zone_name
!=
NULL
)
{
val
=
conf_zone_get
(
conf
,
C_MODULE
,
zone_name
);
}
else
{
val
=
conf_default_get
(
conf
,
C_GLOBAL_MODULE
);
}
switch
(
val
.
code
)
{
case
KNOT_EOK
:
break
;
case
KNOT_ENOENT
:
// Check if a module is configured at all.
case
KNOT_YP_EINVAL_ID
:
return
;
default:
ret
=
val
.
code
;
goto
activate_error
;
}
// Create query plan.
*
query_plan
=
query_plan_create
(
conf
->
mm
);
if
(
*
query_plan
==
NULL
)
{
ret
=
KNOT_ENOMEM
;
goto
activate_error
;
}
// Initialize query modules list.
init_list
(
query_modules
);
// Open the modules.
while
(
val
.
code
==
KNOT_EOK
)
{
conf_mod_id_t
*
mod_id
=
conf_mod_id
(
&
val
);
if
(
mod_id
==
NULL
)
{
ret
=
KNOT_ENOMEM
;
goto
activate_error
;
}
// Open the module.
struct
query_module
*
mod
=
query_module_open
(
conf
,
mod_id
,
*
query_plan
,
zone_name
,
conf
->
mm
);
if
(
mod
==
NULL
)
{
ret
=
KNOT_ENOMEM
;
goto
activate_error
;
}
// Check the module scope.
if
((
zone_name
==
NULL
&&
(
mod
->
scope
&
MOD_SCOPE_GLOBAL
)
==
0
)
||
(
zone_name
!=
NULL
&&
(
mod
->
scope
&
MOD_SCOPE_ZONE
)
==
0
))
{
if
(
zone_name
!=
NULL
)
{
log_zone_warning
(
zone_name
,
LOG_ARGS
(
mod_id
,
"out of scope"
));
}
else
{
log_warning
(
LOG_ARGS
(
mod_id
,
"out of scope"
));
}
query_module_close
(
mod
);
conf_val_next
(
&
val
);
continue
;
}
// Load the module.
ret
=
mod
->
load
(
mod
);
if
(
ret
!=
KNOT_EOK
)
{
if
(
zone_name
!=
NULL
)
{
log_zone_error
(
zone_name
,
LOG_ARGS
(
mod_id
,
"failed to load"
));
}
else
{
log_error
(
LOG_ARGS
(
mod_id
,
"failed to load"
));
}
query_module_close
(
mod
);
conf_val_next
(
&
val
);
continue
;
}
add_tail
(
query_modules
,
&
mod
->
node
);
conf_val_next
(
&
val
);
}
return
;
activate_error:
CONF_LOG
(
LOG_ERR
,
"failed to activate modules (%s)"
,
knot_strerror
(
ret
));
}
void
conf_deactivate_modules
(
list_t
*
query_modules
,
struct
query_plan
**
query_plan
)
{
if
(
query_modules
==
NULL
||
query_plan
==
NULL
)
{
return
;
}
// Free query plan.
query_plan_free
(
*
query_plan
);
*
query_plan
=
NULL
;
// Free query modules list.
struct
query_module
*
mod
=
NULL
,
*
next
=
NULL
;
WALK_LIST_DELSAFE
(
mod
,
next
,
*
query_modules
)
{
mod
->
unload
(
mod
);
query_module_close
(
mod
);
}
init_list
(
query_modules
);
}
#define CONF_LOG_LINE(file, line, msg, ...) do { \
CONF_LOG(LOG_ERR, "%s%s%sline %zu, " msg, \
(file != NULL ? "file '" : ""), (file != NULL ? file : ""), \
...
...
@@ -513,17 +421,17 @@ static void log_parser_err(
static
void
log_call_err
(
yp_parser_t
*
parser
,
conf_check
_t
*
args
,
knotd_conf_check_args
_t
*
args
,
int
ret
)
{
CONF_LOG_LINE
(
args
->
file_name
,
args
->
line
,
CONF_LOG_LINE
(
args
->
extra
->
file_name
,
args
->
extra
->
line
,
"item '%s', value '%.*s' (%s)"
,
args
->
item
->
name
+
1
,
(
int
)
parser
->
data_len
,
parser
->
data
,
args
->
err_str
!=
NULL
?
args
->
err_str
:
knot_strerror
(
ret
));
}
static
void
log_prev_err
(
conf_check
_t
*
args
,
knotd_conf_check_args
_t
*
args
,
int
ret
)
{
char
buff
[
512
]
=
{
0
};
...
...
@@ -537,7 +445,7 @@ static void log_prev_err(
}
}
CONF_LOG_LINE
(
args
->
file_name
,
args
->
line
,
CONF_LOG_LINE
(
args
->
extra
->
file_name
,
args
->
extra
->
line
,
"%s '%s' (%s)"
,
args
->
item
->
name
+
1
,
buff
,
args
->
err_str
!=
NULL
?
args
->
err_str
:
knot_strerror
(
ret
));
}
...
...
@@ -556,14 +464,17 @@ static int finalize_previous_section(
return
KNOT_EOK
;
}
conf_check_t
args
=
{
knotd_conf_check_extra_t
extra
=
{
.
conf
=
conf
,
.
txn
=
txn
,
.
file_name
=
parser
->
file
.
name
,
.
line
=
parser
->
line_count
};
knotd_conf_check_args_t
args
=
{
.
item
=
node
->
item
,
.
id
=
node
->
id
,
.
id_len
=
node
->
id_len
,
.
file_name
=
parser
->
file
.
name
,
.
line
=
parser
->
line_count
.
extra
=
&
extra
};
int
ret
=
conf_exec_callbacks
(
&
args
);
...
...
@@ -587,16 +498,19 @@ static int finalize_item(
return
KNOT_EOK
;
}
conf_check_t
args
=
{
knotd_conf_check_extra_t
extra
=
{
.
conf
=
conf
,
.
txn
=
txn
,
.
file_name
=
parser
->
file
.
name
,
.
line
=
parser
->
line_count
};
knotd_conf_check_args_t
args
=
{
.
item
=
(
parser
->
event
==
YP_EID
)
?
node
->
item
->
var
.
g
.
id
:
node
->
item
,
.
id
=
node
->
id
,
.
id_len
=
node
->
id_len
,
.
data
=
node
->
data
,
.
data_len
=
node
->
data_len
,
.
file_name
=
parser
->
file
.
name
,
.
line
=
parser
->
line_count
.
extra
=
&
extra
};
int
ret
=
conf_exec_callbacks
(
&
args
);
...
...
@@ -693,6 +607,7 @@ int conf_parse(
ret
=
check_ret
;
}
conf_mod_load_purge
(
conf
,
false
);
yp_scheme_check_deinit
(
ctx
);
parse_error:
yp_deinit
(
parser
);
...
...
src/knot/conf/base.h
View file @
65f6161a
...
...
@@ -29,6 +29,8 @@
#include "libknot/yparser/ypscheme.h"
#include "contrib/qp-trie/trie.h"
#include "contrib/ucw/lists.h"
#include "contrib/dynarray.h"
#include "knot/include/module.h"
/*! Default template identifier. */
#define CONF_DEFAULT_ID ((uint8_t *)"\x08""default\0")
...
...
@@ -67,6 +69,19 @@ typedef struct {
int
code
;
}
conf_val_t
;
/*! Query module context. */
typedef
struct
{
/*! Module interface. */
const
knotd_mod_api_t
*
api
;
/*! Shared library dlopen handler. */
void
*
lib_handle
;
/*! Indication of a temporary module created during confio check. */
bool
temporary
;
}
module_t
;
dynarray_declare
(
mod
,
module_t
*
,
DYNARRAY_VISIBILITY_PUBLIC
,
16
)
dynarray_declare
(
old_schema
,
yp_item_t
*
,
DYNARRAY_VISIBILITY_PUBLIC
,
16
)
/*! Configuration context. */
typedef
struct
{
/*! Cloned configuration indicator. */
...
...
@@ -112,6 +127,10 @@ typedef struct {
conf_val_t
srv_nsid
;
}
cache
;
/*! List of dynamically loaded modules. */
mod_dynarray_t
modules
;
/*! List of old schemas (lazy freed). */
old_schema_dynarray_t
old_schemas
;
/*! List of active query modules. */
list_t
query_modules
;
/*! Default query modules plan. */
...
...
@@ -122,10 +141,12 @@ typedef struct {
* Configuration access flags.
*/
typedef
enum
{
CONF_FNONE
=
0
,
/*!< Empty flag. */
CONF_FREADONLY
=
1
<<
0
,
/*!< Read only access. */
CONF_FNOCHECK
=
1
<<
1
,
/*!< Disabled confdb check. */
CONF_FNOHOSTNAME
=
1
<<
2
,
/*!< Don't set the hostname. */
CONF_FNONE
=
0
,
/*!< Empty flag. */
CONF_FREADONLY
=
1
<<
0
,
/*!< Read only access. */
CONF_FNOCHECK
=
1
<<
1
,
/*!< Disabled confdb check. */
CONF_FNOHOSTNAME
=
1
<<
2
,
/*!< Don't set the hostname. */
CONF_FREQMODULES
=
1
<<
3
,
/*!< Load module schemas (must succeed). */
CONF_FOPTMODULES
=
1
<<
4
,
/*!< Load module schemas (may fail). */
}
conf_flag_t
;
/*!
...
...
@@ -133,8 +154,9 @@ typedef enum {
*/
typedef
enum
{
CONF_UPD_FNONE
=
0
,
/*!< Empty flag. */
CONF_UPD_FMODULES
=
1
<<
0
,
/*!< Reuse previous global modules. */
CONF_UPD_FCONFIO
=
1
<<
1
,
/*!< Reuse previous cofio reload context. */
CONF_UPD_FNOFREE
=
1
<<
0
,
/*!< Disable auto-free of previous config. */
CONF_UPD_FMODULES
=
1
<<
1
,
/*!< Reuse previous global modules. */
CONF_UPD_FCONFIO
=
1
<<
2
,
/*!< Reuse previous cofio reload context. */
}
conf_update_flag_t
;
/*!
...
...
@@ -197,8 +219,10 @@ int conf_clone(
*
* \param[in] conf New configuration.
* \param[in] flags Update flags.
*
* \return Previous config if CONF_UPD_FNOFREE, else NULL.
*/
void
conf_update
(
conf_t
*
conf_update
(
conf_t
*
conf
,
conf_update_flag_t
flags
);
...
...
@@ -212,32 +236,6 @@ void conf_free(
conf_t
*
conf
);
/*!
* Activates configured query modules for the specified zone or for all zones.
*
* \param[in] conf Configuration.
* \param[in] zone_name Zone name, NULL for all zones.
* \param[in] query_modules Destination query modules list.
* \param[in] query_plan Destination query plan.
*/
void
conf_activate_modules
(
conf_t
*
conf
,
const
knot_dname_t
*
zone_name
,
list_t
*
query_modules
,
struct
query_plan
**
query_plan
);
/*!
* Deactivates query modules list.
*
* \param[in] query_modules Destination query modules list.
* \param[in] query_plan Destination query plan.
*/
void
conf_deactivate_modules
(
list_t
*
query_modules
,
struct
query_plan
**
query_plan
);
/*!
* Parses textual configuration from the string or from the file.
*
...
...
src/knot/conf/confio.c
View file @
65f6161a
...
...
@@ -16,8 +16,10 @@
#include <assert.h>
#include "knot/common/log.h"
#include "knot/conf/confdb.h"
#include "knot/conf/confio.h"
#include "knot/conf/module.h"
#include "knot/conf/tools.h"
#define FCN(io) (io->fcn != NULL) ? io->fcn(io) : KNOT_EOK;
...
...
@@ -878,20 +880,32 @@ static int set_item(
}
// Postpone group callbacks to config check.
if
(
io
->
key0
->
type
==
YP_TGRP
)
{
if
(
io
->
key0
->
type
==
YP_TGRP
&&
io
->
id_len
==
0
)
{
return
KNOT_EOK
;
}
conf_check_t
args
=
{
knotd_conf_check_extra_t
extra
=
{
.
conf
=
conf
(),
.
txn
=
conf
()
->
io
.
txn
,
.
item
=
(
io
->
key1
!=
NULL
)
?
io
->
key1
:
io
->
key0
,
.
txn
=
conf
()
->
io
.
txn
};
knotd_conf_check_args_t
args
=
{
.
item
=
(
io
->
key1
!=
NULL
)
?
io
->
key1
:
((
io
->
id_len
==
0
)
?
io
->
key0
:
io
->
key0
->
var
.
g
.
id
),
.
id
=
io
->
id
,
.
id_len
=
io
->
id_len
,
.
data
=
io
->
data
.
bin
,
.
data_len
=
io
->
data
.
bin_len
.
data_len
=
io
->
data
.
bin_len
,
.
extra
=
&
extra
};
// Call the item callbacks (include).
return
conf_exec_callbacks
(
&
args
);
// Call the item callbacks (include, item check, mod-id check).
ret
=
conf_exec_callbacks
(
&
args
);
if
(
ret
!=
KNOT_EOK
)
{
CONF_LOG
(
LOG_DEBUG
,
"item '%s' (%s)"
,
args
.
item
->
name
+
1
,
args
.
err_str
!=
NULL
?
args
.
err_str
:
knot_strerror
(
ret
));
}
return
ret
;
}
int
conf_io_set
(
...
...
@@ -1276,11 +1290,15 @@ static int check_section(
size_t
id_len
,
conf_io_t
*
io
)
{
conf_check_t
args
=
{
knotd_conf_check_extra_t
extra
=
{
.
conf
=
conf
(),
.
txn
=
conf
()
->
io
.
txn
,
.
check
=
true
};
knotd_conf_check_args_t
args
=
{
.
id
=
id
,
.
id_len
=
id_len
.
id_len
=
id_len
,
.
extra
=
&
extra
};
bool
non_empty
=
false
;
...
...
@@ -1482,6 +1500,7 @@ int conf_io_check(
ret
=
KNOT_EOK
;
check_error:
conf_mod_load_purge
(
conf
(),
true
);
return
ret
;
}
src/knot/conf/module.c
0 → 100644
View file @
65f6161a
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dlfcn.h>
#include <glob.h>
#include <sys/stat.h>
#include <urcu.h>
#include "knot/conf/conf.h"
#include "knot/conf/confio.h"
#include "knot/conf/module.h"
#include "knot/common/log.h"
#include "knot/modules/static_modules.h"
#include "knot/nameserver/query_module.h"
#include "contrib/openbsd/strlcat.h"
#include "contrib/string.h"
#define LIB_EXTENSION ".so"
dynarray_define
(
mod
,
module_t
*
,
DYNARRAY_VISIBILITY_PUBLIC
,
16
)
dynarray_define
(
old_schema
,
yp_item_t
*
,
DYNARRAY_VISIBILITY_PUBLIC
,
16
)
static
module_t
STATIC_MODULES
[]
=
{
STATIC_MODULES_INIT
{
NULL
}
};
module_t
*
conf_mod_find
(
conf_t
*
conf
,
const
char
*
name
,
size_t
len
,
bool
temporary
)
{
if
(
conf
==
NULL
||
name
==
NULL
)
{
return
NULL
;
}
// First, search in static modules.
for
(
module_t
*
mod
=
STATIC_MODULES
;
mod
->
api
!=
NULL
;
mod
++
)
{
if
(
strncmp
(
name
,
mod
->
api
->
name
,
len
)
==
0
)
{
return
mod
;
}
}
// Second, search in dynamic modules.
dynarray_foreach
(
mod
,
module_t
*
,
module
,
conf
->
modules
)
{
if
((
*
module
)
!=
NULL
&&
(
*
module
)
->
temporary
==
temporary
&&
strncmp
(
name
,
(
*
module
)
->
api
->
name
,
len
)
==
0
)
{
return
(
*
module
);
}
}
return
NULL
;
}
static
int
mod_load
(
conf_t
*
conf
,
module_t
*
mod
)
{
static
const
yp_item_t
module_common
[]
=
{
{
C_ID
,
YP_TSTR
,
YP_VNONE
,
CONF_IO_FREF
},
{
C_COMMENT
,
YP_TSTR
,
YP_VNONE
},
{
NULL
}
};
yp_item_t
*
sub_items
=
NULL
;
int
ret
;
if
(
mod
->
api
->
config
!=
NULL
)
{
ret
=
yp_scheme_merge
(
&
sub_items
,
module_common
,
mod
->
api
->
config
);
}
else
{
ret
=
yp_scheme_copy
(
&
sub_items
,
module_common
);
}
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
/* Synthesise module config section name. */
const
size_t
name_len
=
strlen
(
mod
->
api
->
name
);
if
(
name_len
>
YP_MAX_ITEM_NAME_LEN
)
{
return
KNOT_YP_EINVAL_ITEM
;
}
char
name
[
1
+
YP_MAX_ITEM_NAME_LEN
+
1
];
name
[
0
]
=
name_len
;
memcpy
(
name
+
1
,
mod
->
api
->
name
,
name_len
+
1
);
const
yp_item_t
scheme
[]
=
{
{
name
,
YP_TGRP
,
YP_VGRP
=
{
sub_items
},
YP_FALLOC
|
YP_FMULTI
|
CONF_IO_FRLD_MOD
|
CONF_IO_FRLD_ZONES
},
{
NULL
}
};
yp_item_t
*
merged
=
NULL
;
ret
=
yp_scheme_merge
(
&
merged
,
conf
->
scheme
,
scheme
);
yp_scheme_free
(
sub_items
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
// Update configuration schema (with lazy free).
yp_item_t
**
current_schema
=
&
conf
->
scheme
;
yp_item_t
*
old_schema
=
rcu_xchg_pointer
(
current_schema
,
merged
);
synchronize_rcu
();
old_schema_dynarray_add
(
&
conf
->
old_schemas
,
&
old_schema
);
return
KNOT_EOK
;
}
int
conf_mod_load_common
(
conf_t
*
conf
)
{
if
(
conf
==
NULL
)
{
return
KNOT_EINVAL
;
}
int
ret
=
KNOT_EOK
;