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