diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-06-05 15:35:38 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-06-05 15:35:38 +0000 |
commit | dfb16cb188e82a9f48af6390694c872be2765049 (patch) | |
tree | afdbe3a55a0701c2499486161165fc2f6b242ce3 /src/gns/gnunet-gns-proxy.c | |
parent | f20b8843eaa532e67cb706440e4866df289c83b3 (diff) | |
download | gnunet-dfb16cb188e82a9f48af6390694c872be2765049.tar.gz gnunet-dfb16cb188e82a9f48af6390694c872be2765049.zip |
-beginnings of ssl
Diffstat (limited to 'src/gns/gnunet-gns-proxy.c')
-rw-r--r-- | src/gns/gnunet-gns-proxy.c | 486 |
1 files changed, 405 insertions, 81 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c index 050f38c13..a0157ecbe 100644 --- a/src/gns/gnunet-gns-proxy.c +++ b/src/gns/gnunet-gns-proxy.c | |||
@@ -29,108 +29,218 @@ | |||
29 | 29 | ||
30 | #define GNUNET_GNS_PROXY_PORT 7777 | 30 | #define GNUNET_GNS_PROXY_PORT 7777 |
31 | 31 | ||
32 | //TODO maybe make this an api call | 32 | /* MHD/cURL defines */ |
33 | /** | 33 | #define BUF_WAIT_FOR_CURL 0 |
34 | * Checks if name is in tld | 34 | #define BUF_WAIT_FOR_MHD 1 |
35 | * | 35 | #define HTML_HDR_CONTENT "Content-Type: text/html\r\n" |
36 | * @param name the name to check | ||
37 | * @param tld the TLD to check for | ||
38 | * @return GNUNET_YES or GNUNET_NO | ||
39 | */ | ||
40 | int | ||
41 | is_tld(const char* name, const char* tld) | ||
42 | { | ||
43 | int offset = 0; | ||
44 | 36 | ||
45 | if (strlen(name) <= strlen(tld)) | 37 | /* regexp */ |
46 | { | 38 | #define RE_DOTPLUS "<a href=\"http://(([A-Za-z]+[.])+)([+])" |
47 | return GNUNET_NO; | 39 | #define RE_N_MATCHES 4 |
48 | } | ||
49 | 40 | ||
50 | offset = strlen(name)-strlen(tld); | 41 | /* The usual suspects */ |
51 | if (strcmp (name+offset, tld) != 0) | 42 | #define HTTP_PORT 80 |
52 | { | 43 | #define HTTPS_PORT 443 |
53 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
54 | "%s is not in .%s TLD\n", name, tld); | ||
55 | return GNUNET_NO; | ||
56 | } | ||
57 | 44 | ||
58 | return GNUNET_YES; | ||
59 | } | ||
60 | 45 | ||
46 | |||
47 | /** | ||
48 | * A structure for socks requests | ||
49 | */ | ||
61 | struct Socks5Request | 50 | struct Socks5Request |
62 | { | 51 | { |
52 | /* The client socket */ | ||
63 | struct GNUNET_NETWORK_Handle *sock; | 53 | struct GNUNET_NETWORK_Handle *sock; |
64 | struct GNUNET_NETWORK_Handle *remote_sock; | ||
65 | 54 | ||
55 | /* The server socket */ | ||
56 | struct GNUNET_NETWORK_Handle *remote_sock; | ||
57 | |||
58 | /* The socks state */ | ||
66 | int state; | 59 | int state; |
67 | 60 | ||
61 | /* Client socket read task */ | ||
68 | GNUNET_SCHEDULER_TaskIdentifier rtask; | 62 | GNUNET_SCHEDULER_TaskIdentifier rtask; |
63 | |||
64 | /* Server socket read task */ | ||
69 | GNUNET_SCHEDULER_TaskIdentifier fwdrtask; | 65 | GNUNET_SCHEDULER_TaskIdentifier fwdrtask; |
66 | |||
67 | /* Client socket write task */ | ||
70 | GNUNET_SCHEDULER_TaskIdentifier wtask; | 68 | GNUNET_SCHEDULER_TaskIdentifier wtask; |
69 | |||
70 | /* Server socket write task */ | ||
71 | GNUNET_SCHEDULER_TaskIdentifier fwdwtask; | 71 | GNUNET_SCHEDULER_TaskIdentifier fwdwtask; |
72 | 72 | ||
73 | /* Read buffer */ | ||
73 | char rbuf[2048]; | 74 | char rbuf[2048]; |
75 | |||
76 | /* Write buffer */ | ||
74 | char wbuf[2048]; | 77 | char wbuf[2048]; |
78 | |||
79 | /* Length of data in read buffer */ | ||
75 | unsigned int rbuf_len; | 80 | unsigned int rbuf_len; |
81 | |||
82 | /* Length of data in write buffer */ | ||
76 | unsigned int wbuf_len; | 83 | unsigned int wbuf_len; |
77 | }; | 84 | }; |
78 | 85 | ||
79 | 86 | ||
80 | #define BUF_WAIT_FOR_CURL 0 | 87 | /** |
81 | #define BUF_WAIT_FOR_MHD 1 | 88 | * A structure for all running Httpds |
82 | #define HTML_HDR_CONTENT "Content-Type: text/html\r\n" | 89 | */ |
83 | #define RE_DOTPLUS "<a href=\"http://(([A-Za-z]+[.])+)([+])" | 90 | struct MhdHttpList |
84 | #define RE_N_MATCHES 4 | 91 | { |
92 | /* DLL for httpds */ | ||
93 | struct MhdHttpList *prev; | ||
85 | 94 | ||
86 | #define HTTP_PORT 80 | 95 | /* DLL for httpds */ |
87 | #define HTTPS_PORT 443 | 96 | struct MhdHttpList *next; |
88 | 97 | ||
98 | /* is this an ssl daemon? */ | ||
99 | int is_ssl; | ||
100 | |||
101 | /* the domain name to server (only important for SSL) */ | ||
102 | char domain[256]; | ||
103 | |||
104 | /* The daemon handle */ | ||
105 | struct MHD_Daemon *daemon; | ||
106 | |||
107 | /* The task ID */ | ||
108 | GNUNET_SCHEDULER_TaskIdentifier httpd_task; | ||
109 | }; | ||
110 | |||
111 | /** | ||
112 | * A structure for MHD<->cURL streams | ||
113 | */ | ||
89 | struct ProxyCurlTask | 114 | struct ProxyCurlTask |
90 | { | 115 | { |
91 | //DLL | 116 | /* DLL for tasks */ |
92 | struct ProxyCurlTask *prev; | 117 | struct ProxyCurlTask *prev; |
118 | |||
119 | /* DLL for tasks */ | ||
93 | struct ProxyCurlTask *next; | 120 | struct ProxyCurlTask *next; |
94 | 121 | ||
122 | /* Handle to cURL */ | ||
95 | CURL *curl; | 123 | CURL *curl; |
124 | |||
125 | /* The URL to fetch */ | ||
96 | char url[2048]; | 126 | char url[2048]; |
127 | |||
128 | /* The cURL write buffer / MHD read buffer */ | ||
97 | char buffer[CURL_MAX_WRITE_SIZE]; | 129 | char buffer[CURL_MAX_WRITE_SIZE]; |
130 | |||
131 | /* The pointer to the data in the buffer */ | ||
98 | char *buffer_ptr; | 132 | char *buffer_ptr; |
133 | |||
134 | /* The buffer status (BUF_WAIT_FOR_CURL or BUF_WAIT_FOR_MHD) */ | ||
99 | int buf_status; | 135 | int buf_status; |
100 | unsigned int bytes_downloaded; | 136 | |
137 | /* Number of bytes in buffer */ | ||
101 | unsigned int bytes_in_buffer; | 138 | unsigned int bytes_in_buffer; |
139 | |||
140 | /* Indicates wheather the download is in progress */ | ||
102 | int download_in_progress; | 141 | int download_in_progress; |
142 | |||
143 | /* Indicates wheather the download was successful */ | ||
103 | int download_successful; | 144 | int download_successful; |
145 | |||
146 | /* Indicates wheather the download failed */ | ||
104 | int download_error; | 147 | int download_error; |
105 | struct MHD_Connection *connection; | 148 | |
149 | /* Indicates wheather we need to parse HTML */ | ||
106 | int parse_content; | 150 | int parse_content; |
151 | |||
152 | /* Indicates wheather we are postprocessing the HTML right now */ | ||
107 | int is_postprocessing; | 153 | int is_postprocessing; |
154 | |||
155 | /* Indicates wheather postprocessing has finished */ | ||
108 | int pp_finished; | 156 | int pp_finished; |
109 | 157 | ||
158 | /* Task ID of the postprocessing task */ | ||
110 | GNUNET_SCHEDULER_TaskIdentifier pp_task; | 159 | GNUNET_SCHEDULER_TaskIdentifier pp_task; |
111 | 160 | ||
161 | /* The postprocessing buffer TODO length? */ | ||
112 | char pp_buf[256]; | 162 | char pp_buf[256]; |
163 | |||
164 | /* The authority of the corresponding host (site of origin) */ | ||
113 | char authority[256]; | 165 | char authority[256]; |
166 | |||
167 | /* The hostname (Host header field) */ | ||
114 | char host[256]; | 168 | char host[256]; |
169 | |||
170 | /* The associated daemon list entry */ | ||
171 | struct MhdHttpList *daemon; | ||
115 | 172 | ||
116 | }; | 173 | }; |
117 | 174 | ||
175 | /* The port the proxy is running on (default 7777) */ | ||
118 | unsigned long port = GNUNET_GNS_PROXY_PORT; | 176 | unsigned long port = GNUNET_GNS_PROXY_PORT; |
177 | |||
178 | /* The listen socket of the proxy */ | ||
119 | static struct GNUNET_NETWORK_Handle *lsock; | 179 | static struct GNUNET_NETWORK_Handle *lsock; |
180 | |||
181 | /* The listen task ID */ | ||
120 | GNUNET_SCHEDULER_TaskIdentifier ltask; | 182 | GNUNET_SCHEDULER_TaskIdentifier ltask; |
183 | |||
184 | /* The cURL download task */ | ||
121 | GNUNET_SCHEDULER_TaskIdentifier curl_download_task; | 185 | GNUNET_SCHEDULER_TaskIdentifier curl_download_task; |
186 | |||
187 | /* The non SSL httpd daemon handle */ | ||
122 | static struct MHD_Daemon *httpd; | 188 | static struct MHD_Daemon *httpd; |
189 | |||
190 | /* The http task ID */ | ||
123 | static GNUNET_SCHEDULER_TaskIdentifier httpd_task; | 191 | static GNUNET_SCHEDULER_TaskIdentifier httpd_task; |
192 | |||
193 | /* The cURL multi handle */ | ||
124 | static CURLM *curl_multi; | 194 | static CURLM *curl_multi; |
125 | 195 | ||
196 | /* Handle to the GNS service */ | ||
126 | static struct GNUNET_GNS_Handle *gns_handle; | 197 | static struct GNUNET_GNS_Handle *gns_handle; |
127 | 198 | ||
199 | /* DLL for ProxyCurlTasks */ | ||
128 | static struct ProxyCurlTask *ctasks_head; | 200 | static struct ProxyCurlTask *ctasks_head; |
201 | |||
202 | /* DLL for ProxyCurlTasks */ | ||
129 | static struct ProxyCurlTask *ctasks_tail; | 203 | static struct ProxyCurlTask *ctasks_tail; |
130 | 204 | ||
205 | /* DLL for http daemons */ | ||
206 | static struct MhdHttpList *mhd_httpd_head; | ||
207 | |||
208 | /* DLL for http daemons */ | ||
209 | static struct MhdHttpList *mhd_httpd_tail; | ||
210 | |||
211 | /* Handle to the regex for dotplus (.+) replacement in HTML */ | ||
131 | static regex_t re_dotplus; | 212 | static regex_t re_dotplus; |
132 | 213 | ||
133 | /** | 214 | /** |
215 | * Checks if name is in tld | ||
216 | * | ||
217 | * @param name the name to check | ||
218 | * @param tld the TLD to check for | ||
219 | * @return GNUNET_YES or GNUNET_NO | ||
220 | */ | ||
221 | int | ||
222 | is_tld(const char* name, const char* tld) | ||
223 | { | ||
224 | int offset = 0; | ||
225 | |||
226 | if (strlen(name) <= strlen(tld)) | ||
227 | { | ||
228 | return GNUNET_NO; | ||
229 | } | ||
230 | |||
231 | offset = strlen(name)-strlen(tld); | ||
232 | if (strcmp (name+offset, tld) != 0) | ||
233 | { | ||
234 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
235 | "%s is not in .%s TLD\n", name, tld); | ||
236 | return GNUNET_NO; | ||
237 | } | ||
238 | |||
239 | return GNUNET_YES; | ||
240 | } | ||
241 | |||
242 | |||
243 | /** | ||
134 | * Read HTTP request header field 'Host' | 244 | * Read HTTP request header field 'Host' |
135 | * | 245 | * |
136 | * @param cls buffer to write to | 246 | * @param cls buffer to write to |
@@ -187,9 +297,36 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
187 | 297 | ||
188 | /** | 298 | /** |
189 | * schedule mhd | 299 | * schedule mhd |
300 | * | ||
301 | * @param hd a http daemon list entry | ||
190 | */ | 302 | */ |
191 | static void | 303 | static void |
192 | run_httpd (void); | 304 | run_httpd (struct MhdHttpList *hd); |
305 | |||
306 | |||
307 | /** | ||
308 | * schedule all mhds | ||
309 | * | ||
310 | */ | ||
311 | static void | ||
312 | run_httpds (void); | ||
313 | |||
314 | |||
315 | /** | ||
316 | * Task that simply runs MHD main loop | ||
317 | * | ||
318 | * @param cls NULL | ||
319 | * @param tc task context | ||
320 | */ | ||
321 | static void | ||
322 | run_mhd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
323 | { | ||
324 | |||
325 | struct MhdHttpList *hd; | ||
326 | |||
327 | for (hd=mhd_httpd_head; hd != NULL; hd = hd->next) | ||
328 | MHD_run (hd->daemon); | ||
329 | } | ||
193 | 330 | ||
194 | 331 | ||
195 | /** | 332 | /** |
@@ -208,10 +345,9 @@ callback_download (void *ptr, size_t size, size_t nmemb, void *ctx) | |||
208 | size_t total; | 345 | size_t total; |
209 | struct ProxyCurlTask *ctask = ctx; | 346 | struct ProxyCurlTask *ctask = ctx; |
210 | 347 | ||
211 | MHD_run (httpd); | 348 | //MHD_run (httpd); |
212 | 349 | ||
213 | total = size*nmemb; | 350 | total = size*nmemb; |
214 | ctask->bytes_downloaded += total; | ||
215 | 351 | ||
216 | if (total == 0) | 352 | if (total == 0) |
217 | { | 353 | { |
@@ -244,7 +380,7 @@ callback_download (void *ptr, size_t size, size_t nmemb, void *ctx) | |||
244 | 380 | ||
245 | //GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 381 | //GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
246 | // "cURL chunk:\n%s\n", (char*)ctask->buffer); | 382 | // "cURL chunk:\n%s\n", (char*)ctask->buffer); |
247 | MHD_run (httpd); | 383 | run_mhd (NULL, NULL); |
248 | return total; | 384 | return total; |
249 | } | 385 | } |
250 | 386 | ||
@@ -267,12 +403,16 @@ mhd_content_free (void *cls) | |||
267 | 403 | ||
268 | } | 404 | } |
269 | 405 | ||
270 | static void | ||
271 | run_mhd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
272 | { | ||
273 | MHD_run (httpd); | ||
274 | } | ||
275 | 406 | ||
407 | |||
408 | |||
409 | |||
410 | /** | ||
411 | * Shorten result callback | ||
412 | * | ||
413 | * @param cls the proxycurltask | ||
414 | * @param short_name the shortened name (NULL on error) | ||
415 | */ | ||
276 | static void | 416 | static void |
277 | process_shorten (void* cls, const char* short_name) | 417 | process_shorten (void* cls, const char* short_name) |
278 | { | 418 | { |
@@ -301,14 +441,19 @@ process_shorten (void* cls, const char* short_name) | |||
301 | GNUNET_SCHEDULER_add_now (&run_mhd, NULL); | 441 | GNUNET_SCHEDULER_add_now (&run_mhd, NULL); |
302 | } | 442 | } |
303 | 443 | ||
444 | |||
445 | /** | ||
446 | * Postprocessing task that uses GNS to shorten names | ||
447 | * | ||
448 | * @param cls the proxycurltask | ||
449 | * @param tc the task context | ||
450 | */ | ||
304 | static void | 451 | static void |
305 | postprocess_name (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 452 | postprocess_name (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
306 | { | 453 | { |
307 | struct ProxyCurlTask *ctask = cls; | 454 | struct ProxyCurlTask *ctask = cls; |
308 | char tmp[strlen(ctask->pp_buf)]; | 455 | char tmp[strlen(ctask->pp_buf)]; |
309 | 456 | ||
310 | |||
311 | |||
312 | sprintf ( tmp, "%s%s", ctask->pp_buf, ctask->authority); | 457 | sprintf ( tmp, "%s%s", ctask->pp_buf, ctask->authority); |
313 | 458 | ||
314 | GNUNET_GNS_shorten (gns_handle, | 459 | GNUNET_GNS_shorten (gns_handle, |
@@ -689,7 +834,7 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
689 | 834 | ||
690 | GNUNET_assert ( num_ctasks == running ); | 835 | GNUNET_assert ( num_ctasks == running ); |
691 | 836 | ||
692 | run_httpd (); | 837 | run_httpds (); |
693 | 838 | ||
694 | } while (mret == CURLM_CALL_MULTI_PERFORM); | 839 | } while (mret == CURLM_CALL_MULTI_PERFORM); |
695 | 840 | ||
@@ -706,6 +851,9 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
706 | /** | 851 | /** |
707 | * Initialize download and trigger curl | 852 | * Initialize download and trigger curl |
708 | * | 853 | * |
854 | * @param cls the proxycurltask | ||
855 | * @param auth_name the name of the authority (site of origin) of ctask->host | ||
856 | * | ||
709 | */ | 857 | */ |
710 | static void | 858 | static void |
711 | process_get_authority (void* cls, | 859 | process_get_authority (void* cls, |
@@ -813,8 +961,6 @@ create_response (void *cls, | |||
813 | 961 | ||
814 | ctask->download_in_progress = GNUNET_YES; | 962 | ctask->download_in_progress = GNUNET_YES; |
815 | ctask->download_successful = GNUNET_NO; | 963 | ctask->download_successful = GNUNET_NO; |
816 | ctask->bytes_downloaded = 0; | ||
817 | ctask->connection = con; | ||
818 | ctask->buf_status = BUF_WAIT_FOR_CURL; | 964 | ctask->buf_status = BUF_WAIT_FOR_CURL; |
819 | ctask->bytes_in_buffer = 0; | 965 | ctask->bytes_in_buffer = 0; |
820 | ctask->parse_content = GNUNET_NO; | 966 | ctask->parse_content = GNUNET_NO; |
@@ -891,10 +1037,23 @@ do_httpd (void *cls, | |||
891 | 1037 | ||
892 | 1038 | ||
893 | /** | 1039 | /** |
1040 | * run all httpd | ||
1041 | */ | ||
1042 | static void | ||
1043 | run_httpds () | ||
1044 | { | ||
1045 | struct MhdHttpList *hd; | ||
1046 | |||
1047 | for (hd=mhd_httpd_head; hd != NULL; hd = hd->next) | ||
1048 | run_httpd (hd); | ||
1049 | |||
1050 | } | ||
1051 | |||
1052 | /** | ||
894 | * schedule mhd | 1053 | * schedule mhd |
895 | */ | 1054 | */ |
896 | static void | 1055 | static void |
897 | run_httpd () | 1056 | run_httpd (struct MhdHttpList *hd) |
898 | { | 1057 | { |
899 | fd_set rs; | 1058 | fd_set rs; |
900 | fd_set ws; | 1059 | fd_set ws; |
@@ -914,13 +1073,13 @@ run_httpd () | |||
914 | wes = GNUNET_NETWORK_fdset_create (); | 1073 | wes = GNUNET_NETWORK_fdset_create (); |
915 | wws = GNUNET_NETWORK_fdset_create (); | 1074 | wws = GNUNET_NETWORK_fdset_create (); |
916 | max = -1; | 1075 | max = -1; |
917 | GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max)); | 1076 | GNUNET_assert (MHD_YES == MHD_get_fdset (hd->daemon, &rs, &ws, &es, &max)); |
918 | 1077 | ||
919 | 1078 | ||
920 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1079 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
921 | "MHD fds: max=%d\n", max); | 1080 | "MHD fds: max=%d\n", max); |
922 | 1081 | ||
923 | haveto = MHD_get_timeout (httpd, &timeout); | 1082 | haveto = MHD_get_timeout (hd->daemon, &timeout); |
924 | 1083 | ||
925 | if (haveto == MHD_YES) | 1084 | if (haveto == MHD_YES) |
926 | tv.rel_value = (uint64_t) timeout; | 1085 | tv.rel_value = (uint64_t) timeout; |
@@ -931,16 +1090,17 @@ run_httpd () | |||
931 | GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); | 1090 | GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); |
932 | 1091 | ||
933 | if (httpd_task != GNUNET_SCHEDULER_NO_TASK) | 1092 | if (httpd_task != GNUNET_SCHEDULER_NO_TASK) |
934 | GNUNET_SCHEDULER_cancel (httpd_task); | 1093 | GNUNET_SCHEDULER_cancel (hd->httpd_task); |
935 | httpd_task = | 1094 | hd->httpd_task = |
936 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 1095 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
937 | tv, wrs, wws, | 1096 | tv, wrs, wws, |
938 | &do_httpd, NULL); | 1097 | &do_httpd, hd); |
939 | GNUNET_NETWORK_fdset_destroy (wrs); | 1098 | GNUNET_NETWORK_fdset_destroy (wrs); |
940 | GNUNET_NETWORK_fdset_destroy (wws); | 1099 | GNUNET_NETWORK_fdset_destroy (wws); |
941 | GNUNET_NETWORK_fdset_destroy (wes); | 1100 | GNUNET_NETWORK_fdset_destroy (wes); |
942 | } | 1101 | } |
943 | 1102 | ||
1103 | |||
944 | /** | 1104 | /** |
945 | * Task run whenever HTTP server operations are pending. | 1105 | * Task run whenever HTTP server operations are pending. |
946 | * | 1106 | * |
@@ -951,13 +1111,15 @@ static void | |||
951 | do_httpd (void *cls, | 1111 | do_httpd (void *cls, |
952 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1112 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
953 | { | 1113 | { |
954 | httpd_task = GNUNET_SCHEDULER_NO_TASK; | 1114 | struct MhdHttpList *hd = cls; |
955 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1115 | |
956 | "MHD run \n"); | 1116 | hd->httpd_task = GNUNET_SCHEDULER_NO_TASK; |
957 | MHD_run (httpd); | 1117 | |
958 | run_httpd (); | 1118 | MHD_run (hd->daemon); |
1119 | run_httpd (hd); | ||
959 | } | 1120 | } |
960 | 1121 | ||
1122 | |||
961 | /** | 1123 | /** |
962 | * Read data from socket | 1124 | * Read data from socket |
963 | * | 1125 | * |
@@ -1118,8 +1280,14 @@ do_read_remote (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1118 | } | 1280 | } |
1119 | 1281 | ||
1120 | 1282 | ||
1283 | /** | ||
1284 | * Adds a socket to MHD | ||
1285 | * | ||
1286 | * @param h the handle to the socket to add | ||
1287 | * @return whatever MHD_add_connection returns | ||
1288 | */ | ||
1121 | static int | 1289 | static int |
1122 | add_handle_to_mhd (struct GNUNET_NETWORK_Handle *h) | 1290 | add_handle_to_mhd (struct GNUNET_NETWORK_Handle *h, struct MHD_Daemon *daemon) |
1123 | { | 1291 | { |
1124 | int fd; | 1292 | int fd; |
1125 | struct sockaddr *addr; | 1293 | struct sockaddr *addr; |
@@ -1129,10 +1297,125 @@ add_handle_to_mhd (struct GNUNET_NETWORK_Handle *h) | |||
1129 | addr = GNUNET_NETWORK_get_addr (h); | 1297 | addr = GNUNET_NETWORK_get_addr (h); |
1130 | len = GNUNET_NETWORK_get_addrlen (h); | 1298 | len = GNUNET_NETWORK_get_addrlen (h); |
1131 | 1299 | ||
1132 | return MHD_add_connection (httpd, fd, addr, len); | 1300 | return MHD_add_connection (daemon, fd, addr, len); |
1301 | } | ||
1302 | |||
1303 | |||
1304 | /*TODO this needs MHD API modification */ | ||
1305 | static int http_port = 4444; | ||
1306 | |||
1307 | |||
1308 | static long | ||
1309 | get_file_size (const char* filename) | ||
1310 | { | ||
1311 | FILE *fp; | ||
1312 | |||
1313 | fp = fopen (filename, "rb"); | ||
1314 | if (fp) | ||
1315 | { | ||
1316 | long size; | ||
1317 | |||
1318 | if ((0 != fseek (fp, 0, SEEK_END)) || (-1 == (size = ftell (fp)))) | ||
1319 | size = 0; | ||
1320 | |||
1321 | fclose (fp); | ||
1322 | |||
1323 | return size; | ||
1324 | } | ||
1325 | |||
1326 | return 0; | ||
1133 | } | 1327 | } |
1134 | 1328 | ||
1135 | /** | 1329 | /** |
1330 | * Read file in filename | ||
1331 | * | ||
1332 | * @param filename file to read | ||
1333 | * @return data | ||
1334 | */ | ||
1335 | static char* | ||
1336 | load_file (const char* filename) | ||
1337 | { | ||
1338 | FILE *fp; | ||
1339 | char *buffer; | ||
1340 | long size; | ||
1341 | |||
1342 | size = get_file_size (filename); | ||
1343 | if (size == 0) | ||
1344 | return NULL; | ||
1345 | |||
1346 | fp = fopen (filename, "rb"); | ||
1347 | if (!fp) | ||
1348 | return NULL; | ||
1349 | |||
1350 | buffer = GNUNET_malloc (size); | ||
1351 | if (!buffer) | ||
1352 | { | ||
1353 | fclose (fp); | ||
1354 | return NULL; | ||
1355 | } | ||
1356 | |||
1357 | if (size != fread (buffer, 1, size, fp)) | ||
1358 | { | ||
1359 | GNUNET_free (buffer); | ||
1360 | buffer = NULL; | ||
1361 | } | ||
1362 | |||
1363 | fclose (fp); | ||
1364 | return buffer; | ||
1365 | } | ||
1366 | |||
1367 | /** | ||
1368 | * Adds a socket to an SSL MHD instance | ||
1369 | * It is important the the domain name is | ||
1370 | * correct. In most cases we need to start a new daemon | ||
1371 | */ | ||
1372 | static int | ||
1373 | add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, char* domain) | ||
1374 | { | ||
1375 | struct MhdHttpList *hd = NULL; | ||
1376 | |||
1377 | static char *key_pem; | ||
1378 | static char *cert_pem; | ||
1379 | |||
1380 | key_pem = load_file ("server.key"); | ||
1381 | cert_pem = load_file ("server.pem"); | ||
1382 | |||
1383 | for (hd = mhd_httpd_head; hd != NULL; hd = hd->next) | ||
1384 | { | ||
1385 | if (0 == strcmp (hd->domain, domain)) | ||
1386 | break; | ||
1387 | } | ||
1388 | |||
1389 | if (NULL == hd) | ||
1390 | { | ||
1391 | /* Start new MHD */ | ||
1392 | /* TODO: create cert, start SSL MHD */ | ||
1393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1394 | "No previous SSL instance found... starting new one\n"); | ||
1395 | hd = GNUNET_malloc (sizeof (struct MhdHttpList)); | ||
1396 | hd->is_ssl = GNUNET_YES; | ||
1397 | strcpy (hd->domain, domain); | ||
1398 | hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL, http_port++, | ||
1399 | NULL, NULL, | ||
1400 | &create_response, NULL, | ||
1401 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, | ||
1402 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, | ||
1403 | MHD_OPTION_NOTIFY_COMPLETED, | ||
1404 | NULL, NULL, | ||
1405 | MHD_OPTION_HTTPS_MEM_KEY, key_pem, | ||
1406 | MHD_OPTION_HTTPS_MEM_CERT, cert_pem, | ||
1407 | MHD_OPTION_END); | ||
1408 | hd->httpd_task = GNUNET_SCHEDULER_NO_TASK; | ||
1409 | |||
1410 | GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd); | ||
1411 | } | ||
1412 | |||
1413 | return add_handle_to_mhd (h, hd->daemon); | ||
1414 | } | ||
1415 | |||
1416 | |||
1417 | |||
1418 | /** | ||
1136 | * Read data from incoming connection | 1419 | * Read data from incoming connection |
1137 | * | 1420 | * |
1138 | * @param cls the closure | 1421 | * @param cls the closure |
@@ -1147,6 +1430,7 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1147 | struct socks5_client_request *c_req; | 1430 | struct socks5_client_request *c_req; |
1148 | struct socks5_server_response *s_resp; | 1431 | struct socks5_server_response *s_resp; |
1149 | 1432 | ||
1433 | int ret; | ||
1150 | char domain[256]; | 1434 | char domain[256]; |
1151 | uint8_t dom_len; | 1435 | uint8_t dom_len; |
1152 | uint16_t req_port; | 1436 | uint16_t req_port; |
@@ -1239,8 +1523,22 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1239 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1523 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1240 | "Requested connection is gnunet tld\n", | 1524 | "Requested connection is gnunet tld\n", |
1241 | domain); | 1525 | domain); |
1526 | |||
1527 | ret = MHD_NO; | ||
1528 | if (ntohs(req_port) == HTTPS_PORT) | ||
1529 | { | ||
1530 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1531 | "Requested connection is HTTPS\n"); | ||
1532 | ret = add_handle_to_ssl_mhd ( s5r->sock, domain ); | ||
1533 | } | ||
1534 | else if (NULL != httpd) | ||
1535 | { | ||
1536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1537 | "Requested connection is HTTP\n"); | ||
1538 | ret = add_handle_to_mhd ( s5r->sock, httpd ); | ||
1539 | } | ||
1242 | 1540 | ||
1243 | if (NULL == httpd) | 1541 | if (ret != MHD_YES) |
1244 | { | 1542 | { |
1245 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1543 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1246 | _("Failed to start HTTP server\n")); | 1544 | _("Failed to start HTTP server\n")); |
@@ -1256,10 +1554,8 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1256 | //GNUNET_free(s5r); | 1554 | //GNUNET_free(s5r); |
1257 | return; | 1555 | return; |
1258 | } | 1556 | } |
1259 | 1557 | ||
1260 | if (MHD_YES == add_handle_to_mhd ( s5r->sock )) | 1558 | /* Signal success */ |
1261 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1262 | "Sucessfully added client to MHD!\n"); | ||
1263 | s_resp->version = 0x05; | 1559 | s_resp->version = 0x05; |
1264 | s_resp->reply = 0x00; | 1560 | s_resp->reply = 0x00; |
1265 | s_resp->reserved = 0x00; | 1561 | s_resp->reserved = 0x00; |
@@ -1269,7 +1565,7 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1269 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | 1565 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1270 | s5r->sock, | 1566 | s5r->sock, |
1271 | &do_write, s5r); | 1567 | &do_write, s5r); |
1272 | run_httpd (); | 1568 | run_httpds (); |
1273 | //GNUNET_free ( s5r ); | 1569 | //GNUNET_free ( s5r ); |
1274 | //FIXME complete socks resp! | 1570 | //FIXME complete socks resp! |
1275 | return; | 1571 | return; |
@@ -1398,6 +1694,7 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1398 | 1694 | ||
1399 | } | 1695 | } |
1400 | 1696 | ||
1697 | |||
1401 | /** | 1698 | /** |
1402 | * Accept new incoming connections | 1699 | * Accept new incoming connections |
1403 | * | 1700 | * |
@@ -1441,6 +1738,7 @@ do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1441 | //GNUNET_CONTAINER_DLL_insert (s5conns.head, s5conns.tail, s5r); | 1738 | //GNUNET_CONTAINER_DLL_insert (s5conns.head, s5conns.tail, s5r); |
1442 | } | 1739 | } |
1443 | 1740 | ||
1741 | |||
1444 | /** | 1742 | /** |
1445 | * Task run on shutdown | 1743 | * Task run on shutdown |
1446 | * | 1744 | * |
@@ -1451,25 +1749,37 @@ static void | |||
1451 | do_shutdown (void *cls, | 1749 | do_shutdown (void *cls, |
1452 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1750 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1453 | { | 1751 | { |
1454 | if (GNUNET_SCHEDULER_NO_TASK != httpd_task) | 1752 | |
1455 | { | 1753 | struct MhdHttpList *hd; |
1456 | GNUNET_SCHEDULER_cancel (httpd_task); | 1754 | struct MhdHttpList *tmp_hd; |
1457 | httpd_task = GNUNET_SCHEDULER_NO_TASK; | 1755 | |
1458 | } | ||
1459 | |||
1460 | if (GNUNET_SCHEDULER_NO_TASK != curl_download_task) | 1756 | if (GNUNET_SCHEDULER_NO_TASK != curl_download_task) |
1461 | { | 1757 | { |
1462 | GNUNET_SCHEDULER_cancel (curl_download_task); | 1758 | GNUNET_SCHEDULER_cancel (curl_download_task); |
1463 | curl_download_task = GNUNET_SCHEDULER_NO_TASK; | 1759 | curl_download_task = GNUNET_SCHEDULER_NO_TASK; |
1464 | } | 1760 | } |
1465 | 1761 | ||
1466 | if (NULL != httpd) | 1762 | for (hd = mhd_httpd_head; hd != NULL; hd = tmp_hd) |
1467 | { | 1763 | { |
1468 | MHD_stop_daemon (httpd); | 1764 | tmp_hd = hd->next; |
1469 | httpd = NULL; | 1765 | |
1766 | if (GNUNET_SCHEDULER_NO_TASK != hd->httpd_task) | ||
1767 | { | ||
1768 | GNUNET_SCHEDULER_cancel (hd->httpd_task); | ||
1769 | hd->httpd_task = GNUNET_SCHEDULER_NO_TASK; | ||
1770 | } | ||
1771 | |||
1772 | if (NULL != hd->daemon) | ||
1773 | { | ||
1774 | MHD_stop_daemon (hd->daemon); | ||
1775 | hd->daemon = NULL; | ||
1776 | } | ||
1777 | |||
1778 | GNUNET_free (hd); | ||
1470 | } | 1779 | } |
1471 | } | 1780 | } |
1472 | 1781 | ||
1782 | |||
1473 | /** | 1783 | /** |
1474 | * Compiles a regex for us | 1784 | * Compiles a regex for us |
1475 | * | 1785 | * |
@@ -1494,6 +1804,7 @@ compile_regex (regex_t *re, const char* rt) | |||
1494 | return 0; | 1804 | return 0; |
1495 | } | 1805 | } |
1496 | 1806 | ||
1807 | |||
1497 | /** | 1808 | /** |
1498 | * Main function that will be run | 1809 | * Main function that will be run |
1499 | * | 1810 | * |
@@ -1507,6 +1818,7 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
1507 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 1818 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
1508 | { | 1819 | { |
1509 | struct sockaddr_in sa; | 1820 | struct sockaddr_in sa; |
1821 | struct MhdHttpList *hd; | ||
1510 | 1822 | ||
1511 | compile_regex (&re_dotplus, (char*) RE_DOTPLUS); | 1823 | compile_regex (&re_dotplus, (char*) RE_DOTPLUS); |
1512 | 1824 | ||
@@ -1567,8 +1879,14 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
1567 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1879 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1568 | "Proxy listens on port %u\n", | 1880 | "Proxy listens on port %u\n", |
1569 | port); | 1881 | port); |
1882 | |||
1883 | mhd_httpd_head = NULL; | ||
1884 | mhd_httpd_tail = NULL; | ||
1570 | 1885 | ||
1571 | httpd = MHD_start_daemon (MHD_USE_DEBUG, 4444, | 1886 | hd = GNUNET_malloc (sizeof (struct MhdHttpList)); |
1887 | hd->is_ssl = GNUNET_NO; | ||
1888 | strcpy (hd->domain, ""); | ||
1889 | httpd = MHD_start_daemon (MHD_USE_DEBUG, http_port++, | ||
1572 | NULL, NULL, | 1890 | NULL, NULL, |
1573 | &create_response, NULL, | 1891 | &create_response, NULL, |
1574 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, | 1892 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, |
@@ -1576,13 +1894,19 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
1576 | MHD_OPTION_NOTIFY_COMPLETED, | 1894 | MHD_OPTION_NOTIFY_COMPLETED, |
1577 | NULL, NULL, | 1895 | NULL, NULL, |
1578 | MHD_OPTION_END); | 1896 | MHD_OPTION_END); |
1579 | run_httpd (); | 1897 | hd->daemon = httpd; |
1898 | hd->httpd_task = GNUNET_SCHEDULER_NO_TASK; | ||
1899 | |||
1900 | GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd); | ||
1901 | |||
1902 | run_httpds (); | ||
1580 | 1903 | ||
1581 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 1904 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
1582 | &do_shutdown, NULL); | 1905 | &do_shutdown, NULL); |
1583 | 1906 | ||
1584 | } | 1907 | } |
1585 | 1908 | ||
1909 | |||
1586 | /** | 1910 | /** |
1587 | * The main function for gnunet-gns-proxy. | 1911 | * The main function for gnunet-gns-proxy. |
1588 | * | 1912 | * |