#include <errno.h>
#include <getopt.h>
#include <sys/socket.h>
+#include <syslog.h>
#include "common.h"
#include "configure_ac.h"
/** Format in which file names will be printed. */
enum filename_format filename_format;
/* Log level */
- enum log_level level;
+ uint8_t level;
/* Log output */
enum log_output output;
} log;
rpki_config.log.color = false;
rpki_config.log.filename_format = FNF_GLOBAL;
- rpki_config.log.level = LOG_LEVEL_WARNING;
+ rpki_config.log.level = LOG_WARNING;
rpki_config.log.output = CONSOLE;
rpki_config.output.roa = NULL;
error = validate_config();
+ log_start();
end:
if (error)
free_rpki_config();
return rpki_config.log.filename_format;
}
-enum log_level
+uint8_t
config_get_log_level(void)
{
return rpki_config.log.level;
enum mode config_get_mode(void);
bool config_get_color_output(void);
enum filename_format config_get_filename_format(void);
-enum log_level config_get_log_level(void);
+uint8_t config_get_log_level(void);
enum log_output config_get_log_output(void);
char *config_get_rsync_program(void);
struct string_array const *config_get_rsync_args(bool);
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
+#include <syslog.h>
#include "log.h"
#include "config/str.h"
#define LOG_OUTPUT_VALUE_SYSLOG "syslog"
#define LOG_OUTPUT_VALUE_CONSOLE "console"
-#define DEREFERENCE(type, void_value) (*((enum log_##type *) void_value))
+#define DEREFERENCE_UINT(void_value) (*((uint8_t *) void_value))
+#define DEREFERENCE_ENUM(void_value) (*((enum log_output *) void_value))
static void
print_log_level(struct option_field const *field, void *value)
{
char const *str = "<unknown>";
- switch (DEREFERENCE(level, value)) {
- case LOG_LEVEL_ERROR:
+ switch (DEREFERENCE_UINT(value)) {
+ case LOG_ERR:
str = LOG_LEVEL_VALUE_ERROR;
break;
- case LOG_LEVEL_WARNING:
+ case LOG_WARNING:
str = LOG_LEVEL_VALUE_WARNING;
break;
- case LOG_LEVEL_INFO:
+ case LOG_INFO:
str = LOG_LEVEL_VALUE_INFO;
break;
- case LOG_LEVEL_DEBUG:
+ case LOG_DEBUG:
str = LOG_LEVEL_VALUE_DEBUG;
break;
}
{
char const *str = "<unknown>";
- switch (DEREFERENCE(output, value)) {
+ switch (DEREFERENCE_ENUM(value)) {
case SYSLOG:
str = LOG_OUTPUT_VALUE_SYSLOG;
break;
void *result)
{
if (strcmp(str, LOG_LEVEL_VALUE_ERROR) == 0)
- DEREFERENCE(level, result) = LOG_LEVEL_ERROR;
+ DEREFERENCE_UINT(result) = LOG_ERR;
else if (strcmp(str, LOG_LEVEL_VALUE_WARNING) == 0)
- DEREFERENCE(level, result) = LOG_LEVEL_WARNING;
+ DEREFERENCE_UINT(result) = LOG_WARNING;
else if (strcmp(str, LOG_LEVEL_VALUE_INFO) == 0)
- DEREFERENCE(level, result) = LOG_LEVEL_INFO;
+ DEREFERENCE_UINT(result) = LOG_INFO;
else if (strcmp(str, LOG_LEVEL_VALUE_DEBUG) == 0)
- DEREFERENCE(level, result) = LOG_LEVEL_DEBUG;
+ DEREFERENCE_UINT(result) = LOG_DEBUG;
else
return pr_err("Unknown log level: '%s'", str);
void *result)
{
if (strcmp(str, LOG_OUTPUT_VALUE_SYSLOG) == 0)
- DEREFERENCE(output, result) = SYSLOG;
+ DEREFERENCE_ENUM(result) = SYSLOG;
else if (strcmp(str, LOG_OUTPUT_VALUE_CONSOLE) == 0)
- DEREFERENCE(output, result) = CONSOLE;
+ DEREFERENCE_ENUM(result) = CONSOLE;
else
return pr_err("Unknown log output: '%s'", str);
const struct global_type gt_log_level = {
.has_arg = required_argument,
- .size = sizeof(enum log_level),
+ .size = sizeof(uint8_t),
.print = print_log_level,
.parse.argv = parse_argv_log_level,
.parse.json = parse_json_log_level,
#include "config/types.h"
-enum log_level {
- LOG_LEVEL_ERROR,
- LOG_LEVEL_WARNING,
- LOG_LEVEL_INFO,
- LOG_LEVEL_DEBUG
-};
-
enum log_output {
SYSLOG,
CONSOLE
syslog_enabled = true;
}
-void
+static void
log_disable_std(void)
{
fprintf_enabled = false;
}
-void
+static void
log_disable_syslog(void)
{
if (syslog_enabled) {
}
}
+void
+log_start(void)
+{
+ switch (config_get_log_output()) {
+ case SYSLOG:
+ pr_info("Syslog log output configured; disabling logging on standard streams.");
+ pr_info("(Logs will be sent to syslog only.)");
+ log_disable_std();
+ break;
+ case CONSOLE:
+ pr_info("Console log output configured; disabling logging on syslog.");
+ pr_info("(Logs will be sent to the standard streams only.)");
+ log_disable_syslog();
+ break;
+ }
+}
+
void
log_teardown(void)
{
do { \
va_list args; \
\
+ if (level > config_get_log_level()) \
+ break; \
+ \
if (syslog_enabled) { \
va_start(args, format); \
pr_syslog(level, format, args); \
} \
} while (0)
-#ifdef DEBUG
+bool
+log_debug_enabled(void)
+{
+ return config_get_log_level() == LOG_DEBUG;
+}
void
pr_debug(const char *format, ...)
PR_SIMPLE(LOG_DEBUG);
}
-#endif
-
void
pr_info(const char *format, ...)
{
#define SRC_LOG_H_
#include <sys/cdefs.h>
+#include <stdbool.h>
#include "incidence/incidence.h"
/*
/* Only call this group of functions when you know there's only one thread. */
void log_setup(void);
-void log_disable_std(void);
-void log_disable_syslog(void);
+void log_start(void);
void log_teardown(void);
* error stack) cannot exceed 512 bytes at present.
*/
-#ifdef DEBUG
-void pr_debug(const char *, ...) CHECK_FORMAT(1, 2);
-#else
-#define pr_debug(...) do {} while (0)
-#endif
+/* Check if debug is enabled, useful to avoid boilerplate code */
+bool log_debug_enabled(void);
+/* Debug messages, useful for devs or to track a specific problem */
+void pr_debug(const char *, ...) CHECK_FORMAT(1, 2);
/* Non-errors deemed useful to the user. */
void pr_info(const char *, ...) CHECK_FORMAT(1, 2);
/* Issues that did not trigger RPKI object rejection. */
if (error)
return error;
- switch (config_get_mode()) {
- case SERVER:
- pr_info("Server mode configured; disabling logging on standard streams.");
- pr_info("(Logs will be sent to syslog only.)");
- log_disable_std();
- break;
- case STANDALONE:
- pr_info("Standalone mode configured; disabling logging on syslog.");
- pr_info("(Logs will be sent to the standard streams only.)");
- log_disable_syslog();
- break;
- }
-
error = nid_init();
if (error)
goto revert_config;
static void
debug_serial_number(BIGNUM *number)
{
-#ifdef DEBUG
char *number_str;
number_str = BN_bn2dec(number);
pr_debug("serial Number: %s", number_str);
free(number_str);
-#endif
}
static int
if (number == NULL)
return crypto_err("Could not parse certificate serial number");
- debug_serial_number(number);
+ if (log_debug_enabled())
+ debug_serial_number(number);
error = x509stack_store_serial(validation_certstack(state), number);
if (error)
if (total_parents >= config_get_max_cert_depth())
return pr_err("Certificate chain maximum depth exceeded.");
-#ifdef DEBUG
+ /* Debug cert type */
if (IS_TA)
pr_debug("TA Certificate '%s' {",
uri_get_printable(cert_uri));
else
pr_debug("Certificate '%s' {",
uri_get_printable(cert_uri));
-#endif
+
fnstack_push_uri(cert_uri);
memset(&refs, 0, sizeof(refs));
goto revert_cert;
type = get_certificate_type(cert, IS_TA);
-#ifdef DEBUG
+
+ /* Debug cert type */
switch(type) {
case TA:
break;
pr_debug("Type: unexpected, validated as CA");
break;
}
-#endif
+
error = certificate_validate_rfc6487(cert, type);
if (error)
goto revert_cert;
static void
debug_revoked(ASN1_INTEGER const *serial_int)
{
-#ifdef DEBUG
BIGNUM *serial_bn;
char *serial_str;
free(serial_str);
end: BN_free(serial_bn);
-#endif
}
static int
i + 1);
}
- debug_revoked(serial_int);
+ if (log_debug_enabled())
+ debug_revoked(serial_int);
if (X509_REVOKED_get0_revocationDate(revoked) == NULL) {
return pr_err("CRL's revoked entry #%d lacks a revocation date.",
return error;
}
-#ifdef DEBUG
-
void
x509_name_pr_debug(const char *prefix, X509_NAME *name)
{
+ if (!log_debug_enabled())
+ return;
+
struct rfc5280_name *printable;
if (name == NULL) {
pr_debug("%s: %s", prefix, printable->commonName);
x509_name_put(printable);
}
-
-#endif
/* X509_NAME utils */
int validate_issuer_name(char const *, X509_NAME *);
-#ifdef DEBUG
void x509_name_pr_debug(char const *, X509_NAME *);
-#else
-#define x509_name_pr_debug(a, b) /* Nothing */
-#endif
#endif /* SRC_OBJECT_NAME_H_ */
/* No error response because the PDU might have been an error */
return error;
-#ifdef DEBUG
- {
+
+ if (log_debug_enabled()) {
char buffer[INET6_ADDRSTRLEN];
pr_debug("Received a %s PDU from %s.",
pdutype2str(header.pdu_type),
sockaddr2str(client_addr, buffer));
}
-#endif
error = validate_rtr_version(fd, &header, hdr_bytes);
if (error)
static void
pr_debug_prefix4(struct ipv4_prefix_pdu *pdu)
{
-#ifdef DEBUG
char buffer[INET_ADDRSTRLEN];
char const *addr_str;
pr_debug("Encoded prefix %s/%u into a PDU.", addr_str,
pdu->prefix_length);
-#endif
}
static int
len = serialize_ipv4_prefix_pdu(&pdu, data);
if (len != RTRPDU_IPV4_PREFIX_LEN)
pr_crit("Serialized IPv4 Prefix is %zu bytes.", len);
- pr_debug_prefix4(&pdu);
+ if (log_debug_enabled())
+ pr_debug_prefix4(&pdu);
return send_response(fd, pdu.header.pdu_type, data, len);
}
static void
pr_debug_prefix6(struct ipv6_prefix_pdu *pdu)
{
-#ifdef DEBUG
char buffer[INET6_ADDRSTRLEN];
char const *addr_str;
pr_debug("Encoded prefix %s/%u into a PDU.", addr_str,
pdu->prefix_length);
-#endif
}
static int
len = serialize_ipv6_prefix_pdu(&pdu, data);
if (len != RTRPDU_IPV6_PREFIX_LEN)
pr_crit("Serialized IPv6 Prefix is %zu bytes.", len);
- pr_debug_prefix6(&pdu);
+ if (log_debug_enabled())
+ pr_debug_prefix6(&pdu);
return send_response(fd, pdu.header.pdu_type, data, len);
}
return -EINVAL;
}
-#ifdef DEBUG
- {
+ if (log_debug_enabled()) {
char buffer[INET6_ADDRSTRLEN];
pr_debug("Client accepted: %s",
sockaddr2str(&client_addr, buffer));
}
-#endif
/*
* Note: My gut says that errors from now on (even the unknown