Support audit
This commit is contained in:
@@ -21,6 +21,12 @@ cache-size 512
|
|||||||
# prefetch-domain [yes|no]
|
# prefetch-domain [yes|no]
|
||||||
# prefetch-domain yes
|
# prefetch-domain yes
|
||||||
|
|
||||||
|
# List of hosts that supply bogus NX domain results
|
||||||
|
# bogus-nxdomain [ip]
|
||||||
|
|
||||||
|
# force AAAA query return SO
|
||||||
|
# force-AAAA-SOA [yes|no]
|
||||||
|
|
||||||
# ttl for all resource record
|
# ttl for all resource record
|
||||||
# rr-ttl: ttl for all record
|
# rr-ttl: ttl for all record
|
||||||
# rr-ttl-min: minimum ttl for resource record
|
# rr-ttl-min: minimum ttl for resource record
|
||||||
@@ -31,13 +37,22 @@ cache-size 512
|
|||||||
# rr-ttl-max 86400
|
# rr-ttl-max 86400
|
||||||
|
|
||||||
# set log level
|
# set log level
|
||||||
# log-level [level], level=error, warn, info, debug
|
# log-level: [level], level=error, warn, info, debug
|
||||||
# log-size k,m,g
|
# log-file: file path of log file.
|
||||||
|
# log-size: size of each log file, support k,m,g
|
||||||
|
# log-num: number of logs
|
||||||
log-level error
|
log-level error
|
||||||
# log-file /var/log/smartdns.log
|
# log-file /var/log/smartdns.log
|
||||||
# log-size 128k
|
# log-size 128k
|
||||||
# log-num 2
|
# log-num 2
|
||||||
|
|
||||||
|
# dns audit
|
||||||
|
# audit-enable: enable or disable audit [yes|no]
|
||||||
|
# audit-size size of each audit file, support k,m,g
|
||||||
|
# audit-file /var/log/smartdns-audit.log
|
||||||
|
# audit-size 128k
|
||||||
|
# audit-num 2
|
||||||
|
|
||||||
# remote udp dns server list
|
# remote udp dns server list
|
||||||
# server [IP]:[PORT], default port is 53
|
# server [IP]:[PORT], default port is 53
|
||||||
# server 8.8.8.8
|
# server 8.8.8.8
|
||||||
@@ -54,6 +69,3 @@ log-level error
|
|||||||
# specific address to domain
|
# specific address to domain
|
||||||
# address /domain/ip
|
# address /domain/ip
|
||||||
# address /www.example.com/1.2.3.4
|
# address /www.example.com/1.2.3.4
|
||||||
|
|
||||||
# List of hosts that supply bogus NX domain results
|
|
||||||
# bogus-nxdomain [ip]
|
|
||||||
|
|||||||
64
src/conf.c
64
src/conf.c
@@ -24,6 +24,10 @@ int dns_conf_log_level = TLOG_ERROR;
|
|||||||
char dns_conf_log_file[DNS_MAX_PATH];
|
char dns_conf_log_file[DNS_MAX_PATH];
|
||||||
int dns_conf_log_size = 1024 * 1024;
|
int dns_conf_log_size = 1024 * 1024;
|
||||||
int dns_conf_log_num = 8;
|
int dns_conf_log_num = 8;
|
||||||
|
int dns_conf_audit_enable;
|
||||||
|
char dns_conf_audit_file[DNS_MAX_PATH];
|
||||||
|
int dns_conf_audit_size = 1024 * 1024;
|
||||||
|
int dns_conf_audit_num = 2;
|
||||||
|
|
||||||
art_tree dns_conf_address;
|
art_tree dns_conf_address;
|
||||||
int dns_conf_rr_ttl;
|
int dns_conf_rr_ttl;
|
||||||
@@ -299,6 +303,62 @@ int config_log_num(char *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_audit_enable(char *value)
|
||||||
|
{
|
||||||
|
/* read dns cache size */
|
||||||
|
if (strncmp("yes", value, sizeof("yes")) == 0 || strncmp("YES", value, sizeof("YES")) == 0) {
|
||||||
|
dns_conf_audit_enable = 1;
|
||||||
|
} else if (strncmp("no", value, sizeof("no")) == 0 || strncmp("NO", value, sizeof("NO")) == 0) {
|
||||||
|
dns_conf_audit_enable = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_audit_file(char *value)
|
||||||
|
{
|
||||||
|
/* read dns cache size */
|
||||||
|
strncpy(dns_conf_audit_file, value, DNS_MAX_PATH);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_audit_size(char *value)
|
||||||
|
{
|
||||||
|
/* read dns cache size */
|
||||||
|
int base = 1;
|
||||||
|
|
||||||
|
if (strstr(value, "k") || strstr(value, "K")) {
|
||||||
|
base = 1024;
|
||||||
|
} else if (strstr(value, "m") || strstr(value, "M")) {
|
||||||
|
base = 1024 * 1024;
|
||||||
|
} else if (strstr(value, "g") || strstr(value, "G")) {
|
||||||
|
base = 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = atoi(value);
|
||||||
|
if (size < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_conf_audit_size = size * base;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_audit_num(char *value)
|
||||||
|
{
|
||||||
|
/* read dns cache size */
|
||||||
|
int num = atoi(value);
|
||||||
|
if (num < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_conf_audit_num = num;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_rr_ttl(char *value)
|
int config_rr_ttl(char *value)
|
||||||
{
|
{
|
||||||
/* read dns cache size */
|
/* read dns cache size */
|
||||||
@@ -477,6 +537,10 @@ struct config_item config_item[] = {
|
|||||||
{"log-file", config_log_file},
|
{"log-file", config_log_file},
|
||||||
{"log-size", config_log_size},
|
{"log-size", config_log_size},
|
||||||
{"log-num", config_log_num},
|
{"log-num", config_log_num},
|
||||||
|
{"audit-enable", config_audit_enable},
|
||||||
|
{"audit-file", config_audit_file},
|
||||||
|
{"audit-size", config_audit_size},
|
||||||
|
{"audit-num", config_audit_num},
|
||||||
{"rr-ttl", config_rr_ttl},
|
{"rr-ttl", config_rr_ttl},
|
||||||
{"rr-ttl-min", config_rr_ttl_min},
|
{"rr-ttl-min", config_rr_ttl_min},
|
||||||
{"rr-ttl-max", config_rr_ttl_max},
|
{"rr-ttl-max", config_rr_ttl_max},
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
#define DEFAULT_DNS_PORT 53
|
#define DEFAULT_DNS_PORT 53
|
||||||
#define DEFAULT_DNS_TLS_PORT 853
|
#define DEFAULT_DNS_TLS_PORT 853
|
||||||
#define DNS_MAX_CONF_CNAME_LEN 128
|
#define DNS_MAX_CONF_CNAME_LEN 128
|
||||||
|
#define SMARTDNS_CONF_FILE "/etc/smartdns/smartdns.conf"
|
||||||
|
#define SMARTDNS_LOG_FILE "/var/log/smartdns.log"
|
||||||
|
#define SMARTDNS_AUDIT_FILE "/var/log/smartdns-audit.log"
|
||||||
|
|
||||||
struct dns_servers {
|
struct dns_servers {
|
||||||
char server[DNS_MAX_IPLEN];
|
char server[DNS_MAX_IPLEN];
|
||||||
@@ -58,6 +61,11 @@ extern char dns_conf_log_file[DNS_MAX_PATH];
|
|||||||
extern int dns_conf_log_size;
|
extern int dns_conf_log_size;
|
||||||
extern int dns_conf_log_num;
|
extern int dns_conf_log_num;
|
||||||
|
|
||||||
|
extern int dns_conf_audit_enable;
|
||||||
|
extern char dns_conf_audit_file[DNS_MAX_PATH];
|
||||||
|
extern int dns_conf_audit_size;
|
||||||
|
extern int dns_conf_audit_num;
|
||||||
|
|
||||||
extern char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
|
extern char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
|
||||||
extern art_tree dns_conf_address;
|
extern art_tree dns_conf_address;
|
||||||
|
|
||||||
|
|||||||
@@ -1079,7 +1079,7 @@ static int _dns_client_socket_recv(SSL *ssl, void *buf, int num)
|
|||||||
break;
|
break;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
if (errno != ECONNRESET) {
|
if (errno != ECONNRESET) {
|
||||||
tlog(TLOG_ERROR, "SSL syscall failed, %s ", strerror(errno));
|
tlog(TLOG_INFO, "SSL syscall failed, %s ", strerror(errno));
|
||||||
}
|
}
|
||||||
ret = -1;
|
ret = -1;
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -133,12 +133,44 @@ struct dns_request {
|
|||||||
|
|
||||||
static struct dns_server server;
|
static struct dns_server server;
|
||||||
|
|
||||||
|
static tlog_log *dns_audit;
|
||||||
|
|
||||||
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
|
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
|
||||||
{
|
{
|
||||||
tlog(TLOG_ERROR, "forward request.\n");
|
tlog(TLOG_ERROR, "forward request.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _dns_server_audit_log(struct dns_request *request)
|
||||||
|
{
|
||||||
|
char req_host[MAX_IP_LEN];
|
||||||
|
char req_result[MAX_IP_LEN];
|
||||||
|
char req_time[MAX_IP_LEN];
|
||||||
|
struct tlog_time tm;
|
||||||
|
|
||||||
|
if (dns_audit == NULL || !dns_conf_audit_enable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->qtype == DNS_T_AAAA) {
|
||||||
|
snprintf(req_result, sizeof(req_result), "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||||
|
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
|
||||||
|
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
|
||||||
|
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
|
||||||
|
} else if (request->qtype == DNS_T_A) {
|
||||||
|
snprintf(req_result, sizeof(req_result), "%d.%d.%d.%d", request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2],
|
||||||
|
request->ipv4_addr[3]);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gethost_by_addr(req_host, &request->addr, request->addr_len);
|
||||||
|
tlog_localtime(&tm);
|
||||||
|
|
||||||
|
snprintf(req_time, sizeof(req_time), "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d,%.3d]", tm.year, tm.mon, tm.mday, tm.hour, tm.min, tm.sec, tm.usec / 1000);
|
||||||
|
|
||||||
|
tlog_printf(dns_audit, "%s %s query %s, type %d, result %s\n", req_time, req_host, request->domain, request->qtype, req_result);
|
||||||
|
}
|
||||||
|
|
||||||
static int _dns_recv_addr(struct dns_request *request, struct sockaddr_storage *from, socklen_t from_len)
|
static int _dns_recv_addr(struct dns_request *request, struct sockaddr_storage *from, socklen_t from_len)
|
||||||
{
|
{
|
||||||
switch (from->ss_family) {
|
switch (from->ss_family) {
|
||||||
@@ -235,6 +267,8 @@ static int _dns_reply(struct dns_request *request)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int encode_len = 0;
|
int encode_len = 0;
|
||||||
|
|
||||||
|
_dns_server_audit_log(request);
|
||||||
|
|
||||||
memset(&head, 0, sizeof(head));
|
memset(&head, 0, sizeof(head));
|
||||||
head.id = request->id;
|
head.id = request->id;
|
||||||
head.qr = DNS_QR_ANSWER;
|
head.qr = DNS_QR_ANSWER;
|
||||||
@@ -1332,8 +1366,7 @@ int dns_server_socket(void)
|
|||||||
|
|
||||||
fd = socket(gai->ai_family, gai->ai_socktype, gai->ai_protocol);
|
fd = socket(gai->ai_family, gai->ai_socktype, gai->ai_protocol);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
tlog(TLOG_ERROR, "create socket failed, family = %d, type = %d, proto = %d, %s\n",
|
tlog(TLOG_ERROR, "create socket failed, family = %d, type = %d, proto = %d, %s\n", gai->ai_family, gai->ai_socktype, gai->ai_protocol, strerror(errno));
|
||||||
gai->ai_family, gai->ai_socktype, gai->ai_protocol, strerror(errno));
|
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1362,6 +1395,25 @@ errout:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _dns_server_audit_init(void)
|
||||||
|
{
|
||||||
|
char *audit_file = SMARTDNS_AUDIT_FILE;
|
||||||
|
if (dns_conf_audit_enable == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dns_conf_audit_file[0] != 0) {
|
||||||
|
audit_file = dns_conf_audit_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_audit = tlog_open(audit_file, dns_conf_audit_size, dns_conf_audit_num, 1, 0, 0);
|
||||||
|
if (dns_audit == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int dns_server_init(void)
|
int dns_server_init(void)
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
@@ -1377,6 +1429,11 @@ int dns_server_init(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_dns_server_audit_init() != 0) {
|
||||||
|
tlog(TLOG_ERROR, "init audit failed.");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&server, 0, sizeof(server));
|
memset(&server, 0, sizeof(server));
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,6 @@
|
|||||||
#define RESOLVE_FILE "/etc/resolv.conf"
|
#define RESOLVE_FILE "/etc/resolv.conf"
|
||||||
#define MAX_LINE_LEN 1024
|
#define MAX_LINE_LEN 1024
|
||||||
#define MAX_KEY_LEN 64
|
#define MAX_KEY_LEN 64
|
||||||
#define SMARTDNS_CONF_FILE "/etc/smartdns/smartdns.conf"
|
|
||||||
#define SMARTDNS_LOG_PATH "/var/log"
|
|
||||||
#define SMARTDNS_LOG_FILE "smartdns.log"
|
|
||||||
#define SMARTDNS_PID_FILE "/var/run/smartdns.pid"
|
#define SMARTDNS_PID_FILE "/var/run/smartdns.pid"
|
||||||
#define TMP_BUFF_LEN_32 32
|
#define TMP_BUFF_LEN_32 32
|
||||||
|
|
||||||
@@ -197,21 +194,13 @@ int smartdns_destroy_ssl(void)
|
|||||||
int smartdns_init(void)
|
int smartdns_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char logdir[DNS_MAX_PATH];
|
char *logfile = SMARTDNS_LOG_FILE;
|
||||||
char logname[DNS_MAX_PATH];
|
|
||||||
|
|
||||||
if (dns_conf_log_file[0] != 0) {
|
if (dns_conf_log_file[0] != 0) {
|
||||||
char dns_log_file[DNS_MAX_PATH];
|
logfile = dns_conf_log_file;
|
||||||
strncpy(dns_log_file, dns_conf_log_file, DNS_MAX_PATH);
|
|
||||||
strncpy(logdir, dirname(dns_log_file), DNS_MAX_PATH);
|
|
||||||
strncpy(dns_log_file, dns_conf_log_file, DNS_MAX_PATH);
|
|
||||||
strncpy(logname, basename(dns_log_file), DNS_MAX_PATH);
|
|
||||||
} else {
|
|
||||||
strncpy(logdir, SMARTDNS_LOG_PATH, DNS_MAX_PATH);
|
|
||||||
strncpy(logname, SMARTDNS_LOG_FILE, DNS_MAX_PATH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tlog_init(logdir, logname, dns_conf_log_size, dns_conf_log_num, 1, 0, 0);
|
ret = tlog_init(logfile, dns_conf_log_size, dns_conf_log_num, 1, 0, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
tlog(TLOG_ERROR, "start tlog failed.\n");
|
tlog(TLOG_ERROR, "start tlog failed.\n");
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|||||||
739
src/tlog.c
739
src/tlog.c
File diff suppressed because it is too large
Load Diff
55
src/tlog.h
55
src/tlog.h
@@ -41,7 +41,7 @@ struct tlog_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function:Print log
|
Function: Print log
|
||||||
level: Current log Levels
|
level: Current log Levels
|
||||||
format: Log formats
|
format: Log formats
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +50,8 @@ format: Log formats
|
|||||||
#endif
|
#endif
|
||||||
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, 0, format, ##__VA_ARGS__)
|
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, 0, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
extern int tlog_ext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, ...) __attribute__((format(printf, 6, 7)));
|
extern int tlog_ext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, ...)
|
||||||
|
__attribute__((format(printf, 6, 7)));
|
||||||
extern int tlog_vext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, va_list ap);
|
extern int tlog_vext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, va_list ap);
|
||||||
|
|
||||||
/* set log level */
|
/* set log level */
|
||||||
@@ -59,10 +60,12 @@ extern int tlog_setlevel(tlog_level level);
|
|||||||
/* enalbe log to screen */
|
/* enalbe log to screen */
|
||||||
extern void tlog_setlogscreen(int enable);
|
extern void tlog_setlogscreen(int enable);
|
||||||
|
|
||||||
|
/* enalbe early log to screen */
|
||||||
|
extern void tlog_set_early_printf(int enable);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function:Initialize log module
|
Function: Initialize log module
|
||||||
logdir: Log Output path.
|
logfile: log file.
|
||||||
logname: Log name.
|
|
||||||
maxlogsize: The maximum size of a single log file.
|
maxlogsize: The maximum size of a single log file.
|
||||||
maxlogcount: Number of archived logs.
|
maxlogcount: Number of archived logs.
|
||||||
block: Blocked if buffer is not sufficient.
|
block: Blocked if buffer is not sufficient.
|
||||||
@@ -70,8 +73,9 @@ buffsize: Buffer size, zero for default (128K)
|
|||||||
multiwrite: enable multi process write mode.
|
multiwrite: enable multi process write mode.
|
||||||
NOTICE: maxlogsize in all prcesses must be same when enable this mode.
|
NOTICE: maxlogsize in all prcesses must be same when enable this mode.
|
||||||
*/
|
*/
|
||||||
extern int tlog_init(const char *logdir, const char *logname, int maxlogsize, int maxlogcount, int block, int buffsize, int multiwrite);
|
extern int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int block, int buffsize, int multiwrite);
|
||||||
|
|
||||||
|
/* flush pending log message, and exit tlog */
|
||||||
extern void tlog_exit(void);
|
extern void tlog_exit(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -85,6 +89,45 @@ read _tlog_format for example.
|
|||||||
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_info *info, void *userptr, const char *format, va_list ap);
|
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_info *info, void *userptr, const char *format, va_list ap);
|
||||||
extern int tlog_reg_format_func(tlog_format_func func);
|
extern int tlog_reg_format_func(tlog_format_func func);
|
||||||
|
|
||||||
|
struct tlog_log;
|
||||||
|
typedef struct tlog_log tlog_log;
|
||||||
|
/*
|
||||||
|
Function: open a new log stream, handler should close by tlog_close
|
||||||
|
logfile: log file.
|
||||||
|
maxlogsize: The maximum size of a single log file.
|
||||||
|
maxlogcount: Number of archived logs.
|
||||||
|
block: Blocked if buffer is not sufficient.
|
||||||
|
buffsize: Buffer size, zero for default (128K)
|
||||||
|
multiwrite: enable multi process write mode.
|
||||||
|
NOTICE: maxlogsize in all prcesses must be same when enable this mode.
|
||||||
|
|
||||||
|
return: log stream handler.
|
||||||
|
*/
|
||||||
|
extern tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int block, int buffsize, int multiwrite);
|
||||||
|
|
||||||
|
extern void tlog_close(tlog_log *log);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: Print log to log stream
|
||||||
|
log: log stream
|
||||||
|
format: Log formats
|
||||||
|
*/
|
||||||
|
extern int tlog_printf(tlog_log *log, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: Print log to log stream with ap
|
||||||
|
log: log stream
|
||||||
|
format: Log formats
|
||||||
|
va_list: args list
|
||||||
|
*/
|
||||||
|
extern int tlog_vprintf(tlog_log *log, const char *format, va_list ap);
|
||||||
|
|
||||||
|
/* enalbe log to screen */
|
||||||
|
extern void tlog_logscreen(tlog_log *log, int enable);
|
||||||
|
|
||||||
|
/* get local time */
|
||||||
|
extern int tlog_localtime(struct tlog_time *tm);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus */
|
#endif /*__cplusplus */
|
||||||
|
|||||||
Reference in New Issue
Block a user