From: Willy Tarreau Date: Thu, 30 Aug 2012 13:49:18 +0000 (+0200) Subject: REORG: connection: move the target pointer from si to connection X-Git-Tag: v1.5-dev12~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cefd521facff1d6121e535da5d9ddb2730bf3d8;p=thirdparty%2Fhaproxy.git REORG: connection: move the target pointer from si to connection The target is per connection and is directly used by the connection, so we need it there. It's not needed anymore in the SI however. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 7205b2c4c5..abc7e2226d 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -310,6 +310,67 @@ static inline int conn_sock_shutw_pending(struct connection *c) return (c->flags & (CO_FL_DATA_WR_SH | CO_FL_SOCK_WR_SH)) == CO_FL_DATA_WR_SH; } +static inline void clear_target(struct target *dest) +{ + dest->type = TARG_TYPE_NONE; + dest->ptr.v = NULL; +} + +static inline void set_target_client(struct target *dest, struct listener *l) +{ + dest->type = TARG_TYPE_CLIENT; + dest->ptr.l = l; +} + +static inline void set_target_server(struct target *dest, struct server *s) +{ + dest->type = TARG_TYPE_SERVER; + dest->ptr.s = s; +} + +static inline void set_target_proxy(struct target *dest, struct proxy *p) +{ + dest->type = TARG_TYPE_PROXY; + dest->ptr.p = p; +} + +static inline void set_target_applet(struct target *dest, struct si_applet *a) +{ + dest->type = TARG_TYPE_APPLET; + dest->ptr.a = a; +} + +static inline void set_target_task(struct target *dest, struct task *t) +{ + dest->type = TARG_TYPE_TASK; + dest->ptr.t = t; +} + +static inline struct target *copy_target(struct target *dest, struct target *src) +{ + *dest = *src; + return dest; +} + +static inline int target_match(struct target *a, struct target *b) +{ + return a->type == b->type && a->ptr.v == b->ptr.v; +} + +static inline struct server *target_srv(struct target *t) +{ + if (!t || t->type != TARG_TYPE_SERVER) + return NULL; + return t->ptr.s; +} + +static inline struct listener *target_client(struct target *t) +{ + if (!t || t->type != TARG_TYPE_CLIENT) + return NULL; + return t->ptr.l; +} + #endif /* _PROTO_CONNECTION_H */ /* diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h index 4bb4aae621..7536e95cde 100644 --- a/include/proto/stream_interface.h +++ b/include/proto/stream_interface.h @@ -63,67 +63,6 @@ static inline int si_fd(struct stream_interface *si) return si->conn.t.sock.fd; } -static inline void clear_target(struct target *dest) -{ - dest->type = TARG_TYPE_NONE; - dest->ptr.v = NULL; -} - -static inline void set_target_client(struct target *dest, struct listener *l) -{ - dest->type = TARG_TYPE_CLIENT; - dest->ptr.l = l; -} - -static inline void set_target_server(struct target *dest, struct server *s) -{ - dest->type = TARG_TYPE_SERVER; - dest->ptr.s = s; -} - -static inline void set_target_proxy(struct target *dest, struct proxy *p) -{ - dest->type = TARG_TYPE_PROXY; - dest->ptr.p = p; -} - -static inline void set_target_applet(struct target *dest, struct si_applet *a) -{ - dest->type = TARG_TYPE_APPLET; - dest->ptr.a = a; -} - -static inline void set_target_task(struct target *dest, struct task *t) -{ - dest->type = TARG_TYPE_TASK; - dest->ptr.t = t; -} - -static inline struct target *copy_target(struct target *dest, struct target *src) -{ - *dest = *src; - return dest; -} - -static inline int target_match(struct target *a, struct target *b) -{ - return a->type == b->type && a->ptr.v == b->ptr.v; -} - -static inline struct server *target_srv(struct target *t) -{ - if (!t || t->type != TARG_TYPE_SERVER) - return NULL; - return t->ptr.s; -} - -static inline struct listener *target_client(struct target *t) -{ - if (!t || t->type != TARG_TYPE_CLIENT) - return NULL; - return t->ptr.l; -} - static inline void si_prepare_conn(struct stream_interface *si, const struct protocol *ctrl, const struct data_ops *ops) { si->ops = &si_conn_ops; @@ -165,7 +104,7 @@ static inline void si_get_from_addr(struct stream_interface *si) if (si_ctrl(si)->get_src(si_fd(si), (struct sockaddr *)&si->addr.from, sizeof(si->addr.from), - si->target.type != TARG_TYPE_CLIENT) == -1) + si->conn.target.type != TARG_TYPE_CLIENT) == -1) return; si->flags |= SI_FL_FROM_SET; } @@ -181,7 +120,7 @@ static inline void si_get_to_addr(struct stream_interface *si) if (si_ctrl(si)->get_dst(si_fd(si), (struct sockaddr *)&si->addr.to, sizeof(si->addr.to), - si->target.type != TARG_TYPE_CLIENT) == -1) + si->conn.target.type != TARG_TYPE_CLIENT) == -1) return; si->flags |= SI_FL_TO_SET; } diff --git a/include/types/connection.h b/include/types/connection.h index 171452294a..b1637307fb 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -32,6 +32,11 @@ struct protocol; struct connection; struct buffer; struct pipe; +struct server; +struct proxy; +struct si_applet; +struct task; +struct listener; /* Polling flags that are manipulated by I/O callbacks and handshake callbacks * indicate what they expect from a file descriptor at each layer. For each @@ -110,6 +115,16 @@ enum { CO_FL_CURR_WR_POL = CO_FL_WR_POL << 28, /* sending needs to poll first */ }; +/* target types */ +enum { + TARG_TYPE_NONE = 0, /* no target set, pointer is NULL by definition */ + TARG_TYPE_CLIENT, /* target is a client, pointer is NULL by definition */ + TARG_TYPE_PROXY, /* target is a proxy ; use address with the proxy's settings */ + TARG_TYPE_SERVER, /* target is a server ; use address with server's and its proxy's settings */ + TARG_TYPE_APPLET, /* target is an applet ; use only the applet */ + TARG_TYPE_TASK, /* target is a task running an external applet */ +}; + /* data_ops describes data-layer operations for a connection. They generally * run over a socket-based control layer, but not always. @@ -133,6 +148,19 @@ struct app_cb { void (*send)(struct connection *conn); /* application-layer send callback */ }; +/* a target describes what is on the remote side of the connection. */ +struct target { + int type; + union { + void *v; /* pointer value, for any type */ + struct proxy *p; /* when type is TARG_TYPE_PROXY */ + struct server *s; /* when type is TARG_TYPE_SERVER */ + struct si_applet *a; /* when type is TARG_TYPE_APPLET */ + struct task *t; /* when type is TARG_TYPE_TASK */ + struct listener *l; /* when type is TARG_TYPE_CLIENT */ + } ptr; +}; + /* This structure describes a connection with its methods and data. * A connection may be performed to proxy or server via a local or remote * socket, and can also be made to an internal applet. It can support @@ -152,6 +180,7 @@ struct connection { unsigned int flags; /* CO_F_* */ int data_st; /* data layer state, initialized to zero */ void *data_ctx; /* general purpose pointer, initialized to NULL */ + struct target target; /* the target to connect to (server, proxy, applet, ...) */ struct sockaddr *peeraddr; /* pointer to peer's network address, or NULL if unset */ socklen_t peerlen; /* peer's address length, or 0 if unset */ }; diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index 87f951e11a..9001c60a6d 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -79,35 +79,10 @@ enum { SI_FL_FROM_SET = 0x4000, /* addr.from is set */ }; -/* target types */ -enum { - TARG_TYPE_NONE = 0, /* no target set, pointer is NULL by definition */ - TARG_TYPE_CLIENT, /* target is a client, pointer is NULL by definition */ - TARG_TYPE_PROXY, /* target is a proxy ; use address with the proxy's settings */ - TARG_TYPE_SERVER, /* target is a server ; use address with server's and its proxy's settings */ - TARG_TYPE_APPLET, /* target is an applet ; use only the applet */ - TARG_TYPE_TASK, /* target is a task running an external applet */ -}; - #define SI_FL_CAP_SPLICE (SI_FL_CAP_SPLTCP) -struct server; -struct proxy; -struct si_applet; struct stream_interface; -struct target { - int type; - union { - void *v; /* pointer value, for any type */ - struct proxy *p; /* when type is TARG_TYPE_PROXY */ - struct server *s; /* when type is TARG_TYPE_SERVER */ - struct si_applet *a; /* when type is TARG_TYPE_APPLET */ - struct task *t; /* when type is TARG_TYPE_TASK */ - struct listener *l; /* when type is TARG_TYPE_CLIENT */ - } ptr; -}; - /* operations available on a stream-interface */ struct si_ops { void (*update)(struct stream_interface *); /* I/O update function */ @@ -143,7 +118,6 @@ struct stream_interface { void (*release)(struct stream_interface *); /* handler to call after the last close() */ /* struct members below are the "remote" part, as seen from the buffer side */ - struct target target; /* the target to connect to (server, proxy, applet, ...) */ int conn_retries; /* number of connect retries left */ int send_proxy_ofs; /* <0 = offset to (re)send from the end, >0 = send all */ struct { diff --git a/src/backend.c b/src/backend.c index ea0d8949aa..845c93b92d 100644 --- a/src/backend.c +++ b/src/backend.c @@ -981,7 +981,7 @@ int connect_server(struct session *s) } /* the target was only on the session, assign it to the SI now */ - copy_target(&s->req->cons->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) { diff --git a/src/dumpstats.c b/src/dumpstats.c index 3cdba8d29e..7728616d32 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -125,7 +125,7 @@ static int stats_accept(struct session *s) { /* 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].target); // for logging only + copy_target(&s->target, &s->si[1].conn.target); // for logging only s->si[1].conn.data_ctx = s; s->si[1].applet.st1 = 0; s->si[1].applet.st0 = STAT_CLI_INIT; diff --git a/src/peers.c b/src/peers.c index 312c248fe4..eb9b13b4b8 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1052,8 +1052,8 @@ static void peer_session_forceshutdown(struct session * session) { struct stream_interface *oldsi; - if (session->si[0].target.type == TARG_TYPE_APPLET && - session->si[0].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 { @@ -1077,7 +1077,7 @@ int peer_accept(struct session *s) { /* 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].target); // for logging only + copy_target(&s->target, &s->si[1].conn.target); // for logging only s->si[1].conn.data_ctx = s; s->si[1].applet.st0 = PEER_SESSION_ACCEPT; @@ -1158,7 +1158,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio s->si[0].err_loc = NULL; s->si[0].release = NULL; s->si[0].send_proxy_ofs = 0; - set_target_client(&s->si[0].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) @@ -1179,7 +1179,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio s->si[1].err_loc = NULL; s->si[1].release = NULL; s->si[1].send_proxy_ofs = 0; - set_target_proxy(&s->si[1].target, s->be); + set_target_proxy(&s->si[1].conn.target, s->be); si_prepare_conn(&s->si[1], peer->proto, peer->data); s->si[1].exp = TICK_ETERNITY; s->si[1].flags = SI_FL_NONE; diff --git a/src/proto_http.c b/src/proto_http.c index e671225ff0..0344d965b9 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3028,7 +3028,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit, 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->target); // for logging only + copy_target(&s->target, &s->rep->prod->conn.target); // for logging only s->rep->prod->conn.data_ctx = s; s->rep->prod->applet.st0 = s->rep->prod->applet.st1 = 0; req->analysers = 0; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index f6cc6a3259..de7f4c5c00 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -233,13 +233,13 @@ int tcp_connect_server(struct stream_interface *si) struct server *srv; struct proxy *be; - switch (si->target.type) { + switch (si->conn.target.type) { case TARG_TYPE_PROXY: - be = si->target.ptr.p; + be = si->conn.target.ptr.p; srv = NULL; break; case TARG_TYPE_SERVER: - srv = si->target.ptr.s; + srv = si->conn.target.ptr.s; be = srv->proxy; break; default: diff --git a/src/session.c b/src/session.c index e5a8b7ec9d..b5c7645c36 100644 --- a/src/session.c +++ b/src/session.c @@ -172,7 +172,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->si[0].err_loc = NULL; s->si[0].release = NULL; s->si[0].send_proxy_ofs = 0; - set_target_client(&s->si[0].target, l); + set_target_client(&s->si[0].conn.target, l); s->si[0].exp = TICK_ETERNITY; s->si[0].flags = SI_FL_NONE; @@ -198,7 +198,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->si[1].err_loc = NULL; s->si[1].release = NULL; s->si[1].send_proxy_ofs = 0; - clear_target(&s->si[1].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; @@ -1923,7 +1923,7 @@ struct task *process_session(struct task *t) */ s->req->cons->state = SI_ST_REQ; /* new connection requested */ s->req->cons->conn_retries = s->be->conn_retries; - if (unlikely(s->req->cons->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 */ @@ -2103,10 +2103,10 @@ struct task *process_session(struct task *t) 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->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->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); @@ -2133,12 +2133,12 @@ struct task *process_session(struct task *t) /* Call the stream interfaces' I/O handlers when embedded. * Note that this one may wake the task up again. */ - if (s->req->cons->target.type == TARG_TYPE_APPLET || - s->rep->cons->target.type == TARG_TYPE_APPLET) { - if (s->req->cons->target.type == TARG_TYPE_APPLET) - s->req->cons->target.ptr.a->fct(s->req->cons); - if (s->rep->cons->target.type == TARG_TYPE_APPLET) - s->rep->cons->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 diff --git a/src/stream_interface.c b/src/stream_interface.c index 765d04feab..5776519a21 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -422,7 +422,7 @@ struct task *stream_int_register_handler(struct stream_interface *si, struct si_ DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si->owner); si_prepare_embedded(si); - set_target_applet(&si->target, app); + set_target_applet(&si->conn.target, app); si->release = app->release; si->flags |= SI_FL_WAIT_DATA; return si->owner; @@ -443,7 +443,7 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", fct, si, si->owner); si_prepare_task(si); - clear_target(&si->target); + clear_target(&si->conn.target); si->release = NULL; si->flags |= SI_FL_WAIT_DATA; @@ -452,7 +452,7 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, if (!t) return t; - set_target_task(&si->target, t); + set_target_task(&si->conn.target, t); t->process = fct; t->context = si; @@ -467,14 +467,14 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, */ void stream_int_unregister_handler(struct stream_interface *si) { - if (si->target.type == TARG_TYPE_TASK) { + if (si->conn.target.type == TARG_TYPE_TASK) { /* external handler : kill the task */ - task_delete(si->target.ptr.t); - task_free(si->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->target); + clear_target(&si->conn.target); } /* This callback is used to send a valid PROXY protocol line to a socket being