aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-proxy.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-06 11:54:13 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-06 11:54:13 +0000
commit7ea7c19ca80754addc4069865a674561b8d496d5 (patch)
treebe69055fe4964cbaf1dc083356cb2d7274bd7ce5 /src/gns/gnunet-gns-proxy.c
parent8e32bc8869091470bd243fb78459cb9981d6a1fa (diff)
downloadgnunet-7ea7c19ca80754addc4069865a674561b8d496d5.tar.gz
gnunet-7ea7c19ca80754addc4069865a674561b8d496d5.zip
-fixes, add leho
Diffstat (limited to 'src/gns/gnunet-gns-proxy.c')
-rw-r--r--src/gns/gnunet-gns-proxy.c250
1 files changed, 202 insertions, 48 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 7cea347e2..10a81b073 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -81,6 +81,12 @@ struct Socks5Request
81 81
82 /* Length of data in write buffer */ 82 /* Length of data in write buffer */
83 unsigned int wbuf_len; 83 unsigned int wbuf_len;
84
85 /* This handle is scheduled for cleanup? */
86 int cleanup;
87
88 /* Shall we close the client socket on cleanup? */
89 int cleanup_sock;
84}; 90};
85 91
86 92
@@ -122,6 +128,9 @@ struct ProxyCurlTask
122 /* Handle to cURL */ 128 /* Handle to cURL */
123 CURL *curl; 129 CURL *curl;
124 130
131 /* Optional header replacements for curl (LEHO) */
132 struct curl_slist *headers;
133
125 /* The URL to fetch */ 134 /* The URL to fetch */
126 char url[2048]; 135 char url[2048];
127 136
@@ -167,6 +176,9 @@ struct ProxyCurlTask
167 /* The hostname (Host header field) */ 176 /* The hostname (Host header field) */
168 char host[256]; 177 char host[256];
169 178
179 /* The LEgacy HOstname (can be empty) */
180 char leho[256];
181
170 /* The associated daemon list entry */ 182 /* The associated daemon list entry */
171 struct MhdHttpList *mhd; 183 struct MhdHttpList *mhd;
172 184
@@ -208,6 +220,8 @@ static struct MhdHttpList *mhd_httpd_tail;
208/* Handle to the regex for dotplus (.+) replacement in HTML */ 220/* Handle to the regex for dotplus (.+) replacement in HTML */
209static regex_t re_dotplus; 221static regex_t re_dotplus;
210 222
223/* The users local GNS zone hash */
224struct GNUNET_CRYPTO_ShortHashCode local_gns_zone;
211 225
212/** 226/**
213 * Checks if name is in tld 227 * Checks if name is in tld
@@ -395,9 +409,14 @@ mhd_content_free (void *cls)
395{ 409{
396 struct ProxyCurlTask *ctask = cls; 410 struct ProxyCurlTask *ctask = cls;
397 411
398 if (ctask->curl != NULL) 412 if (NULL != ctask->headers)
413 curl_slist_free_all (ctask->headers);
414
415 if (NULL != ctask->curl)
399 curl_easy_cleanup (ctask->curl); 416 curl_easy_cleanup (ctask->curl);
400 417
418 ctask->curl = NULL;
419
401 GNUNET_free (ctask); 420 GNUNET_free (ctask);
402 421
403} 422}
@@ -845,6 +864,71 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
845} 864}
846 865
847/** 866/**
867 * Process LEHO lookup
868 *
869 * @param cls the ctask
870 * @param rd_count number of records returned
871 * @param rd record data
872 */
873static void
874process_leho_lookup (void *cls,
875 uint32_t rd_count,
876 const struct GNUNET_NAMESTORE_RecordData *rd)
877{
878 struct ProxyCurlTask *ctask = cls;
879 char hosthdr[262]; //256 + "Host: "
880 int i;
881 CURLcode ret;
882 CURLMcode mret;
883
884 ctask->headers = NULL;
885
886 strcpy (ctask->leho, "");
887
888 for (i=0; i<rd_count; i++)
889 {
890 if (rd[i].record_type != GNUNET_GNS_RECORD_LEHO)
891 continue;
892
893 memcpy (ctask->leho, rd[i].data, rd[i].data_size);
894
895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
896 "Found LEHO %s for %s\n", ctask->leho, ctask->url);
897 }
898
899 if (0 != strcmp (ctask->leho, ""))
900 {
901 sprintf (hosthdr, "%s%s", "Host: ", ctask->leho);
902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
903 "New HTTP header value: %s\n", hosthdr);
904 ctask->headers = curl_slist_append (ctask->headers, hosthdr);
905 GNUNET_assert (NULL != ctask->headers);
906 ret = curl_easy_setopt (ctask->curl, CURLOPT_HTTPHEADER, ctask->headers);
907 if (CURLE_OK != ret)
908 {
909 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s failed at %s:%d: `%s'\n",
910 "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret));
911 }
912
913 }
914
915 if (CURLM_OK != (mret=curl_multi_add_handle (curl_multi, ctask->curl)))
916 {
917 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
918 "%s failed at %s:%d: `%s'\n",
919 "curl_multi_add_handle", __FILE__, __LINE__,
920 curl_multi_strerror (mret));
921 ctask->download_successful = GNUNET_NO;
922 ctask->download_error = GNUNET_YES;
923 return;
924 }
925 GNUNET_CONTAINER_DLL_insert (ctasks_head, ctasks_tail, ctask);
926
927 curl_download_prepare ();
928
929}
930
931/**
848 * Initialize download and trigger curl 932 * Initialize download and trigger curl
849 * 933 *
850 * @param cls the proxycurltask 934 * @param cls the proxycurltask
@@ -852,7 +936,7 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
852 * 936 *
853 */ 937 */
854static void 938static void
855process_get_authority (void* cls, 939process_get_authority (void *cls,
856 const char* auth_name) 940 const char* auth_name)
857{ 941{
858 struct ProxyCurlTask *ctask = cls; 942 struct ProxyCurlTask *ctask = cls;
@@ -868,7 +952,12 @@ process_get_authority (void* cls,
868 "Get authority yielded %s\n", auth_name); 952 "Get authority yielded %s\n", auth_name);
869 strcpy (ctask->authority, auth_name); 953 strcpy (ctask->authority, auth_name);
870 954
871 curl_download_prepare (); 955 GNUNET_GNS_lookup_zone (gns_handle,
956 ctask->host,
957 &local_gns_zone,
958 GNUNET_GNS_RECORD_LEHO,
959 &process_leho_lookup,
960 ctask);
872} 961}
873 962
874/** 963/**
@@ -912,7 +1001,6 @@ create_response (void *cls,
912 char curlurl[512]; 1001 char curlurl[512];
913 int ret = MHD_YES; 1002 int ret = MHD_YES;
914 1003
915 CURLMcode mret;
916 struct ProxyCurlTask *ctask; 1004 struct ProxyCurlTask *ctask;
917 1005
918 if (0 != strcmp (meth, "GET")) 1006 if (0 != strcmp (meth, "GET"))
@@ -981,29 +1069,6 @@ create_response (void *cls,
981 curl_easy_setopt (ctask->curl, CURLOPT_CONNECTTIMEOUT, 600L); 1069 curl_easy_setopt (ctask->curl, CURLOPT_CONNECTTIMEOUT, 600L);
982 curl_easy_setopt (ctask->curl, CURLOPT_TIMEOUT, 600L); 1070 curl_easy_setopt (ctask->curl, CURLOPT_TIMEOUT, 600L);
983 1071
984 mret = curl_multi_add_handle (curl_multi, ctask->curl);
985
986 if (mret != CURLM_OK)
987 {
988 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
989 "%s failed at %s:%d: `%s'\n",
990 "curl_multi_add_handle", __FILE__, __LINE__,
991 curl_multi_strerror (mret));
992 response = MHD_create_response_from_buffer (strlen (page),
993 (void*)page,
994 MHD_RESPMEM_PERSISTENT);
995 ret = MHD_queue_response (con,
996 MHD_HTTP_OK,
997 response);
998 MHD_destroy_response (response);
999
1000 curl_easy_cleanup (ctask->curl);
1001 GNUNET_free (ctask);
1002 return ret;
1003 }
1004
1005 GNUNET_CONTAINER_DLL_insert (ctasks_head, ctasks_tail, ctask);
1006
1007 GNUNET_GNS_get_authority (gns_handle, 1072 GNUNET_GNS_get_authority (gns_handle,
1008 ctask->host, 1073 ctask->host,
1009 &process_get_authority, 1074 &process_get_authority,
@@ -1183,6 +1248,29 @@ do_write_remote (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1183 1248
1184 1249
1185/** 1250/**
1251 * Clean up s5r handles
1252 *
1253 * @param s5r the handle to destroy
1254 */
1255static void
1256cleanup_s5r (struct Socks5Request *s5r)
1257{
1258 if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK)
1259 GNUNET_SCHEDULER_cancel (s5r->rtask);
1260 if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK)
1261 GNUNET_SCHEDULER_cancel (s5r->fwdwtask);
1262 if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK)
1263 GNUNET_SCHEDULER_cancel (s5r->fwdrtask);
1264
1265 if (NULL != s5r->remote_sock)
1266 GNUNET_NETWORK_socket_close (s5r->remote_sock);
1267 if ((NULL != s5r->sock) && (s5r->cleanup_sock == GNUNET_YES))
1268 GNUNET_NETWORK_socket_close (s5r->sock);
1269
1270 GNUNET_free(s5r);
1271}
1272
1273/**
1186 * Write data to socket 1274 * Write data to socket
1187 * 1275 *
1188 * @param cls the closure 1276 * @param cls the closure
@@ -1209,16 +1297,16 @@ do_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1209 { 1297 {
1210 1298
1211 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); 1299 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write");
1212 //Really!?!?!? 1300 s5r->cleanup = GNUNET_YES;
1213 if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK) 1301 s5r->cleanup_sock = GNUNET_YES;
1214 GNUNET_SCHEDULER_cancel (s5r->rtask); 1302 cleanup_s5r (s5r);
1215 if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK) 1303
1216 GNUNET_SCHEDULER_cancel (s5r->fwdwtask); 1304 return;
1217 if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK) 1305 }
1218 GNUNET_SCHEDULER_cancel (s5r->fwdrtask); 1306
1219 GNUNET_NETWORK_socket_close (s5r->remote_sock); 1307 if (GNUNET_YES == s5r->cleanup)
1220 GNUNET_NETWORK_socket_close (s5r->sock); 1308 {
1221 GNUNET_free(s5r); 1309 cleanup_s5r (s5r);
1222 return; 1310 return;
1223 } 1311 }
1224 1312
@@ -1542,14 +1630,12 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1542 _("Failed to start HTTP server\n")); 1630 _("Failed to start HTTP server\n"));
1543 s_resp->version = 0x05; 1631 s_resp->version = 0x05;
1544 s_resp->reply = 0x01; 1632 s_resp->reply = 0x01;
1633 s5r->cleanup = GNUNET_YES;
1634 s5r->cleanup_sock = GNUNET_YES;
1545 s5r->wtask = 1635 s5r->wtask =
1546 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 1636 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1547 s5r->sock, 1637 s5r->sock,
1548 &do_write, s5r); 1638 &do_write, s5r);
1549 //ERROR!
1550 //TODO! close socket after the write! schedule task
1551 //GNUNET_NETWORK_socket_close (s5r->sock);
1552 //GNUNET_free(s5r);
1553 return; 1639 return;
1554 } 1640 }
1555 1641
@@ -1558,14 +1644,14 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1558 s_resp->reply = 0x00; 1644 s_resp->reply = 0x00;
1559 s_resp->reserved = 0x00; 1645 s_resp->reserved = 0x00;
1560 s_resp->addr_type = 0x01; 1646 s_resp->addr_type = 0x01;
1561 1647
1648 s5r->cleanup = GNUNET_YES;
1649 s5r->cleanup_sock = GNUNET_NO;
1562 s5r->wtask = 1650 s5r->wtask =
1563 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 1651 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1564 s5r->sock, 1652 s5r->sock,
1565 &do_write, s5r); 1653 &do_write, s5r);
1566 run_httpds (); 1654 run_httpds ();
1567 //GNUNET_free ( s5r );
1568 //FIXME complete socks resp!
1569 return; 1655 return;
1570 } 1656 }
1571 else 1657 else
@@ -1577,14 +1663,12 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1577 "Resolve %s error!\n", domain ); 1663 "Resolve %s error!\n", domain );
1578 s_resp->version = 0x05; 1664 s_resp->version = 0x05;
1579 s_resp->reply = 0x01; 1665 s_resp->reply = 0x01;
1666 s5r->cleanup = GNUNET_YES;
1667 s5r->cleanup_sock = GNUNET_YES;
1580 s5r->wtask = 1668 s5r->wtask =
1581 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 1669 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1582 s5r->sock, 1670 s5r->sock,
1583 &do_write, s5r); 1671 &do_write, s5r);
1584 //ERROR!
1585 //TODO! close socket after the write! schedule task
1586 //GNUNET_NETWORK_socket_close (s5r->sock);
1587 //GNUNET_free(s5r);
1588 return; 1672 return;
1589 } 1673 }
1590 1674
@@ -1750,6 +1834,8 @@ do_shutdown (void *cls,
1750 1834
1751 struct MhdHttpList *hd; 1835 struct MhdHttpList *hd;
1752 struct MhdHttpList *tmp_hd; 1836 struct MhdHttpList *tmp_hd;
1837 struct ProxyCurlTask *ctask;
1838 struct ProxyCurlTask *ctask_tmp;
1753 1839
1754 if (GNUNET_SCHEDULER_NO_TASK != curl_download_task) 1840 if (GNUNET_SCHEDULER_NO_TASK != curl_download_task)
1755 { 1841 {
@@ -1782,6 +1868,22 @@ do_shutdown (void *cls,
1782 GNUNET_free (hd); 1868 GNUNET_free (hd);
1783 } 1869 }
1784 1870
1871 for (ctask=ctasks_head; ctask != NULL; ctask=ctask_tmp)
1872 {
1873 ctask_tmp = ctask->next;
1874
1875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1876 "Cleaning up cURL task\n");
1877
1878 if (ctask->curl != NULL)
1879 curl_easy_cleanup (ctask->curl);
1880 ctask->curl = NULL;
1881 if (NULL != ctask->headers)
1882 curl_slist_free_all (ctask->headers);
1883
1884 GNUNET_free (ctask);
1885 }
1886
1785 GNUNET_GNS_disconnect (gns_handle); 1887 GNUNET_GNS_disconnect (gns_handle);
1786} 1888}
1787 1889
@@ -1812,6 +1914,51 @@ compile_regex (regex_t *re, const char* rt)
1812 1914
1813 1915
1814/** 1916/**
1917 * Loads the users local zone key
1918 *
1919 * @return GNUNET_YES on success
1920 */
1921static int
1922load_local_zone_key (const struct GNUNET_CONFIGURATION_Handle *cfg)
1923{
1924 char *keyfile;
1925 struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL;
1926 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
1927 struct GNUNET_CRYPTO_ShortHashCode *zone = NULL;
1928 struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;
1929
1930 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
1931 "ZONEKEY", &keyfile))
1932 {
1933 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1934 "Unable to load zone key config value!\n");
1935 return GNUNET_NO;
1936 }
1937
1938 if (GNUNET_NO == GNUNET_DISK_file_test (keyfile))
1939 {
1940 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1941 "Unable to load zone key!\n");
1942 GNUNET_free(keyfile);
1943 return GNUNET_NO;
1944 }
1945
1946 key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1947 GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
1948 GNUNET_CRYPTO_short_hash(&pkey,
1949 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1950 &local_gns_zone);
1951 zone = &local_gns_zone;
1952 GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
1953 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1954 "Using zone: %s!\n", &zonename);
1955 GNUNET_CRYPTO_rsa_key_free(key);
1956 GNUNET_free(keyfile);
1957
1958 return GNUNET_YES;
1959}
1960
1961/**
1815 * Main function that will be run 1962 * Main function that will be run
1816 * 1963 *
1817 * @param cls closure 1964 * @param cls closure
@@ -1830,6 +1977,13 @@ run (void *cls, char *const *args, const char *cfgfile,
1830 1977
1831 gns_handle = GNUNET_GNS_connect (cfg); 1978 gns_handle = GNUNET_GNS_connect (cfg);
1832 1979
1980 if (GNUNET_NO == load_local_zone_key (cfg))
1981 {
1982 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1983 "Unable to load zone!\n");
1984 return;
1985 }
1986
1833 if (NULL == gns_handle) 1987 if (NULL == gns_handle)
1834 { 1988 {
1835 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1989 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,