mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-02 03:30:59 +02:00
MINOR: stream: Use a pcli transaction to replace pcli_* members
A new type of transaction was introduced for master-cli streams. So SF_TXN_PCLI flag and functions to allocate and destroy PCLI transactions were added. In the stream structure, all pcli_* members were moved in the pcli transaction and the txn union was updated accordingly. When it was ambiguous, a test on the transaction type was performed. For instance to destroy the transaciton.
This commit is contained in:
parent
9d45929341
commit
24e05fe33a
@ -113,6 +113,13 @@ struct cli_wait_ctx {
|
||||
const char *msg; // static error message for failures if not NULL
|
||||
};
|
||||
|
||||
struct pcli_txn {
|
||||
int next_pid; /* next target PID to use for the CLI proxy */
|
||||
int flags; /* flags for CLI proxy */
|
||||
char payload_pat[65]; /* payload pattern for the CLI proxy, including trailing \0 */
|
||||
|
||||
};
|
||||
|
||||
struct cli_kw {
|
||||
const char *str_kw[CLI_PREFIX_KW_NB]; /* keywords ended by NULL, limited to CLI_PREFIX_KW_NB
|
||||
separated keywords combination */
|
||||
|
||||
@ -47,10 +47,13 @@ int mworker_cli_global_proxy_new_listener(struct mworker_proc *proc);
|
||||
void mworker_cli_proxy_stop(void);
|
||||
|
||||
extern struct bind_conf *mcli_reload_bind_conf;
|
||||
extern struct pool_head *pool_head_pcli_txn;
|
||||
|
||||
/* proxy mode cli functions */
|
||||
|
||||
/* analyzers */
|
||||
struct pcli_txn *pcli_create_txn(struct stream *s);
|
||||
void pcli_destroy_txn(struct stream *s);
|
||||
int pcli_wait_for_request(struct stream *s, struct channel *req, int an_bit);
|
||||
int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit);
|
||||
|
||||
|
||||
@ -93,7 +93,8 @@
|
||||
/* unused: 0x08000000 */
|
||||
#define SF_TXN_NONE 0x00000000 /* No transaction allocated */
|
||||
#define SF_TXN_HTTP 0x10000000 /* HTTP transaction allocated */
|
||||
#define SF_TXN_MASK 0x10000000 /* mask to get the transaction type */
|
||||
#define SF_TXN_PCLI 0x20000000 /* PCLI transaction allocated */
|
||||
#define SF_TXN_MASK 0x30000000 /* mask to get the transaction type */
|
||||
|
||||
/* This function is used to report flags in debugging tools. Please reflect
|
||||
* below any single-bit flag addition above in the same order via the
|
||||
@ -214,6 +215,7 @@ struct session;
|
||||
struct server;
|
||||
struct task;
|
||||
struct sockaddr_storage;
|
||||
struct pcli_txn;
|
||||
|
||||
/* some external definitions */
|
||||
struct strm_logs {
|
||||
@ -262,6 +264,7 @@ struct stream {
|
||||
|
||||
union {
|
||||
struct http_txn *http; /* current HTTP transaction being processed. Should become a list. */
|
||||
struct pcli_txn *pcli; /* current PCLI transaction */
|
||||
} txn;
|
||||
|
||||
struct task *task; /* the task associated with this stream */
|
||||
@ -317,10 +320,6 @@ struct stream {
|
||||
void (*srv_error)(struct stream *s, /* the function to call upon unrecoverable server errors (or NULL) */
|
||||
struct stconn *sc);
|
||||
|
||||
int pcli_next_pid; /* next target PID to use for the CLI proxy */
|
||||
int pcli_flags; /* flags for CLI proxy */
|
||||
char pcli_payload_pat[65]; /* payload pattern for the CLI proxy, including trailing \0 */
|
||||
|
||||
struct ist unique_id; /* custom unique ID */
|
||||
|
||||
/* These two pointers are used to resume the execution of the rule lists. */
|
||||
|
||||
159
src/cli.c
159
src/cli.c
@ -764,7 +764,7 @@ int cli_has_level(struct appctx *appctx, int level)
|
||||
/* same as cli_has_level but for the CLI proxy and without error message */
|
||||
int pcli_has_level(struct stream *s, int level)
|
||||
{
|
||||
if ((s->pcli_flags & ACCESS_LVL_MASK) < level) {
|
||||
if ((s->txn.pcli->flags & ACCESS_LVL_MASK) < level) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -2812,18 +2812,19 @@ static int _send_status(char **args, char *payload, struct appctx *appctx, void
|
||||
|
||||
void pcli_write_prompt(struct stream *s)
|
||||
{
|
||||
struct pcli_txn *pcli = s->txn.pcli;
|
||||
struct buffer *msg = get_trash_chunk();
|
||||
struct channel *oc = sc_oc(s->scf);
|
||||
|
||||
if (!(s->pcli_flags & PCLI_F_PROMPT))
|
||||
if (!(pcli->flags & PCLI_F_PROMPT))
|
||||
return;
|
||||
|
||||
if (s->pcli_flags & PCLI_F_PAYLOAD) {
|
||||
if (pcli->flags & PCLI_F_PAYLOAD) {
|
||||
chunk_appendf(msg, "+ ");
|
||||
} else {
|
||||
if (s->pcli_next_pid == 0) {
|
||||
if (pcli->next_pid == 0) {
|
||||
/* master's prompt */
|
||||
if (s->pcli_flags & PCLI_F_TIMED) {
|
||||
if (pcli->flags & PCLI_F_TIMED) {
|
||||
uint up = ns_to_sec(now_ns - start_time_ns);
|
||||
chunk_appendf(msg, "[%u:%02u:%02u:%02u] ",
|
||||
(up / 86400), (up / 3600) % 24, (up / 60) % 60, up % 60);
|
||||
@ -2834,7 +2835,7 @@ void pcli_write_prompt(struct stream *s)
|
||||
}
|
||||
else {
|
||||
/* worker's prompt */
|
||||
if (s->pcli_flags & PCLI_F_TIMED) {
|
||||
if (pcli->flags & PCLI_F_TIMED) {
|
||||
const struct mworker_proc *tmp, *proc;
|
||||
uint up;
|
||||
|
||||
@ -2843,7 +2844,7 @@ void pcli_write_prompt(struct stream *s)
|
||||
list_for_each_entry(tmp, &proc_list, list) {
|
||||
if (!(tmp->options & PROC_O_TYPE_WORKER))
|
||||
continue;
|
||||
if (tmp->pid == s->pcli_next_pid) {
|
||||
if (tmp->pid == pcli->next_pid) {
|
||||
proc = tmp;
|
||||
break;
|
||||
}
|
||||
@ -2859,19 +2860,19 @@ void pcli_write_prompt(struct stream *s)
|
||||
(up / 86400), (up / 3600) % 24, (up / 60) % 60, up % 60);
|
||||
}
|
||||
}
|
||||
chunk_appendf(msg, "%d", s->pcli_next_pid);
|
||||
chunk_appendf(msg, "%d", pcli->next_pid);
|
||||
}
|
||||
|
||||
if (s->pcli_flags & (ACCESS_EXPERIMENTAL|ACCESS_EXPERT|ACCESS_MCLI_DEBUG)) {
|
||||
if (pcli->flags & (ACCESS_EXPERIMENTAL|ACCESS_EXPERT|ACCESS_MCLI_DEBUG)) {
|
||||
chunk_appendf(msg, "(");
|
||||
|
||||
if (s->pcli_flags & ACCESS_EXPERIMENTAL)
|
||||
if (pcli->flags & ACCESS_EXPERIMENTAL)
|
||||
chunk_appendf(msg, "x");
|
||||
|
||||
if (s->pcli_flags & ACCESS_EXPERT)
|
||||
if (pcli->flags & ACCESS_EXPERT)
|
||||
chunk_appendf(msg, "e");
|
||||
|
||||
if (s->pcli_flags & ACCESS_MCLI_DEBUG)
|
||||
if (pcli->flags & ACCESS_MCLI_DEBUG)
|
||||
chunk_appendf(msg, "d");
|
||||
|
||||
chunk_appendf(msg, ")");
|
||||
@ -3005,6 +3006,8 @@ static int pcli_prefix_to_pid(const char *prefix)
|
||||
*/
|
||||
int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg, int *next_pid)
|
||||
{
|
||||
struct pcli_txn *pcli = s->txn.pcli;
|
||||
|
||||
if (argl < 1)
|
||||
return 0;
|
||||
|
||||
@ -3019,7 +3022,7 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
|
||||
/* if the prefix is alone, define a default target */
|
||||
if (argl == 1)
|
||||
s->pcli_next_pid = target_pid;
|
||||
pcli->next_pid = target_pid;
|
||||
else
|
||||
*next_pid = target_pid;
|
||||
return 1;
|
||||
@ -3055,19 +3058,19 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
* In other mode, the default is to toggle prompt+inter (n/i->p, p->n).
|
||||
*/
|
||||
if (timed) {
|
||||
s->pcli_flags ^= PCLI_F_TIMED;
|
||||
pcli->flags ^= PCLI_F_TIMED;
|
||||
mode = mode ? mode : 3; // p by default
|
||||
}
|
||||
|
||||
if (mode) {
|
||||
/* force mode (i,p) */
|
||||
s->pcli_flags &= ~PCLI_F_PROMPT;
|
||||
s->pcli_flags |= (mode >= 3) ? PCLI_F_PROMPT : 0;
|
||||
pcli->flags &= ~PCLI_F_PROMPT;
|
||||
pcli->flags |= (mode >= 3) ? PCLI_F_PROMPT : 0;
|
||||
}
|
||||
else if (~s->pcli_flags & PCLI_F_PROMPT)
|
||||
s->pcli_flags |= PCLI_F_PROMPT; // p
|
||||
else if (~pcli->flags & PCLI_F_PROMPT)
|
||||
pcli->flags |= PCLI_F_PROMPT; // p
|
||||
else
|
||||
s->pcli_flags &= ~PCLI_F_PROMPT; // i
|
||||
pcli->flags &= ~PCLI_F_PROMPT; // i
|
||||
|
||||
return argl; /* return the number of elements in the array */
|
||||
} else if (strcmp("quit", args[0]) == 0) {
|
||||
@ -3079,8 +3082,8 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
memprintf(errmsg, "Permission denied!\n");
|
||||
return -1;
|
||||
}
|
||||
s->pcli_flags &= ~ACCESS_LVL_MASK;
|
||||
s->pcli_flags |= ACCESS_LVL_OPER;
|
||||
pcli->flags &= ~ACCESS_LVL_MASK;
|
||||
pcli->flags |= ACCESS_LVL_OPER;
|
||||
return argl;
|
||||
|
||||
} else if (strcmp(args[0], "user") == 0) {
|
||||
@ -3088,8 +3091,8 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
memprintf(errmsg, "Permission denied!\n");
|
||||
return -1;
|
||||
}
|
||||
s->pcli_flags &= ~ACCESS_LVL_MASK;
|
||||
s->pcli_flags |= ACCESS_LVL_USER;
|
||||
pcli->flags &= ~ACCESS_LVL_MASK;
|
||||
pcli->flags |= ACCESS_LVL_USER;
|
||||
return argl;
|
||||
|
||||
} else if (strcmp(args[0], "expert-mode") == 0) {
|
||||
@ -3098,9 +3101,9 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->pcli_flags &= ~ACCESS_EXPERT;
|
||||
pcli->flags &= ~ACCESS_EXPERT;
|
||||
if ((argl > 1) && (strcmp(args[1], "on") == 0))
|
||||
s->pcli_flags |= ACCESS_EXPERT;
|
||||
pcli->flags |= ACCESS_EXPERT;
|
||||
return argl;
|
||||
|
||||
} else if (strcmp(args[0], "experimental-mode") == 0) {
|
||||
@ -3108,27 +3111,27 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
memprintf(errmsg, "Permission denied!\n");
|
||||
return -1;
|
||||
}
|
||||
s->pcli_flags &= ~ACCESS_EXPERIMENTAL;
|
||||
pcli->flags &= ~ACCESS_EXPERIMENTAL;
|
||||
if ((argl > 1) && (strcmp(args[1], "on") == 0))
|
||||
s->pcli_flags |= ACCESS_EXPERIMENTAL;
|
||||
pcli->flags |= ACCESS_EXPERIMENTAL;
|
||||
return argl;
|
||||
} else if (strcmp(args[0], "mcli-debug-mode") == 0) {
|
||||
if (!pcli_has_level(s, ACCESS_LVL_ADMIN)) {
|
||||
memprintf(errmsg, "Permission denied!\n");
|
||||
return -1;
|
||||
}
|
||||
s->pcli_flags &= ~ACCESS_MCLI_DEBUG;
|
||||
pcli->flags &= ~ACCESS_MCLI_DEBUG;
|
||||
if ((argl > 1) && (strcmp(args[1], "on") == 0))
|
||||
s->pcli_flags |= ACCESS_MCLI_DEBUG;
|
||||
pcli->flags |= ACCESS_MCLI_DEBUG;
|
||||
return argl;
|
||||
} else if (strcmp(args[0], "set") == 0) {
|
||||
if ((argl > 1) && (strcmp(args[1], "severity-output") == 0)) {
|
||||
if ((argl > 2) &&strcmp(args[2], "none") == 0) {
|
||||
s->pcli_flags &= ~(ACCESS_MCLI_SEVERITY_NB|ACCESS_MCLI_SEVERITY_STR);
|
||||
pcli->flags &= ~(ACCESS_MCLI_SEVERITY_NB|ACCESS_MCLI_SEVERITY_STR);
|
||||
} else if ((argl > 2) && strcmp(args[2], "string") == 0) {
|
||||
s->pcli_flags |= ACCESS_MCLI_SEVERITY_STR;
|
||||
pcli->flags |= ACCESS_MCLI_SEVERITY_STR;
|
||||
} else if ((argl > 2) && strcmp(args[2], "number") == 0) {
|
||||
s->pcli_flags |= ACCESS_MCLI_SEVERITY_NB;
|
||||
pcli->flags |= ACCESS_MCLI_SEVERITY_NB;
|
||||
} else {
|
||||
memprintf(errmsg, "one of 'none', 'number', 'string' is a required argument\n");
|
||||
return -1;
|
||||
@ -3152,6 +3155,7 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
|
||||
*/
|
||||
int pcli_find_bidir_prefix(struct stream *s, struct channel *req, char **str, const char *end, char **errmsg, int *next_pid)
|
||||
{
|
||||
struct pcli_txn *pcli = s->txn.pcli;
|
||||
char *p = *str;
|
||||
int ret = 0;
|
||||
|
||||
@ -3189,7 +3193,7 @@ int pcli_find_bidir_prefix(struct stream *s, struct channel *req, char **str, co
|
||||
}
|
||||
|
||||
/* bidirectional connection to this worker */
|
||||
s->pcli_flags |= PCLI_F_BIDIR;
|
||||
pcli->flags |= PCLI_F_BIDIR;
|
||||
*next_pid = target_pid;
|
||||
|
||||
/* skip '@@pid' and LWS */
|
||||
@ -3209,10 +3213,10 @@ int pcli_find_bidir_prefix(struct stream *s, struct channel *req, char **str, co
|
||||
cmd = "prompt";
|
||||
ret += ci_insert(req, ret, cmd, strlen(cmd));
|
||||
|
||||
cmd = (s->pcli_flags & PCLI_F_PROMPT) ? " p" : " i";
|
||||
cmd = (pcli->flags & PCLI_F_PROMPT) ? " p" : " i";
|
||||
ret += ci_insert(req, ret, cmd, strlen(cmd));
|
||||
|
||||
if (s->pcli_flags & PCLI_F_TIMED) {
|
||||
if (pcli->flags & PCLI_F_TIMED) {
|
||||
cmd = " timed";
|
||||
ret += ci_insert(req, ret, cmd, strlen(cmd));
|
||||
}
|
||||
@ -3239,6 +3243,7 @@ int pcli_find_bidir_prefix(struct stream *s, struct channel *req, char **str, co
|
||||
*/
|
||||
int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int *next_pid)
|
||||
{
|
||||
struct pcli_txn *pcli = s->txn.pcli;
|
||||
char *str;
|
||||
char *end;
|
||||
char *args[MAX_CLI_ARGS + 1]; /* +1 for storing a NULL */
|
||||
@ -3261,7 +3266,7 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
|
||||
|
||||
p = str;
|
||||
|
||||
if (!(s->pcli_flags & PCLI_F_PAYLOAD)) {
|
||||
if (!(pcli->flags & PCLI_F_PAYLOAD)) {
|
||||
/* look for the '@@' prefix and intercept it if found */
|
||||
ret = pcli_find_bidir_prefix(s, req, &p, end, errmsg, next_pid);
|
||||
if (ret != 0) // success or failure
|
||||
@ -3306,11 +3311,11 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
|
||||
}
|
||||
|
||||
/* in payload mode, skip the whole parsing/exec and just look for a pattern */
|
||||
if (s->pcli_flags & PCLI_F_PAYLOAD) {
|
||||
if (reql-1 == strlen(s->pcli_payload_pat)) {
|
||||
if (pcli->flags & PCLI_F_PAYLOAD) {
|
||||
if (reql-1 == strlen(pcli->payload_pat)) {
|
||||
/* the custom pattern len can be 0 (empty line) */
|
||||
if (strncmp(str, s->pcli_payload_pat, strlen(s->pcli_payload_pat)) == 0) {
|
||||
s->pcli_flags &= ~PCLI_F_PAYLOAD;
|
||||
if (strncmp(str, pcli->payload_pat, strlen(pcli->payload_pat)) == 0) {
|
||||
pcli->flags &= ~PCLI_F_PAYLOAD;
|
||||
}
|
||||
}
|
||||
ret = reql;
|
||||
@ -3352,11 +3357,11 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
|
||||
* A customized pattern can't be more than 7 characters
|
||||
* if it's more, don't make it a payload
|
||||
*/
|
||||
if (pat_len < sizeof(s->pcli_payload_pat)) {
|
||||
s->pcli_flags |= PCLI_F_PAYLOAD;
|
||||
if (pat_len < sizeof(pcli->payload_pat)) {
|
||||
pcli->flags |= PCLI_F_PAYLOAD;
|
||||
/* copy the customized pattern, don't store the << */
|
||||
strncpy(s->pcli_payload_pat, args[argl-1] + strlen(PAYLOAD_PATTERN), sizeof(s->pcli_payload_pat)-1);
|
||||
s->pcli_payload_pat[sizeof(s->pcli_payload_pat)-1] = '\0';
|
||||
strncpy(pcli->payload_pat, args[argl-1] + strlen(PAYLOAD_PATTERN), sizeof(pcli->payload_pat)-1);
|
||||
pcli->payload_pat[sizeof(pcli->payload_pat)-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@ -3396,27 +3401,27 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
|
||||
if (ret > 1) {
|
||||
|
||||
/* the mcli-debug-mode is only sent to the applet of the master */
|
||||
if ((s->pcli_flags & ACCESS_MCLI_DEBUG) && *next_pid <= 0) {
|
||||
if ((pcli->flags & ACCESS_MCLI_DEBUG) && *next_pid <= 0) {
|
||||
const char *cmd = "mcli-debug-mode on -;";
|
||||
ci_insert(req, 0, cmd, strlen(cmd));
|
||||
ret += strlen(cmd);
|
||||
}
|
||||
if (s->pcli_flags & ACCESS_EXPERIMENTAL) {
|
||||
if (pcli->flags & ACCESS_EXPERIMENTAL) {
|
||||
const char *cmd = "experimental-mode on -;";
|
||||
ci_insert(req, 0, cmd, strlen(cmd));
|
||||
ret += strlen(cmd);
|
||||
}
|
||||
if (s->pcli_flags & ACCESS_EXPERT) {
|
||||
if (pcli->flags & ACCESS_EXPERT) {
|
||||
const char *cmd = "expert-mode on -;";
|
||||
ci_insert(req, 0, cmd, strlen(cmd));
|
||||
ret += strlen(cmd);
|
||||
}
|
||||
if (s->pcli_flags & ACCESS_MCLI_SEVERITY_STR) {
|
||||
if (pcli->flags & ACCESS_MCLI_SEVERITY_STR) {
|
||||
const char *cmd = "set severity-output string -;";
|
||||
ci_insert(req, 0, cmd, strlen(cmd));
|
||||
ret += strlen(cmd);
|
||||
}
|
||||
if (s->pcli_flags & ACCESS_MCLI_SEVERITY_NB) {
|
||||
if (pcli->flags & ACCESS_MCLI_SEVERITY_NB) {
|
||||
const char *cmd = "set severity-output number -;";
|
||||
ci_insert(req, 0, cmd, strlen(cmd));
|
||||
ret += strlen(cmd);
|
||||
@ -3439,8 +3444,38 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct pcli_txn *pcli_create_txn(struct stream *s)
|
||||
{
|
||||
struct pcli_txn *txn;
|
||||
|
||||
if ((s->flags & SF_TXN_MASK) != SF_TXN_NONE)
|
||||
return NULL;
|
||||
|
||||
txn = pool_alloc(pool_head_pcli_txn);
|
||||
if (!txn)
|
||||
return NULL;
|
||||
s->txn.pcli = txn;
|
||||
txn->next_pid = 0;
|
||||
txn->flags = 0;
|
||||
txn->payload_pat[0] = '\0';
|
||||
|
||||
s->flags |= SF_TXN_PCLI;
|
||||
|
||||
return txn;
|
||||
}
|
||||
|
||||
void pcli_destroy_txn(struct stream *s)
|
||||
{
|
||||
struct pcli_txn *txn = s->txn.pcli;
|
||||
|
||||
pool_free(pool_head_pcli_txn, txn);
|
||||
s->txn.pcli = NULL;
|
||||
s->flags &= ~SF_TXN_MASK;
|
||||
}
|
||||
|
||||
int pcli_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
||||
{
|
||||
struct pcli_txn *pcli = s->txn.pcli;
|
||||
int next_pid = -1;
|
||||
int to_forward;
|
||||
char *errmsg = NULL;
|
||||
@ -3452,13 +3487,13 @@ int pcli_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
||||
if (s->res.analysers & AN_RES_WAIT_CLI)
|
||||
return 0;
|
||||
|
||||
s->pcli_flags &= ~PCLI_F_BIDIR; // only for one connection
|
||||
if ((s->pcli_flags & ACCESS_LVL_MASK) == ACCESS_LVL_NONE)
|
||||
s->pcli_flags |= strm_li(s)->bind_conf->level & ACCESS_LVL_MASK;
|
||||
pcli->flags &= ~PCLI_F_BIDIR; // only for one connection
|
||||
if ((pcli->flags & ACCESS_LVL_MASK) == ACCESS_LVL_NONE)
|
||||
pcli->flags |= strm_li(s)->bind_conf->level & ACCESS_LVL_MASK;
|
||||
|
||||
/* stream that comes from the reload listener only responses the reload
|
||||
* status and quits */
|
||||
if (!(s->pcli_flags & PCLI_F_RELOAD)
|
||||
if (!(pcli->flags & PCLI_F_RELOAD)
|
||||
&& strm_li(s)->bind_conf == mcli_reload_bind_conf)
|
||||
goto send_status;
|
||||
|
||||
@ -3488,16 +3523,16 @@ read_again:
|
||||
/* enough data */
|
||||
|
||||
/* forward only 1 command for '@' or everything for '@@' */
|
||||
if (!(s->pcli_flags & PCLI_F_BIDIR))
|
||||
if (!(pcli->flags & PCLI_F_BIDIR))
|
||||
channel_forward(req, to_forward);
|
||||
else
|
||||
channel_forward_forever(req);
|
||||
|
||||
if (!(s->pcli_flags & PCLI_F_PAYLOAD)) {
|
||||
if (!(pcli->flags & PCLI_F_PAYLOAD)) {
|
||||
/* we send only 1 command per request, and we write
|
||||
* close after it when not in full-duplex mode.
|
||||
*/
|
||||
if (!(s->pcli_flags & PCLI_F_BIDIR))
|
||||
if (!(pcli->flags & PCLI_F_BIDIR))
|
||||
sc_schedule_shutdown(s->scb);
|
||||
} else {
|
||||
pcli_write_prompt(s);
|
||||
@ -3510,7 +3545,7 @@ read_again:
|
||||
if (next_pid > -1)
|
||||
target_pid = next_pid;
|
||||
else
|
||||
target_pid = s->pcli_next_pid;
|
||||
target_pid = pcli->next_pid;
|
||||
/* we can connect now */
|
||||
s->target = pcli_pid_to_server(target_pid);
|
||||
if (objt_server(s->target)) {
|
||||
@ -3550,7 +3585,7 @@ send_help:
|
||||
goto read_again;
|
||||
|
||||
send_status:
|
||||
s->pcli_flags |= PCLI_F_RELOAD;
|
||||
pcli->flags |= PCLI_F_RELOAD;
|
||||
/* don't use ci_putblk here because SHUT_DONE could have been sent */
|
||||
b_reset(&req->buf);
|
||||
b_putblk(&req->buf, "_loadstatus;quit\n", 17);
|
||||
@ -3577,6 +3612,7 @@ server_disconnect:
|
||||
|
||||
int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
{
|
||||
struct pcli_txn *pcli = s->txn.pcli;
|
||||
struct proxy *fe = strm_fe(s);
|
||||
struct proxy *be = s->be;
|
||||
|
||||
@ -3594,7 +3630,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
channel_dont_close(&s->res);
|
||||
channel_dont_close(&s->req);
|
||||
|
||||
if (s->pcli_flags & PCLI_F_PAYLOAD) {
|
||||
if (pcli->flags & PCLI_F_PAYLOAD) {
|
||||
s->res.analysers &= ~AN_RES_WAIT_CLI;
|
||||
s->req.flags |= CF_WAKE_ONCE; /* need to be called again if there is some command left in the request */
|
||||
return 0;
|
||||
@ -3707,7 +3743,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
s->res.flags &= ~(CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_EVENT|CF_WROTE_DATA|CF_READ_EVENT);
|
||||
s->req.to_forward = 0;
|
||||
s->res.to_forward = 0;
|
||||
s->pcli_flags &= ~PCLI_F_BIDIR;
|
||||
pcli->flags &= ~PCLI_F_BIDIR;
|
||||
s->flags &= ~(SF_DIRECT|SF_ASSIGNED|SF_BE_ASSIGNED|SF_FORCE_PRST|SF_IGNORE_PRST);
|
||||
s->flags &= ~(SF_CURR_SESS|SF_REDIRECTABLE|SF_SRV_REUSED);
|
||||
s->flags &= ~(SF_ERR_MASK|SF_FINST_MASK|SF_REDISP);
|
||||
@ -4085,6 +4121,9 @@ static struct applet mcli_applet = {
|
||||
.release = cli_release_handler,
|
||||
};
|
||||
|
||||
|
||||
DECLARE_TYPED_POOL(pool_head_pcli_txn, "pcli_txn", struct pcli_txn);
|
||||
|
||||
/* register cli keywords */
|
||||
static struct cli_kw_list cli_kws = {{ },{
|
||||
{ { "help", NULL }, NULL, cli_parse_simple, NULL, NULL, NULL, ACCESS_MASTER },
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <haproxy/acl.h>
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/arg.h>
|
||||
#include <haproxy/cli.h>
|
||||
#include <haproxy/chunk.h>
|
||||
#include <haproxy/connection.h>
|
||||
#include <haproxy/counters.h>
|
||||
@ -161,6 +162,8 @@ int frontend_accept(struct stream *s)
|
||||
|
||||
if ((fe->http_needed || IS_HTX_STRM(s)) && !http_create_txn(s))
|
||||
goto out_free_rspcap;
|
||||
else if ((fe->mode == PR_MODE_CLI) && !pcli_create_txn(s))
|
||||
goto out_free_rspcap;
|
||||
|
||||
/* everything's OK, let's go on */
|
||||
return 1;
|
||||
|
||||
@ -425,8 +425,6 @@ void *stream_new(struct session *sess, struct stconn *sc, struct buffer *input)
|
||||
s->lat_time = s->cpu_time = 0;
|
||||
s->call_rate.curr_tick = s->call_rate.curr_ctr = s->call_rate.prev_ctr = 0;
|
||||
s->passes_connect = s->passes_stconn = s->passes_reqana = s->passes_resana = s->passes_propag = 0;
|
||||
s->pcli_next_pid = 0;
|
||||
s->pcli_flags = 0;
|
||||
s->unique_id = IST_NULL;
|
||||
s->parent = NULL;
|
||||
if ((t = task_new_here()) == NULL)
|
||||
@ -685,6 +683,8 @@ void stream_free(struct stream *s)
|
||||
|
||||
if ((s->flags & SF_TXN_MASK) == SF_TXN_HTTP)
|
||||
http_destroy_txn(s);
|
||||
else if ((s->flags & SF_TXN_MASK) == SF_TXN_PCLI)
|
||||
pcli_destroy_txn(s);
|
||||
|
||||
/* ensure the client-side transport layer is destroyed */
|
||||
/* Be sure it is useless !! */
|
||||
@ -774,6 +774,7 @@ void stream_free(struct stream *s)
|
||||
pool_flush(pool_head_buffer);
|
||||
pool_flush(pool_head_large_buffer);
|
||||
pool_flush(pool_head_http_txn);
|
||||
pool_flush(pool_head_pcli_txn);
|
||||
pool_flush(pool_head_requri);
|
||||
pool_flush(pool_head_capture);
|
||||
pool_flush(pool_head_stream);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user