mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-11 03:31:36 +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 */
|
||||
}
|
||||
|
||||
|
@ -2085,6 +2085,10 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
|
||||
if (si_b->state == SI_ST_REQ)
|
||||
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,
|
||||
* servers experience the same fate when their connection
|
||||
* is reused.
|
||||
|
Loading…
Reference in New Issue
Block a user