#define _PROTO_CONNECTION_H
#include <common/config.h>
+#include <common/memory.h>
#include <types/connection.h>
#include <types/listener.h>
+extern struct pool_head *pool2_connection;
+
+/* perform minimal intializations, report 0 in case of error, 1 if OK. */
+int init_connection();
+
/* I/O callback for fd-based connections. It calls the read/write handlers
* provided by the connection's sock_ops. Returns 0.
*/
static inline const struct protocol *si_ctrl(struct stream_interface *si)
{
- return si->conn.ctrl;
+ return si->conn->ctrl;
}
static inline int si_fd(struct stream_interface *si)
{
- return si->conn.t.sock.fd;
+ return si->conn->t.sock.fd;
}
static inline void si_prepare_conn(struct stream_interface *si, const struct protocol *ctrl, const struct xprt_ops *xprt)
{
si->ops = &si_conn_ops;
- conn_prepare(&si->conn, &si_conn_cb, ctrl, xprt, si);
+ conn_prepare(si->conn, &si_conn_cb, ctrl, xprt, si);
}
static inline void si_takeover_conn(struct stream_interface *si, const struct protocol *ctrl, const struct xprt_ops *xprt)
{
si->ops = &si_conn_ops;
- conn_assign(&si->conn, &si_conn_cb, ctrl, xprt, si);
+ conn_assign(si->conn, &si_conn_cb, ctrl, xprt, si);
}
static inline void si_prepare_embedded(struct stream_interface *si)
{
si->ops = &si_embedded_ops;
- conn_prepare(&si->conn, NULL, NULL, NULL, si);
+ conn_prepare(si->conn, NULL, NULL, NULL, si);
}
static inline void si_prepare_task(struct stream_interface *si)
{
si->ops = &si_task_ops;
- conn_prepare(&si->conn, NULL, NULL, NULL, si);
+ conn_prepare(si->conn, NULL, NULL, NULL, si);
}
/* Sends a shutr to the connection using the data layer */
static inline void si_shutr(struct stream_interface *si)
{
if (stream_int_shutr(si))
- conn_data_stop_recv(&si->conn);
+ conn_data_stop_recv(si->conn);
}
/* Sends a shutw to the connection using the data layer */
static inline void si_shutw(struct stream_interface *si)
{
if (stream_int_shutw(si))
- conn_data_stop_send(&si->conn);
+ conn_data_stop_send(si->conn);
}
/* Calls the data state update on the stream interfaace */
if (unlikely(!si_ctrl(si) || !si_ctrl(si)->connect))
return SN_ERR_INTERNAL;
- ret = si_ctrl(si)->connect(&si->conn, !channel_is_empty(si->ob));
+ ret = si_ctrl(si)->connect(si->conn, !channel_is_empty(si->ob));
if (ret != SN_ERR_NONE)
return ret;
/* needs src ip/port for logging */
if (si->flags & SI_FL_SRC_ADDR)
- conn_get_from_addr(&si->conn);
+ conn_get_from_addr(si->conn);
/* Prepare to send a few handshakes related to the on-wire protocol. */
if (si->send_proxy_ofs)
- si->conn.flags |= CO_FL_SI_SEND_PROXY;
+ si->conn->flags |= CO_FL_SI_SEND_PROXY;
/* we need to be notified about connection establishment */
- si->conn.flags |= CO_FL_WAKE_DATA;
+ si->conn->flags |= CO_FL_WAKE_DATA;
/* we're in the process of establishing a connection */
si->state = SI_ST_CON;
unsigned int err_type; /* first error detected, one of SI_ET_* */
void *err_loc; /* commonly the server, NULL when SI_ET_NONE */
- struct connection conn; /* descriptor for a connection */
+ struct connection *conn; /* descriptor for a connection */
struct si_ops *ops; /* general operations at the stream interface layer */
void (*release)(struct stream_interface *); /* handler to call after the last close() */
switch (s->be->lbprm.algo & BE_LB_PARM) {
case BE_LB_HASH_SRC:
- if (s->req->prod->conn.addr.from.ss_family == AF_INET) {
+ if (s->req->prod->conn->addr.from.ss_family == AF_INET) {
srv = get_server_sh(s->be,
- (void *)&((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr,
+ (void *)&((struct sockaddr_in *)&s->req->prod->conn->addr.from)->sin_addr,
4);
}
- else if (s->req->prod->conn.addr.from.ss_family == AF_INET6) {
+ else if (s->req->prod->conn->addr.from.ss_family == AF_INET6) {
srv = get_server_sh(s->be,
- (void *)&((struct sockaddr_in6 *)&s->req->prod->conn.addr.from)->sin6_addr,
+ (void *)&((struct sockaddr_in6 *)&s->req->prod->conn->addr.from)->sin6_addr,
16);
}
else {
set_target_proxy(&s->target, s->be);
}
else if ((s->be->options & PR_O_HTTP_PROXY) &&
- is_addr(&s->req->cons->conn.addr.to)) {
+ is_addr(&s->req->cons->conn->addr.to)) {
/* in proxy mode, we need a valid destination address */
set_target_proxy(&s->target, s->be);
}
if (!(s->flags & SN_ASSIGNED))
return SRV_STATUS_INTERNAL;
- s->req->cons->conn.addr.to = target_srv(&s->target)->addr;
+ s->req->cons->conn->addr.to = target_srv(&s->target)->addr;
- if (!is_addr(&s->req->cons->conn.addr.to)) {
+ if (!is_addr(&s->req->cons->conn->addr.to)) {
/* if the server has no address, we use the same address
* the client asked, which is handy for remapping ports
* locally on multiple addresses at once.
*/
if (!(s->be->options & PR_O_TRANSP))
- conn_get_to_addr(&s->req->prod->conn);
+ conn_get_to_addr(s->req->prod->conn);
- if (s->req->prod->conn.addr.to.ss_family == AF_INET) {
- ((struct sockaddr_in *)&s->req->cons->conn.addr.to)->sin_addr = ((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr;
- } else if (s->req->prod->conn.addr.to.ss_family == AF_INET6) {
- ((struct sockaddr_in6 *)&s->req->cons->conn.addr.to)->sin6_addr = ((struct sockaddr_in6 *)&s->req->prod->conn.addr.to)->sin6_addr;
+ if (s->req->prod->conn->addr.to.ss_family == AF_INET) {
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.to)->sin_addr = ((struct sockaddr_in *)&s->req->prod->conn->addr.to)->sin_addr;
+ } else if (s->req->prod->conn->addr.to.ss_family == AF_INET6) {
+ ((struct sockaddr_in6 *)&s->req->cons->conn->addr.to)->sin6_addr = ((struct sockaddr_in6 *)&s->req->prod->conn->addr.to)->sin6_addr;
}
}
int base_port;
if (!(s->be->options & PR_O_TRANSP))
- conn_get_to_addr(&s->req->prod->conn);
+ conn_get_to_addr(s->req->prod->conn);
/* First, retrieve the port from the incoming connection */
- base_port = get_host_port(&s->req->prod->conn.addr.to);
+ base_port = get_host_port(&s->req->prod->conn->addr.to);
/* Second, assign the outgoing connection's port */
- base_port += get_host_port(&s->req->cons->conn.addr.to);
- set_host_port(&s->req->cons->conn.addr.to, base_port);
+ base_port += get_host_port(&s->req->cons->conn->addr.to);
+ set_host_port(&s->req->cons->conn->addr.to, base_port);
}
}
else if (s->be->options & PR_O_DISPATCH) {
/* connect to the defined dispatch addr */
- s->req->cons->conn.addr.to = s->be->dispatch_addr;
+ s->req->cons->conn->addr.to = s->be->dispatch_addr;
}
else if (s->be->options & PR_O_TRANSP) {
/* in transparent mode, use the original dest addr if no dispatch specified */
- conn_get_to_addr(&s->req->prod->conn);
+ conn_get_to_addr(s->req->prod->conn);
- if (s->req->prod->conn.addr.to.ss_family == AF_INET || s->req->prod->conn.addr.to.ss_family == AF_INET6) {
- memcpy(&s->req->cons->conn.addr.to, &s->req->prod->conn.addr.to, MIN(sizeof(s->req->cons->conn.addr.to), sizeof(s->req->prod->conn.addr.to)));
+ if (s->req->prod->conn->addr.to.ss_family == AF_INET || s->req->prod->conn->addr.to.ss_family == AF_INET6) {
+ memcpy(&s->req->cons->conn->addr.to, &s->req->prod->conn->addr.to, MIN(sizeof(s->req->cons->conn->addr.to), sizeof(s->req->prod->conn->addr.to)));
}
/* when we support IPv6 on the backend, we may add other tests */
//qfprintf(stderr, "Cannot get original server address.\n");
if (srv && srv->state & SRV_BIND_SRC) {
switch (srv->state & SRV_TPROXY_MASK) {
case SRV_TPROXY_ADDR:
- s->req->cons->conn.addr.from = srv->tproxy_addr;
+ s->req->cons->conn->addr.from = srv->tproxy_addr;
break;
case SRV_TPROXY_CLI:
case SRV_TPROXY_CIP:
/* FIXME: what can we do if the client connects in IPv6 or unix socket ? */
- s->req->cons->conn.addr.from = s->req->prod->conn.addr.from;
+ s->req->cons->conn->addr.from = s->req->prod->conn->addr.from;
break;
case SRV_TPROXY_DYN:
if (srv->bind_hdr_occ) {
int rewind;
/* bind to the IP in a header */
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_family = AF_INET;
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_port = 0;
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr = 0;
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_family = AF_INET;
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_port = 0;
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr = 0;
b_rew(s->req->buf, rewind = s->req->buf->o);
if (http_get_hdr(&s->txn.req, srv->bind_hdr_name, srv->bind_hdr_len,
&s->txn.hdr_idx, srv->bind_hdr_occ, NULL, &vptr, &vlen)) {
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr =
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr =
htonl(inetaddr_host_lim(vptr, vptr + vlen));
}
b_adv(s->req->buf, rewind);
}
break;
default:
- memset(&s->req->cons->conn.addr.from, 0, sizeof(s->req->cons->conn.addr.from));
+ memset(&s->req->cons->conn->addr.from, 0, sizeof(s->req->cons->conn->addr.from));
}
}
else if (s->be->options & PR_O_BIND_SRC) {
switch (s->be->options & PR_O_TPXY_MASK) {
case PR_O_TPXY_ADDR:
- s->req->cons->conn.addr.from = s->be->tproxy_addr;
+ s->req->cons->conn->addr.from = s->be->tproxy_addr;
break;
case PR_O_TPXY_CLI:
case PR_O_TPXY_CIP:
/* FIXME: what can we do if the client connects in IPv6 or socket unix? */
- s->req->cons->conn.addr.from = s->req->prod->conn.addr.from;
+ s->req->cons->conn->addr.from = s->req->prod->conn->addr.from;
break;
case PR_O_TPXY_DYN:
if (s->be->bind_hdr_occ) {
int rewind;
/* bind to the IP in a header */
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_family = AF_INET;
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_port = 0;
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr = 0;
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_family = AF_INET;
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_port = 0;
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr = 0;
b_rew(s->req->buf, rewind = s->req->buf->o);
if (http_get_hdr(&s->txn.req, s->be->bind_hdr_name, s->be->bind_hdr_len,
&s->txn.hdr_idx, s->be->bind_hdr_occ, NULL, &vptr, &vlen)) {
- ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr =
+ ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr =
htonl(inetaddr_host_lim(vptr, vptr + vlen));
}
b_adv(s->req->buf, rewind);
}
break;
default:
- memset(&s->req->cons->conn.addr.from, 0, sizeof(s->req->cons->conn.addr.from));
+ memset(&s->req->cons->conn->addr.from, 0, sizeof(s->req->cons->conn->addr.from));
}
}
#endif
}
/* the target was only on the session, assign it to the SI now */
- copy_target(&s->req->cons->conn.target, &s->target);
+ copy_target(&s->req->cons->conn->target, &s->target);
/* set the correct protocol on the output stream interface */
if (s->target.type == TARG_TYPE_SERVER) {
}
else if (s->target.type == TARG_TYPE_PROXY) {
/* proxies exclusively run on raw_sock right now */
- si_prepare_conn(s->req->cons, protocol_by_family(s->req->cons->conn.addr.to.ss_family), &raw_sock);
+ si_prepare_conn(s->req->cons, protocol_by_family(s->req->cons->conn->addr.to.ss_family), &raw_sock);
if (!si_ctrl(s->req->cons))
return SN_ERR_INTERNAL;
}
s->req->cons->send_proxy_ofs = 0;
if (s->target.type == TARG_TYPE_SERVER && (s->target.ptr.s->state & SRV_SEND_PROXY)) {
s->req->cons->send_proxy_ofs = 1; /* must compute size */
- conn_get_to_addr(&s->req->prod->conn);
+ conn_get_to_addr(s->req->prod->conn);
}
assign_tproxy_address(s);
#include <proto/ssl_sock.h>
#endif
+struct pool_head *pool2_connection;
+
+/* perform minimal intializations, report 0 in case of error, 1 if OK. */
+int init_connection()
+{
+ pool2_connection = create_pool("connection", sizeof (struct connection), MEM_F_SHARED);
+ return pool2_connection != NULL;
+}
+
/* I/O callback for fd-based connections. It calls the read/write handlers
* provided by the connection's sock_ops, which must be valid. It returns 0.
*/
{
/* we have a dedicated I/O handler for the stats */
stream_int_register_handler(&s->si[1], &cli_applet);
- copy_target(&s->target, &s->si[1].conn.target); // for logging only
- s->si[1].conn.xprt_ctx = s;
+ copy_target(&s->target, &s->si[1].conn->target); // for logging only
+ s->si[1].conn->xprt_ctx = s;
s->si[1].applet.st1 = 0;
s->si[1].applet.st0 = STAT_CLI_INIT;
static int stats_dump_table_head_to_buffer(struct chunk *msg, struct stream_interface *si,
struct proxy *proxy, struct proxy *target)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
chunk_printf(msg, "# table: %s, type: %s, size:%d, used:%d\n",
proxy->id, stktable_types[proxy->table.type].kw, proxy->table.size, proxy->table.current);
static void stats_sock_table_key_request(struct stream_interface *si, char **args, int action)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
struct proxy *px = si->applet.ctx.table.target;
struct stksess *ts;
uint32_t uint32_key;
static void stats_sock_table_request(struct stream_interface *si, char **args, int action)
{
si->applet.ctx.table.data_type = -1;
- si->conn.xprt_st = STAT_ST_INIT;
+ si->conn->xprt_st = STAT_ST_INIT;
si->applet.ctx.table.target = NULL;
si->applet.ctx.table.proxy = NULL;
si->applet.ctx.table.entry = NULL;
*/
static int stats_sock_parse_request(struct stream_interface *si, char *line)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
char *args[MAX_STATS_ARGS + 1];
int arg;
si->applet.ctx.stats.flags |= STAT_SHOW_STAT;
si->applet.ctx.stats.flags |= STAT_FMT_CSV;
- si->conn.xprt_st = STAT_ST_INIT;
+ si->conn->xprt_st = STAT_ST_INIT;
si->applet.st0 = STAT_CLI_O_INFO; // stats_dump_raw_to_buffer
}
else if (strcmp(args[1], "info") == 0) {
si->applet.ctx.stats.flags |= STAT_SHOW_INFO;
si->applet.ctx.stats.flags |= STAT_FMT_CSV;
- si->conn.xprt_st = STAT_ST_INIT;
+ si->conn->xprt_st = STAT_ST_INIT;
si->applet.st0 = STAT_CLI_O_INFO; // stats_dump_raw_to_buffer
}
else if (strcmp(args[1], "sess") == 0) {
- si->conn.xprt_st = STAT_ST_INIT;
+ si->conn->xprt_st = STAT_ST_INIT;
if (s->listener->bind_conf->level < ACCESS_LVL_OPER) {
si->applet.ctx.cli.msg = stats_permission_denied_msg;
si->applet.st0 = STAT_CLI_PRINT;
else
si->applet.ctx.errors.iid = -1;
si->applet.ctx.errors.px = NULL;
- si->conn.xprt_st = STAT_ST_INIT;
+ si->conn->xprt_st = STAT_ST_INIT;
si->applet.st0 = STAT_CLI_O_ERR; // stats_dump_errors_to_buffer
}
else if (strcmp(args[1], "table") == 0) {
chunk_init(&msg, trash, global.tune.bufsize);
- switch (si->conn.xprt_st) {
+ switch (si->conn->xprt_st) {
case STAT_ST_INIT:
/* the function had not been called yet */
- si->conn.xprt_st = STAT_ST_HEAD;
+ si->conn->xprt_st = STAT_ST_HEAD;
/* fall through */
case STAT_ST_HEAD:
return 0;
}
- si->conn.xprt_st = STAT_ST_INFO;
+ si->conn->xprt_st = STAT_ST_INFO;
/* fall through */
case STAT_ST_INFO:
si->applet.ctx.stats.px = proxy;
si->applet.ctx.stats.px_st = STAT_PX_ST_INIT;
si->applet.ctx.stats.sv = NULL;
- si->conn.xprt_st = STAT_ST_LIST;
+ si->conn->xprt_st = STAT_ST_LIST;
/* fall through */
case STAT_ST_LIST:
/* here, we just have reached the last proxy */
}
- si->conn.xprt_st = STAT_ST_END;
+ si->conn->xprt_st = STAT_ST_END;
/* fall through */
case STAT_ST_END:
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
/* fall through */
case STAT_ST_FIN:
default:
/* unknown state ! */
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
return 1;
}
}
*/
static int stats_http_redir(struct stream_interface *si, struct uri_auth *uri)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
struct chunk msg;
chunk_init(&msg, trash, global.tune.bufsize);
- switch (si->conn.xprt_st) {
+ switch (si->conn->xprt_st) {
case STAT_ST_INIT:
chunk_printf(&msg,
"HTTP/1.0 303 See Other\r\n"
if (!(s->flags & SN_FINST_MASK))
s->flags |= SN_FINST_R;
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
return 1;
}
return 1;
*/
static void http_stats_io_handler(struct stream_interface *si)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
struct channel *req = si->ob;
struct channel *res = si->ib;
*/
static int stats_dump_http(struct stream_interface *si, struct uri_auth *uri)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
struct channel *rep = si->ib;
struct proxy *px;
struct chunk msg;
chunk_init(&msg, trash, global.tune.bufsize);
- switch (si->conn.xprt_st) {
+ switch (si->conn->xprt_st) {
case STAT_ST_INIT:
chunk_printf(&msg,
"HTTP/1.0 200 OK\r\n"
if (s->txn.meth == HTTP_METH_HEAD) {
/* that's all we return in case of HEAD request */
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
return 1;
}
- si->conn.xprt_st = STAT_ST_HEAD; /* let's start producing data */
+ si->conn->xprt_st = STAT_ST_HEAD; /* let's start producing data */
/* fall through */
case STAT_ST_HEAD:
if (bi_putchk(rep, &msg) == -1)
return 0;
- si->conn.xprt_st = STAT_ST_INFO;
+ si->conn->xprt_st = STAT_ST_INFO;
/* fall through */
case STAT_ST_INFO:
si->applet.ctx.stats.px = proxy;
si->applet.ctx.stats.px_st = STAT_PX_ST_INIT;
- si->conn.xprt_st = STAT_ST_LIST;
+ si->conn->xprt_st = STAT_ST_LIST;
/* fall through */
case STAT_ST_LIST:
}
/* here, we just have reached the last proxy */
- si->conn.xprt_st = STAT_ST_END;
+ si->conn->xprt_st = STAT_ST_END;
/* fall through */
case STAT_ST_END:
return 0;
}
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
/* fall through */
case STAT_ST_FIN:
default:
/* unknown state ! */
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
return -1;
}
}
*/
static int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struct uri_auth *uri)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
struct channel *rep = si->ib;
struct server *sv, *svs; /* server and server-state, server-state=server or server->track */
struct listener *l;
sess->uniq_id,
sess->listener->proto->name);
- switch (addr_to_str(&sess->si[0].conn.addr.from, pn, sizeof(pn))) {
+ switch (addr_to_str(&sess->si[0].conn->addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " source=%s:%d\n",
- pn, get_host_port(&sess->si[0].conn.addr.from));
+ pn, get_host_port(&sess->si[0].conn->addr.from));
break;
case AF_UNIX:
chunk_printf(&msg, " source=unix:%d\n", sess->listener->luid);
sess->listener ? sess->listener->name ? sess->listener->name : "?" : "?",
sess->listener ? sess->listener->luid : 0);
- conn_get_to_addr(&sess->si[0].conn);
- switch (addr_to_str(&sess->si[0].conn.addr.to, pn, sizeof(pn))) {
+ conn_get_to_addr(sess->si[0].conn);
+ switch (addr_to_str(&sess->si[0].conn->addr.to, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " addr=%s:%d\n",
- pn, get_host_port(&sess->si[0].conn.addr.to));
+ pn, get_host_port(&sess->si[0].conn->addr.to));
break;
case AF_UNIX:
chunk_printf(&msg, " addr=unix:%d\n", sess->listener->luid);
else
chunk_printf(&msg, " backend=<NONE> (id=-1 mode=-)");
- conn_get_from_addr(&sess->si[1].conn);
- switch (addr_to_str(&sess->si[1].conn.addr.from, pn, sizeof(pn))) {
+ conn_get_from_addr(sess->si[1].conn);
+ switch (addr_to_str(&sess->si[1].conn->addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " addr=%s:%d\n",
- pn, get_host_port(&sess->si[1].conn.addr.from));
+ pn, get_host_port(&sess->si[1].conn->addr.from));
break;
case AF_UNIX:
chunk_printf(&msg, " addr=unix\n");
else
chunk_printf(&msg, " server=<NONE> (id=-1)");
- conn_get_to_addr(&sess->si[1].conn);
- switch (addr_to_str(&sess->si[1].conn.addr.to, pn, sizeof(pn))) {
+ conn_get_to_addr(sess->si[1].conn);
+ switch (addr_to_str(&sess->si[1].conn->addr.to, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " addr=%s:%d\n",
- pn, get_host_port(&sess->si[1].conn.addr.to));
+ pn, get_host_port(&sess->si[1].conn->addr.to));
break;
case AF_UNIX:
chunk_printf(&msg, " addr=unix\n");
/* If we're forced to shut down, we might have to remove our
* reference to the last session being dumped.
*/
- if (si->conn.xprt_st == STAT_ST_LIST) {
+ if (si->conn->xprt_st == STAT_ST_LIST) {
if (!LIST_ISEMPTY(&si->applet.ctx.sess.bref.users)) {
LIST_DEL(&si->applet.ctx.sess.bref.users);
LIST_INIT(&si->applet.ctx.sess.bref.users);
chunk_init(&msg, trash, global.tune.bufsize);
- switch (si->conn.xprt_st) {
+ switch (si->conn->xprt_st) {
case STAT_ST_INIT:
/* the function had not been called yet, let's prepare the
* buffer for a response. We initialize the current session
*/
LIST_INIT(&si->applet.ctx.sess.bref.users);
si->applet.ctx.sess.bref.ref = sessions.n;
- si->conn.xprt_st = STAT_ST_LIST;
+ si->conn->xprt_st = STAT_ST_LIST;
/* fall through */
case STAT_ST_LIST:
curr_sess->listener->proto->name);
- switch (addr_to_str(&curr_sess->si[0].conn.addr.from, pn, sizeof(pn))) {
+ switch (addr_to_str(&curr_sess->si[0].conn->addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg,
" src=%s:%d fe=%s be=%s srv=%s",
pn,
- get_host_port(&curr_sess->si[0].conn.addr.from),
+ get_host_port(&curr_sess->si[0].conn->addr.from),
curr_sess->fe->id,
(curr_sess->be->cap & PR_CAP_BE) ? curr_sess->be->id : "<NONE>",
target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "<none>"
return 1;
}
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
/* fall through */
default:
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
return 1;
}
}
*/
static int stats_table_request(struct stream_interface *si, bool show)
{
- struct session *s = si->conn.xprt_ctx;
+ struct session *s = si->conn->xprt_ctx;
struct chunk msg;
struct ebmb_node *eb;
int dt;
bool skip_entry;
/*
- * We have 3 possible states in si->conn.xprt_st :
+ * We have 3 possible states in si->conn->xprt_st :
* - STAT_ST_INIT : the first call
* - STAT_ST_INFO : the proxy pointer points to the next table to
* dump, the entry pointer is NULL ;
if (unlikely(si->ib->flags & (CF_WRITE_ERROR|CF_SHUTW))) {
/* in case of abort, remove any refcount we might have set on an entry */
- if (si->conn.xprt_st == STAT_ST_LIST) {
+ if (si->conn->xprt_st == STAT_ST_LIST) {
si->applet.ctx.table.entry->ref_cnt--;
stksess_kill_if_expired(&si->applet.ctx.table.proxy->table, si->applet.ctx.table.entry);
}
chunk_init(&msg, trash, global.tune.bufsize);
- while (si->conn.xprt_st != STAT_ST_FIN) {
- switch (si->conn.xprt_st) {
+ while (si->conn->xprt_st != STAT_ST_FIN) {
+ switch (si->conn->xprt_st) {
case STAT_ST_INIT:
si->applet.ctx.table.proxy = si->applet.ctx.table.target;
if (!si->applet.ctx.table.proxy)
si->applet.ctx.table.proxy = proxy;
si->applet.ctx.table.entry = NULL;
- si->conn.xprt_st = STAT_ST_INFO;
+ si->conn->xprt_st = STAT_ST_INFO;
break;
case STAT_ST_INFO:
if (!si->applet.ctx.table.proxy ||
(si->applet.ctx.table.target &&
si->applet.ctx.table.proxy != si->applet.ctx.table.target)) {
- si->conn.xprt_st = STAT_ST_END;
+ si->conn->xprt_st = STAT_ST_END;
break;
}
if (eb) {
si->applet.ctx.table.entry = ebmb_entry(eb, struct stksess, key);
si->applet.ctx.table.entry->ref_cnt++;
- si->conn.xprt_st = STAT_ST_LIST;
+ si->conn->xprt_st = STAT_ST_LIST;
break;
}
}
stksess_kill(&si->applet.ctx.table.proxy->table, si->applet.ctx.table.entry);
si->applet.ctx.table.proxy = si->applet.ctx.table.proxy->next;
- si->conn.xprt_st = STAT_ST_INFO;
+ si->conn->xprt_st = STAT_ST_INFO;
break;
case STAT_ST_END:
- si->conn.xprt_st = STAT_ST_FIN;
+ si->conn->xprt_st = STAT_ST_FIN;
break;
}
}
else {
char pn[INET6_ADDRSTRLEN], sn[INET6_ADDRSTRLEN];
- conn_get_from_addr(&s->req->prod->conn);
- conn_get_to_addr(&s->req->prod->conn);
+ conn_get_from_addr(s->req->prod->conn);
+ conn_get_to_addr(s->req->prod->conn);
- switch (addr_to_str(&s->req->prod->conn.addr.from, pn, sizeof(pn))) {
+ switch (addr_to_str(&s->req->prod->conn->addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
- addr_to_str(&s->req->prod->conn.addr.to, sn, sizeof(sn));
+ addr_to_str(&s->req->prod->conn->addr.to, sn, sizeof(sn));
send_log(s->fe, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
- pn, get_host_port(&s->req->prod->conn.addr.from),
- sn, get_host_port(&s->req->prod->conn.addr.to),
+ pn, get_host_port(&s->req->prod->conn->addr.from),
+ sn, get_host_port(&s->req->prod->conn->addr.to),
s->fe->id, (s->fe->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
break;
case AF_UNIX:
char pn[INET6_ADDRSTRLEN];
int len = 0;
- conn_get_from_addr(&s->req->prod->conn);
+ conn_get_from_addr(s->req->prod->conn);
- switch (addr_to_str(&s->req->prod->conn.addr.from, pn, sizeof(pn))) {
+ switch (addr_to_str(&s->req->prod->conn->addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [%s:%d]\n",
s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
- pn, get_host_port(&s->req->prod->conn.addr.from));
+ pn, get_host_port(&s->req->prod->conn->addr.from));
break;
case AF_UNIX:
/* UNIX socket, only the destination is known */
#include <proto/backend.h>
#include <proto/channel.h>
#include <proto/checks.h>
+#include <proto/connection.h>
#include <proto/fd.h>
#include <proto/hdr_idx.h>
#include <proto/listener.h>
signal_init();
init_task();
init_session();
+ init_connection();
/* warning, we init buffers later */
init_pendconn();
init_proto_http();
}
pool_destroy2(pool2_session);
+ pool_destroy2(pool2_connection);
pool_destroy2(pool2_buffer);
pool_destroy2(pool2_channel);
pool_destroy2(pool2_requri);
break;
case LOG_FMT_CLIENTIP: // %Ci
- ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.from,
+ ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->conn->addr.from,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
break;
case LOG_FMT_CLIENTPORT: // %Cp
- if (s->req->prod->conn.addr.from.ss_family == AF_UNIX) {
+ if (s->req->prod->conn->addr.from.ss_family == AF_UNIX) {
ret = ltoa_o(s->listener->luid, tmplog, dst + maxsize - tmplog);
} else {
- ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.from,
+ ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->conn->addr.from,
dst + maxsize - tmplog, tmp);
}
if (ret == NULL)
break;
case LOG_FMT_FRONTENDIP: // %Fi
- conn_get_to_addr(&s->req->prod->conn);
- ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.to,
+ conn_get_to_addr(s->req->prod->conn);
+ ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->conn->addr.to,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
break;
case LOG_FMT_FRONTENDPORT: // %Fp
- conn_get_to_addr(&s->req->prod->conn);
- if (s->req->prod->conn.addr.to.ss_family == AF_UNIX) {
+ conn_get_to_addr(s->req->prod->conn);
+ if (s->req->prod->conn->addr.to.ss_family == AF_UNIX) {
ret = ltoa_o(s->listener->luid,
tmplog, dst + maxsize - tmplog);
} else {
- ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.to,
+ ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->conn->addr.to,
dst + maxsize - tmplog, tmp);
}
if (ret == NULL)
break;
case LOG_FMT_BACKENDIP: // %Bi
- ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.from,
+ ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->conn->addr.from,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
break;
case LOG_FMT_BACKENDPORT: // %Bp
- ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.from,
+ ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->conn->addr.from,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
break;
case LOG_FMT_SERVERIP: // %Si
- ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.to,
+ ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->conn->addr.to,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
break;
case LOG_FMT_SERVERPORT: // %Sp
- ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.to,
+ ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->conn->addr.to,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
case LOG_FMT_SSL_CIPHER: // %sslc
src = NULL;
if (s->listener->xprt == &ssl_sock)
- src = ssl_sock_get_cipher_name(&s->si[0].conn);
+ src = ssl_sock_get_cipher_name(s->si[0].conn);
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
case LOG_FMT_SSL_VERSION: // %sslv
src = NULL;
if (s->listener->xprt == &ssl_sock)
- src = ssl_sock_get_proto_version(&s->si[0].conn);
+ src = ssl_sock_get_proto_version(s->si[0].conn);
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
{
struct task *t = (struct task *)si->owner;
struct session *s = (struct session *)t->context;
- struct peer_session *ps = (struct peer_session *)si->conn.xprt_ctx;
+ struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
- /* si->conn.xprt_ctx is not a peer session */
+ /* si->conn->xprt_ctx is not a peer session */
if (si->applet.st0 < PEER_SESSION_SENDSUCCESS)
return;
switchstate:
switch(si->applet.st0) {
case PEER_SESSION_ACCEPT:
- si->conn.xprt_ctx = NULL;
+ si->conn->xprt_ctx = NULL;
si->applet.st0 = PEER_SESSION_GETVERSION;
/* fall through */
case PEER_SESSION_GETVERSION:
goto switchstate;
}
- si->conn.xprt_ctx = curpeer;
+ si->conn->xprt_ctx = curpeer;
si->applet.st0 = PEER_SESSION_GETTABLE;
/* fall through */
}
case PEER_SESSION_GETTABLE: {
- struct peer *curpeer = (struct peer *)si->conn.xprt_ctx;
+ struct peer *curpeer = (struct peer *)si->conn->xprt_ctx;
struct shared_table *st;
struct peer_session *ps = NULL;
unsigned long key_type;
if (reql <= 0) { /* closed or EOL not found */
if (reql == 0)
goto out;
- si->conn.xprt_ctx = NULL;
+ si->conn->xprt_ctx = NULL;
si->applet.st0 = PEER_SESSION_END;
goto switchstate;
}
- /* Re init si->conn.xprt_ctx to null, to handle correctly a release case */
- si->conn.xprt_ctx = NULL;
+ /* Re init si->conn->xprt_ctx to null, to handle correctly a release case */
+ si->conn->xprt_ctx = NULL;
if (trash[reql-1] != '\n') {
/* Incomplete line, we quit */
p = strchr(p+1, ' ');
if (!p) {
- si->conn.xprt_ctx = NULL;
+ si->conn->xprt_ctx = NULL;
si->applet.st0 = PEER_SESSION_EXIT;
si->applet.st1 = PEER_SESSION_ERRPROTO;
goto switchstate;
goto switchstate;
}
- si->conn.xprt_ctx = ps;
+ si->conn->xprt_ctx = ps;
si->applet.st0 = PEER_SESSION_SENDSUCCESS;
/* fall through */
}
case PEER_SESSION_SENDSUCCESS:{
- struct peer_session *ps = (struct peer_session *)si->conn.xprt_ctx;
+ struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
repl = snprintf(trash, global.tune.bufsize, "%d\n", PEER_SESSION_SUCCESSCODE);
repl = bi_putblk(si->ib, trash, repl);
goto switchstate;
}
case PEER_SESSION_CONNECT: {
- struct peer_session *ps = (struct peer_session *)si->conn.xprt_ctx;
+ struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
/* Send headers */
repl = snprintf(trash, global.tune.bufsize,
/* fall through */
}
case PEER_SESSION_GETSTATUS: {
- struct peer_session *ps = (struct peer_session *)si->conn.xprt_ctx;
+ struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
if (si->ib->flags & CF_WRITE_PARTIAL)
ps->statuscode = PEER_SESSION_CONNECTEDCODE;
/* fall through */
}
case PEER_SESSION_WAITMSG: {
- struct peer_session *ps = (struct peer_session *)si->conn.xprt_ctx;
+ struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
char c;
int totl = 0;
{
struct stream_interface *oldsi;
- if (session->si[0].conn.target.type == TARG_TYPE_APPLET &&
- session->si[0].conn.target.ptr.a == &peer_applet) {
+ if (session->si[0].conn->target.type == TARG_TYPE_APPLET &&
+ session->si[0].conn->target.ptr.a == &peer_applet) {
oldsi = &session->si[0];
}
else {
/* call release to reinit resync states if needed */
peer_session_release(oldsi);
oldsi->applet.st0 = PEER_SESSION_END;
- oldsi->conn.xprt_ctx = NULL;
+ oldsi->conn->xprt_ctx = NULL;
task_wakeup(session->task, TASK_WOKEN_MSG);
}
{
/* we have a dedicated I/O handler for the stats */
stream_int_register_handler(&s->si[1], &peer_applet);
- copy_target(&s->target, &s->si[1].conn.target); // for logging only
- s->si[1].conn.xprt_ctx = s;
+ copy_target(&s->target, &s->si[1].conn->target); // for logging only
+ s->si[1].conn->xprt_ctx = s;
s->si[1].applet.st0 = PEER_SESSION_ACCEPT;
tv_zero(&s->logs.tv_request);
goto out_close;
}
+ if (unlikely((s->si[0].conn = pool_alloc2(pool2_connection)) == NULL))
+ goto out_fail_conn0;
+
+ if (unlikely((s->si[1].conn = pool_alloc2(pool2_connection)) == NULL))
+ goto out_fail_conn1;
+
LIST_ADDQ(&sessions, &s->list);
LIST_INIT(&s->back_refs);
t->context = s;
t->nice = l->nice;
- memcpy(&s->si[1].conn.addr.to, &peer->addr, sizeof(s->si[1].conn.addr.to));
+ memcpy(&s->si[1].conn->addr.to, &peer->addr, sizeof(s->si[1].conn->addr.to));
s->task = t;
s->listener = l;
s->req = s->rep = NULL; /* will be allocated later */
- s->si[0].conn.t.sock.fd = -1;
- s->si[0].conn.flags = CO_FL_NONE;
+ s->si[0].conn->t.sock.fd = -1;
+ s->si[0].conn->flags = CO_FL_NONE;
s->si[0].owner = t;
s->si[0].state = s->si[0].prev_state = SI_ST_EST;
s->si[0].err_type = SI_ET_NONE;
s->si[0].err_loc = NULL;
s->si[0].release = NULL;
s->si[0].send_proxy_ofs = 0;
- set_target_client(&s->si[0].conn.target, l);
+ set_target_client(&s->si[0].conn->target, l);
s->si[0].exp = TICK_ETERNITY;
s->si[0].flags = SI_FL_NONE;
if (s->fe->options2 & PR_O2_INDEPSTR)
stream_int_register_handler(&s->si[0], &peer_applet);
s->si[0].applet.st0 = PEER_SESSION_CONNECT;
- s->si[0].conn.xprt_ctx = (void *)ps;
+ s->si[0].conn->xprt_ctx = (void *)ps;
- s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */
- s->si[1].conn.flags = CO_FL_NONE;
+ s->si[1].conn->t.sock.fd = -1; /* just to help with debugging */
+ s->si[1].conn->flags = CO_FL_NONE;
s->si[1].owner = t;
s->si[1].state = s->si[1].prev_state = SI_ST_ASS;
s->si[1].conn_retries = p->conn_retries;
s->si[1].err_loc = NULL;
s->si[1].release = NULL;
s->si[1].send_proxy_ofs = 0;
- set_target_proxy(&s->si[1].conn.target, s->be);
+ set_target_proxy(&s->si[1].conn->target, s->be);
si_prepare_conn(&s->si[1], peer->proto, peer->xprt);
s->si[1].exp = TICK_ETERNITY;
s->si[1].flags = SI_FL_NONE;
task_free(t);
out_free_session:
LIST_DEL(&s->list);
+ pool_free2(pool2_connection, s->si[1].conn);
+ out_fail_conn1:
+ pool_free2(pool2_connection, s->si[0].conn);
+ out_fail_conn0:
pool_free2(pool2_session, s);
out_close:
return s;
s->logs.tv_request = now;
s->task->nice = -32; /* small boost for HTTP statistics */
stream_int_register_handler(s->rep->prod, &http_stats_applet);
- copy_target(&s->target, &s->rep->prod->conn.target); // for logging only
- s->rep->prod->conn.xprt_ctx = s;
+ copy_target(&s->target, &s->rep->prod->conn->target); // for logging only
+ s->rep->prod->conn->xprt_ctx = s;
s->rep->prod->applet.st0 = s->rep->prod->applet.st1 = 0;
req->analysers = 0;
if (s->fe == s->be) /* report it if the request was intercepted by the frontend */
* parsing incoming request.
*/
if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) {
- url2sa(req->buf->p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->conn.addr.to);
+ url2sa(req->buf->p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->conn->addr.to);
}
/*
* and we found it, so don't do anything.
*/
}
- else if (s->req->prod->conn.addr.from.ss_family == AF_INET) {
+ else if (s->req->prod->conn->addr.from.ss_family == AF_INET) {
/* Add an X-Forwarded-For header unless the source IP is
* in the 'except' network range.
*/
if ((!s->fe->except_mask.s_addr ||
- (((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr.s_addr & s->fe->except_mask.s_addr)
+ (((struct sockaddr_in *)&s->req->prod->conn->addr.from)->sin_addr.s_addr & s->fe->except_mask.s_addr)
!= s->fe->except_net.s_addr) &&
(!s->be->except_mask.s_addr ||
- (((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr.s_addr & s->be->except_mask.s_addr)
+ (((struct sockaddr_in *)&s->req->prod->conn->addr.from)->sin_addr.s_addr & s->be->except_mask.s_addr)
!= s->be->except_net.s_addr)) {
int len;
unsigned char *pn;
- pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr;
+ pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->conn->addr.from)->sin_addr;
/* Note: we rely on the backend to get the header name to be used for
* x-forwarded-for, because the header is really meant for the backends.
goto return_bad_req;
}
}
- else if (s->req->prod->conn.addr.from.ss_family == AF_INET6) {
+ else if (s->req->prod->conn->addr.from.ss_family == AF_INET6) {
/* FIXME: for the sake of completeness, we should also support
* 'except' here, although it is mostly useless in this case.
*/
int len;
char pn[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6,
- (const void *)&((struct sockaddr_in6 *)(&s->req->prod->conn.addr.from))->sin6_addr,
+ (const void *)&((struct sockaddr_in6 *)(&s->req->prod->conn->addr.from))->sin6_addr,
pn, sizeof(pn));
/* Note: we rely on the backend to get the header name to be used for
if ((s->fe->options | s->be->options) & PR_O_ORGTO) {
/* FIXME: don't know if IPv6 can handle that case too. */
- if (s->req->prod->conn.addr.from.ss_family == AF_INET) {
+ if (s->req->prod->conn->addr.from.ss_family == AF_INET) {
/* Add an X-Original-To header unless the destination IP is
* in the 'except' network range.
*/
- conn_get_to_addr(&s->req->prod->conn);
+ conn_get_to_addr(s->req->prod->conn);
- if (s->req->prod->conn.addr.to.ss_family == AF_INET &&
+ if (s->req->prod->conn->addr.to.ss_family == AF_INET &&
((!s->fe->except_mask_to.s_addr ||
- (((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr.s_addr & s->fe->except_mask_to.s_addr)
+ (((struct sockaddr_in *)&s->req->prod->conn->addr.to)->sin_addr.s_addr & s->fe->except_mask_to.s_addr)
!= s->fe->except_to.s_addr) &&
(!s->be->except_mask_to.s_addr ||
- (((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr.s_addr & s->be->except_mask_to.s_addr)
+ (((struct sockaddr_in *)&s->req->prod->conn->addr.to)->sin_addr.s_addr & s->be->except_mask_to.s_addr)
!= s->be->except_to.s_addr))) {
int len;
unsigned char *pn;
- pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr;
+ pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->conn->addr.to)->sin_addr;
/* Note: we rely on the backend to get the header name to be used for
* x-original-to, because the header is really meant for the backends.
clear_target(&s->target);
s->req->cons->state = s->req->cons->prev_state = SI_ST_INI;
- s->req->cons->conn.t.sock.fd = -1; /* just to help with debugging */
- s->req->cons->conn.flags = CO_FL_NONE;
+ s->req->cons->conn->t.sock.fd = -1; /* just to help with debugging */
+ s->req->cons->conn->flags = CO_FL_NONE;
s->req->cons->err_type = SI_ET_NONE;
s->req->cons->conn_retries = 0; /* used for logging too */
s->req->cons->err_loc = NULL;
es->sid = s->uniq_id;
es->srv = target_srv(&s->target);
es->oe = other_end;
- es->src = s->req->prod->conn.addr.from;
+ es->src = s->req->prod->conn->addr.from;
es->state = state;
es->ev_id = error_snapshot_id++;
es->b_flags = chn->flags;
CHECK_HTTP_MESSAGE_FIRST();
/* Parse HTTP request */
- url2sa(txn->req.chn->buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
- if (((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_family != AF_INET)
+ url2sa(txn->req.chn->buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn->addr.to);
+ if (((struct sockaddr_in *)&l4->req->cons->conn->addr.to)->sin_family != AF_INET)
return 0;
smp->type = SMP_T_IPV4;
- smp->data.ipv4 = ((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_addr;
+ smp->data.ipv4 = ((struct sockaddr_in *)&l4->req->cons->conn->addr.to)->sin_addr;
/*
* If we are parsing url in frontend space, we prepare backend stage
CHECK_HTTP_MESSAGE_FIRST();
/* Same optimization as url_ip */
- url2sa(txn->req.chn->buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
+ url2sa(txn->req.chn->buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn->addr.to);
smp->type = SMP_T_UINT;
- smp->data.uint = ntohs(((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_port);
+ smp->data.uint = ntohs(((struct sockaddr_in *)&l4->req->cons->conn->addr.to)->sin_port);
if (px->options & PR_O_HTTP_PROXY)
l4->flags |= SN_ADDR_SET;
* to consider rule->act_prm->trk_ctr.type.
*/
t = rule->act_prm.trk_ctr.table.t;
- ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn.addr.from));
+ ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn->addr.from));
if (ts) {
session_track_stkctr1(s, t, ts);
if (s->fe != s->be)
* to consider rule->act_prm->trk_ctr.type.
*/
t = rule->act_prm.trk_ctr.table.t;
- ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn.addr.from));
+ ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn->addr.from));
if (ts) {
session_track_stkctr2(s, t, ts);
if (s->fe != s->be)
* to consider rule->act_prm->trk_ctr.type.
*/
t = rule->act_prm.trk_ctr.table.t;
- ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn.addr.from));
+ ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn->addr.from));
if (ts)
session_track_stkctr1(s, t, ts);
}
* to consider rule->act_prm->trk_ctr.type.
*/
t = rule->act_prm.trk_ctr.table.t;
- ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn.addr.from));
+ ts = stktable_get_entry(t, addr_to_stktable_key(&s->si[0].conn->addr.from));
if (ts)
session_track_stkctr2(s, t, ts);
}
smp_fetch_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- switch (l4->si[0].conn.addr.from.ss_family) {
+ switch (l4->si[0].conn->addr.from.ss_family) {
case AF_INET:
- smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].conn.addr.from)->sin_addr;
+ smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].conn->addr.from)->sin_addr;
smp->type = SMP_T_IPV4;
break;
case AF_INET6:
- smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].conn.addr.from))->sin6_addr;
+ smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].conn->addr.from))->sin6_addr;
smp->type = SMP_T_IPV6;
break;
default:
const struct arg *args, struct sample *smp)
{
smp->type = SMP_T_UINT;
- if (!(smp->data.uint = get_host_port(&l4->si[0].conn.addr.from)))
+ if (!(smp->data.uint = get_host_port(&l4->si[0].conn->addr.from)))
return 0;
smp->flags = 0;
smp_fetch_dst(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- conn_get_to_addr(&l4->si[0].conn);
+ conn_get_to_addr(l4->si[0].conn);
- switch (l4->si[0].conn.addr.to.ss_family) {
+ switch (l4->si[0].conn->addr.to.ss_family) {
case AF_INET:
- smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].conn.addr.to)->sin_addr;
+ smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].conn->addr.to)->sin_addr;
smp->type = SMP_T_IPV4;
break;
case AF_INET6:
- smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].conn.addr.to))->sin6_addr;
+ smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].conn->addr.to))->sin6_addr;
smp->type = SMP_T_IPV6;
break;
default:
smp_fetch_dport(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- conn_get_to_addr(&l4->si[0].conn);
+ conn_get_to_addr(l4->si[0].conn);
smp->type = SMP_T_UINT;
- if (!(smp->data.uint = get_host_port(&l4->si[0].conn.addr.to)))
+ if (!(smp->data.uint = get_host_port(&l4->si[0].conn->addr.to)))
return 0;
smp->flags = 0;
if (unlikely((s = pool_alloc2(pool2_session)) == NULL))
goto out_close;
+ if (unlikely((s->si[0].conn = pool_alloc2(pool2_connection)) == NULL))
+ goto out_fail_conn0;
+
+ if (unlikely((s->si[1].conn = pool_alloc2(pool2_connection)) == NULL))
+ goto out_fail_conn1;
+
/* minimum session initialization required for an embryonic session is
* fairly low. We need very little to execute L4 ACLs, then we need a
* task to make the client-side connection live on its own.
s->fe = p;
/* OK, we're keeping the session, so let's properly initialize the session */
- s->si[0].conn.t.sock.fd = cfd;
- s->si[0].conn.ctrl = l->proto;
- s->si[0].conn.flags = CO_FL_NONE;
- s->si[0].conn.addr.from = *addr;
- set_target_client(&s->si[0].conn.target, l);
+ s->si[0].conn->t.sock.fd = cfd;
+ s->si[0].conn->ctrl = l->proto;
+ s->si[0].conn->flags = CO_FL_NONE;
+ s->si[0].conn->addr.from = *addr;
+ set_target_client(&s->si[0].conn->target, l);
s->logs.accept_date = date; /* user-visible date for logging */
s->logs.tv_accept = now; /* corrected date for internal use */
/* wait for a PROXY protocol header */
if (l->options & LI_O_ACC_PROXY) {
- s->si[0].conn.flags |= CO_FL_ACCEPT_PROXY;
- conn_sock_want_recv(&s->si[0].conn);
+ s->si[0].conn->flags |= CO_FL_ACCEPT_PROXY;
+ conn_sock_want_recv(s->si[0].conn);
}
if (unlikely((t = task_new()) == NULL))
* but not initialized. Also note we need to be careful as the stream
* int is not initialized yet.
*/
- conn_prepare(&s->si[0].conn, &sess_conn_cb, l->proto, l->xprt, s);
+ conn_prepare(s->si[0].conn, &sess_conn_cb, l->proto, l->xprt, s);
/* finish initialization of the accepted file descriptor */
fd_insert(cfd);
- fdtab[cfd].owner = &s->si[0].conn;
+ fdtab[cfd].owner = s->si[0].conn;
fdtab[cfd].iocb = conn_fd_handler;
- conn_data_want_recv(&s->si[0].conn);
- if (conn_xprt_init(&s->si[0].conn) < 0)
+ conn_data_want_recv(s->si[0].conn);
+ if (conn_xprt_init(s->si[0].conn) < 0)
goto out_free_task;
/* OK, now either we have a pending handshake to execute with and
* set the I/O timeout to the frontend's client timeout.
*/
- if (s->si[0].conn.flags & CO_FL_HANDSHAKE) {
+ if (s->si[0].conn->flags & CO_FL_HANDSHAKE) {
t->process = expire_mini_session;
t->expire = tick_add_ifset(now_ms, p->timeout.client);
task_queue(t);
- s->si[0].conn.flags |= CO_FL_INIT_DATA | CO_FL_WAKE_DATA;
+ s->si[0].conn->flags |= CO_FL_INIT_DATA | CO_FL_WAKE_DATA;
return 1;
}
p->feconn--;
if (s->stkctr1_entry || s->stkctr2_entry)
session_store_counters(s);
+ pool_free2(pool2_connection, s->si[1].conn);
+ out_fail_conn1:
+ pool_free2(pool2_connection, s->si[0].conn);
+ out_fail_conn0:
pool_free2(pool2_session, s);
out_close:
if (ret < 0 && l->xprt == &raw_sock && p->mode == PR_MODE_HTTP) {
static void kill_mini_session(struct session *s)
{
/* kill the connection now */
- conn_xprt_close(&s->si[0].conn);
+ conn_xprt_close(s->si[0].conn);
s->fe->feconn--;
if (s->stkctr1_entry || s->stkctr2_entry)
task_delete(s->task);
task_free(s->task);
- if (fdtab[s->si[0].conn.t.sock.fd].owner)
- fd_delete(s->si[0].conn.t.sock.fd);
+ if (fdtab[s->si[0].conn->t.sock.fd].owner)
+ fd_delete(s->si[0].conn->t.sock.fd);
else
- close(s->si[0].conn.t.sock.fd);
+ close(s->si[0].conn->t.sock.fd);
+ pool_free2(pool2_connection, s->si[1].conn);
+ pool_free2(pool2_connection, s->si[0].conn);
pool_free2(pool2_session, s);
}
/* pre-initialize the other side's stream interface to an INIT state. The
* callbacks will be initialized before attempting to connect.
*/
- s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */
- s->si[1].conn.flags = CO_FL_NONE;
+ s->si[1].conn->t.sock.fd = -1; /* just to help with debugging */
+ s->si[1].conn->flags = CO_FL_NONE;
s->si[1].owner = t;
s->si[1].state = s->si[1].prev_state = SI_ST_INI;
s->si[1].err_type = SI_ET_NONE;
s->si[1].err_loc = NULL;
s->si[1].release = NULL;
s->si[1].send_proxy_ofs = 0;
- clear_target(&s->si[1].conn.target);
+ clear_target(&s->si[1].conn->target);
si_prepare_embedded(&s->si[1]);
s->si[1].exp = TICK_ETERNITY;
s->si[1].flags = SI_FL_NONE;
txn->rsp.chn = s->rep;
/* finish initialization of the accepted file descriptor */
- conn_data_want_recv(&s->si[0].conn);
+ conn_data_want_recv(s->si[0].conn);
if (p->accept && (ret = p->accept(s)) <= 0) {
/* Either we had an unrecoverable error (<0) or work is
/* if logs require transport layer information, note it on the connection */
if (s->logs.logwait & LW_XPRT)
- s->si[0].conn.flags |= CO_FL_XPRT_TRACKED;
+ s->si[0].conn->flags |= CO_FL_XPRT_TRACKED;
/* we want the connection handler to notify the stream interface about updates. */
- s->si[0].conn.flags |= CO_FL_WAKE_DATA;
+ s->si[0].conn->flags |= CO_FL_WAKE_DATA;
/* it is important not to call the wakeup function directly but to
* pass through task_wakeup(), because this one knows how to apply
http_end_txn(s);
/* ensure the client-side transport layer is destroyed */
- s->si[0].conn.flags &= ~CO_FL_XPRT_TRACKED;
- conn_xprt_close(&s->si[0].conn);
+ s->si[0].conn->flags &= ~CO_FL_XPRT_TRACKED;
+ conn_xprt_close(s->si[0].conn);
for (i = 0; i < s->store_count; i++) {
if (!s->store[i].ts)
bref->ref = s->list.n;
}
LIST_DEL(&s->list);
+ pool_free2(pool2_connection, s->si[1].conn);
+ pool_free2(pool2_connection, s->si[0].conn);
pool_free2(pool2_session, s);
/* We may want to free the maximum amount of pools if the proxy is stopping */
si->state = SI_ST_CER;
fd_delete(si_fd(si));
- conn_xprt_close(&si->conn);
+ conn_xprt_close(si->conn);
if (si->release)
si->release(si);
if (!(s->req->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
s->req->to_forward &&
(global.tune.options & GTUNE_USE_SPLICE) &&
- (s->si[0].conn.xprt && s->si[0].conn.xprt->rcv_pipe && s->si[0].conn.xprt->snd_pipe) &&
- (s->si[1].conn.xprt && s->si[1].conn.xprt->rcv_pipe && s->si[1].conn.xprt->snd_pipe) &&
+ (s->si[0].conn->xprt && s->si[0].conn->xprt->rcv_pipe && s->si[0].conn->xprt->snd_pipe) &&
+ (s->si[1].conn->xprt && s->si[1].conn->xprt->rcv_pipe && s->si[1].conn->xprt->snd_pipe) &&
(pipes_used < global.maxpipes) &&
(((s->fe->options2|s->be->options2) & PR_O2_SPLIC_REQ) ||
(((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
*/
s->req->cons->state = SI_ST_REQ; /* new connection requested */
s->req->cons->conn_retries = s->be->conn_retries;
- if (unlikely(s->req->cons->conn.target.type == TARG_TYPE_APPLET &&
+ if (unlikely(s->req->cons->conn->target.type == TARG_TYPE_APPLET &&
!(si_ctrl(s->req->cons) && si_ctrl(s->req->cons)->connect))) {
s->req->cons->state = SI_ST_EST; /* connection established */
s->rep->flags |= CF_READ_ATTACHED; /* producer is now attached */
if (!(s->rep->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
s->rep->to_forward &&
(global.tune.options & GTUNE_USE_SPLICE) &&
- (s->si[0].conn.xprt && s->si[0].conn.xprt->rcv_pipe && s->si[0].conn.xprt->snd_pipe) &&
- (s->si[1].conn.xprt && s->si[1].conn.xprt->rcv_pipe && s->si[1].conn.xprt->snd_pipe) &&
+ (s->si[0].conn->xprt && s->si[0].conn->xprt->rcv_pipe && s->si[0].conn->xprt->snd_pipe) &&
+ (s->si[1].conn->xprt && s->si[1].conn->xprt->rcv_pipe && s->si[1].conn->xprt->snd_pipe) &&
(pipes_used < global.maxpipes) &&
(((s->fe->options2|s->be->options2) & PR_O2_SPLIC_RTR) ||
(((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
session_process_counters(s);
- if (s->rep->cons->state == SI_ST_EST && s->rep->cons->conn.target.type != TARG_TYPE_APPLET)
+ if (s->rep->cons->state == SI_ST_EST && s->rep->cons->conn->target.type != TARG_TYPE_APPLET)
si_update(s->rep->cons);
- if (s->req->cons->state == SI_ST_EST && s->req->cons->conn.target.type != TARG_TYPE_APPLET)
+ if (s->req->cons->state == SI_ST_EST && s->req->cons->conn->target.type != TARG_TYPE_APPLET)
si_update(s->req->cons);
s->req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
/* Call the stream interfaces' I/O handlers when embedded.
* Note that this one may wake the task up again.
*/
- if (s->req->cons->conn.target.type == TARG_TYPE_APPLET ||
- s->rep->cons->conn.target.type == TARG_TYPE_APPLET) {
- if (s->req->cons->conn.target.type == TARG_TYPE_APPLET)
- s->req->cons->conn.target.ptr.a->fct(s->req->cons);
- if (s->rep->cons->conn.target.type == TARG_TYPE_APPLET)
- s->rep->cons->conn.target.ptr.a->fct(s->rep->cons);
+ if (s->req->cons->conn->target.type == TARG_TYPE_APPLET ||
+ s->rep->cons->conn->target.type == TARG_TYPE_APPLET) {
+ if (s->req->cons->conn->target.type == TARG_TYPE_APPLET)
+ s->req->cons->conn->target.ptr.a->fct(s->req->cons);
+ if (s->rep->cons->conn->target.type == TARG_TYPE_APPLET)
+ s->rep->cons->conn->target.ptr.a->fct(s->rep->cons);
if (task_in_rq(t)) {
/* If we woke up, we don't want to requeue the
* task to the wait queue, but rather requeue
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
struct stktable_key *key;
void *ptr;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
{
struct stktable_key *key;
- key = addr_to_stktable_key(&l4->si[0].conn.addr.from);
+ key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
if (!key)
return 0;
smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
smp->flags = 0;
smp->type = SMP_T_BOOL;
- smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & l4->si[0].conn.xprt_st ? 1 : 0;
+ smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & l4->si[0].conn->xprt_st ? 1 : 0;
return 1;
}
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate, it increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate, it increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate, it increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate, it increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate, it increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
{
X509 *crt;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
return 0;
X509 *crt;
int nid;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
return 0;
X509 *crt;
int nid;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_peer_certificate increase X509 * ref count */
- crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_peer_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
return 0;
const struct arg *args, struct sample *smp)
{
smp->type = SMP_T_BOOL;
- smp->data.uint = (l4->si[0].conn.xprt == &ssl_sock);
+ smp->data.uint = (l4->si[0].conn->xprt == &ssl_sock);
return 1;
}
{
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
smp->type = SMP_T_BOOL;
- smp->data.uint = (l4->si[0].conn.xprt == &ssl_sock) &&
- l4->si[0].conn.xprt_ctx &&
- SSL_get_servername(l4->si[0].conn.xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
+ smp->data.uint = (l4->si[0].conn->xprt == &ssl_sock) &&
+ l4->si[0].conn->xprt_ctx &&
+ SSL_get_servername(l4->si[0].conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
return 1;
#else
return 0;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
{
X509 *crt;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
/* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
return 0;
X509 *crt;
int nid;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
return 0;
X509 *crt;
int nid;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
return 0;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
int ret = 0;
struct chunk *smp_trash;
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags |= SMP_F_MAY_CHANGE;
return 0;
}
- crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
+ crt = SSL_get_certificate(l4->si[0].conn->xprt_ctx);
if (!crt)
goto out;
{
smp->flags = 0;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- smp->data.str.str = (char *)SSL_get_cipher_name(l4->si[0].conn.xprt_ctx);
+ smp->data.str.str = (char *)SSL_get_cipher_name(l4->si[0].conn->xprt_ctx);
if (!smp->data.str.str)
return 0;
{
smp->flags = 0;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!SSL_get_cipher_bits(l4->si[0].conn.xprt_ctx, (int *)&smp->data.uint))
+ if (!SSL_get_cipher_bits(l4->si[0].conn->xprt_ctx, (int *)&smp->data.uint))
return 0;
smp->type = SMP_T_UINT;
{
smp->flags = 0;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- smp->data.uint = (unsigned int)SSL_get_cipher_bits(l4->si[0].conn.xprt_ctx, NULL);
+ smp->data.uint = (unsigned int)SSL_get_cipher_bits(l4->si[0].conn->xprt_ctx, NULL);
if (!smp->data.uint)
return 0;
smp->flags = 0;
smp->type = SMP_T_CSTR;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
smp->data.str.str = NULL;
- SSL_get0_next_proto_negotiated(l4->si[0].conn.xprt_ctx,
+ SSL_get0_next_proto_negotiated(l4->si[0].conn->xprt_ctx,
(const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
if (!smp->data.str.str)
{
smp->flags = 0;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- smp->data.str.str = (char *)SSL_get_version(l4->si[0].conn.xprt_ctx);
+ smp->data.str.str = (char *)SSL_get_version(l4->si[0].conn->xprt_ctx);
if (!smp->data.str.str)
return 0;
smp->flags = 0;
smp->type = SMP_T_CBIN;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- sess = SSL_get_session(l4->si[0].conn.xprt_ctx);
+ sess = SSL_get_session(l4->si[0].conn->xprt_ctx);
if (!sess)
return 0;
smp->flags = 0;
smp->type = SMP_T_CSTR;
- if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || !l4->si[0].conn->xprt_ctx || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- smp->data.str.str = (char *)SSL_get_servername(l4->si[0].conn.xprt_ctx, TLSEXT_NAMETYPE_host_name);
+ smp->data.str.str = (char *)SSL_get_servername(l4->si[0].conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
if (!smp->data.str.str)
return 0;
smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags = SMP_F_MAY_CHANGE;
return 0;
}
smp->type = SMP_T_UINT;
- smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(l4->si[0].conn.xprt_st);
+ smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(l4->si[0].conn->xprt_st);
smp->flags = 0;
return 1;
smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags = SMP_F_MAY_CHANGE;
return 0;
}
smp->type = SMP_T_UINT;
- smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(l4->si[0].conn.xprt_st);
+ smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(l4->si[0].conn->xprt_st);
smp->flags = 0;
return 1;
smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags = SMP_F_MAY_CHANGE;
return 0;
}
smp->type = SMP_T_UINT;
- smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(l4->si[0].conn.xprt_st);
+ smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(l4->si[0].conn->xprt_st);
smp->flags = 0;
return 1;
smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
- if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
+ if (!l4 || l4->si[0].conn->xprt != &ssl_sock)
return 0;
- if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
+ if (!(l4->si[0].conn->flags & CO_FL_CONNECTED)) {
smp->flags = SMP_F_MAY_CHANGE;
return 0;
}
- if (!l4->si[0].conn.xprt_ctx)
+ if (!l4->si[0].conn->xprt_ctx)
return 0;
smp->type = SMP_T_UINT;
- smp->data.uint = (unsigned int)SSL_get_verify_result(l4->si[0].conn.xprt_ctx);
+ smp->data.uint = (unsigned int)SSL_get_verify_result(l4->si[0].conn->xprt_ctx);
smp->flags = 0;
return 1;
*/
int stream_int_shutr(struct stream_interface *si)
{
- struct connection *conn = &si->conn;
+ struct connection *conn = si->conn;
si->ib->flags &= ~CF_SHUTR_NOW;
if (si->ib->flags & CF_SHUTR)
return 0;
if (si->ob->flags & CF_SHUTW) {
- conn_xprt_close(&si->conn);
+ conn_xprt_close(si->conn);
if (conn->ctrl)
fd_delete(si_fd(si));
si->state = SI_ST_DIS;
*/
int stream_int_shutw(struct stream_interface *si)
{
- struct connection *conn = &si->conn;
+ struct connection *conn = si->conn;
si->ob->flags &= ~CF_SHUTW_NOW;
if (si->ob->flags & CF_SHUTW)
/* we may have to close a pending connection, and mark the
* response buffer as shutr
*/
- conn_xprt_close(&si->conn);
+ conn_xprt_close(si->conn);
if (conn->ctrl)
fd_delete(si_fd(si));
/* fall through */
DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si->owner);
si_prepare_embedded(si);
- set_target_applet(&si->conn.target, app);
+ set_target_applet(&si->conn->target, app);
si->release = app->release;
si->flags |= SI_FL_WAIT_DATA;
return si->owner;
DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", fct, si, si->owner);
si_prepare_task(si);
- clear_target(&si->conn.target);
+ clear_target(&si->conn->target);
si->release = NULL;
si->flags |= SI_FL_WAIT_DATA;
if (!t)
return t;
- set_target_task(&si->conn.target, t);
+ set_target_task(&si->conn->target, t);
t->process = fct;
t->context = si;
*/
void stream_int_unregister_handler(struct stream_interface *si)
{
- if (si->conn.target.type == TARG_TYPE_TASK) {
+ if (si->conn->target.type == TARG_TYPE_TASK) {
/* external handler : kill the task */
- task_delete(si->conn.target.ptr.t);
- task_free(si->conn.target.ptr.t);
+ task_delete(si->conn->target.ptr.t);
+ task_free(si->conn->target.ptr.t);
}
si->release = NULL;
si->owner = NULL;
- clear_target(&si->conn.target);
+ clear_target(&si->conn->target);
}
/* This callback is used to send a valid PROXY protocol line to a socket being
* (which is recomputed every time since it's constant). If
* it is positive, it means we have to send from the start.
*/
- ret = make_proxy_line(trash, global.tune.bufsize, &si->ob->prod->conn.addr.from, &si->ob->prod->conn.addr.to);
+ ret = make_proxy_line(trash, global.tune.bufsize, &si->ob->prod->conn->addr.from, &si->ob->prod->conn->addr.to);
if (!ret)
goto out_error;
if (!(si->flags & SI_FL_WAIT_ROOM)) {
if (!(ib->flags & (CF_HIJACK|CF_DONT_READ))) /* full */
si->flags |= SI_FL_WAIT_ROOM;
- conn_data_stop_recv(&si->conn);
+ conn_data_stop_recv(si->conn);
ib->rex = TICK_ETERNITY;
}
}
* have updated it if there has been a completed I/O.
*/
si->flags &= ~SI_FL_WAIT_ROOM;
- conn_data_want_recv(&si->conn);
+ conn_data_want_recv(si->conn);
if (!(ib->flags & (CF_READ_NOEXP|CF_DONT_READ)) && !tick_isset(ib->rex))
ib->rex = tick_add_ifset(now_ms, ib->rto);
}
if (!(si->flags & SI_FL_WAIT_DATA)) {
if ((ob->flags & (CF_HIJACK|CF_SHUTW_NOW)) == 0)
si->flags |= SI_FL_WAIT_DATA;
- conn_data_stop_send(&si->conn);
+ conn_data_stop_send(si->conn);
ob->wex = TICK_ETERNITY;
}
}
* have updated it if there has been a completed I/O.
*/
si->flags &= ~SI_FL_WAIT_DATA;
- conn_data_want_send(&si->conn);
+ conn_data_want_send(si->conn);
if (!tick_isset(ob->wex)) {
ob->wex = tick_add_ifset(now_ms, ob->wto);
if (tick_isset(ib->rex) && !(si->flags & SI_FL_INDEP_STR)) {
/* stop reading */
if (!(ib->flags & (CF_HIJACK|CF_DONT_READ))) /* full */
si->flags |= SI_FL_WAIT_ROOM;
- conn_data_stop_recv(&si->conn);
+ conn_data_stop_recv(si->conn);
}
else {
/* (re)start reading */
si->flags &= ~SI_FL_WAIT_ROOM;
- conn_data_want_recv(&si->conn);
+ conn_data_want_recv(si->conn);
}
}
(fdtab[si_fd(si)].ev & FD_POLL_OUT))) /* we'll be called anyway */
return;
- if (!(si->conn.flags & CO_FL_HANDSHAKE) && si_conn_send_loop(&si->conn) < 0) {
+ if (!(si->conn->flags & CO_FL_HANDSHAKE) && si_conn_send_loop(si->conn) < 0) {
/* Write error on the file descriptor. We mark the FD as STERROR so
* that we don't use it anymore and we notify the task.
*/
fdtab[si_fd(si)].ev &= ~FD_POLL_STICKY;
- __conn_data_stop_both(&si->conn);
+ __conn_data_stop_both(si->conn);
si->flags |= SI_FL_ERR;
- si->conn.flags |= CO_FL_ERROR;
+ si->conn->flags |= CO_FL_ERROR;
goto out_wakeup;
}
/* Otherwise there are remaining data to be sent in the buffer,
* which means we have to poll before doing so.
*/
- __conn_data_want_send(&si->conn);
+ __conn_data_want_send(si->conn);
si->flags &= ~SI_FL_WAIT_DATA;
if (!tick_isset(ob->wex))
ob->wex = tick_add_ifset(now_ms, ob->wto);
}
/* commit possible polling changes */
- conn_cond_update_polling(&si->conn);
+ conn_cond_update_polling(si->conn);
}
/*
if (conn->flags & CO_FL_ERROR)
goto out_error;
- if (si->conn.flags & CO_FL_HANDSHAKE)
+ if (si->conn->flags & CO_FL_HANDSHAKE)
/* a handshake was requested */
return;
(struct linger *) &nolinger, sizeof(struct linger));
}
/* force flag on ssl to keep session in cache */
- if (si->conn.xprt->shutw)
- si->conn.xprt->shutw(&si->conn, 0);
+ if (si->conn->xprt->shutw)
+ si->conn->xprt->shutw(si->conn, 0);
goto do_close;
}
/* otherwise that's just a normal read shutdown */
- __conn_data_stop_recv(&si->conn);
+ __conn_data_stop_recv(si->conn);
return;
do_close:
- conn_xprt_close(&si->conn);
+ conn_xprt_close(si->conn);
fd_delete(si_fd(si));
si->state = SI_ST_DIS;
si->exp = TICK_ETERNITY;