diff options
Diffstat (limited to 'src/examples/mhd2spdy_structures.h')
-rw-r--r-- | src/examples/mhd2spdy_structures.h | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/examples/mhd2spdy_structures.h b/src/examples/mhd2spdy_structures.h new file mode 100644 index 00000000..f5679341 --- /dev/null +++ b/src/examples/mhd2spdy_structures.h @@ -0,0 +1,296 @@ +/* + 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 |