aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-proxy.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-10-05 15:09:28 +0200
committerChristian Grothoff <christian@grothoff.org>2019-10-05 15:09:28 +0200
commitc4e9ba925ffd758aaa3feee2ccfc0b76f26fe207 (patch)
treecac3ce030d77b4cbe7c7dc62ed58cfe6d24f73e1 /src/gns/gnunet-gns-proxy.c
parentfbb71d527c7d6babf269a8fefce1db291b9f7068 (diff)
downloadgnunet-c4e9ba925ffd758aaa3feee2ccfc0b76f26fe207.tar.gz
gnunet-c4e9ba925ffd758aaa3feee2ccfc0b76f26fe207.zip
global reindent, now with uncrustify hook enabled
Diffstat (limited to 'src/gns/gnunet-gns-proxy.c')
-rw-r--r--src/gns/gnunet-gns-proxy.c4189
1 files changed, 2112 insertions, 2077 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 6285a8fcd..2a39efef2 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -94,13 +94,15 @@
94/** 94/**
95 * After how long do we clean up unused MHD TLS instances? 95 * After how long do we clean up unused MHD TLS instances?
96 */ 96 */
97#define MHD_CACHE_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) 97#define MHD_CACHE_TIMEOUT GNUNET_TIME_relative_multiply ( \
98 GNUNET_TIME_UNIT_MINUTES, 5)
98 99
99/** 100/**
100 * After how long do we clean up Socks5 handles that failed to show any activity 101 * After how long do we clean up Socks5 handles that failed to show any activity
101 * with their respective MHD instance? 102 * with their respective MHD instance?
102 */ 103 */
103#define HTTP_HANDSHAKE_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 15) 104#define HTTP_HANDSHAKE_TIMEOUT GNUNET_TIME_relative_multiply ( \
105 GNUNET_TIME_UNIT_SECONDS, 15)
104 106
105 107
106/** 108/**
@@ -111,12 +113,12 @@
111 * @param rc return code from curl 113 * @param rc return code from curl
112 */ 114 */
113#define LOG_CURL_EASY(level, fun, rc) \ 115#define LOG_CURL_EASY(level, fun, rc) \
114 GNUNET_log(level, \ 116 GNUNET_log (level, \
115 _("%s failed at %s:%d: `%s'\n"), \ 117 _ ("%s failed at %s:%d: `%s'\n"), \
116 fun, \ 118 fun, \
117 __FILE__, \ 119 __FILE__, \
118 __LINE__, \ 120 __LINE__, \
119 curl_easy_strerror(rc)) 121 curl_easy_strerror (rc))
120 122
121 123
122/* *************** Socks protocol definitions (move to TUN?) ****************** */ 124/* *************** Socks protocol definitions (move to TUN?) ****************** */
@@ -135,7 +137,8 @@
135/** 137/**
136 * Commands in Socks5. 138 * Commands in Socks5.
137 */ 139 */
138enum Socks5Commands { 140enum Socks5Commands
141{
139 /** 142 /**
140 * Establish TCP/IP stream. 143 * Establish TCP/IP stream.
141 */ 144 */
@@ -156,7 +159,8 @@ enum Socks5Commands {
156/** 159/**
157 * Address types in Socks5. 160 * Address types in Socks5.
158 */ 161 */
159enum Socks5AddressType { 162enum Socks5AddressType
163{
160 /** 164 /**
161 * IPv4 address. 165 * IPv4 address.
162 */ 166 */
@@ -177,7 +181,8 @@ enum Socks5AddressType {
177/** 181/**
178 * Status codes in Socks5 response. 182 * Status codes in Socks5 response.
179 */ 183 */
180enum Socks5StatusCode { 184enum Socks5StatusCode
185{
181 SOCKS5_STATUS_REQUEST_GRANTED = 0, 186 SOCKS5_STATUS_REQUEST_GRANTED = 0,
182 SOCKS5_STATUS_GENERAL_FAILURE = 1, 187 SOCKS5_STATUS_GENERAL_FAILURE = 1,
183 SOCKS5_STATUS_CONNECTION_NOT_ALLOWED_BY_RULE = 2, 188 SOCKS5_STATUS_CONNECTION_NOT_ALLOWED_BY_RULE = 2,
@@ -193,7 +198,8 @@ enum Socks5StatusCode {
193/** 198/**
194 * Client hello in Socks5 protocol. 199 * Client hello in Socks5 protocol.
195 */ 200 */
196struct Socks5ClientHelloMessage { 201struct Socks5ClientHelloMessage
202{
197 /** 203 /**
198 * Should be #SOCKS_VERSION_5. 204 * Should be #SOCKS_VERSION_5.
199 */ 205 */
@@ -211,7 +217,8 @@ struct Socks5ClientHelloMessage {
211/** 217/**
212 * Server hello in Socks5 protocol. 218 * Server hello in Socks5 protocol.
213 */ 219 */
214struct Socks5ServerHelloMessage { 220struct Socks5ServerHelloMessage
221{
215 /** 222 /**
216 * Should be #SOCKS_VERSION_5. 223 * Should be #SOCKS_VERSION_5.
217 */ 224 */
@@ -228,7 +235,8 @@ struct Socks5ServerHelloMessage {
228/** 235/**
229 * Client socks request in Socks5 protocol. 236 * Client socks request in Socks5 protocol.
230 */ 237 */
231struct Socks5ClientRequestMessage { 238struct Socks5ClientRequestMessage
239{
232 /** 240 /**
233 * Should be #SOCKS_VERSION_5. 241 * Should be #SOCKS_VERSION_5.
234 */ 242 */
@@ -260,7 +268,8 @@ struct Socks5ClientRequestMessage {
260/** 268/**
261 * Server response to client requests in Socks5 protocol. 269 * Server response to client requests in Socks5 protocol.
262 */ 270 */
263struct Socks5ServerResponseMessage { 271struct Socks5ServerResponseMessage
272{
264 /** 273 /**
265 * Should be #SOCKS_VERSION_5. 274 * Should be #SOCKS_VERSION_5.
266 */ 275 */
@@ -295,7 +304,8 @@ struct Socks5ServerResponseMessage {
295/** 304/**
296 * A structure for CA cert/key 305 * A structure for CA cert/key
297 */ 306 */
298struct ProxyCA { 307struct ProxyCA
308{
299 /** 309 /**
300 * The certificate 310 * The certificate
301 */ 311 */
@@ -311,7 +321,8 @@ struct ProxyCA {
311/** 321/**
312 * Structure for GNS certificates 322 * Structure for GNS certificates
313 */ 323 */
314struct ProxyGNSCertificate { 324struct ProxyGNSCertificate
325{
315 /** 326 /**
316 * The certificate as PEM 327 * The certificate as PEM
317 */ 328 */
@@ -328,7 +339,8 @@ struct ProxyGNSCertificate {
328/** 339/**
329 * A structure for all running Httpds 340 * A structure for all running Httpds
330 */ 341 */
331struct MhdHttpList { 342struct MhdHttpList
343{
332 /** 344 /**
333 * DLL for httpds 345 * DLL for httpds
334 */ 346 */
@@ -372,7 +384,8 @@ struct MhdHttpList {
372/** 384/**
373 * The socks phases. 385 * The socks phases.
374 */ 386 */
375enum SocksPhase { 387enum SocksPhase
388{
376 /** 389 /**
377 * We're waiting to get the client hello. 390 * We're waiting to get the client hello.
378 */ 391 */
@@ -428,7 +441,8 @@ enum SocksPhase {
428/** 441/**
429 * A header list 442 * A header list
430 */ 443 */
431struct HttpResponseHeader { 444struct HttpResponseHeader
445{
432 /** 446 /**
433 * DLL 447 * DLL
434 */ 448 */
@@ -453,7 +467,8 @@ struct HttpResponseHeader {
453/** 467/**
454 * A structure for socks requests 468 * A structure for socks requests
455 */ 469 */
456struct Socks5Request { 470struct Socks5Request
471{
457 /** 472 /**
458 * DLL. 473 * DLL.
459 */ 474 */
@@ -673,17 +688,17 @@ static struct GNUNET_NETWORK_Handle *lsock6;
673/** 688/**
674 * The listen task ID for IPv4 689 * The listen task ID for IPv4
675 */ 690 */
676static struct GNUNET_SCHEDULER_Task * ltask4; 691static struct GNUNET_SCHEDULER_Task *ltask4;
677 692
678/** 693/**
679 * The listen task ID for IPv6 694 * The listen task ID for IPv6
680 */ 695 */
681static struct GNUNET_SCHEDULER_Task * ltask6; 696static struct GNUNET_SCHEDULER_Task *ltask6;
682 697
683/** 698/**
684 * The cURL download task (curl multi API). 699 * The cURL download task (curl multi API).
685 */ 700 */
686static struct GNUNET_SCHEDULER_Task * curl_download_task; 701static struct GNUNET_SCHEDULER_Task *curl_download_task;
687 702
688/** 703/**
689 * The cURL multi handle 704 * The cURL multi handle
@@ -751,7 +766,7 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
751 * @param hd the daemon to run now. 766 * @param hd the daemon to run now.
752 */ 767 */
753static void 768static void
754run_mhd_now(struct MhdHttpList *hd); 769run_mhd_now (struct MhdHttpList *hd);
755 770
756 771
757/** 772/**
@@ -760,79 +775,79 @@ run_mhd_now(struct MhdHttpList *hd);
760 * @param s5r the handle to destroy 775 * @param s5r the handle to destroy
761 */ 776 */
762static void 777static void
763cleanup_s5r(struct Socks5Request *s5r) 778cleanup_s5r (struct Socks5Request *s5r)
764{ 779{
765 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
766 "Cleaning up socks request\n"); 781 "Cleaning up socks request\n");
767 if (NULL != s5r->curl) 782 if (NULL != s5r->curl)
768 { 783 {
769 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "Cleaning up cURL handle\n"); 785 "Cleaning up cURL handle\n");
771 curl_multi_remove_handle(curl_multi, 786 curl_multi_remove_handle (curl_multi,
772 s5r->curl); 787 s5r->curl);
773 curl_easy_cleanup(s5r->curl); 788 curl_easy_cleanup (s5r->curl);
774 s5r->curl = NULL; 789 s5r->curl = NULL;
775 } 790 }
776 if (s5r->suspended) 791 if (s5r->suspended)
777 { 792 {
778 s5r->suspended = GNUNET_NO; 793 s5r->suspended = GNUNET_NO;
779 MHD_resume_connection(s5r->con); 794 MHD_resume_connection (s5r->con);
780 } 795 }
781 curl_slist_free_all(s5r->headers); 796 curl_slist_free_all (s5r->headers);
782 if (NULL != s5r->hosts) 797 if (NULL != s5r->hosts)
783 { 798 {
784 curl_slist_free_all(s5r->hosts); 799 curl_slist_free_all (s5r->hosts);
785 } 800 }
786 if ((NULL != s5r->response) && 801 if ((NULL != s5r->response) &&
787 (curl_failure_response != s5r->response)) 802 (curl_failure_response != s5r->response))
788 { 803 {
789 MHD_destroy_response(s5r->response); 804 MHD_destroy_response (s5r->response);
790 s5r->response = NULL; 805 s5r->response = NULL;
791 } 806 }
792 if (NULL != s5r->rtask) 807 if (NULL != s5r->rtask)
793 { 808 {
794 GNUNET_SCHEDULER_cancel(s5r->rtask); 809 GNUNET_SCHEDULER_cancel (s5r->rtask);
795 s5r->rtask = NULL; 810 s5r->rtask = NULL;
796 } 811 }
797 if (NULL != s5r->timeout_task) 812 if (NULL != s5r->timeout_task)
798 { 813 {
799 GNUNET_SCHEDULER_cancel(s5r->timeout_task); 814 GNUNET_SCHEDULER_cancel (s5r->timeout_task);
800 s5r->timeout_task = NULL; 815 s5r->timeout_task = NULL;
801 } 816 }
802 if (NULL != s5r->wtask) 817 if (NULL != s5r->wtask)
803 { 818 {
804 GNUNET_SCHEDULER_cancel(s5r->wtask); 819 GNUNET_SCHEDULER_cancel (s5r->wtask);
805 s5r->wtask = NULL; 820 s5r->wtask = NULL;
806 } 821 }
807 if (NULL != s5r->gns_lookup) 822 if (NULL != s5r->gns_lookup)
808 { 823 {
809 GNUNET_GNS_lookup_with_tld_cancel(s5r->gns_lookup); 824 GNUNET_GNS_lookup_with_tld_cancel (s5r->gns_lookup);
810 s5r->gns_lookup = NULL; 825 s5r->gns_lookup = NULL;
811 } 826 }
812 if (NULL != s5r->sock) 827 if (NULL != s5r->sock)
813 { 828 {
814 if (SOCKS5_SOCKET_WITH_MHD <= s5r->state) 829 if (SOCKS5_SOCKET_WITH_MHD <= s5r->state)
815 GNUNET_NETWORK_socket_free_memory_only_(s5r->sock); 830 GNUNET_NETWORK_socket_free_memory_only_ (s5r->sock);
816 else 831 else
817 GNUNET_NETWORK_socket_close(s5r->sock); 832 GNUNET_NETWORK_socket_close (s5r->sock);
818 s5r->sock = NULL; 833 s5r->sock = NULL;
819 } 834 }
820 GNUNET_CONTAINER_DLL_remove(s5r_head, 835 GNUNET_CONTAINER_DLL_remove (s5r_head,
821 s5r_tail, 836 s5r_tail,
822 s5r); 837 s5r);
823 GNUNET_free_non_null(s5r->domain); 838 GNUNET_free_non_null (s5r->domain);
824 GNUNET_free_non_null(s5r->leho); 839 GNUNET_free_non_null (s5r->leho);
825 GNUNET_free_non_null(s5r->url); 840 GNUNET_free_non_null (s5r->url);
826 for (unsigned int i = 0; i < s5r->num_danes; i++) 841 for (unsigned int i = 0; i < s5r->num_danes; i++)
827 GNUNET_free(s5r->dane_data[i]); 842 GNUNET_free (s5r->dane_data[i]);
828 GNUNET_free(s5r); 843 GNUNET_free (s5r);
829} 844}
830 845
831 846
832/* ************************* HTTP handling with cURL *********************** */ 847/* ************************* HTTP handling with cURL *********************** */
833 848
834static void 849static void
835curl_download_prepare(); 850curl_download_prepare ();
836 851
837 852
838/** 853/**
@@ -847,89 +862,89 @@ curl_download_prepare();
847 * @return number of bytes written to @a buf 862 * @return number of bytes written to @a buf
848 */ 863 */
849static ssize_t 864static ssize_t
850mhd_content_cb(void *cls, 865mhd_content_cb (void *cls,
851 uint64_t pos, 866 uint64_t pos,
852 char* buf, 867 char*buf,
853 size_t max) 868 size_t max)
854{ 869{
855 struct Socks5Request *s5r = cls; 870 struct Socks5Request *s5r = cls;
856 size_t bytes_to_copy; 871 size_t bytes_to_copy;
857 872
858 if ((SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) || 873 if ((SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) ||
859 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state)) 874 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state))
860 { 875 {
861 /* we're still not done with the upload, do not yet 876 /* we're still not done with the upload, do not yet
862 start the download, the IO buffer is still full 877 start the download, the IO buffer is still full
863 with upload data. */ 878 with upload data. */
864 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 879 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
865 "Pausing MHD download %s%s, not yet ready for download\n", 880 "Pausing MHD download %s%s, not yet ready for download\n",
866 s5r->domain, 881 s5r->domain,
867 s5r->url); 882 s5r->url);
868 return 0; /* not yet ready for data download */ 883 return 0; /* not yet ready for data download */
869 } 884 }
870 bytes_to_copy = GNUNET_MIN(max, 885 bytes_to_copy = GNUNET_MIN (max,
871 s5r->io_len); 886 s5r->io_len);
872 if ((0 == bytes_to_copy) && 887 if ((0 == bytes_to_copy) &&
873 (SOCKS5_SOCKET_DOWNLOAD_DONE != s5r->state)) 888 (SOCKS5_SOCKET_DOWNLOAD_DONE != s5r->state))
889 {
890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
891 "Pausing MHD download %s%s, no data available\n",
892 s5r->domain,
893 s5r->url);
894 if (NULL != s5r->curl)
895 {
896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
897 "Continuing CURL interaction for %s%s\n",
898 s5r->domain,
899 s5r->url);
900 if (GNUNET_YES == s5r->curl_paused)
901 {
902 s5r->curl_paused = GNUNET_NO;
903 curl_easy_pause (s5r->curl,
904 CURLPAUSE_CONT);
905 }
906 curl_download_prepare ();
907 }
908 if (GNUNET_NO == s5r->suspended)
874 { 909 {
875 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 910 MHD_suspend_connection (s5r->con);
876 "Pausing MHD download %s%s, no data available\n", 911 s5r->suspended = GNUNET_YES;
877 s5r->domain,
878 s5r->url);
879 if (NULL != s5r->curl)
880 {
881 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
882 "Continuing CURL interaction for %s%s\n",
883 s5r->domain,
884 s5r->url);
885 if (GNUNET_YES == s5r->curl_paused)
886 {
887 s5r->curl_paused = GNUNET_NO;
888 curl_easy_pause(s5r->curl,
889 CURLPAUSE_CONT);
890 }
891 curl_download_prepare();
892 }
893 if (GNUNET_NO == s5r->suspended)
894 {
895 MHD_suspend_connection(s5r->con);
896 s5r->suspended = GNUNET_YES;
897 }
898 return 0; /* more data later */
899 } 912 }
913 return 0; /* more data later */
914 }
900 if ((0 == bytes_to_copy) && 915 if ((0 == bytes_to_copy) &&
901 (SOCKS5_SOCKET_DOWNLOAD_DONE == s5r->state)) 916 (SOCKS5_SOCKET_DOWNLOAD_DONE == s5r->state))
902 { 917 {
903 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
904 "Completed MHD download %s%s\n", 919 "Completed MHD download %s%s\n",
905 s5r->domain, 920 s5r->domain,
906 s5r->url); 921 s5r->url);
907 return MHD_CONTENT_READER_END_OF_STREAM; 922 return MHD_CONTENT_READER_END_OF_STREAM;
908 } 923 }
909 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
910 "Writing %llu/%llu bytes to %s%s\n", 925 "Writing %llu/%llu bytes to %s%s\n",
911 (unsigned long long)bytes_to_copy, 926 (unsigned long long) bytes_to_copy,
912 (unsigned long long)s5r->io_len, 927 (unsigned long long) s5r->io_len,
913 s5r->domain, 928 s5r->domain,
914 s5r->url); 929 s5r->url);
915 GNUNET_memcpy(buf, 930 GNUNET_memcpy (buf,
916 s5r->io_buf, 931 s5r->io_buf,
917 bytes_to_copy); 932 bytes_to_copy);
918 memmove(s5r->io_buf, 933 memmove (s5r->io_buf,
919 &s5r->io_buf[bytes_to_copy], 934 &s5r->io_buf[bytes_to_copy],
920 s5r->io_len - bytes_to_copy); 935 s5r->io_len - bytes_to_copy);
921 s5r->io_len -= bytes_to_copy; 936 s5r->io_len -= bytes_to_copy;
922 if ((NULL != s5r->curl) && 937 if ((NULL != s5r->curl) &&
923 (GNUNET_YES == s5r->curl_paused)) 938 (GNUNET_YES == s5r->curl_paused))
924 { 939 {
925 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
926 "Continuing CURL interaction for %s%s\n", 941 "Continuing CURL interaction for %s%s\n",
927 s5r->domain, 942 s5r->domain,
928 s5r->url); 943 s5r->url);
929 s5r->curl_paused = GNUNET_NO; 944 s5r->curl_paused = GNUNET_NO;
930 curl_easy_pause(s5r->curl, 945 curl_easy_pause (s5r->curl,
931 CURLPAUSE_CONT); 946 CURLPAUSE_CONT);
932 } 947 }
933 return bytes_to_copy; 948 return bytes_to_copy;
934} 949}
935 950
@@ -943,7 +958,7 @@ mhd_content_cb(void *cls,
943 * @return #GNUNET_OK if the certificate is valid 958 * @return #GNUNET_OK if the certificate is valid
944 */ 959 */
945static int 960static int
946check_ssl_certificate(struct Socks5Request *s5r) 961check_ssl_certificate (struct Socks5Request *s5r)
947{ 962{
948 unsigned int cert_list_size; 963 unsigned int cert_list_size;
949 const gnutls_datum_t *chainp; 964 const gnutls_datum_t *chainp;
@@ -955,113 +970,115 @@ check_ssl_certificate(struct Socks5Request *s5r)
955 const char *name; 970 const char *name;
956 971
957 s5r->ssl_checked = GNUNET_YES; 972 s5r->ssl_checked = GNUNET_YES;
958 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 973 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
959 "Checking X.509 certificate\n"); 974 "Checking X.509 certificate\n");
960 if (CURLE_OK != 975 if (CURLE_OK !=
961 curl_easy_getinfo(s5r->curl, 976 curl_easy_getinfo (s5r->curl,
962 CURLINFO_TLS_SESSION, 977 CURLINFO_TLS_SESSION,
963 &tlsinfo)) 978 &tlsinfo))
964 return GNUNET_SYSERR; 979 return GNUNET_SYSERR;
965 if (CURLSSLBACKEND_GNUTLS != tlsinfo->backend) 980 if (CURLSSLBACKEND_GNUTLS != tlsinfo->backend)
966 { 981 {
967 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 982 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
968 _("Unsupported CURL TLS backend %d\n"), 983 _ ("Unsupported CURL TLS backend %d\n"),
969 tlsinfo->backend); 984 tlsinfo->backend);
970 return GNUNET_SYSERR; 985 return GNUNET_SYSERR;
971 } 986 }
972 chainp = gnutls_certificate_get_peers(tlsinfo->internals, 987 chainp = gnutls_certificate_get_peers (tlsinfo->internals,
973 &cert_list_size); 988 &cert_list_size);
974 if ((!chainp) || 989 if ((! chainp) ||
975 (0 == cert_list_size)) 990 (0 == cert_list_size))
976 return GNUNET_SYSERR; 991 return GNUNET_SYSERR;
977 992
978 size = sizeof(certdn); 993 size = sizeof(certdn);
979 /* initialize an X.509 certificate structure. */ 994 /* initialize an X.509 certificate structure. */
980 gnutls_x509_crt_init(&x509_cert); 995 gnutls_x509_crt_init (&x509_cert);
981 gnutls_x509_crt_import(x509_cert, 996 gnutls_x509_crt_import (x509_cert,
982 chainp, 997 chainp,
983 GNUTLS_X509_FMT_DER); 998 GNUTLS_X509_FMT_DER);
984 999
985 if (0 != (rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, 1000 if (0 != (rc = gnutls_x509_crt_get_dn_by_oid (x509_cert,
986 GNUTLS_OID_X520_COMMON_NAME, 1001 GNUTLS_OID_X520_COMMON_NAME,
987 0, /* the first and only one */ 1002 0, /* the first and only one */
988 0 /* no DER encoding */, 1003 0 /* no DER encoding */,
989 certdn, 1004 certdn,
990 &size))) 1005 &size)))
991 { 1006 {
992 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1007 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
993 _("Failed to fetch CN from cert: %s\n"), 1008 _ ("Failed to fetch CN from cert: %s\n"),
994 gnutls_strerror(rc)); 1009 gnutls_strerror (rc));
995 gnutls_x509_crt_deinit(x509_cert); 1010 gnutls_x509_crt_deinit (x509_cert);
996 return GNUNET_SYSERR; 1011 return GNUNET_SYSERR;
997 } 1012 }
998 /* check for TLSA/DANE records */ 1013 /* check for TLSA/DANE records */
999#if HAVE_GNUTLS_DANE 1014#if HAVE_GNUTLS_DANE
1000 if (0 != s5r->num_danes) 1015 if (0 != s5r->num_danes)
1001 { 1016 {
1002 dane_state_t dane_state; 1017 dane_state_t dane_state;
1003 dane_query_t dane_query; 1018 dane_query_t dane_query;
1004 unsigned int verify; 1019 unsigned int verify;
1005 1020
1006 /* FIXME: add flags to gnutls to NOT read UNBOUND_ROOT_KEY_FILE here! */ 1021 /* FIXME: add flags to gnutls to NOT read UNBOUND_ROOT_KEY_FILE here! */
1007 if (0 != (rc = dane_state_init(&dane_state, 1022 if (0 != (rc = dane_state_init (&dane_state,
1008#ifdef DANE_F_IGNORE_DNSSEC 1023#ifdef DANE_F_IGNORE_DNSSEC
1009 DANE_F_IGNORE_DNSSEC | 1024 DANE_F_IGNORE_DNSSEC |
1010#endif 1025#endif
1011 DANE_F_IGNORE_LOCAL_RESOLVER))) 1026 DANE_F_IGNORE_LOCAL_RESOLVER)))
1012 { 1027 {
1013 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1028 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1014 _("Failed to initialize DANE: %s\n"), 1029 _ ("Failed to initialize DANE: %s\n"),
1015 dane_strerror(rc)); 1030 dane_strerror (rc));
1016 gnutls_x509_crt_deinit(x509_cert); 1031 gnutls_x509_crt_deinit (x509_cert);
1017 return GNUNET_SYSERR; 1032 return GNUNET_SYSERR;
1018 } 1033 }
1019 s5r->dane_data[s5r->num_danes] = NULL; 1034 s5r->dane_data[s5r->num_danes] = NULL;
1020 s5r->dane_data_len[s5r->num_danes] = 0; 1035 s5r->dane_data_len[s5r->num_danes] = 0;
1021 if (0 != (rc = dane_raw_tlsa(dane_state, 1036 if (0 != (rc = dane_raw_tlsa (dane_state,
1022 &dane_query, 1037 &dane_query,
1023 s5r->dane_data, 1038 s5r->dane_data,
1024 s5r->dane_data_len, 1039 s5r->dane_data_len,
1025 GNUNET_YES, 1040 GNUNET_YES,
1026 GNUNET_NO))) 1041 GNUNET_NO)))
1027 { 1042 {
1028 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1043 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1029 _("Failed to parse DANE record: %s\n"), 1044 _ ("Failed to parse DANE record: %s\n"),
1030 dane_strerror(rc)); 1045 dane_strerror (rc));
1031 dane_state_deinit(dane_state); 1046 dane_state_deinit (dane_state);
1032 gnutls_x509_crt_deinit(x509_cert); 1047 gnutls_x509_crt_deinit (x509_cert);
1033 return GNUNET_SYSERR; 1048 return GNUNET_SYSERR;
1034 } 1049 }
1035 if (0 != (rc = dane_verify_crt_raw(dane_state, 1050 if (0 != (rc = dane_verify_crt_raw (dane_state,
1036 chainp, 1051 chainp,
1037 cert_list_size, 1052 cert_list_size,
1038 gnutls_certificate_type_get(tlsinfo->internals), 1053 gnutls_certificate_type_get (
1039 dane_query, 1054 tlsinfo->internals),
1040 0, 0, 1055 dane_query,
1041 &verify))) 1056 0, 0,
1042 { 1057 &verify)))
1043 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1058 {
1044 _("Failed to verify TLS connection using DANE: %s\n"), 1059 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1045 dane_strerror(rc)); 1060 _ ("Failed to verify TLS connection using DANE: %s\n"),
1046 dane_query_deinit(dane_query); 1061 dane_strerror (rc));
1047 dane_state_deinit(dane_state); 1062 dane_query_deinit (dane_query);
1048 gnutls_x509_crt_deinit(x509_cert); 1063 dane_state_deinit (dane_state);
1049 return GNUNET_SYSERR; 1064 gnutls_x509_crt_deinit (x509_cert);
1050 } 1065 return GNUNET_SYSERR;
1051 if (0 != verify) 1066 }
1052 { 1067 if (0 != verify)
1053 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1068 {
1054 _("Failed DANE verification failed with GnuTLS verify status code: %u\n"), 1069 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1055 verify); 1070 _ (
1056 dane_query_deinit(dane_query); 1071 "Failed DANE verification failed with GnuTLS verify status code: %u\n"),
1057 dane_state_deinit(dane_state); 1072 verify);
1058 gnutls_x509_crt_deinit(x509_cert); 1073 dane_query_deinit (dane_query);
1059 return GNUNET_SYSERR; 1074 dane_state_deinit (dane_state);
1060 } 1075 gnutls_x509_crt_deinit (x509_cert);
1061 dane_query_deinit(dane_query); 1076 return GNUNET_SYSERR;
1062 dane_state_deinit(dane_state);
1063 /* success! */
1064 } 1077 }
1078 dane_query_deinit (dane_query);
1079 dane_state_deinit (dane_state);
1080 /* success! */
1081 }
1065 else 1082 else
1066#endif 1083#endif
1067 { 1084 {
@@ -1070,27 +1087,28 @@ check_ssl_certificate(struct Socks5Request *s5r)
1070 if (NULL != s5r->leho) 1087 if (NULL != s5r->leho)
1071 name = s5r->leho; 1088 name = s5r->leho;
1072 if (NULL != name) 1089 if (NULL != name)
1090 {
1091 if (0 == (rc = gnutls_x509_crt_check_hostname (x509_cert,
1092 name)))
1073 { 1093 {
1074 if (0 == (rc = gnutls_x509_crt_check_hostname(x509_cert, 1094 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1075 name))) 1095 _ (
1076 { 1096 "TLS certificate subject name (%s) does not match `%s': %d\n"),
1077 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1097 certdn,
1078 _("TLS certificate subject name (%s) does not match `%s': %d\n"), 1098 name,
1079 certdn, 1099 rc);
1080 name, 1100 gnutls_x509_crt_deinit (x509_cert);
1081 rc);
1082 gnutls_x509_crt_deinit(x509_cert);
1083 return GNUNET_SYSERR;
1084 }
1085 }
1086 else
1087 {
1088 /* we did not even have the domain name!? */
1089 GNUNET_break(0);
1090 return GNUNET_SYSERR; 1101 return GNUNET_SYSERR;
1091 } 1102 }
1103 }
1104 else
1105 {
1106 /* we did not even have the domain name!? */
1107 GNUNET_break (0);
1108 return GNUNET_SYSERR;
1109 }
1092 } 1110 }
1093 gnutls_x509_crt_deinit(x509_cert); 1111 gnutls_x509_crt_deinit (x509_cert);
1094 return GNUNET_OK; 1112 return GNUNET_OK;
1095} 1113}
1096 1114
@@ -1108,10 +1126,10 @@ check_ssl_certificate(struct Socks5Request *s5r)
1108 * @return size of processed bytes 1126 * @return size of processed bytes
1109 */ 1127 */
1110static size_t 1128static size_t
1111curl_check_hdr(void *buffer, 1129curl_check_hdr (void *buffer,
1112 size_t size, 1130 size_t size,
1113 size_t nmemb, 1131 size_t nmemb,
1114 void *cls) 1132 void *cls)
1115{ 1133{
1116 struct Socks5Request *s5r = cls; 1134 struct Socks5Request *s5r = cls;
1117 struct HttpResponseHeader *header; 1135 struct HttpResponseHeader *header;
@@ -1127,178 +1145,178 @@ curl_check_hdr(void *buffer,
1127 int domain_matched; 1145 int domain_matched;
1128 char *tok; 1146 char *tok;
1129 1147
1130 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1131 "Receiving HTTP response header from CURL\n"); 1149 "Receiving HTTP response header from CURL\n");
1132 /* first, check TLS certificate */ 1150 /* first, check TLS certificate */
1133 if ((GNUNET_YES != s5r->ssl_checked) && 1151 if ((GNUNET_YES != s5r->ssl_checked) &&
1134 (GNUNET_YES == s5r->is_tls)) 1152 (GNUNET_YES == s5r->is_tls))
1135 //(HTTPS_PORT == s5r->port)) 1153 // (HTTPS_PORT == s5r->port))
1136 { 1154 {
1137 if (GNUNET_OK != check_ssl_certificate(s5r)) 1155 if (GNUNET_OK != check_ssl_certificate (s5r))
1138 return 0; 1156 return 0;
1139 } 1157 }
1140 ndup = GNUNET_strndup(buffer, 1158 ndup = GNUNET_strndup (buffer,
1141 bytes); 1159 bytes);
1142 hdr_type = strtok(ndup, 1160 hdr_type = strtok (ndup,
1143 ":"); 1161 ":");
1144 if (NULL == hdr_type) 1162 if (NULL == hdr_type)
1145 { 1163 {
1146 GNUNET_free(ndup); 1164 GNUNET_free (ndup);
1147 return bytes; 1165 return bytes;
1148 } 1166 }
1149 hdr_val = strtok(NULL, 1167 hdr_val = strtok (NULL,
1150 ""); 1168 "");
1151 if (NULL == hdr_val) 1169 if (NULL == hdr_val)
1152 { 1170 {
1153 GNUNET_free(ndup); 1171 GNUNET_free (ndup);
1154 return bytes; 1172 return bytes;
1155 } 1173 }
1156 if (' ' == *hdr_val) 1174 if (' ' == *hdr_val)
1157 hdr_val++; 1175 hdr_val++;
1158 1176
1159 /* custom logic for certain header types */ 1177 /* custom logic for certain header types */
1160 new_cookie_hdr = NULL; 1178 new_cookie_hdr = NULL;
1161 if ((NULL != s5r->leho) && 1179 if ((NULL != s5r->leho) &&
1162 (0 == strcasecmp(hdr_type, 1180 (0 == strcasecmp (hdr_type,
1163 MHD_HTTP_HEADER_SET_COOKIE))) 1181 MHD_HTTP_HEADER_SET_COOKIE)))
1164 1182
1165 { 1183 {
1166 new_cookie_hdr = GNUNET_malloc(strlen(hdr_val) + 1184 new_cookie_hdr = GNUNET_malloc (strlen (hdr_val)
1167 strlen(s5r->domain) + 1); 1185 + strlen (s5r->domain) + 1);
1168 offset = 0; 1186 offset = 0;
1169 domain_matched = GNUNET_NO; /* make sure we match domain at most once */ 1187 domain_matched = GNUNET_NO; /* make sure we match domain at most once */
1170 for (tok = strtok(hdr_val, ";"); NULL != tok; tok = strtok(NULL, ";")) 1188 for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";"))
1189 {
1190 if ((0 == strncasecmp (tok,
1191 " domain",
1192 strlen (" domain"))) &&
1193 (GNUNET_NO == domain_matched))
1194 {
1195 domain_matched = GNUNET_YES;
1196 cookie_domain = tok + strlen (" domain") + 1;
1197 if (strlen (cookie_domain) < strlen (s5r->leho))
1171 { 1198 {
1172 if ((0 == strncasecmp(tok, 1199 delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain);
1173 " domain", 1200 if (0 == strcasecmp (cookie_domain,
1174 strlen(" domain"))) && 1201 s5r->leho + delta_cdomain))
1175 (GNUNET_NO == domain_matched)) 1202 {
1176 { 1203 offset += sprintf (new_cookie_hdr + offset,
1177 domain_matched = GNUNET_YES; 1204 " domain=%s;",
1178 cookie_domain = tok + strlen(" domain") + 1; 1205 s5r->domain);
1179 if (strlen(cookie_domain) < strlen(s5r->leho)) 1206 continue;
1180 { 1207 }
1181 delta_cdomain = strlen(s5r->leho) - strlen(cookie_domain);
1182 if (0 == strcasecmp(cookie_domain,
1183 s5r->leho + delta_cdomain))
1184 {
1185 offset += sprintf(new_cookie_hdr + offset,
1186 " domain=%s;",
1187 s5r->domain);
1188 continue;
1189 }
1190 }
1191 else if (0 == strcmp(cookie_domain,
1192 s5r->leho))
1193 {
1194 offset += sprintf(new_cookie_hdr + offset,
1195 " domain=%s;",
1196 s5r->domain);
1197 continue;
1198 }
1199 else if (('.' == cookie_domain[0]) &&
1200 (0 == strcmp(&cookie_domain[1],
1201 s5r->leho)))
1202 {
1203 offset += sprintf(new_cookie_hdr + offset,
1204 " domain=.%s;",
1205 s5r->domain);
1206 continue;
1207 }
1208 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1209 _("Cookie domain `%s' supplied by server is invalid\n"),
1210 tok);
1211 }
1212 GNUNET_memcpy(new_cookie_hdr + offset,
1213 tok,
1214 strlen(tok));
1215 offset += strlen(tok);
1216 new_cookie_hdr[offset++] = ';';
1217 } 1208 }
1218 hdr_val = new_cookie_hdr; 1209 else if (0 == strcmp (cookie_domain,
1219 } 1210 s5r->leho))
1220
1221 new_location = NULL;
1222 if (0 == strcasecmp(MHD_HTTP_HEADER_TRANSFER_ENCODING,
1223 hdr_type))
1224 {
1225 /* Ignore transfer encoding, set automatically by MHD if required */
1226 goto cleanup;
1227 }
1228 if ((0 == strcasecmp(MHD_HTTP_HEADER_LOCATION,
1229 hdr_type)))
1230 {
1231 char *leho_host;
1232
1233 GNUNET_asprintf(&leho_host,
1234 (GNUNET_YES != s5r->is_tls) //(HTTPS_PORT != s5r->port)
1235 ? "http://%s"
1236 : "https://%s",
1237 s5r->leho);
1238 if (0 == strncmp(leho_host,
1239 hdr_val,
1240 strlen(leho_host)))
1241 { 1211 {
1242 GNUNET_asprintf(&new_location, 1212 offset += sprintf (new_cookie_hdr + offset,
1243 "%s%s%s", 1213 " domain=%s;",
1244 (GNUNET_YES != s5r->is_tls) //(HTTPS_PORT != s5r->port) 1214 s5r->domain);
1245 ? "http://" 1215 continue;
1246 : "https://",
1247 s5r->domain,
1248 hdr_val + strlen(leho_host));
1249 hdr_val = new_location;
1250 } 1216 }
1251 GNUNET_free(leho_host); 1217 else if (('.' == cookie_domain[0]) &&
1252 } 1218 (0 == strcmp (&cookie_domain[1],
1253 if (0 == strcasecmp(MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, 1219 s5r->leho)))
1254 hdr_type))
1255 {
1256 char *leho_host;
1257
1258 GNUNET_asprintf(&leho_host,
1259 (GNUNET_YES != s5r->is_tls) //(HTTPS_PORT != s5r->port)
1260 ? "http://%s"
1261 : "https://%s",
1262 s5r->leho);
1263 if (0 == strncmp(leho_host,
1264 hdr_val,
1265 strlen(leho_host)))
1266 { 1220 {
1267 GNUNET_asprintf(&new_location, 1221 offset += sprintf (new_cookie_hdr + offset,
1268 "%s%s", 1222 " domain=.%s;",
1269 (GNUNET_YES != s5r->is_tls) //(HTTPS_PORT != s5r->port) 1223 s5r->domain);
1270 ? "http://" 1224 continue;
1271 : "https://",
1272 s5r->domain);
1273 hdr_val = new_location;
1274 } 1225 }
1275 GNUNET_free(leho_host); 1226 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1227 _ ("Cookie domain `%s' supplied by server is invalid\n"),
1228 tok);
1229 }
1230 GNUNET_memcpy (new_cookie_hdr + offset,
1231 tok,
1232 strlen (tok));
1233 offset += strlen (tok);
1234 new_cookie_hdr[offset++] = ';';
1276 } 1235 }
1236 hdr_val = new_cookie_hdr;
1237 }
1238
1239 new_location = NULL;
1240 if (0 == strcasecmp (MHD_HTTP_HEADER_TRANSFER_ENCODING,
1241 hdr_type))
1242 {
1243 /* Ignore transfer encoding, set automatically by MHD if required */
1244 goto cleanup;
1245 }
1246 if ((0 == strcasecmp (MHD_HTTP_HEADER_LOCATION,
1247 hdr_type)))
1248 {
1249 char *leho_host;
1250
1251 GNUNET_asprintf (&leho_host,
1252 (GNUNET_YES != s5r->is_tls) // (HTTPS_PORT != s5r->port)
1253 ? "http://%s"
1254 : "https://%s",
1255 s5r->leho);
1256 if (0 == strncmp (leho_host,
1257 hdr_val,
1258 strlen (leho_host)))
1259 {
1260 GNUNET_asprintf (&new_location,
1261 "%s%s%s",
1262 (GNUNET_YES != s5r->is_tls) // (HTTPS_PORT != s5r->port)
1263 ? "http://"
1264 : "https://",
1265 s5r->domain,
1266 hdr_val + strlen (leho_host));
1267 hdr_val = new_location;
1268 }
1269 GNUNET_free (leho_host);
1270 }
1271 if (0 == strcasecmp (MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
1272 hdr_type))
1273 {
1274 char *leho_host;
1275
1276 GNUNET_asprintf (&leho_host,
1277 (GNUNET_YES != s5r->is_tls) // (HTTPS_PORT != s5r->port)
1278 ? "http://%s"
1279 : "https://%s",
1280 s5r->leho);
1281 if (0 == strncmp (leho_host,
1282 hdr_val,
1283 strlen (leho_host)))
1284 {
1285 GNUNET_asprintf (&new_location,
1286 "%s%s",
1287 (GNUNET_YES != s5r->is_tls) // (HTTPS_PORT != s5r->port)
1288 ? "http://"
1289 : "https://",
1290 s5r->domain);
1291 hdr_val = new_location;
1292 }
1293 GNUNET_free (leho_host);
1294 }
1277 1295
1278 /* MHD does not allow certain characters in values, remove those */ 1296 /* MHD does not allow certain characters in values, remove those */
1279 if (NULL != (tok = strchr(hdr_val, '\n'))) 1297 if (NULL != (tok = strchr (hdr_val, '\n')))
1280 *tok = '\0'; 1298 *tok = '\0';
1281 if (NULL != (tok = strchr(hdr_val, '\r'))) 1299 if (NULL != (tok = strchr (hdr_val, '\r')))
1282 *tok = '\0'; 1300 *tok = '\0';
1283 if (NULL != (tok = strchr(hdr_val, '\t'))) 1301 if (NULL != (tok = strchr (hdr_val, '\t')))
1284 *tok = '\0'; 1302 *tok = '\0';
1285 if (0 != strlen(hdr_val)) /* Rely in MHD to set those */ 1303 if (0 != strlen (hdr_val)) /* Rely in MHD to set those */
1286 { 1304 {
1287 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1288 "Adding header %s: %s to MHD response\n", 1306 "Adding header %s: %s to MHD response\n",
1289 hdr_type, 1307 hdr_type,
1290 hdr_val); 1308 hdr_val);
1291 header = GNUNET_new(struct HttpResponseHeader); 1309 header = GNUNET_new (struct HttpResponseHeader);
1292 header->type = GNUNET_strdup(hdr_type); 1310 header->type = GNUNET_strdup (hdr_type);
1293 header->value = GNUNET_strdup(hdr_val); 1311 header->value = GNUNET_strdup (hdr_val);
1294 GNUNET_CONTAINER_DLL_insert(s5r->header_head, 1312 GNUNET_CONTAINER_DLL_insert (s5r->header_head,
1295 s5r->header_tail, 1313 s5r->header_tail,
1296 header); 1314 header);
1297 } 1315 }
1298cleanup: 1316cleanup:
1299 GNUNET_free(ndup); 1317 GNUNET_free (ndup);
1300 GNUNET_free_non_null(new_cookie_hdr); 1318 GNUNET_free_non_null (new_cookie_hdr);
1301 GNUNET_free_non_null(new_location); 1319 GNUNET_free_non_null (new_location);
1302 return bytes; 1320 return bytes;
1303} 1321}
1304 1322
@@ -1312,73 +1330,73 @@ cleanup:
1312 * already initialized before 1330 * already initialized before
1313 */ 1331 */
1314static int 1332static int
1315create_mhd_response_from_s5r(struct Socks5Request *s5r) 1333create_mhd_response_from_s5r (struct Socks5Request *s5r)
1316{ 1334{
1317 long resp_code; 1335 long resp_code;
1318 double content_length; 1336 double content_length;
1319 1337
1320 if (NULL != s5r->response) 1338 if (NULL != s5r->response)
1321 { 1339 {
1322 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1323 "Response already set!\n"); 1341 "Response already set!\n");
1324 return GNUNET_SYSERR; 1342 return GNUNET_SYSERR;
1325 } 1343 }
1326 1344
1327 GNUNET_break(CURLE_OK == 1345 GNUNET_break (CURLE_OK ==
1328 curl_easy_getinfo(s5r->curl, 1346 curl_easy_getinfo (s5r->curl,
1329 CURLINFO_RESPONSE_CODE, 1347 CURLINFO_RESPONSE_CODE,
1330 &resp_code)); 1348 &resp_code));
1331 GNUNET_break(CURLE_OK == 1349 GNUNET_break (CURLE_OK ==
1332 curl_easy_getinfo(s5r->curl, 1350 curl_easy_getinfo (s5r->curl,
1333 CURLINFO_CONTENT_LENGTH_DOWNLOAD, 1351 CURLINFO_CONTENT_LENGTH_DOWNLOAD,
1334 &content_length)); 1352 &content_length));
1335 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1336 "Creating MHD response with code %d and size %d for %s%s\n", 1354 "Creating MHD response with code %d and size %d for %s%s\n",
1337 (int)resp_code, 1355 (int) resp_code,
1338 (int)content_length, 1356 (int) content_length,
1339 s5r->domain, 1357 s5r->domain,
1340 s5r->url); 1358 s5r->url);
1341 s5r->response_code = resp_code; 1359 s5r->response_code = resp_code;
1342 s5r->response = MHD_create_response_from_callback((-1 == content_length) 1360 s5r->response = MHD_create_response_from_callback ((-1 == content_length)
1343 ? MHD_SIZE_UNKNOWN 1361 ? MHD_SIZE_UNKNOWN
1344 : content_length, 1362 : content_length,
1345 IO_BUFFERSIZE, 1363 IO_BUFFERSIZE,
1346 &mhd_content_cb, 1364 &mhd_content_cb,
1347 s5r, 1365 s5r,
1348 NULL); 1366 NULL);
1349 for (struct HttpResponseHeader *header = s5r->header_head; 1367 for (struct HttpResponseHeader *header = s5r->header_head;
1350 NULL != header; 1368 NULL != header;
1351 header = header->next) 1369 header = header->next)
1352 { 1370 {
1353 if (0 == strcasecmp(header->type, 1371 if (0 == strcasecmp (header->type,
1354 MHD_HTTP_HEADER_CONTENT_LENGTH)) 1372 MHD_HTTP_HEADER_CONTENT_LENGTH))
1355 continue; /* MHD won't let us mess with those, for good reason */ 1373 continue; /* MHD won't let us mess with those, for good reason */
1356 if ((0 == strcasecmp(header->type, 1374 if ((0 == strcasecmp (header->type,
1357 MHD_HTTP_HEADER_TRANSFER_ENCODING)) && 1375 MHD_HTTP_HEADER_TRANSFER_ENCODING)) &&
1358 ((0 == strcasecmp(header->value, 1376 ((0 == strcasecmp (header->value,
1359 "identity")) || 1377 "identity")) ||
1360 (0 == strcasecmp(header->value, 1378 (0 == strcasecmp (header->value,
1361 "chunked")))) 1379 "chunked"))))
1362 continue; /* MHD won't let us mess with those, for good reason */ 1380 continue; /* MHD won't let us mess with those, for good reason */
1363 if (MHD_YES != 1381 if (MHD_YES !=
1364 MHD_add_response_header(s5r->response, 1382 MHD_add_response_header (s5r->response,
1365 header->type, 1383 header->type,
1366 header->value)) 1384 header->value))
1367 { 1385 {
1368 GNUNET_break(0); 1386 GNUNET_break (0);
1369 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1387 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1370 "Failed to add header `%s:%s'\n", 1388 "Failed to add header `%s:%s'\n",
1371 header->type, 1389 header->type,
1372 header->value); 1390 header->value);
1373 }
1374 } 1391 }
1392 }
1375 /* force connection to be closed after each request, as we 1393 /* force connection to be closed after each request, as we
1376 do not support HTTP pipelining (yet, FIXME!) */ 1394 do not support HTTP pipelining (yet, FIXME!) */
1377 /*GNUNET_break (MHD_YES == 1395 /*GNUNET_break (MHD_YES ==
1378 MHD_add_response_header (s5r->response, 1396 MHD_add_response_header (s5r->response,
1379 MHD_HTTP_HEADER_CONNECTION, 1397 MHD_HTTP_HEADER_CONNECTION,
1380 "close"));*/ 1398 "close"));*/
1381 MHD_resume_connection(s5r->con); 1399 MHD_resume_connection (s5r->con);
1382 s5r->suspended = GNUNET_NO; 1400 s5r->suspended = GNUNET_NO;
1383 return GNUNET_OK; 1401 return GNUNET_OK;
1384} 1402}
@@ -1395,70 +1413,70 @@ create_mhd_response_from_s5r(struct Socks5Request *s5r)
1395 * @return number of bytes handled 1413 * @return number of bytes handled
1396 */ 1414 */
1397static size_t 1415static size_t
1398curl_download_cb(void *ptr, 1416curl_download_cb (void *ptr,
1399 size_t size, 1417 size_t size,
1400 size_t nmemb, 1418 size_t nmemb,
1401 void* ctx) 1419 void*ctx)
1402{ 1420{
1403 struct Socks5Request *s5r = ctx; 1421 struct Socks5Request *s5r = ctx;
1404 size_t total = size * nmemb; 1422 size_t total = size * nmemb;
1405 1423
1406 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1407 "Receiving %ux%u bytes for `%s%s' from cURL to download\n", 1425 "Receiving %ux%u bytes for `%s%s' from cURL to download\n",
1408 (unsigned int)size, 1426 (unsigned int) size,
1409 (unsigned int)nmemb, 1427 (unsigned int) nmemb,
1410 s5r->domain, 1428 s5r->domain,
1411 s5r->url); 1429 s5r->url);
1412 if (NULL == s5r->response) 1430 if (NULL == s5r->response)
1413 GNUNET_assert(GNUNET_OK == 1431 GNUNET_assert (GNUNET_OK ==
1414 create_mhd_response_from_s5r(s5r)); 1432 create_mhd_response_from_s5r (s5r));
1415 if ((SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) && 1433 if ((SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) &&
1416 (0 == s5r->io_len)) 1434 (0 == s5r->io_len))
1417 { 1435 {
1418 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1419 "Previous upload finished... starting DOWNLOAD.\n"); 1437 "Previous upload finished... starting DOWNLOAD.\n");
1420 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1438 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1421 } 1439 }
1422 if ((SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) || 1440 if ((SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) ||
1423 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state)) 1441 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state))
1424 { 1442 {
1425 /* we're still not done with the upload, do not yet 1443 /* we're still not done with the upload, do not yet
1426 start the download, the IO buffer is still full 1444 start the download, the IO buffer is still full
1427 with upload data. */ 1445 with upload data. */
1428 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1429 "Pausing CURL download `%s%s', waiting for UPLOAD to finish\n", 1447 "Pausing CURL download `%s%s', waiting for UPLOAD to finish\n",
1430 s5r->domain, 1448 s5r->domain,
1431 s5r->url); 1449 s5r->url);
1432 s5r->curl_paused = GNUNET_YES; 1450 s5r->curl_paused = GNUNET_YES;
1433 return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */ 1451 return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */
1434 } 1452 }
1435 if (sizeof(s5r->io_buf) - s5r->io_len < total) 1453 if (sizeof(s5r->io_buf) - s5r->io_len < total)
1436 { 1454 {
1437 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1438 "Pausing CURL `%s%s' download, not enough space %llu %llu %llu\n", 1456 "Pausing CURL `%s%s' download, not enough space %llu %llu %llu\n",
1439 s5r->domain, 1457 s5r->domain,
1440 s5r->url, 1458 s5r->url,
1441 (unsigned long long)sizeof(s5r->io_buf), 1459 (unsigned long long) sizeof(s5r->io_buf),
1442 (unsigned long long)s5r->io_len, 1460 (unsigned long long) s5r->io_len,
1443 (unsigned long long)total); 1461 (unsigned long long) total);
1444 s5r->curl_paused = GNUNET_YES; 1462 s5r->curl_paused = GNUNET_YES;
1445 return CURL_WRITEFUNC_PAUSE; /* not enough space */ 1463 return CURL_WRITEFUNC_PAUSE; /* not enough space */
1446 } 1464 }
1447 GNUNET_memcpy(&s5r->io_buf[s5r->io_len], 1465 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
1448 ptr, 1466 ptr,
1449 total); 1467 total);
1450 s5r->io_len += total; 1468 s5r->io_len += total;
1451 if (GNUNET_YES == s5r->suspended) 1469 if (GNUNET_YES == s5r->suspended)
1452 { 1470 {
1453 MHD_resume_connection(s5r->con); 1471 MHD_resume_connection (s5r->con);
1454 s5r->suspended = GNUNET_NO; 1472 s5r->suspended = GNUNET_NO;
1455 } 1473 }
1456 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1474 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1457 "Received %llu bytes of payload via cURL from %s\n", 1475 "Received %llu bytes of payload via cURL from %s\n",
1458 (unsigned long long)total, 1476 (unsigned long long) total,
1459 s5r->domain); 1477 s5r->domain);
1460 if (s5r->io_len == total) 1478 if (s5r->io_len == total)
1461 run_mhd_now(s5r->hd); 1479 run_mhd_now (s5r->hd);
1462 return total; 1480 return total;
1463} 1481}
1464 1482
@@ -1474,64 +1492,64 @@ curl_download_cb(void *ptr,
1474 * @return number of bytes copied to @a buf 1492 * @return number of bytes copied to @a buf
1475 */ 1493 */
1476static size_t 1494static size_t
1477curl_upload_cb(void *buf, 1495curl_upload_cb (void *buf,
1478 size_t size, 1496 size_t size,
1479 size_t nmemb, 1497 size_t nmemb,
1480 void *cls) 1498 void *cls)
1481{ 1499{
1482 struct Socks5Request *s5r = cls; 1500 struct Socks5Request *s5r = cls;
1483 size_t len = size * nmemb; 1501 size_t len = size * nmemb;
1484 size_t to_copy; 1502 size_t to_copy;
1485 1503
1486 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1487 "Receiving %ux%u bytes for `%s%s' from cURL to upload\n", 1505 "Receiving %ux%u bytes for `%s%s' from cURL to upload\n",
1488 (unsigned int)size, 1506 (unsigned int) size,
1489 (unsigned int)nmemb, 1507 (unsigned int) nmemb,
1490 s5r->domain, 1508 s5r->domain,
1491 s5r->url); 1509 s5r->url);
1492 1510
1493 if ((0 == s5r->io_len) && 1511 if ((0 == s5r->io_len) &&
1494 (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state)) 1512 (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state))
1495 { 1513 {
1496 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1497 "Pausing CURL UPLOAD %s%s, need more data\n", 1515 "Pausing CURL UPLOAD %s%s, need more data\n",
1498 s5r->domain, 1516 s5r->domain,
1499 s5r->url); 1517 s5r->url);
1500 return CURL_READFUNC_PAUSE; 1518 return CURL_READFUNC_PAUSE;
1501 } 1519 }
1502 if ((0 == s5r->io_len) && 1520 if ((0 == s5r->io_len) &&
1503 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state)) 1521 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state))
1522 {
1523 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1524 if (GNUNET_YES == s5r->curl_paused)
1504 { 1525 {
1505 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1526 s5r->curl_paused = GNUNET_NO;
1506 if (GNUNET_YES == s5r->curl_paused) 1527 curl_easy_pause (s5r->curl,
1507 { 1528 CURLPAUSE_CONT);
1508 s5r->curl_paused = GNUNET_NO; 1529 }
1509 curl_easy_pause(s5r->curl, 1530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1510 CURLPAUSE_CONT); 1531 "Completed CURL UPLOAD %s%s\n",
1511 } 1532 s5r->domain,
1512 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1533 s5r->url);
1513 "Completed CURL UPLOAD %s%s\n", 1534 return 0; /* upload finished, can now download */
1514 s5r->domain, 1535 }
1515 s5r->url);
1516 return 0; /* upload finished, can now download */
1517 }
1518 if ((SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) && 1536 if ((SOCKS5_SOCKET_UPLOAD_STARTED != s5r->state) &&
1519 (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state)) 1537 (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state))
1520 { 1538 {
1521 GNUNET_break(0); 1539 GNUNET_break (0);
1522 return CURL_READFUNC_ABORT; 1540 return CURL_READFUNC_ABORT;
1523 } 1541 }
1524 to_copy = GNUNET_MIN(s5r->io_len, 1542 to_copy = GNUNET_MIN (s5r->io_len,
1525 len); 1543 len);
1526 GNUNET_memcpy(buf, 1544 GNUNET_memcpy (buf,
1527 s5r->io_buf, 1545 s5r->io_buf,
1528 to_copy); 1546 to_copy);
1529 memmove(s5r->io_buf, 1547 memmove (s5r->io_buf,
1530 &s5r->io_buf[to_copy], 1548 &s5r->io_buf[to_copy],
1531 s5r->io_len - to_copy); 1549 s5r->io_len - to_copy);
1532 s5r->io_len -= to_copy; 1550 s5r->io_len -= to_copy;
1533 if (s5r->io_len + to_copy == sizeof(s5r->io_buf)) 1551 if (s5r->io_len + to_copy == sizeof(s5r->io_buf))
1534 run_mhd_now(s5r->hd); /* got more space for upload now */ 1552 run_mhd_now (s5r->hd); /* got more space for upload now */
1535 return to_copy; 1553 return to_copy;
1536} 1554}
1537 1555
@@ -1546,14 +1564,14 @@ curl_upload_cb(void *buf,
1546 * @param cls closure 1564 * @param cls closure
1547 */ 1565 */
1548static void 1566static void
1549curl_task_download(void *cls); 1567curl_task_download (void *cls);
1550 1568
1551 1569
1552/** 1570/**
1553 * Ask cURL for the select() sets and schedule cURL operations. 1571 * Ask cURL for the select() sets and schedule cURL operations.
1554 */ 1572 */
1555static void 1573static void
1556curl_download_prepare() 1574curl_download_prepare ()
1557{ 1575{
1558 CURLMcode mret; 1576 CURLMcode mret;
1559 fd_set rs; 1577 fd_set rs;
@@ -1565,63 +1583,64 @@ curl_download_prepare()
1565 long to; 1583 long to;
1566 struct GNUNET_TIME_Relative rtime; 1584 struct GNUNET_TIME_Relative rtime;
1567 1585
1568 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1569 "Scheduling CURL interaction\n"); 1587 "Scheduling CURL interaction\n");
1570 if (NULL != curl_download_task) 1588 if (NULL != curl_download_task)
1571 { 1589 {
1572 GNUNET_SCHEDULER_cancel(curl_download_task); 1590 GNUNET_SCHEDULER_cancel (curl_download_task);
1573 curl_download_task = NULL; 1591 curl_download_task = NULL;
1574 } 1592 }
1575 max = -1; 1593 max = -1;
1576 FD_ZERO(&rs); 1594 FD_ZERO (&rs);
1577 FD_ZERO(&ws); 1595 FD_ZERO (&ws);
1578 FD_ZERO(&es); 1596 FD_ZERO (&es);
1579 if (CURLM_OK != (mret = curl_multi_fdset(curl_multi, 1597 if (CURLM_OK != (mret = curl_multi_fdset (curl_multi,
1580 &rs, 1598 &rs,
1581 &ws, 1599 &ws,
1582 &es, 1600 &es,
1583 &max))) 1601 &max)))
1584 { 1602 {
1585 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1603 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1586 "%s failed at %s:%d: `%s'\n", 1604 "%s failed at %s:%d: `%s'\n",
1587 "curl_multi_fdset", __FILE__, __LINE__, 1605 "curl_multi_fdset", __FILE__, __LINE__,
1588 curl_multi_strerror(mret)); 1606 curl_multi_strerror (mret));
1589 return; 1607 return;
1590 } 1608 }
1591 to = -1; 1609 to = -1;
1592 GNUNET_break(CURLM_OK == 1610 GNUNET_break (CURLM_OK ==
1593 curl_multi_timeout(curl_multi, 1611 curl_multi_timeout (curl_multi,
1594 &to)); 1612 &to));
1595 if (-1 == to) 1613 if (-1 == to)
1596 rtime = GNUNET_TIME_UNIT_FOREVER_REL; 1614 rtime = GNUNET_TIME_UNIT_FOREVER_REL;
1597 else 1615 else
1598 rtime = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 1616 rtime = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
1599 to); 1617 to);
1600 if (-1 != max) 1618 if (-1 != max)
1601 { 1619 {
1602 grs = GNUNET_NETWORK_fdset_create(); 1620 grs = GNUNET_NETWORK_fdset_create ();
1603 gws = GNUNET_NETWORK_fdset_create(); 1621 gws = GNUNET_NETWORK_fdset_create ();
1604 GNUNET_NETWORK_fdset_copy_native(grs, 1622 GNUNET_NETWORK_fdset_copy_native (grs,
1605 &rs, 1623 &rs,
1606 max + 1); 1624 max + 1);
1607 GNUNET_NETWORK_fdset_copy_native(gws, 1625 GNUNET_NETWORK_fdset_copy_native (gws,
1608 &ws, 1626 &ws,
1609 max + 1); 1627 max + 1);
1610 curl_download_task = GNUNET_SCHEDULER_add_select(GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1628 curl_download_task = GNUNET_SCHEDULER_add_select (
1611 rtime, 1629 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1612 grs, 1630 rtime,
1613 gws, 1631 grs,
1632 gws,
1633 &curl_task_download,
1634 curl_multi);
1635 GNUNET_NETWORK_fdset_destroy (gws);
1636 GNUNET_NETWORK_fdset_destroy (grs);
1637 }
1638 else
1639 {
1640 curl_download_task = GNUNET_SCHEDULER_add_delayed (rtime,
1614 &curl_task_download, 1641 &curl_task_download,
1615 curl_multi); 1642 curl_multi);
1616 GNUNET_NETWORK_fdset_destroy(gws); 1643 }
1617 GNUNET_NETWORK_fdset_destroy(grs);
1618 }
1619 else
1620 {
1621 curl_download_task = GNUNET_SCHEDULER_add_delayed(rtime,
1622 &curl_task_download,
1623 curl_multi);
1624 }
1625} 1644}
1626 1645
1627 1646
@@ -1631,7 +1650,7 @@ curl_download_prepare()
1631 * @param cls closure, NULL 1650 * @param cls closure, NULL
1632 */ 1651 */
1633static void 1652static void
1634curl_task_download(void *cls) 1653curl_task_download (void *cls)
1635{ 1654{
1636 int running; 1655 int running;
1637 int msgnum; 1656 int msgnum;
@@ -1640,109 +1659,109 @@ curl_task_download(void *cls)
1640 struct Socks5Request *s5r; 1659 struct Socks5Request *s5r;
1641 1660
1642 curl_download_task = NULL; 1661 curl_download_task = NULL;
1643 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1662 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1644 "Running CURL interaction\n"); 1663 "Running CURL interaction\n");
1645 do 1664 do
1646 { 1665 {
1647 running = 0; 1666 running = 0;
1648 mret = curl_multi_perform(curl_multi, 1667 mret = curl_multi_perform (curl_multi,
1649 &running); 1668 &running);
1650 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1651 "Checking CURL multi status: %d\n", 1670 "Checking CURL multi status: %d\n",
1652 mret); 1671 mret);
1653 while (NULL != (msg = curl_multi_info_read(curl_multi, 1672 while (NULL != (msg = curl_multi_info_read (curl_multi,
1654 &msgnum))) 1673 &msgnum)))
1674 {
1675 GNUNET_break (CURLE_OK ==
1676 curl_easy_getinfo (msg->easy_handle,
1677 CURLINFO_PRIVATE,
1678 (char **) &s5r));
1679 if (NULL == s5r)
1680 {
1681 GNUNET_break (0);
1682 continue;
1683 }
1684 switch (msg->msg)
1685 {
1686 case CURLMSG_NONE:
1687 /* documentation says this is not used */
1688 GNUNET_break (0);
1689 break;
1690
1691 case CURLMSG_DONE:
1692 switch (msg->data.result)
1655 { 1693 {
1656 GNUNET_break(CURLE_OK == 1694 case CURLE_OK:
1657 curl_easy_getinfo(msg->easy_handle, 1695 case CURLE_GOT_NOTHING:
1658 CURLINFO_PRIVATE, 1696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1659 (char **)&s5r)); 1697 "CURL download %s%s completed.\n",
1660 if (NULL == s5r) 1698 s5r->domain,
1661 { 1699 s5r->url);
1662 GNUNET_break(0); 1700 if (NULL == s5r->response)
1663 continue; 1701 {
1664 } 1702 GNUNET_assert (GNUNET_OK ==
1665 switch (msg->msg) 1703 create_mhd_response_from_s5r (s5r));
1666 { 1704 }
1667 case CURLMSG_NONE: 1705 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1668 /* documentation says this is not used */ 1706 if (GNUNET_YES == s5r->suspended)
1669 GNUNET_break(0); 1707 {
1670 break; 1708 MHD_resume_connection (s5r->con);
1671 1709 s5r->suspended = GNUNET_NO;
1672 case CURLMSG_DONE: 1710 }
1673 switch (msg->data.result) 1711 run_mhd_now (s5r->hd);
1674 { 1712 break;
1675 case CURLE_OK: 1713
1676 case CURLE_GOT_NOTHING: 1714 default:
1677 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1715 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1678 "CURL download %s%s completed.\n", 1716 "Download curl %s%s failed: %s\n",
1679 s5r->domain, 1717 s5r->domain,
1680 s5r->url); 1718 s5r->url,
1681 if (NULL == s5r->response) 1719 curl_easy_strerror (msg->data.result));
1682 { 1720 /* FIXME: indicate error somehow? close MHD connection badly as well? */
1683 GNUNET_assert(GNUNET_OK == 1721 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1684 create_mhd_response_from_s5r(s5r)); 1722 if (GNUNET_YES == s5r->suspended)
1685 } 1723 {
1686 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; 1724 MHD_resume_connection (s5r->con);
1687 if (GNUNET_YES == s5r->suspended) 1725 s5r->suspended = GNUNET_NO;
1688 { 1726 }
1689 MHD_resume_connection(s5r->con); 1727 run_mhd_now (s5r->hd);
1690 s5r->suspended = GNUNET_NO; 1728 break;
1691 }
1692 run_mhd_now(s5r->hd);
1693 break;
1694
1695 default:
1696 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1697 "Download curl %s%s failed: %s\n",
1698 s5r->domain,
1699 s5r->url,
1700 curl_easy_strerror(msg->data.result));
1701 /* FIXME: indicate error somehow? close MHD connection badly as well? */
1702 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1703 if (GNUNET_YES == s5r->suspended)
1704 {
1705 MHD_resume_connection(s5r->con);
1706 s5r->suspended = GNUNET_NO;
1707 }
1708 run_mhd_now(s5r->hd);
1709 break;
1710 }
1711 if (NULL == s5r->response)
1712 s5r->response = curl_failure_response;
1713 break;
1714
1715 case CURLMSG_LAST:
1716 /* documentation says this is not used */
1717 GNUNET_break(0);
1718 break;
1719
1720 default:
1721 /* unexpected status code */
1722 GNUNET_break(0);
1723 break;
1724 }
1725 } 1729 }
1726 ; 1730 if (NULL == s5r->response)
1731 s5r->response = curl_failure_response;
1732 break;
1733
1734 case CURLMSG_LAST:
1735 /* documentation says this is not used */
1736 GNUNET_break (0);
1737 break;
1738
1739 default:
1740 /* unexpected status code */
1741 GNUNET_break (0);
1742 break;
1743 }
1727 } 1744 }
1745 ;
1746 }
1728 while (mret == CURLM_CALL_MULTI_PERFORM); 1747 while (mret == CURLM_CALL_MULTI_PERFORM);
1729 if (CURLM_OK != mret) 1748 if (CURLM_OK != mret)
1730 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1749 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1731 "%s failed at %s:%d: `%s'\n", 1750 "%s failed at %s:%d: `%s'\n",
1732 "curl_multi_perform", __FILE__, __LINE__, 1751 "curl_multi_perform", __FILE__, __LINE__,
1733 curl_multi_strerror(mret)); 1752 curl_multi_strerror (mret));
1734 if (0 == running) 1753 if (0 == running)
1754 {
1755 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1756 "Suspending cURL multi loop, no more events pending\n");
1757 if (NULL != curl_download_task)
1735 { 1758 {
1736 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1759 GNUNET_SCHEDULER_cancel (curl_download_task);
1737 "Suspending cURL multi loop, no more events pending\n"); 1760 curl_download_task = NULL;
1738 if (NULL != curl_download_task)
1739 {
1740 GNUNET_SCHEDULER_cancel(curl_download_task);
1741 curl_download_task = NULL;
1742 }
1743 return; /* nothing more in progress */
1744 } 1761 }
1745 curl_download_prepare(); 1762 return; /* nothing more in progress */
1763 }
1764 curl_download_prepare ();
1746} 1765}
1747 1766
1748 1767
@@ -1763,28 +1782,28 @@ curl_task_download(void *cls)
1763 * @return #MHD_YES to continue to iterate 1782 * @return #MHD_YES to continue to iterate
1764 */ 1783 */
1765static int 1784static int
1766con_val_iter(void *cls, 1785con_val_iter (void *cls,
1767 enum MHD_ValueKind kind, 1786 enum MHD_ValueKind kind,
1768 const char *key, 1787 const char *key,
1769 const char *value) 1788 const char *value)
1770{ 1789{
1771 struct Socks5Request *s5r = cls; 1790 struct Socks5Request *s5r = cls;
1772 char *hdr; 1791 char *hdr;
1773 1792
1774 if ((0 == strcasecmp(MHD_HTTP_HEADER_HOST, 1793 if ((0 == strcasecmp (MHD_HTTP_HEADER_HOST,
1775 key)) && 1794 key)) &&
1776 (NULL != s5r->leho)) 1795 (NULL != s5r->leho))
1777 value = s5r->leho; 1796 value = s5r->leho;
1778 GNUNET_asprintf(&hdr, 1797 GNUNET_asprintf (&hdr,
1779 "%s: %s", 1798 "%s: %s",
1780 key, 1799 key,
1781 value); 1800 value);
1782 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1801 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1783 "Adding HEADER `%s' to HTTP request\n", 1802 "Adding HEADER `%s' to HTTP request\n",
1784 hdr); 1803 hdr);
1785 s5r->headers = curl_slist_append(s5r->headers, 1804 s5r->headers = curl_slist_append (s5r->headers,
1786 hdr); 1805 hdr);
1787 GNUNET_free(hdr); 1806 GNUNET_free (hdr);
1788 return MHD_YES; 1807 return MHD_YES;
1789} 1808}
1790 1809
@@ -1813,14 +1832,14 @@ con_val_iter(void *cls,
1813 * error while handling the request 1832 * error while handling the request
1814 */ 1833 */
1815static int 1834static int
1816create_response(void *cls, 1835create_response (void *cls,
1817 struct MHD_Connection *con, 1836 struct MHD_Connection *con,
1818 const char *url, 1837 const char *url,
1819 const char *meth, 1838 const char *meth,
1820 const char *ver, 1839 const char *ver,
1821 const char *upload_data, 1840 const char *upload_data,
1822 size_t *upload_data_size, 1841 size_t *upload_data_size,
1823 void **con_cls) 1842 void **con_cls)
1824{ 1843{
1825 struct Socks5Request *s5r = *con_cls; 1844 struct Socks5Request *s5r = *con_cls;
1826 char *curlurl; 1845 char *curlurl;
@@ -1833,415 +1852,415 @@ create_response(void *cls,
1833 size_t left; 1852 size_t left;
1834 1853
1835 if (NULL == s5r) 1854 if (NULL == s5r)
1836 { 1855 {
1837 GNUNET_break(0); 1856 GNUNET_break (0);
1838 return MHD_NO; 1857 return MHD_NO;
1839 } 1858 }
1840 s5r->con = con; 1859 s5r->con = con;
1841 /* Fresh connection. */ 1860 /* Fresh connection. */
1842 if (SOCKS5_SOCKET_WITH_MHD == s5r->state) 1861 if (SOCKS5_SOCKET_WITH_MHD == s5r->state)
1862 {
1863 /* first time here, initialize curl handle */
1864 if (s5r->is_gns)
1843 { 1865 {
1844 /* first time here, initialize curl handle */ 1866 sa = (const struct sockaddr *) &s5r->destination_address;
1845 if (s5r->is_gns) 1867 switch (sa->sa_family)
1846 { 1868 {
1847 sa = (const struct sockaddr *)&s5r->destination_address; 1869 case AF_INET:
1848 switch (sa->sa_family) 1870 s4 = (const struct sockaddr_in *) &s5r->destination_address;
1849 { 1871 if (NULL == inet_ntop (AF_INET,
1850 case AF_INET: 1872 &s4->sin_addr,
1851 s4 = (const struct sockaddr_in *)&s5r->destination_address; 1873 ipstring,
1852 if (NULL == inet_ntop(AF_INET, 1874 sizeof(ipstring)))
1853 &s4->sin_addr,
1854 ipstring,
1855 sizeof(ipstring)))
1856 {
1857 GNUNET_break(0);
1858 return MHD_NO;
1859 }
1860 GNUNET_snprintf(ipaddr,
1861 sizeof(ipaddr),
1862 "%s",
1863 ipstring);
1864 port = ntohs(s4->sin_port);
1865 break;
1866
1867 case AF_INET6:
1868 s6 = (const struct sockaddr_in6 *)&s5r->destination_address;
1869 if (NULL == inet_ntop(AF_INET6,
1870 &s6->sin6_addr,
1871 ipstring,
1872 sizeof(ipstring)))
1873 {
1874 GNUNET_break(0);
1875 return MHD_NO;
1876 }
1877 GNUNET_snprintf(ipaddr,
1878 sizeof(ipaddr),
1879 "%s",
1880 ipstring);
1881 port = ntohs(s6->sin6_port);
1882 break;
1883
1884 default:
1885 GNUNET_break(0);
1886 return MHD_NO;
1887 }
1888 }
1889 else
1890 {
1891 port = s5r->port;
1892 }
1893 if (NULL == s5r->curl)
1894 s5r->curl = curl_easy_init();
1895 if (NULL == s5r->curl)
1896 return MHD_queue_response(con,
1897 MHD_HTTP_INTERNAL_SERVER_ERROR,
1898 curl_failure_response);
1899 curl_easy_setopt(s5r->curl,
1900 CURLOPT_HEADERFUNCTION,
1901 &curl_check_hdr);
1902 curl_easy_setopt(s5r->curl,
1903 CURLOPT_HEADERDATA,
1904 s5r);
1905 curl_easy_setopt(s5r->curl,
1906 CURLOPT_FOLLOWLOCATION,
1907 0);
1908 if (s5r->is_gns)
1909 curl_easy_setopt(s5r->curl,
1910 CURLOPT_IPRESOLVE,
1911 CURL_IPRESOLVE_V4);
1912 curl_easy_setopt(s5r->curl,
1913 CURLOPT_CONNECTTIMEOUT,
1914 600L);
1915 curl_easy_setopt(s5r->curl,
1916 CURLOPT_TIMEOUT,
1917 600L);
1918 curl_easy_setopt(s5r->curl,
1919 CURLOPT_NOSIGNAL,
1920 1L);
1921 curl_easy_setopt(s5r->curl,
1922 CURLOPT_HTTP_CONTENT_DECODING,
1923 0);
1924 curl_easy_setopt(s5r->curl,
1925 CURLOPT_NOSIGNAL,
1926 1L);
1927 curl_easy_setopt(s5r->curl,
1928 CURLOPT_PRIVATE,
1929 s5r);
1930 curl_easy_setopt(s5r->curl,
1931 CURLOPT_VERBOSE,
1932 0L);
1933 /**
1934 * Pre-populate cache to resolve Hostname.
1935 * This is necessary as the DNS name in the CURLOPT_URL is used
1936 * for SNI http://de.wikipedia.org/wiki/Server_Name_Indication
1937 */
1938 if (NULL != s5r->leho)
1939 {
1940 char *curl_hosts;
1941
1942 GNUNET_asprintf(&curl_hosts,
1943 "%s:%d:%s",
1944 s5r->leho,
1945 port,
1946 ipaddr);
1947 s5r->hosts = curl_slist_append(NULL,
1948 curl_hosts);
1949 curl_easy_setopt(s5r->curl,
1950 CURLOPT_RESOLVE,
1951 s5r->hosts);
1952 GNUNET_free(curl_hosts);
1953 }
1954 if (s5r->is_gns)
1955 {
1956 GNUNET_asprintf(&curlurl,
1957 (GNUNET_YES != s5r->is_tls) //(HTTPS_PORT != s5r->port)
1958 ? "http://%s:%d%s"
1959 : "https://%s:%d%s",
1960 (NULL != s5r->leho)
1961 ? s5r->leho
1962 : ipaddr,
1963 port,
1964 s5r->url);
1965 }
1966 else
1967 {
1968 GNUNET_asprintf(&curlurl,
1969 (GNUNET_YES != s5r->is_tls) //(HTTPS_PORT != s5r->port)
1970 ? "http://%s:%d%s"
1971 : "https://%s:%d%s",
1972 s5r->domain,
1973 port,
1974 s5r->url);
1975 }
1976 curl_easy_setopt(s5r->curl,
1977 CURLOPT_URL,
1978 curlurl);
1979 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1980 "Launching %s CURL interaction, fetching `%s'\n",
1981 (s5r->is_gns) ? "GNS" : "DNS",
1982 curlurl);
1983 GNUNET_free(curlurl);
1984 if (0 == strcasecmp(meth,
1985 MHD_HTTP_METHOD_PUT))
1986 {
1987 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
1988 curl_easy_setopt(s5r->curl,
1989 CURLOPT_UPLOAD,
1990 1L);
1991 curl_easy_setopt(s5r->curl,
1992 CURLOPT_WRITEFUNCTION,
1993 &curl_download_cb);
1994 curl_easy_setopt(s5r->curl,
1995 CURLOPT_WRITEDATA,
1996 s5r);
1997 GNUNET_assert(CURLE_OK ==
1998 curl_easy_setopt(s5r->curl,
1999 CURLOPT_READFUNCTION,
2000 &curl_upload_cb));
2001 curl_easy_setopt(s5r->curl,
2002 CURLOPT_READDATA,
2003 s5r);
2004 {
2005 const char *us;
2006 long upload_size = 0;
2007
2008 us = MHD_lookup_connection_value(con,
2009 MHD_HEADER_KIND,
2010 MHD_HTTP_HEADER_CONTENT_LENGTH);
2011 if ((1 == sscanf(us,
2012 "%ld",
2013 &upload_size)) &&
2014 (upload_size >= 0))
2015 {
2016 curl_easy_setopt(s5r->curl,
2017 CURLOPT_INFILESIZE,
2018 upload_size);
2019 }
2020 }
2021 }
2022 else if (0 == strcasecmp(meth, MHD_HTTP_METHOD_POST))
2023 {
2024 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
2025 curl_easy_setopt(s5r->curl,
2026 CURLOPT_POST,
2027 1L);
2028 curl_easy_setopt(s5r->curl,
2029 CURLOPT_WRITEFUNCTION,
2030 &curl_download_cb);
2031 curl_easy_setopt(s5r->curl,
2032 CURLOPT_WRITEDATA,
2033 s5r);
2034 curl_easy_setopt(s5r->curl,
2035 CURLOPT_READFUNCTION,
2036 &curl_upload_cb);
2037 curl_easy_setopt(s5r->curl,
2038 CURLOPT_READDATA,
2039 s5r);
2040 {
2041 const char *us;
2042 long upload_size;
2043
2044 upload_size = 0;
2045 us = MHD_lookup_connection_value(con,
2046 MHD_HEADER_KIND,
2047 MHD_HTTP_HEADER_CONTENT_LENGTH);
2048 if ((NULL != us) &&
2049 (1 == sscanf(us,
2050 "%ld",
2051 &upload_size)) &&
2052 (upload_size >= 0))
2053 {
2054 curl_easy_setopt(s5r->curl,
2055 CURLOPT_INFILESIZE,
2056 upload_size);
2057 }
2058 else
2059 {
2060 curl_easy_setopt(s5r->curl,
2061 CURLOPT_INFILESIZE,
2062 upload_size);
2063 }
2064 }
2065 }
2066 else if (0 == strcasecmp(meth,
2067 MHD_HTTP_METHOD_HEAD))
2068 {
2069 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2070 curl_easy_setopt(s5r->curl,
2071 CURLOPT_NOBODY,
2072 1L);
2073 }
2074 else if (0 == strcasecmp(meth,
2075 MHD_HTTP_METHOD_OPTIONS))
2076 {
2077 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2078 curl_easy_setopt(s5r->curl,
2079 CURLOPT_CUSTOMREQUEST,
2080 "OPTIONS");
2081 curl_easy_setopt(s5r->curl,
2082 CURLOPT_WRITEFUNCTION,
2083 &curl_download_cb);
2084 curl_easy_setopt(s5r->curl,
2085 CURLOPT_WRITEDATA,
2086 s5r);
2087 }
2088 else if (0 == strcasecmp(meth,
2089 MHD_HTTP_METHOD_GET))
2090 {
2091 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2092 curl_easy_setopt(s5r->curl,
2093 CURLOPT_HTTPGET,
2094 1L);
2095 curl_easy_setopt(s5r->curl,
2096 CURLOPT_WRITEFUNCTION,
2097 &curl_download_cb);
2098 curl_easy_setopt(s5r->curl,
2099 CURLOPT_WRITEDATA,
2100 s5r);
2101 }
2102 else if (0 == strcasecmp(meth,
2103 MHD_HTTP_METHOD_DELETE))
2104 { 1875 {
2105 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1876 GNUNET_break (0);
2106 curl_easy_setopt(s5r->curl, 1877 return MHD_NO;
2107 CURLOPT_CUSTOMREQUEST,
2108 "DELETE");
2109 curl_easy_setopt(s5r->curl,
2110 CURLOPT_WRITEFUNCTION,
2111 &curl_download_cb);
2112 curl_easy_setopt(s5r->curl,
2113 CURLOPT_WRITEDATA,
2114 s5r);
2115 } 1878 }
2116 else 1879 GNUNET_snprintf (ipaddr,
1880 sizeof(ipaddr),
1881 "%s",
1882 ipstring);
1883 port = ntohs (s4->sin_port);
1884 break;
1885
1886 case AF_INET6:
1887 s6 = (const struct sockaddr_in6 *) &s5r->destination_address;
1888 if (NULL == inet_ntop (AF_INET6,
1889 &s6->sin6_addr,
1890 ipstring,
1891 sizeof(ipstring)))
2117 { 1892 {
2118 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1893 GNUNET_break (0);
2119 _("Unsupported HTTP method `%s'\n"),
2120 meth);
2121 curl_easy_cleanup(s5r->curl);
2122 s5r->curl = NULL;
2123 return MHD_NO; 1894 return MHD_NO;
2124 } 1895 }
1896 GNUNET_snprintf (ipaddr,
1897 sizeof(ipaddr),
1898 "%s",
1899 ipstring);
1900 port = ntohs (s6->sin6_port);
1901 break;
2125 1902
2126 if (0 == strcasecmp(ver, MHD_HTTP_VERSION_1_0)) 1903 default:
1904 GNUNET_break (0);
1905 return MHD_NO;
1906 }
1907 }
1908 else
1909 {
1910 port = s5r->port;
1911 }
1912 if (NULL == s5r->curl)
1913 s5r->curl = curl_easy_init ();
1914 if (NULL == s5r->curl)
1915 return MHD_queue_response (con,
1916 MHD_HTTP_INTERNAL_SERVER_ERROR,
1917 curl_failure_response);
1918 curl_easy_setopt (s5r->curl,
1919 CURLOPT_HEADERFUNCTION,
1920 &curl_check_hdr);
1921 curl_easy_setopt (s5r->curl,
1922 CURLOPT_HEADERDATA,
1923 s5r);
1924 curl_easy_setopt (s5r->curl,
1925 CURLOPT_FOLLOWLOCATION,
1926 0);
1927 if (s5r->is_gns)
1928 curl_easy_setopt (s5r->curl,
1929 CURLOPT_IPRESOLVE,
1930 CURL_IPRESOLVE_V4);
1931 curl_easy_setopt (s5r->curl,
1932 CURLOPT_CONNECTTIMEOUT,
1933 600L);
1934 curl_easy_setopt (s5r->curl,
1935 CURLOPT_TIMEOUT,
1936 600L);
1937 curl_easy_setopt (s5r->curl,
1938 CURLOPT_NOSIGNAL,
1939 1L);
1940 curl_easy_setopt (s5r->curl,
1941 CURLOPT_HTTP_CONTENT_DECODING,
1942 0);
1943 curl_easy_setopt (s5r->curl,
1944 CURLOPT_NOSIGNAL,
1945 1L);
1946 curl_easy_setopt (s5r->curl,
1947 CURLOPT_PRIVATE,
1948 s5r);
1949 curl_easy_setopt (s5r->curl,
1950 CURLOPT_VERBOSE,
1951 0L);
1952 /**
1953 * Pre-populate cache to resolve Hostname.
1954 * This is necessary as the DNS name in the CURLOPT_URL is used
1955 * for SNI http://de.wikipedia.org/wiki/Server_Name_Indication
1956 */
1957 if (NULL != s5r->leho)
1958 {
1959 char *curl_hosts;
1960
1961 GNUNET_asprintf (&curl_hosts,
1962 "%s:%d:%s",
1963 s5r->leho,
1964 port,
1965 ipaddr);
1966 s5r->hosts = curl_slist_append (NULL,
1967 curl_hosts);
1968 curl_easy_setopt (s5r->curl,
1969 CURLOPT_RESOLVE,
1970 s5r->hosts);
1971 GNUNET_free (curl_hosts);
1972 }
1973 if (s5r->is_gns)
1974 {
1975 GNUNET_asprintf (&curlurl,
1976 (GNUNET_YES != s5r->is_tls) // (HTTPS_PORT != s5r->port)
1977 ? "http://%s:%d%s"
1978 : "https://%s:%d%s",
1979 (NULL != s5r->leho)
1980 ? s5r->leho
1981 : ipaddr,
1982 port,
1983 s5r->url);
1984 }
1985 else
1986 {
1987 GNUNET_asprintf (&curlurl,
1988 (GNUNET_YES != s5r->is_tls) // (HTTPS_PORT != s5r->port)
1989 ? "http://%s:%d%s"
1990 : "https://%s:%d%s",
1991 s5r->domain,
1992 port,
1993 s5r->url);
1994 }
1995 curl_easy_setopt (s5r->curl,
1996 CURLOPT_URL,
1997 curlurl);
1998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1999 "Launching %s CURL interaction, fetching `%s'\n",
2000 (s5r->is_gns) ? "GNS" : "DNS",
2001 curlurl);
2002 GNUNET_free (curlurl);
2003 if (0 == strcasecmp (meth,
2004 MHD_HTTP_METHOD_PUT))
2005 {
2006 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
2007 curl_easy_setopt (s5r->curl,
2008 CURLOPT_UPLOAD,
2009 1L);
2010 curl_easy_setopt (s5r->curl,
2011 CURLOPT_WRITEFUNCTION,
2012 &curl_download_cb);
2013 curl_easy_setopt (s5r->curl,
2014 CURLOPT_WRITEDATA,
2015 s5r);
2016 GNUNET_assert (CURLE_OK ==
2017 curl_easy_setopt (s5r->curl,
2018 CURLOPT_READFUNCTION,
2019 &curl_upload_cb));
2020 curl_easy_setopt (s5r->curl,
2021 CURLOPT_READDATA,
2022 s5r);
2023 {
2024 const char *us;
2025 long upload_size = 0;
2026
2027 us = MHD_lookup_connection_value (con,
2028 MHD_HEADER_KIND,
2029 MHD_HTTP_HEADER_CONTENT_LENGTH);
2030 if ((1 == sscanf (us,
2031 "%ld",
2032 &upload_size)) &&
2033 (upload_size >= 0))
2127 { 2034 {
2128 curl_easy_setopt(s5r->curl, 2035 curl_easy_setopt (s5r->curl,
2129 CURLOPT_HTTP_VERSION, 2036 CURLOPT_INFILESIZE,
2130 CURL_HTTP_VERSION_1_0); 2037 upload_size);
2131 } 2038 }
2132 else if (0 == strcasecmp(ver, MHD_HTTP_VERSION_1_1)) 2039 }
2040 }
2041 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
2042 {
2043 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
2044 curl_easy_setopt (s5r->curl,
2045 CURLOPT_POST,
2046 1L);
2047 curl_easy_setopt (s5r->curl,
2048 CURLOPT_WRITEFUNCTION,
2049 &curl_download_cb);
2050 curl_easy_setopt (s5r->curl,
2051 CURLOPT_WRITEDATA,
2052 s5r);
2053 curl_easy_setopt (s5r->curl,
2054 CURLOPT_READFUNCTION,
2055 &curl_upload_cb);
2056 curl_easy_setopt (s5r->curl,
2057 CURLOPT_READDATA,
2058 s5r);
2059 {
2060 const char *us;
2061 long upload_size;
2062
2063 upload_size = 0;
2064 us = MHD_lookup_connection_value (con,
2065 MHD_HEADER_KIND,
2066 MHD_HTTP_HEADER_CONTENT_LENGTH);
2067 if ((NULL != us) &&
2068 (1 == sscanf (us,
2069 "%ld",
2070 &upload_size)) &&
2071 (upload_size >= 0))
2133 { 2072 {
2134 curl_easy_setopt(s5r->curl, 2073 curl_easy_setopt (s5r->curl,
2135 CURLOPT_HTTP_VERSION, 2074 CURLOPT_INFILESIZE,
2136 CURL_HTTP_VERSION_1_1); 2075 upload_size);
2137 } 2076 }
2138 else 2077 else
2139 { 2078 {
2140 curl_easy_setopt(s5r->curl, 2079 curl_easy_setopt (s5r->curl,
2141 CURLOPT_HTTP_VERSION, 2080 CURLOPT_INFILESIZE,
2142 CURL_HTTP_VERSION_NONE); 2081 upload_size);
2143 } 2082 }
2083 }
2084 }
2085 else if (0 == strcasecmp (meth,
2086 MHD_HTTP_METHOD_HEAD))
2087 {
2088 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2089 curl_easy_setopt (s5r->curl,
2090 CURLOPT_NOBODY,
2091 1L);
2092 }
2093 else if (0 == strcasecmp (meth,
2094 MHD_HTTP_METHOD_OPTIONS))
2095 {
2096 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2097 curl_easy_setopt (s5r->curl,
2098 CURLOPT_CUSTOMREQUEST,
2099 "OPTIONS");
2100 curl_easy_setopt (s5r->curl,
2101 CURLOPT_WRITEFUNCTION,
2102 &curl_download_cb);
2103 curl_easy_setopt (s5r->curl,
2104 CURLOPT_WRITEDATA,
2105 s5r);
2106 }
2107 else if (0 == strcasecmp (meth,
2108 MHD_HTTP_METHOD_GET))
2109 {
2110 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2111 curl_easy_setopt (s5r->curl,
2112 CURLOPT_HTTPGET,
2113 1L);
2114 curl_easy_setopt (s5r->curl,
2115 CURLOPT_WRITEFUNCTION,
2116 &curl_download_cb);
2117 curl_easy_setopt (s5r->curl,
2118 CURLOPT_WRITEDATA,
2119 s5r);
2120 }
2121 else if (0 == strcasecmp (meth,
2122 MHD_HTTP_METHOD_DELETE))
2123 {
2124 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2125 curl_easy_setopt (s5r->curl,
2126 CURLOPT_CUSTOMREQUEST,
2127 "DELETE");
2128 curl_easy_setopt (s5r->curl,
2129 CURLOPT_WRITEFUNCTION,
2130 &curl_download_cb);
2131 curl_easy_setopt (s5r->curl,
2132 CURLOPT_WRITEDATA,
2133 s5r);
2134 }
2135 else
2136 {
2137 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2138 _ ("Unsupported HTTP method `%s'\n"),
2139 meth);
2140 curl_easy_cleanup (s5r->curl);
2141 s5r->curl = NULL;
2142 return MHD_NO;
2143 }
2144 2144
2145 if (GNUNET_YES == s5r->is_tls) //(HTTPS_PORT == s5r->port) 2145 if (0 == strcasecmp (ver, MHD_HTTP_VERSION_1_0))
2146 { 2146 {
2147 curl_easy_setopt(s5r->curl, 2147 curl_easy_setopt (s5r->curl,
2148 CURLOPT_USE_SSL, 2148 CURLOPT_HTTP_VERSION,
2149 CURLUSESSL_ALL); 2149 CURL_HTTP_VERSION_1_0);
2150 if (0 < s5r->num_danes) 2150 }
2151 curl_easy_setopt(s5r->curl, 2151 else if (0 == strcasecmp (ver, MHD_HTTP_VERSION_1_1))
2152 CURLOPT_SSL_VERIFYPEER, 2152 {
2153 0L); 2153 curl_easy_setopt (s5r->curl,
2154 else 2154 CURLOPT_HTTP_VERSION,
2155 curl_easy_setopt(s5r->curl, 2155 CURL_HTTP_VERSION_1_1);
2156 CURLOPT_SSL_VERIFYPEER, 2156 }
2157 1L); 2157 else
2158 /* Disable cURL checking the hostname, as we will check ourselves 2158 {
2159 as only we have the domain name or the LEHO or the DANE record */ 2159 curl_easy_setopt (s5r->curl,
2160 curl_easy_setopt(s5r->curl, 2160 CURLOPT_HTTP_VERSION,
2161 CURLOPT_SSL_VERIFYHOST, 2161 CURL_HTTP_VERSION_NONE);
2162 0L); 2162 }
2163 } 2163
2164 if (GNUNET_YES == s5r->is_tls) // (HTTPS_PORT == s5r->port)
2165 {
2166 curl_easy_setopt (s5r->curl,
2167 CURLOPT_USE_SSL,
2168 CURLUSESSL_ALL);
2169 if (0 < s5r->num_danes)
2170 curl_easy_setopt (s5r->curl,
2171 CURLOPT_SSL_VERIFYPEER,
2172 0L);
2164 else 2173 else
2165 { 2174 curl_easy_setopt (s5r->curl,
2166 curl_easy_setopt(s5r->curl, 2175 CURLOPT_SSL_VERIFYPEER,
2167 CURLOPT_USE_SSL, 2176 1L);
2168 CURLUSESSL_NONE); 2177 /* Disable cURL checking the hostname, as we will check ourselves
2169 } 2178 as only we have the domain name or the LEHO or the DANE record */
2179 curl_easy_setopt (s5r->curl,
2180 CURLOPT_SSL_VERIFYHOST,
2181 0L);
2182 }
2183 else
2184 {
2185 curl_easy_setopt (s5r->curl,
2186 CURLOPT_USE_SSL,
2187 CURLUSESSL_NONE);
2188 }
2170 2189
2171 if (CURLM_OK != 2190 if (CURLM_OK !=
2172 curl_multi_add_handle(curl_multi, 2191 curl_multi_add_handle (curl_multi,
2173 s5r->curl)) 2192 s5r->curl))
2174 { 2193 {
2175 GNUNET_break(0); 2194 GNUNET_break (0);
2176 curl_easy_cleanup(s5r->curl); 2195 curl_easy_cleanup (s5r->curl);
2177 s5r->curl = NULL; 2196 s5r->curl = NULL;
2178 return MHD_NO; 2197 return MHD_NO;
2179 }
2180 MHD_get_connection_values(con,
2181 MHD_HEADER_KIND,
2182 (MHD_KeyValueIterator) & con_val_iter,
2183 s5r);
2184 curl_easy_setopt(s5r->curl,
2185 CURLOPT_HTTPHEADER,
2186 s5r->headers);
2187 curl_download_prepare();
2188 return MHD_YES;
2189 } 2198 }
2199 MHD_get_connection_values (con,
2200 MHD_HEADER_KIND,
2201 (MHD_KeyValueIterator) & con_val_iter,
2202 s5r);
2203 curl_easy_setopt (s5r->curl,
2204 CURLOPT_HTTPHEADER,
2205 s5r->headers);
2206 curl_download_prepare ();
2207 return MHD_YES;
2208 }
2190 2209
2191 /* continuing to process request */ 2210 /* continuing to process request */
2192 if (0 != *upload_data_size) 2211 if (0 != *upload_data_size)
2212 {
2213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2214 "Processing %u bytes UPLOAD\n",
2215 (unsigned int) *upload_data_size);
2216
2217 /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else
2218 * upload callback is not called!
2219 */
2220 curl_easy_setopt (s5r->curl,
2221 CURLOPT_POSTFIELDSIZE,
2222 *upload_data_size);
2223
2224 left = GNUNET_MIN (*upload_data_size,
2225 sizeof(s5r->io_buf) - s5r->io_len);
2226 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
2227 upload_data,
2228 left);
2229 s5r->io_len += left;
2230 *upload_data_size -= left;
2231 GNUNET_assert (NULL != s5r->curl);
2232 if (GNUNET_YES == s5r->curl_paused)
2193 { 2233 {
2194 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2234 s5r->curl_paused = GNUNET_NO;
2195 "Processing %u bytes UPLOAD\n", 2235 curl_easy_pause (s5r->curl,
2196 (unsigned int)*upload_data_size); 2236 CURLPAUSE_CONT);
2197
2198 /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else
2199 * upload callback is not called!
2200 */
2201 curl_easy_setopt(s5r->curl,
2202 CURLOPT_POSTFIELDSIZE,
2203 *upload_data_size);
2204
2205 left = GNUNET_MIN(*upload_data_size,
2206 sizeof(s5r->io_buf) - s5r->io_len);
2207 GNUNET_memcpy(&s5r->io_buf[s5r->io_len],
2208 upload_data,
2209 left);
2210 s5r->io_len += left;
2211 *upload_data_size -= left;
2212 GNUNET_assert(NULL != s5r->curl);
2213 if (GNUNET_YES == s5r->curl_paused)
2214 {
2215 s5r->curl_paused = GNUNET_NO;
2216 curl_easy_pause(s5r->curl,
2217 CURLPAUSE_CONT);
2218 }
2219 return MHD_YES;
2220 } 2237 }
2238 return MHD_YES;
2239 }
2221 if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) 2240 if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state)
2222 { 2241 {
2223 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2224 "Finished processing UPLOAD\n"); 2243 "Finished processing UPLOAD\n");
2225 s5r->state = SOCKS5_SOCKET_UPLOAD_DONE; 2244 s5r->state = SOCKS5_SOCKET_UPLOAD_DONE;
2226 } 2245 }
2227 if (NULL == s5r->response) 2246 if (NULL == s5r->response)
2228 { 2247 {
2229 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2230 "Waiting for HTTP response for %s%s...\n", 2249 "Waiting for HTTP response for %s%s...\n",
2231 s5r->domain, 2250 s5r->domain,
2232 s5r->url); 2251 s5r->url);
2233 MHD_suspend_connection(con); 2252 MHD_suspend_connection (con);
2234 s5r->suspended = GNUNET_YES; 2253 s5r->suspended = GNUNET_YES;
2235 return MHD_YES; 2254 return MHD_YES;
2236 } 2255 }
2237 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2238 "Queueing response for %s%s with MHD\n", 2257 "Queueing response for %s%s with MHD\n",
2239 s5r->domain, 2258 s5r->domain,
2240 s5r->url); 2259 s5r->url);
2241 run_mhd_now(s5r->hd); 2260 run_mhd_now (s5r->hd);
2242 return MHD_queue_response(con, 2261 return MHD_queue_response (con,
2243 s5r->response_code, 2262 s5r->response_code,
2244 s5r->response); 2263 s5r->response);
2245} 2264}
2246 2265
2247 2266
@@ -2258,51 +2277,51 @@ create_response(void *cls,
2258 * @param toe reason for request termination (ignored) 2277 * @param toe reason for request termination (ignored)
2259 */ 2278 */
2260static void 2279static void
2261mhd_completed_cb(void *cls, 2280mhd_completed_cb (void *cls,
2262 struct MHD_Connection *connection, 2281 struct MHD_Connection *connection,
2263 void **con_cls, 2282 void **con_cls,
2264 enum MHD_RequestTerminationCode toe) 2283 enum MHD_RequestTerminationCode toe)
2265{ 2284{
2266 struct Socks5Request *s5r = *con_cls; 2285 struct Socks5Request *s5r = *con_cls;
2267 2286
2268 if (NULL == s5r) 2287 if (NULL == s5r)
2269 return; 2288 return;
2270 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) 2289 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
2271 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 2290 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2272 "MHD encountered error handling request: %d\n", 2291 "MHD encountered error handling request: %d\n",
2273 toe); 2292 toe);
2274 if (NULL != s5r->curl) 2293 if (NULL != s5r->curl)
2275 { 2294 {
2276 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2277 "Removing cURL handle (MHD interaction complete)\n"); 2296 "Removing cURL handle (MHD interaction complete)\n");
2278 curl_multi_remove_handle(curl_multi, 2297 curl_multi_remove_handle (curl_multi,
2279 s5r->curl); 2298 s5r->curl);
2280 curl_slist_free_all(s5r->headers); 2299 curl_slist_free_all (s5r->headers);
2281 s5r->headers = NULL; 2300 s5r->headers = NULL;
2282 curl_easy_reset(s5r->curl); 2301 curl_easy_reset (s5r->curl);
2283 s5r->rbuf_len = 0; 2302 s5r->rbuf_len = 0;
2284 s5r->wbuf_len = 0; 2303 s5r->wbuf_len = 0;
2285 s5r->io_len = 0; 2304 s5r->io_len = 0;
2286 curl_download_prepare(); 2305 curl_download_prepare ();
2287 } 2306 }
2288 if ((NULL != s5r->response) && 2307 if ((NULL != s5r->response) &&
2289 (curl_failure_response != s5r->response)) 2308 (curl_failure_response != s5r->response))
2290 MHD_destroy_response(s5r->response); 2309 MHD_destroy_response (s5r->response);
2291 for (struct HttpResponseHeader *header = s5r->header_head; 2310 for (struct HttpResponseHeader *header = s5r->header_head;
2292 NULL != header; 2311 NULL != header;
2293 header = s5r->header_head) 2312 header = s5r->header_head)
2294 { 2313 {
2295 GNUNET_CONTAINER_DLL_remove(s5r->header_head, 2314 GNUNET_CONTAINER_DLL_remove (s5r->header_head,
2296 s5r->header_tail, 2315 s5r->header_tail,
2297 header); 2316 header);
2298 GNUNET_free(header->type); 2317 GNUNET_free (header->type);
2299 GNUNET_free(header->value); 2318 GNUNET_free (header->value);
2300 GNUNET_free(header); 2319 GNUNET_free (header);
2301 } 2320 }
2302 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2303 "Finished request for %s\n", 2322 "Finished request for %s\n",
2304 s5r->url); 2323 s5r->url);
2305 GNUNET_free(s5r->url); 2324 GNUNET_free (s5r->url);
2306 s5r->state = SOCKS5_SOCKET_WITH_MHD; 2325 s5r->state = SOCKS5_SOCKET_WITH_MHD;
2307 s5r->url = NULL; 2326 s5r->url = NULL;
2308 s5r->response = NULL; 2327 s5r->response = NULL;
@@ -2320,58 +2339,58 @@ mhd_completed_cb(void *cls,
2320 * @param toe connection notification type 2339 * @param toe connection notification type
2321 */ 2340 */
2322static void 2341static void
2323mhd_connection_cb(void *cls, 2342mhd_connection_cb (void *cls,
2324 struct MHD_Connection *connection, 2343 struct MHD_Connection *connection,
2325 void **con_cls, 2344 void **con_cls,
2326 enum MHD_ConnectionNotificationCode cnc) 2345 enum MHD_ConnectionNotificationCode cnc)
2327{ 2346{
2328 struct Socks5Request *s5r; 2347 struct Socks5Request *s5r;
2329 const union MHD_ConnectionInfo *ci; 2348 const union MHD_ConnectionInfo *ci;
2330 int sock; 2349 int sock;
2331 2350
2332 switch (cnc) 2351 switch (cnc)
2352 {
2353 case MHD_CONNECTION_NOTIFY_STARTED:
2354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
2355 ci = MHD_get_connection_info (connection,
2356 MHD_CONNECTION_INFO_CONNECTION_FD);
2357 if (NULL == ci)
2333 { 2358 {
2334 case MHD_CONNECTION_NOTIFY_STARTED: 2359 GNUNET_break (0);
2335 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n"); 2360 return;
2336 ci = MHD_get_connection_info(connection, 2361 }
2337 MHD_CONNECTION_INFO_CONNECTION_FD); 2362 sock = ci->connect_fd;
2338 if (NULL == ci) 2363 for (s5r = s5r_head; NULL != s5r; s5r = s5r->next)
2339 { 2364 {
2340 GNUNET_break(0); 2365 if (GNUNET_NETWORK_get_fd (s5r->sock) == sock)
2341 return; 2366 {
2342 } 2367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2343 sock = ci->connect_fd; 2368 "Context set...\n");
2344 for (s5r = s5r_head; NULL != s5r; s5r = s5r->next) 2369 s5r->ssl_checked = GNUNET_NO;
2345 { 2370 *con_cls = s5r;
2346 if (GNUNET_NETWORK_get_fd(s5r->sock) == sock) 2371 break;
2347 { 2372 }
2348 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2373 }
2349 "Context set...\n"); 2374 break;
2350 s5r->ssl_checked = GNUNET_NO;
2351 *con_cls = s5r;
2352 break;
2353 }
2354 }
2355 break;
2356
2357 case MHD_CONNECTION_NOTIFY_CLOSED:
2358 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2359 "Connection closed... cleaning up\n");
2360 s5r = *con_cls;
2361 if (NULL == s5r)
2362 {
2363 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2364 "Connection stale!\n");
2365 return;
2366 }
2367 cleanup_s5r(s5r);
2368 curl_download_prepare();
2369 *con_cls = NULL;
2370 break;
2371 2375
2372 default: 2376 case MHD_CONNECTION_NOTIFY_CLOSED:
2373 GNUNET_break(0); 2377 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2378 "Connection closed... cleaning up\n");
2379 s5r = *con_cls;
2380 if (NULL == s5r)
2381 {
2382 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2383 "Connection stale!\n");
2384 return;
2374 } 2385 }
2386 cleanup_s5r (s5r);
2387 curl_download_prepare ();
2388 *con_cls = NULL;
2389 break;
2390
2391 default:
2392 GNUNET_break (0);
2393 }
2375} 2394}
2376 2395
2377/** 2396/**
@@ -2388,34 +2407,34 @@ mhd_connection_cb(void *cls,
2388 * @return the `struct Socks5Request` that this @a connection is for 2407 * @return the `struct Socks5Request` that this @a connection is for
2389 */ 2408 */
2390static void * 2409static void *
2391mhd_log_callback(void *cls, 2410mhd_log_callback (void *cls,
2392 const char *url, 2411 const char *url,
2393 struct MHD_Connection *connection) 2412 struct MHD_Connection *connection)
2394{ 2413{
2395 struct Socks5Request *s5r; 2414 struct Socks5Request *s5r;
2396 const union MHD_ConnectionInfo *ci; 2415 const union MHD_ConnectionInfo *ci;
2397 2416
2398 ci = MHD_get_connection_info(connection, 2417 ci = MHD_get_connection_info (connection,
2399 MHD_CONNECTION_INFO_SOCKET_CONTEXT); 2418 MHD_CONNECTION_INFO_SOCKET_CONTEXT);
2400 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); 2419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
2401 if (NULL == ci) 2420 if (NULL == ci)
2402 { 2421 {
2403 GNUNET_break(0); 2422 GNUNET_break (0);
2404 return NULL; 2423 return NULL;
2405 } 2424 }
2406 s5r = ci->socket_context; 2425 s5r = ci->socket_context;
2407 if (NULL != s5r->url) 2426 if (NULL != s5r->url)
2408 { 2427 {
2409 GNUNET_break(0); 2428 GNUNET_break (0);
2410 return NULL; 2429 return NULL;
2411 } 2430 }
2412 s5r->url = GNUNET_strdup(url); 2431 s5r->url = GNUNET_strdup (url);
2413 if (NULL != s5r->timeout_task) 2432 if (NULL != s5r->timeout_task)
2414 { 2433 {
2415 GNUNET_SCHEDULER_cancel(s5r->timeout_task); 2434 GNUNET_SCHEDULER_cancel (s5r->timeout_task);
2416 s5r->timeout_task = NULL; 2435 s5r->timeout_task = NULL;
2417 } 2436 }
2418 GNUNET_assert(s5r->state == SOCKS5_SOCKET_WITH_MHD); 2437 GNUNET_assert (s5r->state == SOCKS5_SOCKET_WITH_MHD);
2419 return s5r; 2438 return s5r;
2420} 2439}
2421 2440
@@ -2426,22 +2445,22 @@ mhd_log_callback(void *cls,
2426 * @param hd daemon to stop 2445 * @param hd daemon to stop
2427 */ 2446 */
2428static void 2447static void
2429kill_httpd(struct MhdHttpList *hd) 2448kill_httpd (struct MhdHttpList *hd)
2430{ 2449{
2431 GNUNET_CONTAINER_DLL_remove(mhd_httpd_head, 2450 GNUNET_CONTAINER_DLL_remove (mhd_httpd_head,
2432 mhd_httpd_tail, 2451 mhd_httpd_tail,
2433 hd); 2452 hd);
2434 GNUNET_free_non_null(hd->domain); 2453 GNUNET_free_non_null (hd->domain);
2435 MHD_stop_daemon(hd->daemon); 2454 MHD_stop_daemon (hd->daemon);
2436 if (NULL != hd->httpd_task) 2455 if (NULL != hd->httpd_task)
2437 { 2456 {
2438 GNUNET_SCHEDULER_cancel(hd->httpd_task); 2457 GNUNET_SCHEDULER_cancel (hd->httpd_task);
2439 hd->httpd_task = NULL; 2458 hd->httpd_task = NULL;
2440 } 2459 }
2441 GNUNET_free_non_null(hd->proxy_cert); 2460 GNUNET_free_non_null (hd->proxy_cert);
2442 if (hd == httpd) 2461 if (hd == httpd)
2443 httpd = NULL; 2462 httpd = NULL;
2444 GNUNET_free(hd); 2463 GNUNET_free (hd);
2445} 2464}
2446 2465
2447 2466
@@ -2451,12 +2470,12 @@ kill_httpd(struct MhdHttpList *hd)
2451 * @param cls the `struct MhdHttpList *` 2470 * @param cls the `struct MhdHttpList *`
2452 */ 2471 */
2453static void 2472static void
2454kill_httpd_task(void *cls) 2473kill_httpd_task (void *cls)
2455{ 2474{
2456 struct MhdHttpList *hd = cls; 2475 struct MhdHttpList *hd = cls;
2457 2476
2458 hd->httpd_task = NULL; 2477 hd->httpd_task = NULL;
2459 kill_httpd(hd); 2478 kill_httpd (hd);
2460} 2479}
2461 2480
2462 2481
@@ -2466,7 +2485,7 @@ kill_httpd_task(void *cls)
2466 * @param cls the `struct MhdHttpList *` of the daemon that is being run 2485 * @param cls the `struct MhdHttpList *` of the daemon that is being run
2467 */ 2486 */
2468static void 2487static void
2469do_httpd(void *cls); 2488do_httpd (void *cls);
2470 2489
2471 2490
2472/** 2491/**
@@ -2477,7 +2496,7 @@ do_httpd(void *cls);
2477 * @param hd the daemon to schedule 2496 * @param hd the daemon to schedule
2478 */ 2497 */
2479static void 2498static void
2480schedule_httpd(struct MhdHttpList *hd) 2499schedule_httpd (struct MhdHttpList *hd)
2481{ 2500{
2482 fd_set rs; 2501 fd_set rs;
2483 fd_set ws; 2502 fd_set ws;
@@ -2489,63 +2508,63 @@ schedule_httpd(struct MhdHttpList *hd)
2489 MHD_UNSIGNED_LONG_LONG timeout; 2508 MHD_UNSIGNED_LONG_LONG timeout;
2490 struct GNUNET_TIME_Relative tv; 2509 struct GNUNET_TIME_Relative tv;
2491 2510
2492 FD_ZERO(&rs); 2511 FD_ZERO (&rs);
2493 FD_ZERO(&ws); 2512 FD_ZERO (&ws);
2494 FD_ZERO(&es); 2513 FD_ZERO (&es);
2495 max = -1; 2514 max = -1;
2496 if (MHD_YES != 2515 if (MHD_YES !=
2497 MHD_get_fdset(hd->daemon, 2516 MHD_get_fdset (hd->daemon,
2498 &rs, 2517 &rs,
2499 &ws, 2518 &ws,
2500 &es, 2519 &es,
2501 &max)) 2520 &max))
2502 { 2521 {
2503 kill_httpd(hd); 2522 kill_httpd (hd);
2504 return; 2523 return;
2505 } 2524 }
2506 haveto = MHD_get_timeout(hd->daemon, 2525 haveto = MHD_get_timeout (hd->daemon,
2507 &timeout); 2526 &timeout);
2508 if (MHD_YES == haveto) 2527 if (MHD_YES == haveto)
2509 tv.rel_value_us = (uint64_t)timeout * 1000LL; 2528 tv.rel_value_us = (uint64_t) timeout * 1000LL;
2510 else 2529 else
2511 tv = GNUNET_TIME_UNIT_FOREVER_REL; 2530 tv = GNUNET_TIME_UNIT_FOREVER_REL;
2512 if (-1 != max) 2531 if (-1 != max)
2513 { 2532 {
2514 wrs = GNUNET_NETWORK_fdset_create(); 2533 wrs = GNUNET_NETWORK_fdset_create ();
2515 wws = GNUNET_NETWORK_fdset_create(); 2534 wws = GNUNET_NETWORK_fdset_create ();
2516 GNUNET_NETWORK_fdset_copy_native(wrs, &rs, max + 1); 2535 GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
2517 GNUNET_NETWORK_fdset_copy_native(wws, &ws, max + 1); 2536 GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
2518 } 2537 }
2519 else 2538 else
2520 { 2539 {
2521 wrs = NULL; 2540 wrs = NULL;
2522 wws = NULL; 2541 wws = NULL;
2523 } 2542 }
2524 if (NULL != hd->httpd_task) 2543 if (NULL != hd->httpd_task)
2525 { 2544 {
2526 GNUNET_SCHEDULER_cancel(hd->httpd_task); 2545 GNUNET_SCHEDULER_cancel (hd->httpd_task);
2527 hd->httpd_task = NULL; 2546 hd->httpd_task = NULL;
2528 } 2547 }
2529 if ((MHD_YES != haveto) && 2548 if ((MHD_YES != haveto) &&
2530 (-1 == max) && 2549 (-1 == max) &&
2531 (hd != httpd)) 2550 (hd != httpd))
2532 { 2551 {
2533 /* daemon is idle, kill after timeout */ 2552 /* daemon is idle, kill after timeout */
2534 hd->httpd_task = GNUNET_SCHEDULER_add_delayed(MHD_CACHE_TIMEOUT, 2553 hd->httpd_task = GNUNET_SCHEDULER_add_delayed (MHD_CACHE_TIMEOUT,
2535 &kill_httpd_task, 2554 &kill_httpd_task,
2536 hd); 2555 hd);
2537 } 2556 }
2538 else 2557 else
2539 { 2558 {
2540 hd->httpd_task = 2559 hd->httpd_task =
2541 GNUNET_SCHEDULER_add_select(GNUNET_SCHEDULER_PRIORITY_DEFAULT, 2560 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
2542 tv, wrs, wws, 2561 tv, wrs, wws,
2543 &do_httpd, hd); 2562 &do_httpd, hd);
2544 } 2563 }
2545 if (NULL != wrs) 2564 if (NULL != wrs)
2546 GNUNET_NETWORK_fdset_destroy(wrs); 2565 GNUNET_NETWORK_fdset_destroy (wrs);
2547 if (NULL != wws) 2566 if (NULL != wws)
2548 GNUNET_NETWORK_fdset_destroy(wws); 2567 GNUNET_NETWORK_fdset_destroy (wws);
2549} 2568}
2550 2569
2551 2570
@@ -2555,13 +2574,13 @@ schedule_httpd(struct MhdHttpList *hd)
2555 * @param cls the `struct MhdHttpList` of the daemon that is being run 2574 * @param cls the `struct MhdHttpList` of the daemon that is being run
2556 */ 2575 */
2557static void 2576static void
2558do_httpd(void *cls) 2577do_httpd (void *cls)
2559{ 2578{
2560 struct MhdHttpList *hd = cls; 2579 struct MhdHttpList *hd = cls;
2561 2580
2562 hd->httpd_task = NULL; 2581 hd->httpd_task = NULL;
2563 MHD_run(hd->daemon); 2582 MHD_run (hd->daemon);
2564 schedule_httpd(hd); 2583 schedule_httpd (hd);
2565} 2584}
2566 2585
2567 2586
@@ -2571,12 +2590,12 @@ do_httpd(void *cls)
2571 * @param hd the daemon to run now. 2590 * @param hd the daemon to run now.
2572 */ 2591 */
2573static void 2592static void
2574run_mhd_now(struct MhdHttpList *hd) 2593run_mhd_now (struct MhdHttpList *hd)
2575{ 2594{
2576 if (NULL != hd->httpd_task) 2595 if (NULL != hd->httpd_task)
2577 GNUNET_SCHEDULER_cancel(hd->httpd_task); 2596 GNUNET_SCHEDULER_cancel (hd->httpd_task);
2578 hd->httpd_task = GNUNET_SCHEDULER_add_now(&do_httpd, 2597 hd->httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd,
2579 hd); 2598 hd);
2580} 2599}
2581 2600
2582 2601
@@ -2588,30 +2607,30 @@ run_mhd_now(struct MhdHttpList *hd)
2588 * @return NULL on error 2607 * @return NULL on error
2589 */ 2608 */
2590static void* 2609static void*
2591load_file(const char* filename, 2610load_file (const char*filename,
2592 unsigned int* size) 2611 unsigned int*size)
2593{ 2612{
2594 void *buffer; 2613 void *buffer;
2595 uint64_t fsize; 2614 uint64_t fsize;
2596 2615
2597 if (GNUNET_OK != 2616 if (GNUNET_OK !=
2598 GNUNET_DISK_file_size(filename, 2617 GNUNET_DISK_file_size (filename,
2599 &fsize, 2618 &fsize,
2600 GNUNET_YES, 2619 GNUNET_YES,
2601 GNUNET_YES)) 2620 GNUNET_YES))
2602 return NULL; 2621 return NULL;
2603 if (fsize > MAX_PEM_SIZE) 2622 if (fsize > MAX_PEM_SIZE)
2604 return NULL; 2623 return NULL;
2605 *size = (unsigned int)fsize; 2624 *size = (unsigned int) fsize;
2606 buffer = GNUNET_malloc(*size); 2625 buffer = GNUNET_malloc (*size);
2607 if (fsize != 2626 if (fsize !=
2608 GNUNET_DISK_fn_read(filename, 2627 GNUNET_DISK_fn_read (filename,
2609 buffer, 2628 buffer,
2610 (size_t)fsize)) 2629 (size_t) fsize))
2611 { 2630 {
2612 GNUNET_free(buffer); 2631 GNUNET_free (buffer);
2613 return NULL; 2632 return NULL;
2614 } 2633 }
2615 return buffer; 2634 return buffer;
2616} 2635}
2617 2636
@@ -2624,25 +2643,25 @@ load_file(const char* filename,
2624 * @return #GNUNET_OK on success 2643 * @return #GNUNET_OK on success
2625 */ 2644 */
2626static int 2645static int
2627load_key_from_file(gnutls_x509_privkey_t key, 2646load_key_from_file (gnutls_x509_privkey_t key,
2628 const char* keyfile) 2647 const char*keyfile)
2629{ 2648{
2630 gnutls_datum_t key_data; 2649 gnutls_datum_t key_data;
2631 int ret; 2650 int ret;
2632 2651
2633 key_data.data = load_file(keyfile, 2652 key_data.data = load_file (keyfile,
2634 &key_data.size); 2653 &key_data.size);
2635 if (NULL == key_data.data) 2654 if (NULL == key_data.data)
2636 return GNUNET_SYSERR; 2655 return GNUNET_SYSERR;
2637 ret = gnutls_x509_privkey_import(key, &key_data, 2656 ret = gnutls_x509_privkey_import (key, &key_data,
2638 GNUTLS_X509_FMT_PEM); 2657 GNUTLS_X509_FMT_PEM);
2639 if (GNUTLS_E_SUCCESS != ret) 2658 if (GNUTLS_E_SUCCESS != ret)
2640 { 2659 {
2641 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2660 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2642 _("Unable to import private key from file `%s'\n"), 2661 _ ("Unable to import private key from file `%s'\n"),
2643 keyfile); 2662 keyfile);
2644 } 2663 }
2645 GNUNET_free_non_null(key_data.data); 2664 GNUNET_free_non_null (key_data.data);
2646 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK; 2665 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK;
2647} 2666}
2648 2667
@@ -2655,26 +2674,26 @@ load_key_from_file(gnutls_x509_privkey_t key,
2655 * @return #GNUNET_OK on success 2674 * @return #GNUNET_OK on success
2656 */ 2675 */
2657static int 2676static int
2658load_cert_from_file(gnutls_x509_crt_t crt, 2677load_cert_from_file (gnutls_x509_crt_t crt,
2659 const char* certfile) 2678 const char*certfile)
2660{ 2679{
2661 gnutls_datum_t cert_data; 2680 gnutls_datum_t cert_data;
2662 int ret; 2681 int ret;
2663 2682
2664 cert_data.data = load_file(certfile, 2683 cert_data.data = load_file (certfile,
2665 &cert_data.size); 2684 &cert_data.size);
2666 if (NULL == cert_data.data) 2685 if (NULL == cert_data.data)
2667 return GNUNET_SYSERR; 2686 return GNUNET_SYSERR;
2668 ret = gnutls_x509_crt_import(crt, 2687 ret = gnutls_x509_crt_import (crt,
2669 &cert_data, 2688 &cert_data,
2670 GNUTLS_X509_FMT_PEM); 2689 GNUTLS_X509_FMT_PEM);
2671 if (GNUTLS_E_SUCCESS != ret) 2690 if (GNUTLS_E_SUCCESS != ret)
2672 { 2691 {
2673 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2692 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2674 _("Unable to import certificate from `%s'\n"), 2693 _ ("Unable to import certificate from `%s'\n"),
2675 certfile); 2694 certfile);
2676 } 2695 }
2677 GNUNET_free_non_null(cert_data.data); 2696 GNUNET_free_non_null (cert_data.data);
2678 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK; 2697 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK;
2679} 2698}
2680 2699
@@ -2686,7 +2705,7 @@ load_cert_from_file(gnutls_x509_crt_t crt,
2686 * @return a struct holding the PEM data, NULL on error 2705 * @return a struct holding the PEM data, NULL on error
2687 */ 2706 */
2688static struct ProxyGNSCertificate * 2707static struct ProxyGNSCertificate *
2689generate_gns_certificate(const char *name) 2708generate_gns_certificate (const char *name)
2690{ 2709{
2691 unsigned int serial; 2710 unsigned int serial;
2692 size_t key_buf_size; 2711 size_t key_buf_size;
@@ -2696,65 +2715,66 @@ generate_gns_certificate(const char *name)
2696 struct tm *tm_data; 2715 struct tm *tm_data;
2697 struct ProxyGNSCertificate *pgc; 2716 struct ProxyGNSCertificate *pgc;
2698 2717
2699 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2700 "Generating x.509 certificate for `%s'\n", 2719 "Generating x.509 certificate for `%s'\n",
2701 name); 2720 name);
2702 GNUNET_break(GNUTLS_E_SUCCESS == gnutls_x509_crt_init(&request)); 2721 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_init (&request));
2703 GNUNET_break(GNUTLS_E_SUCCESS == gnutls_x509_crt_set_key(request, proxy_ca.key)); 2722 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_key (request,
2704 pgc = GNUNET_new(struct ProxyGNSCertificate); 2723 proxy_ca.key));
2705 gnutls_x509_crt_set_dn_by_oid(request, 2724 pgc = GNUNET_new (struct ProxyGNSCertificate);
2706 GNUTLS_OID_X520_COUNTRY_NAME, 2725 gnutls_x509_crt_set_dn_by_oid (request,
2707 0, 2726 GNUTLS_OID_X520_COUNTRY_NAME,
2708 "ZZ", 2727 0,
2709 strlen("ZZ")); 2728 "ZZ",
2710 gnutls_x509_crt_set_dn_by_oid(request, 2729 strlen ("ZZ"));
2711 GNUTLS_OID_X520_ORGANIZATION_NAME, 2730 gnutls_x509_crt_set_dn_by_oid (request,
2712 0, 2731 GNUTLS_OID_X520_ORGANIZATION_NAME,
2713 "GNU Name System", 2732 0,
2714 strlen("GNU Name System")); 2733 "GNU Name System",
2715 gnutls_x509_crt_set_dn_by_oid(request, 2734 strlen ("GNU Name System"));
2716 GNUTLS_OID_X520_COMMON_NAME, 2735 gnutls_x509_crt_set_dn_by_oid (request,
2717 0, 2736 GNUTLS_OID_X520_COMMON_NAME,
2718 name, 2737 0,
2719 strlen(name)); 2738 name,
2720 gnutls_x509_crt_set_subject_alternative_name(request, 2739 strlen (name));
2721 GNUTLS_SAN_DNSNAME, 2740 gnutls_x509_crt_set_subject_alternative_name (request,
2722 name); 2741 GNUTLS_SAN_DNSNAME,
2723 GNUNET_break(GNUTLS_E_SUCCESS == 2742 name);
2724 gnutls_x509_crt_set_version(request, 2743 GNUNET_break (GNUTLS_E_SUCCESS ==
2725 3)); 2744 gnutls_x509_crt_set_version (request,
2726 gnutls_rnd(GNUTLS_RND_NONCE, 2745 3));
2727 &serial, 2746 gnutls_rnd (GNUTLS_RND_NONCE,
2728 sizeof(serial)); 2747 &serial,
2729 gnutls_x509_crt_set_serial(request, 2748 sizeof(serial));
2730 &serial, 2749 gnutls_x509_crt_set_serial (request,
2731 sizeof(serial)); 2750 &serial,
2732 etime = time(NULL); 2751 sizeof(serial));
2733 tm_data = localtime(&etime); 2752 etime = time (NULL);
2753 tm_data = localtime (&etime);
2734 tm_data->tm_hour--; 2754 tm_data->tm_hour--;
2735 etime = mktime(tm_data); 2755 etime = mktime (tm_data);
2736 gnutls_x509_crt_set_activation_time(request, 2756 gnutls_x509_crt_set_activation_time (request,
2737 etime); 2757 etime);
2738 tm_data->tm_year++; 2758 tm_data->tm_year++;
2739 etime = mktime(tm_data); 2759 etime = mktime (tm_data);
2740 gnutls_x509_crt_set_expiration_time(request, 2760 gnutls_x509_crt_set_expiration_time (request,
2741 etime); 2761 etime);
2742 gnutls_x509_crt_sign2(request, 2762 gnutls_x509_crt_sign2 (request,
2743 proxy_ca.cert, 2763 proxy_ca.cert,
2744 proxy_ca.key, 2764 proxy_ca.key,
2745 GNUTLS_DIG_SHA512, 2765 GNUTLS_DIG_SHA512,
2746 0); 2766 0);
2747 key_buf_size = sizeof(pgc->key); 2767 key_buf_size = sizeof(pgc->key);
2748 cert_buf_size = sizeof(pgc->cert); 2768 cert_buf_size = sizeof(pgc->cert);
2749 gnutls_x509_crt_export(request, 2769 gnutls_x509_crt_export (request,
2750 GNUTLS_X509_FMT_PEM, 2770 GNUTLS_X509_FMT_PEM,
2751 pgc->cert, 2771 pgc->cert,
2752 &cert_buf_size); 2772 &cert_buf_size);
2753 gnutls_x509_privkey_export(proxy_ca.key, 2773 gnutls_x509_privkey_export (proxy_ca.key,
2754 GNUTLS_X509_FMT_PEM, 2774 GNUTLS_X509_FMT_PEM,
2755 pgc->key, 2775 pgc->key,
2756 &key_buf_size); 2776 &key_buf_size);
2757 gnutls_x509_crt_deinit(request); 2777 gnutls_x509_crt_deinit (request);
2758 return pgc; 2778 return pgc;
2759} 2779}
2760 2780
@@ -2767,9 +2787,9 @@ generate_gns_certificate(const char *name)
2767 * @param ap arguments to @a fm 2787 * @param ap arguments to @a fm
2768 */ 2788 */
2769static void 2789static void
2770mhd_error_log_callback(void *cls, 2790mhd_error_log_callback (void *cls,
2771 const char *fm, 2791 const char *fm,
2772 va_list ap) 2792 va_list ap)
2773{ 2793{
2774 /* do nothing */ 2794 /* do nothing */
2775} 2795}
@@ -2782,49 +2802,56 @@ mhd_error_log_callback(void *cls,
2782 * @return NULL on error 2802 * @return NULL on error
2783 */ 2803 */
2784static struct MhdHttpList * 2804static struct MhdHttpList *
2785lookup_ssl_httpd(const char* domain) 2805lookup_ssl_httpd (const char*domain)
2786{ 2806{
2787 struct MhdHttpList *hd; 2807 struct MhdHttpList *hd;
2788 struct ProxyGNSCertificate *pgc; 2808 struct ProxyGNSCertificate *pgc;
2789 2809
2790 if (NULL == domain) 2810 if (NULL == domain)
2791 { 2811 {
2792 GNUNET_break(0); 2812 GNUNET_break (0);
2793 return NULL; 2813 return NULL;
2794 } 2814 }
2795 for (hd = mhd_httpd_head; NULL != hd; hd = hd->next) 2815 for (hd = mhd_httpd_head; NULL != hd; hd = hd->next)
2796 if ((NULL != hd->domain) && 2816 if ((NULL != hd->domain) &&
2797 (0 == strcmp(hd->domain, domain))) 2817 (0 == strcmp (hd->domain, domain)))
2798 return hd; 2818 return hd;
2799 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2800 "Starting fresh MHD HTTPS instance for domain `%s'\n", 2820 "Starting fresh MHD HTTPS instance for domain `%s'\n",
2801 domain); 2821 domain);
2802 pgc = generate_gns_certificate(domain); 2822 pgc = generate_gns_certificate (domain);
2803 hd = GNUNET_new(struct MhdHttpList); 2823 hd = GNUNET_new (struct MhdHttpList);
2804 hd->is_ssl = GNUNET_YES; 2824 hd->is_ssl = GNUNET_YES;
2805 hd->domain = GNUNET_strdup(domain); 2825 hd->domain = GNUNET_strdup (domain);
2806 hd->proxy_cert = pgc; 2826 hd->proxy_cert = pgc;
2807 hd->daemon = MHD_start_daemon(MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_NO_LISTEN_SOCKET | MHD_ALLOW_SUSPEND_RESUME, 2827 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL
2808 0, 2828 | MHD_USE_NO_LISTEN_SOCKET
2809 NULL, NULL, 2829 | MHD_ALLOW_SUSPEND_RESUME,
2810 &create_response, hd, 2830 0,
2811 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int)16, 2831 NULL, NULL,
2812 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL, 2832 &create_response, hd,
2813 MHD_OPTION_NOTIFY_CONNECTION, &mhd_connection_cb, NULL, 2833 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned
2814 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL, 2834 int) 16,
2815 MHD_OPTION_EXTERNAL_LOGGER, &mhd_error_log_callback, NULL, 2835 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb,
2816 MHD_OPTION_HTTPS_MEM_KEY, pgc->key, 2836 NULL,
2817 MHD_OPTION_HTTPS_MEM_CERT, pgc->cert, 2837 MHD_OPTION_NOTIFY_CONNECTION,
2818 MHD_OPTION_END); 2838 &mhd_connection_cb, NULL,
2839 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback,
2840 NULL,
2841 MHD_OPTION_EXTERNAL_LOGGER,
2842 &mhd_error_log_callback, NULL,
2843 MHD_OPTION_HTTPS_MEM_KEY, pgc->key,
2844 MHD_OPTION_HTTPS_MEM_CERT, pgc->cert,
2845 MHD_OPTION_END);
2819 if (NULL == hd->daemon) 2846 if (NULL == hd->daemon)
2820 { 2847 {
2821 GNUNET_free(pgc); 2848 GNUNET_free (pgc);
2822 GNUNET_free(hd); 2849 GNUNET_free (hd);
2823 return NULL; 2850 return NULL;
2824 } 2851 }
2825 GNUNET_CONTAINER_DLL_insert(mhd_httpd_head, 2852 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head,
2826 mhd_httpd_tail, 2853 mhd_httpd_tail,
2827 hd); 2854 hd);
2828 return hd; 2855 return hd;
2829} 2856}
2830 2857
@@ -2837,12 +2864,12 @@ lookup_ssl_httpd(const char* domain)
2837 * @param cls the `struct Socks5Request *` 2864 * @param cls the `struct Socks5Request *`
2838 */ 2865 */
2839static void 2866static void
2840timeout_s5r_handshake(void *cls) 2867timeout_s5r_handshake (void *cls)
2841{ 2868{
2842 struct Socks5Request *s5r = cls; 2869 struct Socks5Request *s5r = cls;
2843 2870
2844 s5r->timeout_task = NULL; 2871 s5r->timeout_task = NULL;
2845 cleanup_s5r(s5r); 2872 cleanup_s5r (s5r);
2846} 2873}
2847 2874
2848 2875
@@ -2855,7 +2882,7 @@ timeout_s5r_handshake(void *cls)
2855 * @param s5r socks request that has reached the final stage 2882 * @param s5r socks request that has reached the final stage
2856 */ 2883 */
2857static void 2884static void
2858setup_data_transfer(struct Socks5Request *s5r) 2885setup_data_transfer (struct Socks5Request *s5r)
2859{ 2886{
2860 struct MhdHttpList *hd; 2887 struct MhdHttpList *hd;
2861 int fd; 2888 int fd;
@@ -2864,49 +2891,49 @@ setup_data_transfer(struct Socks5Request *s5r)
2864 char *domain; 2891 char *domain;
2865 2892
2866 if (GNUNET_YES == s5r->is_tls) 2893 if (GNUNET_YES == s5r->is_tls)
2867 { 2894 {
2868 GNUNET_asprintf(&domain, 2895 GNUNET_asprintf (&domain,
2869 "%s", 2896 "%s",
2870 s5r->domain);
2871 hd = lookup_ssl_httpd(domain);
2872 if (NULL == hd)
2873 {
2874 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2875 _("Failed to start HTTPS server for `%s'\n"),
2876 s5r->domain); 2897 s5r->domain);
2877 cleanup_s5r(s5r); 2898 hd = lookup_ssl_httpd (domain);
2878 GNUNET_free(domain); 2899 if (NULL == hd)
2879 return; 2900 {
2880 } 2901 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2902 _ ("Failed to start HTTPS server for `%s'\n"),
2903 s5r->domain);
2904 cleanup_s5r (s5r);
2905 GNUNET_free (domain);
2906 return;
2881 } 2907 }
2908 }
2882 else 2909 else
2883 { 2910 {
2884 domain = NULL; 2911 domain = NULL;
2885 GNUNET_assert(NULL != httpd); 2912 GNUNET_assert (NULL != httpd);
2886 hd = httpd; 2913 hd = httpd;
2887 } 2914 }
2888 fd = GNUNET_NETWORK_get_fd(s5r->sock); 2915 fd = GNUNET_NETWORK_get_fd (s5r->sock);
2889 addr = GNUNET_NETWORK_get_addr(s5r->sock); 2916 addr = GNUNET_NETWORK_get_addr (s5r->sock);
2890 len = GNUNET_NETWORK_get_addrlen(s5r->sock); 2917 len = GNUNET_NETWORK_get_addrlen (s5r->sock);
2891 s5r->state = SOCKS5_SOCKET_WITH_MHD; 2918 s5r->state = SOCKS5_SOCKET_WITH_MHD;
2892 if (MHD_YES != 2919 if (MHD_YES !=
2893 MHD_add_connection(hd->daemon, 2920 MHD_add_connection (hd->daemon,
2894 fd, 2921 fd,
2895 addr, 2922 addr,
2896 len)) 2923 len))
2897 { 2924 {
2898 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 2925 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2899 _("Failed to pass client to MHD\n")); 2926 _ ("Failed to pass client to MHD\n"));
2900 cleanup_s5r(s5r); 2927 cleanup_s5r (s5r);
2901 GNUNET_free_non_null(domain); 2928 GNUNET_free_non_null (domain);
2902 return; 2929 return;
2903 } 2930 }
2904 s5r->hd = hd; 2931 s5r->hd = hd;
2905 schedule_httpd(hd); 2932 schedule_httpd (hd);
2906 s5r->timeout_task = GNUNET_SCHEDULER_add_delayed(HTTP_HANDSHAKE_TIMEOUT, 2933 s5r->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_HANDSHAKE_TIMEOUT,
2907 &timeout_s5r_handshake, 2934 &timeout_s5r_handshake,
2908 s5r); 2935 s5r);
2909 GNUNET_free_non_null(domain); 2936 GNUNET_free_non_null (domain);
2910} 2937}
2911 2938
2912 2939
@@ -2919,61 +2946,61 @@ setup_data_transfer(struct Socks5Request *s5r)
2919 * @param cls the closure with the `struct Socks5Request` 2946 * @param cls the closure with the `struct Socks5Request`
2920 */ 2947 */
2921static void 2948static void
2922do_write(void *cls) 2949do_write (void *cls)
2923{ 2950{
2924 struct Socks5Request *s5r = cls; 2951 struct Socks5Request *s5r = cls;
2925 ssize_t len; 2952 ssize_t len;
2926 2953
2927 s5r->wtask = NULL; 2954 s5r->wtask = NULL;
2928 len = GNUNET_NETWORK_socket_send(s5r->sock, 2955 len = GNUNET_NETWORK_socket_send (s5r->sock,
2929 s5r->wbuf, 2956 s5r->wbuf,
2930 s5r->wbuf_len); 2957 s5r->wbuf_len);
2931 if (len <= 0) 2958 if (len <= 0)
2932 { 2959 {
2933 /* write error: connection closed, shutdown, etc.; just clean up */ 2960 /* write error: connection closed, shutdown, etc.; just clean up */
2934 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2961 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2935 "Write Error\n"); 2962 "Write Error\n");
2936 cleanup_s5r(s5r); 2963 cleanup_s5r (s5r);
2937 return; 2964 return;
2938 } 2965 }
2939 memmove(s5r->wbuf, 2966 memmove (s5r->wbuf,
2940 &s5r->wbuf[len], 2967 &s5r->wbuf[len],
2941 s5r->wbuf_len - len); 2968 s5r->wbuf_len - len);
2942 s5r->wbuf_len -= len; 2969 s5r->wbuf_len -= len;
2943 if (s5r->wbuf_len > 0) 2970 if (s5r->wbuf_len > 0)
2944 { 2971 {
2945 /* not done writing */ 2972 /* not done writing */
2946 s5r->wtask = 2973 s5r->wtask =
2947 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 2974 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2948 s5r->sock, 2975 s5r->sock,
2949 &do_write, s5r); 2976 &do_write, s5r);
2950 return; 2977 return;
2951 } 2978 }
2952 2979
2953 /* we're done writing, continue with state machine! */ 2980 /* we're done writing, continue with state machine! */
2954 2981
2955 switch (s5r->state) 2982 switch (s5r->state)
2956 { 2983 {
2957 case SOCKS5_INIT: 2984 case SOCKS5_INIT:
2958 GNUNET_assert(0); 2985 GNUNET_assert (0);
2959 break; 2986 break;
2960 2987
2961 case SOCKS5_REQUEST: 2988 case SOCKS5_REQUEST:
2962 GNUNET_assert(NULL != s5r->rtask); 2989 GNUNET_assert (NULL != s5r->rtask);
2963 break; 2990 break;
2964 2991
2965 case SOCKS5_DATA_TRANSFER: 2992 case SOCKS5_DATA_TRANSFER:
2966 setup_data_transfer(s5r); 2993 setup_data_transfer (s5r);
2967 return; 2994 return;
2968 2995
2969 case SOCKS5_WRITE_THEN_CLEANUP: 2996 case SOCKS5_WRITE_THEN_CLEANUP:
2970 cleanup_s5r(s5r); 2997 cleanup_s5r (s5r);
2971 return; 2998 return;
2972 2999
2973 default: 3000 default:
2974 GNUNET_break(0); 3001 GNUNET_break (0);
2975 break; 3002 break;
2976 } 3003 }
2977} 3004}
2978 3005
2979 3006
@@ -2984,21 +3011,21 @@ do_write(void *cls)
2984 * @param sc status code to return 3011 * @param sc status code to return
2985 */ 3012 */
2986static void 3013static void
2987signal_socks_failure(struct Socks5Request *s5r, 3014signal_socks_failure (struct Socks5Request *s5r,
2988 enum Socks5StatusCode sc) 3015 enum Socks5StatusCode sc)
2989{ 3016{
2990 struct Socks5ServerResponseMessage *s_resp; 3017 struct Socks5ServerResponseMessage *s_resp;
2991 3018
2992 s_resp = (struct Socks5ServerResponseMessage *)&s5r->wbuf[s5r->wbuf_len]; 3019 s_resp = (struct Socks5ServerResponseMessage *) &s5r->wbuf[s5r->wbuf_len];
2993 memset(s_resp, 0, sizeof(struct Socks5ServerResponseMessage)); 3020 memset (s_resp, 0, sizeof(struct Socks5ServerResponseMessage));
2994 s_resp->version = SOCKS_VERSION_5; 3021 s_resp->version = SOCKS_VERSION_5;
2995 s_resp->reply = sc; 3022 s_resp->reply = sc;
2996 s5r->state = SOCKS5_WRITE_THEN_CLEANUP; 3023 s5r->state = SOCKS5_WRITE_THEN_CLEANUP;
2997 if (NULL != s5r->wtask) 3024 if (NULL != s5r->wtask)
2998 s5r->wtask = 3025 s5r->wtask =
2999 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 3026 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3000 s5r->sock, 3027 s5r->sock,
3001 &do_write, s5r); 3028 &do_write, s5r);
3002} 3029}
3003 3030
3004 3031
@@ -3008,26 +3035,26 @@ signal_socks_failure(struct Socks5Request *s5r,
3008 * @param s5r request to return success status message for 3035 * @param s5r request to return success status message for
3009 */ 3036 */
3010static void 3037static void
3011signal_socks_success(struct Socks5Request *s5r) 3038signal_socks_success (struct Socks5Request *s5r)
3012{ 3039{
3013 struct Socks5ServerResponseMessage *s_resp; 3040 struct Socks5ServerResponseMessage *s_resp;
3014 3041
3015 s_resp = (struct Socks5ServerResponseMessage *)&s5r->wbuf[s5r->wbuf_len]; 3042 s_resp = (struct Socks5ServerResponseMessage *) &s5r->wbuf[s5r->wbuf_len];
3016 s_resp->version = SOCKS_VERSION_5; 3043 s_resp->version = SOCKS_VERSION_5;
3017 s_resp->reply = SOCKS5_STATUS_REQUEST_GRANTED; 3044 s_resp->reply = SOCKS5_STATUS_REQUEST_GRANTED;
3018 s_resp->reserved = 0; 3045 s_resp->reserved = 0;
3019 s_resp->addr_type = SOCKS5_AT_IPV4; 3046 s_resp->addr_type = SOCKS5_AT_IPV4;
3020 /* zero out IPv4 address and port */ 3047 /* zero out IPv4 address and port */
3021 memset(&s_resp[1], 3048 memset (&s_resp[1],
3022 0, 3049 0,
3023 sizeof(struct in_addr) + sizeof(uint16_t)); 3050 sizeof(struct in_addr) + sizeof(uint16_t));
3024 s5r->wbuf_len += sizeof(struct Socks5ServerResponseMessage) + 3051 s5r->wbuf_len += sizeof(struct Socks5ServerResponseMessage)
3025 sizeof(struct in_addr) + sizeof(uint16_t); 3052 + sizeof(struct in_addr) + sizeof(uint16_t);
3026 if (NULL == s5r->wtask) 3053 if (NULL == s5r->wtask)
3027 s5r->wtask = 3054 s5r->wtask =
3028 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 3055 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3029 s5r->sock, 3056 s5r->sock,
3030 &do_write, s5r); 3057 &do_write, s5r);
3031} 3058}
3032 3059
3033 3060
@@ -3040,10 +3067,10 @@ signal_socks_success(struct Socks5Request *s5r)
3040 * @param rd record data 3067 * @param rd record data
3041 */ 3068 */
3042static void 3069static void
3043handle_gns_result(void *cls, 3070handle_gns_result (void *cls,
3044 int tld, 3071 int tld,
3045 uint32_t rd_count, 3072 uint32_t rd_count,
3046 const struct GNUNET_GNSRECORD_Data *rd) 3073 const struct GNUNET_GNSRECORD_Data *rd)
3047{ 3074{
3048 struct Socks5Request *s5r = cls; 3075 struct Socks5Request *s5r = cls;
3049 const struct GNUNET_GNSRECORD_Data *r; 3076 const struct GNUNET_GNSRECORD_Data *r;
@@ -3053,122 +3080,122 @@ handle_gns_result(void *cls,
3053 s5r->is_gns = tld; 3080 s5r->is_gns = tld;
3054 got_ip = GNUNET_NO; 3081 got_ip = GNUNET_NO;
3055 for (uint32_t i = 0; i < rd_count; i++) 3082 for (uint32_t i = 0; i < rd_count; i++)
3083 {
3084 r = &rd[i];
3085 switch (r->record_type)
3056 { 3086 {
3057 r = &rd[i]; 3087 case GNUNET_DNSPARSER_TYPE_A:
3058 switch (r->record_type) 3088 {
3059 { 3089 struct sockaddr_in *in;
3060 case GNUNET_DNSPARSER_TYPE_A: 3090
3091 if (sizeof(struct in_addr) != r->data_size)
3061 { 3092 {
3062 struct sockaddr_in *in; 3093 GNUNET_break_op (0);
3063 3094 break;
3064 if (sizeof(struct in_addr) != r->data_size) 3095 }
3065 { 3096 if (GNUNET_YES == got_ip)
3066 GNUNET_break_op(0); 3097 break;
3067 break; 3098 if (GNUNET_OK !=
3068 } 3099 GNUNET_NETWORK_test_pf (PF_INET))
3069 if (GNUNET_YES == got_ip) 3100 break;
3070 break; 3101 got_ip = GNUNET_YES;
3071 if (GNUNET_OK != 3102 in = (struct sockaddr_in *) &s5r->destination_address;
3072 GNUNET_NETWORK_test_pf(PF_INET)) 3103 in->sin_family = AF_INET;
3073 break; 3104 GNUNET_memcpy (&in->sin_addr,
3074 got_ip = GNUNET_YES; 3105 r->data,
3075 in = (struct sockaddr_in *)&s5r->destination_address; 3106 r->data_size);
3076 in->sin_family = AF_INET; 3107 in->sin_port = htons (s5r->port);
3077 GNUNET_memcpy(&in->sin_addr,
3078 r->data,
3079 r->data_size);
3080 in->sin_port = htons(s5r->port);
3081#if HAVE_SOCKADDR_IN_SIN_LEN 3108#if HAVE_SOCKADDR_IN_SIN_LEN
3082 in->sin_len = sizeof(*in); 3109 in->sin_len = sizeof(*in);
3083#endif 3110#endif
3084 } 3111 }
3085 break; 3112 break;
3113
3114 case GNUNET_DNSPARSER_TYPE_AAAA:
3115 {
3116 struct sockaddr_in6 *in;
3086 3117
3087 case GNUNET_DNSPARSER_TYPE_AAAA: 3118 if (sizeof(struct in6_addr) != r->data_size)
3088 { 3119 {
3089 struct sockaddr_in6 *in; 3120 GNUNET_break_op (0);
3090 3121 break;
3091 if (sizeof(struct in6_addr) != r->data_size) 3122 }
3092 { 3123 if (GNUNET_YES == got_ip)
3093 GNUNET_break_op(0); 3124 break;
3094 break; 3125 if (GNUNET_YES == disable_v6)
3095 } 3126 break;
3096 if (GNUNET_YES == got_ip) 3127 if (GNUNET_OK !=
3097 break; 3128 GNUNET_NETWORK_test_pf (PF_INET6))
3098 if (GNUNET_YES == disable_v6) 3129 break;
3099 break; 3130 /* FIXME: allow user to disable IPv6 per configuration option... */
3100 if (GNUNET_OK != 3131 got_ip = GNUNET_YES;
3101 GNUNET_NETWORK_test_pf(PF_INET6)) 3132 in = (struct sockaddr_in6 *) &s5r->destination_address;
3102 break; 3133 in->sin6_family = AF_INET6;
3103 /* FIXME: allow user to disable IPv6 per configuration option... */ 3134 GNUNET_memcpy (&in->sin6_addr,
3104 got_ip = GNUNET_YES; 3135 r->data,
3105 in = (struct sockaddr_in6 *)&s5r->destination_address; 3136 r->data_size);
3106 in->sin6_family = AF_INET6; 3137 in->sin6_port = htons (s5r->port);
3107 GNUNET_memcpy(&in->sin6_addr,
3108 r->data,
3109 r->data_size);
3110 in->sin6_port = htons(s5r->port);
3111#if HAVE_SOCKADDR_IN_SIN_LEN 3138#if HAVE_SOCKADDR_IN_SIN_LEN
3112 in->sin6_len = sizeof(*in); 3139 in->sin6_len = sizeof(*in);
3113#endif 3140#endif
3114 } 3141 }
3115 break; 3142 break;
3116 3143
3117 case GNUNET_GNSRECORD_TYPE_VPN: 3144 case GNUNET_GNSRECORD_TYPE_VPN:
3118 GNUNET_break(0); /* should have been translated within GNS */ 3145 GNUNET_break (0); /* should have been translated within GNS */
3119 break; 3146 break;
3120 3147
3121 case GNUNET_GNSRECORD_TYPE_LEHO: 3148 case GNUNET_GNSRECORD_TYPE_LEHO:
3122 GNUNET_free_non_null(s5r->leho); 3149 GNUNET_free_non_null (s5r->leho);
3123 s5r->leho = GNUNET_strndup(r->data, 3150 s5r->leho = GNUNET_strndup (r->data,
3124 r->data_size); 3151 r->data_size);
3125 break; 3152 break;
3153
3154 case GNUNET_GNSRECORD_TYPE_BOX:
3155 {
3156 const struct GNUNET_GNSRECORD_BoxRecord *box;
3126 3157
3127 case GNUNET_GNSRECORD_TYPE_BOX: 3158 if (r->data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
3128 { 3159 {
3129 const struct GNUNET_GNSRECORD_BoxRecord *box; 3160 GNUNET_break_op (0);
3130
3131 if (r->data_size < sizeof(struct GNUNET_GNSRECORD_BoxRecord))
3132 {
3133 GNUNET_break_op(0);
3134 break;
3135 }
3136 box = r->data;
3137 if ((ntohl(box->record_type) != GNUNET_DNSPARSER_TYPE_TLSA) ||
3138 (ntohs(box->protocol) != IPPROTO_TCP) ||
3139 (ntohs(box->service) != s5r->port))
3140 break; /* BOX record does not apply */
3141 if (s5r->num_danes >= MAX_DANES)
3142 {
3143 GNUNET_break(0); /* MAX_DANES too small */
3144 break;
3145 }
3146 s5r->is_tls = GNUNET_YES; /* This should be TLS */
3147 s5r->dane_data_len[s5r->num_danes]
3148 = r->data_size - sizeof(struct GNUNET_GNSRECORD_BoxRecord);
3149 s5r->dane_data[s5r->num_danes]
3150 = GNUNET_memdup(&box[1],
3151 s5r->dane_data_len[s5r->num_danes]);
3152 s5r->num_danes++;
3153 break; 3161 break;
3154 } 3162 }
3155 3163 box = r->data;
3156 default: 3164 if ((ntohl (box->record_type) != GNUNET_DNSPARSER_TYPE_TLSA) ||
3157 /* don't care */ 3165 (ntohs (box->protocol) != IPPROTO_TCP) ||
3166 (ntohs (box->service) != s5r->port))
3167 break; /* BOX record does not apply */
3168 if (s5r->num_danes >= MAX_DANES)
3169 {
3170 GNUNET_break (0); /* MAX_DANES too small */
3158 break; 3171 break;
3159 } 3172 }
3173 s5r->is_tls = GNUNET_YES; /* This should be TLS */
3174 s5r->dane_data_len[s5r->num_danes]
3175 = r->data_size - sizeof(struct GNUNET_GNSRECORD_BoxRecord);
3176 s5r->dane_data[s5r->num_danes]
3177 = GNUNET_memdup (&box[1],
3178 s5r->dane_data_len[s5r->num_danes]);
3179 s5r->num_danes++;
3180 break;
3181 }
3182
3183 default:
3184 /* don't care */
3185 break;
3160 } 3186 }
3187 }
3161 if ((GNUNET_YES != got_ip) && 3188 if ((GNUNET_YES != got_ip) &&
3162 (GNUNET_YES == tld)) 3189 (GNUNET_YES == tld))
3163 { 3190 {
3164 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3191 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3165 "Name resolution failed to yield useful IP address.\n"); 3192 "Name resolution failed to yield useful IP address.\n");
3166 signal_socks_failure(s5r, 3193 signal_socks_failure (s5r,
3167 SOCKS5_STATUS_GENERAL_FAILURE); 3194 SOCKS5_STATUS_GENERAL_FAILURE);
3168 return; 3195 return;
3169 } 3196 }
3170 s5r->state = SOCKS5_DATA_TRANSFER; 3197 s5r->state = SOCKS5_DATA_TRANSFER;
3171 signal_socks_success(s5r); 3198 signal_socks_success (s5r);
3172} 3199}
3173 3200
3174 3201
@@ -3179,13 +3206,13 @@ handle_gns_result(void *cls,
3179 * @param len number of bytes in read buffer to advance 3206 * @param len number of bytes in read buffer to advance
3180 */ 3207 */
3181static void 3208static void
3182clear_from_s5r_rbuf(struct Socks5Request *s5r, 3209clear_from_s5r_rbuf (struct Socks5Request *s5r,
3183 size_t len) 3210 size_t len)
3184{ 3211{
3185 GNUNET_assert(len <= s5r->rbuf_len); 3212 GNUNET_assert (len <= s5r->rbuf_len);
3186 memmove(s5r->rbuf, 3213 memmove (s5r->rbuf,
3187 &s5r->rbuf[len], 3214 &s5r->rbuf[len],
3188 s5r->rbuf_len - len); 3215 s5r->rbuf_len - len);
3189 s5r->rbuf_len -= len; 3216 s5r->rbuf_len -= len;
3190} 3217}
3191 3218
@@ -3196,7 +3223,7 @@ clear_from_s5r_rbuf(struct Socks5Request *s5r,
3196 * @param cls the closure with the `struct Socks5Request` 3223 * @param cls the closure with the `struct Socks5Request`
3197 */ 3224 */
3198static void 3225static void
3199do_s5r_read(void *cls) 3226do_s5r_read (void *cls)
3200{ 3227{
3201 struct Socks5Request *s5r = cls; 3228 struct Socks5Request *s5r = cls;
3202 const struct Socks5ClientHelloMessage *c_hello; 3229 const struct Socks5ClientHelloMessage *c_hello;
@@ -3207,196 +3234,198 @@ do_s5r_read(void *cls)
3207 const struct GNUNET_SCHEDULER_TaskContext *tc; 3234 const struct GNUNET_SCHEDULER_TaskContext *tc;
3208 3235
3209 s5r->rtask = NULL; 3236 s5r->rtask = NULL;
3210 tc = GNUNET_SCHEDULER_get_task_context(); 3237 tc = GNUNET_SCHEDULER_get_task_context ();
3211 if ((NULL != tc->read_ready) && 3238 if ((NULL != tc->read_ready) &&
3212 (GNUNET_NETWORK_fdset_isset(tc->read_ready, 3239 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
3213 s5r->sock))) 3240 s5r->sock)))
3214 { 3241 {
3215 rlen = GNUNET_NETWORK_socket_recv(s5r->sock, 3242 rlen = GNUNET_NETWORK_socket_recv (s5r->sock,
3216 &s5r->rbuf[s5r->rbuf_len], 3243 &s5r->rbuf[s5r->rbuf_len],
3217 sizeof(s5r->rbuf) - s5r->rbuf_len); 3244 sizeof(s5r->rbuf) - s5r->rbuf_len);
3218 if (rlen <= 0) 3245 if (rlen <= 0)
3219 { 3246 {
3220 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3221 "socks5 client disconnected.\n"); 3248 "socks5 client disconnected.\n");
3222 cleanup_s5r(s5r); 3249 cleanup_s5r (s5r);
3223 return; 3250 return;
3224 }
3225 s5r->rbuf_len += rlen;
3226 } 3251 }
3227 s5r->rtask = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 3252 s5r->rbuf_len += rlen;
3228 s5r->sock, 3253 }
3229 &do_s5r_read, s5r); 3254 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3230 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3255 s5r->sock,
3231 "Processing %zu bytes of socks data in state %d\n", 3256 &do_s5r_read, s5r);
3232 s5r->rbuf_len, 3257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3233 s5r->state); 3258 "Processing %zu bytes of socks data in state %d\n",
3259 s5r->rbuf_len,
3260 s5r->state);
3234 switch (s5r->state) 3261 switch (s5r->state)
3235 { 3262 {
3236 case SOCKS5_INIT: 3263 case SOCKS5_INIT:
3237 c_hello = (const struct Socks5ClientHelloMessage*)&s5r->rbuf; 3264 c_hello = (const struct Socks5ClientHelloMessage*) &s5r->rbuf;
3238 if ((s5r->rbuf_len < sizeof(struct Socks5ClientHelloMessage)) || 3265 if ((s5r->rbuf_len < sizeof(struct Socks5ClientHelloMessage)) ||
3239 (s5r->rbuf_len < sizeof(struct Socks5ClientHelloMessage) + c_hello->num_auth_methods)) 3266 (s5r->rbuf_len < sizeof(struct Socks5ClientHelloMessage)
3240 return; /* need more data */ 3267 + c_hello->num_auth_methods))
3241 if (SOCKS_VERSION_5 != c_hello->version) 3268 return; /* need more data */
3242 { 3269 if (SOCKS_VERSION_5 != c_hello->version)
3243 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3270 {
3244 _("Unsupported socks version %d\n"), 3271 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3245 (int)c_hello->version); 3272 _ ("Unsupported socks version %d\n"),
3246 cleanup_s5r(s5r); 3273 (int) c_hello->version);
3247 return; 3274 cleanup_s5r (s5r);
3248 }
3249 clear_from_s5r_rbuf(s5r,
3250 sizeof(struct Socks5ClientHelloMessage) + c_hello->num_auth_methods);
3251 GNUNET_assert(0 == s5r->wbuf_len);
3252 s_hello = (struct Socks5ServerHelloMessage *)&s5r->wbuf;
3253 s5r->wbuf_len = sizeof(struct Socks5ServerHelloMessage);
3254 s_hello->version = SOCKS_VERSION_5;
3255 s_hello->auth_method = SOCKS_AUTH_NONE;
3256 GNUNET_assert(NULL == s5r->wtask);
3257 s5r->wtask = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL,
3258 s5r->sock,
3259 &do_write, s5r);
3260 s5r->state = SOCKS5_REQUEST;
3261 return; 3275 return;
3276 }
3277 clear_from_s5r_rbuf (s5r,
3278 sizeof(struct Socks5ClientHelloMessage)
3279 + c_hello->num_auth_methods);
3280 GNUNET_assert (0 == s5r->wbuf_len);
3281 s_hello = (struct Socks5ServerHelloMessage *) &s5r->wbuf;
3282 s5r->wbuf_len = sizeof(struct Socks5ServerHelloMessage);
3283 s_hello->version = SOCKS_VERSION_5;
3284 s_hello->auth_method = SOCKS_AUTH_NONE;
3285 GNUNET_assert (NULL == s5r->wtask);
3286 s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3287 s5r->sock,
3288 &do_write, s5r);
3289 s5r->state = SOCKS5_REQUEST;
3290 return;
3262 3291
3263 case SOCKS5_REQUEST: 3292 case SOCKS5_REQUEST:
3264 c_req = (const struct Socks5ClientRequestMessage *)&s5r->rbuf; 3293 c_req = (const struct Socks5ClientRequestMessage *) &s5r->rbuf;
3265 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage)) 3294 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage))
3266 return; 3295 return;
3267 switch (c_req->command) 3296 switch (c_req->command)
3268 { 3297 {
3269 case SOCKS5_CMD_TCP_STREAM: 3298 case SOCKS5_CMD_TCP_STREAM:
3270 /* handled below */ 3299 /* handled below */
3271 break; 3300 break;
3272 3301
3273 default: 3302 default:
3274 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3303 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3275 _("Unsupported socks command %d\n"), 3304 _ ("Unsupported socks command %d\n"),
3276 (int)c_req->command); 3305 (int) c_req->command);
3277 signal_socks_failure(s5r, 3306 signal_socks_failure (s5r,
3278 SOCKS5_STATUS_COMMAND_NOT_SUPPORTED); 3307 SOCKS5_STATUS_COMMAND_NOT_SUPPORTED);
3279 return; 3308 return;
3280 } 3309 }
3281 switch (c_req->addr_type) 3310 switch (c_req->addr_type)
3282 { 3311 {
3283 case SOCKS5_AT_IPV4: 3312 case SOCKS5_AT_IPV4:
3284 { 3313 {
3285 const struct in_addr *v4 = (const struct in_addr *)&c_req[1]; 3314 const struct in_addr *v4 = (const struct in_addr *) &c_req[1];
3286 const uint16_t *port = (const uint16_t *)&v4[1]; 3315 const uint16_t *port = (const uint16_t *) &v4[1];
3287 struct sockaddr_in *in; 3316 struct sockaddr_in *in;
3288 3317
3289 s5r->port = ntohs(*port); 3318 s5r->port = ntohs (*port);
3290 alen = sizeof(struct in_addr); 3319 alen = sizeof(struct in_addr);
3291 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage) + 3320 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage)
3292 alen + sizeof(uint16_t)) 3321 + alen + sizeof(uint16_t))
3293 return; /* need more data */ 3322 return; /* need more data */
3294 in = (struct sockaddr_in *)&s5r->destination_address; 3323 in = (struct sockaddr_in *) &s5r->destination_address;
3295 in->sin_family = AF_INET; 3324 in->sin_family = AF_INET;
3296 in->sin_addr = *v4; 3325 in->sin_addr = *v4;
3297 in->sin_port = *port; 3326 in->sin_port = *port;
3298#if HAVE_SOCKADDR_IN_SIN_LEN 3327#if HAVE_SOCKADDR_IN_SIN_LEN
3299 in->sin_len = sizeof(*in); 3328 in->sin_len = sizeof(*in);
3300#endif 3329#endif
3301 s5r->state = SOCKS5_DATA_TRANSFER; 3330 s5r->state = SOCKS5_DATA_TRANSFER;
3302 } 3331 }
3303 break; 3332 break;
3304 3333
3305 case SOCKS5_AT_IPV6: 3334 case SOCKS5_AT_IPV6:
3306 { 3335 {
3307 const struct in6_addr *v6 = (const struct in6_addr *)&c_req[1]; 3336 const struct in6_addr *v6 = (const struct in6_addr *) &c_req[1];
3308 const uint16_t *port = (const uint16_t *)&v6[1]; 3337 const uint16_t *port = (const uint16_t *) &v6[1];
3309 struct sockaddr_in6 *in; 3338 struct sockaddr_in6 *in;
3310 3339
3311 s5r->port = ntohs(*port); 3340 s5r->port = ntohs (*port);
3312 alen = sizeof(struct in6_addr); 3341 alen = sizeof(struct in6_addr);
3313 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage) + 3342 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage)
3314 alen + sizeof(uint16_t)) 3343 + alen + sizeof(uint16_t))
3315 return; /* need more data */ 3344 return; /* need more data */
3316 in = (struct sockaddr_in6 *)&s5r->destination_address; 3345 in = (struct sockaddr_in6 *) &s5r->destination_address;
3317 in->sin6_family = AF_INET6; 3346 in->sin6_family = AF_INET6;
3318 in->sin6_addr = *v6; 3347 in->sin6_addr = *v6;
3319 in->sin6_port = *port; 3348 in->sin6_port = *port;
3320#if HAVE_SOCKADDR_IN_SIN_LEN 3349#if HAVE_SOCKADDR_IN_SIN_LEN
3321 in->sin6_len = sizeof(*in); 3350 in->sin6_len = sizeof(*in);
3322#endif 3351#endif
3323 s5r->state = SOCKS5_DATA_TRANSFER; 3352 s5r->state = SOCKS5_DATA_TRANSFER;
3324 } 3353 }
3325 break; 3354 break;
3326 3355
3327 case SOCKS5_AT_DOMAINNAME: 3356 case SOCKS5_AT_DOMAINNAME:
3328 { 3357 {
3329 const uint8_t *dom_len; 3358 const uint8_t *dom_len;
3330 const char *dom_name; 3359 const char *dom_name;
3331 const uint16_t *port; 3360 const uint16_t *port;
3332 3361
3333 dom_len = (const uint8_t *)&c_req[1]; 3362 dom_len = (const uint8_t *) &c_req[1];
3334 alen = *dom_len + 1; 3363 alen = *dom_len + 1;
3335 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage) + 3364 if (s5r->rbuf_len < sizeof(struct Socks5ClientRequestMessage)
3336 alen + sizeof(uint16_t)) 3365 + alen + sizeof(uint16_t))
3337 return; /* need more data */ 3366 return; /* need more data */
3338 dom_name = (const char *)&dom_len[1]; 3367 dom_name = (const char *) &dom_len[1];
3339 port = (const uint16_t*)&dom_name[*dom_len]; 3368 port = (const uint16_t*) &dom_name[*dom_len];
3340 s5r->domain = GNUNET_strndup(dom_name, 3369 s5r->domain = GNUNET_strndup (dom_name,
3341 *dom_len); 3370 *dom_len);
3342 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3343 "Requested connection is to %s:%d\n", 3372 "Requested connection is to %s:%d\n",
3344 //(HTTPS_PORT == s5r->port) ? "s" : "", 3373 // (HTTPS_PORT == s5r->port) ? "s" : "",
3345 s5r->domain, 3374 s5r->domain,
3346 ntohs(*port)); 3375 ntohs (*port));
3347 s5r->state = SOCKS5_RESOLVING; 3376 s5r->state = SOCKS5_RESOLVING;
3348 s5r->port = ntohs(*port); 3377 s5r->port = ntohs (*port);
3349 s5r->is_tls = (HTTPS_PORT == s5r->port) ? GNUNET_YES : GNUNET_NO; 3378 s5r->is_tls = (HTTPS_PORT == s5r->port) ? GNUNET_YES : GNUNET_NO;
3350 s5r->gns_lookup = GNUNET_GNS_lookup_with_tld(gns_handle, 3379 s5r->gns_lookup = GNUNET_GNS_lookup_with_tld (gns_handle,
3351 s5r->domain, 3380 s5r->domain,
3352 GNUNET_DNSPARSER_TYPE_A, 3381 GNUNET_DNSPARSER_TYPE_A,
3353 GNUNET_NO /* only cached */, 3382 GNUNET_NO /* only cached */,
3354 &handle_gns_result, 3383 &handle_gns_result,
3355 s5r); 3384 s5r);
3356 break; 3385 break;
3357 } 3386 }
3358 3387
3359 default: 3388 default:
3360 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3389 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3361 _("Unsupported socks address type %d\n"), 3390 _ ("Unsupported socks address type %d\n"),
3362 (int)c_req->addr_type); 3391 (int) c_req->addr_type);
3363 signal_socks_failure(s5r, 3392 signal_socks_failure (s5r,
3364 SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED); 3393 SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED);
3365 return;
3366 }
3367 clear_from_s5r_rbuf(s5r,
3368 sizeof(struct Socks5ClientRequestMessage) +
3369 alen + sizeof(uint16_t));
3370 if (0 != s5r->rbuf_len)
3371 {
3372 /* read more bytes than healthy, why did the client send more!? */
3373 GNUNET_break_op(0);
3374 signal_socks_failure(s5r,
3375 SOCKS5_STATUS_GENERAL_FAILURE);
3376 return;
3377 }
3378 if (SOCKS5_DATA_TRANSFER == s5r->state)
3379 {
3380 /* if we are not waiting for GNS resolution, signal success */
3381 signal_socks_success(s5r);
3382 }
3383 /* We are done reading right now */
3384 GNUNET_SCHEDULER_cancel(s5r->rtask);
3385 s5r->rtask = NULL;
3386 return; 3394 return;
3387 3395 }
3388 case SOCKS5_RESOLVING: 3396 clear_from_s5r_rbuf (s5r,
3389 GNUNET_assert(0); 3397 sizeof(struct Socks5ClientRequestMessage)
3398 + alen + sizeof(uint16_t));
3399 if (0 != s5r->rbuf_len)
3400 {
3401 /* read more bytes than healthy, why did the client send more!? */
3402 GNUNET_break_op (0);
3403 signal_socks_failure (s5r,
3404 SOCKS5_STATUS_GENERAL_FAILURE);
3390 return; 3405 return;
3406 }
3407 if (SOCKS5_DATA_TRANSFER == s5r->state)
3408 {
3409 /* if we are not waiting for GNS resolution, signal success */
3410 signal_socks_success (s5r);
3411 }
3412 /* We are done reading right now */
3413 GNUNET_SCHEDULER_cancel (s5r->rtask);
3414 s5r->rtask = NULL;
3415 return;
3391 3416
3392 case SOCKS5_DATA_TRANSFER: 3417 case SOCKS5_RESOLVING:
3393 GNUNET_assert(0); 3418 GNUNET_assert (0);
3394 return; 3419 return;
3395 3420
3396 default: 3421 case SOCKS5_DATA_TRANSFER:
3397 GNUNET_assert(0); 3422 GNUNET_assert (0);
3398 return; 3423 return;
3399 } 3424
3425 default:
3426 GNUNET_assert (0);
3427 return;
3428 }
3400} 3429}
3401 3430
3402 3431
@@ -3407,46 +3436,46 @@ do_s5r_read(void *cls)
3407 * @param tc the scheduler context 3436 * @param tc the scheduler context
3408 */ 3437 */
3409static void 3438static void
3410do_accept(void *cls) 3439do_accept (void *cls)
3411{ 3440{
3412 struct GNUNET_NETWORK_Handle *lsock = cls; 3441 struct GNUNET_NETWORK_Handle *lsock = cls;
3413 struct GNUNET_NETWORK_Handle *s; 3442 struct GNUNET_NETWORK_Handle *s;
3414 struct Socks5Request *s5r; 3443 struct Socks5Request *s5r;
3415 3444
3416 GNUNET_assert(NULL != lsock); 3445 GNUNET_assert (NULL != lsock);
3417 if (lsock == lsock4) 3446 if (lsock == lsock4)
3418 ltask4 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 3447 ltask4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3419 lsock, 3448 lsock,
3420 &do_accept, 3449 &do_accept,
3421 lsock); 3450 lsock);
3422 else if (lsock == lsock6) 3451 else if (lsock == lsock6)
3423 ltask6 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 3452 ltask6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3424 lsock, 3453 lsock,
3425 &do_accept, 3454 &do_accept,
3426 lsock); 3455 lsock);
3427 else 3456 else
3428 GNUNET_assert(0); 3457 GNUNET_assert (0);
3429 s = GNUNET_NETWORK_socket_accept(lsock, 3458 s = GNUNET_NETWORK_socket_accept (lsock,
3430 NULL, 3459 NULL,
3431 NULL); 3460 NULL);
3432 if (NULL == s) 3461 if (NULL == s)
3433 { 3462 {
3434 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, 3463 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3435 "accept"); 3464 "accept");
3436 return; 3465 return;
3437 } 3466 }
3438 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3439 "Got an inbound connection, waiting for data\n"); 3468 "Got an inbound connection, waiting for data\n");
3440 s5r = GNUNET_new(struct Socks5Request); 3469 s5r = GNUNET_new (struct Socks5Request);
3441 GNUNET_CONTAINER_DLL_insert(s5r_head, 3470 GNUNET_CONTAINER_DLL_insert (s5r_head,
3442 s5r_tail, 3471 s5r_tail,
3443 s5r); 3472 s5r);
3444 s5r->sock = s; 3473 s5r->sock = s;
3445 s5r->state = SOCKS5_INIT; 3474 s5r->state = SOCKS5_INIT;
3446 s5r->rtask = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 3475 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3447 s5r->sock, 3476 s5r->sock,
3448 &do_s5r_read, 3477 &do_s5r_read,
3449 s5r); 3478 s5r);
3450} 3479}
3451 3480
3452 3481
@@ -3459,63 +3488,63 @@ do_accept(void *cls)
3459 * @param cls closure 3488 * @param cls closure
3460 */ 3489 */
3461static void 3490static void
3462do_shutdown(void *cls) 3491do_shutdown (void *cls)
3463{ 3492{
3464 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 3493 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3465 "Shutting down...\n"); 3494 "Shutting down...\n");
3466 /* MHD requires resuming before destroying the daemons */ 3495 /* MHD requires resuming before destroying the daemons */
3467 for (struct Socks5Request *s5r = s5r_head; 3496 for (struct Socks5Request *s5r = s5r_head;
3468 NULL != s5r; 3497 NULL != s5r;
3469 s5r = s5r->next) 3498 s5r = s5r->next)
3499 {
3500 if (s5r->suspended)
3470 { 3501 {
3471 if (s5r->suspended) 3502 s5r->suspended = GNUNET_NO;
3472 { 3503 MHD_resume_connection (s5r->con);
3473 s5r->suspended = GNUNET_NO;
3474 MHD_resume_connection(s5r->con);
3475 }
3476 } 3504 }
3505 }
3477 while (NULL != mhd_httpd_head) 3506 while (NULL != mhd_httpd_head)
3478 kill_httpd(mhd_httpd_head); 3507 kill_httpd (mhd_httpd_head);
3479 while (NULL != s5r_head) 3508 while (NULL != s5r_head)
3480 cleanup_s5r(s5r_head); 3509 cleanup_s5r (s5r_head);
3481 if (NULL != lsock4) 3510 if (NULL != lsock4)
3482 { 3511 {
3483 GNUNET_NETWORK_socket_close(lsock4); 3512 GNUNET_NETWORK_socket_close (lsock4);
3484 lsock4 = NULL; 3513 lsock4 = NULL;
3485 } 3514 }
3486 if (NULL != lsock6) 3515 if (NULL != lsock6)
3487 { 3516 {
3488 GNUNET_NETWORK_socket_close(lsock6); 3517 GNUNET_NETWORK_socket_close (lsock6);
3489 lsock6 = NULL; 3518 lsock6 = NULL;
3490 } 3519 }
3491 if (NULL != curl_multi) 3520 if (NULL != curl_multi)
3492 { 3521 {
3493 curl_multi_cleanup(curl_multi); 3522 curl_multi_cleanup (curl_multi);
3494 curl_multi = NULL; 3523 curl_multi = NULL;
3495 } 3524 }
3496 if (NULL != gns_handle) 3525 if (NULL != gns_handle)
3497 { 3526 {
3498 GNUNET_GNS_disconnect(gns_handle); 3527 GNUNET_GNS_disconnect (gns_handle);
3499 gns_handle = NULL; 3528 gns_handle = NULL;
3500 } 3529 }
3501 if (NULL != curl_download_task) 3530 if (NULL != curl_download_task)
3502 { 3531 {
3503 GNUNET_SCHEDULER_cancel(curl_download_task); 3532 GNUNET_SCHEDULER_cancel (curl_download_task);
3504 curl_download_task = NULL; 3533 curl_download_task = NULL;
3505 } 3534 }
3506 if (NULL != ltask4) 3535 if (NULL != ltask4)
3507 { 3536 {
3508 GNUNET_SCHEDULER_cancel(ltask4); 3537 GNUNET_SCHEDULER_cancel (ltask4);
3509 ltask4 = NULL; 3538 ltask4 = NULL;
3510 } 3539 }
3511 if (NULL != ltask6) 3540 if (NULL != ltask6)
3512 { 3541 {
3513 GNUNET_SCHEDULER_cancel(ltask6); 3542 GNUNET_SCHEDULER_cancel (ltask6);
3514 ltask6 = NULL; 3543 ltask6 = NULL;
3515 } 3544 }
3516 gnutls_x509_crt_deinit(proxy_ca.cert); 3545 gnutls_x509_crt_deinit (proxy_ca.cert);
3517 gnutls_x509_privkey_deinit(proxy_ca.key); 3546 gnutls_x509_privkey_deinit (proxy_ca.key);
3518 gnutls_global_deinit(); 3547 gnutls_global_deinit ();
3519} 3548}
3520 3549
3521 3550
@@ -3525,34 +3554,34 @@ do_shutdown(void *cls)
3525 * @return NULL on error 3554 * @return NULL on error
3526 */ 3555 */
3527static struct GNUNET_NETWORK_Handle * 3556static struct GNUNET_NETWORK_Handle *
3528bind_v4() 3557bind_v4 ()
3529{ 3558{
3530 struct GNUNET_NETWORK_Handle *ls; 3559 struct GNUNET_NETWORK_Handle *ls;
3531 struct sockaddr_in sa4; 3560 struct sockaddr_in sa4;
3532 int eno; 3561 int eno;
3533 3562
3534 memset(&sa4, 0, sizeof(sa4)); 3563 memset (&sa4, 0, sizeof(sa4));
3535 sa4.sin_family = AF_INET; 3564 sa4.sin_family = AF_INET;
3536 sa4.sin_port = htons(port); 3565 sa4.sin_port = htons (port);
3537 sa4.sin_addr.s_addr = address; 3566 sa4.sin_addr.s_addr = address;
3538#if HAVE_SOCKADDR_IN_SIN_LEN 3567#if HAVE_SOCKADDR_IN_SIN_LEN
3539 sa4.sin_len = sizeof(sa4); 3568 sa4.sin_len = sizeof(sa4);
3540#endif 3569#endif
3541 ls = GNUNET_NETWORK_socket_create(AF_INET, 3570 ls = GNUNET_NETWORK_socket_create (AF_INET,
3542 SOCK_STREAM, 3571 SOCK_STREAM,
3543 0); 3572 0);
3544 if (NULL == ls) 3573 if (NULL == ls)
3545 return NULL; 3574 return NULL;
3546 if (GNUNET_OK != 3575 if (GNUNET_OK !=
3547 GNUNET_NETWORK_socket_bind(ls, 3576 GNUNET_NETWORK_socket_bind (ls,
3548 (const struct sockaddr *)&sa4, 3577 (const struct sockaddr *) &sa4,
3549 sizeof(sa4))) 3578 sizeof(sa4)))
3550 { 3579 {
3551 eno = errno; 3580 eno = errno;
3552 GNUNET_NETWORK_socket_close(ls); 3581 GNUNET_NETWORK_socket_close (ls);
3553 errno = eno; 3582 errno = eno;
3554 return NULL; 3583 return NULL;
3555 } 3584 }
3556 return ls; 3585 return ls;
3557} 3586}
3558 3587
@@ -3563,34 +3592,34 @@ bind_v4()
3563 * @return NULL on error 3592 * @return NULL on error
3564 */ 3593 */
3565static struct GNUNET_NETWORK_Handle * 3594static struct GNUNET_NETWORK_Handle *
3566bind_v6() 3595bind_v6 ()
3567{ 3596{
3568 struct GNUNET_NETWORK_Handle *ls; 3597 struct GNUNET_NETWORK_Handle *ls;
3569 struct sockaddr_in6 sa6; 3598 struct sockaddr_in6 sa6;
3570 int eno; 3599 int eno;
3571 3600
3572 memset(&sa6, 0, sizeof(sa6)); 3601 memset (&sa6, 0, sizeof(sa6));
3573 sa6.sin6_family = AF_INET6; 3602 sa6.sin6_family = AF_INET6;
3574 sa6.sin6_port = htons(port); 3603 sa6.sin6_port = htons (port);
3575 sa6.sin6_addr = address6; 3604 sa6.sin6_addr = address6;
3576#if HAVE_SOCKADDR_IN_SIN_LEN 3605#if HAVE_SOCKADDR_IN_SIN_LEN
3577 sa6.sin6_len = sizeof(sa6); 3606 sa6.sin6_len = sizeof(sa6);
3578#endif 3607#endif
3579 ls = GNUNET_NETWORK_socket_create(AF_INET6, 3608 ls = GNUNET_NETWORK_socket_create (AF_INET6,
3580 SOCK_STREAM, 3609 SOCK_STREAM,
3581 0); 3610 0);
3582 if (NULL == ls) 3611 if (NULL == ls)
3583 return NULL; 3612 return NULL;
3584 if (GNUNET_OK != 3613 if (GNUNET_OK !=
3585 GNUNET_NETWORK_socket_bind(ls, 3614 GNUNET_NETWORK_socket_bind (ls,
3586 (const struct sockaddr *)&sa6, 3615 (const struct sockaddr *) &sa6,
3587 sizeof(sa6))) 3616 sizeof(sa6)))
3588 { 3617 {
3589 eno = errno; 3618 eno = errno;
3590 GNUNET_NETWORK_socket_close(ls); 3619 GNUNET_NETWORK_socket_close (ls);
3591 errno = eno; 3620 errno = eno;
3592 return NULL; 3621 return NULL;
3593 } 3622 }
3594 return ls; 3623 return ls;
3595} 3624}
3596 3625
@@ -3604,211 +3633,216 @@ bind_v6()
3604 * @param c configuration 3633 * @param c configuration
3605 */ 3634 */
3606static void 3635static void
3607run(void *cls, 3636run (void *cls,
3608 char *const *args, 3637 char *const *args,
3609 const char *cfgfile, 3638 const char *cfgfile,
3610 const struct GNUNET_CONFIGURATION_Handle *c) 3639 const struct GNUNET_CONFIGURATION_Handle *c)
3611{ 3640{
3612 char* cafile_cfg = NULL; 3641 char*cafile_cfg = NULL;
3613 char* cafile; 3642 char*cafile;
3614 char* addr_str; 3643 char*addr_str;
3615 struct MhdHttpList *hd; 3644 struct MhdHttpList *hd;
3616 3645
3617 cfg = c; 3646 cfg = c;
3618 3647
3619 /* Get address to bind to */ 3648 /* Get address to bind to */
3620 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "gns-proxy", 3649 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "gns-proxy",
3621 "BIND_TO", 3650 "BIND_TO",
3622 &addr_str)) 3651 &addr_str))
3623 { 3652 {
3624 //No address specified 3653 // No address specified
3625 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3654 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3626 "Don't know what to bind to...\n"); 3655 "Don't know what to bind to...\n");
3627 GNUNET_free(addr_str); 3656 GNUNET_free (addr_str);
3628 GNUNET_SCHEDULER_shutdown(); 3657 GNUNET_SCHEDULER_shutdown ();
3629 return; 3658 return;
3630 } 3659 }
3631 if (1 != inet_pton(AF_INET, addr_str, &address)) 3660 if (1 != inet_pton (AF_INET, addr_str, &address))
3632 { 3661 {
3633 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3662 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3634 "Unable to parse address %s\n", 3663 "Unable to parse address %s\n",
3635 addr_str); 3664 addr_str);
3636 GNUNET_free(addr_str); 3665 GNUNET_free (addr_str);
3637 GNUNET_SCHEDULER_shutdown(); 3666 GNUNET_SCHEDULER_shutdown ();
3638 return; 3667 return;
3639 } 3668 }
3640 GNUNET_free(addr_str); 3669 GNUNET_free (addr_str);
3641 /* Get address to bind to */ 3670 /* Get address to bind to */
3642 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "gns-proxy", 3671 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "gns-proxy",
3643 "BIND_TO6", 3672 "BIND_TO6",
3644 &addr_str)) 3673 &addr_str))
3645 { 3674 {
3646 //No address specified 3675 // No address specified
3647 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3676 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3648 "Don't know what to bind6 to...\n"); 3677 "Don't know what to bind6 to...\n");
3649 GNUNET_free(addr_str); 3678 GNUNET_free (addr_str);
3650 GNUNET_SCHEDULER_shutdown(); 3679 GNUNET_SCHEDULER_shutdown ();
3651 return; 3680 return;
3652 } 3681 }
3653 if (1 != inet_pton(AF_INET6, addr_str, &address6)) 3682 if (1 != inet_pton (AF_INET6, addr_str, &address6))
3654 { 3683 {
3655 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3684 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3656 "Unable to parse IPv6 address %s\n", 3685 "Unable to parse IPv6 address %s\n",
3657 addr_str); 3686 addr_str);
3658 GNUNET_free(addr_str); 3687 GNUNET_free (addr_str);
3659 GNUNET_SCHEDULER_shutdown(); 3688 GNUNET_SCHEDULER_shutdown ();
3660 return; 3689 return;
3661 } 3690 }
3662 GNUNET_free(addr_str); 3691 GNUNET_free (addr_str);
3663 3692
3664 if (NULL == (curl_multi = curl_multi_init())) 3693 if (NULL == (curl_multi = curl_multi_init ()))
3665 { 3694 {
3666 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3695 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3667 "Failed to create cURL multi handle!\n"); 3696 "Failed to create cURL multi handle!\n");
3668 return; 3697 return;
3669 } 3698 }
3670 cafile = cafile_opt; 3699 cafile = cafile_opt;
3671 if (NULL == cafile) 3700 if (NULL == cafile)
3672 { 3701 {
3673 if (GNUNET_OK != 3702 if (GNUNET_OK !=
3674 GNUNET_CONFIGURATION_get_value_filename(cfg, 3703 GNUNET_CONFIGURATION_get_value_filename (cfg,
3675 "gns-proxy", 3704 "gns-proxy",
3676 "PROXY_CACERT", 3705 "PROXY_CACERT",
3677 &cafile_cfg)) 3706 &cafile_cfg))
3678 { 3707 {
3679 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, 3708 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
3680 "gns-proxy", 3709 "gns-proxy",
3681 "PROXY_CACERT"); 3710 "PROXY_CACERT");
3682 return; 3711 return;
3683 }
3684 cafile = cafile_cfg;
3685 } 3712 }
3686 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3713 cafile = cafile_cfg;
3687 "Using `%s' as CA\n", 3714 }
3688 cafile); 3715 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3716 "Using `%s' as CA\n",
3717 cafile);
3689 3718
3690 gnutls_global_init(); 3719 gnutls_global_init ();
3691 gnutls_x509_crt_init(&proxy_ca.cert); 3720 gnutls_x509_crt_init (&proxy_ca.cert);
3692 gnutls_x509_privkey_init(&proxy_ca.key); 3721 gnutls_x509_privkey_init (&proxy_ca.key);
3693 3722
3694 if ((GNUNET_OK != 3723 if ((GNUNET_OK !=
3695 load_cert_from_file(proxy_ca.cert, 3724 load_cert_from_file (proxy_ca.cert,
3696 cafile)) || 3725 cafile)) ||
3697 (GNUNET_OK != 3726 (GNUNET_OK !=
3698 load_key_from_file(proxy_ca.key, 3727 load_key_from_file (proxy_ca.key,
3699 cafile))) 3728 cafile)))
3700 { 3729 {
3701 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3730 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3702 _("Failed to load X.509 key and certificate from `%s'\n"), 3731 _ ("Failed to load X.509 key and certificate from `%s'\n"),
3703 cafile); 3732 cafile);
3704 gnutls_x509_crt_deinit(proxy_ca.cert); 3733 gnutls_x509_crt_deinit (proxy_ca.cert);
3705 gnutls_x509_privkey_deinit(proxy_ca.key); 3734 gnutls_x509_privkey_deinit (proxy_ca.key);
3706 gnutls_global_deinit(); 3735 gnutls_global_deinit ();
3707 GNUNET_free_non_null(cafile_cfg); 3736 GNUNET_free_non_null (cafile_cfg);
3708 return; 3737 return;
3709 } 3738 }
3710 GNUNET_free_non_null(cafile_cfg); 3739 GNUNET_free_non_null (cafile_cfg);
3711 if (NULL == (gns_handle = GNUNET_GNS_connect(cfg))) 3740 if (NULL == (gns_handle = GNUNET_GNS_connect (cfg)))
3712 { 3741 {
3713 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3742 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3714 "Unable to connect to GNS!\n"); 3743 "Unable to connect to GNS!\n");
3715 gnutls_x509_crt_deinit(proxy_ca.cert); 3744 gnutls_x509_crt_deinit (proxy_ca.cert);
3716 gnutls_x509_privkey_deinit(proxy_ca.key); 3745 gnutls_x509_privkey_deinit (proxy_ca.key);
3717 gnutls_global_deinit(); 3746 gnutls_global_deinit ();
3718 return; 3747 return;
3719 } 3748 }
3720 GNUNET_SCHEDULER_add_shutdown(&do_shutdown, 3749 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
3721 NULL); 3750 NULL);
3722 3751
3723 /* Open listen socket for socks proxy */ 3752 /* Open listen socket for socks proxy */
3724 lsock6 = bind_v6(); 3753 lsock6 = bind_v6 ();
3725 if (NULL == lsock6) 3754 if (NULL == lsock6)
3755 {
3756 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3757 "bind");
3758 }
3759 else
3760 {
3761 if (GNUNET_OK !=
3762 GNUNET_NETWORK_socket_listen (lsock6,
3763 5))
3726 { 3764 {
3727 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, 3765 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3728 "bind"); 3766 "listen");
3767 GNUNET_NETWORK_socket_close (lsock6);
3768 lsock6 = NULL;
3729 } 3769 }
3730 else 3770 else
3731 { 3771 {
3732 if (GNUNET_OK != 3772 ltask6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3733 GNUNET_NETWORK_socket_listen(lsock6, 3773 lsock6,
3734 5)) 3774 &do_accept,
3735 { 3775 lsock6);
3736 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR,
3737 "listen");
3738 GNUNET_NETWORK_socket_close(lsock6);
3739 lsock6 = NULL;
3740 }
3741 else
3742 {
3743 ltask6 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
3744 lsock6,
3745 &do_accept,
3746 lsock6);
3747 }
3748 } 3776 }
3749 lsock4 = bind_v4(); 3777 }
3778 lsock4 = bind_v4 ();
3750 if (NULL == lsock4) 3779 if (NULL == lsock4)
3780 {
3781 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3782 "bind");
3783 }
3784 else
3785 {
3786 if (GNUNET_OK !=
3787 GNUNET_NETWORK_socket_listen (lsock4,
3788 5))
3751 { 3789 {
3752 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, 3790 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3753 "bind"); 3791 "listen");
3792 GNUNET_NETWORK_socket_close (lsock4);
3793 lsock4 = NULL;
3754 } 3794 }
3755 else 3795 else
3756 { 3796 {
3757 if (GNUNET_OK != 3797 ltask4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3758 GNUNET_NETWORK_socket_listen(lsock4, 3798 lsock4,
3759 5)) 3799 &do_accept,
3760 { 3800 lsock4);
3761 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR,
3762 "listen");
3763 GNUNET_NETWORK_socket_close(lsock4);
3764 lsock4 = NULL;
3765 }
3766 else
3767 {
3768 ltask4 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
3769 lsock4,
3770 &do_accept,
3771 lsock4);
3772 }
3773 } 3801 }
3802 }
3774 if ((NULL == lsock4) && 3803 if ((NULL == lsock4) &&
3775 (NULL == lsock6)) 3804 (NULL == lsock6))
3776 { 3805 {
3777 GNUNET_SCHEDULER_shutdown(); 3806 GNUNET_SCHEDULER_shutdown ();
3778 return; 3807 return;
3779 } 3808 }
3780 if (0 != curl_global_init(CURL_GLOBAL_WIN32)) 3809 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
3781 { 3810 {
3782 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 3811 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3783 "cURL global init failed!\n"); 3812 "cURL global init failed!\n");
3784 GNUNET_SCHEDULER_shutdown(); 3813 GNUNET_SCHEDULER_shutdown ();
3785 return; 3814 return;
3786 } 3815 }
3787 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3788 "Proxy listens on port %u\n", 3817 "Proxy listens on port %u\n",
3789 (unsigned int)port); 3818 (unsigned int) port);
3790 3819
3791 /* start MHD daemon for HTTP */ 3820 /* start MHD daemon for HTTP */
3792 hd = GNUNET_new(struct MhdHttpList); 3821 hd = GNUNET_new (struct MhdHttpList);
3793 hd->daemon = MHD_start_daemon(MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET | MHD_ALLOW_SUSPEND_RESUME, 3822 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
3794 0, 3823 | MHD_ALLOW_SUSPEND_RESUME,
3795 NULL, NULL, 3824 0,
3796 &create_response, hd, 3825 NULL, NULL,
3797 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int)16, 3826 &create_response, hd,
3798 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL, 3827 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned
3799 MHD_OPTION_NOTIFY_CONNECTION, &mhd_connection_cb, NULL, 3828 int) 16,
3800 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL, 3829 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb,
3801 MHD_OPTION_END); 3830 NULL,
3831 MHD_OPTION_NOTIFY_CONNECTION,
3832 &mhd_connection_cb, NULL,
3833 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback,
3834 NULL,
3835 MHD_OPTION_END);
3802 if (NULL == hd->daemon) 3836 if (NULL == hd->daemon)
3803 { 3837 {
3804 GNUNET_free(hd); 3838 GNUNET_free (hd);
3805 GNUNET_SCHEDULER_shutdown(); 3839 GNUNET_SCHEDULER_shutdown ();
3806 return; 3840 return;
3807 } 3841 }
3808 httpd = hd; 3842 httpd = hd;
3809 GNUNET_CONTAINER_DLL_insert(mhd_httpd_head, 3843 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head,
3810 mhd_httpd_tail, 3844 mhd_httpd_tail,
3811 hd); 3845 hd);
3812} 3846}
3813 3847
3814 3848
@@ -3820,53 +3854,54 @@ run(void *cls,
3820 * @return 0 ok, 1 on error 3854 * @return 0 ok, 1 on error
3821 */ 3855 */
3822int 3856int
3823main(int argc, 3857main (int argc,
3824 char *const *argv) 3858 char *const *argv)
3825{ 3859{
3826 struct GNUNET_GETOPT_CommandLineOption options[] = { 3860 struct GNUNET_GETOPT_CommandLineOption options[] = {
3827 GNUNET_GETOPT_option_uint16('p', 3861 GNUNET_GETOPT_option_uint16 ('p',
3828 "port", 3862 "port",
3829 NULL, 3863 NULL,
3830 gettext_noop("listen on specified port (default: 7777)"), 3864 gettext_noop (
3831 &port), 3865 "listen on specified port (default: 7777)"),
3832 GNUNET_GETOPT_option_string('a', 3866 &port),
3833 "authority", 3867 GNUNET_GETOPT_option_string ('a',
3834 NULL, 3868 "authority",
3835 gettext_noop("pem file to use as CA"), 3869 NULL,
3836 &cafile_opt), 3870 gettext_noop ("pem file to use as CA"),
3837 GNUNET_GETOPT_option_flag('6', 3871 &cafile_opt),
3838 "disable-ivp6", 3872 GNUNET_GETOPT_option_flag ('6',
3839 gettext_noop("disable use of IPv6"), 3873 "disable-ivp6",
3840 &disable_v6), 3874 gettext_noop ("disable use of IPv6"),
3875 &disable_v6),
3841 3876
3842 GNUNET_GETOPT_OPTION_END 3877 GNUNET_GETOPT_OPTION_END
3843 }; 3878 };
3844 static const char* page = 3879 static const char*page =
3845 "<html><head><title>gnunet-gns-proxy</title>" 3880 "<html><head><title>gnunet-gns-proxy</title>"
3846 "</head><body>cURL fail</body></html>"; 3881 "</head><body>cURL fail</body></html>";
3847 int ret; 3882 int ret;
3848 3883
3849 if (GNUNET_OK != 3884 if (GNUNET_OK !=
3850 GNUNET_STRINGS_get_utf8_args(argc, argv, 3885 GNUNET_STRINGS_get_utf8_args (argc, argv,
3851 &argc, &argv)) 3886 &argc, &argv))
3852 return 2; 3887 return 2;
3853 GNUNET_log_setup("gnunet-gns-proxy", 3888 GNUNET_log_setup ("gnunet-gns-proxy",
3854 "WARNING", 3889 "WARNING",
3855 NULL); 3890 NULL);
3856 curl_failure_response 3891 curl_failure_response
3857 = MHD_create_response_from_buffer(strlen(page), 3892 = MHD_create_response_from_buffer (strlen (page),
3858 (void *)page, 3893 (void *) page,
3859 MHD_RESPMEM_PERSISTENT); 3894 MHD_RESPMEM_PERSISTENT);
3860 3895
3861 ret = 3896 ret =
3862 (GNUNET_OK == 3897 (GNUNET_OK ==
3863 GNUNET_PROGRAM_run(argc, argv, 3898 GNUNET_PROGRAM_run (argc, argv,
3864 "gnunet-gns-proxy", 3899 "gnunet-gns-proxy",
3865 _("GNUnet GNS proxy"), 3900 _ ("GNUnet GNS proxy"),
3866 options, 3901 options,
3867 &run, NULL)) ? 0 : 1; 3902 &run, NULL)) ? 0 : 1;
3868 MHD_destroy_response(curl_failure_response); 3903 MHD_destroy_response (curl_failure_response);
3869 GNUNET_free_non_null((char *)argv); 3904 GNUNET_free_non_null ((char *) argv);
3870 return ret; 3905 return ret;
3871} 3906}
3872 3907