aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_client.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-11-22 20:07:46 +0000
committerChristian Grothoff <christian@grothoff.org>2014-11-22 20:07:46 +0000
commit3a628a8b12195e3d15dce032d2e11110a6bb71a0 (patch)
treee04c545488b6e191f739b5bec4e1b6cc5db70e27 /src/transport/plugin_transport_http_client.c
parentdc82ebded4c48483815fd73d4e33750b73fed496 (diff)
downloadgnunet-3a628a8b12195e3d15dce032d2e11110a6bb71a0.tar.gz
gnunet-3a628a8b12195e3d15dce032d2e11110a6bb71a0.zip
adding TCP STEALTH support to HTTP client (without integrity protection)
Diffstat (limited to 'src/transport/plugin_transport_http_client.c')
-rw-r--r--src/transport/plugin_transport_http_client.c449
1 files changed, 334 insertions, 115 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c
index adb83c719..971e581fd 100644
--- a/src/transport/plugin_transport_http_client.c
+++ b/src/transport/plugin_transport_http_client.c
@@ -384,6 +384,7 @@ struct HTTP_Client_Plugin
384 int emulate_xhr; 384 int emulate_xhr;
385}; 385};
386 386
387
387/** 388/**
388 * Disconnect a session 389 * Disconnect a session
389 * 390 *
@@ -394,6 +395,7 @@ struct HTTP_Client_Plugin
394static int 395static int
395http_client_plugin_session_disconnect (void *cls, struct Session *s); 396http_client_plugin_session_disconnect (void *cls, struct Session *s);
396 397
398
397/** 399/**
398 * If a session monitor is attached, notify it about the new 400 * If a session monitor is attached, notify it about the new
399 * session state. 401 * session state.
@@ -589,20 +591,23 @@ client_schedule (struct HTTP_Client_Plugin *plugin,
589 mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); 591 mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max);
590 if (mret != CURLM_OK) 592 if (mret != CURLM_OK)
591 { 593 {
592 LOG (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), 594 LOG (GNUNET_ERROR_TYPE_ERROR,
593 "curl_multi_fdset", __FILE__, __LINE__, 595 _("%s failed at %s:%d: `%s'\n"),
594 curl_multi_strerror (mret)); 596 "curl_multi_fdset",
597 __FILE__,
598 __LINE__,
599 curl_multi_strerror (mret));
595 return GNUNET_SYSERR; 600 return GNUNET_SYSERR;
596 } 601 }
597 mret = curl_multi_timeout (plugin->curl_multi_handle, &to); 602 mret = curl_multi_timeout (plugin->curl_multi_handle, &to);
598 if (to == -1) 603 if (-1 == to)
599 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); 604 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1);
600 else 605 else
601 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); 606 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to);
602 if (now == GNUNET_YES) 607 if (now == GNUNET_YES)
603 timeout = GNUNET_TIME_UNIT_MILLISECONDS; 608 timeout = GNUNET_TIME_UNIT_MILLISECONDS;
604 609
605 if (mret != CURLM_OK) 610 if (CURLM_OK != mret)
606 { 611 {
607 LOG (GNUNET_ERROR_TYPE_ERROR, 612 LOG (GNUNET_ERROR_TYPE_ERROR,
608 _("%s failed at %s:%d: `%s'\n"), 613 _("%s failed at %s:%d: `%s'\n"),
@@ -626,6 +631,7 @@ client_schedule (struct HTTP_Client_Plugin *plugin,
626 return GNUNET_OK; 631 return GNUNET_OK;
627} 632}
628 633
634
629#if VERBOSE_CURL 635#if VERBOSE_CURL
630/** 636/**
631 * Loggging function 637 * Loggging function
@@ -648,7 +654,9 @@ client_log (CURL *curl,
648 const char *ttype = "UNSPECIFIED"; 654 const char *ttype = "UNSPECIFIED";
649 char text[size + 2]; 655 char text[size + 2];
650 656
651 if (! ((type == CURLINFO_TEXT) || (type == CURLINFO_HEADER_IN) || (type == CURLINFO_HEADER_OUT))) 657 if (! ((CURLINFO_TEXT == type) ||
658 (CURLINFO_HEADER_IN == type) ||
659 (CURLINFO_HEADER_OUT == type)))
652 return 0; 660 return 0;
653 switch (type) 661 switch (type)
654 { 662 {
@@ -731,7 +739,7 @@ client_connect_put (struct Session *s);
731 * been transmitted (or if the transport is ready 739 * been transmitted (or if the transport is ready
732 * for the next transmission call; or if the 740 * for the next transmission call; or if the
733 * peer disconnected...); can be NULL 741 * peer disconnected...); can be NULL
734 * @param cont_cls closure for cont 742 * @param cont_cls closure for @a cont
735 * @return number of bytes used (on the physical network, with overheads); 743 * @return number of bytes used (on the physical network, with overheads);
736 * -1 on hard errors (i.e. address invalid); 0 is a legal value 744 * -1 on hard errors (i.e. address invalid); 0 is a legal value
737 * and does NOT mean that the message was not transmitted (DV) 745 * and does NOT mean that the message was not transmitted (DV)
@@ -752,18 +760,20 @@ http_client_plugin_send (void *cls,
752 760
753 LOG (GNUNET_ERROR_TYPE_DEBUG, 761 LOG (GNUNET_ERROR_TYPE_DEBUG,
754 "Session %p/request %p: Sending message with %u to peer `%s' \n", 762 "Session %p/request %p: Sending message with %u to peer `%s' \n",
755 s, s->put.easyhandle, 763 s,
756 msgbuf_size, GNUNET_i2s (&s->address->peer)); 764 s->put.easyhandle,
765 msgbuf_size,
766 GNUNET_i2s (&s->address->peer));
757 767
758 /* create new message and schedule */ 768 /* create new message and schedule */
759 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); 769 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
760 msg->next = NULL;
761 msg->size = msgbuf_size; 770 msg->size = msgbuf_size;
762 msg->pos = 0;
763 msg->buf = (char *) &msg[1]; 771 msg->buf = (char *) &msg[1];
764 msg->transmit_cont = cont; 772 msg->transmit_cont = cont;
765 msg->transmit_cont_cls = cont_cls; 773 msg->transmit_cont_cls = cont_cls;
766 memcpy (msg->buf, msgbuf, msgbuf_size); 774 memcpy (msg->buf,
775 msgbuf,
776 msgbuf_size);
767 GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, 777 GNUNET_CONTAINER_DLL_insert_tail (s->msg_head,
768 s->msg_tail, 778 s->msg_tail,
769 msg); 779 msg);
@@ -833,8 +843,11 @@ http_client_plugin_session_disconnect (void *cls,
833 struct HTTP_Client_Plugin *plugin = cls; 843 struct HTTP_Client_Plugin *plugin = cls;
834 844
835 LOG (GNUNET_ERROR_TYPE_DEBUG, 845 LOG (GNUNET_ERROR_TYPE_DEBUG,
836 "Session %p: notifying transport about ending session\n",s); 846 "Session %p: notifying transport about ending session\n",
837 plugin->env->session_end (plugin->env->cls, s->address, s); 847 s);
848 plugin->env->session_end (plugin->env->cls,
849 s->address,
850 s);
838 client_delete_session (s); 851 client_delete_session (s);
839 852
840 /* Re-schedule since handles have changed */ 853 /* Re-schedule since handles have changed */
@@ -902,8 +915,10 @@ http_client_plugin_peer_disconnect (void *cls,
902 LOG (GNUNET_ERROR_TYPE_DEBUG, 915 LOG (GNUNET_ERROR_TYPE_DEBUG,
903 "Transport tells me to disconnect `%s'\n", 916 "Transport tells me to disconnect `%s'\n",
904 GNUNET_i2s (target)); 917 GNUNET_i2s (target));
905 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, target, 918 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions,
906 &destroy_session_cb, plugin); 919 target,
920 &destroy_session_cb,
921 plugin);
907} 922}
908 923
909 924
@@ -992,7 +1007,8 @@ client_put_disconnect (void *cls,
992 s, s->put.easyhandle); 1007 s, s->put.easyhandle);
993 s->put.state = H_TMP_DISCONNECTING; 1008 s->put.state = H_TMP_DISCONNECTING;
994 if (NULL != s->put.easyhandle) 1009 if (NULL != s->put.easyhandle)
995 curl_easy_pause (s->put.easyhandle, CURLPAUSE_CONT); 1010 curl_easy_pause (s->put.easyhandle,
1011 CURLPAUSE_CONT);
996 client_schedule (s->plugin, GNUNET_YES); 1012 client_schedule (s->plugin, GNUNET_YES);
997} 1013}
998 1014
@@ -1033,7 +1049,8 @@ client_send_cb (void *stream,
1033 { 1049 {
1034 LOG (GNUNET_ERROR_TYPE_DEBUG, 1050 LOG (GNUNET_ERROR_TYPE_DEBUG,
1035 "Session %p/request %p: PUT request finished\n", 1051 "Session %p/request %p: PUT request finished\n",
1036 s, s->put.easyhandle); 1052 s,
1053 s->put.easyhandle);
1037 s->put.state = H_TMP_DISCONNECTING; 1054 s->put.state = H_TMP_DISCONNECTING;
1038 return 0; 1055 return 0;
1039 } 1056 }
@@ -1041,7 +1058,8 @@ client_send_cb (void *stream,
1041 /* We have nothing to send, so pause PUT request */ 1058 /* We have nothing to send, so pause PUT request */
1042 LOG (GNUNET_ERROR_TYPE_DEBUG, 1059 LOG (GNUNET_ERROR_TYPE_DEBUG,
1043 "Session %p/request %p: nothing to send, suspending\n", 1060 "Session %p/request %p: nothing to send, suspending\n",
1044 s, s->put.easyhandle); 1061 s,
1062 s->put.easyhandle);
1045 s->put_disconnect_task = GNUNET_SCHEDULER_add_delayed (PUT_DISCONNECT_TIMEOUT, 1063 s->put_disconnect_task = GNUNET_SCHEDULER_add_delayed (PUT_DISCONNECT_TIMEOUT,
1046 &client_put_disconnect, s); 1064 &client_put_disconnect, s);
1047 s->put.state = H_PAUSED; 1065 s->put.state = H_PAUSED;
@@ -1058,7 +1076,10 @@ client_send_cb (void *stream,
1058 { 1076 {
1059 LOG (GNUNET_ERROR_TYPE_DEBUG, 1077 LOG (GNUNET_ERROR_TYPE_DEBUG,
1060 "Session %p/request %p: sent message with %u bytes sent, removing message from queue\n", 1078 "Session %p/request %p: sent message with %u bytes sent, removing message from queue\n",
1061 s, s->put.easyhandle, msg->size, msg->pos); 1079 s,
1080 s->put.easyhandle,
1081 msg->size,
1082 msg->pos);
1062 /* Calling transmit continuation */ 1083 /* Calling transmit continuation */
1063 GNUNET_CONTAINER_DLL_remove (s->msg_head, 1084 GNUNET_CONTAINER_DLL_remove (s->msg_head,
1064 s->msg_tail, 1085 s->msg_tail,
@@ -1161,7 +1182,8 @@ client_receive_mst_cb (void *cls,
1161 s, 1182 s,
1162 message); 1183 message);
1163 plugin->env->update_address_metrics (plugin->env->cls, 1184 plugin->env->update_address_metrics (plugin->env->cls,
1164 s->address, s, 1185 s->address,
1186 s,
1165 &atsi, 1); 1187 &atsi, 1);
1166 1188
1167 GNUNET_asprintf (&stat_txt, 1189 GNUNET_asprintf (&stat_txt,
@@ -1232,8 +1254,10 @@ client_receive (void *stream,
1232 1254
1233 LOG (GNUNET_ERROR_TYPE_DEBUG, 1255 LOG (GNUNET_ERROR_TYPE_DEBUG,
1234 "Session %p / request %p: Received %u bytes from peer `%s'\n", 1256 "Session %p / request %p: Received %u bytes from peer `%s'\n",
1235 s, s->get.easyhandle, 1257 s,
1236 len, GNUNET_i2s (&s->address->peer)); 1258 s->get.easyhandle,
1259 len,
1260 GNUNET_i2s (&s->address->peer));
1237 now = GNUNET_TIME_absolute_get (); 1261 now = GNUNET_TIME_absolute_get ();
1238 if (now.abs_value_us < s->next_receive.abs_value_us) 1262 if (now.abs_value_us < s->next_receive.abs_value_us)
1239 { 1263 {
@@ -1428,6 +1452,52 @@ client_run (void *cls,
1428} 1452}
1429 1453
1430 1454
1455#ifdef SO_TCPSTEALTH
1456/**
1457 * Open TCP socket with TCP STEALTH enabled.
1458 */
1459static curl_socket_t
1460open_tcp_stealth_socket_cb (void *clientp,
1461 curlsocktype purpose,
1462 struct curl_sockaddr *address)
1463{
1464 struct Session *s = clientp;
1465 int ret;
1466
1467 switch (purpose)
1468 {
1469 case CURLSOCKTYPE_IPCXN:
1470 ret = socket (address->family,
1471 address->socktype,
1472 address->protocol);
1473 if (-1 == ret)
1474 return CURL_SOCKET_BAD;
1475 if ( ( (SOCK_STREAM != address->socktype) ||
1476 ( (0 != address->protocol) &&
1477 (IPPROTO_TCP != address->protocol))) )
1478 return (curl_socket_t) ret;
1479 if ( (0 != setsockopt (ret,
1480 IPPROTO_TCP,
1481 SO_TCPSTEALTH,
1482 &s->target,
1483 sizeof (struct GNUNET_PeerIdentity))) )
1484 {
1485 (void) close (ret);
1486 return CURL_SOCKET_BAD;
1487 }
1488 return (curl_socket_t) ret;
1489 case CURLSOCKTYPE_ACCEPT:
1490 GNUNET_break (0);
1491 return CURL_SOCKET_BAD;
1492 break;
1493 case CURLSOCKTYPE_LAST:
1494 GNUNET_break (0);
1495 return CURL_SOCKET_BAD;
1496 }
1497}
1498#endif
1499
1500
1431/** 1501/**
1432 * Connect GET request for a session 1502 * Connect GET request for a session
1433 * 1503 *
@@ -1438,82 +1508,152 @@ static int
1438client_connect_get (struct Session *s) 1508client_connect_get (struct Session *s)
1439{ 1509{
1440 CURLMcode mret; 1510 CURLMcode mret;
1511 struct HttpAddress *ha;
1512 uint32_t options;
1441 1513
1514 ha = (struct HttpAddress *) s->address->address;
1515 options = ntohl (ha->options);
1442 /* create get request */ 1516 /* create get request */
1443 s->get.easyhandle = curl_easy_init (); 1517 s->get.easyhandle = curl_easy_init ();
1444 s->get.s = s; 1518 s->get.s = s;
1519 if (0 != (options & HTTP_OPTIONS_TCP_STEALTH))
1520 {
1521#ifdef SO_TCPSTEALTH
1522 curl_easy_setopt (s->get.easyhandle,
1523 CURLOPT_OPENSOCKETFUNCTION,
1524 &open_tcp_stealth_socket_cb);
1525 curl_easy_setopt (s->get.easyhandle,
1526 CURLOPT_OPENSOCKETDATA,
1527 s);
1528#else
1529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1530 "Cannot connect, TCP STEALTH needed and not supported by kernel.\n");
1531 curl_easy_cleanup (s->get.easyhandle);
1532 s->get.easyhandle = NULL;
1533 s->get.s = NULL;
1534 return GNUNET_SYSERR;
1535#endif
1536 }
1537
1445#if VERBOSE_CURL 1538#if VERBOSE_CURL
1446 curl_easy_setopt (s->get.easyhandle, CURLOPT_VERBOSE, 1L); 1539 curl_easy_setopt (s->get.easyhandle,
1447 curl_easy_setopt (s->get.easyhandle, CURLOPT_DEBUGFUNCTION, &client_log); 1540 CURLOPT_VERBOSE,
1448 curl_easy_setopt (s->get.easyhandle, CURLOPT_DEBUGDATA, &s->get); 1541 1L);
1542 curl_easy_setopt (s->get.easyhandle,
1543 CURLOPT_DEBUGFUNCTION,
1544 &client_log);
1545 curl_easy_setopt (s->get.easyhandle,
1546 CURLOPT_DEBUGDATA,
1547 &s->get);
1449#endif 1548#endif
1450#if BUILD_HTTPS 1549#if BUILD_HTTPS
1451 curl_easy_setopt (s->get.easyhandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 1550 curl_easy_setopt (s->get.easyhandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
1452 { 1551 {
1453 struct HttpAddress *ha;
1454
1455 ha = (struct HttpAddress *) s->address->address;
1456
1457 if (HTTP_OPTIONS_VERIFY_CERTIFICATE == 1552 if (HTTP_OPTIONS_VERIFY_CERTIFICATE ==
1458 (ntohl (ha->options) & HTTP_OPTIONS_VERIFY_CERTIFICATE)) 1553 (options & HTTP_OPTIONS_VERIFY_CERTIFICATE))
1459 { 1554 {
1460 curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYPEER, 1L); 1555 curl_easy_setopt (s->get.easyhandle,
1461 curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYHOST, 2L); 1556 CURLOPT_SSL_VERIFYPEER, 1L);
1557 curl_easy_setopt (s->get.easyhandle,
1558 CURLOPT_SSL_VERIFYHOST,
1559 2L);
1462 } 1560 }
1463 else 1561 else
1464 { 1562 {
1465 curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYPEER, 0); 1563 curl_easy_setopt (s->get.easyhandle,
1466 curl_easy_setopt (s->get.easyhandle, CURLOPT_SSL_VERIFYHOST, 0); 1564 CURLOPT_SSL_VERIFYPEER,
1565 0L);
1566 curl_easy_setopt (s->get.easyhandle,
1567 CURLOPT_SSL_VERIFYHOST,
1568 0L);
1467 } 1569 }
1468 } 1570 }
1469 curl_easy_setopt (s->get.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); 1571 curl_easy_setopt (s->get.easyhandle,
1470 curl_easy_setopt (s->get.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); 1572 CURLOPT_PROTOCOLS,
1573 CURLPROTO_HTTPS);
1574 curl_easy_setopt (s->get.easyhandle,
1575 CURLOPT_REDIR_PROTOCOLS,
1576 CURLPROTO_HTTPS);
1471#else 1577#else
1472 curl_easy_setopt (s->get.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); 1578 curl_easy_setopt (s->get.easyhandle,
1473 curl_easy_setopt (s->get.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); 1579 CURLOPT_PROTOCOLS,
1580 CURLPROTO_HTTP);
1581 curl_easy_setopt (s->get.easyhandle,
1582 CURLOPT_REDIR_PROTOCOLS,
1583 CURLPROTO_HTTP);
1474#endif 1584#endif
1475 1585
1476 if (NULL != s->plugin->proxy_hostname) 1586 if (NULL != s->plugin->proxy_hostname)
1477 { 1587 {
1478 curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXY, s->plugin->proxy_hostname); 1588 curl_easy_setopt (s->get.easyhandle,
1479 curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXYTYPE, s->plugin->proxytype); 1589 CURLOPT_PROXY,
1590 s->plugin->proxy_hostname);
1591 curl_easy_setopt (s->get.easyhandle,
1592 CURLOPT_PROXYTYPE,
1593 s->plugin->proxytype);
1480 if (NULL != s->plugin->proxy_username) 1594 if (NULL != s->plugin->proxy_username)
1481 curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXYUSERNAME, 1595 curl_easy_setopt (s->get.easyhandle,
1482 s->plugin->proxy_username); 1596 CURLOPT_PROXYUSERNAME,
1597 s->plugin->proxy_username);
1483 if (NULL != s->plugin->proxy_password) 1598 if (NULL != s->plugin->proxy_password)
1484 curl_easy_setopt (s->get.easyhandle, CURLOPT_PROXYPASSWORD, 1599 curl_easy_setopt (s->get.easyhandle,
1485 s->plugin->proxy_password); 1600 CURLOPT_PROXYPASSWORD,
1601 s->plugin->proxy_password);
1486 if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel) 1602 if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel)
1487 curl_easy_setopt (s->get.easyhandle, CURLOPT_HTTPPROXYTUNNEL, 1603 curl_easy_setopt (s->get.easyhandle,
1488 s->plugin->proxy_use_httpproxytunnel); 1604 CURLOPT_HTTPPROXYTUNNEL,
1605 s->plugin->proxy_use_httpproxytunnel);
1489 } 1606 }
1490 1607
1491 if (GNUNET_YES == s->plugin->emulate_xhr) 1608 if (GNUNET_YES == s->plugin->emulate_xhr)
1492 { 1609 {
1493 char *url; 1610 char *url;
1494 1611
1495 GNUNET_asprintf(&url, "%s,1", s->url); 1612 GNUNET_asprintf (&url,
1496 curl_easy_setopt (s->get.easyhandle, CURLOPT_URL, url); 1613 "%s,1",
1614 s->url);
1615 curl_easy_setopt (s->get.easyhandle,
1616 CURLOPT_URL,
1617 url);
1497 GNUNET_free(url); 1618 GNUNET_free(url);
1498 } else 1619 }
1499 curl_easy_setopt (s->get.easyhandle, CURLOPT_URL, s->url); 1620 else
1500 //curl_easy_setopt (s->get.easyhandle, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); 1621 {
1501 //curl_easy_setopt (s->get.easyhandle, CURLOPT_WRITEHEADER, ps); 1622 curl_easy_setopt (s->get.easyhandle,
1502 curl_easy_setopt (s->get.easyhandle, CURLOPT_READFUNCTION, client_send_cb); 1623 CURLOPT_URL,
1503 curl_easy_setopt (s->get.easyhandle, CURLOPT_READDATA, s); 1624 s->url);
1504 curl_easy_setopt (s->get.easyhandle, CURLOPT_WRITEFUNCTION, client_receive); 1625 }
1505 curl_easy_setopt (s->get.easyhandle, CURLOPT_WRITEDATA, s); 1626 curl_easy_setopt (s->get.easyhandle,
1627 CURLOPT_READFUNCTION,
1628 &client_send_cb);
1629 curl_easy_setopt (s->get.easyhandle,
1630 CURLOPT_READDATA,
1631 s);
1632 curl_easy_setopt (s->get.easyhandle,
1633 CURLOPT_WRITEFUNCTION,
1634 &client_receive);
1635 curl_easy_setopt (s->get.easyhandle,
1636 CURLOPT_WRITEDATA,
1637 s);
1506 /* No timeout by default, timeout done with session timeout */ 1638 /* No timeout by default, timeout done with session timeout */
1507 curl_easy_setopt (s->get.easyhandle, CURLOPT_TIMEOUT, 0); 1639 curl_easy_setopt (s->get.easyhandle,
1508 curl_easy_setopt (s->get.easyhandle, CURLOPT_PRIVATE, s); 1640 CURLOPT_TIMEOUT,
1509 curl_easy_setopt (s->get.easyhandle, CURLOPT_CONNECTTIMEOUT_MS, 1641 0L);
1642 curl_easy_setopt (s->get.easyhandle,
1643 CURLOPT_PRIVATE, s);
1644 curl_easy_setopt (s->get.easyhandle,
1645 CURLOPT_CONNECTTIMEOUT_MS,
1510 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); 1646 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL));
1511 curl_easy_setopt (s->get.easyhandle, CURLOPT_BUFFERSIZE, 1647 curl_easy_setopt (s->get.easyhandle, CURLOPT_BUFFERSIZE,
1512 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 1648 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE);
1513#if CURL_TCP_NODELAY 1649#if CURL_TCP_NODELAY
1514 curl_easy_setopt (ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); 1650 curl_easy_setopt (ps->recv_endpoint,
1651 CURLOPT_TCP_NODELAY,
1652 1L);
1515#endif 1653#endif
1516 curl_easy_setopt (s->get.easyhandle, CURLOPT_FOLLOWLOCATION, 0); 1654 curl_easy_setopt (s->get.easyhandle,
1655 CURLOPT_FOLLOWLOCATION,
1656 0L);
1517 1657
1518 mret = curl_multi_add_handle (s->plugin->curl_multi_handle, 1658 mret = curl_multi_add_handle (s->plugin->curl_multi_handle,
1519 s->get.easyhandle); 1659 s->get.easyhandle);
@@ -1526,14 +1666,14 @@ client_connect_get (struct Session *s)
1526 curl_easy_cleanup (s->get.easyhandle); 1666 curl_easy_cleanup (s->get.easyhandle);
1527 s->get.easyhandle = NULL; 1667 s->get.easyhandle = NULL;
1528 s->get.s = NULL; 1668 s->get.s = NULL;
1529 s->get.easyhandle = NULL;
1530 GNUNET_break (0); 1669 GNUNET_break (0);
1531 return GNUNET_SYSERR; 1670 return GNUNET_SYSERR;
1532 } 1671 }
1533 s->plugin->cur_requests++; 1672 s->plugin->cur_requests++;
1534 LOG (GNUNET_ERROR_TYPE_INFO, 1673 LOG (GNUNET_ERROR_TYPE_INFO,
1535 "GET request `%s' established, number of requests increased to %u\n", 1674 "GET request `%s' established, number of requests increased to %u\n",
1536 s->url, s->plugin->cur_requests); 1675 s->url,
1676 s->plugin->cur_requests);
1537 return GNUNET_OK; 1677 return GNUNET_OK;
1538} 1678}
1539 1679
@@ -1548,19 +1688,51 @@ static int
1548client_connect_put (struct Session *s) 1688client_connect_put (struct Session *s)
1549{ 1689{
1550 CURLMcode mret; 1690 CURLMcode mret;
1691 struct HttpAddress *ha;
1692 uint32_t options;
1551 1693
1694 ha = (struct HttpAddress *) s->address->address;
1695 options = ntohl (ha->options);
1552 /* create put request */ 1696 /* create put request */
1553 LOG (GNUNET_ERROR_TYPE_DEBUG, 1697 LOG (GNUNET_ERROR_TYPE_DEBUG,
1554 "Session %p: Init PUT handle\n", s); 1698 "Session %p: Init PUT handle\n",
1699 s);
1555 s->put.easyhandle = curl_easy_init (); 1700 s->put.easyhandle = curl_easy_init ();
1556 s->put.s = s; 1701 s->put.s = s;
1557#if VERBOSE_CURL 1702#if VERBOSE_CURL
1558 curl_easy_setopt (s->put.easyhandle, CURLOPT_VERBOSE, 1L); 1703 curl_easy_setopt (s->put.easyhandle,
1559 curl_easy_setopt (s->put.easyhandle, CURLOPT_DEBUGFUNCTION, &client_log); 1704 CURLOPT_VERBOSE,
1560 curl_easy_setopt (s->put.easyhandle, CURLOPT_DEBUGDATA, &s->put); 1705 1L);
1706 curl_easy_setopt (s->put.easyhandle,
1707 CURLOPT_DEBUGFUNCTION,
1708 &client_log);
1709 curl_easy_setopt (s->put.easyhandle,
1710 CURLOPT_DEBUGDATA,
1711 &s->put);
1561#endif 1712#endif
1713 if (0 != (options & HTTP_OPTIONS_TCP_STEALTH))
1714 {
1715#ifdef SO_TCPSTEALTH
1716 curl_easy_setopt (s->put.easyhandle,
1717 CURLOPT_OPENSOCKETFUNCTION,
1718 &open_tcp_stealth_socket_cb);
1719 curl_easy_setopt (s->put.easyhandle,
1720 CURLOPT_OPENSOCKETDATA,
1721 s);
1722#else
1723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1724 "Cannot connect, TCP STEALTH needed and not supported by kernel.\n");
1725 curl_easy_cleanup (s->put.easyhandle);
1726 s->put.easyhandle = NULL;
1727 s->put.s = NULL;
1728 s->put.state = H_DISCONNECTED;
1729 return GNUNET_SYSERR;
1730#endif
1731 }
1562#if BUILD_HTTPS 1732#if BUILD_HTTPS
1563 curl_easy_setopt (s->put.easyhandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 1733 curl_easy_setopt (s->put.easyhandle,
1734 CURLOPT_SSLVERSION,
1735 CURL_SSLVERSION_TLSv1);
1564 { 1736 {
1565 struct HttpAddress *ha; 1737 struct HttpAddress *ha;
1566 ha = (struct HttpAddress *) s->address->address; 1738 ha = (struct HttpAddress *) s->address->address;
@@ -1568,48 +1740,86 @@ client_connect_put (struct Session *s)
1568 if (HTTP_OPTIONS_VERIFY_CERTIFICATE == 1740 if (HTTP_OPTIONS_VERIFY_CERTIFICATE ==
1569 (ntohl (ha->options) & HTTP_OPTIONS_VERIFY_CERTIFICATE)) 1741 (ntohl (ha->options) & HTTP_OPTIONS_VERIFY_CERTIFICATE))
1570 { 1742 {
1571 curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYPEER, 1L); 1743 curl_easy_setopt (s->put.easyhandle,
1572 curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYHOST, 2L); 1744 CURLOPT_SSL_VERIFYPEER,
1745 1L);
1746 curl_easy_setopt (s->put.easyhandle,
1747 CURLOPT_SSL_VERIFYHOST,
1748 2L);
1573 } 1749 }
1574 else 1750 else
1575 { 1751 {
1576 curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYPEER, 0); 1752 curl_easy_setopt (s->put.easyhandle,
1577 curl_easy_setopt (s->put.easyhandle, CURLOPT_SSL_VERIFYHOST, 0); 1753 CURLOPT_SSL_VERIFYPEER,
1754 0L);
1755 curl_easy_setopt (s->put.easyhandle,
1756 CURLOPT_SSL_VERIFYHOST,
1757 0L);
1578 } 1758 }
1579 } 1759 }
1580 curl_easy_setopt (s->put.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); 1760 curl_easy_setopt (s->put.easyhandle,
1581 curl_easy_setopt (s->put.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); 1761 CURLOPT_PROTOCOLS,
1762 CURLPROTO_HTTPS);
1763 curl_easy_setopt (s->put.easyhandle,
1764 CURLOPT_REDIR_PROTOCOLS,
1765 CURLPROTO_HTTPS);
1582#else 1766#else
1583 curl_easy_setopt (s->put.easyhandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); 1767 curl_easy_setopt (s->put.easyhandle,
1584 curl_easy_setopt (s->put.easyhandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); 1768 CURLOPT_PROTOCOLS,
1769 CURLPROTO_HTTP);
1770 curl_easy_setopt (s->put.easyhandle,
1771 CURLOPT_REDIR_PROTOCOLS,
1772 CURLPROTO_HTTP);
1585#endif 1773#endif
1586 if (s->plugin->proxy_hostname != NULL) 1774 if (NULL != s->plugin->proxy_hostname)
1587 { 1775 {
1588 curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXY, s->plugin->proxy_hostname); 1776 curl_easy_setopt (s->put.easyhandle,
1589 curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXYTYPE, s->plugin->proxytype); 1777 CURLOPT_PROXY,
1778 s->plugin->proxy_hostname);
1779 curl_easy_setopt (s->put.easyhandle,
1780 CURLOPT_PROXYTYPE,
1781 s->plugin->proxytype);
1590 if (NULL != s->plugin->proxy_username) 1782 if (NULL != s->plugin->proxy_username)
1591 curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXYUSERNAME, 1783 curl_easy_setopt (s->put.easyhandle,
1592 s->plugin->proxy_username); 1784 CURLOPT_PROXYUSERNAME,
1785 s->plugin->proxy_username);
1593 if (NULL != s->plugin->proxy_password) 1786 if (NULL != s->plugin->proxy_password)
1594 curl_easy_setopt (s->put.easyhandle, CURLOPT_PROXYPASSWORD, 1787 curl_easy_setopt (s->put.easyhandle,
1595 s->plugin->proxy_password); 1788 CURLOPT_PROXYPASSWORD,
1789 s->plugin->proxy_password);
1596 if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel) 1790 if (GNUNET_YES == s->plugin->proxy_use_httpproxytunnel)
1597 curl_easy_setopt (s->put.easyhandle, CURLOPT_HTTPPROXYTUNNEL, 1791 curl_easy_setopt (s->put.easyhandle,
1598 s->plugin->proxy_use_httpproxytunnel); 1792 CURLOPT_HTTPPROXYTUNNEL,
1793 s->plugin->proxy_use_httpproxytunnel);
1599 } 1794 }
1600 1795
1601 curl_easy_setopt (s->put.easyhandle, CURLOPT_URL, s->url); 1796 curl_easy_setopt (s->put.easyhandle,
1602 curl_easy_setopt (s->put.easyhandle, CURLOPT_UPLOAD, 1L); 1797 CURLOPT_URL,
1603 //curl_easy_setopt (s->put.easyhandle, CURLOPT_HEADERFUNCTION, &client_curl_header); 1798 s->url);
1604 //curl_easy_setopt (s->put.easyhandle, CURLOPT_WRITEHEADER, ps); 1799 curl_easy_setopt (s->put.easyhandle,
1605 curl_easy_setopt (s->put.easyhandle, CURLOPT_READFUNCTION, client_send_cb); 1800 CURLOPT_UPLOAD,
1606 curl_easy_setopt (s->put.easyhandle, CURLOPT_READDATA, s); 1801 1L);
1607 curl_easy_setopt (s->put.easyhandle, CURLOPT_WRITEFUNCTION, client_receive_put); 1802 curl_easy_setopt (s->put.easyhandle,
1608 curl_easy_setopt (s->put.easyhandle, CURLOPT_WRITEDATA, s); 1803 CURLOPT_READFUNCTION,
1804 &client_send_cb);
1805 curl_easy_setopt (s->put.easyhandle,
1806 CURLOPT_READDATA,
1807 s);
1808 curl_easy_setopt (s->put.easyhandle,
1809 CURLOPT_WRITEFUNCTION,
1810 &client_receive_put);
1811 curl_easy_setopt (s->put.easyhandle,
1812 CURLOPT_WRITEDATA,
1813 s);
1609 /* No timeout by default, timeout done with session timeout */ 1814 /* No timeout by default, timeout done with session timeout */
1610 curl_easy_setopt (s->put.easyhandle, CURLOPT_TIMEOUT, 0); 1815 curl_easy_setopt (s->put.easyhandle,
1611 curl_easy_setopt (s->put.easyhandle, CURLOPT_PRIVATE, s); 1816 CURLOPT_TIMEOUT,
1612 curl_easy_setopt (s->put.easyhandle, CURLOPT_CONNECTTIMEOUT_MS, 1817 0L);
1818 curl_easy_setopt (s->put.easyhandle,
1819 CURLOPT_PRIVATE,
1820 s);
1821 curl_easy_setopt (s->put.easyhandle,
1822 CURLOPT_CONNECTTIMEOUT_MS,
1613 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); 1823 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL));
1614 curl_easy_setopt (s->put.easyhandle, CURLOPT_BUFFERSIZE, 1824 curl_easy_setopt (s->put.easyhandle, CURLOPT_BUFFERSIZE,
1615 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 1825 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE);
@@ -1625,7 +1835,6 @@ client_connect_put (struct Session *s)
1625 s, curl_multi_strerror (mret)); 1835 s, curl_multi_strerror (mret));
1626 curl_easy_cleanup (s->put.easyhandle); 1836 curl_easy_cleanup (s->put.easyhandle);
1627 s->put.easyhandle = NULL; 1837 s->put.easyhandle = NULL;
1628 s->put.easyhandle = NULL;
1629 s->put.s = NULL; 1838 s->put.s = NULL;
1630 s->put.state = H_DISCONNECTED; 1839 s->put.state = H_DISCONNECTED;
1631 return GNUNET_SYSERR; 1840 return GNUNET_SYSERR;
@@ -1654,18 +1863,24 @@ client_connect (struct Session *s)
1654 int res = GNUNET_OK; 1863 int res = GNUNET_OK;
1655 1864
1656 /* create url */ 1865 /* create url */
1657 if (NULL == http_common_plugin_address_to_string(plugin->protocol, 1866 if (NULL ==
1658 s->address->address, s->address->address_length)) 1867 http_common_plugin_address_to_string(plugin->protocol,
1659 { 1868 s->address->address,
1660 LOG(GNUNET_ERROR_TYPE_DEBUG, "Invalid address peer `%s'\n", 1869 s->address->address_length))
1661 GNUNET_i2s(&s->address->peer)); 1870 {
1662 return GNUNET_SYSERR; 1871 LOG (GNUNET_ERROR_TYPE_DEBUG,
1663 } 1872 "Invalid address peer `%s'\n",
1873 GNUNET_i2s(&s->address->peer));
1874 return GNUNET_SYSERR;
1875 }
1664 1876
1665 GNUNET_asprintf(&s->url, "%s/%s;%u", 1877 GNUNET_asprintf(&s->url,
1666 http_common_plugin_address_to_url(NULL, s->address->address, 1878 "%s/%s;%u",
1667 s->address->address_length), 1879 http_common_plugin_address_to_url(NULL,
1668 GNUNET_i2s_full(plugin->env->my_identity), plugin->last_tag); 1880 s->address->address,
1881 s->address->address_length),
1882 GNUNET_i2s_full (plugin->env->my_identity),
1883 plugin->last_tag);
1669 1884
1670 plugin->last_tag++; 1885 plugin->last_tag++;
1671 LOG (GNUNET_ERROR_TYPE_DEBUG, 1886 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1798,7 +2013,9 @@ http_client_plugin_get_session (void *cls,
1798 /* Determine network location */ 2013 /* Determine network location */
1799 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 2014 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1800 ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED); 2015 ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED);
1801 sa = http_common_socket_from_address (address->address, address->address_length, &res); 2016 sa = http_common_socket_from_address (address->address,
2017 address->address_length,
2018 &res);
1802 if (GNUNET_SYSERR == res) 2019 if (GNUNET_SYSERR == res)
1803 return NULL; 2020 return NULL;
1804 if (GNUNET_YES == res) 2021 if (GNUNET_YES == res)
@@ -1975,7 +2192,6 @@ client_configure_plugin (struct HTTP_Client_Plugin *plugin)
1975 unsigned long long max_requests; 2192 unsigned long long max_requests;
1976 char *proxy_type; 2193 char *proxy_type;
1977 2194
1978
1979 /* Optional parameters */ 2195 /* Optional parameters */
1980 if (GNUNET_OK != 2196 if (GNUNET_OK !=
1981 GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, 2197 GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg,
@@ -1990,8 +2206,11 @@ client_configure_plugin (struct HTTP_Client_Plugin *plugin)
1990 plugin->max_requests); 2206 plugin->max_requests);
1991 2207
1992 /* Read proxy configuration */ 2208 /* Read proxy configuration */
1993 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, 2209 if (GNUNET_OK ==
1994 plugin->name, "PROXY", &plugin->proxy_hostname)) 2210 GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg,
2211 plugin->name,
2212 "PROXY",
2213 &plugin->proxy_hostname))
1995 { 2214 {
1996 LOG (GNUNET_ERROR_TYPE_DEBUG, 2215 LOG (GNUNET_ERROR_TYPE_DEBUG,
1997 "Found proxy host: `%s'\n", 2216 "Found proxy host: `%s'\n",