mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-19 05:25:41 +00:00
MEDIUM: stream-int: make sure to try to immediately validate the connection
In the rare case of immediate connect() (unix sockets, socket pairs, and occasionally TCP over the loopback), it is counter-productive to subscribe for sending and then getting immediately back to process_stream() after having passed through si_cs_process() just to update the connection. We already know it is established and it doesn't have any handshake anymore so we just have to complete it and return to process_stream() with the stream_interface in the SI_ST_RDY state. In this case, process_stream will simply loop back to the beginning to synchronize the state and turn it to SI_ST_EST/ASS/CLO/TAR etc. This will save us from having to needlessly subscribe in the connect() code, something which in addition cannot work with edge-triggered pollers.
This commit is contained in:
parent
667fefdc90
commit
ada4c5806b
@ -1525,6 +1525,40 @@ int connect_server(struct stream *s)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now handle synchronously connected sockets. We know the stream-int
|
||||||
|
* is at least in state SI_ST_CON. These ones typically are UNIX
|
||||||
|
* sockets, socket pairs, and occasionally TCP connections on the
|
||||||
|
* loopback on a heavily loaded system.
|
||||||
|
*/
|
||||||
|
if ((srv_conn->flags & CO_FL_ERROR || srv_cs->flags & CS_FL_ERROR))
|
||||||
|
s->si[1].flags |= SI_FL_ERR;
|
||||||
|
|
||||||
|
/* If we had early data, and the handshake ended, then
|
||||||
|
* we can remove the flag, and attempt to wake the task up,
|
||||||
|
* in the event there's an analyser waiting for the end of
|
||||||
|
* the handshake.
|
||||||
|
*/
|
||||||
|
if (!(srv_conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)))
|
||||||
|
srv_cs->flags &= ~CS_FL_WAIT_FOR_HS;
|
||||||
|
|
||||||
|
if (!si_state_in(s->si[1].state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
|
||||||
|
(srv_conn->flags & CO_FL_WAIT_XPRT) == 0) {
|
||||||
|
s->si[1].exp = TICK_ETERNITY;
|
||||||
|
si_oc(&s->si[1])->flags |= CF_WRITE_NULL;
|
||||||
|
if (s->si[1].state == SI_ST_CON)
|
||||||
|
s->si[1].state = SI_ST_RDY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report EOI on the channel if it was reached from the mux point of
|
||||||
|
* view.
|
||||||
|
*
|
||||||
|
* Note: This test is only required because si_cs_process is also the SI
|
||||||
|
* wake callback. Otherwise si_cs_recv()/si_cs_send() already take
|
||||||
|
* care of it.
|
||||||
|
*/
|
||||||
|
if ((srv_cs->flags & CS_FL_EOI) && !(si_ic(&s->si[1])->flags & CF_EOI))
|
||||||
|
si_ic(&s->si[1])->flags |= (CF_EOI|CF_READ_PARTIAL);
|
||||||
|
|
||||||
return SF_ERR_NONE; /* connection is OK */
|
return SF_ERR_NONE; /* connection is OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2085,6 +2085,10 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
|
|||||||
if (si_b->state == SI_ST_REQ)
|
if (si_b->state == SI_ST_REQ)
|
||||||
back_handle_st_req(s);
|
back_handle_st_req(s);
|
||||||
|
|
||||||
|
/* get a chance to complete an immediate connection setup */
|
||||||
|
if (si_b->state == SI_ST_RDY)
|
||||||
|
goto resync_stream_interface;
|
||||||
|
|
||||||
/* applets directly go to the ESTABLISHED state. Similarly,
|
/* applets directly go to the ESTABLISHED state. Similarly,
|
||||||
* servers experience the same fate when their connection
|
* servers experience the same fate when their connection
|
||||||
* is reused.
|
* is reused.
|
||||||
|
Loading…
Reference in New Issue
Block a user