MINOR: spoe: Add status code in error variable instead of hardcoded value
Now, when option "set-on-error" is enabled, we set a status code representing the error occurred instead of "true". For values under 256, it represents an error coming from the engine. Below 256, it reports a SPOP error. In this case, to retrieve the right SPOP status code, you must remove 256 to this value. Here are possible values: * 1: a timeout occurred during the event processing. * 2: an error was triggered during the ressources allocation. * 255: an unknown error occurred during the event processing. * 256+N: a SPOP error occurred during the event processing.
This commit is contained in:
parent
42bfa46234
commit
b067b06fc7
21
doc/SPOE.txt
21
doc/SPOE.txt
|
@ -217,9 +217,22 @@ option set-on-error <var name>
|
|||
prefixed. So, if your variable name is "error" and your prefix is
|
||||
"my_spoe_pfx", the variable will be "txn.my_spoe_pfx.error".
|
||||
|
||||
When set, the variable is the boolean "true". Note that if "option
|
||||
continue-on-error" is set, the variable is not automatically removed between
|
||||
events processing.
|
||||
When set, the variable is an integer representing the error reason. For values
|
||||
under 256, it represents an error coming from the engine. Below 256, it
|
||||
reports a SPOP error. In this case, to retrieve the right SPOP status code,
|
||||
you must remove 256 to this value. Here are possible values:
|
||||
|
||||
* 1 a timeout occurred during the event processing.
|
||||
|
||||
* 2 an error was triggered during the ressources allocation.
|
||||
|
||||
* 255 an unknown error occurred during the event processing.
|
||||
|
||||
* 256+N a SPOP error occurred during the event processing (see section
|
||||
"Errors & timeouts").
|
||||
|
||||
Note that if "option continue-on-error" is set, the variable is not
|
||||
automatically removed between events processing.
|
||||
|
||||
See also: "option continue-on-error", "option var-prefix".
|
||||
|
||||
|
@ -341,7 +354,7 @@ event <name>
|
|||
- on-backend-http-request
|
||||
- on-http-response
|
||||
|
||||
See section 3.5 about Events.
|
||||
See section "Events & Messages".
|
||||
|
||||
2.4. Example
|
||||
-------------
|
||||
|
|
135
src/flt_spoe.c
135
src/flt_spoe.c
|
@ -119,6 +119,15 @@ enum spoe_event {
|
|||
SPOE_EV_EVENTS
|
||||
};
|
||||
|
||||
/* Errors triggered by streams */
|
||||
enum spoe_context_error {
|
||||
SPOE_CTX_ERR_NONE = 0,
|
||||
SPOE_CTX_ERR_TOUT,
|
||||
SPOE_CTX_ERR_RES,
|
||||
SPOE_CTX_ERR_UNKNOWN = 255,
|
||||
SPOE_CTX_ERRS,
|
||||
};
|
||||
|
||||
/* Errors triggerd by SPOE applet */
|
||||
enum spoe_frame_error {
|
||||
SPOE_FRM_ERR_NONE = 0,
|
||||
|
@ -243,6 +252,7 @@ struct spoe_context {
|
|||
|
||||
enum spoe_ctx_state state; /* SPOE_CTX_ST_* */
|
||||
unsigned int flags; /* SPOE_CTX_FL_* */
|
||||
unsigned int status_code; /* SPOE_CTX_ERR_* */
|
||||
|
||||
unsigned int stream_id; /* stream_id and frame_id are used */
|
||||
unsigned int frame_id; /* to map NOTIFY and ACK frames */
|
||||
|
@ -259,6 +269,7 @@ struct spoe_appctx {
|
|||
unsigned int max_frame_size; /* the negotiated max-frame-size value */
|
||||
unsigned int flags; /* SPOE_APPCTX_FL_* */
|
||||
|
||||
unsigned int status_code; /* SPOE_FRM_ERR_* */
|
||||
struct list waiting_queue; /* list of streams waiting for a ACK frame, in sync and pipelining mode */
|
||||
struct list list; /* next spoe appctx for the same agent */
|
||||
};
|
||||
|
@ -793,8 +804,10 @@ prepare_spoe_hahello_frame(struct appctx *appctx, char *frame, size_t size)
|
|||
+ 1 + SLEN(CAPABILITIES_KEY) + 1 + 1 + SLEN(CAPABILITIES_VAL)
|
||||
+ 1 + SLEN(ENGINE_ID_KEY) + 1 + 1 + 36);
|
||||
|
||||
if (size < max)
|
||||
if (size < max) {
|
||||
spoe_status_code = SPOE_FRM_ERR_TOO_BIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Frame type */
|
||||
frame[idx++] = SPOE_FRM_T_HAPROXY_HELLO;
|
||||
|
@ -890,9 +903,6 @@ prepare_spoe_hanotify_frame(struct appctx *appctx, struct spoe_context *ctx,
|
|||
{
|
||||
int idx = 0;
|
||||
|
||||
if (size < SPOE_APPCTX(appctx)->max_frame_size)
|
||||
return -1;
|
||||
|
||||
frame[idx++] = SPOE_FRM_T_HAPROXY_NOTIFY;
|
||||
|
||||
/* No flags for now */
|
||||
|
@ -904,8 +914,10 @@ prepare_spoe_hanotify_frame(struct appctx *appctx, struct spoe_context *ctx,
|
|||
idx += encode_spoe_varint(ctx->frame_id, frame+idx);
|
||||
|
||||
/* Copy encoded messages */
|
||||
if (idx + ctx->buffer->i > size)
|
||||
if (idx + ctx->buffer->i > size) {
|
||||
spoe_status_code = SPOE_FRM_ERR_TOO_BIG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy encoded messages */
|
||||
memcpy(frame+idx, ctx->buffer->p, ctx->buffer->i);
|
||||
|
@ -1218,7 +1230,7 @@ handle_spoe_agentack_frame(struct appctx *appctx, char *frame, size_t size)
|
|||
return 0;
|
||||
|
||||
found:
|
||||
if (acquire_spoe_buffer(ctx) <= 0)
|
||||
if (!acquire_spoe_buffer(ctx))
|
||||
return 1; /* Retry later */
|
||||
|
||||
/* Copy encoded actions */
|
||||
|
@ -1327,6 +1339,7 @@ send_spoe_frame(struct appctx *appctx, char *buf, size_t framesz)
|
|||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
return 1; /* retry */
|
||||
spoe_status_code = SPOE_FRM_ERR_IO;
|
||||
return -1; /* error */
|
||||
}
|
||||
return framesz;
|
||||
|
@ -1411,6 +1424,8 @@ release_spoe_applet(struct appctx *appctx)
|
|||
si_shutr(si);
|
||||
si_ic(si)->flags |= CF_READ_NULL;
|
||||
appctx->st0 = SPOE_APPCTX_ST_END;
|
||||
if (SPOE_APPCTX(appctx)->status_code == SPOE_FRM_ERR_NONE)
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
|
||||
}
|
||||
|
||||
if (SPOE_APPCTX(appctx)->task) {
|
||||
|
@ -1422,6 +1437,7 @@ release_spoe_applet(struct appctx *appctx)
|
|||
LIST_DEL(&ctx->list);
|
||||
LIST_INIT(&ctx->list);
|
||||
ctx->state = SPOE_CTX_ST_ERROR;
|
||||
ctx->status_code = (SPOE_APPCTX(appctx)->status_code + 0x100);
|
||||
task_wakeup(ctx->strm->task, TASK_WOKEN_MSG);
|
||||
}
|
||||
|
||||
|
@ -1434,6 +1450,7 @@ release_spoe_applet(struct appctx *appctx)
|
|||
LIST_DEL(&ctx->list);
|
||||
LIST_INIT(&ctx->list);
|
||||
ctx->state = SPOE_CTX_ST_ERROR;
|
||||
ctx->status_code = (SPOE_APPCTX(appctx)->status_code + 0x100);
|
||||
task_wakeup(ctx->strm->task, TASK_WOKEN_MSG);
|
||||
}
|
||||
|
||||
|
@ -1441,6 +1458,7 @@ release_spoe_applet(struct appctx *appctx)
|
|||
LIST_DEL(&ctx->list);
|
||||
LIST_INIT(&ctx->list);
|
||||
ctx->state = SPOE_CTX_ST_ERROR;
|
||||
ctx->status_code = (SPOE_APPCTX(appctx)->status_code + 0x100);
|
||||
task_wakeup(ctx->strm->task, TASK_WOKEN_MSG);
|
||||
}
|
||||
}
|
||||
|
@ -1458,12 +1476,15 @@ handle_connect_spoe_applet(struct appctx *appctx)
|
|||
task_wakeup(si_strm(si)->task, TASK_WOKEN_MSG);
|
||||
goto stop;
|
||||
}
|
||||
if (si->state != SI_ST_EST)
|
||||
if (si->state != SI_ST_EST) {
|
||||
spoe_status_code = SPOE_FRM_ERR_IO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (appctx->st1 == SPOE_APPCTX_ERR_TOUT) {
|
||||
SPOE_PRINTF(stderr, "%d.%06d [SPOE/%-15s] %s: appctx=%p - Connection timed out\n",
|
||||
(int)now.tv_sec, (int)now.tv_usec, agent->id, __FUNCTION__, appctx);
|
||||
spoe_status_code = SPOE_FRM_ERR_TOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -1495,6 +1516,7 @@ handle_connect_spoe_applet(struct appctx *appctx)
|
|||
stop:
|
||||
return 1;
|
||||
exit:
|
||||
SPOE_APPCTX(appctx)->status_code = spoe_status_code;
|
||||
appctx->st0 = SPOE_APPCTX_ST_EXIT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1508,12 +1530,15 @@ handle_connecting_spoe_applet(struct appctx *appctx)
|
|||
int ret, framesz = 0;
|
||||
|
||||
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO)
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO) {
|
||||
spoe_status_code = SPOE_FRM_ERR_IO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (appctx->st1 == SPOE_APPCTX_ERR_TOUT) {
|
||||
SPOE_PRINTF(stderr, "%d.%06d [SPOE/%-15s] %s: appctx=%p - Connection timed out\n",
|
||||
(int)now.tv_sec, (int)now.tv_usec, agent->id, __FUNCTION__, appctx);
|
||||
spoe_status_code = SPOE_FRM_ERR_TOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -1562,6 +1587,7 @@ handle_connecting_spoe_applet(struct appctx *appctx)
|
|||
stop:
|
||||
return 1;
|
||||
exit:
|
||||
SPOE_APPCTX(appctx)->status_code = spoe_status_code;
|
||||
appctx->st0 = SPOE_APPCTX_ST_EXIT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1576,8 +1602,10 @@ handle_processing_spoe_applet(struct appctx *appctx)
|
|||
unsigned int fpa = 0;
|
||||
int ret, framesz = 0, skip_sending = 0, skip_receiving = 0;
|
||||
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO)
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO) {
|
||||
spoe_status_code = SPOE_FRM_ERR_IO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (appctx->st1 == SPOE_APPCTX_ERR_TOUT) {
|
||||
spoe_status_code = SPOE_FRM_ERR_TOUT;
|
||||
|
@ -1617,6 +1645,7 @@ handle_processing_spoe_applet(struct appctx *appctx)
|
|||
case 0: /* ignore */
|
||||
agent->sending_rate++;
|
||||
ctx->state = SPOE_CTX_ST_ERROR;
|
||||
ctx->status_code = (spoe_status_code + 0x100);
|
||||
release_spoe_buffer(ctx);
|
||||
task_wakeup(ctx->strm->task, TASK_WOKEN_MSG);
|
||||
LIST_DEL(&ctx->list);
|
||||
|
@ -1702,6 +1731,7 @@ handle_processing_spoe_applet(struct appctx *appctx)
|
|||
return 1;
|
||||
|
||||
exit:
|
||||
SPOE_APPCTX(appctx)->status_code = spoe_status_code;
|
||||
appctx->st0 = SPOE_APPCTX_ST_EXIT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1714,6 +1744,8 @@ handle_disconnect_spoe_applet(struct appctx *appctx)
|
|||
char *frame = trash.str;
|
||||
int ret;
|
||||
|
||||
SPOE_APPCTX(appctx)->status_code = spoe_status_code;
|
||||
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO)
|
||||
goto exit;
|
||||
|
||||
|
@ -1763,11 +1795,15 @@ handle_disconnecting_spoe_applet(struct appctx *appctx)
|
|||
char *frame = trash.str;
|
||||
int ret, framesz = 0;
|
||||
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO)
|
||||
if (si->state == SI_ST_CLO || si_opposite(si)->state == SI_ST_CLO) {
|
||||
spoe_status_code = SPOE_FRM_ERR_IO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (appctx->st1 == SPOE_APPCTX_ERR_TOUT)
|
||||
if (appctx->st1 == SPOE_APPCTX_ERR_TOUT) {
|
||||
spoe_status_code = SPOE_FRM_ERR_TOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
framesz = 0;
|
||||
ret = recv_spoe_frame(appctx, frame, SPOE_APPCTX(appctx)->max_frame_size);
|
||||
|
@ -1813,6 +1849,8 @@ handle_disconnecting_spoe_applet(struct appctx *appctx)
|
|||
stop:
|
||||
return 1;
|
||||
exit:
|
||||
if (SPOE_APPCTX(appctx)->status_code == SPOE_FRM_ERR_NONE)
|
||||
SPOE_APPCTX(appctx)->status_code = spoe_status_code;
|
||||
appctx->st0 = SPOE_APPCTX_ST_EXIT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1824,6 +1862,8 @@ handle_spoe_applet(struct appctx *appctx)
|
|||
struct stream_interface *si = appctx->owner;
|
||||
struct spoe_agent *agent = SPOE_APPCTX(appctx)->agent;
|
||||
|
||||
spoe_status_code = SPOE_FRM_ERR_NONE;
|
||||
|
||||
switchstate:
|
||||
SPOE_PRINTF(stderr, "%d.%06d [SPOE/%-15s] %s: appctx=%p"
|
||||
" - appctx-state=%s\n",
|
||||
|
@ -1832,7 +1872,6 @@ handle_spoe_applet(struct appctx *appctx)
|
|||
|
||||
switch (appctx->st0) {
|
||||
case SPOE_APPCTX_ST_CONNECT:
|
||||
spoe_status_code = SPOE_FRM_ERR_NONE;
|
||||
if (handle_connect_spoe_applet(appctx))
|
||||
goto out;
|
||||
goto switchstate;
|
||||
|
@ -1923,6 +1962,7 @@ create_spoe_appctx(struct spoe_config *conf)
|
|||
SPOE_APPCTX(appctx)->version = 0;
|
||||
SPOE_APPCTX(appctx)->max_frame_size = conf->agent->max_frame_size;
|
||||
SPOE_APPCTX(appctx)->flags = 0;
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_NONE;
|
||||
|
||||
LIST_INIT(&SPOE_APPCTX(appctx)->list);
|
||||
LIST_INIT(&SPOE_APPCTX(appctx)->waiting_queue);
|
||||
|
@ -2330,15 +2370,13 @@ process_spoe_actions(struct stream *s, struct spoe_context *ctx,
|
|||
static int
|
||||
start_event_processing(struct spoe_context *ctx, int dir)
|
||||
{
|
||||
int ret;
|
||||
/* If a process is already started for this SPOE context, retry
|
||||
* later. */
|
||||
if (ctx->flags & SPOE_CTX_FL_PROCESS)
|
||||
goto wait;
|
||||
|
||||
ret = acquire_spoe_buffer(ctx);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (!acquire_spoe_buffer(ctx))
|
||||
goto wait;
|
||||
|
||||
/* Set the right flag to prevent request and response processing
|
||||
* in same time. */
|
||||
|
@ -2358,6 +2396,8 @@ stop_event_processing(struct spoe_context *ctx)
|
|||
/* Reset the flag to allow next processing */
|
||||
ctx->flags &= ~SPOE_CTX_FL_PROCESS;
|
||||
|
||||
ctx->status_code = 0;
|
||||
|
||||
/* Reset processing timer */
|
||||
ctx->process_exp = TICK_ETERNITY;
|
||||
|
||||
|
@ -2405,6 +2445,7 @@ process_spoe_event(struct stream *s, struct spoe_context *ctx,
|
|||
send_log(ctx->strm->be, LOG_WARNING,
|
||||
"failed to process event '%s': timeout.\n",
|
||||
spoe_event_str[ev]);
|
||||
ctx->status_code = SPOE_CTX_ERR_TOUT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -2425,21 +2466,17 @@ process_spoe_event(struct stream *s, struct spoe_context *ctx,
|
|||
ctx->process_exp);
|
||||
}
|
||||
ret = start_event_processing(ctx, dir);
|
||||
if (ret <= 0) {
|
||||
if (!ret)
|
||||
goto out;
|
||||
goto error;
|
||||
}
|
||||
if (!ret)
|
||||
goto out;
|
||||
ret = process_spoe_messages(s, ctx, &(ctx->messages[ev]), dir);
|
||||
if (ret <= 0) {
|
||||
if (!ret)
|
||||
goto skip;
|
||||
if (!ret)
|
||||
goto skip;
|
||||
|
||||
if (!queue_spoe_context(ctx)) {
|
||||
ctx->status_code = SPOE_CTX_ERR_RES;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!queue_spoe_context(ctx))
|
||||
goto error;
|
||||
|
||||
ctx->state = SPOE_CTX_ST_SENDING_MSGS;
|
||||
/* fall through */
|
||||
}
|
||||
|
@ -2452,11 +2489,8 @@ process_spoe_event(struct stream *s, struct spoe_context *ctx,
|
|||
|
||||
if (ctx->state == SPOE_CTX_ST_DONE) {
|
||||
ret = process_spoe_actions(s, ctx, ev, dir);
|
||||
if (ret <= 0) {
|
||||
if (!ret)
|
||||
goto skip;
|
||||
goto error;
|
||||
}
|
||||
if (!ret)
|
||||
goto skip;
|
||||
ctx->frame_id++;
|
||||
ctx->state = SPOE_CTX_ST_READY;
|
||||
goto end;
|
||||
|
@ -2475,7 +2509,7 @@ process_spoe_event(struct stream *s, struct spoe_context *ctx,
|
|||
// FIXME: Get the error code here
|
||||
memset(&smp, 0, sizeof(smp));
|
||||
smp_set_owner(&smp, s->be, s->sess, s, dir|SMP_OPT_FINAL);
|
||||
smp.data.u.sint = 1;
|
||||
smp.data.u.sint = ctx->status_code;
|
||||
smp.data.type = SMP_T_BOOL;
|
||||
|
||||
set_spoe_var(ctx, "txn", agent->var_on_error,
|
||||
|
@ -2484,7 +2518,7 @@ process_spoe_event(struct stream *s, struct spoe_context *ctx,
|
|||
|
||||
ctx->state = ((agent->flags & SPOE_FL_CONT_ON_ERR)
|
||||
? SPOE_CTX_ST_READY
|
||||
: SPOE_CTX_ST_ERROR);
|
||||
: SPOE_CTX_ST_NONE);
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
|
@ -2550,11 +2584,12 @@ create_spoe_context(struct filter *filter)
|
|||
return NULL;
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->filter = filter;
|
||||
ctx->state = SPOE_CTX_ST_NONE;
|
||||
ctx->flags = 0;
|
||||
ctx->messages = conf->agent->messages;
|
||||
ctx->buffer = &buf_empty;
|
||||
ctx->filter = filter;
|
||||
ctx->state = SPOE_CTX_ST_NONE;
|
||||
ctx->status_code = SPOE_CTX_ERR_NONE;
|
||||
ctx->flags = 0;
|
||||
ctx->messages = conf->agent->messages;
|
||||
ctx->buffer = &buf_empty;
|
||||
LIST_INIT(&ctx->buffer_wait.list);
|
||||
ctx->buffer_wait.target = ctx;
|
||||
ctx->buffer_wait.wakeup_cb = (int (*)(void *))wakeup_spoe_context;
|
||||
|
@ -2791,6 +2826,9 @@ spoe_start_analyze(struct stream *s, struct filter *filter, struct channel *chn)
|
|||
((struct spoe_config *)FLT_CONF(filter))->agent->id,
|
||||
__FUNCTION__, s, spoe_ctx_state_str[ctx->state], ctx->flags);
|
||||
|
||||
if (ctx->state == SPOE_CTX_ST_NONE)
|
||||
goto out;
|
||||
|
||||
if (!(chn->flags & CF_ISRESP)) {
|
||||
if (filter->pre_analyzers & AN_REQ_INSPECT_FE)
|
||||
chn->analysers |= AN_REQ_INSPECT_FE;
|
||||
|
@ -2801,11 +2839,9 @@ spoe_start_analyze(struct stream *s, struct filter *filter, struct channel *chn)
|
|||
goto out;
|
||||
|
||||
ctx->stream_id = s->uniq_id;
|
||||
if (ctx->state != SPOE_CTX_ST_NONE && ctx->state != SPOE_CTX_ST_ERROR) {
|
||||
ret = process_spoe_event(s, ctx, SPOE_EV_ON_CLIENT_SESS);
|
||||
if (ret != 1)
|
||||
goto out;
|
||||
}
|
||||
ret = process_spoe_event(s, ctx, SPOE_EV_ON_CLIENT_SESS);
|
||||
if (!ret)
|
||||
goto out;
|
||||
ctx->flags |= SPOE_CTX_FL_CLI_CONNECTED;
|
||||
}
|
||||
else {
|
||||
|
@ -2815,16 +2851,13 @@ spoe_start_analyze(struct stream *s, struct filter *filter, struct channel *chn)
|
|||
if (ctx->flags & SPOE_CTX_FL_SRV_CONNECTED)
|
||||
goto out;
|
||||
|
||||
if (ctx->state != SPOE_CTX_ST_NONE && ctx->state != SPOE_CTX_ST_ERROR) {
|
||||
ret = process_spoe_event(s, ctx, SPOE_EV_ON_SERVER_SESS);
|
||||
if (ret != 1)
|
||||
goto out;
|
||||
}
|
||||
ctx->flags |= SPOE_CTX_FL_SRV_CONNECTED;
|
||||
ret = process_spoe_event(s, ctx, SPOE_EV_ON_SERVER_SESS);
|
||||
if (!ret) {
|
||||
channel_dont_read(chn);
|
||||
channel_dont_close(chn);
|
||||
goto out;
|
||||
}
|
||||
ctx->flags |= SPOE_CTX_FL_SRV_CONNECTED;
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -2846,7 +2879,7 @@ spoe_chn_pre_analyze(struct stream *s, struct filter *filter,
|
|||
__FUNCTION__, s, spoe_ctx_state_str[ctx->state],
|
||||
ctx->flags, an_bit);
|
||||
|
||||
if (ctx->state == SPOE_CTX_ST_NONE || ctx->state == SPOE_CTX_ST_ERROR)
|
||||
if (ctx->state == SPOE_CTX_ST_NONE)
|
||||
goto out;
|
||||
|
||||
switch (an_bit) {
|
||||
|
|
Loading…
Reference in New Issue