aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-09-20 08:55:20 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-09-20 08:55:20 +0000
commit37c4704049df39026b5fb043bcebcd7a15ecf1a2 (patch)
tree63715573fa07c05d7ff393462f0ce986adca9d85 /src
parentf1be2c0c8410b0829171990f85ffb4d107216ffb (diff)
downloadgnunet-37c4704049df39026b5fb043bcebcd7a15ecf1a2.tar.gz
gnunet-37c4704049df39026b5fb043bcebcd7a15ecf1a2.zip
- url parsing
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_http_server.c235
1 files changed, 125 insertions, 110 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index e8250af8b..c674a6755 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -221,6 +221,11 @@ struct HTTP_Server_Plugin
221 int in_shutdown; 221 int in_shutdown;
222 222
223 /** 223 /**
224 * Length of peer id
225 */
226 int peer_id_length;
227
228 /**
224 * External hostname the plugin can be connected to, can be different to 229 * External hostname the plugin can be connected to, can be different to
225 * the host's FQDN, used e.g. for reverse proxying 230 * the host's FQDN, used e.g. for reverse proxying
226 */ 231 */
@@ -844,6 +849,112 @@ server_mhd_connection_timeout (struct HTTP_Server_Plugin *plugin, struct Session
844#endif 849#endif
845} 850}
846 851
852/**
853 * Parse incoming URL for tag and target
854 *
855 * @url incoming url
856 * @target where to store the target
857 * @tag where to store the tag
858 * @return GNUNET_OK on success, GNUNET_SYSERR on error
859 */
860
861static int
862server_parse_url (struct HTTP_Server_Plugin *plugin, const char * url, struct GNUNET_PeerIdentity * target, uint32_t *tag)
863{
864 int debug = GNUNET_YES;
865
866 char * tag_start = NULL;
867 char * tag_end = NULL;
868 char * target_start = NULL;
869 char * separator = NULL;
870 char hash[plugin->peer_id_length+1];
871 int hash_length;
872
873 /* URL parsing
874 * URL is valid if it is in the form [prefix with (multiple) '/'][peerid[103];tag]*/
875
876 if (NULL == url)
877 {
878 GNUNET_break (0);
879 return GNUNET_SYSERR;
880 }
881 /* convert tag */
882
883 /* find separator */
884 separator = strrchr (url, ';');
885
886 if (NULL == separator)
887 {
888 if (debug) GNUNET_break (0);
889 return GNUNET_SYSERR;
890 }
891 tag_start = separator + 1;
892
893 if (strlen (tag_start) == 0)
894 {
895 /* No tag after separator */
896 if (debug) GNUNET_break (0);
897 return GNUNET_SYSERR;
898 }
899 (*tag) = strtoul (tag_start, &tag_end, 10);
900 if ((*tag) == 0)
901 {
902 /* tag == 0 , invalid */
903 if (debug) GNUNET_break (0);
904 return GNUNET_SYSERR;
905 }
906 if (((*tag) == ULONG_MAX) && (ERANGE == errno))
907 {
908 /* out of range: > ULONG_MAX */
909 if (debug) GNUNET_break (0);
910 return GNUNET_SYSERR;
911 }
912 if (NULL == tag_end)
913 {
914 /* no char after tag */
915 if (debug) GNUNET_break (0);
916 return GNUNET_SYSERR;
917 }
918 if (url[strlen(url)] != tag_end[0])
919 {
920 /* there are more not converted chars after tag */
921 if (debug) GNUNET_break (0);
922 return GNUNET_SYSERR;
923 }
924 if (debug)
925 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
926 "Found tag `%u' in url\n", (*tag));
927
928 /* convert peer id */
929 target_start = strrchr (url, '/');
930 if (NULL == target_start)
931 {
932 /* no leading '/' */
933 target_start = url;
934 }
935 target_start++;
936 hash_length = separator - target_start;
937 if (hash_length != plugin->peer_id_length)
938 {
939 /* no char after tag */
940 if (debug) GNUNET_break (0);
941 return GNUNET_SYSERR;
942 }
943 memcpy (hash, target_start, hash_length);
944 hash[hash_length] = '\0';
945
946 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target->hashPubKey)))
947 {
948 /* hash conversion failed */
949 if (debug) GNUNET_break (0);
950 return GNUNET_SYSERR;
951 }
952
953 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
954 "Found target `%s' in url\n", GNUNET_h2s_full(&target->hashPubKey));
955 return GNUNET_OK;
956}
957
847 958
848/** 959/**
849 * Lookup a mhd connection and create one if none is found 960 * Lookup a mhd connection and create one if none is found
@@ -872,14 +983,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
872 int direction = GNUNET_SYSERR; 983 int direction = GNUNET_SYSERR;
873 int to; 984 int to;
874 985
875 /* url parsing variables */
876 size_t url_len;
877 char *url_end;
878 char *hash_start;
879 char *hash_end;
880 char *tag_start;
881 char *tag_end;
882
883 conn_info = MHD_get_connection_info (mhd_connection, 986 conn_info = MHD_get_connection_info (mhd_connection,
884 MHD_CONNECTION_INFO_CLIENT_ADDRESS); 987 MHD_CONNECTION_INFO_CLIENT_ADDRESS);
885 if ((conn_info->client_addr->sa_family != AF_INET) && 988 if ((conn_info->client_addr->sa_family != AF_INET) &&
@@ -888,104 +991,21 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
888 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 991 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
889 "New %s connection from %s\n", method, url); 992 "New %s connection from %s\n", method, url);
890 993
891 /* URL parsing 994 if (GNUNET_SYSERR == server_parse_url (plugin, url, &target, &tag))
892 * URL is valid if it is in the form [peerid[103];tag]*/
893 url_len = strlen (url);
894 url_end = (char *) &url[url_len];
895
896 if (url_len < 105)
897 {
898
899 goto error; /* too short */
900 }
901 hash_start = strrchr (url, '/');
902 if (NULL == hash_start)
903 {
904 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
905 "Invalid request with url `%s': %s\n", url, "No delimiter found");
906 goto error; /* '/' delimiter not found */
907 }
908 if (hash_start >= url_end)
909 { 995 {
910 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 996 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
911 "Invalid request with url `%s': %s\n", url, "Malformed delimiter"); 997 "Invalid url %s\n", url);
912 goto error; /* mal formed */ 998 return NULL;
913 }
914 hash_start++;
915
916 hash_end = strrchr (hash_start, ';');
917 if (NULL == hash_end)
918 {
919 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
920 "Invalid request with url `%s': %s\n", url, "No `;' delimiter found");
921 goto error; /* ';' delimiter not found */
922 }
923
924 if (hash_end >= url_end)
925 {
926 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
927 "Invalid request with url `%s': %s\n", url, "Malformed length");
928 goto error; /* mal formed */
929 }
930
931 if (hash_start >= hash_end)
932 {
933 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
934 "Invalid request with url `%s': %s\n", url, "Malformed length");
935 goto error; /* mal formed */
936 }
937
938 if ((strlen(hash_start) - strlen(hash_end)) != 103)
939 {
940 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
941 "New %s connection from %s\n", method, url);
942 goto error; /* invalid hash length */
943 }
944
945 char hash[104];
946 memcpy (hash, hash_start, 103);
947 hash[103] = '\0';
948 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target.hashPubKey)))
949 {
950 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
951 "Invalid request with url `%s': %s\n", url, "Malformed peer id");
952 goto error; /* mal formed */
953 }
954
955 if (hash_end >= url_end)
956 {
957 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
958 "Invalid request with url `%s': %s\n", url, "Malformed length");
959 goto error; /* mal formed */
960 }
961
962 tag_start = &hash_end[1];
963 /* Converting tag */
964 tag_end = NULL;
965 tag = strtoul (tag_start, &tag_end, 10);
966 if (tag == 0)
967 {
968 GNUNET_break (0);
969 goto error; /* mal formed */
970 }
971 if (tag_end == NULL)
972 {
973 GNUNET_break (0);
974 goto error; /* mal formed */
975 }
976 if (tag_end != url_end)
977 {
978 GNUNET_break (0);
979 goto error; /* mal formed */
980 } 999 }
981
982 if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) 1000 if (0 == strcmp (MHD_HTTP_METHOD_PUT, method))
983 direction = _RECEIVE; 1001 direction = _RECEIVE;
984 else if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) 1002 else if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
985 direction = _SEND; 1003 direction = _SEND;
986 else 1004 else
987 { 1005 {
988 goto error; 1006 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1007 "Invalid method %s connection from %s\n", method, url);
1008 return NULL;
989 } 1009 }
990 1010
991 plugin->cur_connections++; 1011 plugin->cur_connections++;
@@ -994,7 +1014,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
994 method, 1014 method,
995 GNUNET_i2s (&target), tag, 1015 GNUNET_i2s (&target), tag,
996 plugin->cur_connections, plugin->max_connections); 1016 plugin->cur_connections, plugin->max_connections);
997
998 /* find duplicate session */ 1017 /* find duplicate session */
999 s = plugin->head; 1018 s = plugin->head;
1000 while (s != NULL) 1019 while (s != NULL)
@@ -1012,7 +1031,8 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1012 "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n", 1031 "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n",
1013 GNUNET_i2s (&target), 1032 GNUNET_i2s (&target),
1014 tag); 1033 tag);
1015 goto error; 1034 return NULL;
1035
1016 } 1036 }
1017 if ((_SEND == direction) && (NULL != s->server_send)) 1037 if ((_SEND == direction) && (NULL != s->server_send))
1018 { 1038 {
@@ -1020,7 +1040,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1020 "Duplicate GET connection from `%s' tag %u, dismissing new connection\n", 1040 "Duplicate GET connection from `%s' tag %u, dismissing new connection\n",
1021 GNUNET_i2s (&target), 1041 GNUNET_i2s (&target),
1022 tag); 1042 tag);
1023 goto error; 1043 return NULL;
1024 } 1044 }
1025 } 1045 }
1026 else 1046 else
@@ -1040,9 +1060,8 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1040 break; 1060 break;
1041 default: 1061 default:
1042 GNUNET_break (0); 1062 GNUNET_break (0);
1043 goto error; 1063 return NULL;
1044 } 1064 }
1045
1046 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 1065 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1047 "Creating new session for peer `%s' connecting from `%s'\n", 1066 "Creating new session for peer `%s' connecting from `%s'\n",
1048 GNUNET_i2s (&target), 1067 GNUNET_i2s (&target),
@@ -1063,7 +1082,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1063 server_start_session_timeout(s); 1082 server_start_session_timeout(s);
1064 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); 1083 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
1065 } 1084 }
1066
1067 sc = GNUNET_malloc (sizeof (struct ServerConnection)); 1085 sc = GNUNET_malloc (sizeof (struct ServerConnection));
1068 if (conn_info->client_addr->sa_family == AF_INET) 1086 if (conn_info->client_addr->sa_family == AF_INET)
1069 sc->mhd_daemon = plugin->server_v4; 1087 sc->mhd_daemon = plugin->server_v4;
@@ -1077,7 +1095,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1077 s->server_send = sc; 1095 s->server_send = sc;
1078 if (direction == _RECEIVE) 1096 if (direction == _RECEIVE)
1079 s->server_recv = sc; 1097 s->server_recv = sc;
1080
1081#if MHD_VERSION >= 0x00090E00 1098#if MHD_VERSION >= 0x00090E00
1082 if ((NULL == s->server_recv) || (NULL == s->server_send)) 1099 if ((NULL == s->server_recv) || (NULL == s->server_send))
1083 { 1100 {
@@ -1098,12 +1115,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1098 "Setting timeout for %p to %u sec.\n", sc, to); 1115 "Setting timeout for %p to %u sec.\n", sc, to);
1099#endif 1116#endif
1100 return sc; 1117 return sc;
1101
1102/* Error condition */
1103 error:
1104 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1105 "Invalid connection request\n");
1106 return NULL;
1107} 1118}
1108 1119
1109 1120
@@ -2692,6 +2703,10 @@ server_configure_plugin (struct HTTP_Server_Plugin *plugin)
2692 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 2703 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
2693 _("Maximum number of connections is %u\n"), 2704 _("Maximum number of connections is %u\n"),
2694 plugin->max_connections); 2705 plugin->max_connections);
2706
2707
2708 plugin->peer_id_length = strlen (GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey));
2709
2695 return GNUNET_OK; 2710 return GNUNET_OK;
2696} 2711}
2697 2712