1 #ifndef INCLUDED_GW_BACKEND_H 2 #define INCLUDED_GW_BACKEND_H 3 4 #include "first.h" 5 6 #include <sys/types.h> 7 #include "sys-socket.h" 8 9 #include "array.h" 10 #include "buffer.h" 11 12 typedef struct { 13 char **ptr; 14 15 uint32_t size; 16 uint32_t used; 17 } char_array; 18 19 typedef struct gw_proc { 20 struct gw_proc *next; /* see first */ 21 enum { 22 PROC_STATE_RUNNING, /* alive */ 23 PROC_STATE_OVERLOADED, /* listen-queue is full */ 24 PROC_STATE_DIED_WAIT_FOR_PID, /* */ 25 PROC_STATE_DIED, /* marked as dead, should be restarted */ 26 PROC_STATE_KILLED /* killed (signal sent to proc) */ 27 } state; 28 uint32_t load; /* number of requests waiting on this process */ 29 unix_time64_t last_used; /* see idle_timeout */ 30 int *stats_load; 31 int *stats_connected; 32 pid_t pid; /* PID of the spawned process (0 if not spawned locally) */ 33 int is_local; 34 uint32_t id; /* id will be between 1 and max_procs */ 35 socklen_t saddrlen; 36 struct sockaddr *saddr; 37 38 unix_time64_t disabled_until; /* proc disabled until given time */ 39 struct gw_proc *prev; /* see first */ 40 41 /* either tcp:<host>:<port> or unix:<socket> for debugging purposes */ 42 buffer *connection_name; 43 buffer *unixsocket; /* config.socket + "-" + id */ 44 unsigned short port; /* config.port + pno */ 45 } gw_proc; 46 47 struct gw_handler_ctx; /* declaration */ 48 49 typedef struct { 50 /* list of processes handling this extension 51 * sorted by lowest load 52 * 53 * whenever a job is done move it up in the list 54 * until it is sorted, move it down as soon as the 55 * job is started 56 */ 57 gw_proc *first; 58 59 uint32_t active_procs; /* how many procs in state PROC_STATE_RUNNING */ 60 uint32_t gw_hash; 61 62 int32_t load; 63 int *stats_load; 64 int *stats_global_active; 65 66 /* 67 * host:port 68 * 69 * if host is one of the local IP addresses the 70 * whole connection is local 71 * 72 * if port is not 0, and host is not specified, 73 * "localhost" (INADDR_LOOPBACK) is assumed. 74 * 75 */ 76 unsigned short port; 77 unsigned short family; /* sa_family_t */ 78 const buffer *host; 79 80 /* the key that is used to reference this value */ 81 const buffer *id; 82 gw_proc *unused_procs; 83 84 /* 85 * spawn at least min_procs, at max_procs. 86 * 87 * as soon as the load of the first entry 88 * is max_load_per_proc we spawn a new one 89 * and add it to the first entry and give it 90 * the load 91 * 92 */ 93 94 unsigned short min_procs; 95 unsigned short max_procs; 96 uint32_t num_procs; /* how many procs are started */ 97 98 unsigned short max_load_per_proc; 99 100 /* 101 * kick the process from the list if it was not 102 * used for idle_timeout until min_procs is 103 * reached. this helps to get the processlist 104 * small again we had a small peak load. 105 * 106 */ 107 108 unsigned short idle_timeout; 109 110 /* 111 * time after a disabled remote connection is tried to be re-enabled 112 * 113 * 114 */ 115 116 unsigned short disable_time; 117 118 unsigned short read_timeout; 119 unsigned short write_timeout; 120 unsigned short connect_timeout; 121 struct gw_handler_ctx *hctxs; 122 123 /* 124 * some gw processes get a little bit larger 125 * than wanted. max_requests_per_proc kills a 126 * process after a number of handled requests. 127 * 128 */ 129 /*uint32_t max_requests_per_proc;*//* not implemented */ 130 131 132 /* config */ 133 134 /* 135 * Unix Domain Socket 136 * 137 * instead of TCP/IP we can use Unix Domain Sockets 138 * - more secure (you have fileperms to play with) 139 * - more control (on locally) 140 * - more speed (no extra overhead) 141 */ 142 const buffer *unixsocket; 143 144 /* if socket is local we can start the gw process ourself 145 * 146 * bin-path is the path to the binary 147 * 148 * check min_procs and max_procs for the number 149 * of process to start up 150 */ 151 const buffer *bin_path; 152 153 /* bin-path is set bin-environment is taken to 154 * create the environment before starting the 155 * FastCGI process 156 * 157 */ 158 const array *bin_env; 159 160 const array *bin_env_copy; 161 162 /* 163 * docroot-translation between URL->phys and the 164 * remote host 165 * 166 * reasons: 167 * - different dir-layout if remote 168 * - chroot if local 169 * 170 */ 171 const buffer *docroot; 172 173 /* 174 * append PATH_INFO to SCRIPT_FILENAME 175 * 176 * php needs this if cgi.fix_pathinfo is provided 177 * 178 */ 179 180 unsigned short break_scriptfilename_for_php; 181 182 /* 183 * check_local tells you if the phys file is stat()ed 184 * or not. FastCGI doesn't care if the service is 185 * remote. If the web-server side doesn't contain 186 * the FastCGI-files we should not stat() for them 187 * and say '404 not found'. 188 */ 189 unsigned short check_local; 190 191 /* 192 * workaround for program when prefix="/" 193 * 194 * rule to build PATH_INFO is hardcoded for when check_local is disabled 195 * enable this option to use the workaround 196 * 197 */ 198 199 unsigned short fix_root_path_name; 200 201 /* 202 * If the backend includes X-Sendfile in the response 203 * we use the value as filename and ignore the content. 204 * 205 */ 206 unsigned short xsendfile_allow; 207 const array *xsendfile_docroot; 208 209 uint32_t max_id; /* corresponds most of the time to num_procs */ 210 211 const buffer *strip_request_uri; 212 213 unsigned short tcp_fin_propagate; 214 unsigned short kill_signal; /* we need a setting for this as libfcgi 215 applications prefer SIGUSR1 while the 216 rest of the world would use SIGTERM 217 *sigh* */ 218 219 int listen_backlog; 220 int refcount; 221 222 char_array args; 223 } gw_host; 224 225 /* 226 * one extension can have multiple hosts assigned 227 * one host can spawn additional processes on the same 228 * socket (if we control it) 229 * 230 * ext -> host -> procs 231 * 1:n 1:n 232 * 233 * if the gw process is remote that whole goes down 234 * to 235 * 236 * ext -> host -> procs 237 * 1:n 1:1 238 * 239 * in case of PHP and FCGI_CHILDREN we have again a procs 240 * but we don't control it directly. 241 * 242 */ 243 244 typedef struct { 245 const buffer key; /* like .php */ 246 247 int note_is_sent; 248 int last_used_ndx; 249 250 gw_host **hosts; 251 252 uint32_t used; 253 uint32_t size; 254 } gw_extension; 255 256 typedef struct { 257 gw_extension *exts; 258 uint32_t used; 259 uint32_t size; 260 } gw_exts; 261 262 263 264 265 #include "base_decls.h" 266 #include "chunk.h" 267 #include "plugin.h" 268 #include "response.h" 269 270 typedef struct gw_plugin_config { 271 gw_exts *exts; 272 gw_exts *exts_auth; 273 gw_exts *exts_resp; 274 const array *ext_mapping; 275 int balance; 276 int proto; 277 int debug; 278 } gw_plugin_config; 279 280 /* generic plugin data, shared between all connections */ 281 typedef struct gw_plugin_data { 282 PLUGIN_DATA; 283 pid_t srv_pid; /* must precede gw_plugin_config for mods w/ larger struct */ 284 gw_plugin_config conf; /* used only as long as no gw_handler_ctx is setup */ 285 gw_plugin_config defaults;/*(must not be used by gw_backend.c: lg struct) */ 286 } gw_plugin_data; 287 288 /* connection specific data */ 289 typedef enum { 290 GW_STATE_INIT, 291 GW_STATE_CONNECT_DELAYED, 292 GW_STATE_PREPARE_WRITE, 293 GW_STATE_WRITE, 294 GW_STATE_READ 295 } gw_connection_state_t; 296 297 struct fdevents; /* declaration */ 298 299 #define GW_RESPONDER 1 300 #define GW_AUTHORIZER 2 301 #define GW_FILTER 3 /*(not implemented)*/ 302 303 typedef struct gw_handler_ctx { 304 gw_proc *proc; 305 gw_host *host; 306 gw_extension *ext; 307 gw_extension *ext_auth; /* (future: might allow multiple authorizers)*/ 308 unsigned short gw_mode; /* mode: GW_AUTHORIZER or GW_RESPONDER */ 309 310 gw_connection_state_t state; 311 312 chunkqueue *rb; /* read queue */ 313 off_t wb_reqlen; 314 chunkqueue wb; /* write queue */ 315 316 buffer *response; 317 318 struct fdevents *ev; 319 fdnode *fdn; /* fdevent (fdnode *) object */ 320 int fd; /* fd to the gw process */ 321 int revents; /* ready events on fd */ 322 323 pid_t pid; 324 int reconnects; /* number of reconnect attempts */ 325 326 int request_id; 327 int send_content_body; 328 329 http_response_opts opts; 330 gw_plugin_config conf; 331 332 request_st *r; /* dumb pointer */ 333 connection *con; /* dumb pointer */ 334 gw_plugin_data *plugin_data; /* dumb pointer */ 335 unix_time64_t read_ts; 336 unix_time64_t write_ts; 337 handler_t(*stdin_append)(struct gw_handler_ctx *hctx); 338 handler_t(*create_env)(struct gw_handler_ctx *hctx); 339 struct gw_handler_ctx *prev; 340 struct gw_handler_ctx *next; 341 void(*backend_error)(struct gw_handler_ctx *hctx); 342 void(*handler_ctx_free)(void *hctx); 343 } gw_handler_ctx; 344 345 346 __attribute_cold__ 347 __attribute_malloc__ 348 void * gw_init(void); 349 350 __attribute_cold__ 351 void gw_plugin_config_free(gw_plugin_config *s); 352 353 __attribute_cold__ 354 void gw_free(void *p_d); 355 356 __attribute_cold__ 357 void gw_exts_clear_check_local(gw_exts *exts); 358 359 __attribute_cold__ 360 int gw_set_defaults_backend(server *srv, gw_plugin_data *p, const array *a, gw_plugin_config *s, int sh_exec, const char *cpkkey); 361 362 __attribute_cold__ 363 int gw_get_defaults_balance(server *srv, const buffer *b); 364 365 handler_t gw_check_extension(request_st *r, gw_plugin_data *p, int uri_path_handler, size_t hctx_sz); 366 handler_t gw_handle_request_reset(request_st *r, void *p_d); 367 handler_t gw_handle_subrequest(request_st *r, void *p_d); 368 handler_t gw_handle_trigger(server *srv, void *p_d); 369 handler_t gw_handle_waitpid_cb(server *srv, void *p_d, pid_t pid, int status); 370 371 void gw_set_transparent(gw_handler_ctx *hctx); 372 373 #endif 374