| /* |
| Copyright Copyright (C) 2013 Andrey Uzunov |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program 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 General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| /** |
| * @file mhd2spdy_structures.h |
| * @brief Common structures, functions, macros and global variables. |
| * @author Andrey Uzunov |
| */ |
| #ifndef STRUCTURES_H |
| #define STRUCTURES_H |
| |
| #define _GNU_SOURCE |
| |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <ctype.h> |
| #include <errno.h> |
| #include <assert.h> |
| #include <microhttpd.h> |
| #include <signal.h> |
| #include <poll.h> |
| #include <fcntl.h> |
| #include <regex.h> |
| #include <sys/types.h> |
| #include <sys/socket.h> |
| #include <netdb.h> |
| #include <netinet/in.h> |
| #include <netinet/tcp.h> |
| #include <openssl/ssl.h> |
| #include <openssl/err.h> |
| #include <spdylay/spdylay.h> |
| #include <getopt.h> |
| |
| |
| /* WANT_READ if SSL connection needs more input; or WANT_WRITE if it |
| needs more output; or IO_NONE. This is necessary because SSL/TLS |
| re-negotiation is possible at any time. Spdylay API offers |
| similar functions like spdylay_session_want_read() and |
| spdylay_session_want_write() but they do not take into account |
| SSL connection. */ |
| enum |
| { |
| IO_NONE, |
| WANT_READ, |
| WANT_WRITE |
| }; |
| |
| |
| struct Proxy; |
| |
| |
| struct SPDY_Connection { |
| SSL *ssl; |
| spdylay_session *session; |
| struct SPDY_Connection *prev; |
| struct SPDY_Connection *next; |
| struct Proxy *proxies_head; |
| struct Proxy *proxies_tail; |
| char *host; |
| int fd; |
| int want_io; |
| uint counter; |
| uint streams_opened; |
| bool is_tls; |
| }; |
| |
| |
| struct URI |
| { |
| char * full_uri; |
| char * scheme; |
| char * host_and_port; |
| char * host; |
| char * path; |
| char * path_and_more; |
| char * query; |
| char * fragment; |
| uint16_t port; |
| }; |
| |
| |
| struct HTTP_URI; |
| |
| |
| struct Proxy |
| { |
| struct MHD_Connection *http_connection; |
| struct MHD_Response *http_response; |
| struct URI *uri; |
| struct HTTP_URI *http_uri; |
| struct SPDY_Connection *spdy_connection; |
| struct Proxy *next; |
| struct Proxy *prev; |
| char *url; |
| char *version; |
| void *http_body; |
| void *received_body; |
| size_t http_body_size; |
| size_t received_body_size; |
| ssize_t length; |
| int status; |
| int id; |
| int32_t stream_id; |
| bool done; |
| bool http_error; |
| bool spdy_error; |
| bool http_active; |
| bool spdy_active; |
| bool receiving_done; |
| }; |
| |
| |
| struct HTTP_URI |
| { |
| char * uri; |
| struct Proxy * proxy; |
| }; |
| |
| |
| struct SPDY_Headers |
| { |
| const char **nv; |
| int num; |
| int cnt; |
| }; |
| |
| |
| struct global_options |
| { |
| char *spdy2http_str; |
| struct SPDY_Connection *spdy_connection; |
| struct SPDY_Connection *spdy_connections_head; |
| struct SPDY_Connection *spdy_connections_tail; |
| int streams_opened; |
| int responses_pending; |
| regex_t uri_preg; |
| size_t global_memory; |
| SSL_CTX *ssl_ctx; |
| uint32_t total_spdy_connections; |
| uint16_t spdy_proto_version; |
| uint16_t listen_port; |
| bool verbose; |
| bool only_proxy; |
| bool spdy_data_received; |
| bool statistics; |
| bool ignore_rst_stream; |
| } |
| glob_opt; |
| |
| |
| struct global_statistics |
| { |
| //unsigned long long http_bytes_sent; |
| //unsigned long long http_bytes_received; |
| unsigned long long spdy_bytes_sent; |
| unsigned long long spdy_bytes_received; |
| unsigned long long spdy_bytes_received_and_dropped; |
| } |
| glob_stat; |
| |
| |
| //forbidden headers |
| #define SPDY_HTTP_HEADER_TRANSFER_ENCODING "transfer-encoding" |
| #define SPDY_HTTP_HEADER_PROXY_CONNECTION "proxy-connection" |
| #define SPDY_HTTP_HEADER_KEEP_ALIVE "keep-alive" |
| #define SPDY_HTTP_HEADER_CONNECTION "connection" |
| |
| #define MAX_SPDY_CONNECTIONS 100 |
| |
| #define SPDY_MAX_OUTLEN 4096 |
| |
| /** |
| * Insert an element at the head of a DLL. Assumes that head, tail and |
| * element are structs with prev and next fields. |
| * |
| * @param head pointer to the head of the DLL (struct ? *) |
| * @param tail pointer to the tail of the DLL (struct ? *) |
| * @param element element to insert (struct ? *) |
| */ |
| #define DLL_insert(head,tail,element) do { \ |
| (element)->next = (head); \ |
| (element)->prev = NULL; \ |
| if ((tail) == NULL) \ |
| (tail) = element; \ |
| else \ |
| (head)->prev = element; \ |
| (head) = (element); } while (0) |
| |
| |
| /** |
| * Remove an element from a DLL. Assumes |
| * that head, tail and element are structs |
| * with prev and next fields. |
| * |
| * @param head pointer to the head of the DLL (struct ? *) |
| * @param tail pointer to the tail of the DLL (struct ? *) |
| * @param element element to remove (struct ? *) |
| */ |
| #define DLL_remove(head,tail,element) do { \ |
| if ((element)->prev == NULL) \ |
| (head) = (element)->next; \ |
| else \ |
| (element)->prev->next = (element)->next; \ |
| if ((element)->next == NULL) \ |
| (tail) = (element)->prev; \ |
| else \ |
| (element)->next->prev = (element)->prev; \ |
| (element)->next = NULL; \ |
| (element)->prev = NULL; } while (0) |
| |
| |
| #define PRINT_INFO(msg) do{\ |
| if(glob_opt.verbose){\ |
| printf("%i:%s\n", __LINE__, msg);\ |
| fflush(stdout);\ |
| }\ |
| }\ |
| while(0) |
| |
| |
| #define PRINT_INFO2(fmt, ...) do{\ |
| if(glob_opt.verbose){\ |
| printf("%i\n", __LINE__);\ |
| printf(fmt,##__VA_ARGS__);\ |
| printf("\n");\ |
| fflush(stdout);\ |
| }\ |
| }\ |
| while(0) |
| |
| |
| #define DIE(msg) do{\ |
| printf("FATAL ERROR (line %i): %s\n", __LINE__, msg);\ |
| fflush(stdout);\ |
| exit(EXIT_FAILURE);\ |
| }\ |
| while(0) |
| |
| |
| #define UPDATE_STAT(stat, value) do{\ |
| if(glob_opt.statistics)\ |
| {\ |
| stat += value;\ |
| }\ |
| }\ |
| while(0) |
| |
| |
| void |
| free_uri(struct URI * uri); |
| |
| |
| int |
| init_parse_uri(regex_t * preg); |
| |
| |
| void |
| deinit_parse_uri(regex_t * preg); |
| |
| |
| int |
| parse_uri(regex_t * preg, |
| char * full_uri, |
| struct URI ** uri); |
| |
| |
| void |
| free_proxy(struct Proxy *proxy); |
| |
| |
| void * |
| au_malloc(size_t size); |
| |
| |
| bool |
| copy_buffer(const void *src, size_t src_size, void **dst, size_t *dst_size); |
| |
| #endif |