aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-05-20 13:00:26 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-05-20 13:00:26 +0000
commit9bf22db9cf42ff29f51e9ea1474b8a1915c4f339 (patch)
tree224570e6466a40fac3a1bb7a54c56af89a9a9676
parent52cab305fc73c75fedcbf877f0ef6bb03151970b (diff)
downloadgnunet-9bf22db9cf42ff29f51e9ea1474b8a1915c4f339.tar.gz
gnunet-9bf22db9cf42ff29f51e9ea1474b8a1915c4f339.zip
- make mhd and curl play nice thread wise
-rw-r--r--src/gns/gnocksy/gnocksy.c186
-rw-r--r--src/gns/gnocksy/protocol.h21
2 files changed, 173 insertions, 34 deletions
diff --git a/src/gns/gnocksy/gnocksy.c b/src/gns/gnocksy/gnocksy.c
index 2f2699955..3f2254778 100644
--- a/src/gns/gnocksy/gnocksy.c
+++ b/src/gns/gnocksy/gnocksy.c
@@ -30,7 +30,8 @@
30 30
31#define DEBUG 1 31#define DEBUG 1
32 32
33CURL *curl = NULL; 33#define HTML_HDR_CONTENT "Content-Type: text/html\r\n"
34
34struct MHD_Daemon *mhd_daemon; 35struct MHD_Daemon *mhd_daemon;
35 36
36static size_t 37static size_t
@@ -38,21 +39,56 @@ curl_write_data (void *buffer, size_t size, size_t nmemb, void* cls)
38{ 39{
39 const char* page = buffer; 40 const char* page = buffer;
40 size_t bytes = size * nmemb; 41 size_t bytes = size * nmemb;
41 struct MHD_Response *response; 42 struct socks5_bridge* br = cls;
42 struct MHD_Connection *con = cls;
43 int ret; 43 int ret;
44 44
45 response = MHD_create_response_from_data (strlen(page), 45 pthread_mutex_lock ( &br->m_buf );
46 (void*) page, 46 if (br->MHD_CURL_BUF_STATUS == BUF_WAIT_FOR_MHD)
47 MHD_NO, 47 {
48 MHD_NO); 48 pthread_mutex_unlock ( &br->m_buf );
49 printf( "waiting for mhd to process data... pausing curl\n");
50 return CURL_WRITEFUNC_PAUSE;
51 }
52
53 /* do regex magic */
54 if ( br->res_is_html )
55 {
56 printf ("result is html text\n");
57 //void
58 }
59
60 memcpy (br->MHD_CURL_BUF, buffer, bytes);
61 br->MHD_CURL_BUF_SIZE = bytes;
62
63 br->MHD_CURL_BUF_STATUS = BUF_WAIT_FOR_MHD;
64
65 pthread_mutex_unlock ( &br->m_buf );
66
67
68 //MHD_destroy_response (response);
69 printf( "buffer: %s\n", (char*)buffer );
70 return bytes;
71}
72
73static size_t
74curl_check_hdr (void *buffer, size_t size, size_t nmemb, void* cls)
75{
76 size_t bytes = size * nmemb;
77 struct socks5_bridge* br = cls;
78 char hdr[bytes+1];
79
80 memcpy(hdr, buffer, bytes);
81 hdr[bytes] = '\0';
82
83 printf ("got hdr: %s\n", hdr);
84
85 if (0 == strcmp(hdr, HTML_HDR_CONTENT))
86 br->res_is_html = 1;
49 87
50 ret = MHD_queue_response (con, MHD_HTTP_OK, response);
51 MHD_destroy_response (response);
52 printf( "buffer %s\n", (char*)buffer );
53 return bytes; 88 return bytes;
54} 89}
55 90
91
56/* 92/*
57 * Create an ipv4/6 tcp socket for a given port 93 * Create an ipv4/6 tcp socket for a given port
58 * 94 *
@@ -203,6 +239,87 @@ access_cb (void* cls,
203 return MHD_YES; 239 return MHD_YES;
204} 240}
205 241
242static void
243fetch_url (struct socks5_bridge* br)
244{
245
246 CURLcode ret;
247
248 br->curl = curl_easy_init();
249
250 /* TODO optionally do LEHO stuff here */
251
252 if (br->curl)
253 {
254 curl_easy_setopt (br->curl, CURLOPT_URL, br->full_url);
255 curl_easy_setopt (br->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr);
256 curl_easy_setopt (br->curl, CURLOPT_HEADERDATA, br);
257 curl_easy_setopt (br->curl, CURLOPT_WRITEFUNCTION, &curl_write_data);
258 curl_easy_setopt (br->curl, CURLOPT_WRITEDATA, br);
259 ret = curl_easy_perform (br->curl);
260 free (br->full_url);
261 pthread_mutex_lock ( &br->m_done );
262 br->is_done = 1;
263 pthread_mutex_unlock ( &br->m_done );
264
265 curl_easy_cleanup (br->curl);
266
267 if (ret == CURLE_OK)
268 {
269 printf("all good on the curl end\n");
270 return;
271 }
272 printf("error on the curl end %s\n", curl_easy_strerror(ret));
273 }
274}
275
276static ssize_t
277mhd_content_cb (void* cls,
278 uint64_t pos,
279 char* buf,
280 size_t max)
281{
282 struct socks5_bridge* br = cls;
283
284 pthread_mutex_lock ( &br->m_done );
285 /* if done and buf empty */
286 if ( (br->is_done == 1) &&
287 (br->MHD_CURL_BUF_STATUS == BUF_WAIT_FOR_CURL) )
288 {
289 printf("done. sending response...\n");
290 br->is_done = 0;
291 pthread_mutex_unlock ( &br->m_done );
292 return MHD_CONTENT_READER_END_OF_STREAM;
293 }
294 pthread_mutex_unlock ( &br->m_done );
295
296 pthread_mutex_lock ( &br->m_buf );
297 if ( br->MHD_CURL_BUF_STATUS == BUF_WAIT_FOR_CURL )
298 {
299 printf("waiting for curl...\n");
300 pthread_mutex_unlock ( &br->m_buf );
301 return 0;
302 }
303
304 if ( br->MHD_CURL_BUF_SIZE > max )
305 {
306 printf("buffer in mhd response too small!\n");
307 pthread_mutex_unlock ( &br->m_buf );
308 return MHD_CONTENT_READER_END_WITH_ERROR;
309 }
310
311 if (0 != br->MHD_CURL_BUF_SIZE)
312 {
313 printf("copying %d bytes to mhd response at offset %d\n",
314 br->MHD_CURL_BUF_SIZE, pos);
315 memcpy ( buf, br->MHD_CURL_BUF, br->MHD_CURL_BUF_SIZE );
316 }
317 br->MHD_CURL_BUF_STATUS = BUF_WAIT_FOR_CURL;
318 pthread_mutex_unlock ( &br->m_buf );
319
320 return br->MHD_CURL_BUF_SIZE;
321}
322
206static int 323static int
207accept_cb (void *cls, 324accept_cb (void *cls,
208 struct MHD_Connection *con, 325 struct MHD_Connection *con,
@@ -218,7 +335,7 @@ accept_cb (void *cls,
218 "</head><body>gnoxy demo</body></html>"; 335 "</head><body>gnoxy demo</body></html>";
219 struct MHD_Response *response; 336 struct MHD_Response *response;
220 struct socks5_bridge *br = cls; 337 struct socks5_bridge *br = cls;
221 CURLcode ret; 338 int ret;
222 char* full_url; 339 char* full_url;
223 340
224 if (0 != strcmp (meth, "GET")) 341 if (0 != strcmp (meth, "GET"))
@@ -233,28 +350,31 @@ accept_cb (void *cls,
233 return MHD_NO; 350 return MHD_NO;
234 351
235 *con_cls = NULL; 352 *con_cls = NULL;
236 353
237 if (curl) 354 if (-1 == asprintf (&br->full_url, "%s%s", br->host, url))
238 { 355 {
239 if (-1 == asprintf (&full_url, "%s%s", br->host, url)) 356 printf ("error building url!\n");
240 { 357 return MHD_NO;
241 printf ("error building url!\n");
242 return MHD_NO;
243 }
244 printf ("url %s\n", full_url);
245 curl_easy_setopt (curl, CURLOPT_URL, full_url);
246 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, &curl_write_data);
247 curl_easy_setopt (curl, CURLOPT_WRITEDATA, con);
248 ret = curl_easy_perform (curl);
249 free (full_url);
250 if (ret == CURLE_OK)
251 {
252 printf("all good on the curl end\n");
253 return MHD_YES;
254 }
255 printf("error on the curl end %s\n", curl_easy_strerror(ret));
256 } 358 }
257 return MHD_NO; 359 printf ("url %s\n", br->full_url);
360
361 pthread_mutex_lock ( &br->m_done );
362 br->is_done = 0;
363 pthread_mutex_unlock ( &br->m_done );
364
365 br->MHD_CURL_BUF_STATUS = BUF_WAIT_FOR_CURL;
366 br->res_is_html = 0;
367
368 response = MHD_create_response_from_callback (-1, -1,
369 &mhd_content_cb,
370 br,
371 NULL); //TODO destroy resp here
372
373 ret = MHD_queue_response (con, MHD_HTTP_OK, response);
374 pthread_create ( &br->thread, NULL, &fetch_url, br );
375
376 return MHD_YES;
377
258 378
259} 379}
260 380
@@ -281,14 +401,13 @@ int main ( int argc, char *argv[] )
281 struct socks5_client_request *req; 401 struct socks5_client_request *req;
282 struct socks5_bridge* new_br; 402 struct socks5_bridge* new_br;
283 char domain[256]; 403 char domain[256];
284 uint8_t msg[16];
285 uint8_t dom_len; 404 uint8_t dom_len;
286 uint16_t req_port; 405 uint16_t req_port;
287 int conn_fd; 406 int conn_fd;
288 struct hostent *phost; 407 struct hostent *phost;
289 408
290 mhd_daemon = NULL; 409 mhd_daemon = NULL;
291 curl = curl_easy_init(); 410 curl_global_init(CURL_GLOBAL_ALL);
292 411
293 for (j = 0; j < MAXEVENTS; j++) 412 for (j = 0; j < MAXEVENTS; j++)
294 ev_states[j] = SOCKS5_INIT; 413 ev_states[j] = SOCKS5_INIT;
@@ -565,7 +684,6 @@ int main ( int argc, char *argv[] )
565 684
566 free (events); 685 free (events);
567 MHD_stop_daemon (mhd_daemon); 686 MHD_stop_daemon (mhd_daemon);
568 curl_easy_cleanup (curl);
569 close (sfd); 687 close (sfd);
570 688
571 return EXIT_SUCCESS; 689 return EXIT_SUCCESS;
diff --git a/src/gns/gnocksy/protocol.h b/src/gns/gnocksy/protocol.h
index 8b3b218d6..4f7e23675 100644
--- a/src/gns/gnocksy/protocol.h
+++ b/src/gns/gnocksy/protocol.h
@@ -36,6 +36,9 @@ struct socks5_server_hello
36 uint8_t auth_method; 36 uint8_t auth_method;
37}; 37};
38 38
39#define BUF_WAIT_FOR_CURL 0
40#define BUF_WAIT_FOR_MHD 1
41
39/* Struct used to store connection 42/* Struct used to store connection
40 * information 43 * information
41 */ 44 */
@@ -47,6 +50,24 @@ struct socks5_bridge
47 socklen_t addr_len; 50 socklen_t addr_len;
48 char host[256]; 51 char host[256];
49 int status; 52 int status;
53
54 /* http url + host */
55 char* full_url;
56
57 /* handle to curl */
58 CURL* curl;
59
60 /* is response html? */
61 int res_is_html;
62
63 /* buffer structures */
64 pthread_t thread;
65 pthread_mutex_t m_done;
66 int is_done;
67 pthread_mutex_t m_buf;
68 char MHD_CURL_BUF[CURL_MAX_WRITE_SIZE];
69 size_t MHD_CURL_BUF_SIZE;
70 int MHD_CURL_BUF_STATUS;
50}; 71};
51 72
52/* Server response to client requests */ 73/* Server response to client requests */