aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-proxy.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-05 15:35:38 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-05 15:35:38 +0000
commitdfb16cb188e82a9f48af6390694c872be2765049 (patch)
treeafdbe3a55a0701c2499486161165fc2f6b242ce3 /src/gns/gnunet-gns-proxy.c
parentf20b8843eaa532e67cb706440e4866df289c83b3 (diff)
downloadgnunet-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.c486
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 */
40int
41is_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 */
61struct Socks5Request 50struct 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]+[.])+)([+])" 90struct 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 */
89struct ProxyCurlTask 114struct 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) */
118unsigned long port = GNUNET_GNS_PROXY_PORT; 176unsigned long port = GNUNET_GNS_PROXY_PORT;
177
178/* The listen socket of the proxy */
119static struct GNUNET_NETWORK_Handle *lsock; 179static struct GNUNET_NETWORK_Handle *lsock;
180
181/* The listen task ID */
120GNUNET_SCHEDULER_TaskIdentifier ltask; 182GNUNET_SCHEDULER_TaskIdentifier ltask;
183
184/* The cURL download task */
121GNUNET_SCHEDULER_TaskIdentifier curl_download_task; 185GNUNET_SCHEDULER_TaskIdentifier curl_download_task;
186
187/* The non SSL httpd daemon handle */
122static struct MHD_Daemon *httpd; 188static struct MHD_Daemon *httpd;
189
190/* The http task ID */
123static GNUNET_SCHEDULER_TaskIdentifier httpd_task; 191static GNUNET_SCHEDULER_TaskIdentifier httpd_task;
192
193/* The cURL multi handle */
124static CURLM *curl_multi; 194static CURLM *curl_multi;
125 195
196/* Handle to the GNS service */
126static struct GNUNET_GNS_Handle *gns_handle; 197static struct GNUNET_GNS_Handle *gns_handle;
127 198
199/* DLL for ProxyCurlTasks */
128static struct ProxyCurlTask *ctasks_head; 200static struct ProxyCurlTask *ctasks_head;
201
202/* DLL for ProxyCurlTasks */
129static struct ProxyCurlTask *ctasks_tail; 203static struct ProxyCurlTask *ctasks_tail;
130 204
205/* DLL for http daemons */
206static struct MhdHttpList *mhd_httpd_head;
207
208/* DLL for http daemons */
209static struct MhdHttpList *mhd_httpd_tail;
210
211/* Handle to the regex for dotplus (.+) replacement in HTML */
131static regex_t re_dotplus; 212static 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 */
221int
222is_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 */
191static void 303static void
192run_httpd (void); 304run_httpd (struct MhdHttpList *hd);
305
306
307/**
308 * schedule all mhds
309 *
310 */
311static void
312run_httpds (void);
313
314
315/**
316 * Task that simply runs MHD main loop
317 *
318 * @param cls NULL
319 * @param tc task context
320 */
321static void
322run_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
270static void
271run_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 */
276static void 416static void
277process_shorten (void* cls, const char* short_name) 417process_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 */
304static void 451static void
305postprocess_name (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 452postprocess_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 */
710static void 858static void
711process_get_authority (void* cls, 859process_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 */
1042static void
1043run_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 */
896static void 1055static void
897run_httpd () 1056run_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
951do_httpd (void *cls, 1111do_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 */
1121static int 1289static int
1122add_handle_to_mhd (struct GNUNET_NETWORK_Handle *h) 1290add_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 */
1305static int http_port = 4444;
1306
1307
1308static long
1309get_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 */
1335static char*
1336load_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 */
1372static int
1373add_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
1451do_shutdown (void *cls, 1749do_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 *