diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-23 14:54:27 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-23 14:54:27 +0000 |
commit | 701f3aaab234871e99915e41a57cae14da9f4b09 (patch) | |
tree | acc0ba0262ffc220f34f895267d65df4cfd7c8a0 /src/transport | |
parent | 5e471d41364b2139abf8c252fedb97d79b0e8e86 (diff) | |
download | gnunet-701f3aaab234871e99915e41a57cae14da9f4b09.tar.gz gnunet-701f3aaab234871e99915e41a57cae14da9f4b09.zip |
more code
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 589 |
1 files changed, 529 insertions, 60 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index bb0a7692d..293dbd060 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -58,6 +58,9 @@ | |||
58 | #define TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT | 58 | #define TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #define HTTP_ERROR_RESPONSE "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"><HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY><H1>Not Found</H1>The requested URL was not found on this server.<P><HR><ADDRESS></ADDRESS></BODY></HTML>" | ||
62 | #define _RECEIVE 0 | ||
63 | #define _SEND 1 | ||
61 | 64 | ||
62 | /** | 65 | /** |
63 | * Encapsulation of all of the state of the plugin. | 66 | * Encapsulation of all of the state of the plugin. |
@@ -121,6 +124,31 @@ struct HttpServerSession | |||
121 | */ | 124 | */ |
122 | void *addr; | 125 | void *addr; |
123 | 126 | ||
127 | size_t addrlen; | ||
128 | |||
129 | /** | ||
130 | * Inbound or outbound connection | ||
131 | * Outbound: GNUNET_NO (client is used to send and receive) | ||
132 | * Inbound : GNUNET_YES (server is used to send and receive) | ||
133 | */ | ||
134 | int inbound; | ||
135 | |||
136 | /** | ||
137 | * Unique HTTP/S connection tag for this connection | ||
138 | */ | ||
139 | uint32_t tag; | ||
140 | |||
141 | /** | ||
142 | * ATS network type in NBO | ||
143 | */ | ||
144 | uint32_t ats_address_network_type; | ||
145 | |||
146 | /** | ||
147 | * Absolute time when to receive data again | ||
148 | * Used for receive throttling | ||
149 | */ | ||
150 | struct GNUNET_TIME_Absolute next_receive; | ||
151 | |||
124 | /** | 152 | /** |
125 | * Session timeout task | 153 | * Session timeout task |
126 | */ | 154 | */ |
@@ -136,7 +164,7 @@ struct ServerConnection | |||
136 | int disconnect; | 164 | int disconnect; |
137 | 165 | ||
138 | /* The session this server connection belongs to */ | 166 | /* The session this server connection belongs to */ |
139 | struct Session *session; | 167 | struct HttpServerSession *session; |
140 | 168 | ||
141 | /* The MHD connection */ | 169 | /* The MHD connection */ |
142 | struct MHD_Connection *mhd_conn; | 170 | struct MHD_Connection *mhd_conn; |
@@ -380,13 +408,13 @@ struct HTTP_Message | |||
380 | 408 | ||
381 | static struct Plugin * p; | 409 | static struct Plugin * p; |
382 | 410 | ||
383 | #if 0 | ||
384 | /** | 411 | /** |
385 | * Start session timeout | 412 | * Start session timeout |
386 | */ | 413 | */ |
387 | static void | 414 | static void |
388 | server_start_session_timeout (struct HttpServerSession *s); | 415 | server_start_session_timeout (struct HttpServerSession *s); |
389 | 416 | ||
417 | #if 0 | ||
390 | /** | 418 | /** |
391 | * Increment session timeout due to activity | 419 | * Increment session timeout due to activity |
392 | */ | 420 | */ |
@@ -620,58 +648,6 @@ server_stop_session_timeout (struct HttpServerSession *s) | |||
620 | } | 648 | } |
621 | } | 649 | } |
622 | 650 | ||
623 | static int | ||
624 | server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | ||
625 | const char *url, const char *method, const char *version, | ||
626 | const char *upload_data, size_t * upload_data_size, | ||
627 | void **httpSessionCache) | ||
628 | { | ||
629 | /* FIXME SPLIT */ | ||
630 | return MHD_NO; | ||
631 | } | ||
632 | |||
633 | static void | ||
634 | server_disconnect_cb (void *cls, struct MHD_Connection *connection, | ||
635 | void **httpSessionCache) | ||
636 | { | ||
637 | /* FIXME SPLIT */ | ||
638 | GNUNET_break (0); | ||
639 | } | ||
640 | |||
641 | /** | ||
642 | * Check if incoming connection is accepted. | ||
643 | * NOTE: Here every connection is accepted | ||
644 | * @param cls plugin as closure | ||
645 | * @param addr address of incoming connection | ||
646 | * @param addr_len address length of incoming connection | ||
647 | * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected | ||
648 | * | ||
649 | */ | ||
650 | static int | ||
651 | server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) | ||
652 | { | ||
653 | struct HTTP_Server_Plugin *plugin = cls; | ||
654 | GNUNET_break (0); | ||
655 | if (plugin->cur_connections <= plugin->max_connections) | ||
656 | return MHD_YES; | ||
657 | else | ||
658 | { | ||
659 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
660 | "Server: Cannot accept new connections\n"); | ||
661 | return MHD_NO; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | static void | ||
666 | server_log (void *arg, const char *fmt, va_list ap) | ||
667 | { | ||
668 | char text[1024]; | ||
669 | |||
670 | vsnprintf (text, sizeof (text), fmt, ap); | ||
671 | va_end (ap); | ||
672 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server: %s\n", text); | ||
673 | } | ||
674 | |||
675 | /** | 651 | /** |
676 | * Function that queries MHD's select sets and | 652 | * Function that queries MHD's select sets and |
677 | * starts the task waiting for them. | 653 | * starts the task waiting for them. |
@@ -726,6 +702,498 @@ server_reschedule (struct HTTP_Server_Plugin *plugin, struct MHD_Daemon *server, | |||
726 | } | 702 | } |
727 | } | 703 | } |
728 | 704 | ||
705 | |||
706 | static struct ServerConnection * | ||
707 | server_lookup_connection (struct HTTP_Server_Plugin *plugin, | ||
708 | struct MHD_Connection *mhd_connection, const char *url, | ||
709 | const char *method) | ||
710 | { | ||
711 | struct HttpServerSession *s = NULL; | ||
712 | struct HttpServerSession *t; | ||
713 | struct ServerConnection *sc = NULL; | ||
714 | const union MHD_ConnectionInfo *conn_info; | ||
715 | struct GNUNET_ATS_Information ats; | ||
716 | |||
717 | char *addr; | ||
718 | size_t addr_len; | ||
719 | |||
720 | struct GNUNET_PeerIdentity target; | ||
721 | uint32_t tag = 0; | ||
722 | int direction = GNUNET_SYSERR; | ||
723 | |||
724 | /* url parsing variables */ | ||
725 | size_t url_len; | ||
726 | char *url_end; | ||
727 | char *hash_start; | ||
728 | char *hash_end; | ||
729 | char *tag_start; | ||
730 | char *tag_end; | ||
731 | |||
732 | conn_info = MHD_get_connection_info (mhd_connection, | ||
733 | MHD_CONNECTION_INFO_CLIENT_ADDRESS); | ||
734 | if ((conn_info->client_addr->sa_family != AF_INET) && | ||
735 | (conn_info->client_addr->sa_family != AF_INET6)) | ||
736 | return NULL; | ||
737 | |||
738 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
739 | "New %s connection from %s\n", method, url); | ||
740 | /* URL parsing | ||
741 | * URL is valid if it is in the form [peerid[103];tag]*/ | ||
742 | url_len = strlen (url); | ||
743 | url_end = (char *) &url[url_len]; | ||
744 | |||
745 | if (url_len < 105) | ||
746 | { | ||
747 | goto error; /* too short */ | ||
748 | } | ||
749 | hash_start = strrchr (url, '/'); | ||
750 | if (NULL == hash_start) | ||
751 | { | ||
752 | goto error; /* '/' delimiter not found */ | ||
753 | } | ||
754 | if (hash_start >= url_end) | ||
755 | { | ||
756 | goto error; /* mal formed */ | ||
757 | } | ||
758 | hash_start++; | ||
759 | |||
760 | hash_end = strrchr (hash_start, ';'); | ||
761 | if (NULL == hash_end) | ||
762 | goto error; /* ';' delimiter not found */ | ||
763 | if (hash_end >= url_end) | ||
764 | { | ||
765 | goto error; /* mal formed */ | ||
766 | } | ||
767 | |||
768 | if (hash_start >= hash_end) | ||
769 | { | ||
770 | goto error; /* mal formed */ | ||
771 | } | ||
772 | |||
773 | if ((strlen(hash_start) - strlen(hash_end)) != 103) | ||
774 | { | ||
775 | goto error; /* invalid hash length */ | ||
776 | } | ||
777 | |||
778 | char hash[104]; | ||
779 | memcpy (hash, hash_start, 103); | ||
780 | hash[103] = '\0'; | ||
781 | if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target.hashPubKey))) | ||
782 | { | ||
783 | goto error; /* mal formed */ | ||
784 | } | ||
785 | |||
786 | if (hash_end >= url_end) | ||
787 | { | ||
788 | goto error; /* mal formed */ | ||
789 | } | ||
790 | |||
791 | tag_start = &hash_end[1]; | ||
792 | /* Converting tag */ | ||
793 | tag_end = NULL; | ||
794 | tag = strtoul (tag_start, &tag_end, 10); | ||
795 | if (tag == 0) | ||
796 | { | ||
797 | goto error; /* mal formed */ | ||
798 | } | ||
799 | if (tag_end == NULL) | ||
800 | { | ||
801 | goto error; /* mal formed */ | ||
802 | } | ||
803 | if (tag_end != url_end) | ||
804 | { | ||
805 | goto error; /* mal formed */ | ||
806 | } | ||
807 | |||
808 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) | ||
809 | direction = _RECEIVE; | ||
810 | else if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) | ||
811 | direction = _SEND; | ||
812 | else | ||
813 | { | ||
814 | goto error; | ||
815 | } | ||
816 | |||
817 | plugin->cur_connections++; | ||
818 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
819 | "New %s connection from %s with tag %u (%u of %u)\n", | ||
820 | method, | ||
821 | GNUNET_i2s (&target), tag, | ||
822 | plugin->cur_connections, plugin->max_connections); | ||
823 | |||
824 | /* find duplicate session */ | ||
825 | t = plugin->head; | ||
826 | while (t != NULL) | ||
827 | { | ||
828 | if ((t->inbound) && | ||
829 | (0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) | ||
830 | && | ||
831 | /* FIXME add source address comparison */ | ||
832 | (t->tag == tag)) | ||
833 | break; | ||
834 | t = t->next; | ||
835 | } | ||
836 | if (t != NULL) | ||
837 | { | ||
838 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
839 | "Duplicate session, dismissing new connection from peer `%s'\n", | ||
840 | GNUNET_i2s (&target)); | ||
841 | goto error; | ||
842 | } | ||
843 | |||
844 | /* find semi-session */ | ||
845 | t = plugin->server_semi_head; | ||
846 | |||
847 | while (t != NULL) | ||
848 | { | ||
849 | /* FIXME add source address comparison */ | ||
850 | if ((0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) | ||
851 | && (t->tag == tag)) | ||
852 | { | ||
853 | break; | ||
854 | } | ||
855 | t = t->next; | ||
856 | } | ||
857 | |||
858 | if (t == NULL) | ||
859 | goto create; | ||
860 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
861 | "Found existing semi-session for `%s'\n", | ||
862 | GNUNET_i2s (&target)); | ||
863 | |||
864 | if ((direction == _SEND) && (t->server_send != NULL)) | ||
865 | { | ||
866 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
867 | "Duplicate GET session, dismissing new connection from peer `%s'\n", | ||
868 | GNUNET_i2s (&target)); | ||
869 | goto error; | ||
870 | } | ||
871 | else | ||
872 | { | ||
873 | s = t; | ||
874 | GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head, | ||
875 | plugin->server_semi_tail, s); | ||
876 | GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); | ||
877 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
878 | "Found matching semi-session, merging session for peer `%s'\n", | ||
879 | GNUNET_i2s (&target)); | ||
880 | GNUNET_assert (NULL != s); | ||
881 | goto found; | ||
882 | } | ||
883 | if ((direction == _RECEIVE) && (t->server_recv != NULL)) | ||
884 | { | ||
885 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
886 | "Duplicate PUT session, dismissing new connection from peer `%s'\n", | ||
887 | GNUNET_i2s (&target)); | ||
888 | goto error; | ||
889 | } | ||
890 | else | ||
891 | { | ||
892 | s = t; | ||
893 | GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head, | ||
894 | plugin->server_semi_tail, s); | ||
895 | GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); | ||
896 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
897 | "Found matching semi-session, merging session for peer `%s'\n", | ||
898 | GNUNET_i2s (&target)); | ||
899 | GNUNET_assert (NULL != s); | ||
900 | goto found; | ||
901 | } | ||
902 | |||
903 | create: | ||
904 | /* create new session */ | ||
905 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
906 | "Creating new session for peer `%s' \n", | ||
907 | GNUNET_i2s (&target)); | ||
908 | switch (conn_info->client_addr->sa_family) | ||
909 | { | ||
910 | case (AF_INET): | ||
911 | addr = http_common_address_from_socket (plugin->protocol, conn_info->client_addr, sizeof (struct sockaddr_in)); | ||
912 | addr_len = http_common_address_get_size (addr); | ||
913 | ats = plugin->env->get_address_type (plugin->env->cls, conn_info->client_addr, sizeof (struct sockaddr_in)); | ||
914 | break; | ||
915 | case (AF_INET6): | ||
916 | addr = http_common_address_from_socket (plugin->protocol, conn_info->client_addr, sizeof (struct sockaddr_in6)); | ||
917 | addr_len = http_common_address_get_size (addr); | ||
918 | ats = plugin->env->get_address_type (plugin->env->cls, conn_info->client_addr, sizeof (struct sockaddr_in6)); | ||
919 | break; | ||
920 | default: | ||
921 | GNUNET_break (0); | ||
922 | goto error; | ||
923 | } | ||
924 | |||
925 | s = GNUNET_malloc (sizeof (struct HttpServerSession)); | ||
926 | memcpy (&s->target, &target, sizeof (struct GNUNET_PeerIdentity)); | ||
927 | s->plugin = plugin; | ||
928 | s->addr = addr; | ||
929 | s->addrlen = addr_len; | ||
930 | s->ats_address_network_type = ats.value; | ||
931 | s->inbound = GNUNET_YES; | ||
932 | s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; | ||
933 | s->tag = tag; | ||
934 | s->server_recv = NULL; | ||
935 | s->server_send = NULL; | ||
936 | |||
937 | server_start_session_timeout(s); | ||
938 | |||
939 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, | ||
940 | plugin->server_semi_tail, s); | ||
941 | goto found; | ||
942 | error: | ||
943 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
944 | "Invalid connection request\n"); | ||
945 | return NULL; | ||
946 | |||
947 | found: | ||
948 | sc = GNUNET_malloc (sizeof (struct ServerConnection)); | ||
949 | sc->mhd_conn = mhd_connection; | ||
950 | sc->direction = direction; | ||
951 | sc->session = s; | ||
952 | if (direction == _SEND) | ||
953 | s->server_send = sc; | ||
954 | if (direction == _RECEIVE) | ||
955 | s->server_recv = sc; | ||
956 | |||
957 | #if MHD_VERSION >= 0x00090E00 | ||
958 | int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); | ||
959 | |||
960 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
961 | "Setting timeout for %p to %u sec.\n", sc, to); | ||
962 | MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to); | ||
963 | |||
964 | struct MHD_Daemon *d = NULL; | ||
965 | #if 0 | ||
966 | if (s->addrlen == sizeof (struct IPv6HttpAddress)) | ||
967 | d = plugin->server_v6; | ||
968 | if (s->addrlen == sizeof (struct IPv4HttpAddress)) | ||
969 | d = plugin->server_v4; | ||
970 | #endif | ||
971 | server_reschedule (plugin, d, GNUNET_NO); | ||
972 | #endif | ||
973 | return sc; | ||
974 | |||
975 | } | ||
976 | |||
977 | static struct HttpServerSession * | ||
978 | server_lookup_session (struct HTTP_Server_Plugin *plugin, | ||
979 | struct ServerConnection * sc) | ||
980 | { | ||
981 | struct HttpServerSession *s; | ||
982 | |||
983 | for (s = plugin->head; NULL != s; s = s->next) | ||
984 | if ((s->server_recv == sc) || (s->server_send == sc)) | ||
985 | return s; | ||
986 | for (s = plugin->server_semi_head; NULL != s; s = s->next) | ||
987 | if ((s->server_recv == sc) || (s->server_send == sc)) | ||
988 | return s; | ||
989 | return NULL; | ||
990 | } | ||
991 | |||
992 | |||
993 | static int | ||
994 | server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | ||
995 | const char *url, const char *method, const char *version, | ||
996 | const char *upload_data, size_t * upload_data_size, | ||
997 | void **httpSessionCache) | ||
998 | { | ||
999 | struct HTTP_Server_Plugin *plugin = cls; | ||
1000 | int res = MHD_YES; | ||
1001 | |||
1002 | struct ServerConnection *sc = *httpSessionCache; | ||
1003 | struct HttpServerSession *s; | ||
1004 | struct MHD_Response *response; | ||
1005 | |||
1006 | GNUNET_assert (cls != NULL); | ||
1007 | if (sc == NULL) | ||
1008 | { | ||
1009 | /* new connection */ | ||
1010 | sc = server_lookup_connection (plugin, mhd_connection, url, method); | ||
1011 | if (sc != NULL) | ||
1012 | (*httpSessionCache) = sc; | ||
1013 | else | ||
1014 | { | ||
1015 | response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE), HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); | ||
1016 | res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response); | ||
1017 | MHD_destroy_response (response); | ||
1018 | return res; | ||
1019 | } | ||
1020 | } | ||
1021 | else | ||
1022 | { | ||
1023 | /* 'old' connection */ | ||
1024 | if (NULL == server_lookup_session (plugin, sc)) | ||
1025 | { | ||
1026 | /* Session was already disconnected */ | ||
1027 | return MHD_NO; | ||
1028 | } | ||
1029 | } | ||
1030 | |||
1031 | /* existing connection */ | ||
1032 | sc = (*httpSessionCache); | ||
1033 | s = sc->session; | ||
1034 | |||
1035 | GNUNET_assert (NULL != s); | ||
1036 | #if 0 | ||
1037 | /* connection is to be disconnected */ | ||
1038 | if (sc->disconnect == GNUNET_YES) | ||
1039 | { | ||
1040 | /* Sent HTTP/1.1: 200 OK as PUT Response\ */ | ||
1041 | response = | ||
1042 | MHD_create_response_from_data (strlen ("Thank you!"), "Thank you!", | ||
1043 | MHD_NO, MHD_NO); | ||
1044 | res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); | ||
1045 | MHD_destroy_response (response); | ||
1046 | return MHD_YES; | ||
1047 | } | ||
1048 | |||
1049 | GNUNET_assert (s != NULL); | ||
1050 | /* Check if both directions are connected */ | ||
1051 | if ((sc->session->server_recv == NULL) || (sc->session->server_send == NULL)) | ||
1052 | { | ||
1053 | /* Delayed read from since not both semi-connections are connected */ | ||
1054 | return MHD_YES; | ||
1055 | } | ||
1056 | |||
1057 | if (sc->direction == _SEND) | ||
1058 | { | ||
1059 | response = | ||
1060 | MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, | ||
1061 | 32 * 1024, | ||
1062 | &server_send_callback, s, | ||
1063 | NULL); | ||
1064 | MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); | ||
1065 | MHD_destroy_response (response); | ||
1066 | return MHD_YES; | ||
1067 | } | ||
1068 | if (sc->direction == _RECEIVE) | ||
1069 | { | ||
1070 | if (*upload_data_size == 0) | ||
1071 | { | ||
1072 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1073 | "Server: Peer `%s' PUT on address `%s' connected\n", | ||
1074 | GNUNET_i2s (&s->target), | ||
1075 | http_plugin_address_to_string (NULL, s->addr, | ||
1076 | s->addrlen)); | ||
1077 | return MHD_YES; | ||
1078 | } | ||
1079 | |||
1080 | /* Receiving data */ | ||
1081 | if ((*upload_data_size > 0)) | ||
1082 | { | ||
1083 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1084 | "Server: peer `%s' PUT on address `%s' received %u bytes\n", | ||
1085 | GNUNET_i2s (&s->target), | ||
1086 | http_plugin_address_to_string (NULL, s->addr, | ||
1087 | s->addrlen), | ||
1088 | *upload_data_size); | ||
1089 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
1090 | |||
1091 | if ((s->next_receive.abs_value <= now.abs_value)) | ||
1092 | { | ||
1093 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1094 | "Server: %p: PUT with %u bytes forwarded to MST\n", s, | ||
1095 | *upload_data_size); | ||
1096 | if (s->msg_tk == NULL) | ||
1097 | { | ||
1098 | s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s); | ||
1099 | } | ||
1100 | GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, | ||
1101 | *upload_data_size, GNUNET_NO, GNUNET_NO); | ||
1102 | |||
1103 | #if MHD_VERSION >= 0x00090E00 | ||
1104 | int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); | ||
1105 | struct ServerConnection *t = NULL; | ||
1106 | |||
1107 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1108 | "Server: Received %u bytes\n", *upload_data_size); | ||
1109 | /* Setting timeouts for other connections */ | ||
1110 | if (s->server_recv != NULL) | ||
1111 | { | ||
1112 | t = s->server_recv; | ||
1113 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1114 | "Server: Setting timeout for %p to %u sec.\n", t, | ||
1115 | to); | ||
1116 | MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, | ||
1117 | to); | ||
1118 | } | ||
1119 | if (s->server_send != NULL) | ||
1120 | { | ||
1121 | t = s->server_send; | ||
1122 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1123 | "Server: Setting timeout for %p to %u sec.\n", t, | ||
1124 | to); | ||
1125 | MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, | ||
1126 | to); | ||
1127 | } | ||
1128 | struct MHD_Daemon *d = NULL; | ||
1129 | |||
1130 | if (s->addrlen == sizeof (struct IPv6HttpAddress)) | ||
1131 | d = plugin->server_v6; | ||
1132 | if (s->addrlen == sizeof (struct IPv4HttpAddress)) | ||
1133 | d = plugin->server_v4; | ||
1134 | server_reschedule (plugin, d, GNUNET_NO); | ||
1135 | #endif | ||
1136 | (*upload_data_size) = 0; | ||
1137 | } | ||
1138 | else | ||
1139 | { | ||
1140 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1141 | "Server: %p no inbound bandwidth available! Next read was delayed by %llu ms\n", | ||
1142 | s, now.abs_value - s->next_receive.abs_value); | ||
1143 | } | ||
1144 | return MHD_YES; | ||
1145 | } | ||
1146 | else | ||
1147 | return MHD_NO; | ||
1148 | } | ||
1149 | #endif | ||
1150 | return res; | ||
1151 | } | ||
1152 | |||
1153 | static void | ||
1154 | server_disconnect_cb (void *cls, struct MHD_Connection *connection, | ||
1155 | void **httpSessionCache) | ||
1156 | { | ||
1157 | /* FIXME SPLIT */ | ||
1158 | GNUNET_break (0); | ||
1159 | } | ||
1160 | |||
1161 | /** | ||
1162 | * Check if incoming connection is accepted. | ||
1163 | * NOTE: Here every connection is accepted | ||
1164 | * @param cls plugin as closure | ||
1165 | * @param addr address of incoming connection | ||
1166 | * @param addr_len address length of incoming connection | ||
1167 | * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected | ||
1168 | * | ||
1169 | */ | ||
1170 | static int | ||
1171 | server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) | ||
1172 | { | ||
1173 | struct HTTP_Server_Plugin *plugin = cls; | ||
1174 | |||
1175 | if (plugin->cur_connections <= plugin->max_connections) | ||
1176 | return MHD_YES; | ||
1177 | else | ||
1178 | { | ||
1179 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, | ||
1180 | _("Server reached maximum number connections (%u), rejecting new connection\n"), | ||
1181 | plugin->max_connections); | ||
1182 | return MHD_NO; | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | static void | ||
1187 | server_log (void *arg, const char *fmt, va_list ap) | ||
1188 | { | ||
1189 | char text[1024]; | ||
1190 | |||
1191 | vsnprintf (text, sizeof (text), fmt, ap); | ||
1192 | va_end (ap); | ||
1193 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server: %s\n", text); | ||
1194 | } | ||
1195 | |||
1196 | |||
729 | /** | 1197 | /** |
730 | * Call MHD IPv4 to process pending requests and then go back | 1198 | * Call MHD IPv4 to process pending requests and then go back |
731 | * and schedule the next run. | 1199 | * and schedule the next run. |
@@ -1757,10 +2225,7 @@ server_configure_plugin (struct HTTP_Server_Plugin *plugin) | |||
1757 | return GNUNET_OK; | 2225 | return GNUNET_OK; |
1758 | } | 2226 | } |
1759 | 2227 | ||
1760 | #if 0 | 2228 | |
1761 | /** | ||
1762 | * Session was idle, so disconnect it | ||
1763 | */ | ||
1764 | static void | 2229 | static void |
1765 | server_session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 2230 | server_session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1766 | { | 2231 | { |
@@ -1776,7 +2241,6 @@ server_session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1776 | GNUNET_assert (GNUNET_OK == server_disconnect (s)); | 2241 | GNUNET_assert (GNUNET_OK == server_disconnect (s)); |
1777 | } | 2242 | } |
1778 | 2243 | ||
1779 | |||
1780 | /** | 2244 | /** |
1781 | * Start session timeout | 2245 | * Start session timeout |
1782 | */ | 2246 | */ |
@@ -1786,13 +2250,18 @@ server_start_session_timeout (struct HttpServerSession *s) | |||
1786 | GNUNET_assert (NULL != s); | 2250 | GNUNET_assert (NULL != s); |
1787 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); | 2251 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); |
1788 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 2252 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
1789 | &session_timeout, | 2253 | &server_session_timeout, |
1790 | s); | 2254 | s); |
1791 | GNUNET_log (TIMEOUT_LOG, | 2255 | GNUNET_log (TIMEOUT_LOG, |
1792 | "Timeout for session %p set to %llu ms\n", | 2256 | "Timeout for session %p set to %llu ms\n", |
1793 | s, (unsigned long long) TIMEOUT.rel_value); | 2257 | s, (unsigned long long) TIMEOUT.rel_value); |
1794 | } | 2258 | } |
1795 | 2259 | ||
2260 | #if 0 | ||
2261 | /** | ||
2262 | * Session was idle, so disconnect it | ||
2263 | */ | ||
2264 | |||
1796 | 2265 | ||
1797 | /** | 2266 | /** |
1798 | * Increment session timeout due to activity | 2267 | * Increment session timeout due to activity |