diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-06-06 11:54:13 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-06-06 11:54:13 +0000 |
commit | 7ea7c19ca80754addc4069865a674561b8d496d5 (patch) | |
tree | be69055fe4964cbaf1dc083356cb2d7274bd7ce5 /src/gns/gnunet-gns-proxy.c | |
parent | 8e32bc8869091470bd243fb78459cb9981d6a1fa (diff) | |
download | gnunet-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.c | 250 |
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 */ |
209 | static regex_t re_dotplus; | 221 | static regex_t re_dotplus; |
210 | 222 | ||
223 | /* The users local GNS zone hash */ | ||
224 | struct 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 | */ | ||
873 | static void | ||
874 | process_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 | */ |
854 | static void | 938 | static void |
855 | process_get_authority (void* cls, | 939 | process_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 | */ | ||
1255 | static void | ||
1256 | cleanup_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 | */ | ||
1921 | static int | ||
1922 | load_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, |