1 /* 2 * (GNU Serveez 0.2.1) libserveez.h 3 * 4 * Copyright (C) 2011-2012, 2013 Thien-Thi Nguyen 5 * Copyright (C) 2000-2003 Stefan Jahn <stefan@lkcc.org> 6 * Copyright (C) 2002 Andreas Rottmann <a.rottmann@gmx.at> 7 * Copyright (C) 2000-2001 Raimund Jacob <raimi@lkcc.org> 8 * Copyright (C) 1999 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> 9 * 10 * This is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 3, or (at your option) 13 * any later version. 14 * 15 * This software is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this package. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef __LIBSERVEEZ_H__ 25 #define __LIBSERVEEZ_H__ 1 26 27 /* (svzconfig) */ 28 /* Define to 1 if you have the <winsock2.h> header file. */ 29 /* #undef SVZ_HAVE_WINSOCK2_H */ 30 31 /* Define to 1 if you have the <arpa/inet.h> header file. */ 32 #define SVZ_HAVE_ARPA_INET_H 1 33 34 /* Define to 1 if you have the <netinet/in.h> header file. */ 35 #define SVZ_HAVE_NETINET_IN_H 1 36 37 /* Define to 'int' if <winsock2.h> does not define 'HANDLE'. */ 38 #define svz_t_handle int 39 40 /* Define to 'int' if <winsock2.h> does not define 'SOCKET'. */ 41 #define svz_t_socket int 42 43 /* Make CygWin / MinGW32 use large FD sets. */ 44 /* #undef FD_SETSIZE */ 45 46 /* Define for faster code generation. */ 47 /* #undef WIN32_LEAN_AND_MEAN */ 48 49 /* Define if you are using Windows Socket-API (not CYGWIN). */ 50 /* #undef Win32_Winsock */ 51 52 53 /* (defines) */ 54 55 /* System headers: standard ones unconditional; 56 the rest only ‘#ifdef SVZ_HAVE_HEADER_H’ .. ‘#endif’. */ 57 58 #include <stdio.h> 59 #include <stdlib.h> 60 #include <stdint.h> 61 62 #ifdef SVZ_HAVE_WINSOCK2_H 63 #include <winsock2.h> 64 #endif 65 66 #ifdef SVZ_HAVE_ARPA_INET_H 67 #include <arpa/inet.h> 68 #endif 69 70 #ifdef SVZ_HAVE_NETINET_IN_H 71 #include <netinet/in.h> 72 #endif 73 74 75 /* ‘__BEGIN_DECLS’ should be used at the beginning of your declarations, 76 so that C++ compilers don't mangle their names. Use ‘__END_DECLS’ at 77 the end of C declarations. */ 78 79 #undef __BEGIN_DECLS 80 #undef __END_DECLS 81 #ifdef __cplusplus 82 # define __BEGIN_DECLS extern "C" { 83 # define __END_DECLS } 84 #else 85 # define __BEGIN_DECLS 86 # define __END_DECLS 87 #endif 88 89 /* ‘SERVEEZ_API’ is a macro prepended to all function and data definitions 90 which should be exported or imported in the resulting dynamic link 91 library in the Win32 port. */ 92 93 #if defined (__SERVEEZ_IMPORT__) 94 # define SERVEEZ_API __declspec (dllimport) extern 95 #elif defined (__SERVEEZ_EXPORT__) || defined (DLL_EXPORT) 96 # define SERVEEZ_API __declspec (dllexport) extern 97 #else 98 # define SERVEEZ_API extern 99 #endif 100 101 102 /* (address) */ 103 104 typedef struct svz_address svz_address_t; 105 106 __BEGIN_DECLS 107 108 SERVEEZ_API svz_address_t *svz_address_make (int family, const void *bits); 109 SERVEEZ_API int svz_address_family (const svz_address_t *addr); 110 SERVEEZ_API int svz_address_to (void *dest, const svz_address_t *addr); 111 SERVEEZ_API int svz_address_same (const svz_address_t *a, 112 const svz_address_t *b); 113 SERVEEZ_API const char *svz_pp_address (char *buf, size_t size, 114 const svz_address_t *addr); 115 SERVEEZ_API const char *svz_pp_addr_port (char *buf, size_t size, 116 const svz_address_t *addr, 117 in_port_t port); 118 SERVEEZ_API svz_address_t *svz_address_copy (const svz_address_t *addr); 119 120 __END_DECLS 121 122 123 /* Idioms. */ 124 125 /** 126 * Expand to a series of commands. First, if @var{place} is 127 * non-@code{NULL}, then @code{svz_free} it. Next, assign to 128 * @var{place} a new address object made by calling 129 * @code{svz_address_make} with @var{family} and @var{bits}. 130 */ 131 #define SVZ_SET_ADDR(place,family,bits) do \ 132 { \ 133 if (place) \ 134 svz_free (place); \ 135 place = svz_address_make (family, bits); \ 136 } \ 137 while (0) 138 139 /** 140 * Expand to a call to @code{svz_pp_address}, passing it 141 * @var{buf} and @code{sizeof @var{buf}}, in addition to @var{addr}. 142 */ 143 #define SVZ_PP_ADDR(buf,addr) \ 144 svz_pp_address (buf, sizeof buf, addr) 145 146 /** 147 * Expand to a call to @code{svz_pp_addr_port}, passing it 148 * @var{buf} and @code{sizeof @var{buf}}, in addition to 149 * @var{addr} and @var{port}. 150 */ 151 #define SVZ_PP_ADDR_PORT(buf,addr,port) \ 152 svz_pp_addr_port (buf, sizeof buf, addr, port) 153 154 155 /* (boot) */ 156 157 /* Runtime parameters. */ 158 #define SVZ_RUNPARM_VERBOSITY 0 159 #define SVZ_RUNPARM_MAX_SOCKETS 1 160 161 __BEGIN_DECLS 162 163 SERVEEZ_API const char * const * svz_library_features (size_t *); 164 SERVEEZ_API void svz_boot (char const *); 165 SERVEEZ_API long svz_uptime (void); 166 SERVEEZ_API int svz_runparm (int, int); 167 SERVEEZ_API void svz_halt (void); 168 169 __END_DECLS 170 171 /** 172 * Return the value of runtime parameter @var{nick}. 173 */ 174 #define SVZ_RUNPARM(nick) \ 175 svz_runparm (-1, SVZ_RUNPARM_ ## nick) 176 177 /** 178 * Set the runtime paramater @var{nick} 179 * to have value @var{val}, an integer. 180 */ 181 #define SVZ_RUNPARM_X(nick,val) \ 182 svz_runparm (SVZ_RUNPARM_ ## nick, (val)) 183 184 185 /* (alloc) */ 186 187 __BEGIN_DECLS 188 189 /* Function type definitions. */ 190 typedef void * (* svz_malloc_func_t) (size_t); 191 typedef void * (* svz_realloc_func_t) (void *, size_t); 192 typedef void (* svz_free_func_t) (void *); 193 194 /* Global allocator functions. */ 195 SERVEEZ_API void svz_set_mm_funcs (svz_malloc_func_t, 196 svz_realloc_func_t, 197 svz_free_func_t); 198 199 /* Internal allocator functions. */ 200 SERVEEZ_API void *svz_malloc (size_t); 201 SERVEEZ_API void *svz_calloc (size_t); 202 SERVEEZ_API void *svz_realloc (void *, size_t); 203 SERVEEZ_API void svz_free (void *); 204 SERVEEZ_API char *svz_strdup (const char *); 205 206 207 SERVEEZ_API void svz_get_curalloc (size_t *); 208 209 __END_DECLS 210 211 212 /* (array) */ 213 214 typedef struct svz_array svz_array_t; 215 216 __BEGIN_DECLS 217 218 SERVEEZ_API svz_array_t *svz_array_create (size_t, svz_free_func_t); 219 SERVEEZ_API void svz_array_destroy (svz_array_t *); 220 SERVEEZ_API void *svz_array_get (svz_array_t *, size_t); 221 SERVEEZ_API void *svz_array_set (svz_array_t *, size_t, void *); 222 SERVEEZ_API void svz_array_add (svz_array_t *, void *); 223 SERVEEZ_API void *svz_array_del (svz_array_t *, size_t); 224 SERVEEZ_API size_t svz_array_size (svz_array_t *); 225 226 __END_DECLS 227 228 /** 229 * Expand into a @code{for}-statement header, for iterating over 230 * @var{array}. On each cycle, @var{value} is assigned to successive 231 * elements of @var{array}, and @var{i} the element's position. 232 */ 233 #define svz_array_foreach(array, value, i) \ 234 for ((i) = 0, (value) = svz_array_get ((array), 0); \ 235 (array) && (i) < svz_array_size (array); \ 236 ++(i), (value) = svz_array_get ((array), (i))) 237 238 239 /* (hash) */ 240 241 typedef struct svz_hash_entry svz_hash_entry_t; 242 typedef struct svz_hash_bucket svz_hash_bucket_t; 243 typedef struct svz_hash svz_hash_t; 244 245 typedef void (svz_hash_do_t) (void *, void *, void *); 246 247 __BEGIN_DECLS 248 249 /* 250 * Basic hash table functions. 251 */ 252 SERVEEZ_API svz_hash_t *svz_hash_create (size_t, svz_free_func_t); 253 SERVEEZ_API svz_hash_t * 254 svz_hash_configure (svz_hash_t *hash, 255 size_t (* keylen) (const char *), 256 unsigned long (* code) (const char *), 257 int (* equals) (const char *, const char *)); 258 SERVEEZ_API void svz_hash_destroy (svz_hash_t *); 259 SERVEEZ_API void *svz_hash_delete (svz_hash_t *, const char *); 260 SERVEEZ_API void *svz_hash_put (svz_hash_t *, const char *, void *); 261 SERVEEZ_API void *svz_hash_get (const svz_hash_t *, const char *); 262 SERVEEZ_API void svz_hash_foreach (svz_hash_do_t *, svz_hash_t *, void *); 263 SERVEEZ_API size_t svz_hash_size (const svz_hash_t *); 264 SERVEEZ_API char *svz_hash_contains (const svz_hash_t *, void *); 265 SERVEEZ_API int svz_hash_exists (const svz_hash_t *, char *); 266 267 __END_DECLS 268 269 270 /* (util) */ 271 272 /* 273 * level of server's verbosity: 274 * 0 - only fatal error messages 275 * 1 - error messages 276 * 2 - warnings 277 * 3 - informational messages 278 * 4 - debugging output 279 * levels always imply numerically lesser levels 280 */ 281 #define SVZ_LOG_FATAL 0 282 #define SVZ_LOG_ERROR 1 283 #define SVZ_LOG_WARNING 2 284 #define SVZ_LOG_NOTICE 3 285 #define SVZ_LOG_DEBUG 4 286 287 __BEGIN_DECLS 288 289 290 SERVEEZ_API void svz_log (int, const char *, ...); 291 SERVEEZ_API void svz_log_setfile (FILE *); 292 SERVEEZ_API int svz_hexdump (FILE *, char *, int, char *, int, int); 293 SERVEEZ_API char *svz_itoa (unsigned int); 294 SERVEEZ_API unsigned int svz_atoi (char *); 295 SERVEEZ_API char *svz_getcwd (void); 296 SERVEEZ_API int svz_openfiles (int); 297 SERVEEZ_API char *svz_time (long); 298 SERVEEZ_API char *svz_tolower (char *); 299 SERVEEZ_API char *svz_sys_version (void); 300 301 SERVEEZ_API int svz_socket_unavailable_error_p (void); 302 303 SERVEEZ_API const char *svz_sys_strerror (void); 304 SERVEEZ_API void svz_log_sys_error (char const *, ...); 305 SERVEEZ_API void svz_log_net_error (char const *, ...); 306 307 308 SERVEEZ_API int svz_mingw_at_least_nt4_p (void); 309 310 __END_DECLS 311 312 313 /* (socket) */ 314 315 /* Do not write more than this many bytes to a socket at once. */ 316 #define SVZ_SOCK_MAX_WRITE 1024 317 318 319 #define SVZ_SOFLG_INIT 0x00000000 /* Value for initializing. */ 320 #define SVZ_SOFLG_INBUF 0x00000001 /* Outbuf is allocated. */ 321 #define SVZ_SOFLG_OUTBUF 0x00000002 /* Inbuf is allocated. */ 322 #define SVZ_SOFLG_CONNECTED 0x00000004 /* Socket is connected. */ 323 #define SVZ_SOFLG_LISTENING 0x00000008 /* Socket is listening. */ 324 #define SVZ_SOFLG_KILLED 0x00000010 /* Socket will be shut down soon. */ 325 #define SVZ_SOFLG_NOFLOOD 0x00000020 /* Flood protection off. */ 326 #define SVZ_SOFLG_INITED 0x00000040 /* Socket was initialized. */ 327 #define SVZ_SOFLG_ENQUEUED 0x00000080 /* Socket is on socket queue. */ 328 #define SVZ_SOFLG_RECV_PIPE 0x00000100 /* Receiving pipe is active. */ 329 #define SVZ_SOFLG_SEND_PIPE 0x00000200 /* Sending pipe is active. */ 330 #define SVZ_SOFLG_FILE 0x00000400 /* Socket is no socket, but file. */ 331 #define SVZ_SOFLG_COSERVER 0x00000800 /* Socket is a coserver */ 332 #define SVZ_SOFLG_SOCK 0x00001000 /* Socket is a plain socket. */ 333 /* Socket is no socket, but pipe. */ 334 #define SVZ_SOFLG_PIPE \ 335 ( SVZ_SOFLG_RECV_PIPE | \ 336 SVZ_SOFLG_SEND_PIPE ) 337 #define SVZ_SOFLG_CONNECTING 0x00002000 /* Socket is still connecting */ 338 #define SVZ_SOFLG_PRIORITY 0x00004000 /* Enqueue socket preferred. */ 339 #define SVZ_SOFLG_FIXED 0x00008000 /* Dedicated UDP connection. */ 340 #define SVZ_SOFLG_FINAL_WRITE 0x00010000 /* Disconnect as soon as send 341 queue is empty. */ 342 #define SVZ_SOFLG_READING 0x00020000 /* Pending read operation. */ 343 #define SVZ_SOFLG_WRITING 0x00040000 /* Pending write operation. */ 344 #define SVZ_SOFLG_FLUSH 0x00080000 /* Flush receive and send queue. */ 345 #define SVZ_SOFLG_NOSHUTDOWN 0x00100000 /* Disable shutdown. */ 346 #define SVZ_SOFLG_NOOVERFLOW 0x00200000 /* Disable receive buffer overflow. */ 347 348 typedef struct svz_socket svz_socket_t; 349 350 struct svz_socket 351 { 352 svz_socket_t *next; /* Next socket in chain. */ 353 svz_socket_t *prev; /* Previous socket in chain. */ 354 355 int id; /* Unique ID for this socket. */ 356 int version; /* Socket version */ 357 int parent_id; /* A sockets parent ID. */ 358 int parent_version; /* A sockets parent version. */ 359 int referrer_id; /* Referring socket ID. */ 360 int referrer_version; /* Referring socket version. */ 361 362 int proto; /* Server/Protocol flag. */ 363 int flags; /* One of the SVZ_SOFLG_* flags above. */ 364 int userflags; /* Can be used for protocol specific flags. */ 365 svz_t_socket sock_desc; /* Socket descriptor. */ 366 int file_desc; /* Used for files descriptors. */ 367 svz_t_handle pipe_desc[2]; /* Used for the pipes and coservers. */ 368 svz_t_handle pid; /* Process id. */ 369 370 #ifdef __MINGW32__ 371 LPOVERLAPPED overlap[2]; /* Overlap info for WinNT. */ 372 int recv_pending; /* Number of pending read bytes. */ 373 int send_pending; /* Number of pending write bytes. */ 374 #endif /* not __MINGW32__ */ 375 376 char *recv_pipe; /* File of the receive pipe. */ 377 char *send_pipe; /* File of the send pipe. */ 378 379 char *boundary; /* Packet boundary. */ 380 int boundary_size; /* Packet boundary length */ 381 382 /* The following items always MUST be in network byte order. */ 383 in_port_t remote_port; /* Port number of remote end. */ 384 svz_address_t *remote_addr; /* IP address of remote end. */ 385 in_port_t local_port; /* Port number of local end. */ 386 svz_address_t *local_addr; /* IP address of local end. */ 387 388 char *send_buffer; /* Buffer for outbound data. */ 389 char *recv_buffer; /* Buffer for inbound data. */ 390 int send_buffer_size; /* Size of SEND_BUFFER. */ 391 int recv_buffer_size; /* Size of RECV_BUFFER. */ 392 int send_buffer_fill; /* Valid bytes in SEND_BUFFER. */ 393 int recv_buffer_fill; /* Valid bytes in RECV_BUFFER. */ 394 395 uint16_t sequence; /* Currently received sequence. */ 396 uint16_t send_seq; /* Send stream sequence number. */ 397 uint16_t recv_seq; /* Receive stream sequence number. */ 398 uint8_t itype; /* ICMP message type. */ 399 400 /* 401 * READ_SOCKET gets called whenever data is available on the socket. 402 * Normally, this is set to a default function which reads all available 403 * data from the socket and feeds it to CHECK_REQUEST, but specific 404 * sockets may need another policy. 405 */ 406 int (* read_socket) (svz_socket_t *sock); 407 408 /* 409 * READ_SOCKET_OOB is run when urgent data has been detected on the 410 * socket. By default it reads a single byte, stores it in OOB and passes 411 * it to the CHECK_REQUEST_OOB callback. 412 */ 413 int (* read_socket_oob) (svz_socket_t *sock); 414 415 /* 416 * WRITE_SOCKET is called when data is is valid in the output buffer 417 * and the socket gets available for writing. Normally, this simply 418 * writes as much data as possible to the socket and removes it from 419 * the buffer. 420 */ 421 int (* write_socket) (svz_socket_t *sock); 422 423 /* 424 * DISCONNECTED_SOCKET gets called whenever the socket is lost for 425 * some external reason. 426 */ 427 int (* disconnected_socket) (svz_socket_t *sock); 428 429 /* 430 * CONNECTED_SOCKET gets called whenever the socket is finally 431 * connected. 432 */ 433 int (* connected_socket) (svz_socket_t *sock); 434 435 /* 436 * KICKED_SOCKET gets called whenever the socket gets closed by us. 437 */ 438 int (* kicked_socket) (svz_socket_t *sock, int reason); 439 440 /* 441 * CHECK_REQUEST gets called whenever data was read from the socket. 442 * Its purpose is to check whether a complete request was read, and 443 * if it was, it should be handled and removed from the input buffer. 444 */ 445 int (* check_request) (svz_socket_t *sock); 446 447 /* 448 * CHECK_REQUEST_OOB is called when urgent data has been read from the 449 * socket. The received byte is stored in OOB. 450 */ 451 int (* check_request_oob) (svz_socket_t *sock); 452 453 /* 454 * HANDLE_REQUEST gets called when the CHECK_REQUEST got 455 * a valid packet. 456 */ 457 int (* handle_request) (svz_socket_t *sock, char *request, int len); 458 459 /* 460 * CHILD_DIED is called when the PID stored in the socket structure 461 * equals the one signaled by the internal signal handler. 462 */ 463 int (* child_died) (svz_socket_t *sock); 464 465 /* 466 * Called if TRIGGER_COND returned non-zero. 467 */ 468 int (* trigger_func) (svz_socket_t *sock); 469 470 /* 471 * TRIGGER_COND is called once every server loop. If it returns 472 * non-zero TRIGGER_FUNC is run. 473 */ 474 int (* trigger_cond) (svz_socket_t *sock); 475 476 /* 477 * IDLE_FUNC gets called from the periodic task scheduler. Whenever 478 * IDLE_COUNTER (see below) is non-zero, it is decremented and 479 * IDLE_FUNC gets called when it drops to zero. IDLE_FUNC can reset 480 * IDLE_COUNTER to some value and thus can re-schedule itself for a 481 * later task. 482 */ 483 int (* idle_func) (svz_socket_t * sock); 484 485 int idle_counter; /* Counter for calls to IDLE_FUNC. */ 486 487 long last_send; /* Timestamp of last send to socket. */ 488 long last_recv; /* Timestamp of last receive from socket */ 489 490 /* Note: These two are used only if flood protection is enabled. */ 491 int flood_points; /* Accumulated flood points. */ 492 int flood_limit; /* Limit of the above before kicking. */ 493 494 /* Out-of-band data for TCP protocol. This byte is used for both, 495 receiving and sending. */ 496 uint8_t oob; 497 498 /* Set to non-zero @code{time} value if the the socket is temporarily 499 unavailable (EAGAIN). This is why we use O_NONBLOCK socket descriptors. */ 500 int unavailable; 501 502 /* Miscellaneous field. Listener keeps array of server instances here. 503 This array is NULL terminated. */ 504 void *data; 505 506 /* When the final protocol detection has been done this should get the 507 actual configuration hash. */ 508 void *cfg; 509 510 /* Port configuration of a parent (listener). */ 511 void *port; 512 513 /* Codec data pointers. Yet another extension. */ 514 void *recv_codec; 515 void *send_codec; 516 }; 517 518 __BEGIN_DECLS 519 520 typedef void (svz_sock_prefree_fn) (const svz_socket_t *); 521 SERVEEZ_API void svz_sock_prefree (int addsub, svz_sock_prefree_fn fn); 522 SERVEEZ_API int svz_sock_nconnections (void); 523 SERVEEZ_API int svz_sock_write (svz_socket_t *, char *, int); 524 SERVEEZ_API int svz_sock_printf (svz_socket_t *, const char *, ...); 525 SERVEEZ_API int svz_sock_resize_buffers (svz_socket_t *, int, int); 526 SERVEEZ_API int svz_sock_check_request (svz_socket_t *); 527 SERVEEZ_API int svz_wait_if_unavailable (svz_socket_t *, unsigned int); 528 SERVEEZ_API void svz_sock_reduce_recv (svz_socket_t *, int); 529 SERVEEZ_API void svz_sock_reduce_send (svz_socket_t *, int); 530 531 __END_DECLS 532 533 534 /* (core) */ 535 536 /* protocol definitions */ 537 #define SVZ_PROTO_TCP 0x00000001 /* tcp - bidirectional, reliable */ 538 #define SVZ_PROTO_UDP 0x00000002 /* udp - multidirectional, unreliable */ 539 #define SVZ_PROTO_PIPE 0x00000004 /* pipe - unidirectional, reliable */ 540 #define SVZ_PROTO_ICMP 0x00000008 /* icmp - multidirectional, unreliable */ 541 #define SVZ_PROTO_RAW 0x00000010 /* raw - multidirectional, unreliable */ 542 543 /* Silence the "declared inside parameter list" warning. */ 544 struct stat; 545 546 __BEGIN_DECLS 547 548 SERVEEZ_API int svz_fd_cloexec (int); 549 SERVEEZ_API int svz_tcp_cork (svz_t_socket, int); 550 SERVEEZ_API int svz_tcp_nodelay (svz_t_socket, int, int *); 551 SERVEEZ_API int svz_closesocket (svz_t_socket); 552 SERVEEZ_API char *svz_inet_ntoa (in_addr_t); 553 SERVEEZ_API int svz_inet_aton (char *, struct sockaddr_in *); 554 SERVEEZ_API int svz_sendfile (int, int, off_t *, size_t); 555 SERVEEZ_API int svz_open (const char *, int, mode_t); 556 SERVEEZ_API int svz_close (int); 557 SERVEEZ_API int svz_fstat (int, struct stat *); 558 SERVEEZ_API FILE *svz_fopen (const char *, const char *); 559 SERVEEZ_API int svz_fclose (FILE *); 560 561 562 __END_DECLS 563 564 565 /* (pipe-socket) */ 566 567 #define SVZ_READ 0 /* read pipe index */ 568 #define SVZ_WRITE 1 /* write pipe index */ 569 570 /* 571 * Definition of a named pipe. 572 */ 573 typedef struct svz_pipe 574 { 575 char *name; /* name of named pipe */ 576 mode_t perm; /* user and group permissions */ 577 char *user; /* user name */ 578 uid_t uid; /* user id (calculated from user name) */ 579 gid_t pgid; /* primary group id */ 580 char *group; /* group name */ 581 gid_t gid; /* group id (calculated from group name) */ 582 } 583 svz_pipe_t; 584 585 __BEGIN_DECLS 586 587 SERVEEZ_API svz_socket_t *svz_pipe_create (svz_t_handle, 588 svz_t_handle); 589 SERVEEZ_API int svz_pipe_create_pair (svz_t_handle pipe_desc[2]); 590 SERVEEZ_API svz_socket_t *svz_pipe_connect (svz_pipe_t *, 591 svz_pipe_t *); 592 593 SERVEEZ_API void svz_invalidate_handle (svz_t_handle *); 594 SERVEEZ_API int svz_invalid_handle_p (svz_t_handle); 595 SERVEEZ_API int svz_closehandle (svz_t_handle); 596 597 __END_DECLS 598 599 600 /* (portcfg) */ 601 602 /* Port configuration items. */ 603 #define SVZ_PORTCFG_ANY "any" 604 #define SVZ_PORTCFG_NOIP "*" 605 606 607 /* Return values for port configuration comparisons. */ 608 #define SVZ_PORTCFG_NOMATCH 0x0001 609 #define SVZ_PORTCFG_EQUAL 0x0002 610 #define SVZ_PORTCFG_MATCH 0x0004 611 #define SVZ_PORTCFG_CONFLICT 0x0008 612 613 /* 614 * Definition of a single port configuration reflecting either a network 615 * (TCP, UDP, ICMP or RAW) or filesystem configuration (PIPE). 616 */ 617 typedef struct svz_portcfg 618 { 619 /* the symbolic name of this port configuration */ 620 char *name; 621 622 /* one of the PROTO_ flags defined in <core.h> */ 623 int proto; 624 625 /* one of PORTCFG_FLAG_ flags */ 626 int flags; 627 628 /* unified structure for each type of port */ 629 union protocol_t 630 { 631 /* tcp port */ 632 struct tcp_t 633 { 634 in_port_t port; /* TCP/IP port */ 635 char *ipaddr; /* dotted decimal or "*" for any address */ 636 struct sockaddr_in addr; /* converted from the above 2 values */ 637 char *device; /* network device */ 638 int backlog; /* backlog argument for ‘listen’ */ 639 } tcp; 640 641 /* udp port */ 642 struct udp_t 643 { 644 in_port_t port; /* UDP port */ 645 char *ipaddr; /* dotted decimal or "*" */ 646 struct sockaddr_in addr; /* converted from the above 2 values */ 647 char *device; /* network device */ 648 } udp; 649 650 /* icmp port */ 651 struct icmp_t 652 { 653 char *ipaddr; /* dotted decimal or "*" */ 654 struct sockaddr_in addr; /* converted from the above value */ 655 char *device; /* network device */ 656 uint8_t type; /* message type */ 657 } icmp; 658 659 /* raw ip port */ 660 struct raw_t 661 { 662 char *ipaddr; /* dotted decimal or "*" */ 663 struct sockaddr_in addr; /* converted from the above value */ 664 char *device; /* network device */ 665 } raw; 666 667 /* pipe port */ 668 struct pipe_t 669 { 670 svz_pipe_t recv; /* pipe for sending data into serveez */ 671 svz_pipe_t send; /* pipe serveez sends responses out on */ 672 } pipe; 673 } 674 protocol; 675 676 /* maximum number of bytes for protocol identification */ 677 int detection_fill; 678 679 /* maximum seconds for protocol identification */ 680 int detection_wait; 681 682 /* initial buffer sizes */ 683 int send_buffer_size; 684 int recv_buffer_size; 685 686 /* allowed number of connects per second (hammer protection) */ 687 int connect_freq; 688 689 /* remembers connect frequency for each ip */ 690 svz_hash_t *accepted; 691 692 /* denied and allowed access list (ip based) */ 693 svz_array_t *deny; 694 svz_array_t *allow; 695 } 696 svz_portcfg_t; 697 698 /* 699 * Accessor definitions for each type of protocol. 700 */ 701 #define SVZ_CFG_TCP(portcfg,x) (portcfg->protocol.tcp.x) 702 #define SVZ_CFG_UDP(portcfg,x) (portcfg->protocol.udp.x) 703 #define SVZ_CFG_ICMP(portcfg,x) (portcfg->protocol.icmp.x) 704 #define SVZ_CFG_RAW(portcfg,x) (portcfg->protocol.raw.x) 705 #define SVZ_CFG_PIPE(portcfg,x) (portcfg->protocol.pipe.x) 706 707 __BEGIN_DECLS 708 709 SERVEEZ_API struct sockaddr_in *svz_portcfg_addr (svz_portcfg_t *); 710 SERVEEZ_API char *svz_portcfg_ipaddr (svz_portcfg_t *); 711 SERVEEZ_API char *svz_portcfg_device (svz_portcfg_t *); 712 SERVEEZ_API in_port_t svz_portcfg_port (svz_portcfg_t *); 713 714 SERVEEZ_API svz_portcfg_t *svz_portcfg_create (void); 715 SERVEEZ_API int svz_portcfg_equal (svz_portcfg_t *, svz_portcfg_t *); 716 SERVEEZ_API svz_portcfg_t *svz_portcfg_add (char *, svz_portcfg_t *); 717 SERVEEZ_API svz_portcfg_t *svz_portcfg_get (char *); 718 SERVEEZ_API void svz_portcfg_destroy (svz_portcfg_t *); 719 SERVEEZ_API int svz_portcfg_mkaddr (svz_portcfg_t *); 720 SERVEEZ_API svz_portcfg_t *svz_portcfg_dup (svz_portcfg_t *); 721 722 __END_DECLS 723 724 725 /* (cfg) */ 726 727 /* 728 * Each server can have a an array of key-value-pairs specific for it. 729 * Use macros at end of this file for setting up these. 730 */ 731 typedef struct svz_key_value_pair 732 { 733 int type; /* data type (string, integer, etc.) */ 734 char *name; /* variable name (symbol) */ 735 int defaultable; /* set if this item is defaultable */ 736 void *address; /* memory address of the variable */ 737 } 738 svz_key_value_pair_t; 739 740 /* 741 * This structure defines callbacks for the (internal) server configuration 742 * function. Each of these have the following arguments: 743 * instance: might be the name of the instance to configure 744 * arg: an optional argument (e.g. scheme cell), supplied by user 745 * name: the symbolic name of the configuration item 746 * target: target address of the configuration item 747 * hasdef: is there a default value 748 * def: the default value for this configuration item 749 * 750 * The 'before' and 'after' callbacks are called just before and after 751 * other options are set. The user is supposed to emit error messages since 752 * the library cannot guess what went wrong. 753 * Both callbacks have to return @code{SVZ_ITEM_OK} to allow the configure 754 * function to complete successfully. No other callback is invoked when 755 * the 'before' callback fails. 756 * 757 * Default values and the @var{hasdef} flag are passed to callbacks for 758 * no sane reason. You do not need to care about them if you set 759 * appropriate return values. If you use them, however, everything that 760 * is a pointer needs to be copied. 761 */ 762 763 #define SVZ_ITEM_OK 0 /* okay, value set */ 764 #define SVZ_ITEM_DEFAULT 1 /* use default, be silent if missing */ 765 #define SVZ_ITEM_DEFAULT_ERRMSG 2 /* use default, croak if missing */ 766 #define SVZ_ITEM_FAILED 3 /* error, error messages already emitted */ 767 #define SVZ_ITEM_FAILED_ERRMSG 4 /* error, please report error */ 768 769 typedef struct 770 { 771 int (* before) (char *instance, void *arg); 772 int (* integer) (char *instance, void *arg, char *name, 773 int *target, int hasdef, int def); 774 int (* boolean) (char *instance, void *arg, char *name, 775 int *target, int hasdef, int def); 776 int (* intarray) (char *instance, void *arg, char *name, 777 svz_array_t **target, int hasdef, svz_array_t *def); 778 int (* string) (char *instance, void *arg, char *name, 779 char **target, int hasdef, char *def); 780 int (* strarray) (char *instance, void *arg, char *name, 781 svz_array_t **target, int hasdef, svz_array_t *def); 782 int (* hash) (char *instance, void *arg, char *name, 783 svz_hash_t **target, int hasdef, svz_hash_t *def); 784 int (* portcfg) (char *instance, void *arg, char *name, 785 svz_portcfg_t **target, int hasdef, svz_portcfg_t *def); 786 int (* after) (char *instance, void *arg); 787 } 788 svz_config_accessor_t; 789 790 typedef struct 791 { 792 /* description of the configuration prototype */ 793 char *description; 794 /* start of example structure */ 795 void *start; 796 /* size of the above structure */ 797 int size; 798 /* array of key-value-pairs of configuration items */ 799 svz_key_value_pair_t *items; 800 } 801 svz_config_prototype_t; 802 803 /* Constants for the @var{defaultable} argument. */ 804 #define SVZ_ITEM_DEFAULTABLE 1 805 #define SVZ_ITEM_NOTDEFAULTABLE 0 806 807 /* Configuration item identifiers. */ 808 #define SVZ_ITEM_END 0 809 #define SVZ_ITEM_INT 1 810 #define SVZ_ITEM_INTARRAY 2 811 #define SVZ_ITEM_STR 3 812 #define SVZ_ITEM_STRARRAY 4 813 #define SVZ_ITEM_HASH 5 814 #define SVZ_ITEM_PORTCFG 6 815 #define SVZ_ITEM_BOOL 7 816 817 /** 818 * Expand to a data structure that properly associates the example 819 * configuration @var{config} with the name @var{description} and its 820 * configuration items @var{prototypes}, for use within a server type 821 * definition. 822 */ 823 #define SVZ_CONFIG_DEFINE(description, config, prototypes) \ 824 { description, &(config), sizeof (config), (prototypes) } 825 826 /* 827 * Returns a text representation of the given configuration item 828 * identifier @var{item}. 829 */ 830 #define SVZ_ITEM_TEXT(item) \ 831 ((item) == SVZ_ITEM_INT) ? "integer" : \ 832 ((item) == SVZ_ITEM_INTARRAY) ? "integer array" : \ 833 ((item) == SVZ_ITEM_STR) ? "string" : \ 834 ((item) == SVZ_ITEM_STRARRAY) ? "string array" : \ 835 ((item) == SVZ_ITEM_HASH) ? "hash table" : \ 836 ((item) == SVZ_ITEM_BOOL) ? "boolean" : \ 837 ((item) == SVZ_ITEM_PORTCFG) ? "port configuration" : NULL 838 839 /** 840 * Register a simple integer. C-type: @code{int}. The given @var{name} 841 * specifies the symbolic name of the integer and @var{item} the integer 842 * itself (not its address). The @var{defaultable} argument can be either 843 * @code{SVZ_ITEM_DEFAULTABLE} or @code{SVZ_ITEM_NOTDEFAULTABLE}. 844 */ 845 #define SVZ_REGISTER_INT(name, item, defaultable) \ 846 { SVZ_ITEM_INT, (name), (defaultable), &(item) } 847 848 /** 849 * Register an array of integers. C-type: @code{svz_array_t *}. 850 */ 851 #define SVZ_REGISTER_INTARRAY(name, item, defaultable) \ 852 { SVZ_ITEM_INTARRAY, (name), (defaultable), &(item) } 853 854 /** 855 * Register a boolean value. C-type: @code{int}. 856 */ 857 #define SVZ_REGISTER_BOOL(name, item, defaultable) \ 858 { SVZ_ITEM_BOOL, (name), (defaultable), &(item) } 859 860 /** 861 * Register a simple character string. C-type: @code{char *}. 862 */ 863 #define SVZ_REGISTER_STR(name, item, defaultable) \ 864 { SVZ_ITEM_STR, (name), (defaultable), &(item) } 865 866 /** 867 * Register a string array. C-type: @code{svz_array_t *}. 868 */ 869 #define SVZ_REGISTER_STRARRAY(name, item, defaultable) \ 870 { SVZ_ITEM_STRARRAY, (name), (defaultable), &(item) } 871 872 /** 873 * Register a hash table associating strings with strings only. C-type: 874 * @code{svz_hash_t *}. 875 */ 876 #define SVZ_REGISTER_HASH(name, item, defaultable) \ 877 { SVZ_ITEM_HASH, (name), (defaultable), &(item) } 878 879 /** 880 * Register a port configuration. C-type: @code{svz_portcfg_t *}. 881 */ 882 #define SVZ_REGISTER_PORTCFG(name, item, defaultable) \ 883 { SVZ_ITEM_PORTCFG, (name), (defaultable), &(item) } 884 885 /** 886 * Indicate the end of the list of configuration items. It is 887 * the only mandatory item you need to specify in an example server type 888 * configuration. 889 */ 890 #define SVZ_REGISTER_END() \ 891 { SVZ_ITEM_END, NULL, SVZ_ITEM_DEFAULTABLE, NULL } 892 893 #define SVZ_INTARRAY 0 894 #define SVZ_STRARRAY 1 895 #define SVZ_STRHASH 2 896 897 __BEGIN_DECLS 898 899 SERVEEZ_API void svz_config_free (svz_config_prototype_t *, void *); 900 SERVEEZ_API int svz_config_type_instantiate (char *, char *, 901 char *, void *, 902 svz_config_accessor_t *, 903 size_t, char *); 904 SERVEEZ_API void *svz_collect (int, size_t, void *); 905 906 __END_DECLS 907 908 #define __SVZ_COLLECT(nick,ctype,cvar) \ 909 svz_collect (SVZ_ ## nick, sizeof (cvar) / sizeof (ctype), cvar) 910 911 /** 912 * Return an integer array @code{svz_array_t *} 913 * created from @code{int @var{cvar}[]}. 914 */ 915 #define SVZ_COLLECT_INTARRAY(cvar) __SVZ_COLLECT (INTARRAY, int, cvar) 916 917 /** 918 * Return a string array @code{svz_array_t *} 919 * created from @code{char *@var{cvar}[]}. 920 */ 921 #define SVZ_COLLECT_STRARRAY(cvar) __SVZ_COLLECT (STRARRAY, char *, cvar) 922 923 /** 924 * Return a string hash @code{svz_hash_t *} 925 * created from @code{char *@var{cvar}[]}. 926 */ 927 #define SVZ_COLLECT_STRHASH(cvar) __SVZ_COLLECT (STRHASH, char *, cvar) 928 929 930 /* (server) */ 931 932 typedef struct svz_servertype svz_servertype_t; 933 typedef struct svz_server svz_server_t; 934 935 /* 936 * Each server instance gets such a structure. 937 */ 938 struct svz_server 939 { 940 /* one of the PROTO_ flags defined in <core.h> */ 941 int proto; 942 /* variable name in configuration language, used to identify it */ 943 char *name; 944 /* server description */ 945 char *description; 946 /* configuration structure for this instance */ 947 void *cfg; 948 /* pointer to this server instances server type */ 949 svz_servertype_t *type; 950 /* arbitrary data field */ 951 void *data; 952 953 /* init of instance */ 954 int (* init) (svz_server_t *); 955 /* protocol detection */ 956 int (* detect_proto) (svz_server_t *, svz_socket_t *); 957 /* what to do if detected */ 958 int (* connect_socket) (svz_server_t *, svz_socket_t *); 959 /* finalize this instance */ 960 int (* finalize) (svz_server_t *); 961 /* return client info */ 962 char * (* info_client) (svz_server_t *, svz_socket_t *); 963 /* return server info */ 964 char * (* info_server) (svz_server_t *); 965 /* server timer */ 966 int (* notify) (svz_server_t *); 967 /* server reset callback */ 968 int (* reset) (svz_server_t *); 969 /* packet processing */ 970 int (* handle_request) (svz_socket_t *, char *, int); 971 }; 972 973 /* 974 * Every type (class) of server is completely defined by the following 975 * structure. 976 */ 977 struct svz_servertype 978 { 979 /* full descriptive name */ 980 char *description; 981 /* variable prefix (short name) as used in configuration */ 982 char *prefix; 983 984 /* run once per server definition */ 985 int (* global_init) (svz_servertype_t *); 986 /* per server instance callback */ 987 int (* init) (svz_server_t *); 988 /* protocol detection routine */ 989 int (* detect_proto) (svz_server_t *, svz_socket_t *); 990 /* for accepting a client (tcp or pipe only) */ 991 int (* connect_socket) (svz_server_t *, svz_socket_t *); 992 /* per instance */ 993 int (* finalize) (svz_server_t *); 994 /* per server definition */ 995 int (* global_finalize) (svz_servertype_t *); 996 /* return client info */ 997 char * (* info_client) (svz_server_t *, svz_socket_t *); 998 /* return server info */ 999 char * (* info_server) (svz_server_t *); 1000 /* server timer */ 1001 int (* notify) (svz_server_t *); 1002 /* server reset */ 1003 int (* reset) (svz_server_t *); 1004 /* packet processing */ 1005 int (* handle_request) (svz_socket_t *, char *, int); 1006 1007 /* configuration prototype */ 1008 svz_config_prototype_t config_prototype; 1009 }; 1010 1011 1012 typedef int (svz_servertype_do_t) (const svz_servertype_t *, void *); 1013 typedef void (svz_server_do_t) (svz_server_t *, void *); 1014 1015 __BEGIN_DECLS 1016 1017 SERVEEZ_API int svz_foreach_servertype (svz_servertype_do_t *, void *); 1018 SERVEEZ_API void svz_foreach_server (svz_server_do_t *, void *); 1019 SERVEEZ_API svz_server_t *svz_server_get (char *); 1020 SERVEEZ_API svz_server_t *svz_server_find (void *); 1021 SERVEEZ_API svz_array_t *svz_server_clients (svz_server_t *); 1022 SERVEEZ_API int svz_updn_all_servers (int); 1023 1024 SERVEEZ_API void svz_servertype_add (svz_servertype_t *); 1025 SERVEEZ_API svz_servertype_t *svz_servertype_get (char *, int); 1026 SERVEEZ_API svz_servertype_t *svz_servertype_find (svz_server_t *); 1027 1028 __END_DECLS 1029 1030 1031 /* (binding) */ 1032 1033 1034 __BEGIN_DECLS 1035 1036 SERVEEZ_API int svz_server_bind (svz_server_t *, svz_portcfg_t *); 1037 SERVEEZ_API svz_array_t *svz_server_portcfgs (svz_server_t *); 1038 SERVEEZ_API svz_array_t *svz_server_listeners (svz_server_t *); 1039 SERVEEZ_API svz_array_t *svz_sock_servers (svz_socket_t *); 1040 SERVEEZ_API int svz_binding_contains_server (svz_socket_t *, 1041 svz_server_t *); 1042 SERVEEZ_API size_t svz_pp_server_bindings (char *, size_t, svz_server_t *); 1043 1044 __END_DECLS 1045 1046 1047 /* (tcp-socket) */ 1048 1049 __BEGIN_DECLS 1050 1051 SERVEEZ_API svz_socket_t *svz_tcp_connect (svz_address_t *, in_port_t); 1052 SERVEEZ_API int svz_tcp_read_socket (svz_socket_t *); 1053 SERVEEZ_API int svz_tcp_send_oob (svz_socket_t *); 1054 1055 __END_DECLS 1056 1057 1058 /* (udp-socket) */ 1059 1060 /* The maximum size of a UDP packet. */ 1061 #define SVZ_UDP_MSG_SIZE (64 * 1024) 1062 1063 /* Space for 4 messages. */ 1064 #define SVZ_UDP_BUF_SIZE (4 * (SVZ_UDP_MSG_SIZE + 24)) 1065 1066 __BEGIN_DECLS 1067 1068 SERVEEZ_API svz_socket_t *svz_udp_connect (svz_address_t *, in_port_t); 1069 SERVEEZ_API int svz_udp_write (svz_socket_t *, char *, int); 1070 1071 __END_DECLS 1072 1073 1074 /* (icmp-socket) */ 1075 1076 /* Serveez-ICMP types and sub-codes. */ 1077 #define SVZ_ICMP_SERVEEZ 42 1078 #define SVZ_ICMP_SERVEEZ_DATA 0 1079 #define SVZ_ICMP_SERVEEZ_REQ 1 1080 #define SVZ_ICMP_SERVEEZ_ACK 2 1081 #define SVZ_ICMP_SERVEEZ_CLOSE 3 1082 #define SVZ_ICMP_SERVEEZ_CONNECT 4 1083 1084 __BEGIN_DECLS 1085 1086 SERVEEZ_API svz_socket_t *svz_icmp_connect (svz_address_t *, in_port_t, uint8_t); 1087 SERVEEZ_API int svz_icmp_send_control (svz_socket_t *, uint8_t); 1088 SERVEEZ_API int svz_icmp_write (svz_socket_t *, char *, int); 1089 1090 __END_DECLS 1091 1092 1093 /* (server-core) */ 1094 1095 1096 1097 typedef int (svz_socket_do_t) (svz_socket_t *, void *); 1098 1099 __BEGIN_DECLS 1100 1101 SERVEEZ_API int svz_foreach_socket (svz_socket_do_t *, void *); 1102 SERVEEZ_API svz_socket_t *svz_sock_find (int, int); 1103 SERVEEZ_API int svz_sock_schedule_for_shutdown (svz_socket_t *); 1104 SERVEEZ_API int svz_sock_enqueue (svz_socket_t *); 1105 SERVEEZ_API void svz_sock_setparent (svz_socket_t *, svz_socket_t *); 1106 SERVEEZ_API svz_socket_t *svz_sock_getparent (svz_socket_t *); 1107 SERVEEZ_API void svz_sock_setreferrer (svz_socket_t *, svz_socket_t *); 1108 SERVEEZ_API svz_socket_t *svz_sock_getreferrer (svz_socket_t *); 1109 SERVEEZ_API svz_portcfg_t *svz_sock_portcfg (svz_socket_t *); 1110 1111 SERVEEZ_API int svz_shutting_down_p (void); 1112 SERVEEZ_API void svz_loop_pre (void); 1113 SERVEEZ_API void svz_loop_post (void); 1114 SERVEEZ_API void svz_loop (void); 1115 SERVEEZ_API void svz_loop_one (void); 1116 1117 __END_DECLS 1118 1119 1120 /* (coserver/coserver) */ 1121 1122 /* 1123 * Every invoked internal coserver has got such a structure. 1124 * It contains all the data it needs to run properly. 1125 */ 1126 typedef struct 1127 { 1128 #ifdef __MINGW32__ 1129 1130 /* Win32 specific part. */ 1131 CRITICAL_SECTION sync; /* critical section handle */ 1132 HANDLE thread; /* the thread handle for access */ 1133 DWORD tid; /* internal thread id */ 1134 1135 #else /* not __MINGW32__ */ 1136 1137 /* Unix specific part. */ 1138 int pid; /* process id */ 1139 1140 #endif /* not __MINGW32__ */ 1141 1142 char * (* callback) (char *); /* callback routine, blocking... */ 1143 svz_socket_t *sock; /* socket structure for this coserver */ 1144 int type; /* coserver type id */ 1145 int busy; /* is this thread currently busy? */ 1146 } 1147 svz_coserver_t; 1148 1149 1150 /* 1151 * This structure holds a socket's ‘.id’ and ‘.version’ information, 1152 * created by ‘svz_make_sock_iv’ to be later fed (by the callback) to 1153 * ‘svz_sock_find’. The callback should ‘svz_free’ it afterwards. 1154 */ 1155 typedef struct 1156 { 1157 int id; 1158 int version; 1159 } 1160 svz_sock_iv_t; 1161 1162 /* 1163 * The callback structure is used to finally execute some code 1164 * which should be called whenever one of the coservers produces 1165 * any data for the server. 1166 */ 1167 typedef int (* svz_coserver_handle_result_t) (char *, void *); 1168 1169 typedef struct 1170 { 1171 svz_coserver_handle_result_t handle_result; /* any code callback */ 1172 void *closure; /* opaque to libserveez */ 1173 } 1174 svz_coserver_callback_t; 1175 1176 /* 1177 * Types of internal servers you can start as threads or processes. 1178 * coserver-TODO: 1179 * add your coserver identification here and increase SVZ_MAX_COSERVER_TYPES 1180 */ 1181 #define SVZ_COSERVER_REVERSE_DNS 0 /* reverse DNS lookup ID */ 1182 #define SVZ_COSERVER_IDENT 1 /* identification ID */ 1183 #define SVZ_COSERVER_DNS 2 /* DNS lookup ID */ 1184 #define SVZ_MAX_COSERVER_TYPES 3 /* number of different coservers */ 1185 1186 typedef int (svz_coserver_do_t) (const svz_coserver_t *, void *); 1187 1188 __BEGIN_DECLS 1189 1190 SERVEEZ_API svz_sock_iv_t *svz_make_sock_iv (svz_socket_t *); 1191 SERVEEZ_API int svz_foreach_coserver (svz_coserver_do_t *, void *); 1192 SERVEEZ_API void svz_coserver_check (void); 1193 SERVEEZ_API int svz_updn_all_coservers (int); 1194 SERVEEZ_API void svz_coserver_destroy (int); 1195 SERVEEZ_API svz_coserver_t *svz_coserver_create (int); 1196 SERVEEZ_API const char *svz_coserver_type_name (const svz_coserver_t *); 1197 1198 /* 1199 * These are the three wrappers for our existing coservers. 1200 */ 1201 SERVEEZ_API void svz_coserver_rdns_invoke (svz_address_t *, 1202 svz_coserver_handle_result_t, 1203 void *); 1204 1205 SERVEEZ_API void svz_coserver_dns_invoke (char *, 1206 svz_coserver_handle_result_t, 1207 void *); 1208 1209 SERVEEZ_API void svz_coserver_ident_invoke (svz_socket_t *, 1210 svz_coserver_handle_result_t, 1211 void *); 1212 1213 __END_DECLS 1214 1215 1216 /* (interface) */ 1217 1218 /* 1219 * Structure for collecting IP interfaces. 1220 */ 1221 typedef struct svz_interface 1222 { 1223 size_t index; /* interface index */ 1224 char *description; /* interface description */ 1225 svz_address_t *addr; /* address */ 1226 int detected; /* interface flag */ 1227 } 1228 svz_interface_t; 1229 1230 typedef int (svz_interface_do_t) (const svz_interface_t *, void *); 1231 1232 __BEGIN_DECLS 1233 1234 SERVEEZ_API int svz_foreach_interface (svz_interface_do_t *, void *); 1235 SERVEEZ_API int svz_interface_add (size_t, char *, int, const void *, int); 1236 1237 __END_DECLS 1238 1239 1240 /* (dynload) */ 1241 1242 __BEGIN_DECLS 1243 1244 SERVEEZ_API void svz_dynload_path_set (svz_array_t *); 1245 SERVEEZ_API svz_array_t *svz_dynload_path_get (void); 1246 1247 __END_DECLS 1248 1249 1250 /* (passthrough) */ 1251 1252 /* Structure containing a system independent environment. */ 1253 typedef struct 1254 { 1255 int size; /* Number of environment entries. */ 1256 char **entry; /* Environment entries in the format "VAR=VALUE". */ 1257 char *block; /* Temporary environment block. */ 1258 } 1259 svz_envblock_t; 1260 1261 /* Definitions for the @var{user} argument of @code{svz_sock_process}. */ 1262 #define SVZ_PROCESS_NONE ((char *) 0L) 1263 #define SVZ_PROCESS_OWNER ((char *) ~0L) 1264 1265 __BEGIN_DECLS 1266 1267 SERVEEZ_API int svz_sock_process (svz_socket_t *, char *, char *, 1268 char **, svz_envblock_t *, int, 1269 char *); 1270 #ifdef __MINGW32__ 1271 SERVEEZ_API int svz_mingw_child_dead_p (char *, svz_t_handle *); 1272 #endif 1273 SERVEEZ_API int svz_most_recent_dead_child_p (svz_t_handle); 1274 SERVEEZ_API void svz_envblock_setup (void); 1275 SERVEEZ_API svz_envblock_t *svz_envblock_create (void); 1276 SERVEEZ_API int svz_envblock_default (svz_envblock_t *); 1277 SERVEEZ_API int svz_envblock_add (svz_envblock_t *, char *, ...); 1278 SERVEEZ_API void svz_envblock_destroy (svz_envblock_t *); 1279 SERVEEZ_API void * svz_envblock_get (svz_envblock_t *); 1280 1281 __END_DECLS 1282 1283 1284 /* (codec/codec) */ 1285 1286 /* Modes of operation. */ 1287 #define SVZ_CODEC_INIT 0x0001 1288 #define SVZ_CODEC_FLUSH 0x0002 1289 #define SVZ_CODEC_RESET 0x0004 1290 #define SVZ_CODEC_FINISH 0x0008 1291 #define SVZ_CODEC_CODE 0x0010 1292 1293 /* Return values of the codec callbacks. */ 1294 #define SVZ_CODEC_OK 0x0001 1295 #define SVZ_CODEC_FINISHED 0x0002 1296 #define SVZ_CODEC_ERROR 0x0004 1297 #define SVZ_CODEC_MORE_OUT 0x0008 1298 #define SVZ_CODEC_MORE_IN 0x0010 1299 1300 /* Internal state of a codec. */ 1301 #define SVZ_CODEC_NONE 0x0000 1302 #define SVZ_CODEC_READY 0x0001 1303 1304 /* Codec types. */ 1305 #define SVZ_CODEC_ENCODER 0x0001 1306 #define SVZ_CODEC_DECODER 0x0002 1307 1308 typedef struct svz_codec svz_codec_t; 1309 typedef struct svz_codec_data svz_codec_data_t; 1310 1311 /* 1312 * General codec data structure for both encoding and encoding calls. 1313 */ 1314 struct svz_codec_data 1315 { 1316 /* Current codec class. */ 1317 svz_codec_t *codec; 1318 1319 /* Operation flags. */ 1320 int flag; 1321 1322 /* Current state flags. */ 1323 int state; 1324 1325 /* Input buffer description. */ 1326 char *in_buffer; 1327 int in_fill; 1328 int in_size; 1329 1330 /* Output buffer description. */ 1331 char *out_buffer; 1332 int out_fill; 1333 int out_size; 1334 1335 /* Configuration field (passed to each codec callback). Could be 1336 used as compression level, algorithm, etc. indicator. */ 1337 void *config; 1338 1339 /* Arbitrary data field. Can be used by codec for internal data. */ 1340 void *data; 1341 1342 /* Saved @code{check_request} callback. Used by receiving codecs. */ 1343 int (* check_request) (svz_socket_t *sock); 1344 1345 /* Saved @code{write_socket} callback. Used by sending codecs. */ 1346 int (* write_socket) (svz_socket_t *sock); 1347 1348 /* Saved @code{disconnected_socket} callback. Used by both. */ 1349 int (* disconnected_socket) (svz_socket_t *sock); 1350 }; 1351 1352 /* 1353 * Description of a codec class. 1354 */ 1355 struct svz_codec 1356 { 1357 /* Name of the codec. Should be short descriptive name. */ 1358 char *description; 1359 1360 /* Codec type. */ 1361 int type; 1362 1363 /* Initializer. */ 1364 int (* init) (svz_codec_data_t *); 1365 1366 /* Finalizer. */ 1367 int (* finalize) (svz_codec_data_t *); 1368 1369 /* Encoding / decoding routine. */ 1370 int (* code) (svz_codec_data_t *); 1371 1372 /* Last error description. */ 1373 char * (* error) (svz_codec_data_t *); 1374 1375 /* Overall ratio request. */ 1376 int (* ratio) (svz_codec_data_t *, size_t *, size_t *); 1377 1378 /* Magic detection sequence. */ 1379 char *detection; 1380 1381 /* Length of the above detection sequence. */ 1382 int detection_size; 1383 }; 1384 1385 typedef int (svz_codec_do_t) (const svz_codec_t *, void *); 1386 1387 __BEGIN_DECLS 1388 1389 SERVEEZ_API int svz_foreach_codec (svz_codec_do_t *, void *); 1390 SERVEEZ_API svz_codec_t * svz_codec_get (char *, int); 1391 SERVEEZ_API int svz_codec_register (svz_codec_t *); 1392 SERVEEZ_API int svz_codec_unregister (svz_codec_t *); 1393 SERVEEZ_API int svz_codec_sock_receive_setup (svz_socket_t *, 1394 svz_codec_t *); 1395 SERVEEZ_API int svz_codec_sock_receive (svz_socket_t *); 1396 SERVEEZ_API int svz_codec_sock_send_setup (svz_socket_t *, 1397 svz_codec_t *); 1398 SERVEEZ_API int svz_codec_sock_send (svz_socket_t *); 1399 SERVEEZ_API int svz_codec_sock_disconnect (svz_socket_t *); 1400 SERVEEZ_API void svz_codec_ratio (svz_codec_t *, 1401 svz_codec_data_t *); 1402 SERVEEZ_API svz_codec_t * svz_codec_sock_detect (svz_socket_t *); 1403 1404 __END_DECLS 1405 1406 1407 #endif /* not __LIBSERVEEZ_H__ */ 1408 1409 /* (GNU Serveez 0.2.1) libserveez.h ends here */ 1410