"Fossies" - the Fresh Open Source Software Archive 
Member "Pound-3.0.2/src/util.c" (28 Nov 2021, 5501 Bytes) of package /linux/www/Pound-3.0.2.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "util.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
3.0e_vs_3.0.1.
1 /*
2 * Pound - the reverse-proxy load-balancer
3 * Copyright (C) 2002-2020 Apsis GmbH
4 *
5 * This file is part of Pound.
6 *
7 * Pound is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Pound is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/> .
19 *
20 * Contact information:
21 * Apsis GmbH
22 * P.O.Box
23 * 8707 Uetikon am See
24 * Switzerland
25 * EMail: roseg@apsis.ch
26 */
27
28 #include "pound.h"
29
30 #ifdef HAVE_STDARG_H
31 void
32 logmsg(int level, const char *fmt, ...)
33 {
34 char buf[MAXBUF];
35 va_list ap;
36
37 if(level > global.log_level)
38 return;
39 buf[MAXBUF - 1] = '\0';
40 va_start(ap, fmt);
41 vsnprintf(buf, MAXBUF - 1, fmt, ap);
42 va_end(ap);
43 if(global.log_level > 0)
44 fprintf(stderr, "%s\n", buf);
45 else
46 syslog(global.log_facility | LOG_INFO, "%s", buf);
47 return;
48 }
49 #else
50 void
51 logmsg(int level, const char *fmt, va_alist)
52 va_dcl
53 {
54 char buf[MAXBUF];
55 va_list ap;
56 struct tm *t_now, t_res;
57
58 if(level > global.log_level)
59 return;
60 buf[MAXBUF - 1] = '\0';
61 va_start(ap);
62 vsnprintf(buf, MAXBUF - 1, fmt, ap);
63 va_end(ap);
64 if(global.log_level > 0)
65 fprintf(stderr, "%s\n", buf);
66 else
67 syslog(global.log_facility | LOG_INFO, "%s", buf);
68 return;
69 }
70 #endif
71
72 void *
73 thr_resurrect(void *arg)
74 {
75 BACKEND **dead_be, *t_be;
76 int n_be, i, j, flags;
77 struct pollfd *dead_poll;
78 char be_addr[NI_MAXHOST];
79
80 logmsg(1, "Starting resurrector thread %s:%d", __FILE__, __LINE__);
81 for(;;) {
82 sleep(RESURRECT_CYCLE - RESURRECT_TO);
83 logmsg(2, "Resurrect: wake-up %s:%d", __FILE__, __LINE__);
84 for(n_be = 0, i = 0; i < backends_len; i++)
85 if(backends[i].is_dead)
86 n_be++;
87 if(n_be == 0)
88 continue;
89 if((dead_be = calloc(n_be, sizeof(BACKEND *))) == NULL) {
90 logmsg(0, "resurrect: out of memory");
91 continue;
92 }
93 if((dead_poll = calloc(n_be, sizeof(struct pollfd))) == NULL) {
94 free(dead_be);
95 logmsg(0, "resurrect: out of memory");
96 continue;
97 }
98 for(i = 0, j = 0; i < backends_len && j < n_be; i++)
99 if(backends[i].is_dead) {
100 dead_poll[j].fd = socket(backends[i].addr->ai_family, SOCK_STREAM, 0);
101 flags = fcntl(dead_poll[j].fd, F_GETFL, &flags);
102 fcntl(dead_poll[j].fd, F_SETFL, flags | O_NONBLOCK);
103 if(!connect(dead_poll[j].fd, backends[i].addr->ai_addr, backends[i].addr->ai_addrlen)) {
104 logmsg(2, "Resurrect: backend %d immediate connect %s:%d", i, __FILE__, __LINE__);
105 backends[i].is_dead = 0;
106 close(dead_poll[j].fd);
107 continue;
108 }
109 if(errno != EINPROGRESS) {
110 backends[i].is_dead = 1;
111 close(dead_poll[j].fd);
112 continue;
113 }
114 dead_poll[j].events = POLLOUT;
115 dead_be[j++] = &backends[i];
116 }
117 n_be = j;
118 sleep(RESURRECT_TO);
119 logmsg(2, "Resurrect: check backends %s:%d", i, __FILE__, __LINE__);
120 poll(dead_poll, n_be, 1);
121 for(i = 0; i < n_be; i++) {
122 if(dead_poll[i].revents & POLLOUT) {
123 dead_be[i]->is_dead = 0;
124 getnameinfo(dead_be[i]->addr->ai_addr, dead_be[i]->addr->ai_addrlen, be_addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
125 logmsg(0, "Backend %s resurrected", be_addr);
126 }
127 close(dead_poll[i].fd);
128 }
129 free(dead_be);
130 free(dead_poll);
131 }
132 }
133
134 void
135 time_stamp(char *buf)
136 {
137 time_t t_now;
138 struct tm *s_now;
139
140 t_now = time(NULL);
141 s_now = localtime(&t_now);
142 if(s_now == NULL) {
143 *buf = '\0';
144 return;
145 }
146 strftime(buf, MAXBUF, "%c", s_now);
147 return;
148 }
149
150 int
151 do_sni(void *data, mbedtls_ssl_context *ctx, const unsigned char *host_name, size_t host_len)
152 {
153 char *name;
154 int i, j;
155 SNI **sni;
156
157 logmsg(1, "%lX start sni %s:%d", pthread_self(), __FILE__, __LINE__);
158 sni = (SNI **)data;
159 if((name = malloc(host_len + 1)) == NULL) {
160 logmsg(0, "SNI: out of memory!");
161 return 0;
162 }
163 memset(name, '\0', host_len + 1);
164 strncpy(name, host_name, host_len);
165 logmsg(4, "%lX sni for %s %s:%d", pthread_self(), name, __FILE__, __LINE__);
166 for(i = 0; sni[i] != NULL; i++)
167 for(j = 0; j < sni[i]->host_len; j++)
168 if(!regexec(&sni[i]->host[j], name, 0, NULL, REG_ICASE)) {
169 logmsg(2, "%lX: found match at %d %s:%d", pthread_self(), j, __FILE__, __LINE__);
170 return mbedtls_ssl_set_hs_own_cert(ctx, &sni[i]->certificate, &sni[i]->key);
171 }
172 /* if no match found: use the default certificate (from conf, aka the first sni) and let the client figure it out */
173 logmsg(2, "%lX %s: no match found %s:%d", pthread_self(), name, __FILE__, __LINE__);
174 return 0;
175 }