return (p - frame);
}
-/* This function is used in cfgparse.c and declared in proto/checks.h. It
- * prepare the request to send to agents during a healthcheck. It returns 0 on
- * success and -1 if an error occurred. */
-int
-spoe_prepare_healthcheck_request(char **req, int *len)
-{
- struct appctx appctx;
- struct spoe_appctx spoe_appctx;
- char *frame, *end, buf[SPOP_MAX_FRAME_SIZE+4];
- size_t sz;
- int ret;
-
- memset(&appctx, 0, sizeof(appctx));
- memset(&spoe_appctx, 0, sizeof(spoe_appctx));
- memset(buf, 0, sizeof(buf));
-
- appctx.svcctx = &spoe_appctx;
- SPOE_APPCTX(&appctx)->max_frame_size = SPOP_MAX_FRAME_SIZE;
-
- frame = buf+4; /* Reserved the 4 first bytes for the frame size */
- end = frame + SPOP_MAX_FRAME_SIZE;
-
- ret = spoe_prepare_hahello_frame(&appctx, frame, SPOP_MAX_FRAME_SIZE);
- if (ret <= 0)
- return -1;
- frame += ret;
-
- /* Add "healthcheck" K/V item */
- sz = SLEN(HEALTHCHECK_KEY);
- if (spoe_encode_buffer(HEALTHCHECK_KEY, sz, &frame, end) == -1)
- return -1;
- *frame++ = (SPOP_DATA_T_BOOL | SPOP_DATA_FL_TRUE);
-
- *len = frame - buf;
- sz = htonl(*len - 4);
- memcpy(buf, (char *)&sz, 4);
-
- if ((*req = malloc(*len)) == NULL)
- return -1;
- memcpy(*req, buf, *len);
- return 0;
-}
-
-/* This function is used in checks.c and declared in proto/checks.h. It decode
- * the response received from an agent during a healthcheck. It returns 0 on
- * success and -1 if an error occurred. */
-int
-spoe_handle_healthcheck_response(char *frame, size_t size, char *err, int errlen)
-{
- struct appctx appctx;
- struct spoe_appctx spoe_appctx;
-
- memset(&appctx, 0, sizeof(appctx));
- memset(&spoe_appctx, 0, sizeof(spoe_appctx));
-
- appctx.svcctx = &spoe_appctx;
- SPOE_APPCTX(&appctx)->max_frame_size = SPOP_MAX_FRAME_SIZE;
-
- if (*frame == SPOP_FRM_T_AGENT_DISCON) {
- spoe_handle_agentdiscon_frame(&appctx, frame, size);
- goto error;
- }
- if (spoe_handle_agenthello_frame(&appctx, frame, size) <= 0)
- goto error;
-
- return 0;
-
- error:
- if (SPOE_APPCTX(&appctx)->status_code >= SPOP_ERR_ENTRIES)
- SPOE_APPCTX(&appctx)->status_code = SPOP_ERR_UNKNOWN;
- strncpy(err, spoe_frm_err_reasons[SPOE_APPCTX(&appctx)->status_code], errlen);
- return -1;
-}
-
/* Send a SPOE frame to an agent. It returns -1 when an error occurred, 0 when
* the frame can be ignored, 1 to retry later, and the frame length on
* success. */
goto out;
}
-/* Custom tcp-check expect function to parse and validate the SPOP hello agent
- * frame. Returns TCPCHK_EVAL_WAIT to wait for more data, TCPCHK_EVAL_CONTINUE
- * to evaluate the next rule or TCPCHK_EVAL_STOP if an error occurred.
- */
-enum tcpcheck_eval_ret tcpcheck_spop_expect_agenthello(struct check *check, struct tcpcheck_rule *rule, int last_read)
-{
- enum tcpcheck_eval_ret ret = TCPCHK_EVAL_CONTINUE;
- enum healthcheck_status status;
- struct buffer *msg = NULL;
- struct ist desc = IST_NULL;
- unsigned int framesz;
-
- TRACE_ENTER(CHK_EV_TCPCHK_EXP, check);
-
- memcpy(&framesz, b_head(&check->bi), 4);
- framesz = ntohl(framesz);
-
- if (!last_read && b_data(&check->bi) < (4+framesz))
- goto wait_more_data;
-
- memset(b_orig(&trash), 0, b_size(&trash));
- if (spoe_handle_healthcheck_response(b_peek(&check->bi, 4), framesz, b_orig(&trash), HCHK_DESC_LEN) == -1) {
- status = HCHK_STATUS_L7RSP;
- desc = ist2(b_orig(&trash), strlen(b_orig(&trash)));
- goto error;
- }
-
- status = ((rule->expect.ok_status != HCHK_STATUS_UNKNOWN) ? rule->expect.ok_status : HCHK_STATUS_L7OKD);
- set_server_check_status(check, status, "SPOA server is ok");
-
- out:
- free_trash_chunk(msg);
- TRACE_LEAVE(CHK_EV_TCPCHK_EXP, check, 0, 0, (size_t[]){ret});
- return ret;
-
- error:
- ret = TCPCHK_EVAL_STOP;
- msg = alloc_trash_chunk();
- if (msg)
- tcpcheck_expect_onerror_message(msg, check, rule, 0, desc);
- set_server_check_status(check, status, (msg ? b_head(msg) : NULL));
- goto out;
-
- wait_more_data:
- TRACE_DEVEL("waiting for more data", CHK_EV_TCPCHK_EXP, check);
- ret = TCPCHK_EVAL_WAIT;
- goto out;
-}
-
/* Custom tcp-check expect function to parse and validate the agent-check
* reply. Returns TCPCHK_EVAL_WAIT to wait for more data, TCPCHK_EVAL_CONTINUE
* to evaluate the next rule or TCPCHK_EVAL_STOP if an error occurred.
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && check->mux_proto)
mux_ops = check->mux_proto->mux;
else {
- int mode = ((check->tcpcheck_rules->flags & TCPCHK_RULES_PROTO_CHK) == TCPCHK_RULES_HTTP_CHK
- ? PROTO_MODE_HTTP
- : PROTO_MODE_TCP);
+ int mode = tcpchk_rules_type_to_proto_mode(check->tcpcheck_rules->flags);
mux_ops = conn_get_best_mux(conn, IST_NULL, PROTO_SIDE_BE, mode);
}
{
struct tcpcheck_ruleset *rs = NULL;
struct tcpcheck_rules *rules = &curpx->tcpcheck_rules;
- struct tcpcheck_rule *chk;
- char *spop_req = NULL;
- char *errmsg = NULL;
- int spop_len = 0, err_code = 0;
+ int err_code = 0;
if (warnifnotcap(curpx, PR_CAP_BE, file, line, args[cur_arg+1], NULL))
err_code |= ERR_WARN;
rules->list = NULL;
rules->flags = 0;
-
rs = find_tcpcheck_ruleset("*spop-check");
if (rs)
goto ruleset_found;
goto error;
}
- if (spoe_prepare_healthcheck_request(&spop_req, &spop_len) == -1) {
- ha_alert("parsing [%s:%d] : out of memory.\n", file, line);
- goto error;
- }
- chunk_reset(&trash);
- dump_binary(&trash, spop_req, spop_len);
- trash.area[trash.data] = '\0';
-
- chk = parse_tcpcheck_send((char *[]){"tcp-check", "send-binary", b_head(&trash), ""},
- 1, curpx, &rs->rules, file, line, &errmsg);
- if (!chk) {
- ha_alert("parsing [%s:%d] : %s\n", file, line, errmsg);
- goto error;
- }
- chk->index = 0;
- LIST_APPEND(&rs->rules, &chk->list);
-
- chk = parse_tcpcheck_expect((char *[]){"tcp-check", "expect", "custom", "min-recv", "4", ""},
- 1, curpx, &rs->rules, TCPCHK_RULES_SPOP_CHK, file, line, &errmsg);
- if (!chk) {
- ha_alert("parsing [%s:%d] : %s\n", file, line, errmsg);
- goto error;
- }
- chk->expect.custom = tcpcheck_spop_expect_agenthello;
- chk->index = 1;
- LIST_APPEND(&rs->rules, &chk->list);
-
ruleset_found:
rules->list = &rs->rules;
rules->flags &= ~(TCPCHK_RULES_PROTO_CHK|TCPCHK_RULES_UNUSED_RS);
rules->flags |= TCPCHK_RULES_SPOP_CHK;
out:
- free(spop_req);
- free(errmsg);
return err_code;
error: