diff --git a/include/proto/connection.h b/include/proto/connection.h index 7205b2c4c..abc7e2226 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 4bb4aae62..7536e95cd 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 171452294..b1637307f 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 87f951e11..9001c60a6 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 ea0d8949a..845c93b92 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 3cdba8d29..7728616d3 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 312c248fe..eb9b13b4b 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 e671225ff..0344d965b 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 f6cc6a325..de7f4c5c0 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 e5a8b7ec9..b5c7645c3 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 765d04fea..5776519a2 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