34
int http_connect_thread(thread *);
34
int http_connect_thread(thread_t *);
36
36
/* Configuration stream handling */
38
38
free_url(void *data)
42
FREE(url_obj->digest);
47
47
dump_url(void *data)
50
log_message(LOG_INFO, " Checked url = %s", url_obj->path);
50
log_message(LOG_INFO, " Checked url = %s", url->path);
52
52
log_message(LOG_INFO, " digest = %s",
54
if (url_obj->status_code)
55
55
log_message(LOG_INFO, " HTTP Status Code = %d",
56
url_obj->status_code);
60
60
free_http_get_check(void *data)
62
http_get_checker *http_get_chk = CHECKER_DATA(data);
62
http_checker_t *http_get_chk = CHECKER_DATA(data);
64
64
free_list(http_get_chk->url);
65
65
FREE(http_get_chk->arg);
71
71
dump_http_get_check(void *data)
73
http_get_checker *http_get_chk = CHECKER_DATA(data);
73
http_checker_t *http_get_chk = CHECKER_DATA(data);
75
75
if (http_get_chk->proto == PROTO_HTTP)
76
76
log_message(LOG_INFO, " Keepalive method = HTTP_GET");
78
78
log_message(LOG_INFO, " Keepalive method = SSL_GET");
79
if (http_get_chk->connection_port)
80
log_message(LOG_INFO, " Connection port = %d",
81
ntohs(http_get_chk->connection_port));
82
if (http_get_chk->bindto)
83
log_message(LOG_INFO, " Bind to = %s",
84
inet_ntop2(http_get_chk->bindto));
79
log_message(LOG_INFO, " Connection port = %d", ntohs(inet_sockaddrport(&http_get_chk->dst)));
80
if (http_get_chk->bindto.ss_family)
81
log_message(LOG_INFO, " Bind to = %s", inet_sockaddrtos(&http_get_chk->bindto));
85
82
log_message(LOG_INFO, " Connection timeout = %lu",
86
83
http_get_chk->connection_to/TIMER_HZ);
87
84
log_message(LOG_INFO, " Nb get retry = %d", http_get_chk->nb_get_retry);
89
86
http_get_chk->delay_before_retry/TIMER_HZ);
90
87
dump_list(http_get_chk->url);
92
static http_get_checker *
89
static http_checker_t *
93
90
alloc_http_get(char *proto)
95
http_get_checker *http_get_chk;
92
http_checker_t *http_get_chk;
97
http_get_chk = (http_get_checker *) MALLOC(sizeof (http_get_checker));
98
http_get_chk->arg = (http_arg *) MALLOC(sizeof (http_arg));
94
http_get_chk = (http_checker_t *) MALLOC(sizeof (http_checker_t));
95
http_get_chk->arg = (http_arg_t *) MALLOC(sizeof (http_arg_t));
99
96
http_get_chk->proto =
100
97
(!strcmp(proto, "HTTP_GET")) ? PROTO_HTTP : PROTO_SSL;
101
98
http_get_chk->url = alloc_list(free_url, dump_url);
120
118
connect_p_handler(vector strvec)
122
http_get_checker *http_get_chk = CHECKER_GET();
123
http_get_chk->connection_port = htons(CHECKER_VALUE_INT(strvec));
120
http_checker_t *http_get_chk = CHECKER_GET();
121
checker_set_dst_port(&http_get_chk->dst, htons(CHECKER_VALUE_INT(strvec)));
127
125
bindto_handler(vector strvec)
129
http_get_checker *http_get_chk = CHECKER_GET();
130
inet_ston(VECTOR_SLOT(strvec, 1), &http_get_chk->bindto);
127
http_checker_t *http_get_chk = CHECKER_GET();
128
inet_stosockaddr(VECTOR_SLOT(strvec, 1), 0, &http_get_chk->bindto);
134
132
connect_to_handler(vector strvec)
136
http_get_checker *http_get_chk = CHECKER_GET();
134
http_checker_t *http_get_chk = CHECKER_GET();
137
135
http_get_chk->connection_to = CHECKER_VALUE_INT(strvec) * TIMER_HZ;
141
139
nb_get_retry_handler(vector strvec)
143
http_get_checker *http_get_chk = CHECKER_GET();
141
http_checker_t *http_get_chk = CHECKER_GET();
144
142
http_get_chk->nb_get_retry = CHECKER_VALUE_INT(strvec);
148
146
delay_before_retry_handler(vector strvec)
150
http_get_checker *http_get_chk = CHECKER_GET();
148
http_checker_t *http_get_chk = CHECKER_GET();
151
149
http_get_chk->delay_before_retry = CHECKER_VALUE_INT(strvec) * TIMER_HZ;
155
153
url_handler(vector strvec)
157
http_get_checker *http_get_chk = CHECKER_GET();
155
http_checker_t *http_get_chk = CHECKER_GET();
160
158
/* allocate the new URL */
161
new = (url *) MALLOC(sizeof (url));
159
new = (url_t *) MALLOC(sizeof (url_t));
163
161
list_add(http_get_chk->url, new);
167
165
path_handler(vector strvec)
169
http_get_checker *http_get_chk = CHECKER_GET();
170
url *url_obj = LIST_TAIL_DATA(http_get_chk->url);
167
http_checker_t *http_get_chk = CHECKER_GET();
168
url_t *url = LIST_TAIL_DATA(http_get_chk->url);
172
url_obj->path = CHECKER_VALUE_STRING(strvec);
170
url->path = CHECKER_VALUE_STRING(strvec);
176
174
digest_handler(vector strvec)
178
http_get_checker *http_get_chk = CHECKER_GET();
179
url *url_obj = LIST_TAIL_DATA(http_get_chk->url);
176
http_checker_t *http_get_chk = CHECKER_GET();
177
url_t *url = LIST_TAIL_DATA(http_get_chk->url);
181
url_obj->digest = CHECKER_VALUE_STRING(strvec);
179
url->digest = CHECKER_VALUE_STRING(strvec);
185
183
status_code_handler(vector strvec)
187
http_get_checker *http_get_chk = CHECKER_GET();
188
url *url_obj = LIST_TAIL_DATA(http_get_chk->url);
185
http_checker_t *http_get_chk = CHECKER_GET();
186
url_t *url = LIST_TAIL_DATA(http_get_chk->url);
190
url_obj->status_code = CHECKER_VALUE_INT(strvec);
188
url->status_code = CHECKER_VALUE_INT(strvec);
254
252
* http_handle_response (next checker thread registration)
258
get_service_port(checker * checker_obj)
260
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
264
* Set the remote connection port.
265
* If a specific checker port is specified, we used this.
266
* If we are balancing all services (host rather than service),
267
* then assume we want to use default ports for HTTP or HTTPS.
268
* Known as 'Layer3 stickyness'.
270
addr_port = CHECKER_RPORT(checker_obj);
273
htons((http_get_check->proto == PROTO_SSL) ? 443 : 80);
274
if (http_get_check->connection_port)
275
addr_port = http_get_check->connection_port;
280
256
* Simple epilog functions. Handling event timeout.
281
257
* Finish the checker with memory managment or url rety check.
286
262
* method == 2 => register a retry on url checker thread
289
epilog(thread * thread_obj, int method, int t, int c)
265
epilog(thread_t * thread, int method, int t, int c)
291
checker *checker_obj = THREAD_ARG(thread_obj);
292
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
293
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
294
REQ *req = HTTP_REQ(http_arg_obj);
295
uint16_t addr_port = get_service_port(checker_obj);
267
checker_t *checker = THREAD_ARG(thread);
268
http_checker_t *http_get_check = CHECKER_ARG(checker);
269
http_arg_t *http_arg = HTTP_ARG(http_get_check);
270
request_t *req = HTTP_REQ(http_arg);
299
http_arg_obj->url_it += t ? t : -http_arg_obj->url_it;
300
http_arg_obj->retry_it += c ? c : -http_arg_obj->retry_it;
274
http_arg->url_it += t ? t : -http_arg->url_it;
275
http_arg->retry_it += c ? c : -http_arg->retry_it;
306
281
* html buffer. This is sometime needed with some applications
309
if (http_arg_obj->retry_it > http_get_check->nb_get_retry-1) {
310
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
311
log_message(LOG_INFO, "Check on service [%s:%d] failed after %d retry."
312
, inet_ntop2(CHECKER_RIP(checker_obj))
313
, ntohs(addr_port), http_arg_obj->retry_it);
314
smtp_alert(checker_obj->rs, NULL, NULL,
284
if (http_arg->retry_it > http_get_check->nb_get_retry-1) {
285
if (svr_checker_up(checker->id, checker->rs)) {
286
log_message(LOG_INFO, "Check on service [%s]:%d failed after %d retry."
287
, inet_sockaddrtos(&http_get_check->dst)
288
, ntohs(inet_sockaddrport(&http_get_check->dst)), http_arg->retry_it);
289
smtp_alert(checker->rs, NULL, NULL,
316
291
"=> CHECK failed on service"
317
292
" : MD5 digest mismatch <=");
318
update_svr_checker_state(DOWN, checker_obj->id
293
update_svr_checker_state(DOWN, checker->id
323
298
/* Reset it counters */
324
http_arg_obj->url_it = 0;
325
http_arg_obj->retry_it = 0;
299
http_arg->url_it = 0;
300
http_arg->retry_it = 0;
328
303
/* register next timer thread */
329
304
switch (method) {
332
delay = checker_obj->vs->delay_loop;
307
delay = checker->vs->delay_loop;
335
310
http_get_check->delay_before_retry;
338
if (http_arg_obj->url_it == 0 && http_arg_obj->retry_it == 0)
339
delay = checker_obj->vs->delay_loop;
313
if (http_arg->url_it == 0 && http_arg->retry_it == 0)
314
delay = checker->vs->delay_loop;
341
316
delay = http_get_check->delay_before_retry;
350
325
FREE(req->buffer);
352
http_arg_obj->req = NULL;
353
close(thread_obj->u.fd);
327
http_arg->req = NULL;
356
331
/* Register next checker thread */
357
thread_add_timer(thread_obj->master, http_connect_thread, checker_obj, delay);
332
thread_add_timer(thread->master, http_connect_thread, checker, delay);
362
timeout_epilog(thread * thread_obj, char *smtp_msg, char *debug_msg)
337
timeout_epilog(thread_t * thread, char *smtp_msg, char *debug_msg)
364
checker *checker_obj = THREAD_ARG(thread_obj);
365
uint16_t addr_port = get_service_port(checker_obj);
339
checker_t *checker = THREAD_ARG(thread);
340
http_checker_t *http_get_check = CHECKER_ARG(checker);
367
log_message(LOG_INFO, "Timeout %s server [%s:%d].",
369
, inet_ntop2(CHECKER_RIP(checker_obj))
342
log_message(LOG_INFO, "Timeout %s server [%s]:%d."
344
, inet_sockaddrtos(&http_get_check->dst)
345
, ntohs(inet_sockaddrport(&http_get_check->dst)));
372
347
/* check if server is currently alive */
373
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
374
smtp_alert(checker_obj->rs, NULL, NULL,
348
if (svr_checker_up(checker->id, checker->rs)) {
349
smtp_alert(checker->rs, NULL, NULL,
375
350
"DOWN", smtp_msg);
376
update_svr_checker_state(DOWN, checker_obj->id
351
update_svr_checker_state(DOWN, checker->id
381
return epilog(thread_obj, 1, 0, 0);
356
return epilog(thread, 1, 0, 0);
384
359
/* return the url pointer of the current url iterator */
386
fetch_next_url(http_get_checker * http_get_check)
361
fetch_next_url(http_checker_t * http_get_check)
388
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
363
http_arg_t *http_arg = HTTP_ARG(http_get_check);
390
return list_element(http_get_check->url, http_arg_obj->url_it);
365
return list_element(http_get_check->url, http_arg->url_it);
393
368
/* Handle response */
395
http_handle_response(thread * thread_obj, unsigned char digest[16]
370
http_handle_response(thread_t * thread, unsigned char digest[16]
396
371
, int empty_buffer)
398
checker *checker_obj = THREAD_ARG(thread_obj);
399
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
400
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
401
REQ *req = HTTP_REQ(http_arg_obj);
402
uint16_t addr_port = get_service_port(checker_obj);
373
checker_t *checker = THREAD_ARG(thread);
374
http_checker_t *http_get_check = CHECKER_ARG(checker);
375
http_arg_t *http_arg = HTTP_ARG(http_get_check);
376
request_t *req = HTTP_REQ(http_arg);
404
378
char *digest_tmp;
405
url *fetched_url = fetch_next_url(http_get_check);
379
url_t *fetched_url = fetch_next_url(http_get_check);
407
381
/* First check if remote webserver returned data */
408
382
if (empty_buffer)
409
return timeout_epilog(thread_obj, "=> CHECK failed on service"
383
return timeout_epilog(thread, "=> CHECK failed on service"
410
384
" : empty buffer received <=\n\n",
411
385
"Read, no data received from ");
414
388
if (fetched_url->status_code) {
415
389
if (req->status_code != fetched_url->status_code) {
416
390
/* check if server is currently alive */
417
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
391
if (svr_checker_up(checker->id, checker->rs)) {
418
392
log_message(LOG_INFO,
419
"HTTP status code error to [%s:%d] url(%s)"
393
"HTTP status code error to [%s]:%d url(%s)"
420
394
", status_code [%d].",
421
inet_ntop2(CHECKER_RIP(checker_obj)),
422
ntohs(addr_port), fetched_url->path,
395
inet_sockaddrtos(&http_get_check->dst),
396
ntohs(inet_sockaddrport(&http_get_check->dst)),
423
398
req->status_code);
424
smtp_alert(checker_obj->rs, NULL, NULL,
399
smtp_alert(checker->rs, NULL, NULL,
426
401
"=> CHECK failed on service"
427
402
" : HTTP status code mismatch <=");
428
update_svr_checker_state(DOWN, checker_obj->id
403
update_svr_checker_state(DOWN, checker->id
432
DBG("HTTP Status_code to [%s:%d] url(%d) = [%d].",
433
inet_ntop2(CHECKER_RIP(checker_obj))
435
, http_arg_obj->url_it + 1
407
DBG("HTTP Status_code to [%s]:%d url(%d) = [%d]."
408
, inet_sockaddrtos(&http_get_check->dst)
409
, ntohs(inet_sockaddrport(&http_get_check->dst))
410
, http_arg->url_it + 1
436
411
, req->status_code);
438
413
* We set retry iterator to max value to not retry
439
414
* when service is already know as die.
441
http_arg_obj->retry_it = http_get_check->nb_get_retry;
416
http_arg->retry_it = http_get_check->nb_get_retry;
443
return epilog(thread_obj, 2, 0, 1);
418
return epilog(thread, 2, 0, 1);
445
if (!svr_checker_up(checker_obj->id, checker_obj->rs))
420
if (!svr_checker_up(checker->id, checker->rs))
446
421
log_message(LOG_INFO,
447
"HTTP status code success to [%s:%d] url(%d).",
448
inet_ntop2(CHECKER_RIP(checker_obj))
450
, http_arg_obj->url_it + 1);
451
return epilog(thread_obj, 1, 1, 0) + 1;
422
"HTTP status code success to [%s]:%d url(%d)."
423
, inet_sockaddrtos(&http_get_check->dst)
424
, ntohs(inet_sockaddrport(&http_get_check->dst))
425
, http_arg->url_it + 1);
426
return epilog(thread, 1, 1, 0) + 1;
465
440
/* check if server is currently alive */
466
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
441
if (svr_checker_up(checker->id, checker->rs)) {
467
442
log_message(LOG_INFO,
468
"MD5 digest error to [%s:%d] url[%s]"
443
"MD5 digest error to [%s]:%d url[%s]"
469
444
", MD5SUM [%s].",
470
inet_ntop2(CHECKER_RIP(checker_obj)),
471
ntohs(addr_port), fetched_url->path,
445
inet_sockaddrtos(&http_get_check->dst),
446
ntohs(inet_sockaddrport(&http_get_check->dst)),
473
smtp_alert(checker_obj->rs, NULL, NULL,
449
smtp_alert(checker->rs, NULL, NULL,
475
451
"=> CHECK failed on service"
476
452
" : HTTP MD5SUM mismatch <=");
477
update_svr_checker_state(DOWN, checker_obj->id
453
update_svr_checker_state(DOWN, checker->id
481
DBG("MD5SUM to [%s:%d] url(%d) = [%s].",
482
inet_ntop2(CHECKER_RIP(checker_obj))
484
, http_arg_obj->url_it + 1
457
DBG("MD5SUM to [%s]:%d url(%d) = [%s]."
458
, inet_sockaddrtos(&http_get_check->dst)
459
, ntohs(inet_sockaddrport(&http_get_check->dst))
460
, http_arg->url_it + 1
487
463
* We set retry iterator to max value to not retry
488
464
* when service is already know as die.
490
http_arg_obj->retry_it = http_get_check->nb_get_retry;
466
http_arg->retry_it = http_get_check->nb_get_retry;
492
468
FREE(digest_tmp);
493
return epilog(thread_obj, 2, 0, 1);
469
return epilog(thread, 2, 0, 1);
495
if (!svr_checker_up(checker_obj->id, checker_obj->rs))
496
log_message(LOG_INFO, "MD5 digest success to [%s:%d] url(%d).",
497
inet_ntop2(CHECKER_RIP(checker_obj))
499
, http_arg_obj->url_it + 1);
471
if (!svr_checker_up(checker->id, checker->rs))
472
log_message(LOG_INFO, "MD5 digest success to [%s]:%d url(%d)."
473
, inet_sockaddrtos(&http_get_check->dst)
474
, ntohs(inet_sockaddrport(&http_get_check->dst))
475
, http_arg->url_it + 1);
500
476
FREE(digest_tmp);
501
return epilog(thread_obj, 1, 1, 0) + 1;
477
return epilog(thread, 1, 1, 0) + 1;
505
return epilog(thread_obj, 1, 0, 0) + 1;
481
return epilog(thread, 1, 0, 0) + 1;
508
484
/* Handle response stream performing MD5 updates */
510
http_process_response(REQ *req, int r)
486
http_process_response(request_t *req, int r)
513
489
if (!req->extracted) {
534
510
/* Asynchronous HTTP stream reader */
536
http_read_thread(thread * thread_obj)
512
http_read_thread(thread_t * thread)
538
checker *checker_obj = THREAD_ARG(thread_obj);
539
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
540
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
541
REQ *req = HTTP_REQ(http_arg_obj);
542
uint16_t addr_port = get_service_port(checker_obj);
514
checker_t *checker = THREAD_ARG(thread);
515
http_checker_t *http_get_check = CHECKER_ARG(checker);
516
http_arg_t *http_arg = HTTP_ARG(http_get_check);
517
request_t *req = HTTP_REQ(http_arg);
543
518
unsigned char digest[16];
547
522
/* Handle read timeout */
548
if (thread_obj->type == THREAD_READ_TIMEOUT)
549
return timeout_epilog(thread_obj, "=> HTTP CHECK failed on service"
523
if (thread->type == THREAD_READ_TIMEOUT)
524
return timeout_epilog(thread, "=> HTTP CHECK failed on service"
550
525
" : recevice data <=\n\n", "HTTP read");
552
527
/* Set descriptor non blocking */
553
val = fcntl(thread_obj->u.fd, F_GETFL, 0);
554
fcntl(thread_obj->u.fd, F_SETFL, val | O_NONBLOCK);
528
val = fcntl(thread->u.fd, F_GETFL, 0);
529
fcntl(thread->u.fd, F_SETFL, val | O_NONBLOCK);
556
531
/* read the HTTP stream */
557
r = read(thread_obj->u.fd, req->buffer + req->len,
532
r = read(thread->u.fd, req->buffer + req->len,
558
533
MAX_BUFFER_LENGTH - req->len);
560
535
/* restore descriptor flags */
561
fcntl(thread_obj->u.fd, F_SETFL, val);
536
fcntl(thread->u.fd, F_SETFL, val);
563
538
/* Test if data are ready */
564
539
if (r == -1 && (errno == EAGAIN || errno == EINTR)) {
565
log_message(LOG_INFO, "Read error with server [%s:%d]: %s",
566
inet_ntop2(CHECKER_RIP(checker_obj))
569
thread_add_read(thread_obj->master, http_read_thread, checker_obj,
570
thread_obj->u.fd, http_get_check->connection_to);
540
log_message(LOG_INFO, "Read error with server [%s]:%d: %s"
541
, inet_sockaddrtos(&http_get_check->dst)
542
, ntohs(inet_sockaddrport(&http_get_check->dst))
544
thread_add_read(thread->master, http_read_thread, checker,
545
thread->u.fd, http_get_check->connection_to);
580
555
/* We have encourred a real read error */
581
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
582
log_message(LOG_INFO, "Read error with server [%s:%d]: %s",
583
inet_ntop2(CHECKER_RIP(checker_obj))
556
if (svr_checker_up(checker->id, checker->rs)) {
557
log_message(LOG_INFO, "Read error with server [%s]:%d: %s"
558
, inet_sockaddrtos(&http_get_check->dst)
559
, ntohs(inet_sockaddrport(&http_get_check->dst))
585
560
, strerror(errno));
586
smtp_alert(checker_obj->rs, NULL, NULL,
561
smtp_alert(checker->rs, NULL, NULL,
588
563
"=> HTTP CHECK failed on service"
589
564
" : cannot receive data <=");
590
update_svr_checker_state(DOWN, checker_obj->id
565
update_svr_checker_state(DOWN, checker->id
594
return epilog(thread_obj, 1, 0, 0);
569
return epilog(thread, 1, 0, 0);
597
572
/* Handle response stream */
598
http_handle_response(thread_obj, digest, (!req->extracted) ? 1 : 0);
573
http_handle_response(thread, digest, (!req->extracted) ? 1 : 0);
618
593
* Apply trigger check to this result.
621
http_response_thread(thread * thread_obj)
596
http_response_thread(thread_t * thread)
623
checker *checker_obj = THREAD_ARG(thread_obj);
624
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
625
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
626
REQ *req = HTTP_REQ(http_arg_obj);
598
checker_t *checker = THREAD_ARG(thread);
599
http_checker_t *http_get_check = CHECKER_ARG(checker);
600
http_arg_t *http_arg = HTTP_ARG(http_get_check);
601
request_t *req = HTTP_REQ(http_arg);
628
603
/* Handle read timeout */
629
if (thread_obj->type == THREAD_READ_TIMEOUT)
630
return timeout_epilog(thread_obj, "=> CHECK failed on service"
604
if (thread->type == THREAD_READ_TIMEOUT)
605
return timeout_epilog(thread, "=> CHECK failed on service"
631
606
" : recevice data <=\n\n", "WEB read");
633
608
/* Allocate & clean the get buffer */
640
615
/* Register asynchronous http/ssl read thread */
641
616
if (http_get_check->proto == PROTO_SSL)
642
thread_add_read(thread_obj->master, ssl_read_thread, checker_obj,
643
thread_obj->u.fd, http_get_check->connection_to);
617
thread_add_read(thread->master, ssl_read_thread, checker,
618
thread->u.fd, http_get_check->connection_to);
645
thread_add_read(thread_obj->master, http_read_thread, checker_obj,
646
thread_obj->u.fd, http_get_check->connection_to);
620
thread_add_read(thread->master, http_read_thread, checker,
621
thread->u.fd, http_get_check->connection_to);
650
625
/* remote Web server is connected, send it the get url query. */
652
http_request_thread(thread * thread_obj)
627
http_request_thread(thread_t * thread)
654
checker *checker_obj = THREAD_ARG(thread_obj);
655
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
656
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
657
REQ *req = HTTP_REQ(http_arg_obj);
658
uint16_t addr_port = get_service_port(checker_obj);
659
char *vhost = CHECKER_VHOST(checker_obj);
629
checker_t *checker = THREAD_ARG(thread);
630
http_checker_t *http_get_check = CHECKER_ARG(checker);
631
http_arg_t *http_arg = HTTP_ARG(http_get_check);
632
request_t *req = HTTP_REQ(http_arg);
633
char *vhost = CHECKER_VHOST(checker);
660
634
char *str_request;
665
639
/* Handle read timeout */
666
if (thread_obj->type == THREAD_WRITE_TIMEOUT)
667
return timeout_epilog(thread_obj, "=> CHECK failed on service"
640
if (thread->type == THREAD_WRITE_TIMEOUT)
641
return timeout_epilog(thread, "=> CHECK failed on service"
668
642
" : read timeout <=\n\n",
669
643
"Web read, timeout");
674
648
fetched_url = fetch_next_url(http_get_check);
675
649
snprintf(str_request, GET_BUFFER_LENGTH, REQUEST_TEMPLATE,
676
650
fetched_url->path,
677
(vhost) ? vhost : inet_ntop2(CHECKER_RIP(checker_obj))
679
DBG("Processing url(%d) of [%s:%d].",
680
http_arg_obj->url_it + 1
681
, inet_ntop2(CHECKER_RIP(checker_obj))
651
(vhost) ? vhost : inet_sockaddrtos(&http_get_check->dst)
652
, ntohs(inet_sockaddrport(&http_get_check->dst)));
653
DBG("Processing url(%d) of [%s]:%d.",
655
, inet_sockaddrtos(&http_get_check->dst)
656
, ntohs(inet_sockaddrport(&http_get_check->dst)));
684
658
/* Set descriptor non blocking */
685
val = fcntl(thread_obj->u.fd, F_GETFL, 0);
686
fcntl(thread_obj->u.fd, F_SETFL, val | O_NONBLOCK);
659
val = fcntl(thread->u.fd, F_GETFL, 0);
660
fcntl(thread->u.fd, F_SETFL, val | O_NONBLOCK);
688
662
/* Send the GET request to remote Web server */
689
663
if (http_get_check->proto == PROTO_SSL) {
690
664
ret = ssl_send_request(req->ssl, str_request,
691
665
strlen(str_request));
693
ret = (send(thread_obj->u.fd, str_request, strlen(str_request), 0) !=
667
ret = (send(thread->u.fd, str_request, strlen(str_request), 0) !=
697
671
/* restore descriptor flags */
698
fcntl(thread_obj->u.fd, F_SETFL, val);
672
fcntl(thread->u.fd, F_SETFL, val);
700
674
FREE(str_request);
703
log_message(LOG_INFO, "Cannot send get request to [%s:%d].",
704
inet_ntop2(CHECKER_RIP(checker_obj))
677
log_message(LOG_INFO, "Cannot send get request to [%s]:%d."
678
, inet_sockaddrtos(&http_get_check->dst)
679
, ntohs(inet_sockaddrport(&http_get_check->dst)));
707
681
/* check if server is currently alive */
708
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
709
smtp_alert(checker_obj->rs, NULL, NULL,
682
if (svr_checker_up(checker->id, checker->rs)) {
683
smtp_alert(checker->rs, NULL, NULL,
711
685
"=> CHECK failed on service"
712
686
" : cannot send data <=");
713
update_svr_checker_state(DOWN, checker_obj->id
687
update_svr_checker_state(DOWN, checker->id
717
return epilog(thread_obj, 1, 0, 0);
691
return epilog(thread, 1, 0, 0);
720
694
/* Register read timeouted thread */
721
thread_add_read(thread_obj->master, http_response_thread, checker_obj,
722
thread_obj->u.fd, http_get_check->connection_to);
695
thread_add_read(thread->master, http_response_thread, checker,
696
thread->u.fd, http_get_check->connection_to);
726
700
/* WEB checkers threads */
728
http_check_thread(thread * thread_obj)
702
http_check_thread(thread_t * thread)
730
checker *checker_obj = THREAD_ARG(thread_obj);
731
http_get_checker *http_get_check = CHECKER_ARG(checker_obj);
732
uint16_t addr_port = get_service_port(checker_obj);
733
http_arg *http_arg_obj = HTTP_ARG(http_get_check);
704
checker_t *checker = THREAD_ARG(thread);
705
http_checker_t *http_get_check = CHECKER_ARG(checker);
706
http_arg_t *http_arg = HTTP_ARG(http_get_check);
735
REQ *req = HTTP_REQ(http_arg_obj);
708
request_t *req = HTTP_REQ(http_arg);
743
status = tcp_socket_state(thread_obj->u.fd, thread_obj, CHECKER_RIP(checker_obj)
744
, addr_port, http_check_thread);
716
status = tcp_socket_state(thread->u.fd, thread, http_check_thread);
745
717
switch (status) {
746
718
case connect_error:
747
719
/* check if server is currently alive */
748
if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
749
log_message(LOG_INFO, "Error connecting server [%s:%d].",
750
inet_ntop2(CHECKER_RIP(checker_obj))
752
smtp_alert(checker_obj->rs, NULL, NULL,
720
if (svr_checker_up(checker->id, checker->rs)) {
721
log_message(LOG_INFO, "Error connecting server [%s]:%d."
722
, inet_sockaddrtos(&http_get_check->dst)
723
, ntohs(inet_sockaddrport(&http_get_check->dst)));
724
smtp_alert(checker->rs, NULL, NULL,
754
726
"=> CHECK failed on service"
755
727
" : connection error <=");
756
update_svr_checker_state(DOWN, checker_obj->id
728
update_svr_checker_state(DOWN, checker->id
760
return epilog(thread_obj, 1, 0, 0);
732
return epilog(thread, 1, 0, 0);
763
735
case connect_timeout:
764
return timeout_epilog(thread_obj, "==> CHECK failed on service"
736
return timeout_epilog(thread, "==> CHECK failed on service"
765
737
" : connection timeout <=\n\n",
766
738
"connect, timeout");
769
741
case connect_success:{
770
if (!http_arg_obj->req) {
771
http_arg_obj->req = (REQ *) MALLOC(sizeof (REQ));
742
if (!http_arg->req) {
743
http_arg->req = (request_t *) MALLOC(sizeof (request_t));
776
748
if (http_get_check->proto == PROTO_SSL) {
777
timeout = TIMER_LONG(thread_obj->sands)-TIMER_LONG(time_now);
778
if (thread_obj->type != THREAD_WRITE_TIMEOUT &&
779
thread_obj->type != THREAD_READ_TIMEOUT)
780
ret = ssl_connect(thread_obj, new_req);
749
timeout = TIMER_LONG(thread->sands)-TIMER_LONG(time_now);
750
if (thread->type != THREAD_WRITE_TIMEOUT &&
751
thread->type != THREAD_READ_TIMEOUT)
752
ret = ssl_connect(thread, new_req);
782
return timeout_epilog(thread_obj, "==> CHECK failed on service"
754
return timeout_epilog(thread, "==> CHECK failed on service"
783
755
" : connection timeout <=\n\n",
784
756
"connect, timeout");
788
switch ((ssl_err = SSL_get_error(http_arg_obj->req->ssl,
760
switch ((ssl_err = SSL_get_error(http_arg->req->ssl,
790
762
case SSL_ERROR_WANT_READ:
791
thread_add_read(thread_obj->master,
763
thread_add_read(thread->master,
792
764
http_check_thread,
793
THREAD_ARG(thread_obj),
794
thread_obj->u.fd, timeout);
766
thread->u.fd, timeout);
796
768
case SSL_ERROR_WANT_WRITE:
797
thread_add_write(thread_obj->master,
769
thread_add_write(thread->master,
798
770
http_check_thread,
799
THREAD_ARG(thread_obj),
800
thread_obj->u.fd, timeout);
772
thread->u.fd, timeout);
813
785
/* Remote WEB server is connected.
814
786
* Register the next step thread ssl_request_thread.
816
DBG("Remote Web server [%s:%d] connected.",
817
inet_ntop2(CHECKER_RIP(checker_obj)),
819
thread_add_write(thread_obj->master,
820
http_request_thread, checker_obj,
788
DBG("Remote Web server [%s]:%d connected."
789
, inet_sockaddrtos(&http_get_check->dst)
790
, ntohs(inet_sockaddrport(&http_get_check->dst)));
791
thread_add_write(thread->master,
792
http_request_thread, checker,
822
794
http_get_check->connection_to);
824
DBG(LOG_INFO, "Connection trouble to: [%s:%d]."
825
, inet_ntop2(CHECKER_RIP(checker_obj))
796
DBG(LOG_INFO, "Connection trouble to: [%s]:%d."
797
, inet_sockaddrtos(&http_get_check->dst)
798
, ntohs(inet_sockaddrport(&http_get_check->dst)));
828
800
if (http_get_check->proto == PROTO_SSL)
829
801
ssl_printerr(SSL_get_error
830
802
(req->ssl, ret));
832
804
if ((http_get_check->proto == PROTO_SSL) &&
833
(svr_checker_up(checker_obj->id, checker_obj->rs))) {
805
(svr_checker_up(checker->id, checker->rs))) {
834
806
log_message(LOG_INFO, "SSL handshake/communication error"
835
807
" connecting to server"
836
" (openssl errno: %d) [%s:%d]."
837
, SSL_get_error (http_arg_obj->req->ssl, ret)
838
, inet_ntop2(CHECKER_RIP(checker_obj))
840
smtp_alert(checker_obj->rs, NULL, NULL,
808
" (openssl errno: %d) [%s]:%d."
809
, SSL_get_error (http_arg->req->ssl, ret)
810
, inet_sockaddrtos(&http_get_check->dst)
811
, ntohs(inet_sockaddrport(&http_get_check->dst)));
812
smtp_alert(checker->rs, NULL, NULL,
842
814
"=> CHECK failed on service"
843
815
" : SSL connection error <=");
844
update_svr_checker_state(DOWN, checker_obj->id
816
update_svr_checker_state(DOWN, checker->id
849
return epilog(thread_obj, 1, 0, 0);
821
return epilog(thread, 1, 0, 0);
884
855
* Check completed.
885
856
* check if server is currently alive.
887
if (!svr_checker_up(checker_obj->id, checker_obj->rs)) {
888
log_message(LOG_INFO, "Remote Web server [%s:%d] succeed on service.",
889
inet_ntop2(CHECKER_RIP(checker_obj))
891
smtp_alert(checker_obj->rs, NULL, NULL, "UP",
858
if (!svr_checker_up(checker->id, checker->rs)) {
859
log_message(LOG_INFO, "Remote Web server [%s]:%d succeed on service."
860
, inet_sockaddrtos(&http_get_check->dst)
861
, ntohs(inet_sockaddrport(&http_get_check->dst)));
862
smtp_alert(checker->rs, NULL, NULL, "UP",
892
863
"=> CHECK succeed on service <=");
893
update_svr_checker_state(UP, checker_obj->id
864
update_svr_checker_state(UP, checker->id
897
http_arg_obj->req = NULL;
898
return epilog(thread_obj, 1, 0, 0) + 1;
868
http_arg->req = NULL;
869
return epilog(thread, 1, 0, 0) + 1;
901
872
/* Create the socket */
902
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
873
if ((fd = socket(http_get_check->dst.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
903
874
DBG("WEB connection fail to create socket.");
907
status = tcp_bind_connect(fd, CHECKER_RIP(checker_obj), addr_port
908
, http_get_check->bindto);
878
status = tcp_bind_connect(fd, &http_get_check->dst, &http_get_check->bindto);
879
if (status == connect_error) {
880
thread_add_timer(thread->master, http_connect_thread, checker,
881
checker->vs->delay_loop);
910
885
/* handle tcp connection status & register check worker thread */
911
tcp_connection_state(fd, status, thread_obj, http_check_thread,
886
tcp_connection_state(fd, status, thread, http_check_thread,
912
887
http_get_check->connection_to);