MEDIUM: proxy-proto: don't use buffer flags in conn_si_send_proxy()

These ones should only be handled by the stream interface at the end
of the handshake now. Similarly a number of information are now taken
at the connection level rather than at the data level (eg: shutdown).

Fast polling updates have been used instead of slow ones since the
function is only called by the connection handler.
This commit is contained in:
Willy Tarreau 2012-08-24 12:14:49 +02:00 committed by Willy Tarreau
parent 44b5dc6f85
commit a1a74744a4

View File

@ -476,16 +476,15 @@ void stream_int_unregister_handler(struct stream_interface *si)
/* This callback is used to send a valid PROXY protocol line to a socket being /* This callback is used to send a valid PROXY protocol line to a socket being
* established. It returns 0 if it fails in a fatal way or needs to poll to go * established. It returns 0 if it fails in a fatal way or needs to poll to go
* further, otherwise it returns non-zero and removes itself from the connection's * further, otherwise it returns non-zero and removes itself from the connection's
* flags (the bit is provided in <flag> by the caller). * flags (the bit is provided in <flag> by the caller). It is designed to be
* called by the connection handler and relies on it to commit polling changes.
*/ */
int conn_si_send_proxy(struct connection *conn, unsigned int flag) int conn_si_send_proxy(struct connection *conn, unsigned int flag)
{ {
int fd = conn->t.sock.fd;
struct stream_interface *si = container_of(conn, struct stream_interface, conn); struct stream_interface *si = container_of(conn, struct stream_interface, conn);
struct channel *b = si->ob;
/* we might have been called just after an asynchronous shutw */ /* we might have been called just after an asynchronous shutw */
if (b->flags & BF_SHUTW) if (conn->flags & CO_FL_SOCK_WR_SH)
goto out_error; goto out_error;
/* If we have a PROXY line to send, we'll use this to validate the /* If we have a PROXY line to send, we'll use this to validate the
@ -501,16 +500,18 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
* (which is recomputed every time since it's constant). If * (which is recomputed every time since it's constant). If
* it is positive, it means we have to send from the start. * it is positive, it means we have to send from the start.
*/ */
ret = make_proxy_line(trash, trashlen, &b->prod->addr.from, &b->prod->addr.to); ret = make_proxy_line(trash, trashlen, &si->ob->prod->addr.from, &si->ob->prod->addr.to);
if (!ret) if (!ret)
goto out_error; goto out_error;
if (si->send_proxy_ofs > 0) if (si->send_proxy_ofs > 0)
si->send_proxy_ofs = -ret; /* first call */ si->send_proxy_ofs = -ret; /* first call */
/* we have to send trash from (ret+sp for -sp bytes) */ /* we have to send trash from (ret+sp for -sp bytes). If the
ret = send(fd, trash + ret + si->send_proxy_ofs, -si->send_proxy_ofs, * data layer has a pending write, we'll also set MSG_MORE.
(b->flags & BF_OUT_EMPTY) ? 0 : MSG_MORE); */
ret = send(conn->t.sock.fd, trash + ret + si->send_proxy_ofs, -si->send_proxy_ofs,
(conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0);
if (ret == 0) if (ret == 0)
goto out_wait; goto out_wait;
@ -528,13 +529,11 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
/* OK we've sent the whole line, we're connected */ /* OK we've sent the whole line, we're connected */
} }
/* The FD is ready now, simply return and let the connection handler /* The connection is ready now, simply return and let the connection
* notify upper layers if needed. * handler notify upper layers if needed.
*/ */
if (conn->flags & CO_FL_WAIT_L4_CONN) if (conn->flags & CO_FL_WAIT_L4_CONN)
conn->flags &= ~CO_FL_WAIT_L4_CONN; conn->flags &= ~CO_FL_WAIT_L4_CONN;
b->flags |= BF_WRITE_NULL;
si->exp = TICK_ETERNITY;
conn->flags &= ~flag; conn->flags &= ~flag;
return 1; return 1;
@ -542,13 +541,12 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
/* Write error on the file descriptor */ /* Write error on the file descriptor */
conn->flags |= CO_FL_ERROR; conn->flags |= CO_FL_ERROR;
conn->flags &= ~flag; conn->flags &= ~flag;
fdtab[fd].ev &= ~FD_POLL_STICKY; __conn_sock_stop_both(conn);
conn_sock_stop_both(conn);
return 0; return 0;
out_wait: out_wait:
conn_sock_stop_recv(conn); __conn_sock_stop_recv(conn);
conn_sock_poll_send(conn); __conn_sock_poll_send(conn);
return 0; return 0;
} }