aboutsummaryrefslogtreecommitdiff
path: root/src/gns
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-08-31 09:53:47 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-08-31 09:53:47 +0000
commit16f176f0ff371539c270b95a9b6d333a39f26ede (patch)
tree65a59fb6f9e2940e56d17201ea0f29945aa120c5 /src/gns
parent7284d5df365298347caca546fd91a010d0af3719 (diff)
downloadgnunet-16f176f0ff371539c270b95a9b6d333a39f26ede.tar.gz
gnunet-16f176f0ff371539c270b95a9b6d333a39f26ede.zip
- fixing a variety of bugs including POSTing data, content-length handling and improving connection handling
Diffstat (limited to 'src/gns')
-rw-r--r--src/gns/gnunet-gns-proxy.c362
1 files changed, 226 insertions, 136 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index c02247988..36b21365e 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -430,6 +430,31 @@ enum SocksPhase
430}; 430};
431 431
432 432
433/**
434 * A header list
435 */
436struct HttpResponseHeader
437{
438 /**
439 * DLL
440 */
441 struct HttpResponseHeader *next;
442
443 /**
444 * DLL
445 */
446 struct HttpResponseHeader *prev;
447
448 /**
449 * Header type
450 */
451 char *type;
452
453 /**
454 * Header value
455 */
456 char *value;
457};
433 458
434/** 459/**
435 * A structure for socks requests 460 * A structure for socks requests
@@ -572,6 +597,16 @@ struct Socks5Request
572 */ 597 */
573 uint16_t port; 598 uint16_t port;
574 599
600 /**
601 * Headers from response
602 */
603 struct HttpResponseHeader *header_head;
604
605 /**
606 * Headers from response
607 */
608 struct HttpResponseHeader *header_tail;
609
575}; 610};
576 611
577 612
@@ -986,12 +1021,12 @@ static size_t
986curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) 1021curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
987{ 1022{
988 struct Socks5Request *s5r = cls; 1023 struct Socks5Request *s5r = cls;
1024 struct HttpResponseHeader *header;
989 size_t bytes = size * nmemb; 1025 size_t bytes = size * nmemb;
990 char *ndup; 1026 char *ndup;
991 const char *hdr_type; 1027 const char *hdr_type;
992 const char *cookie_domain; 1028 const char *cookie_domain;
993 char *hdr_val; 1029 char *hdr_val;
994 long resp_code;
995 char *new_cookie_hdr; 1030 char *new_cookie_hdr;
996 char *new_location; 1031 char *new_location;
997 size_t offset; 1032 size_t offset;
@@ -999,49 +1034,11 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
999 int domain_matched; 1034 int domain_matched;
1000 char *tok; 1035 char *tok;
1001 1036
1002 if (NULL == s5r->response) 1037 /* first, check SSL certificate */
1003 { 1038 if ( (HTTPS_PORT == s5r->port) &&
1004 /* first, check SSL certificate */ 1039 (GNUNET_OK != check_ssl_certificate (s5r)) )
1005 if ( (HTTPS_PORT == s5r->port) && 1040 return GNUNET_SYSERR;
1006 (GNUNET_OK != check_ssl_certificate (s5r)) )
1007 return 0;
1008 1041
1009 GNUNET_break (CURLE_OK ==
1010 curl_easy_getinfo (s5r->curl,
1011 CURLINFO_RESPONSE_CODE,
1012 &resp_code));
1013 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1014 "Creating MHD response with code %d\n",
1015 (int) resp_code);
1016 s5r->response_code = resp_code;
1017 s5r->response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
1018 IO_BUFFERSIZE,
1019 &mhd_content_cb,
1020 s5r,
1021 NULL);
1022 if (NULL != s5r->leho)
1023 {
1024 char *cors_hdr;
1025
1026 GNUNET_asprintf (&cors_hdr,
1027 (HTTPS_PORT == s5r->port)
1028 ? "https://%s"
1029 : "http://%s",
1030 s5r->leho);
1031
1032 GNUNET_break (MHD_YES ==
1033 MHD_add_response_header (s5r->response,
1034 MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
1035 cors_hdr));
1036 GNUNET_free (cors_hdr);
1037 }
1038 /* force connection to be closed after each request, as we
1039 do not support HTTP pipelining (yet, FIXME!) */
1040 /*GNUNET_break (MHD_YES ==
1041 MHD_add_response_header (s5r->response,
1042 MHD_HTTP_HEADER_CONNECTION,
1043 "close"));*/
1044 }
1045 1042
1046 ndup = GNUNET_strndup (buffer, bytes); 1043 ndup = GNUNET_strndup (buffer, bytes);
1047 hdr_type = strtok (ndup, ":"); 1044 hdr_type = strtok (ndup, ":");
@@ -1063,41 +1060,41 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
1063 new_cookie_hdr = NULL; 1060 new_cookie_hdr = NULL;
1064 if ( (NULL != s5r->leho) && 1061 if ( (NULL != s5r->leho) &&
1065 (0 == strcasecmp (hdr_type, 1062 (0 == strcasecmp (hdr_type,
1066 MHD_HTTP_HEADER_SET_COOKIE)) ) 1063 MHD_HTTP_HEADER_SET_COOKIE)) )
1067 1064
1068 { 1065 {
1069 new_cookie_hdr = GNUNET_malloc (strlen (hdr_val) + 1066 new_cookie_hdr = GNUNET_malloc (strlen (hdr_val) +
1070 strlen (s5r->domain) + 1); 1067 strlen (s5r->domain) + 1);
1071 offset = 0; 1068 offset = 0;
1072 domain_matched = GNUNET_NO; /* make sure we match domain at most once */ 1069 domain_matched = GNUNET_NO; /* make sure we match domain at most once */
1073 for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";")) 1070 for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";"))
1074 { 1071 {
1075 if ( (0 == strncasecmp (tok, " domain", strlen (" domain"))) && 1072 if ( (0 == strncasecmp (tok, " domain", strlen (" domain"))) &&
1076 (GNUNET_NO == domain_matched) ) 1073 (GNUNET_NO == domain_matched) )
1077 { 1074 {
1078 domain_matched = GNUNET_YES; 1075 domain_matched = GNUNET_YES;
1079 cookie_domain = tok + strlen (" domain") + 1; 1076 cookie_domain = tok + strlen (" domain") + 1;
1080 if (strlen (cookie_domain) < strlen (s5r->leho)) 1077 if (strlen (cookie_domain) < strlen (s5r->leho))
1081 { 1078 {
1082 delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain); 1079 delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain);
1083 if (0 == strcasecmp (cookie_domain, s5r->leho + delta_cdomain)) 1080 if (0 == strcasecmp (cookie_domain, s5r->leho + delta_cdomain))
1084 { 1081 {
1085 offset += sprintf (new_cookie_hdr + offset, 1082 offset += sprintf (new_cookie_hdr + offset,
1086 " domain=%s;", 1083 " domain=%s;",
1087 s5r->domain); 1084 s5r->domain);
1088 continue; 1085 continue;
1089 } 1086 }
1090 } 1087 }
1091 else if (0 == strcmp (cookie_domain, s5r->leho)) 1088 else if (0 == strcmp (cookie_domain, s5r->leho))
1092 { 1089 {
1093 offset += sprintf (new_cookie_hdr + offset, 1090 offset += sprintf (new_cookie_hdr + offset,
1094 " domain=%s;", 1091 " domain=%s;",
1095 s5r->domain); 1092 s5r->domain);
1096 continue; 1093 continue;
1097 } 1094 }
1098 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1095 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1099 _("Cookie domain `%s' supplied by server is invalid\n"), 1096 _("Cookie domain `%s' supplied by server is invalid\n"),
1100 tok); 1097 tok);
1101 } 1098 }
1102 GNUNET_memcpy (new_cookie_hdr + offset, tok, strlen (tok)); 1099 GNUNET_memcpy (new_cookie_hdr + offset, tok, strlen (tok));
1103 offset += strlen (tok); 1100 offset += strlen (tok);
@@ -1112,21 +1109,21 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
1112 char *leho_host; 1109 char *leho_host;
1113 1110
1114 GNUNET_asprintf (&leho_host, 1111 GNUNET_asprintf (&leho_host,
1115 (HTTPS_PORT != s5r->port) 1112 (HTTPS_PORT != s5r->port)
1116 ? "http://%s" 1113 ? "http://%s"
1117 : "https://%s", 1114 : "https://%s",
1118 s5r->leho); 1115 s5r->leho);
1119 if (0 == strncmp (leho_host, 1116 if (0 == strncmp (leho_host,
1120 hdr_val, 1117 hdr_val,
1121 strlen (leho_host))) 1118 strlen (leho_host)))
1122 { 1119 {
1123 GNUNET_asprintf (&new_location, 1120 GNUNET_asprintf (&new_location,
1124 "%s%s%s", 1121 "%s%s%s",
1125 (HTTPS_PORT != s5r->port) 1122 (HTTPS_PORT != s5r->port)
1126 ? "http://" 1123 ? "http://"
1127 : "https://", 1124 : "https://",
1128 s5r->domain, 1125 s5r->domain,
1129 hdr_val + strlen (leho_host)); 1126 hdr_val + strlen (leho_host));
1130 hdr_val = new_location; 1127 hdr_val = new_location;
1131 } 1128 }
1132 GNUNET_free (leho_host); 1129 GNUNET_free (leho_host);
@@ -1138,17 +1135,18 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
1138 *tok = '\0'; 1135 *tok = '\0';
1139 if (NULL != (tok = strchr (hdr_val, '\t'))) 1136 if (NULL != (tok = strchr (hdr_val, '\t')))
1140 *tok = '\0'; 1137 *tok = '\0';
1141 if ((0 != strlen (hdr_val) ) && 1138 if (0 != strlen (hdr_val)) /* Rely in MHD to set those */
1142 (0 != strcasecmp (MHD_HTTP_HEADER_CONTENT_LENGTH, hdr_type)))
1143 { 1139 {
1144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1140 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1145 "Adding header %s: %s to MHD response\n", 1141 "Adding header %s: %s to MHD response\n",
1146 hdr_type, 1142 hdr_type,
1147 hdr_val); 1143 hdr_val);
1148 GNUNET_break (MHD_YES == 1144 header = GNUNET_new (struct HttpResponseHeader);
1149 MHD_add_response_header (s5r->response, 1145 header->type = GNUNET_strndup (hdr_type, strlen (hdr_type));
1150 hdr_type, 1146 header->value = GNUNET_strndup (hdr_val, strlen (hdr_val));
1151 hdr_val)); 1147 GNUNET_CONTAINER_DLL_insert (s5r->header_head,
1148 s5r->header_tail,
1149 header);
1152 } 1150 }
1153 GNUNET_free (ndup); 1151 GNUNET_free (ndup);
1154 GNUNET_free_non_null (new_cookie_hdr); 1152 GNUNET_free_non_null (new_cookie_hdr);
@@ -1156,6 +1154,69 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
1156 return bytes; 1154 return bytes;
1157} 1155}
1158 1156
1157static int
1158create_mhd_response_from_s5r (struct Socks5Request *s5r)
1159{
1160 long resp_code;
1161 double content_length;
1162 struct HttpResponseHeader *header;
1163
1164 if (NULL != s5r->response)
1165 {
1166 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1167 "Response already set!\n");
1168 return GNUNET_SYSERR;
1169 }
1170
1171 GNUNET_break (CURLE_OK ==
1172 curl_easy_getinfo (s5r->curl,
1173 CURLINFO_RESPONSE_CODE,
1174 &resp_code));
1175 GNUNET_break (CURLE_OK ==
1176 curl_easy_getinfo (s5r->curl,
1177 CURLINFO_CONTENT_LENGTH_DOWNLOAD,
1178 &content_length));
1179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1180 "Creating MHD response with code %d and size %d\n",
1181 (int) resp_code, (int) content_length);
1182 s5r->response_code = resp_code;
1183 s5r->response = MHD_create_response_from_callback ((-1 == content_length) ? MHD_SIZE_UNKNOWN : content_length,
1184 IO_BUFFERSIZE,
1185 &mhd_content_cb,
1186 s5r,
1187 NULL);
1188 for (header = s5r->header_head; NULL != header; header = header->next)
1189 {
1190 GNUNET_break (MHD_YES ==
1191 MHD_add_response_header (s5r->response,
1192 header->type,
1193 header->value));
1194
1195 }
1196 if (NULL != s5r->leho)
1197 {
1198 char *cors_hdr;
1199
1200 GNUNET_asprintf (&cors_hdr,
1201 (HTTPS_PORT == s5r->port)
1202 ? "https://%s"
1203 : "http://%s",
1204 s5r->leho);
1205
1206 GNUNET_break (MHD_YES ==
1207 MHD_add_response_header (s5r->response,
1208 MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
1209 cors_hdr));
1210 GNUNET_free (cors_hdr);
1211 }
1212 /* force connection to be closed after each request, as we
1213 do not support HTTP pipelining (yet, FIXME!) */
1214 /*GNUNET_break (MHD_YES ==
1215 MHD_add_response_header (s5r->response,
1216 MHD_HTTP_HEADER_CONNECTION,
1217 "close"));*/
1218 return GNUNET_OK;
1219}
1159 1220
1160/** 1221/**
1161 * Handle response payload data from cURL. Copies it into our `io_buf` to make 1222 * Handle response payload data from cURL. Copies it into our `io_buf` to make
@@ -1173,6 +1234,9 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx)
1173 struct Socks5Request *s5r = ctx; 1234 struct Socks5Request *s5r = ctx;
1174 size_t total = size * nmemb; 1235 size_t total = size * nmemb;
1175 1236
1237 if (NULL == s5r->response)
1238 GNUNET_assert (GNUNET_OK == create_mhd_response_from_s5r (s5r));
1239
1176 if ( (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) || 1240 if ( (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) ||
1177 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) ) 1241 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) )
1178 { 1242 {
@@ -1180,18 +1244,18 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx)
1180 start the download, the IO buffer is still full 1244 start the download, the IO buffer is still full
1181 with upload data. */ 1245 with upload data. */
1182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1183 "Pausing CURL download, waiting for UPLOAD to finish\n"); 1247 "Pausing CURL download, waiting for UPLOAD to finish\n");
1184 return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */ 1248 return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */
1185 } 1249 }
1186 if (sizeof (s5r->io_buf) - s5r->io_len < total) 1250 if (sizeof (s5r->io_buf) - s5r->io_len < total)
1187 { 1251 {
1188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1189 "Pausing CURL download, not enough space\n"); 1253 "Pausing CURL download, not enough space\n");
1190 return CURL_WRITEFUNC_PAUSE; /* not enough space */ 1254 return CURL_WRITEFUNC_PAUSE; /* not enough space */
1191 } 1255 }
1192 GNUNET_memcpy (&s5r->io_buf[s5r->io_len], 1256 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
1193 ptr, 1257 ptr,
1194 total); 1258 total);
1195 s5r->io_len += total; 1259 s5r->io_len += total;
1196 if (s5r->io_len == total) 1260 if (s5r->io_len == total)
1197 run_mhd_now (s5r->hd); 1261 run_mhd_now (s5r->hd);
@@ -1215,12 +1279,12 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls)
1215 struct Socks5Request *s5r = cls; 1279 struct Socks5Request *s5r = cls;
1216 size_t len = size * nmemb; 1280 size_t len = size * nmemb;
1217 size_t to_copy; 1281 size_t to_copy;
1218 1282
1219 if ( (0 == s5r->io_len) && 1283 if ( (0 == s5r->io_len) &&
1220 (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) ) 1284 (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) )
1221 { 1285 {
1222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1223 "Pausing CURL UPLOAD, need more data\n"); 1287 "Pausing CURL UPLOAD, need more data\n");
1224 return CURL_READFUNC_PAUSE; 1288 return CURL_READFUNC_PAUSE;
1225 } 1289 }
1226 if ( (0 == s5r->io_len) && 1290 if ( (0 == s5r->io_len) &&
@@ -1228,7 +1292,7 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls)
1228 { 1292 {
1229 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1293 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1231 "Completed CURL UPLOAD\n"); 1295 "Completed CURL UPLOAD\n");
1232 return 0; /* upload finished, can now download */ 1296 return 0; /* upload finished, can now download */
1233 } 1297 }
1234 if ( (SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) && 1298 if ( (SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) &&
@@ -1238,11 +1302,11 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls)
1238 return CURL_READFUNC_ABORT; 1302 return CURL_READFUNC_ABORT;
1239 } 1303 }
1240 to_copy = GNUNET_MIN (s5r->io_len, 1304 to_copy = GNUNET_MIN (s5r->io_len,
1241 len); 1305 len);
1242 GNUNET_memcpy (buf, s5r->io_buf, to_copy); 1306 GNUNET_memcpy (buf, s5r->io_buf, to_copy);
1243 memmove (s5r->io_buf, 1307 memmove (s5r->io_buf,
1244 &s5r->io_buf[to_copy], 1308 &s5r->io_buf[to_copy],
1245 s5r->io_len - to_copy); 1309 s5r->io_len - to_copy);
1246 s5r->io_len -= to_copy; 1310 s5r->io_len -= to_copy;
1247 if (s5r->io_len + to_copy == sizeof (s5r->io_buf)) 1311 if (s5r->io_len + to_copy == sizeof (s5r->io_buf))
1248 run_mhd_now (s5r->hd); /* got more space for upload now */ 1312 run_mhd_now (s5r->hd); /* got more space for upload now */
@@ -1309,9 +1373,9 @@ curl_download_prepare ()
1309 GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); 1373 GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
1310 GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); 1374 GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
1311 curl_download_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1375 curl_download_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1312 rtime, 1376 rtime,
1313 grs, gws, 1377 grs, gws,
1314 &curl_task_download, curl_multi); 1378 &curl_task_download, curl_multi);
1315 GNUNET_NETWORK_fdset_destroy (gws); 1379 GNUNET_NETWORK_fdset_destroy (gws);
1316 GNUNET_NETWORK_fdset_destroy (grs); 1380 GNUNET_NETWORK_fdset_destroy (grs);
1317 } 1381 }
@@ -1367,6 +1431,8 @@ curl_task_download (void *cls)
1367 case CURLE_GOT_NOTHING: 1431 case CURLE_GOT_NOTHING:
1368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1369 "CURL download completed.\n"); 1433 "CURL download completed.\n");
1434 if (NULL == s5r->response)
1435 GNUNET_assert (GNUNET_OK == create_mhd_response_from_s5r (s5r));
1370 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; 1436 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1371 run_mhd_now (s5r->hd); 1437 run_mhd_now (s5r->hd);
1372 break; 1438 break;
@@ -1605,8 +1671,8 @@ create_response (void *cls,
1605 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) 1671 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
1606 { 1672 {
1607 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED; 1673 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
1608 curl_easy_setopt (s5r->curl, CURLOPT_POST, 1); 1674 curl_easy_setopt (s5r->curl, CURLOPT_POST, 1L);
1609 curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb); 1675 curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb);
1610 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); 1676 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r);
1611 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); 1677 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb);
1612 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); 1678 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r);
@@ -1654,7 +1720,10 @@ create_response (void *cls,
1654 if (HTTPS_PORT == s5r->port) 1720 if (HTTPS_PORT == s5r->port)
1655 { 1721 {
1656 curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); 1722 curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
1657 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L); 1723 if (NULL != s5r->dane_data)
1724 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 0L);
1725 else
1726 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L);
1658 /* Disable cURL checking the hostname, as we will check ourselves 1727 /* Disable cURL checking the hostname, as we will check ourselves
1659 as only we have the domain name or the LEHO or the DANE record */ 1728 as only we have the domain name or the LEHO or the DANE record */
1660 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L); 1729 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L);
@@ -1686,8 +1755,15 @@ create_response (void *cls,
1686 /* continuing to process request */ 1755 /* continuing to process request */
1687 if (0 != *upload_data_size) 1756 if (0 != *upload_data_size)
1688 { 1757 {
1758
1689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1690 "Processing %lu bytes UPLOAD\n", *upload_data_size); 1760 "Processing %lu bytes UPLOAD\n", *upload_data_size);
1761
1762 /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else
1763 * upload callback is not called!
1764 */
1765 curl_easy_setopt (s5r->curl, CURLOPT_POSTFIELDSIZE, *upload_data_size);
1766
1691 left = GNUNET_MIN (*upload_data_size, 1767 left = GNUNET_MIN (*upload_data_size,
1692 sizeof (s5r->io_buf) - s5r->io_len); 1768 sizeof (s5r->io_buf) - s5r->io_len);
1693 GNUNET_memcpy (&s5r->io_buf[s5r->io_len], 1769 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
@@ -1705,6 +1781,7 @@ create_response (void *cls,
1705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1781 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1706 "Finished processing UPLOAD\n"); 1782 "Finished processing UPLOAD\n");
1707 s5r->state = SOCKS5_SOCKET_UPLOAD_DONE; 1783 s5r->state = SOCKS5_SOCKET_UPLOAD_DONE;
1784 curl_download_prepare ();
1708 } 1785 }
1709 if (NULL == s5r->response) 1786 if (NULL == s5r->response)
1710 return MHD_YES; /* too early to queue response, did not yet get headers from cURL */ 1787 return MHD_YES; /* too early to queue response, did not yet get headers from cURL */
@@ -1736,6 +1813,7 @@ mhd_completed_cb (void *cls,
1736 enum MHD_RequestTerminationCode toe) 1813 enum MHD_RequestTerminationCode toe)
1737{ 1814{
1738 struct Socks5Request *s5r = *con_cls; 1815 struct Socks5Request *s5r = *con_cls;
1816 struct HttpResponseHeader *header;
1739 1817
1740 if (NULL == s5r) 1818 if (NULL == s5r)
1741 return; 1819 return;
@@ -1758,6 +1836,15 @@ mhd_completed_cb (void *cls,
1758 if ( (NULL != s5r->response) && 1836 if ( (NULL != s5r->response) &&
1759 (curl_failure_response != s5r->response) ) 1837 (curl_failure_response != s5r->response) )
1760 MHD_destroy_response (s5r->response); 1838 MHD_destroy_response (s5r->response);
1839 for (header = s5r->header_head; header != NULL; header = s5r->header_head)
1840 {
1841 GNUNET_CONTAINER_DLL_remove (s5r->header_head,
1842 s5r->header_head,
1843 header);
1844 GNUNET_free (header->type);
1845 GNUNET_free (header->value);
1846 GNUNET_free (header);
1847 }
1761 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished request for %s\n", s5r->url); 1848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished request for %s\n", s5r->url);
1762 GNUNET_free (s5r->url); 1849 GNUNET_free (s5r->url);
1763 s5r->state = SOCKS5_SOCKET_WITH_MHD; 1850 s5r->state = SOCKS5_SOCKET_WITH_MHD;
@@ -1786,34 +1873,46 @@ mhd_connection_cb (void *cls,
1786 const union MHD_ConnectionInfo *ci; 1873 const union MHD_ConnectionInfo *ci;
1787 int sock; 1874 int sock;
1788 1875
1789 if (MHD_CONNECTION_NOTIFY_STARTED == cnc) 1876 switch (cnc)
1790 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
1791
1792 if (MHD_CONNECTION_NOTIFY_CLOSED != cnc)
1793 return; //Ignore
1794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection closed... cleaning up\n");
1795
1796 ci = MHD_get_connection_info (connection,
1797 MHD_CONNECTION_INFO_CONNECTION_FD);
1798 if (NULL == ci)
1799 { 1877 {
1800 GNUNET_break (0); 1878 case MHD_CONNECTION_NOTIFY_STARTED:
1801 return; 1879 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
1802 } 1880 ci = MHD_get_connection_info (connection,
1881 MHD_CONNECTION_INFO_CONNECTION_FD);
1882 if (NULL == ci)
1883 {
1884 GNUNET_break (0);
1885 return;
1886 }
1803 1887
1804 sock = ci->connect_fd; 1888 sock = ci->connect_fd;
1805 for (s5r = s5r_head; NULL != s5r; s5r = s5r->next) 1889 for (s5r = s5r_head; NULL != s5r; s5r = s5r->next)
1806 if (GNUNET_NETWORK_get_fd (s5r->sock) == sock) 1890 {
1891 if (GNUNET_NETWORK_get_fd (s5r->sock) == sock)
1892 {
1893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Context set...\n");
1894 *con_cls = s5r;
1895 break;
1896 }
1897 }
1898 if (NULL == s5r)
1899 GNUNET_break (0);
1807 break; 1900 break;
1808 1901 case MHD_CONNECTION_NOTIFY_CLOSED:
1809 if (NULL == s5r) 1902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection closed... cleaning up\n");
1810 { 1903 s5r = *con_cls;
1811 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection stale!\n"); 1904 if (NULL == s5r)
1812 return; 1905 {
1906 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection stale!\n");
1907 return;
1908 }
1909 cleanup_s5r (s5r);
1910 curl_download_prepare ();
1911 *con_cls = NULL;
1912 break;
1913 default:
1914 GNUNET_break (0);
1813 } 1915 }
1814 cleanup_s5r (s5r);
1815 curl_download_prepare ();
1816 *con_cls = NULL;
1817} 1916}
1818 1917
1819/** 1918/**
@@ -1836,36 +1935,27 @@ mhd_log_callback (void *cls,
1836{ 1935{
1837 struct Socks5Request *s5r; 1936 struct Socks5Request *s5r;
1838 const union MHD_ConnectionInfo *ci; 1937 const union MHD_ConnectionInfo *ci;
1839 int sock;
1840 1938
1841 ci = MHD_get_connection_info (connection, 1939 ci = MHD_get_connection_info (connection,
1842 MHD_CONNECTION_INFO_CONNECTION_FD); 1940 MHD_CONNECTION_INFO_SOCKET_CONTEXT);
1843 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); 1941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
1844 if (NULL == ci) 1942 if (NULL == ci)
1845 { 1943 {
1846 GNUNET_break (0); 1944 GNUNET_break (0);
1847 return NULL; 1945 return NULL;
1848 } 1946 }
1849 sock = ci->connect_fd; 1947 s5r = ci->socket_context;
1850 for (s5r = s5r_head; NULL != s5r; s5r = s5r->next) 1948 if (NULL != s5r->url)
1851 { 1949 {
1852 if (GNUNET_NETWORK_get_fd (s5r->sock) == sock) 1950 GNUNET_break (0);
1853 { 1951 return NULL;
1854 if (NULL != s5r->url)
1855 {
1856 GNUNET_break (0);
1857 return NULL;
1858 }
1859 s5r->url = GNUNET_strdup (url);
1860 if (NULL != s5r->timeout_task)
1861 GNUNET_SCHEDULER_cancel (s5r->timeout_task);
1862 s5r->timeout_task = NULL;
1863 GNUNET_assert (s5r->state == SOCKS5_SOCKET_WITH_MHD);
1864 return s5r;
1865 }
1866 } 1952 }
1867 GNUNET_break (0); 1953 s5r->url = GNUNET_strdup (url);
1868 return NULL; 1954 if (NULL != s5r->timeout_task)
1955 GNUNET_SCHEDULER_cancel (s5r->timeout_task);
1956 s5r->timeout_task = NULL;
1957 GNUNET_assert (s5r->state == SOCKS5_SOCKET_WITH_MHD);
1958 return s5r;
1869} 1959}
1870 1960
1871 1961