Blame


1 6b5c4000 2026-03-02 rsadowski /* $OpenBSD: check_tcp.c,v 1.62 2026/03/02 19:28:01 rsadowski Exp $ */
2 41042ecc 2006-12-16 reyk
3 41042ecc 2006-12-16 reyk /*
4 8c736326 2007-09-28 pyr * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
5 41042ecc 2006-12-16 reyk *
6 41042ecc 2006-12-16 reyk * Permission to use, copy, modify, and distribute this software for any
7 41042ecc 2006-12-16 reyk * purpose with or without fee is hereby granted, provided that the above
8 41042ecc 2006-12-16 reyk * copyright notice and this permission notice appear in all copies.
9 41042ecc 2006-12-16 reyk *
10 41042ecc 2006-12-16 reyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 41042ecc 2006-12-16 reyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 41042ecc 2006-12-16 reyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 41042ecc 2006-12-16 reyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 41042ecc 2006-12-16 reyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 41042ecc 2006-12-16 reyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 41042ecc 2006-12-16 reyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 41042ecc 2006-12-16 reyk */
18 41042ecc 2006-12-16 reyk
19 d93c36af 2015-01-22 reyk #include <sys/types.h>
20 d93c36af 2015-01-22 reyk #include <sys/time.h>
21 41042ecc 2006-12-16 reyk #include <sys/socket.h>
22 d4babff5 2007-02-03 reyk
23 e1f9d231 2007-11-24 reyk #include <netinet/in.h>
24 d4babff5 2007-02-03 reyk
25 41042ecc 2006-12-16 reyk #include <limits.h>
26 41042ecc 2006-12-16 reyk #include <event.h>
27 41042ecc 2006-12-16 reyk #include <fcntl.h>
28 41042ecc 2006-12-16 reyk #include <unistd.h>
29 41042ecc 2006-12-16 reyk #include <string.h>
30 ae98db81 2006-12-25 reyk #include <stdlib.h>
31 41042ecc 2006-12-16 reyk #include <errno.h>
32 d4babff5 2007-02-03 reyk #include <fnmatch.h>
33 d4babff5 2007-02-03 reyk #include <sha1.h>
34 d93c36af 2015-01-22 reyk #include <imsg.h>
35 41042ecc 2006-12-16 reyk
36 6d0767ae 2007-12-07 reyk #include "relayd.h"
37 6b5c4000 2026-03-02 rsadowski #include "log.h"
38 41042ecc 2006-12-16 reyk
39 ae98db81 2006-12-25 reyk void tcp_write(int, short, void *);
40 591e6ab5 2011-05-19 reyk void tcp_host_up(struct ctl_tcp_event *);
41 591e6ab5 2011-05-19 reyk void tcp_close(struct ctl_tcp_event *, int);
42 cbeeaf47 2007-01-12 pyr void tcp_send_req(int, short, void *);
43 cbeeaf47 2007-01-12 pyr void tcp_read_buf(int, short, void *);
44 41042ecc 2006-12-16 reyk
45 ed8a90c8 2007-02-06 pyr int check_http_code(struct ctl_tcp_event *);
46 ed8a90c8 2007-02-06 pyr int check_http_digest(struct ctl_tcp_event *);
47 ed8a90c8 2007-02-06 pyr int check_send_expect(struct ctl_tcp_event *);
48 ed8a90c8 2007-02-06 pyr
49 ae98db81 2006-12-25 reyk void
50 ae98db81 2006-12-25 reyk check_tcp(struct ctl_tcp_event *cte)
51 41042ecc 2006-12-16 reyk {
52 ae98db81 2006-12-25 reyk int s;
53 ae98db81 2006-12-25 reyk socklen_t len;
54 ae98db81 2006-12-25 reyk struct timeval tv;
55 ae98db81 2006-12-25 reyk struct linger lng;
56 ea47f1c4 2010-11-30 reyk int he = HCE_TCP_SOCKET_OPTION;
57 41042ecc 2006-12-16 reyk
58 87178699 2007-05-27 pyr switch (cte->host->conf.ss.ss_family) {
59 41042ecc 2006-12-16 reyk case AF_INET:
60 87178699 2007-05-27 pyr ((struct sockaddr_in *)&cte->host->conf.ss)->sin_port =
61 87178699 2007-05-27 pyr cte->table->conf.port;
62 41042ecc 2006-12-16 reyk break;
63 41042ecc 2006-12-16 reyk case AF_INET6:
64 87178699 2007-05-27 pyr ((struct sockaddr_in6 *)&cte->host->conf.ss)->sin6_port =
65 87178699 2007-05-27 pyr cte->table->conf.port;
66 41042ecc 2006-12-16 reyk break;
67 41042ecc 2006-12-16 reyk }
68 41042ecc 2006-12-16 reyk
69 87178699 2007-05-27 pyr len = ((struct sockaddr *)&cte->host->conf.ss)->sa_len;
70 41042ecc 2006-12-16 reyk
71 24dcf092 2015-11-28 reyk if ((s = socket(cte->host->conf.ss.ss_family,
72 24dcf092 2015-11-28 reyk SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) {
73 ea47f1c4 2010-11-30 reyk if (errno == EMFILE || errno == ENFILE)
74 ea47f1c4 2010-11-30 reyk he = HCE_TCP_SOCKET_LIMIT;
75 ea47f1c4 2010-11-30 reyk else
76 ea47f1c4 2010-11-30 reyk he = HCE_TCP_SOCKET_ERROR;
77 ae98db81 2006-12-25 reyk goto bad;
78 ea47f1c4 2010-11-30 reyk }
79 41042ecc 2006-12-16 reyk
80 4de4b10b 2011-06-17 jsg cte->s = s;
81 4de4b10b 2011-06-17 jsg
82 ae98db81 2006-12-25 reyk bzero(&lng, sizeof(lng));
83 ae98db81 2006-12-25 reyk if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
84 ae98db81 2006-12-25 reyk goto bad;
85 ae98db81 2006-12-25 reyk
86 0d3a002e 2017-07-04 benno if (cte->host->conf.ttl > 0)
87 0d3a002e 2017-07-04 benno switch (cte->host->conf.ss.ss_family) {
88 0d3a002e 2017-07-04 benno case AF_INET:
89 0d3a002e 2017-07-04 benno if (setsockopt(s, IPPROTO_IP, IP_TTL,
90 0d3a002e 2017-07-04 benno &cte->host->conf.ttl, sizeof(int)) == -1)
91 0d3a002e 2017-07-04 benno goto bad;
92 0d3a002e 2017-07-04 benno break;
93 0d3a002e 2017-07-04 benno case AF_INET6:
94 0d3a002e 2017-07-04 benno if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
95 0d3a002e 2017-07-04 benno &cte->host->conf.ttl, sizeof(int)) == -1)
96 0d3a002e 2017-07-04 benno goto bad;
97 0d3a002e 2017-07-04 benno break;
98 0d3a002e 2017-07-04 benno }
99 c3895d83 2009-08-07 reyk
100 87178699 2007-05-27 pyr bcopy(&cte->table->conf.timeout, &tv, sizeof(tv));
101 87178699 2007-05-27 pyr if (connect(s, (struct sockaddr *)&cte->host->conf.ss, len) == -1) {
102 b2665266 2008-12-05 reyk if (errno != EINPROGRESS) {
103 b2665266 2008-12-05 reyk he = HCE_TCP_CONNECT_FAIL;
104 ae98db81 2006-12-25 reyk goto bad;
105 b2665266 2008-12-05 reyk }
106 0859a257 2007-01-30 pyr }
107 0859a257 2007-01-30 pyr
108 63639854 2009-06-04 reyk cte->buf = NULL;
109 0859a257 2007-01-30 pyr cte->host->up = HOST_UP;
110 b140f974 2010-02-18 jsg event_del(&cte->ev);
111 816ddb53 2007-01-11 reyk event_set(&cte->ev, s, EV_TIMEOUT|EV_WRITE, tcp_write, cte);
112 816ddb53 2007-01-11 reyk event_add(&cte->ev, &tv);
113 ae98db81 2006-12-25 reyk return;
114 816ddb53 2007-01-11 reyk
115 ae98db81 2006-12-25 reyk bad:
116 591e6ab5 2011-05-19 reyk tcp_close(cte, HOST_DOWN);
117 b2665266 2008-12-05 reyk hce_notify_done(cte->host, he);
118 ae98db81 2006-12-25 reyk }
119 41042ecc 2006-12-16 reyk
120 ae98db81 2006-12-25 reyk void
121 ae98db81 2006-12-25 reyk tcp_write(int s, short event, void *arg)
122 ae98db81 2006-12-25 reyk {
123 ae98db81 2006-12-25 reyk struct ctl_tcp_event *cte = arg;
124 ae98db81 2006-12-25 reyk int err;
125 ae98db81 2006-12-25 reyk socklen_t len;
126 41042ecc 2006-12-16 reyk
127 ae98db81 2006-12-25 reyk if (event == EV_TIMEOUT) {
128 591e6ab5 2011-05-19 reyk tcp_close(cte, HOST_DOWN);
129 b2665266 2008-12-05 reyk hce_notify_done(cte->host, HCE_TCP_CONNECT_TIMEOUT);
130 a58e0804 2008-03-03 reyk return;
131 ae98db81 2006-12-25 reyk }
132 05982e1a 2007-01-29 pyr
133 a58e0804 2008-03-03 reyk len = sizeof(err);
134 a58e0804 2008-03-03 reyk if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len))
135 09e53fee 2017-05-28 benno fatal("%s: getsockopt", __func__);
136 a58e0804 2008-03-03 reyk if (err != 0) {
137 591e6ab5 2011-05-19 reyk tcp_close(cte, HOST_DOWN);
138 b2665266 2008-12-05 reyk hce_notify_done(cte->host, HCE_TCP_CONNECT_FAIL);
139 a58e0804 2008-03-03 reyk return;
140 ae98db81 2006-12-25 reyk }
141 a58e0804 2008-03-03 reyk
142 a58e0804 2008-03-03 reyk cte->host->up = HOST_UP;
143 591e6ab5 2011-05-19 reyk tcp_host_up(cte);
144 ae98db81 2006-12-25 reyk }
145 ae98db81 2006-12-25 reyk
146 ae98db81 2006-12-25 reyk void
147 591e6ab5 2011-05-19 reyk tcp_close(struct ctl_tcp_event *cte, int status)
148 ae98db81 2006-12-25 reyk {
149 591e6ab5 2011-05-19 reyk close(cte->s);
150 591e6ab5 2011-05-19 reyk cte->s = -1;
151 591e6ab5 2011-05-19 reyk if (status != 0)
152 591e6ab5 2011-05-19 reyk cte->host->up = status;
153 d3d5a154 2015-12-30 benno ibuf_free(cte->buf);
154 d3d5a154 2015-12-30 benno cte->buf = NULL;
155 591e6ab5 2011-05-19 reyk }
156 7c36f315 2007-01-08 reyk
157 591e6ab5 2011-05-19 reyk void
158 591e6ab5 2011-05-19 reyk tcp_host_up(struct ctl_tcp_event *cte)
159 591e6ab5 2011-05-19 reyk {
160 87178699 2007-05-27 pyr switch (cte->table->conf.check) {
161 ae98db81 2006-12-25 reyk case CHECK_TCP:
162 096ff28b 2014-12-12 reyk if (cte->table->conf.flags & F_TLS)
163 05982e1a 2007-01-29 pyr break;
164 591e6ab5 2011-05-19 reyk tcp_close(cte, 0);
165 b2665266 2008-12-05 reyk hce_notify_done(cte->host, HCE_TCP_CONNECT_OK);
166 cbeeaf47 2007-01-12 pyr return;
167 ae98db81 2006-12-25 reyk case CHECK_HTTP_CODE:
168 71ae3402 2015-12-24 benno cte->validate_read = NULL;
169 cbeeaf47 2007-01-12 pyr cte->validate_close = check_http_code;
170 cbeeaf47 2007-01-12 pyr break;
171 ae98db81 2006-12-25 reyk case CHECK_HTTP_DIGEST:
172 dc035ae8 2007-11-19 reyk cte->validate_read = NULL;
173 cbeeaf47 2007-01-12 pyr cte->validate_close = check_http_digest;
174 ae98db81 2006-12-25 reyk break;
175 738b3cc9 2019-09-15 rob case CHECK_BINSEND_EXPECT:
176 7c36f315 2007-01-08 reyk case CHECK_SEND_EXPECT:
177 cbeeaf47 2007-01-12 pyr cte->validate_read = check_send_expect;
178 cbeeaf47 2007-01-12 pyr cte->validate_close = check_send_expect;
179 7c36f315 2007-01-08 reyk break;
180 41042ecc 2006-12-16 reyk }
181 cbeeaf47 2007-01-12 pyr
182 096ff28b 2014-12-12 reyk if (cte->table->conf.flags & F_TLS) {
183 f4a6eef3 2017-05-27 claudio check_tls(cte);
184 05982e1a 2007-01-29 pyr return;
185 05982e1a 2007-01-29 pyr }
186 05982e1a 2007-01-29 pyr
187 738b3cc9 2019-09-15 rob if (cte->table->sendbuf != NULL || cte->table->sendbinbuf != NULL) {
188 591e6ab5 2011-05-19 reyk event_again(&cte->ev, cte->s, EV_TIMEOUT|EV_WRITE, tcp_send_req,
189 87178699 2007-05-27 pyr &cte->tv_start, &cte->table->conf.timeout, cte);
190 cbeeaf47 2007-01-12 pyr return;
191 cbeeaf47 2007-01-12 pyr }
192 cbeeaf47 2007-01-12 pyr
193 fb0e4fa0 2010-05-26 nicm if ((cte->buf = ibuf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
194 09e53fee 2017-05-28 benno fatalx("%s: cannot create dynamic buffer", __func__);
195 591e6ab5 2011-05-19 reyk event_again(&cte->ev, cte->s, EV_TIMEOUT|EV_READ, tcp_read_buf,
196 87178699 2007-05-27 pyr &cte->tv_start, &cte->table->conf.timeout, cte);
197 41042ecc 2006-12-16 reyk }
198 cbeeaf47 2007-01-12 pyr
199 cbeeaf47 2007-01-12 pyr void
200 cbeeaf47 2007-01-12 pyr tcp_send_req(int s, short event, void *arg)
201 cbeeaf47 2007-01-12 pyr {
202 cbeeaf47 2007-01-12 pyr struct ctl_tcp_event *cte = arg;
203 64b0dc5e 2023-06-21 claudio char *req;
204 3e2ddb06 2007-02-22 reyk int bs;
205 3e2ddb06 2007-02-22 reyk int len;
206 cbeeaf47 2007-01-12 pyr
207 cbeeaf47 2007-01-12 pyr if (event == EV_TIMEOUT) {
208 591e6ab5 2011-05-19 reyk tcp_close(cte, HOST_DOWN);
209 b2665266 2008-12-05 reyk hce_notify_done(cte->host, HCE_TCP_WRITE_TIMEOUT);
210 cbeeaf47 2007-01-12 pyr return;
211 cbeeaf47 2007-01-12 pyr }
212 738b3cc9 2019-09-15 rob
213 738b3cc9 2019-09-15 rob if (cte->table->sendbinbuf != NULL) {
214 738b3cc9 2019-09-15 rob len = ibuf_size(cte->table->sendbinbuf);
215 64b0dc5e 2023-06-21 claudio req = ibuf_data(cte->table->sendbinbuf);
216 738b3cc9 2019-09-15 rob log_debug("%s: table %s sending binary", __func__,
217 738b3cc9 2019-09-15 rob cte->table->conf.name);
218 a4719117 2023-07-03 claudio print_hex(req, 0, len);
219 64b0dc5e 2023-06-21 claudio } else {
220 64b0dc5e 2023-06-21 claudio len = strlen(cte->table->sendbuf);
221 64b0dc5e 2023-06-21 claudio req = cte->table->sendbuf;
222 64b0dc5e 2023-06-21 claudio }
223 738b3cc9 2019-09-15 rob
224 cbeeaf47 2007-01-12 pyr do {
225 64b0dc5e 2023-06-21 claudio bs = write(s, req, len);
226 cbeeaf47 2007-01-12 pyr if (bs == -1) {
227 cbeeaf47 2007-01-12 pyr if (errno == EAGAIN || errno == EINTR)
228 cbeeaf47 2007-01-12 pyr goto retry;
229 87300aaf 2014-05-15 reyk log_warn("%s: cannot send request", __func__);
230 591e6ab5 2011-05-19 reyk tcp_close(cte, HOST_DOWN);
231 b2665266 2008-12-05 reyk hce_notify_done(cte->host, HCE_TCP_WRITE_FAIL);
232 cbeeaf47 2007-01-12 pyr return;
233 cbeeaf47 2007-01-12 pyr }
234 64b0dc5e 2023-06-21 claudio req += bs;
235 cbeeaf47 2007-01-12 pyr len -= bs;
236 cbeeaf47 2007-01-12 pyr } while (len > 0);
237 cbeeaf47 2007-01-12 pyr
238 fb0e4fa0 2010-05-26 nicm if ((cte->buf = ibuf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
239 09e53fee 2017-05-28 benno fatalx("%s: cannot create dynamic buffer", __func__);
240 cbeeaf47 2007-01-12 pyr event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
241 87178699 2007-05-27 pyr &cte->tv_start, &cte->table->conf.timeout, cte);
242 cbeeaf47 2007-01-12 pyr return;
243 cbeeaf47 2007-01-12 pyr
244 cbeeaf47 2007-01-12 pyr retry:
245 cbeeaf47 2007-01-12 pyr event_again(&cte->ev, s, EV_TIMEOUT|EV_WRITE, tcp_send_req,
246 87178699 2007-05-27 pyr &cte->tv_start, &cte->table->conf.timeout, cte);
247 cbeeaf47 2007-01-12 pyr }
248 cbeeaf47 2007-01-12 pyr
249 cbeeaf47 2007-01-12 pyr void
250 cbeeaf47 2007-01-12 pyr tcp_read_buf(int s, short event, void *arg)
251 cbeeaf47 2007-01-12 pyr {
252 cbeeaf47 2007-01-12 pyr ssize_t br;
253 cbeeaf47 2007-01-12 pyr char rbuf[SMALL_READ_BUF_SIZE];
254 cbeeaf47 2007-01-12 pyr struct ctl_tcp_event *cte = arg;
255 cbeeaf47 2007-01-12 pyr
256 3e2ddb06 2007-02-22 reyk if (event == EV_TIMEOUT) {
257 d90afa1e 2017-02-09 reyk if (ibuf_size(cte->buf))
258 d90afa1e 2017-02-09 reyk (void)cte->validate_close(cte);
259 5d6b7c18 2018-04-14 benno else {
260 d90afa1e 2017-02-09 reyk cte->host->he = HCE_TCP_READ_TIMEOUT;
261 5d6b7c18 2018-04-14 benno cte->host->up = HOST_DOWN;
262 5d6b7c18 2018-04-14 benno }
263 d90afa1e 2017-02-09 reyk tcp_close(cte, cte->host->up == HOST_UP ? 0 : HOST_DOWN);
264 d90afa1e 2017-02-09 reyk hce_notify_done(cte->host, cte->host->he);
265 cbeeaf47 2007-01-12 pyr return;
266 cbeeaf47 2007-01-12 pyr }
267 cbeeaf47 2007-01-12 pyr
268 cbeeaf47 2007-01-12 pyr bzero(rbuf, sizeof(rbuf));
269 cbeeaf47 2007-01-12 pyr br = read(s, rbuf, sizeof(rbuf) - 1);
270 0859a257 2007-01-30 pyr switch (br) {
271 0859a257 2007-01-30 pyr case -1:
272 cbeeaf47 2007-01-12 pyr if (errno == EAGAIN || errno == EINTR)
273 cbeeaf47 2007-01-12 pyr goto retry;
274 591e6ab5 2011-05-19 reyk tcp_close(cte, HOST_DOWN);
275 b2665266 2008-12-05 reyk hce_notify_done(cte->host, HCE_TCP_READ_FAIL);
276 dc035ae8 2007-11-19 reyk return;
277 0859a257 2007-01-30 pyr case 0:
278 cbeeaf47 2007-01-12 pyr cte->host->up = HOST_DOWN;
279 cbeeaf47 2007-01-12 pyr (void)cte->validate_close(cte);
280 591e6ab5 2011-05-19 reyk tcp_close(cte, 0);
281 b2665266 2008-12-05 reyk hce_notify_done(cte->host, cte->host->he);
282 cbeeaf47 2007-01-12 pyr return;
283 0859a257 2007-01-30 pyr default:
284 fb0e4fa0 2010-05-26 nicm if (ibuf_add(cte->buf, rbuf, br) == -1)
285 09e53fee 2017-05-28 benno fatal("%s: buf_add error", __func__);
286 0859a257 2007-01-30 pyr if (cte->validate_read != NULL) {
287 0859a257 2007-01-30 pyr if (cte->validate_read(cte) != 0)
288 0859a257 2007-01-30 pyr goto retry;
289 591e6ab5 2011-05-19 reyk tcp_close(cte, 0);
290 b2665266 2008-12-05 reyk hce_notify_done(cte->host, cte->host->he);
291 0859a257 2007-01-30 pyr return;
292 0859a257 2007-01-30 pyr }
293 0859a257 2007-01-30 pyr break; /* retry */
294 cbeeaf47 2007-01-12 pyr }
295 cbeeaf47 2007-01-12 pyr retry:
296 cbeeaf47 2007-01-12 pyr event_again(&cte->ev, s, EV_TIMEOUT|EV_READ, tcp_read_buf,
297 87178699 2007-05-27 pyr &cte->tv_start, &cte->table->conf.timeout, cte);
298 cbeeaf47 2007-01-12 pyr }
299 d4babff5 2007-02-03 reyk
300 d4babff5 2007-02-03 reyk int
301 d4babff5 2007-02-03 reyk check_send_expect(struct ctl_tcp_event *cte)
302 d4babff5 2007-02-03 reyk {
303 d4babff5 2007-02-03 reyk u_char *b;
304 d4babff5 2007-02-03 reyk
305 738b3cc9 2019-09-15 rob if (cte->table->conf.check == CHECK_BINSEND_EXPECT) {
306 64b0dc5e 2023-06-21 claudio size_t exlen;
307 64b0dc5e 2023-06-21 claudio
308 64b0dc5e 2023-06-21 claudio exlen = strlen(cte->table->conf.exbuf) / 2;
309 738b3cc9 2019-09-15 rob log_debug("%s: table %s expecting binary",
310 738b3cc9 2019-09-15 rob __func__, cte->table->conf.name);
311 64b0dc5e 2023-06-21 claudio print_hex(cte->table->conf.exbinbuf, 0, exlen);
312 738b3cc9 2019-09-15 rob
313 64b0dc5e 2023-06-21 claudio if (ibuf_size(cte->buf) >= exlen && memcmp(ibuf_data(cte->buf),
314 64b0dc5e 2023-06-21 claudio cte->table->conf.exbinbuf, exlen) == 0) {
315 738b3cc9 2019-09-15 rob cte->host->he = HCE_SEND_EXPECT_OK;
316 738b3cc9 2019-09-15 rob cte->host->up = HOST_UP;
317 738b3cc9 2019-09-15 rob return (0);
318 64b0dc5e 2023-06-21 claudio } else if (ibuf_size(cte->buf) >= exlen) {
319 738b3cc9 2019-09-15 rob log_debug("%s: table %s received mismatching binary",
320 738b3cc9 2019-09-15 rob __func__, cte->table->conf.name);
321 64b0dc5e 2023-06-21 claudio print_hex(ibuf_data(cte->buf), 0, ibuf_size(cte->buf));
322 738b3cc9 2019-09-15 rob }
323 738b3cc9 2019-09-15 rob } else if (cte->table->conf.check == CHECK_SEND_EXPECT) {
324 738b3cc9 2019-09-15 rob /*
325 738b3cc9 2019-09-15 rob * ensure string is nul-terminated.
326 738b3cc9 2019-09-15 rob */
327 a4719117 2023-07-03 claudio b = strndup(ibuf_data(cte->buf), ibuf_size(cte->buf));
328 738b3cc9 2019-09-15 rob if (b == NULL)
329 738b3cc9 2019-09-15 rob fatal("out of memory");
330 e8b51d49 2021-09-18 claudio if (fnmatch(cte->table->conf.exbuf, b, 0) == 0) {
331 738b3cc9 2019-09-15 rob cte->host->he = HCE_SEND_EXPECT_OK;
332 738b3cc9 2019-09-15 rob cte->host->up = HOST_UP;
333 e8b51d49 2021-09-18 claudio free(b);
334 738b3cc9 2019-09-15 rob return (0);
335 738b3cc9 2019-09-15 rob }
336 e8b51d49 2021-09-18 claudio free(b);
337 d4babff5 2007-02-03 reyk }
338 e8b51d49 2021-09-18 claudio
339 b2665266 2008-12-05 reyk cte->host->he = HCE_SEND_EXPECT_FAIL;
340 d4babff5 2007-02-03 reyk cte->host->up = HOST_UNKNOWN;
341 d4babff5 2007-02-03 reyk return (1);
342 d4babff5 2007-02-03 reyk }
343 d4babff5 2007-02-03 reyk
344 d4babff5 2007-02-03 reyk int
345 d4babff5 2007-02-03 reyk check_http_code(struct ctl_tcp_event *cte)
346 d4babff5 2007-02-03 reyk {
347 d4babff5 2007-02-03 reyk char *head;
348 d4babff5 2007-02-03 reyk char scode[4];
349 d4babff5 2007-02-03 reyk const char *estr;
350 d4babff5 2007-02-03 reyk int code;
351 b63dbf87 2007-02-07 reyk struct host *host;
352 d4babff5 2007-02-03 reyk
353 d4babff5 2007-02-03 reyk /*
354 d4babff5 2007-02-03 reyk * ensure string is nul-terminated.
355 d4babff5 2007-02-03 reyk */
356 4010a5ee 2023-06-20 claudio if (ibuf_add_zero(cte->buf, 1) == -1)
357 d4babff5 2007-02-03 reyk fatal("out of memory");
358 d4babff5 2007-02-03 reyk
359 64b0dc5e 2023-06-21 claudio head = ibuf_data(cte->buf);
360 b63dbf87 2007-02-07 reyk host = cte->host;
361 b2665266 2008-12-05 reyk host->he = HCE_HTTP_CODE_ERROR;
362 e7687e91 2016-01-11 benno host->code = 0;
363 b2665266 2008-12-05 reyk
364 d4babff5 2007-02-03 reyk if (strncmp(head, "HTTP/1.1 ", strlen("HTTP/1.1 ")) &&
365 d4babff5 2007-02-03 reyk strncmp(head, "HTTP/1.0 ", strlen("HTTP/1.0 "))) {
366 666bd316 2011-05-05 reyk log_debug("%s: %s failed (cannot parse HTTP version)",
367 666bd316 2011-05-05 reyk __func__, host->conf.name);
368 b63dbf87 2007-02-07 reyk host->up = HOST_DOWN;
369 d4babff5 2007-02-03 reyk return (1);
370 d4babff5 2007-02-03 reyk }
371 d4babff5 2007-02-03 reyk head += strlen("HTTP/1.1 ");
372 d4babff5 2007-02-03 reyk if (strlen(head) < 5) /* code + \r\n */ {
373 b63dbf87 2007-02-07 reyk host->up = HOST_DOWN;
374 d4babff5 2007-02-03 reyk return (1);
375 d4babff5 2007-02-03 reyk }
376 1ad64381 2007-02-08 reyk (void)strlcpy(scode, head, sizeof(scode));
377 d4babff5 2007-02-03 reyk code = strtonum(scode, 100, 999, &estr);
378 d4babff5 2007-02-03 reyk if (estr != NULL) {
379 666bd316 2011-05-05 reyk log_debug("%s: %s failed (cannot parse HTTP code)",
380 666bd316 2011-05-05 reyk __func__, host->conf.name);
381 b63dbf87 2007-02-07 reyk host->up = HOST_DOWN;
382 d4babff5 2007-02-03 reyk return (1);
383 d4babff5 2007-02-03 reyk }
384 87178699 2007-05-27 pyr if (code != cte->table->conf.retcode) {
385 e7687e91 2016-01-11 benno log_debug("%s: %s failed (invalid HTTP code %d returned)",
386 e7687e91 2016-01-11 benno __func__, host->conf.name, code);
387 b2665266 2008-12-05 reyk host->he = HCE_HTTP_CODE_FAIL;
388 b63dbf87 2007-02-07 reyk host->up = HOST_DOWN;
389 e7687e91 2016-01-11 benno host->code = code;
390 b2665266 2008-12-05 reyk } else {
391 b2665266 2008-12-05 reyk host->he = HCE_HTTP_CODE_OK;
392 b63dbf87 2007-02-07 reyk host->up = HOST_UP;
393 b2665266 2008-12-05 reyk }
394 b63dbf87 2007-02-07 reyk return (!(host->up == HOST_UP));
395 d4babff5 2007-02-03 reyk }
396 d4babff5 2007-02-03 reyk
397 d4babff5 2007-02-03 reyk int
398 d4babff5 2007-02-03 reyk check_http_digest(struct ctl_tcp_event *cte)
399 d4babff5 2007-02-03 reyk {
400 b63dbf87 2007-02-07 reyk char *head;
401 babcfdb5 2007-11-21 reyk char digest[SHA1_DIGEST_STRING_LENGTH];
402 b63dbf87 2007-02-07 reyk struct host *host;
403 d4babff5 2007-02-03 reyk
404 d4babff5 2007-02-03 reyk /*
405 d4babff5 2007-02-03 reyk * ensure string is nul-terminated.
406 d4babff5 2007-02-03 reyk */
407 4010a5ee 2023-06-20 claudio if (ibuf_add_zero(cte->buf, 1) == -1)
408 d4babff5 2007-02-03 reyk fatal("out of memory");
409 d4babff5 2007-02-03 reyk
410 64b0dc5e 2023-06-21 claudio head = ibuf_data(cte->buf);
411 b63dbf87 2007-02-07 reyk host = cte->host;
412 b2665266 2008-12-05 reyk host->he = HCE_HTTP_DIGEST_ERROR;
413 b2665266 2008-12-05 reyk
414 d4babff5 2007-02-03 reyk if ((head = strstr(head, "\r\n\r\n")) == NULL) {
415 666bd316 2011-05-05 reyk log_debug("%s: %s failed (no end of headers)",
416 666bd316 2011-05-05 reyk __func__, host->conf.name);
417 b63dbf87 2007-02-07 reyk host->up = HOST_DOWN;
418 d4babff5 2007-02-03 reyk return (1);
419 d4babff5 2007-02-03 reyk }
420 d4babff5 2007-02-03 reyk head += strlen("\r\n\r\n");
421 d4babff5 2007-02-03 reyk
422 8a025509 2007-11-21 reyk digeststr(cte->table->conf.digest_type, head, strlen(head), digest);
423 babcfdb5 2007-11-21 reyk
424 87178699 2007-05-27 pyr if (strcmp(cte->table->conf.digest, digest)) {
425 666bd316 2011-05-05 reyk log_warnx("%s: %s failed (wrong digest)",
426 666bd316 2011-05-05 reyk __func__, host->conf.name);
427 b2665266 2008-12-05 reyk host->he = HCE_HTTP_DIGEST_FAIL;
428 b63dbf87 2007-02-07 reyk host->up = HOST_DOWN;
429 b2665266 2008-12-05 reyk } else {
430 b2665266 2008-12-05 reyk host->he = HCE_HTTP_DIGEST_OK;
431 b63dbf87 2007-02-07 reyk host->up = HOST_UP;
432 b2665266 2008-12-05 reyk }
433 b63dbf87 2007-02-07 reyk return (!(host->up == HOST_UP));
434 d4babff5 2007-02-03 reyk }