crossroads.h (14389B)
1 /************************************************************************* 2 * This file is part of Crosroads 1.23, a load balancer and fail over 3 * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. 4 * Visit http://crossroads.e-tunity.com for information. 5 *************************************************************************/ 6 7 /* Includes. */ 8 9 #include <ctype.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <netdb.h> 13 #ifdef HAVE_MALLOC_H 14 #include <malloc.h> 15 #endif 16 #include <math.h> 17 #include <pwd.h> 18 #include <setjmp.h> 19 #include <signal.h> 20 #include <stdarg.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #ifdef HAVE_STDINT_H 24 #include <stdint.h> 25 #endif 26 #include <string.h> 27 #include <syslog.h> 28 #include <time.h> 29 #include <unistd.h> 30 #include <arpa/inet.h> 31 #include <netinet/in.h> 32 #include <sys/file.h> 33 #include <sys/ipc.h> 34 #include <sys/sem.h> 35 #include <sys/shm.h> 36 #include <sys/stat.h> 37 #include <sys/socket.h> 38 #include <sys/time.h> 39 #include <sys/times.h> 40 #include <sys/types.h> 41 42 /* flock() macros, incase they aren't present on your system. */ 43 #ifndef LOCK_SH 44 #define LOCK_SH 1 45 #endif 46 #ifndef LOCK_EX 47 #define LOCK_EX 2 48 #endif 49 #ifndef LOCK_NB 50 #define LOCK_NB 4 51 #endif 52 #ifndef LOCK_UN 53 #define LOCK_UN 8 54 #endif 55 56 /* inet_addr() macros, incase they aren't present on your system. */ 57 #ifndef INADDR_NONE 58 #define INADDR_NONE ((unsigned long) -1) 59 #endif 60 61 /* Types. */ 62 typedef enum { /* Config parsing related */ 63 cf_portspec, 64 cf_verbosityspec, 65 cf_backendspec, 66 cf_serverspec, 67 cf_dispatchspec, 68 cf_revivespec, 69 cf_shmkeyspec, 70 cf_weightspec, 71 cf_decayspec, 72 cf_onstartspec, 73 cf_onfailspec, 74 cf_onendspec, 75 cf_connectiontimeoutspec, 76 cf_maxconnectionsspec, 77 cf_typespec, 78 cf_dumpspec, 79 cf_thruspec, 80 cf_bindspec, 81 cf_stickycookiespec, 82 cf_setclientheaderspec, 83 cf_addclientheaderspec, 84 cf_appendclientheaderspec, 85 cf_setserverheaderspec, 86 cf_addserverheaderspec, 87 cf_appendserverheaderspec, 88 cf_allowfromspec, 89 cf_denyfromspec, 90 cf_allowfilespec, 91 cf_denyfilespec, 92 cf_useraccountspec, 93 } Conftype; 94 95 typedef union { /* Integer of string value */ 96 int ival; /* passed around by the parser */ 97 char *sval; 98 } IntOrString; 99 100 typedef struct { 101 Conftype cf; 102 IntOrString v; 103 } Confset; 104 105 typedef struct { 106 int n; 107 Confset *set; 108 } Confsets; 109 110 typedef enum { /* Dispatching types */ 111 ds_roundrobin, 112 ds_random, 113 ds_bysize, 114 ds_byduration, 115 ds_byorder, 116 ds_byconnections, 117 ds_externalhandler, 118 } Dispatchtype; 119 120 typedef enum { /* Service types */ 121 type_any, 122 type_http, 123 } Servicetype; 124 125 typedef struct { /* Backend description */ 126 char *name; /* .. back end identifier */ 127 int port; /* .. TCP port */ 128 char *server; /* .. server name */ 129 int verbosity; /* .. debugging on/off */ 130 int weight; /* .. weight in backend selection */ 131 int decay; /* .. decay in % */ 132 char *onstart; /* .. system() on success */ 133 char *onfail; /* .. or on failure */ 134 char *onend; /* .. or on ending */ 135 char *dumpfile; /* .. traffic dump file */ 136 char *thruputfile; /* .. traffic throughput file */ 137 int maxconnections; /* .. max # of allowed connections */ 138 char *stickycookie; /* .. cookie selector */ 139 char **addclientheader; /* .. client hdrs to ADD */ 140 int naddclientheader; /* .. table size */ 141 char **setclientheader; /* .. client hdrs to SET */ 142 int nsetclientheader; /* .. table size */ 143 char **appendclientheader; /* .. client hdrs to APPEND */ 144 int nappendclientheader; /* .. table size */ 145 char **addserverheader; /* .. server hdrs to ADD */ 146 int naddserverheader; /* .. table size */ 147 char **setserverheader; /* .. server hdrs to SET */ 148 int nsetserverheader; /* .. table size */ 149 char **appendserverheader; /* .. server hdrs to APPEND */ 150 int nappendserverheader; /* .. table size */ 151 } Backend; 152 153 typedef struct { /* Filtering information: */ 154 unsigned ip; /* .. IP address (or part of it) */ 155 unsigned mask; /* .. netmask */ 156 } IpFilter; 157 158 typedef struct { /* Service description */ 159 char *name; /* .. service name */ 160 char *bind; /* .. address to bind to */ 161 unsigned port; /* .. listening port */ 162 unsigned verbosity; /* .. message generation */ 163 Dispatchtype dispatchtype; /* .. backend selection method */ 164 unsigned dispatchover; /* .. selection over # connections */ 165 char *dispatchext; /* .. external handler */ 166 unsigned rev_interval; /* .. dead backend revival interval */ 167 unsigned backlog; /* .. # pending TCP connections */ 168 unsigned shmkey; /* .. key for SysV IPC */ 169 unsigned connectiontimeout; /* .. # secs for timeout handling */ 170 unsigned maxconnections; /* .. max # of allowed connections */ 171 Servicetype type; /* .. type of the service */ 172 Backend *backend; /* .. the back ends */ 173 int nbackend; /* .. size of backend array */ 174 char *allowfile; /* .. file with allowed IP filters */ 175 char *denyfile; /* .. and denied */ 176 IpFilter *allowchain; /* .. chain of allowed IP's */ 177 int nallowchain; /* .. size of chain */ 178 IpFilter *denychain; /* .. chain of denied IP's */ 179 int ndenychain; /* .. size of chain */ 180 int uid; /* .. UID to assume for system() */ 181 int gid; /* .. GID to assume for system() */ 182 } Service; 183 184 typedef enum { /* Backend availability */ 185 st_available, /* .. all OK */ 186 st_unavailable, /* .. temporarily unavailable */ 187 st_down, /* .. permanently unavailable */\ 188 st_waking, /* .. scheduled for wake up */ 189 st_intermediate, /* .. bogus, for mark_activity() */ 190 st_unknown, /* .. no idea (terminator) */ 191 } Backendavail; 192 193 typedef struct { /* Backend state */ 194 Backendavail avail; /* .. availability */ 195 unsigned long totuses; /* .. times hit */ 196 unsigned long failures; /* .. times failed */ 197 unsigned long long nbytes; /* .. transferred bytes */ 198 unsigned long sessions; /* .. # of http sessions */ 199 unsigned long avg_nbytes; /* .. averaged over # connections */ 200 double nsec; /* .. connection durations */ 201 double avg_nsec; /* .. averaged over # connections */ 202 unsigned nclients; /* .. active clients */ 203 } Backendstate; 204 205 typedef struct { /* Service reporting (shmem) */ 206 int pid; /* .. PID of service daemon */ 207 int rev_pid; /* .. PID of revival handler */ 208 int nclients; /* .. active clients */ 209 int last_backend; /* .. last used back end */ 210 Backendstate /* .. states of the back ends */ 211 backendstate[MAX_BACKEND]; 212 } Servicereport; 213 214 typedef enum { /* Stage of the program: */ 215 stage_main, /* .. commandline */ 216 stage_waiting, /* .. waiting for connections */ 217 stage_serving, /* .. servicing a connection */ 218 stage_retrying, /* .. waking up a backend */ 219 } Programstage; /* Update stagetostring.c when */ 220 /* modifying! */ 221 222 typedef struct { /* An HTTP Message */ 223 char **header; /* Headers table, excluding first */ 224 int nheader; /* Headers table size */ 225 } HttpHeader; 226 227 typedef enum { /* Time representation format */ 228 tm_localtime, /* .. local */ 229 tm_gmtime, /* .. UTC */ 230 } TmType; 231 232 typedef enum { /* TCP copying direction */ 233 dir_client_to_server, 234 dir_server_to_client, 235 } CopyDirection; 236 237 typedef enum { /* HTTP version */ 238 con_unknown, 239 con_keepalive, 240 con_close, 241 } HttpConnectionType; 242 243 /* Globals. */ 244 #ifndef EXTERN 245 #define EXTERN extern 246 #endif 247 248 EXTERN Service *activeservice; /* target service of a daemon */ 249 EXTERN unsigned char *clbuf; /* client socket input buffer */ 250 EXTERN unsigned clbufpos, clbufmax; /* .. position & bytes */ 251 EXTERN char *client_ip; /* connected client */ 252 EXTERN char *config_file; /* config to parse */ 253 EXTERN int current_backend; /* of a given service */ 254 EXTERN int daemonized; /* are we forked off yet */ 255 EXTERN int flag_verbose; /* flag: verbosity */ 256 EXTERN int gid_org, gid_set; /* original gid, flag: changed? */ 257 EXTERN int iflag_present; /* flag: -i present */ 258 EXTERN int interrupted; /* got a signal? */ 259 EXTERN char *laststring; /* semantic lexer value */ 260 EXTERN int listen_sock; /* servicer listening socket */ 261 EXTERN int log_activity; /* log activy to syslog? */ 262 EXTERN int log_facility; /* openlog(3) facility, -l flag */ 263 EXTERN int logstarted; /* was syslog() called yet? */ 264 EXTERN int nservice; /* # service descriptions */ 265 EXTERN int org_argc; /* original argc */ 266 EXTERN char **org_argv; /* and original argv */ 267 EXTERN Programstage program_stage; /* stage of the program */ 268 EXTERN int relevant_sigs[]; /* relevant signals */ 269 EXTERN int semid; /* semaphore ID */ 270 EXTERN Service *service; /* service descriptions */ 271 EXTERN Servicereport *servicereport; /* reporter in shared mem */ 272 EXTERN int sloppyportbind; /* -s flag present */ 273 EXTERN unsigned char *srbuf; /* server socket input buffer */ 274 EXTERN unsigned srbufpos, srbufmax; /* .. position & bytes */ 275 EXTERN char *state_to_string_map[]; /* backend states as strings */ 276 EXTERN int uid_org, uid_set; /* original uid, flag: changed? */ 277 EXTERN FILE *yyin; /* config file handle */ 278 EXTERN int yylineno; /* input line number */ 279 EXTERN char *yyerrmsg; /* parsing error msg */ 280 EXTERN char *yytext; /* lexical buffer */ 281 282 /* Functions. */ 283 extern void alloc_reporter (Service *active, int first); 284 extern char *ansistamp (TmType t); 285 extern int backend_available (int target); 286 extern int backend_count(void); 287 extern int backend_connect (void); 288 extern void choose_backend (void); 289 extern void copysockets (int clientsock, int serversock); 290 extern int configtest (int ac, char **av); 291 extern void create_commandline_space (void); 292 extern void decr_client_count (void); 293 extern void dealloc_reporter (Service *s); 294 extern void error (char const *fmt, ...); 295 extern int fork_tcp_servicer (int to_backend); 296 extern void http_copy (HttpHeader *h, int src_sock, int dst_sock, 297 CopyDirection dir); 298 extern void http_error (int clientsock); 299 extern void http_header_addheader (HttpHeader *m, char const *hdr); 300 extern void http_header_appendheader (HttpHeader *m, char const *hdr); 301 extern HttpConnectionType http_header_connectiontype (HttpHeader *h); 302 extern void http_header_free (HttpHeader *msg); 303 extern int http_header_hascookie (HttpHeader *m, char const *cookie); 304 extern double http_header_httpver (HttpHeader *h); 305 extern void http_header_removeheader (HttpHeader *h, char const *hdr); 306 extern unsigned char const *http_header_val (HttpHeader *h, char const *hdr); 307 extern HttpHeader *http_header_new (void); 308 extern void http_header_read (HttpHeader *m, int srcsock, CopyDirection dir); 309 extern void http_header_setheader (HttpHeader *m, char const *hdr); 310 extern void http_header_write (HttpHeader *m, int sock, CopyDirection dir); 311 extern void http_serve (int clientsock); 312 extern int http_serversocket (HttpHeader *m, int *is_continuation); 313 extern int http_write (int sock, CopyDirection dir, unsigned char const *buf, 314 unsigned buflen); 315 extern void incr_client_count (void); 316 extern int init_sockaddr (struct sockaddr_in *name, 317 const char *hostname, int port); 318 extern void interrupt (int sig); 319 extern int ipf_add_allow (Service *s, char const *val); 320 extern int ipf_add_deny (Service *s, char const *val); 321 extern int ipf_allowed (void); 322 extern int ipf_denied (void); 323 extern int ipf_loadfile (char const *fname, IpFilter **chain, int *nchain); 324 extern int ipf_match (IpFilter f); 325 extern int ipf_parse (char const *val, IpFilter *res); 326 extern int is_hex_digit (char ch); 327 extern int is_space (char ch); 328 extern void lock_reporter (void); 329 extern void log_activity_any (char const *action); 330 extern void log_activity_start (void); 331 extern void log_activity_end (void); 332 extern void log_activity_continuation (void); 333 extern int make_socket (int port, char const *ipaddr); 334 extern void mark_activity (unsigned long long nbytes, 335 double nsec, 336 Backendavail newstate); 337 extern void msg (char const *fmt, ...); 338 extern void msgdumpbuf (unsigned char const *buf, int buflen); 339 extern unsigned net_copy (int clientsock, int serversock, unsigned maxbytes, 340 unsigned char *buf); 341 extern unsigned net_read (int sock, unsigned maxbytes, unsigned char *buf, 342 int is_client); 343 extern unsigned char *net_buffer (CopyDirection dir, unsigned *sz); 344 extern unsigned char *net_bufread (int sock, unsigned maxbytes, 345 unsigned *nreadp, int is_client); 346 extern int net_write (int sock, unsigned char const *buf, unsigned len, 347 int is_client); 348 extern int restart (int ac, char **av); 349 extern void runservice (void); 350 extern int serve (int ac, char **av); 351 extern void set_program_title (char const *fmt, ...); 352 extern int show_services (int ac, char **av); 353 extern int show_status (int ac, char **av); 354 extern char *stage_to_string (Programstage stage); 355 extern char *state_to_string (Backendavail avail); 356 extern Backendavail string_to_state (char const *str); 357 extern int stop_daemon (int ac, char **av); 358 extern char *str_expand_format (char const *h); 359 extern char *str_printf (char const *fmt, ...); 360 extern char *str_vprintf (char const *fmt, va_list args); 361 extern void sysrun (char const *cmd); 362 extern void tcpserve (int sock); 363 extern int tell_service (int ac, char **av); 364 extern void thruputlog (unsigned char const *buf, int len, CopyDirection dir); 365 extern void trafficlog (unsigned char const *buf, int len, CopyDirection dir); 366 extern void unlock_reporter (void); 367 extern void uid_assume (void); 368 extern void uid_restore (void); 369 extern void usage (void); 370 extern void wakeup_handler (void); 371 extern void warning (char const *fmt, ...); 372 extern void writelog (int prio, char const *fmt, ...); 373 extern int yyparse (void); 374 extern void *xmalloc (unsigned sz); 375 extern void *xrealloc (void *what, unsigned sz); 376 extern char *xstrcat (char *what, char const *rest); 377 extern char *xstrcatch (char *what, char ch); 378 extern char *xstrdup (char const *what); 379 380 /* strlcat() if it's missing on this system */ 381 #ifndef HAVE_STRLCAT 382 extern size_t strlcat (char *dst, char const *src, size_t size); 383 #endif 384 385 /* vsyslog() if it's missing on this system */ 386 #ifndef HAVE_VSYSLOG 387 extern void vsyslog (int fac, char const *fmt, va_list args); 388 #endif 389 390 /* strcasestr() if it's missing on this system */ 391 #ifndef HAVE_STRCASESTR 392 extern char *strcasestr (char const *big, char const *little); 393 #endif