/* Send as many bytes as possible from the pipe to the connection's socket. */ int raw_sock_from_pipe(struct connection *conn, struct pipe *pipe) { int ret, done; if (!conn_ctrl_ready(conn)) return 0; if (!fd_send_ready(conn->t.sock.fd)) return 0; done = 0; while (pipe->data) { ret = splice(pipe->cons, NULL, conn->t.sock.fd, NULL, pipe->data, SPLICE_F_MOVE|SPLICE_F_NONBLOCK); if (ret <= 0) { if (ret == 0 || errno == EAGAIN) { fd_cant_send(conn->t.sock.fd); break; } else if (errno == EINTR) continue; /* here we have another error */ conn->flags |= CO_FL_ERROR; break; } done += ret; pipe->data -= ret; } if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done) conn->flags &= ~CO_FL_WAIT_L4_CONN; return done; }
/* Send a message over an established connection. It makes use of send() and * returns the same return code and errno. If the socket layer is not ready yet * then -1 is returned and ENOTSOCK is set into errno. If the fd is not marked * as ready, or if EAGAIN or ENOTCONN is returned, then we return 0. It returns * EMSGSIZE if called with a zero length message. The purpose is to simplify * some rare attempts to directly write on the socket from above the connection * (typically send_proxy). In case of EAGAIN, the fd is marked as "cant_send". * It automatically retries on EINTR. Other errors cause the connection to be * marked as in error state. It takes similar arguments as send() except the * first one which is the connection instead of the file descriptor. Note, * MSG_DONTWAIT and MSG_NOSIGNAL are forced on the flags. */ int conn_sock_send(struct connection *conn, const void *buf, int len, int flags) { int ret; ret = -1; errno = ENOTSOCK; if (conn->flags & CO_FL_SOCK_WR_SH) goto fail; if (!conn_ctrl_ready(conn)) goto fail; errno = EMSGSIZE; if (!len) goto fail; if (!fd_send_ready(conn->t.sock.fd)) goto wait; do { ret = send(conn->t.sock.fd, buf, len, flags | MSG_DONTWAIT | MSG_NOSIGNAL); } while (ret < 0 && errno == EINTR); if (ret > 0) return ret; if (ret == 0 || errno == EAGAIN || errno == ENOTCONN) { wait: fd_cant_send(conn->t.sock.fd); return 0; } fail: conn->flags |= CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH | CO_FL_ERROR; return ret; }
/* 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 * further, otherwise it returns non-zero and removes itself from the connection's * 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. * Note that it can emit a PROXY line by relying on the other end's address * when the connection is attached to a stream interface, or by resolving the * local address otherwise (also called a LOCAL line). */ int conn_si_send_proxy(struct connection *conn, unsigned int flag) { /* we might have been called just after an asynchronous shutw */ if (conn->flags & CO_FL_SOCK_WR_SH) goto out_error; if (!conn_ctrl_ready(conn)) goto out_error; if (!fd_send_ready(conn->t.sock.fd)) goto out_wait; /* If we have a PROXY line to send, we'll use this to validate the * connection, in which case the connection is validated only once * we've sent the whole proxy line. Otherwise we use connect(). */ while (conn->send_proxy_ofs) { int ret; /* The target server expects a PROXY line to be sent first. * If the send_proxy_ofs is negative, it corresponds to the * offset to start sending from then end of the proxy string * (which is recomputed every time since it's constant). If * it is positive, it means we have to send from the start. * We can only send a "normal" PROXY line when the connection * is attached to a stream interface. Otherwise we can only * send a LOCAL line (eg: for use with health checks). */ if (conn->data == &si_conn_cb) { struct stream_interface *si = conn->owner; struct connection *remote = objt_conn(si->ob->prod->end); ret = make_proxy_line(trash.str, trash.size, objt_server(conn->target), remote); } else { /* The target server expects a LOCAL line to be sent first. Retrieving * local or remote addresses may fail until the connection is established. */ conn_get_from_addr(conn); if (!(conn->flags & CO_FL_ADDR_FROM_SET)) goto out_wait; conn_get_to_addr(conn); if (!(conn->flags & CO_FL_ADDR_TO_SET)) goto out_wait; ret = make_proxy_line(trash.str, trash.size, objt_server(conn->target), conn); } if (!ret) goto out_error; if (conn->send_proxy_ofs > 0) conn->send_proxy_ofs = -ret; /* first call */ /* we have to send trash from (ret+sp for -sp bytes). If the * data layer has a pending write, we'll also set MSG_MORE. */ ret = send(conn->t.sock.fd, trash.str + ret + conn->send_proxy_ofs, -conn->send_proxy_ofs, (conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0); if (ret == 0) goto out_wait; if (ret < 0) { if (errno == EAGAIN || errno == ENOTCONN) goto out_wait; if (errno == EINTR) continue; conn->flags |= CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH; goto out_error; } conn->send_proxy_ofs += ret; /* becomes zero once complete */ if (conn->send_proxy_ofs != 0) goto out_wait; /* OK we've sent the whole line, we're connected */ break; } /* The connection is ready now, simply return and let the connection * handler notify upper layers if needed. */ if (conn->flags & CO_FL_WAIT_L4_CONN) conn->flags &= ~CO_FL_WAIT_L4_CONN; conn->flags &= ~flag; return 1; out_error: /* Write error on the file descriptor */ conn->flags |= CO_FL_ERROR; return 0; out_wait: __conn_sock_stop_recv(conn); fd_cant_send(conn->t.sock.fd); return 0; }