summaryrefslogtreecommitdiffstats
path: root/include/haproxy/proxy.h
blob: efdfa21540f6278f362e612c91fa9f1e2fc6dc9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/*
 * include/haproxy/proxy.h
 * This file defines function prototypes for proxy management.
 *
 * Copyright (C) 2000-2011 Willy Tarreau - w@1wt.eu
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _HAPROXY_PROXY_H
#define _HAPROXY_PROXY_H

#include <haproxy/api.h>
#include <haproxy/applet-t.h>
#include <haproxy/freq_ctr.h>
#include <haproxy/list.h>
#include <haproxy/listener-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
#include <haproxy/ticks.h>
#include <haproxy/thread.h>

extern struct proxy *proxies_list;
extern struct eb_root used_proxy_id;	/* list of proxy IDs in use */
extern unsigned int error_snapshot_id;  /* global ID assigned to each error then incremented */
extern struct eb_root proxy_by_name;    /* tree of proxies sorted by name */

extern const struct cfg_opt cfg_opts[];
extern const struct cfg_opt cfg_opts2[];

struct task *manage_proxy(struct task *t, void *context, unsigned int state);
void proxy_cond_pause(struct proxy *p);
void proxy_cond_resume(struct proxy *p);
void proxy_cond_disable(struct proxy *p);
void soft_stop(void);
int pause_proxy(struct proxy *p);
int resume_proxy(struct proxy *p);
void stop_proxy(struct proxy *p);
int  stream_set_backend(struct stream *s, struct proxy *be);

void free_proxy(struct proxy *p);
const char *proxy_cap_str(int cap);
const char *proxy_mode_str(int mode);
const char *proxy_find_best_option(const char *word, const char **extra);
void proxy_store_name(struct proxy *px);
struct proxy *proxy_find_by_id(int id, int cap, int table);
struct proxy *proxy_find_by_name(const char *name, int cap, int table);
struct proxy *proxy_find_best_match(int cap, const char *name, int id, int *diff);
struct server *findserver(const struct proxy *px, const char *name);
struct server *findserver_unique_id(const struct proxy *px, int puid, uint32_t rid);
struct server *findserver_unique_name(const struct proxy *px, const char *name, uint32_t rid);
int proxy_cfg_ensure_no_http(struct proxy *curproxy);
int proxy_cfg_ensure_no_log(struct proxy *curproxy);
void init_new_proxy(struct proxy *p);
void proxy_preset_defaults(struct proxy *defproxy);
void proxy_free_defaults(struct proxy *defproxy);
void proxy_destroy_defaults(struct proxy *px);
void proxy_destroy_all_unref_defaults(void);
void proxy_ref_defaults(struct proxy *px, struct proxy *defpx);
void proxy_unref_defaults(struct proxy *px);
struct proxy *alloc_new_proxy(const char *name, unsigned int cap,
                              char **errmsg);
struct proxy *parse_new_proxy(const char *name, unsigned int cap,
                              const char *file, int linenum,
                              const struct proxy *defproxy);
void proxy_capture_error(struct proxy *proxy, int is_back,
			 struct proxy *other_end, enum obj_type *target,
			 const struct session *sess,
			 const struct buffer *buf, long buf_ofs,
			 unsigned int buf_out, unsigned int err_pos,
			 const union error_snapshot_ctx *ctx,
			 void (*show)(struct buffer *, const struct error_snapshot *));
void proxy_adjust_all_maxconn(void);
struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg);
struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg);
int resolve_stick_rule(struct proxy *curproxy, struct sticking_rule *mrule);
void free_stick_rules(struct list *rules);
void free_server_rules(struct list *srules);

/*
 * This function returns a string containing the type of the proxy in a format
 * suitable for error messages, from its capabilities.
 */
static inline const char *proxy_type_str(struct proxy *proxy)
{
	if (proxy->mode == PR_MODE_PEERS)
		return "peers section";
	return proxy_cap_str(proxy->cap);
}

/* Find the frontend having name <name>. The name may also start with a '#' to
 * reference a numeric id. NULL is returned if not found.
 */
static inline struct proxy *proxy_fe_by_name(const char *name)
{
	return proxy_find_by_name(name, PR_CAP_FE, 0);
}

/* Find the backend having name <name>. The name may also start with a '#' to
 * reference a numeric id. NULL is returned if not found.
 */
static inline struct proxy *proxy_be_by_name(const char *name)
{
	return proxy_find_by_name(name, PR_CAP_BE, 0);
}

/* this function initializes all timeouts for proxy p */
static inline void proxy_reset_timeouts(struct proxy *proxy)
{
	proxy->timeout.client = TICK_ETERNITY;
	proxy->timeout.tarpit = TICK_ETERNITY;
	proxy->timeout.queue = TICK_ETERNITY;
	proxy->timeout.connect = TICK_ETERNITY;
	proxy->timeout.server = TICK_ETERNITY;
	proxy->timeout.httpreq = TICK_ETERNITY;
	proxy->timeout.check = TICK_ETERNITY;
	proxy->timeout.tunnel = TICK_ETERNITY;
}

/* increase the number of cumulated connections received on the designated frontend */
static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
{
	_HA_ATOMIC_INC(&fe->fe_counters.cum_conn);
	if (l && l->counters)
		_HA_ATOMIC_INC(&l->counters->cum_conn);
	HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max,
			     update_freq_ctr(&fe->fe_conn_per_sec, 1));
}

/* increase the number of cumulated connections accepted by the designated frontend */
static inline void proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe)
{

	_HA_ATOMIC_INC(&fe->fe_counters.cum_sess);
	if (l && l->counters)
		_HA_ATOMIC_INC(&l->counters->cum_sess);
	HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max,
			     update_freq_ctr(&fe->fe_sess_per_sec, 1));
}

/* increase the number of cumulated HTTP sessions on the designated frontend.
 * <http_ver> must be the HTTP version for such requests.
 */
static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct proxy *fe,
                                                 unsigned int http_ver)
{
	if (http_ver == 0 ||
	    http_ver > sizeof(fe->fe_counters.cum_sess_ver) / sizeof(*fe->fe_counters.cum_sess_ver))
	    return;

	_HA_ATOMIC_INC(&fe->fe_counters.cum_sess_ver[http_ver - 1]);
	if (l && l->counters)
		_HA_ATOMIC_INC(&l->counters->cum_sess_ver[http_ver - 1]);
}

/* increase the number of cumulated connections on the designated backend */
static inline void proxy_inc_be_ctr(struct proxy *be)
{
	_HA_ATOMIC_INC(&be->be_counters.cum_conn);
	HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max,
			     update_freq_ctr(&be->be_sess_per_sec, 1));
}

/* increase the number of cumulated requests on the designated frontend.
 * <http_ver> must be the HTTP version for HTTP request. 0 may be provided
 * for others requests.
 */
static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
                                        unsigned int http_ver)
{
	if (http_ver >= sizeof(fe->fe_counters.p.http.cum_req) / sizeof(*fe->fe_counters.p.http.cum_req))
	    return;

	_HA_ATOMIC_INC(&fe->fe_counters.p.http.cum_req[http_ver]);
	if (l && l->counters)
		_HA_ATOMIC_INC(&l->counters->p.http.cum_req[http_ver]);
	HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
			     update_freq_ctr(&fe->fe_req_per_sec, 1));
}

/* Returns non-zero if the proxy is configured to retry a request if we got that status, 0 otherwise */
static inline int l7_status_match(struct proxy *p, int status)
{
	/* Just return 0 if no retry was configured for any status */
	if (!(p->retry_type & PR_RE_STATUS_MASK))
		return 0;

	switch (status) {
	case 401:
		return (p->retry_type & PR_RE_401);
	case 403:
		return (p->retry_type & PR_RE_403);
	case 404:
		return (p->retry_type & PR_RE_404);
	case 408:
		return (p->retry_type & PR_RE_408);
	case 425:
		return (p->retry_type & PR_RE_425);
	case 500:
		return (p->retry_type & PR_RE_500);
	case 501:
		return (p->retry_type & PR_RE_501);
	case 502:
		return (p->retry_type & PR_RE_502);
	case 503:
		return (p->retry_type & PR_RE_503);
	case 504:
		return (p->retry_type & PR_RE_504);
	default:
		break;
	}
	return 0;
}

/* Return 1 if <p> proxy is in <list> list of proxies which are also stick-tables,
 * 0 if not.
 */
static inline int in_proxies_list(struct proxy *list, struct proxy *proxy)
{
	struct proxy *p;

	for (p = list; p; p = p->next_stkt_ref)
		if (proxy == p)
			return 1;

	return 0;
}

/* Add <bytes> to the global total bytes sent and adjust the send rate. Set
 * <splice> if this was sent usigin splicing.
 */
static inline void increment_send_rate(uint64_t bytes, int splice)
{
	/* We count the total bytes sent, and the send rate for 32-byte blocks.
	 * The reason for the latter is that freq_ctr are limited to 4GB and
	 * that it's not enough per second.
	 */

	if (splice)
		_HA_ATOMIC_ADD(&th_ctx->spliced_out_bytes, bytes);
	_HA_ATOMIC_ADD(&th_ctx->out_bytes, bytes);
	update_freq_ctr(&th_ctx->out_32bps, (bytes + 16) / 32);
}

#endif /* _HAPROXY_PROXY_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */