diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-08-29 09:56:48 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-08-29 09:56:48 +0000 |
commit | aac3c952498f814df3843fb18ffcc11783c763ba (patch) | |
tree | 4610708cf003acd11967c45084af399584dd8335 /src/gns | |
parent | cda23f9580da561752aee04753054aa6225af7cf (diff) | |
download | gnunet-aac3c952498f814df3843fb18ffcc11783c763ba.tar.gz gnunet-aac3c952498f814df3843fb18ffcc11783c763ba.zip |
- add persistent connections
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/gnunet-gns-proxy.c | 1099 |
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 | */ |
1722 | static void | 1734 | static void |
1723 | mhd_completed_cb (void *cls, | 1735 | mhd_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 | */ | ||
1774 | static void | ||
1775 | mhd_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 | */ |
1755 | static void * | 1826 | static void * |
1756 | mhd_log_callback (void *cls, | 1827 | mhd_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 | |||
1798 | kill_httpd (struct MhdHttpList *hd) | 1869 | kill_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 | */ |
1951 | static void* | 2022 | static void* |
1952 | load_file (const char* filename, | 2023 | load_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 | */ |
1982 | static int | 2053 | static int |
1983 | load_key_from_file (gnutls_x509_privkey_t key, | 2054 | load_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 | */ |
2012 | static int | 2083 | static int |
2013 | load_cert_from_file (gnutls_x509_crt_t crt, | 2084 | load_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 | */ |
2297 | static void | 2369 | static void |
2298 | signal_socks_failure (struct Socks5Request *s5r, | 2370 | signal_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 | */ |
2352 | static void | 2424 | static void |
2353 | handle_gns_result (void *cls, | 2425 | handle_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 | */ |
2476 | static void | 2548 | static void |
2477 | clear_from_s5r_rbuf (struct Socks5Request *s5r, | 2549 | clear_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 | */ |
2989 | static void | 3062 | static void |
2990 | identity_shorten_cb (void *cls, | 3063 | identity_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 | */ |
3029 | static void | 3102 | static void |
3030 | identity_master_cb (void *cls, | 3103 | identity_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); |