0 /* See LICENSE file for copyright and license details. */
1 #include <time.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdarg.h>
5 #include <pthread.h>
6 #include <string.h>
7 #include <tls.h>
8 #include "util.h"
9 #include "server.h"
10 #include "log.h"
11 #include "conf.h"
12 #include "murmur3.h"
13
14 pthread_mutex_t printf_mutex = PTHREAD_MUTEX_INITIALIZER;
15
16 enum {
17 LOG_INFO,
18 LOG_WARNING,
19 LOG_ERROR,
20 LOG_DEBUG
21 };
22
23 char* log_type[] = {
24 "INFO",
25 "WARNING",
26 "ERROR",
27 "DEBUG"
28 };
29
30 void _log_(int type, int nl, const char *format, va_list args) {
31
32 char data[1024];
33 time_t t;
34 struct tm* now;
35
36 if ((unsigned)type > SIZEOF(log_type))
37 return;
38
39 t = time(0);
40 now = localtime(&t);
41
42 pthread_mutex_lock(&printf_mutex);
43 snprintf(data, sizeof(data),
44 "[%04d/%02d/%02d %02d:%02d:%02d][%s]",
45 now->tm_year + 1900, now->tm_mon + 1, now->tm_mday,
46 now->tm_hour, now->tm_min, now->tm_sec,
47 log_type[type]);
48 printf(nl ? "\r%s " : "\r%s", data);
49 vprintf(format, args);
50 if (nl) {
51 printf("\n");
52 fflush(stdout);
53 pthread_mutex_unlock(&printf_mutex);
54 }
55 }
56
57 void _log__(int type, int nl, const char *format, ...) {
58 va_list args;
59 va_start(args, format);
60 _log_(type, nl, format, args);
61 va_end(args);
62 }
63
64 void _log_r_(struct client* c, int type, const char *format, va_list args) {
65
66 int provided = (c->start && c->ctx) ?
67 tls_peer_cert_provided(c->ctx) : 0;
68 int hash = 0;
69 if (provided) {
70 const char* h = tls_peer_cert_hash(c->ctx);
71 if (h) {
72 int len = strlen(h);
73 hash = murmur3(h, len, len);
74 }
75 }
76 _log__(type, 0, "[%d.%d.%d.%d][%c%08X] ",
77 (c->addr.sin_addr.s_addr & 0x000000FF),
78 (c->addr.sin_addr.s_addr & 0x0000FF00) >> 8,
79 (c->addr.sin_addr.s_addr & 0x00FF0000) >> 16,
80 (c->addr.sin_addr.s_addr & 0xFF000000) >> 24,
81 provided ? 'C' : 'X',
82 provided ? hash : ((c->tid << 20) + c->id));
83
84 vprintf(format, args);
85 printf("\n");
86 fflush(stdout);
87 pthread_mutex_unlock(&printf_mutex);
88 }
89
90 void log_info(const char *format, ...) {
91 va_list args;
92 va_start(args, format);
93 _log_(LOG_INFO, 1, format, args);
94 va_end(args);
95 }
96
97 void log_warning(const char *format, ...) {
98 va_list args;
99 va_start(args, format);
100 _log_(LOG_WARNING, 1, format, args);
101 va_end(args);
102 }
103
104 void log_error(const char *format, ...) {
105 va_list args;
106 va_start(args, format);
107 _log_(LOG_ERROR, 1, format, args);
108 va_end(args);
109 }
110
111 void log_debug(const char *format, ...) {
112 va_list args;
113 va_start(args, format);
114 _log_(LOG_DEBUG, 1, format, args);
115 va_end(args);
116 }
117
118 void log_info_r(struct client* c, const char *format, ...) {
119 va_list args;
120 va_start(args, format);
121 _log_r_(c, LOG_INFO, format, args);
122 va_end(args);
123 }
124
125 void log_error_r(struct client* c, const char *format, ...) {
126 va_list args;
127 va_start(args, format);
128 _log_r_(c, LOG_ERROR, format, args);
129 va_end(args);
130 }
131
132 void log_debug_r(struct client* c, const char *format, ...) {
133 va_list args;
134 va_start(args, format);
135 _log_r_(c, LOG_DEBUG, format, args);
136 va_end(args);
137 }
138