]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: connections: Don't assume the connection has a valid session.
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 12 Mar 2020 14:30:17 +0000 (15:30 +0100)
committerOlivier Houchard <cognet@ci0.org>
Thu, 12 Mar 2020 14:39:37 +0000 (15:39 +0100)
Don't assume the connection always has a valid session in "owner".
Instead, attempt to retrieve the session from the stream, and modify
the error snapshot code to not assume we always have a session, or the proxy
for the other end.

src/mux_fcgi.c
src/mux_h1.c
src/proxy.c

index 02a5e2c1df98343e2184f4a717e25b76937b7766..50cda636646fc48c86f9cf81ec338bbe8d155514 100644 (file)
@@ -3136,9 +3136,18 @@ static void fcgi_strm_capture_bad_message(struct fcgi_conn *fconn, struct fcgi_s
 {
        struct session *sess = fstrm->sess;
        struct proxy *proxy = fconn->proxy;
-       struct proxy *other_end = sess->fe;
+       struct proxy *other_end;
        union error_snapshot_ctx ctx;
 
+       if (fstrm->cs && fstrm->cs->data) {
+               if (sess == NULL)
+                       sess = si_strm(fstrm->cs->data)->sess;
+               if (!(h1m->flags & H1_MF_RESP))
+                       other_end = si_strm(fstrm->cs->data)->be;
+               else
+                       other_end = sess->fe;
+       } else
+               other_end = NULL;
        /* http-specific part now */
        ctx.h1.state   = h1m->state;
        ctx.h1.c_flags = fconn->flags;
index 9edbaea8816d28a40514cdae0a544fab9268d8fe..b3c954e0e559dd5fd34e8b667b0e81463cb9292e 100644 (file)
@@ -1054,11 +1054,18 @@ static void h1_capture_bad_message(struct h1c *h1c, struct h1s *h1s,
 {
        struct session *sess = h1c->conn->owner;
        struct proxy *proxy = h1c->px;
-       struct proxy *other_end = sess->fe;
+       struct proxy *other_end;
        union error_snapshot_ctx ctx;
 
-       if (h1s->cs->data && !(h1m->flags & H1_MF_RESP))
-               other_end = si_strm(h1s->cs->data)->be;
+       if (h1s->cs && h1s->cs->data) {
+               if (sess == NULL)
+                       sess = si_strm(h1s->cs->data)->sess;
+               if (!(h1m->flags & H1_MF_RESP))
+                       other_end = si_strm(h1s->cs->data)->be;
+               else
+                       other_end = sess->fe;
+       } else
+               other_end = NULL;
 
        /* http-specific part now */
        ctx.h1.state   = h1m->state;
index 8e325648f7a9c05506e1c1db4209063b98f14d94..046b1b555a2342a3947df20c5c76e1e8447ffd5a 100644 (file)
@@ -1560,7 +1560,7 @@ void proxy_capture_error(struct proxy *proxy, int is_back,
        es->when    = date; // user-visible date
        es->srv     = objt_server(target);
        es->oe      = other_end;
-       if (objt_conn(sess->origin) && conn_get_src(__objt_conn(sess->origin)))
+       if (sess && objt_conn(sess->origin) && conn_get_src(__objt_conn(sess->origin)))
                es->src  = *__objt_conn(sess->origin)->src;
        else
                memset(&es->src, 0, sizeof(es->src));
@@ -2234,7 +2234,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
 
                if (appctx->ctx.errors.iid >= 0 &&
                    appctx->ctx.errors.px->uuid != appctx->ctx.errors.iid &&
-                   es->oe->uuid != appctx->ctx.errors.iid)
+                   (!es->oe || es->oe->uuid != appctx->ctx.errors.iid))
                        goto next;
 
                if (appctx->ctx.errors.ptr < 0) {
@@ -2264,15 +2264,15 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                                             " frontend %s (#%d): invalid request\n"
                                             "  backend %s (#%d)",
                                             appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
-                                            (es->oe->cap & PR_CAP_BE) ? es->oe->id : "<NONE>",
-                                            (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1);
+                                            (es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->id : "<NONE>",
+                                            (es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1);
                                break;
                        case 1:
                                chunk_appendf(&trash,
                                             " backend %s (#%d): invalid response\n"
                                             "  frontend %s (#%d)",
                                             appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
-                                            es->oe->id, es->oe->uuid);
+                                            es->oe ? es->oe->id : "<NONE>" , es->oe ? es->oe->uuid : -1);
                                break;
                        }