aboutsummaryrefslogtreecommitdiff
path: root/src/gns
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-08-29 09:56:48 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-08-29 09:56:48 +0000
commitaac3c952498f814df3843fb18ffcc11783c763ba (patch)
tree4610708cf003acd11967c45084af399584dd8335 /src/gns
parentcda23f9580da561752aee04753054aa6225af7cf (diff)
downloadgnunet-aac3c952498f814df3843fb18ffcc11783c763ba.tar.gz
gnunet-aac3c952498f814df3843fb18ffcc11783c763ba.zip
- add persistent connections
Diffstat (limited to 'src/gns')
-rw-r--r--src/gns/gnunet-gns-proxy.c1099
1 files changed, 586 insertions, 513 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 2671404a0..e7671c5d5 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -802,6 +802,7 @@ mhd_content_cb (void *cls,
802 { 802 {
803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
804 "Completed MHD download\n"); 804 "Completed MHD download\n");
805 s5r->state = SOCKS5_SOCKET_WITH_MHD;
805 return MHD_CONTENT_READER_END_OF_STREAM; 806 return MHD_CONTENT_READER_END_OF_STREAM;
806 } 807 }
807 GNUNET_memcpy (buf, s5r->io_buf, bytes_to_copy); 808 GNUNET_memcpy (buf, s5r->io_buf, bytes_to_copy);
@@ -1037,10 +1038,10 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
1037 } 1038 }
1038 /* force connection to be closed after each request, as we 1039 /* force connection to be closed after each request, as we
1039 do not support HTTP pipelining (yet, FIXME!) */ 1040 do not support HTTP pipelining (yet, FIXME!) */
1040 GNUNET_break (MHD_YES == 1041 /*GNUNET_break (MHD_YES ==
1041 MHD_add_response_header (s5r->response, 1042 MHD_add_response_header (s5r->response,
1042 MHD_HTTP_HEADER_CONNECTION, 1043 MHD_HTTP_HEADER_CONNECTION,
1043 "close")); 1044 "close"));*/
1044 } 1045 }
1045 1046
1046 ndup = GNUNET_strndup (buffer, bytes); 1047 ndup = GNUNET_strndup (buffer, bytes);
@@ -1345,67 +1346,67 @@ curl_task_download (void *cls)
1345 while (NULL != (msg = curl_multi_info_read (curl_multi, &msgnum))) 1346 while (NULL != (msg = curl_multi_info_read (curl_multi, &msgnum)))
1346 { 1347 {
1347 GNUNET_break (CURLE_OK == 1348 GNUNET_break (CURLE_OK ==
1348 curl_easy_getinfo (msg->easy_handle, 1349 curl_easy_getinfo (msg->easy_handle,
1349 CURLINFO_PRIVATE, 1350 CURLINFO_PRIVATE,
1350 (char **) &s5r )); 1351 (char **) &s5r ));
1351 if (NULL == s5r) 1352 if (NULL == s5r)
1352 { 1353 {
1353 GNUNET_break (0); 1354 GNUNET_break (0);
1354 continue; 1355 continue;
1355 } 1356 }
1356 switch (msg->msg) 1357 switch (msg->msg)
1357 { 1358 {
1358 case CURLMSG_NONE: 1359 case CURLMSG_NONE:
1359 /* documentation says this is not used */ 1360 /* documentation says this is not used */
1360 GNUNET_break (0); 1361 GNUNET_break (0);
1361 break; 1362 break;
1362 case CURLMSG_DONE: 1363 case CURLMSG_DONE:
1363 switch (msg->data.result) 1364 switch (msg->data.result)
1364 { 1365 {
1365 case CURLE_OK: 1366 case CURLE_OK:
1366 case CURLE_GOT_NOTHING: 1367 case CURLE_GOT_NOTHING:
1367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1368 "CURL download completed.\n"); 1369 "CURL download completed.\n");
1369 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; 1370 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1370 run_mhd_now (s5r->hd); 1371 run_mhd_now (s5r->hd);
1371 break; 1372 break;
1372 default: 1373 default:
1373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1374 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1374 "Download curl failed: %s\n", 1375 "Download curl failed: %s\n",
1375 curl_easy_strerror (msg->data.result)); 1376 curl_easy_strerror (msg->data.result));
1376 /* FIXME: indicate error somehow? close MHD connection badly as well? */ 1377 /* FIXME: indicate error somehow? close MHD connection badly as well? */
1377 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; 1378 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1378 run_mhd_now (s5r->hd); 1379 run_mhd_now (s5r->hd);
1379 break; 1380 break;
1380 } 1381 }
1381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1382 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1382 "Cleaning up cURL handle\n"); 1383 "Cleaning up cURL handle\n");
1383 curl_multi_remove_handle (curl_multi, s5r->curl); 1384 curl_multi_remove_handle (curl_multi, s5r->curl);
1384 curl_easy_cleanup (s5r->curl); 1385 curl_easy_cleanup (s5r->curl);
1385 s5r->curl = NULL; 1386 s5r->curl = NULL;
1386 if (NULL == s5r->response) 1387 if (NULL == s5r->response)
1387 s5r->response = curl_failure_response; 1388 s5r->response = curl_failure_response;
1388 break; 1389 break;
1389 case CURLMSG_LAST: 1390 case CURLMSG_LAST:
1390 /* documentation says this is not used */ 1391 /* documentation says this is not used */
1391 GNUNET_break (0); 1392 GNUNET_break (0);
1392 break; 1393 break;
1393 default: 1394 default:
1394 /* unexpected status code */ 1395 /* unexpected status code */
1395 GNUNET_break (0); 1396 GNUNET_break (0);
1396 break; 1397 break;
1397 } 1398 }
1398 }; 1399 };
1399 } while (mret == CURLM_CALL_MULTI_PERFORM); 1400 } while (mret == CURLM_CALL_MULTI_PERFORM);
1400 if (CURLM_OK != mret) 1401 if (CURLM_OK != mret)
1401 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1402 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1402 "%s failed at %s:%d: `%s'\n", 1403 "%s failed at %s:%d: `%s'\n",
1403 "curl_multi_perform", __FILE__, __LINE__, 1404 "curl_multi_perform", __FILE__, __LINE__,
1404 curl_multi_strerror (mret)); 1405 curl_multi_strerror (mret));
1405 if (0 == running) 1406 if (0 == running)
1406 { 1407 {
1407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1408 "Suspending cURL multi loop, no more events pending\n"); 1409 "Suspending cURL multi loop, no more events pending\n");
1409 return; /* nothing more in progress */ 1410 return; /* nothing more in progress */
1410 } 1411 }
1411 curl_download_prepare (); 1412 curl_download_prepare ();
@@ -1440,17 +1441,17 @@ con_val_iter (void *cls,
1440 if ( (0 == strcasecmp (MHD_HTTP_HEADER_HOST, key)) && 1441 if ( (0 == strcasecmp (MHD_HTTP_HEADER_HOST, key)) &&
1441 (NULL != s5r->leho) ) 1442 (NULL != s5r->leho) )
1442 value = s5r->leho; 1443 value = s5r->leho;
1443 if (0 == strcasecmp (MHD_HTTP_HEADER_CONNECTION, key)) 1444 /*if (0 == strcasecmp (MHD_HTTP_HEADER_CONNECTION, key))
1444 value = "Close"; 1445 value = "Close";*/
1445 GNUNET_asprintf (&hdr, 1446 GNUNET_asprintf (&hdr,
1446 "%s: %s", 1447 "%s: %s",
1447 key, 1448 key,
1448 value); 1449 value);
1449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1450 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1450 "Adding HEADER `%s' to HTTP request\n", 1451 "Adding HEADER `%s' to HTTP request\n",
1451 hdr); 1452 hdr);
1452 s5r->headers = curl_slist_append (s5r->headers, 1453 s5r->headers = curl_slist_append (s5r->headers,
1453 hdr); 1454 hdr);
1454 GNUNET_free (hdr); 1455 GNUNET_free (hdr);
1455 return MHD_YES; 1456 return MHD_YES;
1456} 1457}
@@ -1505,54 +1506,55 @@ create_response (void *cls,
1505 GNUNET_break (0); 1506 GNUNET_break (0);
1506 return MHD_NO; 1507 return MHD_NO;
1507 } 1508 }
1508 if ( (NULL == s5r->curl) && 1509 //Fresh connection. Maybe move to notify callback??
1509 (SOCKS5_SOCKET_WITH_MHD == s5r->state) ) 1510 if (SOCKS5_SOCKET_WITH_MHD == s5r->state)
1510 { 1511 {
1511 /* first time here, initialize curl handle */ 1512 /* first time here, initialize curl handle */
1512 sa = (const struct sockaddr *) &s5r->destination_address; 1513 sa = (const struct sockaddr *) &s5r->destination_address;
1513 switch (sa->sa_family) 1514 switch (sa->sa_family)
1514 { 1515 {
1515 case AF_INET: 1516 case AF_INET:
1516 s4 = (const struct sockaddr_in *) &s5r->destination_address; 1517 s4 = (const struct sockaddr_in *) &s5r->destination_address;
1517 if (NULL == inet_ntop (AF_INET, 1518 if (NULL == inet_ntop (AF_INET,
1518 &s4->sin_addr, 1519 &s4->sin_addr,
1519 ipstring, 1520 ipstring,
1520 sizeof (ipstring))) 1521 sizeof (ipstring)))
1521 { 1522 {
1522 GNUNET_break (0); 1523 GNUNET_break (0);
1523 return MHD_NO; 1524 return MHD_NO;
1524 } 1525 }
1525 GNUNET_snprintf (ipaddr, 1526 GNUNET_snprintf (ipaddr,
1526 sizeof (ipaddr), 1527 sizeof (ipaddr),
1527 "%s", 1528 "%s",
1528 ipstring); 1529 ipstring);
1529 port = ntohs (s4->sin_port); 1530 port = ntohs (s4->sin_port);
1530 break; 1531 break;
1531 case AF_INET6: 1532 case AF_INET6:
1532 s6 = (const struct sockaddr_in6 *) &s5r->destination_address; 1533 s6 = (const struct sockaddr_in6 *) &s5r->destination_address;
1533 if (NULL == inet_ntop (AF_INET6, 1534 if (NULL == inet_ntop (AF_INET6,
1534 &s6->sin6_addr, 1535 &s6->sin6_addr,
1535 ipstring, 1536 ipstring,
1536 sizeof (ipstring))) 1537 sizeof (ipstring)))
1537 { 1538 {
1538 GNUNET_break (0); 1539 GNUNET_break (0);
1539 return MHD_NO; 1540 return MHD_NO;
1540 } 1541 }
1541 GNUNET_snprintf (ipaddr, 1542 GNUNET_snprintf (ipaddr,
1542 sizeof (ipaddr), 1543 sizeof (ipaddr),
1543 "[%s]", 1544 "[%s]",
1544 ipstring); 1545 ipstring);
1545 port = ntohs (s6->sin6_port); 1546 port = ntohs (s6->sin6_port);
1546 break; 1547 break;
1547 default: 1548 default:
1548 GNUNET_break (0); 1549 GNUNET_break (0);
1549 return MHD_NO; 1550 return MHD_NO;
1550 } 1551 }
1551 s5r->curl = curl_easy_init (); 1552 if (NULL == s5r->curl)
1553 s5r->curl = curl_easy_init ();
1552 if (NULL == s5r->curl) 1554 if (NULL == s5r->curl)
1553 return MHD_queue_response (con, 1555 return MHD_queue_response (con,
1554 MHD_HTTP_INTERNAL_SERVER_ERROR, 1556 MHD_HTTP_INTERNAL_SERVER_ERROR,
1555 curl_failure_response); 1557 curl_failure_response);
1556 curl_easy_setopt (s5r->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr); 1558 curl_easy_setopt (s5r->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr);
1557 curl_easy_setopt (s5r->curl, CURLOPT_HEADERDATA, s5r); 1559 curl_easy_setopt (s5r->curl, CURLOPT_HEADERDATA, s5r);
1558 curl_easy_setopt (s5r->curl, CURLOPT_FOLLOWLOCATION, 0); 1560 curl_easy_setopt (s5r->curl, CURLOPT_FOLLOWLOCATION, 0);
@@ -1572,29 +1574,28 @@ create_response (void *cls,
1572 */ 1574 */
1573 if (NULL != s5r->leho) 1575 if (NULL != s5r->leho)
1574 { 1576 {
1575 GNUNET_asprintf (&curl_hosts, 1577 GNUNET_asprintf (&curl_hosts,
1576 "%s:%d:%s", 1578 "%s:%d:%s",
1577 s5r->leho, 1579 s5r->leho,
1578 port, 1580 port,
1579 ipaddr); 1581 ipaddr);
1580 s5r->hosts = curl_slist_append(NULL, curl_hosts); 1582 s5r->hosts = curl_slist_append(NULL, curl_hosts);
1581 curl_easy_setopt(s5r->curl, CURLOPT_RESOLVE, s5r->hosts); 1583 curl_easy_setopt(s5r->curl, CURLOPT_RESOLVE, s5r->hosts);
1582 GNUNET_free (curl_hosts); 1584 GNUNET_free (curl_hosts);
1583 } 1585 }
1584 GNUNET_asprintf (&curlurl, 1586 GNUNET_asprintf (&curlurl,
1585 (HTTPS_PORT != s5r->port) 1587 (HTTPS_PORT != s5r->port)
1586 ? "http://%s:%d%s" 1588 ? "http://%s:%d%s"
1587 : "https://%s:%d%s", 1589 : "https://%s:%d%s",
1588 (NULL != s5r->leho) 1590 (NULL != s5r->leho)
1589 ? s5r->leho 1591 ? s5r->leho
1590 : ipaddr, 1592 : ipaddr,
1591 port, 1593 port,
1592 s5r->url); 1594 s5r->url);
1593 curl_easy_setopt (s5r->curl, 1595 curl_easy_setopt (s5r->curl,
1594 CURLOPT_URL, 1596 CURLOPT_URL,
1595 curlurl); 1597 curlurl);
1596 GNUNET_free (curlurl); 1598 GNUNET_free (curlurl);
1597
1598 if (0 == strcasecmp (meth, MHD_HTTP_METHOD_PUT)) 1599 if (0 == strcasecmp (meth, MHD_HTTP_METHOD_PUT))
1599 { 1600 {
1600 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED; 1601 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
@@ -1618,6 +1619,11 @@ create_response (void *cls,
1618 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1619 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1619 curl_easy_setopt (s5r->curl, CURLOPT_NOBODY, 1); 1620 curl_easy_setopt (s5r->curl, CURLOPT_NOBODY, 1);
1620 } 1621 }
1622 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_OPTIONS))
1623 {
1624 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1625 curl_easy_setopt (s5r->curl, CURLOPT_CUSTOMREQUEST, "OPTIONS");
1626 }
1621 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_GET)) 1627 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_GET))
1622 { 1628 {
1623 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1629 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
@@ -1628,8 +1634,8 @@ create_response (void *cls,
1628 else 1634 else
1629 { 1635 {
1630 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1636 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1631 _("Unsupported HTTP method `%s'\n"), 1637 _("Unsupported HTTP method `%s'\n"),
1632 meth); 1638 meth);
1633 curl_easy_cleanup (s5r->curl); 1639 curl_easy_cleanup (s5r->curl);
1634 s5r->curl = NULL; 1640 s5r->curl = NULL;
1635 return MHD_NO; 1641 return MHD_NO;
@@ -1653,7 +1659,7 @@ create_response (void *cls,
1653 curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); 1659 curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
1654 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L); 1660 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L);
1655 /* Disable cURL checking the hostname, as we will check ourselves 1661 /* Disable cURL checking the hostname, as we will check ourselves
1656 as only we have the domain name or the LEHO or the DANE record */ 1662 as only we have the domain name or the LEHO or the DANE record */
1657 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L); 1663 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L);
1658 } 1664 }
1659 else 1665 else
@@ -1669,8 +1675,11 @@ create_response (void *cls,
1669 return MHD_NO; 1675 return MHD_NO;
1670 } 1676 }
1671 MHD_get_connection_values (con, 1677 MHD_get_connection_values (con,
1672 MHD_HEADER_KIND, 1678 MHD_HEADER_KIND,
1673 &con_val_iter, s5r); 1679 &con_val_iter, s5r);
1680 //TODO is this sane?
1681 s5r->headers = curl_slist_append (s5r->headers,
1682 "Expect:");
1674 curl_easy_setopt (s5r->curl, CURLOPT_HTTPHEADER, s5r->headers); 1683 curl_easy_setopt (s5r->curl, CURLOPT_HTTPHEADER, s5r->headers);
1675 curl_download_prepare (); 1684 curl_download_prepare ();
1676 return MHD_YES; 1685 return MHD_YES;
@@ -1679,11 +1688,13 @@ create_response (void *cls,
1679 /* continuing to process request */ 1688 /* continuing to process request */
1680 if (0 != *upload_data_size) 1689 if (0 != *upload_data_size)
1681 { 1690 {
1691 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1692 "Processing %lu bytes UPLOAD\n", *upload_data_size);
1682 left = GNUNET_MIN (*upload_data_size, 1693 left = GNUNET_MIN (*upload_data_size,
1683 sizeof (s5r->io_buf) - s5r->io_len); 1694 sizeof (s5r->io_buf) - s5r->io_len);
1684 GNUNET_memcpy (&s5r->io_buf[s5r->io_len], 1695 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
1685 upload_data, 1696 upload_data,
1686 left); 1697 left);
1687 s5r->io_len += left; 1698 s5r->io_len += left;
1688 *upload_data_size -= left; 1699 *upload_data_size -= left;
1689 GNUNET_assert (NULL != s5r->curl); 1700 GNUNET_assert (NULL != s5r->curl);
@@ -1693,17 +1704,18 @@ create_response (void *cls,
1693 } 1704 }
1694 if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) 1705 if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state)
1695 { 1706 {
1696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1707 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1697 "Finished processing UPLOAD\n"); 1708 "Finished processing UPLOAD\n");
1698 s5r->state = SOCKS5_SOCKET_UPLOAD_DONE; 1709 s5r->state = SOCKS5_SOCKET_UPLOAD_DONE;
1699 } 1710 }
1700 if (NULL == s5r->response) 1711 if (NULL == s5r->response)
1701 return MHD_YES; /* too early to queue response, did not yet get headers from cURL */ 1712 return MHD_YES; /* too early to queue response, did not yet get headers from cURL */
1702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1713 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1703 "Queueing response with MHD\n"); 1714 "Queueing response with MHD\n");
1715 run_mhd_now (s5r->hd);
1704 return MHD_queue_response (con, 1716 return MHD_queue_response (con,
1705 s5r->response_code, 1717 s5r->response_code,
1706 s5r->response); 1718 s5r->response);
1707} 1719}
1708 1720
1709 1721
@@ -1711,7 +1723,7 @@ create_response (void *cls,
1711 1723
1712 1724
1713/** 1725/**
1714 * Function called when MHD decides that we are done with a connection. 1726 * Function called when MHD decides that we are done with a request.
1715 * 1727 *
1716 * @param cls NULL 1728 * @param cls NULL
1717 * @param connection connection handle 1729 * @param connection connection handle
@@ -1721,9 +1733,9 @@ create_response (void *cls,
1721 */ 1733 */
1722static void 1734static void
1723mhd_completed_cb (void *cls, 1735mhd_completed_cb (void *cls,
1724 struct MHD_Connection *connection, 1736 struct MHD_Connection *connection,
1725 void **con_cls, 1737 void **con_cls,
1726 enum MHD_RequestTerminationCode toe) 1738 enum MHD_RequestTerminationCode toe)
1727{ 1739{
1728 struct Socks5Request *s5r = *con_cls; 1740 struct Socks5Request *s5r = *con_cls;
1729 1741
@@ -1731,15 +1743,74 @@ mhd_completed_cb (void *cls,
1731 return; 1743 return;
1732 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) 1744 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
1733 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1745 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1734 "MHD encountered error handling request: %d\n", 1746 "MHD encountered error handling request: %d\n",
1735 toe); 1747 toe);
1736 cleanup_s5r (s5r); 1748 if (NULL != s5r->curl)
1749 {
1750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1751 "Cleaning up cURL handle\n");
1752 curl_multi_remove_handle (curl_multi, s5r->curl);
1753 curl_easy_cleanup (s5r->curl);
1754 s5r->curl = NULL;
1755 }
1756 if ( (NULL != s5r->response) &&
1757 (curl_failure_response != s5r->response) )
1758 MHD_destroy_response (s5r->response);
1759 s5r->response = NULL;
1737 curl_download_prepare(); 1760 curl_download_prepare();
1738 *con_cls = NULL; 1761 *con_cls = NULL;
1739} 1762}
1740 1763
1741 1764
1742/** 1765/**
1766 * Function called when MHD connection is opened or closed.
1767 *
1768 * @param cls NULL
1769 * @param connection connection handle
1770 * @param con_cls value as set by the last call to
1771 * the MHD_AccessHandlerCallback, should be our `struct Socks5Request *`
1772 * @param toe connection notification type
1773 */
1774static void
1775mhd_connection_cb (void *cls,
1776 struct MHD_Connection *connection,
1777 void **con_cls,
1778 enum MHD_ConnectionNotificationCode cnc)
1779{
1780 struct Socks5Request *s5r;
1781 const union MHD_ConnectionInfo *ci;
1782 int sock;
1783
1784 if (MHD_CONNECTION_NOTIFY_STARTED == cnc)
1785 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection started...\n");
1786
1787 if (MHD_CONNECTION_NOTIFY_CLOSED != cnc)
1788 return; //Ignore
1789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection closed... cleaning up\n");
1790
1791 ci = MHD_get_connection_info (connection,
1792 MHD_CONNECTION_INFO_CONNECTION_FD);
1793 if (NULL == ci)
1794 {
1795 GNUNET_break (0);
1796 return;
1797 }
1798
1799 sock = ci->connect_fd;
1800 for (s5r = s5r_head; NULL != s5r; s5r = s5r->next)
1801 if (GNUNET_NETWORK_get_fd (s5r->sock) == sock)
1802 break;
1803
1804 if (NULL == s5r)
1805 {
1806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection stale!\n");
1807 return;
1808 }
1809 cleanup_s5r (s5r);
1810 *con_cls = NULL;
1811}
1812
1813/**
1743 * Function called when MHD first processes an incoming connection. 1814 * Function called when MHD first processes an incoming connection.
1744 * Gives us the respective URI information. 1815 * Gives us the respective URI information.
1745 * 1816 *
@@ -1754,15 +1825,15 @@ mhd_completed_cb (void *cls,
1754 */ 1825 */
1755static void * 1826static void *
1756mhd_log_callback (void *cls, 1827mhd_log_callback (void *cls,
1757 const char *url, 1828 const char *url,
1758 struct MHD_Connection *connection) 1829 struct MHD_Connection *connection)
1759{ 1830{
1760 struct Socks5Request *s5r; 1831 struct Socks5Request *s5r;
1761 const union MHD_ConnectionInfo *ci; 1832 const union MHD_ConnectionInfo *ci;
1762 int sock; 1833 int sock;
1763 1834
1764 ci = MHD_get_connection_info (connection, 1835 ci = MHD_get_connection_info (connection,
1765 MHD_CONNECTION_INFO_CONNECTION_FD); 1836 MHD_CONNECTION_INFO_CONNECTION_FD);
1766 if (NULL == ci) 1837 if (NULL == ci)
1767 { 1838 {
1768 GNUNET_break (0); 1839 GNUNET_break (0);
@@ -1775,8 +1846,8 @@ mhd_log_callback (void *cls,
1775 { 1846 {
1776 if (NULL != s5r->url) 1847 if (NULL != s5r->url)
1777 { 1848 {
1778 GNUNET_break (0); 1849 GNUNET_break (0);
1779 return NULL; 1850 return NULL;
1780 } 1851 }
1781 s5r->url = GNUNET_strdup (url); 1852 s5r->url = GNUNET_strdup (url);
1782 GNUNET_SCHEDULER_cancel (s5r->timeout_task); 1853 GNUNET_SCHEDULER_cancel (s5r->timeout_task);
@@ -1798,8 +1869,8 @@ static void
1798kill_httpd (struct MhdHttpList *hd) 1869kill_httpd (struct MhdHttpList *hd)
1799{ 1870{
1800 GNUNET_CONTAINER_DLL_remove (mhd_httpd_head, 1871 GNUNET_CONTAINER_DLL_remove (mhd_httpd_head,
1801 mhd_httpd_tail, 1872 mhd_httpd_tail,
1802 hd); 1873 hd);
1803 GNUNET_free_non_null (hd->domain); 1874 GNUNET_free_non_null (hd->domain);
1804 MHD_stop_daemon (hd->daemon); 1875 MHD_stop_daemon (hd->daemon);
1805 if (NULL != hd->httpd_task) 1876 if (NULL != hd->httpd_task)
@@ -1892,15 +1963,15 @@ schedule_httpd (struct MhdHttpList *hd)
1892 { 1963 {
1893 /* daemon is idle, kill after timeout */ 1964 /* daemon is idle, kill after timeout */
1894 hd->httpd_task = GNUNET_SCHEDULER_add_delayed (MHD_CACHE_TIMEOUT, 1965 hd->httpd_task = GNUNET_SCHEDULER_add_delayed (MHD_CACHE_TIMEOUT,
1895 &kill_httpd_task, 1966 &kill_httpd_task,
1896 hd); 1967 hd);
1897 } 1968 }
1898 else 1969 else
1899 { 1970 {
1900 hd->httpd_task = 1971 hd->httpd_task =
1901 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1972 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1902 tv, wrs, wws, 1973 tv, wrs, wws,
1903 &do_httpd, hd); 1974 &do_httpd, hd);
1904 } 1975 }
1905 if (NULL != wrs) 1976 if (NULL != wrs)
1906 GNUNET_NETWORK_fdset_destroy (wrs); 1977 GNUNET_NETWORK_fdset_destroy (wrs);
@@ -1937,7 +2008,7 @@ run_mhd_now (struct MhdHttpList *hd)
1937 hd->httpd_task) 2008 hd->httpd_task)
1938 GNUNET_SCHEDULER_cancel (hd->httpd_task); 2009 GNUNET_SCHEDULER_cancel (hd->httpd_task);
1939 hd->httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd, 2010 hd->httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd,
1940 hd); 2011 hd);
1941} 2012}
1942 2013
1943 2014
@@ -1950,14 +2021,14 @@ run_mhd_now (struct MhdHttpList *hd)
1950 */ 2021 */
1951static void* 2022static void*
1952load_file (const char* filename, 2023load_file (const char* filename,
1953 unsigned int* size) 2024 unsigned int* size)
1954{ 2025{
1955 void *buffer; 2026 void *buffer;
1956 uint64_t fsize; 2027 uint64_t fsize;
1957 2028
1958 if (GNUNET_OK != 2029 if (GNUNET_OK !=
1959 GNUNET_DISK_file_size (filename, &fsize, 2030 GNUNET_DISK_file_size (filename, &fsize,
1960 GNUNET_YES, GNUNET_YES)) 2031 GNUNET_YES, GNUNET_YES))
1961 return NULL; 2032 return NULL;
1962 if (fsize > MAX_PEM_SIZE) 2033 if (fsize > MAX_PEM_SIZE)
1963 return NULL; 2034 return NULL;
@@ -1981,7 +2052,7 @@ load_file (const char* filename,
1981 */ 2052 */
1982static int 2053static int
1983load_key_from_file (gnutls_x509_privkey_t key, 2054load_key_from_file (gnutls_x509_privkey_t key,
1984 const char* keyfile) 2055 const char* keyfile)
1985{ 2056{
1986 gnutls_datum_t key_data; 2057 gnutls_datum_t key_data;
1987 int ret; 2058 int ret;
@@ -1995,7 +2066,7 @@ load_key_from_file (gnutls_x509_privkey_t key,
1995 { 2066 {
1996 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2067 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1997 _("Unable to import private key from file `%s'\n"), 2068 _("Unable to import private key from file `%s'\n"),
1998 keyfile); 2069 keyfile);
1999 } 2070 }
2000 GNUNET_free_non_null (key_data.data); 2071 GNUNET_free_non_null (key_data.data);
2001 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK; 2072 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK;
@@ -2011,7 +2082,7 @@ load_key_from_file (gnutls_x509_privkey_t key,
2011 */ 2082 */
2012static int 2083static int
2013load_cert_from_file (gnutls_x509_crt_t crt, 2084load_cert_from_file (gnutls_x509_crt_t crt,
2014 const char* certfile) 2085 const char* certfile)
2015{ 2086{
2016 gnutls_datum_t cert_data; 2087 gnutls_datum_t cert_data;
2017 int ret; 2088 int ret;
@@ -2024,7 +2095,7 @@ load_cert_from_file (gnutls_x509_crt_t crt,
2024 if (GNUTLS_E_SUCCESS != ret) 2095 if (GNUTLS_E_SUCCESS != ret)
2025 { 2096 {
2026 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2097 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2027 _("Unable to import certificate %s\n"), certfile); 2098 _("Unable to import certificate %s\n"), certfile);
2028 } 2099 }
2029 GNUNET_free_non_null (cert_data.data); 2100 GNUNET_free_non_null (cert_data.data);
2030 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK; 2101 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK;
@@ -2049,8 +2120,8 @@ generate_gns_certificate (const char *name)
2049 struct ProxyGNSCertificate *pgc; 2120 struct ProxyGNSCertificate *pgc;
2050 2121
2051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2052 "Generating TLS/SSL certificate for `%s'\n", 2123 "Generating TLS/SSL certificate for `%s'\n",
2053 name); 2124 name);
2054 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_init (&request)); 2125 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_init (&request));
2055 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_key (request, proxy_ca.key)); 2126 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_key (request, proxy_ca.key));
2056 pgc = GNUNET_new (struct ProxyGNSCertificate); 2127 pgc = GNUNET_new (struct ProxyGNSCertificate);
@@ -2063,25 +2134,25 @@ generate_gns_certificate (const char *name)
2063 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_version (request, 3)); 2134 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_version (request, 3));
2064 gnutls_rnd (GNUTLS_RND_NONCE, &serial, sizeof (serial)); 2135 gnutls_rnd (GNUTLS_RND_NONCE, &serial, sizeof (serial));
2065 gnutls_x509_crt_set_serial (request, 2136 gnutls_x509_crt_set_serial (request,
2066 &serial, 2137 &serial,
2067 sizeof (serial)); 2138 sizeof (serial));
2068 etime = time (NULL); 2139 etime = time (NULL);
2069 tm_data = localtime (&etime); 2140 tm_data = localtime (&etime);
2070 gnutls_x509_crt_set_activation_time (request, 2141 gnutls_x509_crt_set_activation_time (request,
2071 etime); 2142 etime);
2072 tm_data->tm_year++; 2143 tm_data->tm_year++;
2073 etime = mktime (tm_data); 2144 etime = mktime (tm_data);
2074 gnutls_x509_crt_set_expiration_time (request, 2145 gnutls_x509_crt_set_expiration_time (request,
2075 etime); 2146 etime);
2076 gnutls_x509_crt_sign (request, 2147 gnutls_x509_crt_sign (request,
2077 proxy_ca.cert, 2148 proxy_ca.cert,
2078 proxy_ca.key); 2149 proxy_ca.key);
2079 key_buf_size = sizeof (pgc->key); 2150 key_buf_size = sizeof (pgc->key);
2080 cert_buf_size = sizeof (pgc->cert); 2151 cert_buf_size = sizeof (pgc->cert);
2081 gnutls_x509_crt_export (request, GNUTLS_X509_FMT_PEM, 2152 gnutls_x509_crt_export (request, GNUTLS_X509_FMT_PEM,
2082 pgc->cert, &cert_buf_size); 2153 pgc->cert, &cert_buf_size);
2083 gnutls_x509_privkey_export (proxy_ca.key, GNUTLS_X509_FMT_PEM, 2154 gnutls_x509_privkey_export (proxy_ca.key, GNUTLS_X509_FMT_PEM,
2084 pgc->key, &key_buf_size); 2155 pgc->key, &key_buf_size);
2085 gnutls_x509_crt_deinit (request); 2156 gnutls_x509_crt_deinit (request);
2086 return pgc; 2157 return pgc;
2087} 2158}
@@ -2122,27 +2193,28 @@ lookup_ssl_httpd (const char* domain)
2122 } 2193 }
2123 for (hd = mhd_httpd_head; NULL != hd; hd = hd->next) 2194 for (hd = mhd_httpd_head; NULL != hd; hd = hd->next)
2124 if ( (NULL != hd->domain) && 2195 if ( (NULL != hd->domain) &&
2125 (0 == strcmp (hd->domain, domain)) ) 2196 (0 == strcmp (hd->domain, domain)) )
2126 return hd; 2197 return hd;
2127 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2128 "Starting fresh MHD HTTPS instance for domain `%s'\n", 2199 "Starting fresh MHD HTTPS instance for domain `%s'\n",
2129 domain); 2200 domain);
2130 pgc = generate_gns_certificate (domain); 2201 pgc = generate_gns_certificate (domain);
2131 hd = GNUNET_new (struct MhdHttpList); 2202 hd = GNUNET_new (struct MhdHttpList);
2132 hd->is_ssl = GNUNET_YES; 2203 hd->is_ssl = GNUNET_YES;
2133 hd->domain = GNUNET_strdup (domain); 2204 hd->domain = GNUNET_strdup (domain);
2134 hd->proxy_cert = pgc; 2205 hd->proxy_cert = pgc;
2135 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_NO_LISTEN_SOCKET, 2206 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_NO_LISTEN_SOCKET,
2136 0, 2207 0,
2137 NULL, NULL, 2208 NULL, NULL,
2138 &create_response, hd, 2209 &create_response, hd,
2139 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, 2210 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
2140 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL, 2211 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL,
2141 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL, 2212 MHD_OPTION_NOTIFY_CONNECTION, &mhd_connection_cb, NULL,
2213 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
2142 MHD_OPTION_EXTERNAL_LOGGER, &mhd_error_log_callback, NULL, 2214 MHD_OPTION_EXTERNAL_LOGGER, &mhd_error_log_callback, NULL,
2143 MHD_OPTION_HTTPS_MEM_KEY, pgc->key, 2215 MHD_OPTION_HTTPS_MEM_KEY, pgc->key,
2144 MHD_OPTION_HTTPS_MEM_CERT, pgc->cert, 2216 MHD_OPTION_HTTPS_MEM_CERT, pgc->cert,
2145 MHD_OPTION_END); 2217 MHD_OPTION_END);
2146 if (NULL == hd->daemon) 2218 if (NULL == hd->daemon)
2147 { 2219 {
2148 GNUNET_free (pgc); 2220 GNUNET_free (pgc);
@@ -2150,8 +2222,8 @@ lookup_ssl_httpd (const char* domain)
2150 return NULL; 2222 return NULL;
2151 } 2223 }
2152 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, 2224 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head,
2153 mhd_httpd_tail, 2225 mhd_httpd_tail,
2154 hd); 2226 hd);
2155 return hd; 2227 return hd;
2156} 2228}
2157 2229
@@ -2191,22 +2263,22 @@ setup_data_transfer (struct Socks5Request *s5r)
2191 2263
2192 switch (s5r->port) 2264 switch (s5r->port)
2193 { 2265 {
2194 case HTTPS_PORT: 2266 case HTTPS_PORT:
2195 hd = lookup_ssl_httpd (s5r->domain); 2267 hd = lookup_ssl_httpd (s5r->domain);
2196 if (NULL == hd) 2268 if (NULL == hd)
2197 { 2269 {
2198 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2270 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2199 _("Failed to start HTTPS server for `%s'\n"), 2271 _("Failed to start HTTPS server for `%s'\n"),
2200 s5r->domain); 2272 s5r->domain);
2201 cleanup_s5r (s5r); 2273 cleanup_s5r (s5r);
2202 return; 2274 return;
2203 } 2275 }
2204 break; 2276 break;
2205 case HTTP_PORT: 2277 case HTTP_PORT:
2206 default: 2278 default:
2207 GNUNET_assert (NULL != httpd); 2279 GNUNET_assert (NULL != httpd);
2208 hd = httpd; 2280 hd = httpd;
2209 break; 2281 break;
2210 } 2282 }
2211 fd = GNUNET_NETWORK_get_fd (s5r->sock); 2283 fd = GNUNET_NETWORK_get_fd (s5r->sock);
2212 addr = GNUNET_NETWORK_get_addr (s5r->sock); 2284 addr = GNUNET_NETWORK_get_addr (s5r->sock);
@@ -2215,15 +2287,15 @@ setup_data_transfer (struct Socks5Request *s5r)
2215 if (MHD_YES != MHD_add_connection (hd->daemon, fd, addr, len)) 2287 if (MHD_YES != MHD_add_connection (hd->daemon, fd, addr, len))
2216 { 2288 {
2217 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2289 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2218 _("Failed to pass client to MHD\n")); 2290 _("Failed to pass client to MHD\n"));
2219 cleanup_s5r (s5r); 2291 cleanup_s5r (s5r);
2220 return; 2292 return;
2221 } 2293 }
2222 s5r->hd = hd; 2294 s5r->hd = hd;
2223 schedule_httpd (hd); 2295 schedule_httpd (hd);
2224 s5r->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_HANDSHAKE_TIMEOUT, 2296 s5r->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_HANDSHAKE_TIMEOUT,
2225 &timeout_s5r_handshake, 2297 &timeout_s5r_handshake,
2226 s5r); 2298 s5r);
2227} 2299}
2228 2300
2229 2301
@@ -2243,8 +2315,8 @@ do_write (void *cls)
2243 2315
2244 s5r->wtask = NULL; 2316 s5r->wtask = NULL;
2245 len = GNUNET_NETWORK_socket_send (s5r->sock, 2317 len = GNUNET_NETWORK_socket_send (s5r->sock,
2246 s5r->wbuf, 2318 s5r->wbuf,
2247 s5r->wbuf_len); 2319 s5r->wbuf_len);
2248 if (len <= 0) 2320 if (len <= 0)
2249 { 2321 {
2250 /* write error: connection closed, shutdown, etc.; just clean up */ 2322 /* write error: connection closed, shutdown, etc.; just clean up */
@@ -2252,16 +2324,16 @@ do_write (void *cls)
2252 return; 2324 return;
2253 } 2325 }
2254 memmove (s5r->wbuf, 2326 memmove (s5r->wbuf,
2255 &s5r->wbuf[len], 2327 &s5r->wbuf[len],
2256 s5r->wbuf_len - len); 2328 s5r->wbuf_len - len);
2257 s5r->wbuf_len -= len; 2329 s5r->wbuf_len -= len;
2258 if (s5r->wbuf_len > 0) 2330 if (s5r->wbuf_len > 0)
2259 { 2331 {
2260 /* not done writing */ 2332 /* not done writing */
2261 s5r->wtask = 2333 s5r->wtask =
2262 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 2334 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2263 s5r->sock, 2335 s5r->sock,
2264 &do_write, s5r); 2336 &do_write, s5r);
2265 return; 2337 return;
2266 } 2338 }
2267 2339
@@ -2269,21 +2341,21 @@ do_write (void *cls)
2269 2341
2270 switch (s5r->state) 2342 switch (s5r->state)
2271 { 2343 {
2272 case SOCKS5_INIT: 2344 case SOCKS5_INIT:
2273 GNUNET_assert (0); 2345 GNUNET_assert (0);
2274 break; 2346 break;
2275 case SOCKS5_REQUEST: 2347 case SOCKS5_REQUEST:
2276 GNUNET_assert (NULL != s5r->rtask); 2348 GNUNET_assert (NULL != s5r->rtask);
2277 break; 2349 break;
2278 case SOCKS5_DATA_TRANSFER: 2350 case SOCKS5_DATA_TRANSFER:
2279 setup_data_transfer (s5r); 2351 setup_data_transfer (s5r);
2280 return; 2352 return;
2281 case SOCKS5_WRITE_THEN_CLEANUP: 2353 case SOCKS5_WRITE_THEN_CLEANUP:
2282 cleanup_s5r (s5r); 2354 cleanup_s5r (s5r);
2283 return; 2355 return;
2284 default: 2356 default:
2285 GNUNET_break (0); 2357 GNUNET_break (0);
2286 break; 2358 break;
2287 } 2359 }
2288} 2360}
2289 2361
@@ -2296,7 +2368,7 @@ do_write (void *cls)
2296 */ 2368 */
2297static void 2369static void
2298signal_socks_failure (struct Socks5Request *s5r, 2370signal_socks_failure (struct Socks5Request *s5r,
2299 enum Socks5StatusCode sc) 2371 enum Socks5StatusCode sc)
2300{ 2372{
2301 struct Socks5ServerResponseMessage *s_resp; 2373 struct Socks5ServerResponseMessage *s_resp;
2302 2374
@@ -2308,8 +2380,8 @@ signal_socks_failure (struct Socks5Request *s5r,
2308 if (NULL != s5r->wtask) 2380 if (NULL != s5r->wtask)
2309 s5r->wtask = 2381 s5r->wtask =
2310 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 2382 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2311 s5r->sock, 2383 s5r->sock,
2312 &do_write, s5r); 2384 &do_write, s5r);
2313} 2385}
2314 2386
2315 2387
@@ -2330,15 +2402,15 @@ signal_socks_success (struct Socks5Request *s5r)
2330 s_resp->addr_type = SOCKS5_AT_IPV4; 2402 s_resp->addr_type = SOCKS5_AT_IPV4;
2331 /* zero out IPv4 address and port */ 2403 /* zero out IPv4 address and port */
2332 memset (&s_resp[1], 2404 memset (&s_resp[1],
2333 0, 2405 0,
2334 sizeof (struct in_addr) + sizeof (uint16_t)); 2406 sizeof (struct in_addr) + sizeof (uint16_t));
2335 s5r->wbuf_len += sizeof (struct Socks5ServerResponseMessage) + 2407 s5r->wbuf_len += sizeof (struct Socks5ServerResponseMessage) +
2336 sizeof (struct in_addr) + sizeof (uint16_t); 2408 sizeof (struct in_addr) + sizeof (uint16_t);
2337 if (NULL == s5r->wtask) 2409 if (NULL == s5r->wtask)
2338 s5r->wtask = 2410 s5r->wtask =
2339 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 2411 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2340 s5r->sock, 2412 s5r->sock,
2341 &do_write, s5r); 2413 &do_write, s5r);
2342} 2414}
2343 2415
2344 2416
@@ -2351,8 +2423,8 @@ signal_socks_success (struct Socks5Request *s5r)
2351 */ 2423 */
2352static void 2424static void
2353handle_gns_result (void *cls, 2425handle_gns_result (void *cls,
2354 uint32_t rd_count, 2426 uint32_t rd_count,
2355 const struct GNUNET_GNSRECORD_Data *rd) 2427 const struct GNUNET_GNSRECORD_Data *rd)
2356{ 2428{
2357 struct Socks5Request *s5r = cls; 2429 struct Socks5Request *s5r = cls;
2358 uint32_t i; 2430 uint32_t i;
@@ -2366,100 +2438,100 @@ handle_gns_result (void *cls,
2366 r = &rd[i]; 2438 r = &rd[i];
2367 switch (r->record_type) 2439 switch (r->record_type)
2368 { 2440 {
2369 case GNUNET_DNSPARSER_TYPE_A: 2441 case GNUNET_DNSPARSER_TYPE_A:
2370 { 2442 {
2371 struct sockaddr_in *in; 2443 struct sockaddr_in *in;
2372 2444
2373 if (sizeof (struct in_addr) != r->data_size) 2445 if (sizeof (struct in_addr) != r->data_size)
2374 { 2446 {
2375 GNUNET_break_op (0); 2447 GNUNET_break_op (0);
2376 break; 2448 break;
2377 } 2449 }
2378 if (GNUNET_YES == got_ip) 2450 if (GNUNET_YES == got_ip)
2379 break; 2451 break;
2380 if (GNUNET_OK != 2452 if (GNUNET_OK !=
2381 GNUNET_NETWORK_test_pf (PF_INET)) 2453 GNUNET_NETWORK_test_pf (PF_INET))
2382 break; 2454 break;
2383 got_ip = GNUNET_YES; 2455 got_ip = GNUNET_YES;
2384 in = (struct sockaddr_in *) &s5r->destination_address; 2456 in = (struct sockaddr_in *) &s5r->destination_address;
2385 in->sin_family = AF_INET; 2457 in->sin_family = AF_INET;
2386 GNUNET_memcpy (&in->sin_addr, 2458 GNUNET_memcpy (&in->sin_addr,
2387 r->data, 2459 r->data,
2388 r->data_size); 2460 r->data_size);
2389 in->sin_port = htons (s5r->port); 2461 in->sin_port = htons (s5r->port);
2390#if HAVE_SOCKADDR_IN_SIN_LEN 2462#if HAVE_SOCKADDR_IN_SIN_LEN
2391 in->sin_len = sizeof (*in); 2463 in->sin_len = sizeof (*in);
2392#endif 2464#endif
2393 } 2465 }
2394 break; 2466 break;
2395 case GNUNET_DNSPARSER_TYPE_AAAA: 2467 case GNUNET_DNSPARSER_TYPE_AAAA:
2396 { 2468 {
2397 struct sockaddr_in6 *in; 2469 struct sockaddr_in6 *in;
2398 2470
2399 if (sizeof (struct in6_addr) != r->data_size) 2471 if (sizeof (struct in6_addr) != r->data_size)
2400 { 2472 {
2401 GNUNET_break_op (0); 2473 GNUNET_break_op (0);
2402 break; 2474 break;
2403 } 2475 }
2404 if (GNUNET_YES == got_ip) 2476 if (GNUNET_YES == got_ip)
2405 break; 2477 break;
2406 if (GNUNET_OK != 2478 if (GNUNET_OK !=
2407 GNUNET_NETWORK_test_pf (PF_INET)) 2479 GNUNET_NETWORK_test_pf (PF_INET))
2408 break; 2480 break;
2409 /* FIXME: allow user to disable IPv6 per configuration option... */ 2481 /* FIXME: allow user to disable IPv6 per configuration option... */
2410 got_ip = GNUNET_YES; 2482 got_ip = GNUNET_YES;
2411 in = (struct sockaddr_in6 *) &s5r->destination_address; 2483 in = (struct sockaddr_in6 *) &s5r->destination_address;
2412 in->sin6_family = AF_INET6; 2484 in->sin6_family = AF_INET6;
2413 GNUNET_memcpy (&in->sin6_addr, 2485 GNUNET_memcpy (&in->sin6_addr,
2414 r->data, 2486 r->data,
2415 r->data_size); 2487 r->data_size);
2416 in->sin6_port = htons (s5r->port); 2488 in->sin6_port = htons (s5r->port);
2417#if HAVE_SOCKADDR_IN_SIN_LEN 2489#if HAVE_SOCKADDR_IN_SIN_LEN
2418 in->sin6_len = sizeof (*in); 2490 in->sin6_len = sizeof (*in);
2419#endif 2491#endif
2420 } 2492 }
2421 break; 2493 break;
2422 case GNUNET_GNSRECORD_TYPE_VPN: 2494 case GNUNET_GNSRECORD_TYPE_VPN:
2423 GNUNET_break (0); /* should have been translated within GNS */ 2495 GNUNET_break (0); /* should have been translated within GNS */
2424 break; 2496 break;
2425 case GNUNET_GNSRECORD_TYPE_LEHO: 2497 case GNUNET_GNSRECORD_TYPE_LEHO:
2426 GNUNET_free_non_null (s5r->leho); 2498 GNUNET_free_non_null (s5r->leho);
2427 s5r->leho = GNUNET_strndup (r->data, 2499 s5r->leho = GNUNET_strndup (r->data,
2428 r->data_size); 2500 r->data_size);
2429 break; 2501 break;
2430 case GNUNET_GNSRECORD_TYPE_BOX: 2502 case GNUNET_GNSRECORD_TYPE_BOX:
2431 {
2432 const struct GNUNET_GNSRECORD_BoxRecord *box;
2433
2434 if (r->data_size < sizeof (struct GNUNET_GNSRECORD_BoxRecord))
2435 { 2503 {
2436 GNUNET_break_op (0); 2504 const struct GNUNET_GNSRECORD_BoxRecord *box;
2505
2506 if (r->data_size < sizeof (struct GNUNET_GNSRECORD_BoxRecord))
2507 {
2508 GNUNET_break_op (0);
2509 break;
2510 }
2511 box = r->data;
2512 if ( (ntohl (box->record_type) != GNUNET_DNSPARSER_TYPE_TLSA) ||
2513 (ntohs (box->protocol) != IPPROTO_TCP) ||
2514 (ntohs (box->service) != s5r->port) )
2515 break; /* BOX record does not apply */
2516 GNUNET_free_non_null (s5r->dane_data);
2517 s5r->dane_data_len = r->data_size - sizeof (struct GNUNET_GNSRECORD_BoxRecord);
2518 s5r->dane_data = GNUNET_malloc (s5r->dane_data_len);
2519 GNUNET_memcpy (s5r->dane_data,
2520 &box[1],
2521 s5r->dane_data_len);
2437 break; 2522 break;
2438 } 2523 }
2439 box = r->data; 2524 default:
2440 if ( (ntohl (box->record_type) != GNUNET_DNSPARSER_TYPE_TLSA) || 2525 /* don't care */
2441 (ntohs (box->protocol) != IPPROTO_TCP) ||
2442 (ntohs (box->service) != s5r->port) )
2443 break; /* BOX record does not apply */
2444 GNUNET_free_non_null (s5r->dane_data);
2445 s5r->dane_data_len = r->data_size - sizeof (struct GNUNET_GNSRECORD_BoxRecord);
2446 s5r->dane_data = GNUNET_malloc (s5r->dane_data_len);
2447 GNUNET_memcpy (s5r->dane_data,
2448 &box[1],
2449 s5r->dane_data_len);
2450 break; 2526 break;
2451 }
2452 default:
2453 /* don't care */
2454 break;
2455 } 2527 }
2456 } 2528 }
2457 if (GNUNET_YES != got_ip) 2529 if (GNUNET_YES != got_ip)
2458 { 2530 {
2459 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2460 "Name resolution failed to yield useful IP address.\n"); 2532 "Name resolution failed to yield useful IP address.\n");
2461 signal_socks_failure (s5r, 2533 signal_socks_failure (s5r,
2462 SOCKS5_STATUS_GENERAL_FAILURE); 2534 SOCKS5_STATUS_GENERAL_FAILURE);
2463 return; 2535 return;
2464 } 2536 }
2465 s5r->state = SOCKS5_DATA_TRANSFER; 2537 s5r->state = SOCKS5_DATA_TRANSFER;
@@ -2475,12 +2547,12 @@ handle_gns_result (void *cls,
2475 */ 2547 */
2476static void 2548static void
2477clear_from_s5r_rbuf (struct Socks5Request *s5r, 2549clear_from_s5r_rbuf (struct Socks5Request *s5r,
2478 size_t len) 2550 size_t len)
2479{ 2551{
2480 GNUNET_assert (len <= s5r->rbuf_len); 2552 GNUNET_assert (len <= s5r->rbuf_len);
2481 memmove (s5r->rbuf, 2553 memmove (s5r->rbuf,
2482 &s5r->rbuf[len], 2554 &s5r->rbuf[len],
2483 s5r->rbuf_len - len); 2555 s5r->rbuf_len - len);
2484 s5r->rbuf_len -= len; 2556 s5r->rbuf_len -= len;
2485} 2557}
2486 2558
@@ -2507,196 +2579,196 @@ do_s5r_read (void *cls)
2507 (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) ) 2579 (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) )
2508 { 2580 {
2509 rlen = GNUNET_NETWORK_socket_recv (s5r->sock, 2581 rlen = GNUNET_NETWORK_socket_recv (s5r->sock,
2510 &s5r->rbuf[s5r->rbuf_len], 2582 &s5r->rbuf[s5r->rbuf_len],
2511 sizeof (s5r->rbuf) - s5r->rbuf_len); 2583 sizeof (s5r->rbuf) - s5r->rbuf_len);
2512 if (rlen <= 0) 2584 if (rlen <= 0)
2513 { 2585 {
2514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2515 "socks5 client disconnected.\n"); 2587 "socks5 client disconnected.\n");
2516 cleanup_s5r (s5r); 2588 cleanup_s5r (s5r);
2517 return; 2589 return;
2518 } 2590 }
2519 s5r->rbuf_len += rlen; 2591 s5r->rbuf_len += rlen;
2520 } 2592 }
2521 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2593 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2522 s5r->sock, 2594 s5r->sock,
2523 &do_s5r_read, s5r); 2595 &do_s5r_read, s5r);
2524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2525 "Processing %zu bytes of socks data in state %d\n", 2597 "Processing %zu bytes of socks data in state %d\n",
2526 s5r->rbuf_len, 2598 s5r->rbuf_len,
2527 s5r->state); 2599 s5r->state);
2528 switch (s5r->state) 2600 switch (s5r->state)
2529 { 2601 {
2530 case SOCKS5_INIT: 2602 case SOCKS5_INIT:
2531 c_hello = (const struct Socks5ClientHelloMessage*) &s5r->rbuf; 2603 c_hello = (const struct Socks5ClientHelloMessage*) &s5r->rbuf;
2532 if ( (s5r->rbuf_len < sizeof (struct Socks5ClientHelloMessage)) || 2604 if ( (s5r->rbuf_len < sizeof (struct Socks5ClientHelloMessage)) ||
2533 (s5r->rbuf_len < sizeof (struct Socks5ClientHelloMessage) + c_hello->num_auth_methods) ) 2605 (s5r->rbuf_len < sizeof (struct Socks5ClientHelloMessage) + c_hello->num_auth_methods) )
2534 return; /* need more data */ 2606 return; /* need more data */
2535 if (SOCKS_VERSION_5 != c_hello->version) 2607 if (SOCKS_VERSION_5 != c_hello->version)
2536 { 2608 {
2537 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2609 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2538 _("Unsupported socks version %d\n"), 2610 _("Unsupported socks version %d\n"),
2539 (int) c_hello->version); 2611 (int) c_hello->version);
2540 cleanup_s5r (s5r); 2612 cleanup_s5r (s5r);
2541 return; 2613 return;
2542 } 2614 }
2543 clear_from_s5r_rbuf (s5r, 2615 clear_from_s5r_rbuf (s5r,
2544 sizeof (struct Socks5ClientHelloMessage) + c_hello->num_auth_methods); 2616 sizeof (struct Socks5ClientHelloMessage) + c_hello->num_auth_methods);
2545 GNUNET_assert (0 == s5r->wbuf_len); 2617 GNUNET_assert (0 == s5r->wbuf_len);
2546 s_hello = (struct Socks5ServerHelloMessage *) &s5r->wbuf; 2618 s_hello = (struct Socks5ServerHelloMessage *) &s5r->wbuf;
2547 s5r->wbuf_len = sizeof (struct Socks5ServerHelloMessage); 2619 s5r->wbuf_len = sizeof (struct Socks5ServerHelloMessage);
2548 s_hello->version = SOCKS_VERSION_5; 2620 s_hello->version = SOCKS_VERSION_5;
2549 s_hello->auth_method = SOCKS_AUTH_NONE; 2621 s_hello->auth_method = SOCKS_AUTH_NONE;
2550 GNUNET_assert (NULL == s5r->wtask); 2622 GNUNET_assert (NULL == s5r->wtask);
2551 s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 2623 s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2552 s5r->sock, 2624 s5r->sock,
2553 &do_write, s5r); 2625 &do_write, s5r);
2554 s5r->state = SOCKS5_REQUEST; 2626 s5r->state = SOCKS5_REQUEST;
2555 return;
2556 case SOCKS5_REQUEST:
2557 c_req = (const struct Socks5ClientRequestMessage *) &s5r->rbuf;
2558 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage))
2559 return;
2560 switch (c_req->command)
2561 {
2562 case SOCKS5_CMD_TCP_STREAM:
2563 /* handled below */
2564 break;
2565 default:
2566 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2567 _("Unsupported socks command %d\n"),
2568 (int) c_req->command);
2569 signal_socks_failure (s5r,
2570 SOCKS5_STATUS_COMMAND_NOT_SUPPORTED);
2571 return; 2627 return;
2572 } 2628 case SOCKS5_REQUEST:
2573 switch (c_req->addr_type) 2629 c_req = (const struct Socks5ClientRequestMessage *) &s5r->rbuf;
2574 { 2630 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage))
2575 case SOCKS5_AT_IPV4: 2631 return;
2632 switch (c_req->command)
2576 { 2633 {
2577 const struct in_addr *v4 = (const struct in_addr *) &c_req[1]; 2634 case SOCKS5_CMD_TCP_STREAM:
2578 const uint16_t *port = (const uint16_t *) &v4[1]; 2635 /* handled below */
2579 struct sockaddr_in *in; 2636 break;
2580 2637 default:
2581 s5r->port = ntohs (*port);
2582 if (HTTPS_PORT == s5r->port)
2583 {
2584 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2638 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2585 _("SSL connection to plain IPv4 address requested\n")); 2639 _("Unsupported socks command %d\n"),
2640 (int) c_req->command);
2586 signal_socks_failure (s5r, 2641 signal_socks_failure (s5r,
2587 SOCKS5_STATUS_CONNECTION_NOT_ALLOWED_BY_RULE); 2642 SOCKS5_STATUS_COMMAND_NOT_SUPPORTED);
2588 return; 2643 return;
2589 }
2590 alen = sizeof (struct in_addr);
2591 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage) +
2592 alen + sizeof (uint16_t))
2593 return; /* need more data */
2594 in = (struct sockaddr_in *) &s5r->destination_address;
2595 in->sin_family = AF_INET;
2596 in->sin_addr = *v4;
2597 in->sin_port = *port;
2598#if HAVE_SOCKADDR_IN_SIN_LEN
2599 in->sin_len = sizeof (*in);
2600#endif
2601 s5r->state = SOCKS5_DATA_TRANSFER;
2602 } 2644 }
2603 break; 2645 switch (c_req->addr_type)
2604 case SOCKS5_AT_IPV6:
2605 { 2646 {
2606 const struct in6_addr *v6 = (const struct in6_addr *) &c_req[1]; 2647 case SOCKS5_AT_IPV4:
2607 const uint16_t *port = (const uint16_t *) &v6[1]; 2648 {
2608 struct sockaddr_in6 *in; 2649 const struct in_addr *v4 = (const struct in_addr *) &c_req[1];
2609 2650 const uint16_t *port = (const uint16_t *) &v4[1];
2610 s5r->port = ntohs (*port); 2651 struct sockaddr_in *in;
2611 if (HTTPS_PORT == s5r->port) 2652
2612 { 2653 s5r->port = ntohs (*port);
2654 if (HTTPS_PORT == s5r->port)
2655 {
2656 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2657 _("SSL connection to plain IPv4 address requested\n"));
2658 signal_socks_failure (s5r,
2659 SOCKS5_STATUS_CONNECTION_NOT_ALLOWED_BY_RULE);
2660 return;
2661 }
2662 alen = sizeof (struct in_addr);
2663 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage) +
2664 alen + sizeof (uint16_t))
2665 return; /* need more data */
2666 in = (struct sockaddr_in *) &s5r->destination_address;
2667 in->sin_family = AF_INET;
2668 in->sin_addr = *v4;
2669 in->sin_port = *port;
2670#if HAVE_SOCKADDR_IN_SIN_LEN
2671 in->sin_len = sizeof (*in);
2672#endif
2673 s5r->state = SOCKS5_DATA_TRANSFER;
2674 }
2675 break;
2676 case SOCKS5_AT_IPV6:
2677 {
2678 const struct in6_addr *v6 = (const struct in6_addr *) &c_req[1];
2679 const uint16_t *port = (const uint16_t *) &v6[1];
2680 struct sockaddr_in6 *in;
2681
2682 s5r->port = ntohs (*port);
2683 if (HTTPS_PORT == s5r->port)
2684 {
2685 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2686 _("SSL connection to plain IPv4 address requested\n"));
2687 signal_socks_failure (s5r,
2688 SOCKS5_STATUS_CONNECTION_NOT_ALLOWED_BY_RULE);
2689 return;
2690 }
2691 alen = sizeof (struct in6_addr);
2692 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage) +
2693 alen + sizeof (uint16_t))
2694 return; /* need more data */
2695 in = (struct sockaddr_in6 *) &s5r->destination_address;
2696 in->sin6_family = AF_INET6;
2697 in->sin6_addr = *v6;
2698 in->sin6_port = *port;
2699#if HAVE_SOCKADDR_IN_SIN_LEN
2700 in->sin6_len = sizeof (*in);
2701#endif
2702 s5r->state = SOCKS5_DATA_TRANSFER;
2703 }
2704 break;
2705 case SOCKS5_AT_DOMAINNAME:
2706 {
2707 const uint8_t *dom_len;
2708 const char *dom_name;
2709 const uint16_t *port;
2710
2711 dom_len = (const uint8_t *) &c_req[1];
2712 alen = *dom_len + 1;
2713 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage) +
2714 alen + sizeof (uint16_t))
2715 return; /* need more data */
2716 dom_name = (const char *) &dom_len[1];
2717 port = (const uint16_t*) &dom_name[*dom_len];
2718 s5r->domain = GNUNET_strndup (dom_name, *dom_len);
2719 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2720 "Requested connection is to %s:%d\n",
2721 s5r->domain,
2722 ntohs (*port));
2723 s5r->state = SOCKS5_RESOLVING;
2724 s5r->port = ntohs (*port);
2725 s5r->gns_lookup = GNUNET_GNS_lookup (gns_handle,
2726 s5r->domain,
2727 &local_gns_zone,
2728 GNUNET_DNSPARSER_TYPE_A,
2729 GNUNET_NO /* only cached */,
2730 (GNUNET_YES == do_shorten) ? &local_shorten_zone : NULL,
2731 &handle_gns_result,
2732 s5r);
2733 break;
2734 }
2735 default:
2613 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2736 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2614 _("SSL connection to plain IPv4 address requested\n")); 2737 _("Unsupported socks address type %d\n"),
2738 (int) c_req->addr_type);
2615 signal_socks_failure (s5r, 2739 signal_socks_failure (s5r,
2616 SOCKS5_STATUS_CONNECTION_NOT_ALLOWED_BY_RULE); 2740 SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED);
2617 return; 2741 return;
2618 }
2619 alen = sizeof (struct in6_addr);
2620 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage) +
2621 alen + sizeof (uint16_t))
2622 return; /* need more data */
2623 in = (struct sockaddr_in6 *) &s5r->destination_address;
2624 in->sin6_family = AF_INET6;
2625 in->sin6_addr = *v6;
2626 in->sin6_port = *port;
2627#if HAVE_SOCKADDR_IN_SIN_LEN
2628 in->sin6_len = sizeof (*in);
2629#endif
2630 s5r->state = SOCKS5_DATA_TRANSFER;
2631 } 2742 }
2632 break; 2743 clear_from_s5r_rbuf (s5r,
2633 case SOCKS5_AT_DOMAINNAME: 2744 sizeof (struct Socks5ClientRequestMessage) +
2745 alen + sizeof (uint16_t));
2746 if (0 != s5r->rbuf_len)
2634 { 2747 {
2635 const uint8_t *dom_len; 2748 /* read more bytes than healthy, why did the client send more!? */
2636 const char *dom_name; 2749 GNUNET_break_op (0);
2637 const uint16_t *port; 2750 signal_socks_failure (s5r,
2638 2751 SOCKS5_STATUS_GENERAL_FAILURE);
2639 dom_len = (const uint8_t *) &c_req[1]; 2752 return;
2640 alen = *dom_len + 1;
2641 if (s5r->rbuf_len < sizeof (struct Socks5ClientRequestMessage) +
2642 alen + sizeof (uint16_t))
2643 return; /* need more data */
2644 dom_name = (const char *) &dom_len[1];
2645 port = (const uint16_t*) &dom_name[*dom_len];
2646 s5r->domain = GNUNET_strndup (dom_name, *dom_len);
2647 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2648 "Requested connection is to %s:%d\n",
2649 s5r->domain,
2650 ntohs (*port));
2651 s5r->state = SOCKS5_RESOLVING;
2652 s5r->port = ntohs (*port);
2653 s5r->gns_lookup = GNUNET_GNS_lookup (gns_handle,
2654 s5r->domain,
2655 &local_gns_zone,
2656 GNUNET_DNSPARSER_TYPE_A,
2657 GNUNET_NO /* only cached */,
2658 (GNUNET_YES == do_shorten) ? &local_shorten_zone : NULL,
2659 &handle_gns_result,
2660 s5r);
2661 break;
2662 } 2753 }
2663 default: 2754 if (SOCKS5_DATA_TRANSFER == s5r->state)
2664 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2755 {
2665 _("Unsupported socks address type %d\n"), 2756 /* if we are not waiting for GNS resolution, signal success */
2666 (int) c_req->addr_type); 2757 signal_socks_success (s5r);
2667 signal_socks_failure (s5r, 2758 }
2668 SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED); 2759 /* We are done reading right now */
2760 GNUNET_SCHEDULER_cancel (s5r->rtask);
2761 s5r->rtask = NULL;
2669 return; 2762 return;
2670 } 2763 case SOCKS5_RESOLVING:
2671 clear_from_s5r_rbuf (s5r, 2764 GNUNET_assert (0);
2672 sizeof (struct Socks5ClientRequestMessage) + 2765 return;
2673 alen + sizeof (uint16_t)); 2766 case SOCKS5_DATA_TRANSFER:
2674 if (0 != s5r->rbuf_len) 2767 GNUNET_assert (0);
2675 { 2768 return;
2676 /* read more bytes than healthy, why did the client send more!? */ 2769 default:
2677 GNUNET_break_op (0); 2770 GNUNET_assert (0);
2678 signal_socks_failure (s5r,
2679 SOCKS5_STATUS_GENERAL_FAILURE);
2680 return; 2771 return;
2681 }
2682 if (SOCKS5_DATA_TRANSFER == s5r->state)
2683 {
2684 /* if we are not waiting for GNS resolution, signal success */
2685 signal_socks_success (s5r);
2686 }
2687 /* We are done reading right now */
2688 GNUNET_SCHEDULER_cancel (s5r->rtask);
2689 s5r->rtask = NULL;
2690 return;
2691 case SOCKS5_RESOLVING:
2692 GNUNET_assert (0);
2693 return;
2694 case SOCKS5_DATA_TRANSFER:
2695 GNUNET_assert (0);
2696 return;
2697 default:
2698 GNUNET_assert (0);
2699 return;
2700 } 2772 }
2701} 2773}
2702 2774
@@ -2736,8 +2808,8 @@ do_accept (void *cls)
2736 "Got an inbound connection, waiting for data\n"); 2808 "Got an inbound connection, waiting for data\n");
2737 s5r = GNUNET_new (struct Socks5Request); 2809 s5r = GNUNET_new (struct Socks5Request);
2738 GNUNET_CONTAINER_DLL_insert (s5r_head, 2810 GNUNET_CONTAINER_DLL_insert (s5r_head,
2739 s5r_tail, 2811 s5r_tail,
2740 s5r); 2812 s5r);
2741 s5r->sock = s; 2813 s5r->sock = s;
2742 s5r->state = SOCKS5_INIT; 2814 s5r->state = SOCKS5_INIT;
2743 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2815 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -2839,7 +2911,7 @@ bind_v4 ()
2839 return NULL; 2911 return NULL;
2840 if (GNUNET_OK != 2912 if (GNUNET_OK !=
2841 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4, 2913 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4,
2842 sizeof (sa4))) 2914 sizeof (sa4)))
2843 { 2915 {
2844 eno = errno; 2916 eno = errno;
2845 GNUNET_NETWORK_socket_close (ls); 2917 GNUNET_NETWORK_socket_close (ls);
@@ -2875,7 +2947,7 @@ bind_v6 ()
2875 return NULL; 2947 return NULL;
2876 if (GNUNET_OK != 2948 if (GNUNET_OK !=
2877 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa6, 2949 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa6,
2878 sizeof (sa6))) 2950 sizeof (sa6)))
2879 { 2951 {
2880 eno = errno; 2952 eno = errno;
2881 GNUNET_NETWORK_socket_close (ls); 2953 GNUNET_NETWORK_socket_close (ls);
@@ -2949,13 +3021,14 @@ run_cont ()
2949 /* start MHD daemon for HTTP */ 3021 /* start MHD daemon for HTTP */
2950 hd = GNUNET_new (struct MhdHttpList); 3022 hd = GNUNET_new (struct MhdHttpList);
2951 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET, 3023 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET,
2952 0, 3024 0,
2953 NULL, NULL, 3025 NULL, NULL,
2954 &create_response, hd, 3026 &create_response, hd,
2955 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, 3027 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
2956 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL, 3028 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL,
2957 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL, 3029 MHD_OPTION_NOTIFY_CONNECTION, &mhd_connection_cb, NULL,
2958 MHD_OPTION_END); 3030 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
3031 MHD_OPTION_END);
2959 if (NULL == hd->daemon) 3032 if (NULL == hd->daemon)
2960 { 3033 {
2961 GNUNET_free (hd); 3034 GNUNET_free (hd);
@@ -2988,15 +3061,15 @@ run_cont ()
2988 */ 3061 */
2989static void 3062static void
2990identity_shorten_cb (void *cls, 3063identity_shorten_cb (void *cls,
2991 struct GNUNET_IDENTITY_Ego *ego, 3064 struct GNUNET_IDENTITY_Ego *ego,
2992 void **ctx, 3065 void **ctx,
2993 const char *name) 3066 const char *name)
2994{ 3067{
2995 id_op = NULL; 3068 id_op = NULL;
2996 if (NULL == ego) 3069 if (NULL == ego)
2997 { 3070 {
2998 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3071 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2999 _("No ego configured for `shorten-zone`\n")); 3072 _("No ego configured for `shorten-zone`\n"));
3000 } 3073 }
3001 else 3074 else
3002 { 3075 {
@@ -3028,25 +3101,25 @@ identity_shorten_cb (void *cls,
3028 */ 3101 */
3029static void 3102static void
3030identity_master_cb (void *cls, 3103identity_master_cb (void *cls,
3031 struct GNUNET_IDENTITY_Ego *ego, 3104 struct GNUNET_IDENTITY_Ego *ego,
3032 void **ctx, 3105 void **ctx,
3033 const char *name) 3106 const char *name)
3034{ 3107{
3035 id_op = NULL; 3108 id_op = NULL;
3036 if (NULL == ego) 3109 if (NULL == ego)
3037 { 3110 {
3038 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3039 _("No ego configured for `%s`\n"), 3112 _("No ego configured for `%s`\n"),
3040 "gns-proxy"); 3113 "gns-proxy");
3041 GNUNET_SCHEDULER_shutdown (); 3114 GNUNET_SCHEDULER_shutdown ();
3042 return; 3115 return;
3043 } 3116 }
3044 GNUNET_IDENTITY_ego_get_public_key (ego, 3117 GNUNET_IDENTITY_ego_get_public_key (ego,
3045 &local_gns_zone); 3118 &local_gns_zone);
3046 id_op = GNUNET_IDENTITY_get (identity, 3119 id_op = GNUNET_IDENTITY_get (identity,
3047 "gns-short", 3120 "gns-short",
3048 &identity_shorten_cb, 3121 &identity_shorten_cb,
3049 NULL); 3122 NULL);
3050} 3123}
3051 3124
3052 3125
@@ -3077,12 +3150,12 @@ run (void *cls, char *const *args, const char *cfgfile,
3077 if (NULL == cafile) 3150 if (NULL == cafile)
3078 { 3151 {
3079 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy", 3152 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy",
3080 "PROXY_CACERT", 3153 "PROXY_CACERT",
3081 &cafile_cfg)) 3154 &cafile_cfg))
3082 { 3155 {
3083 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 3156 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
3084 "gns-proxy", 3157 "gns-proxy",
3085 "PROXY_CACERT"); 3158 "PROXY_CACERT");
3086 return; 3159 return;
3087 } 3160 }
3088 cafile = cafile_cfg; 3161 cafile = cafile_cfg;
@@ -3098,8 +3171,8 @@ run (void *cls, char *const *args, const char *cfgfile,
3098 (GNUNET_OK != load_key_from_file (proxy_ca.key, cafile)) ) 3171 (GNUNET_OK != load_key_from_file (proxy_ca.key, cafile)) )
3099 { 3172 {
3100 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3101 _("Failed to load SSL/TLS key and certificate from `%s'\n"), 3174 _("Failed to load SSL/TLS key and certificate from `%s'\n"),
3102 cafile); 3175 cafile);
3103 gnutls_x509_crt_deinit (proxy_ca.cert); 3176 gnutls_x509_crt_deinit (proxy_ca.cert);
3104 gnutls_x509_privkey_deinit (proxy_ca.key); 3177 gnutls_x509_privkey_deinit (proxy_ca.key);
3105 gnutls_global_deinit (); 3178 gnutls_global_deinit ();
@@ -3117,11 +3190,11 @@ run (void *cls, char *const *args, const char *cfgfile,
3117 return; 3190 return;
3118 } 3191 }
3119 identity = GNUNET_IDENTITY_connect (cfg, 3192 identity = GNUNET_IDENTITY_connect (cfg,
3120 NULL, NULL); 3193 NULL, NULL);
3121 id_op = GNUNET_IDENTITY_get (identity, 3194 id_op = GNUNET_IDENTITY_get (identity,
3122 "gns-proxy", 3195 "gns-proxy",
3123 &identity_master_cb, 3196 &identity_master_cb,
3124 NULL); 3197 NULL);
3125 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 3198 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
3126} 3199}
3127 3200
@@ -3138,8 +3211,8 @@ main (int argc, char *const *argv)
3138{ 3211{
3139 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 3212 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3140 {'p', "port", NULL, 3213 {'p', "port", NULL,
3141 gettext_noop ("listen on specified port (default: 7777)"), 1, 3214 gettext_noop ("listen on specified port (default: 7777)"), 1,
3142 &GNUNET_GETOPT_set_ulong, &port}, 3215 &GNUNET_GETOPT_set_ulong, &port},
3143 {'a', "authority", NULL, 3216 {'a', "authority", NULL,
3144 gettext_noop ("pem file to use as CA"), 1, 3217 gettext_noop ("pem file to use as CA"), 1,
3145 &GNUNET_GETOPT_set_string, &cafile_opt}, 3218 &GNUNET_GETOPT_set_string, &cafile_opt},
@@ -3154,15 +3227,15 @@ main (int argc, char *const *argv)
3154 return 2; 3227 return 2;
3155 GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL); 3228 GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL);
3156 curl_failure_response = MHD_create_response_from_buffer (strlen (page), 3229 curl_failure_response = MHD_create_response_from_buffer (strlen (page),
3157 (void*)page, 3230 (void*)page,
3158 MHD_RESPMEM_PERSISTENT); 3231 MHD_RESPMEM_PERSISTENT);
3159 3232
3160 ret = 3233 ret =
3161 (GNUNET_OK == 3234 (GNUNET_OK ==
3162 GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy", 3235 GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy",
3163 _("GNUnet GNS proxy"), 3236 _("GNUnet GNS proxy"),
3164 options, 3237 options,
3165 &run, NULL)) ? 0 : 1; 3238 &run, NULL)) ? 0 : 1;
3166 MHD_destroy_response (curl_failure_response); 3239 MHD_destroy_response (curl_failure_response);
3167 GNUNET_free_non_null ((char *) argv); 3240 GNUNET_free_non_null ((char *) argv);
3168 GNUNET_CRYPTO_ecdsa_key_clear (&local_shorten_zone); 3241 GNUNET_CRYPTO_ecdsa_key_clear (&local_shorten_zone);