aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_wlan.c
diff options
context:
space:
mode:
authorDavid Brodski <david@brodski.eu>2011-01-23 17:15:21 +0000
committerDavid Brodski <david@brodski.eu>2011-01-23 17:15:21 +0000
commit529055038874c97055e554f83b2fcd8f4f7f0dab (patch)
tree1fef67e4f36d7bc8045badb438682acdfed9ba10 /src/transport/plugin_transport_wlan.c
parent7fc649b003d105b2fbc31aa7a4d10a60c6d64cfe (diff)
downloadgnunet-529055038874c97055e554f83b2fcd8f4f7f0dab.tar.gz
gnunet-529055038874c97055e554f83b2fcd8f4f7f0dab.zip
Some errors fixed, most of them where buffer-position errors.
Diffstat (limited to 'src/transport/plugin_transport_wlan.c')
-rw-r--r--src/transport/plugin_transport_wlan.c346
1 files changed, 231 insertions, 115 deletions
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index 9f91cbfb6..e8d4d11c5 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -206,6 +206,14 @@ struct Plugin
206 206
207}; 207};
208 208
209struct Finish_send
210{
211 struct Plugin * plugin;
212 char * msgheader;
213 struct GNUNET_MessageHeader * msgstart;
214 ssize_t size;
215};
216
209/** 217/**
210 * Queue of sessions, for the general session queue and the pending session queue 218 * Queue of sessions, for the general session queue and the pending session queue
211 */ 219 */
@@ -555,6 +563,9 @@ wlan_process_helper (void *cls,
555 void *client, 563 void *client,
556 const struct GNUNET_MessageHeader *hdr); 564 const struct GNUNET_MessageHeader *hdr);
557 565
566static void
567finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
568
558/** 569/**
559 * get the next message number, at the moment just a random one 570 * get the next message number, at the moment just a random one
560 * @return returns the next valid message-number for sending packets 571 * @return returns the next valid message-number for sending packets
@@ -562,7 +573,7 @@ wlan_process_helper (void *cls,
562uint32_t 573uint32_t
563get_next_message_id() 574get_next_message_id()
564{ 575{
565 return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); 576 return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
566} 577}
567 578
568/** 579/**
@@ -1006,14 +1017,14 @@ check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){
1006} 1017}
1007 1018
1008/** 1019/**
1009 * Function called to when wlan helper is ready to get some data 1020 * Function called when wlan helper is ready to get some data
1010 * 1021 *
1011 * @param cls closure 1022 * @param cls closure
1012 * @param tc GNUNET_SCHEDULER_TaskContext 1023 * @param tc GNUNET_SCHEDULER_TaskContext
1013 */ 1024 */
1014 1025
1015static void 1026static void
1016do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1027do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1017{ 1028{
1018 1029
1019 struct Plugin * plugin = cls; 1030 struct Plugin * plugin = cls;
@@ -1032,6 +1043,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1032 struct GNUNET_MessageHeader * msgheader2 = NULL; 1043 struct GNUNET_MessageHeader * msgheader2 = NULL;
1033 struct FragmentationHeader fragheader; 1044 struct FragmentationHeader fragheader;
1034 struct FragmentationHeader * fragheaderptr = NULL; 1045 struct FragmentationHeader * fragheaderptr = NULL;
1046 struct Finish_send * finish = NULL;
1035 uint16_t size = 0; 1047 uint16_t size = 0;
1036 const char * copystart = NULL; 1048 const char * copystart = NULL;
1037 uint16_t copysize = 0; 1049 uint16_t copysize = 0;
@@ -1060,159 +1072,261 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1060 getWlanHeader(ieeewlanheader); 1072 getWlanHeader(ieeewlanheader);
1061 1073
1062 msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1]; 1074 msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1];
1063 msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello)) + sizeof(struct GNUNET_MessageHeader)); 1075 msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello))
1076 + sizeof(struct GNUNET_MessageHeader));
1064 msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); 1077 msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);
1065 1078
1066 memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size( 1079 memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size(
1067 *(plugin->env->our_hello))); 1080 *(plugin->env->our_hello)));
1068 1081
1069
1070 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, 1082 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader,
1071 size); 1083 size);
1084 if (bytes == GNUNET_SYSERR)
1085 {
1086 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1087 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1088 errno, strerror(errno));
1089
1090 }
1091 GNUNET_assert(bytes != GNUNET_SYSERR);
1072 GNUNET_assert(bytes == size); 1092 GNUNET_assert(bytes == size);
1073 1093
1094 GNUNET_free(msgheader);
1095
1074 set_next_beacon_time(plugin); 1096 set_next_beacon_time(plugin);
1075 check_next_fragment_timeout(plugin); 1097 check_next_fragment_timeout(plugin);
1098
1076 return; 1099 return;
1077 1100
1078 } 1101 }
1079 1102
1080
1081 fm = plugin->pending_Fragment_Messages_head; 1103 fm = plugin->pending_Fragment_Messages_head;
1082 GNUNET_assert(fm != NULL); 1104 GNUNET_assert(fm != NULL);
1083 session = fm->session; 1105 session = fm->session;
1084 GNUNET_assert(session != NULL); 1106 GNUNET_assert(session != NULL);
1085 1107
1086 // test if message timed out 1108 // test if message timed out
1087 if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0){ 1109 if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0)
1088 free_acks(fm); 1110 {
1089 GNUNET_assert(plugin->pending_fragment_messages > 0); 1111 free_acks(fm);
1090 plugin->pending_fragment_messages --; 1112 GNUNET_assert(plugin->pending_fragment_messages > 0);
1091 GNUNET_CONTAINER_DLL_remove(plugin->pending_Fragment_Messages_head, 1113 plugin->pending_fragment_messages--;
1092 plugin->pending_Fragment_Messages_tail, fm); 1114 GNUNET_CONTAINER_DLL_remove(plugin->pending_Fragment_Messages_head,
1115 plugin->pending_Fragment_Messages_tail, fm);
1093 1116
1094 GNUNET_free(fm->msg); 1117 GNUNET_free(fm->msg);
1095 1118
1096 GNUNET_free(fm); 1119 GNUNET_free(fm);
1097 check_fragment_queue(plugin); 1120 check_fragment_queue(plugin);
1098 } else { 1121 }
1122 else
1123 {
1099 1124
1100 if (fm->message_size > WLAN_MTU) { 1125 if (fm->message_size > WLAN_MTU)
1101 size += sizeof(struct FragmentationHeader); 1126 {
1102 // check/set for retransmission 1127 size += sizeof(struct FragmentationHeader);
1103 if (GNUNET_TIME_absolute_get_duration(fm->next_ack).rel_value == 0) { 1128 // check/set for retransmission
1129 if (GNUNET_TIME_absolute_get_duration(fm->next_ack).rel_value == 0)
1130 {
1104 1131
1105 // be positive and try again later :-D 1132 // be positive and try again later :-D
1106 fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(fm)); 1133 fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(
1107 // find first missing fragment 1134 fm));
1108 akt = fm->head; 1135 // find first missing fragment
1109 fm->message_pos = 0; 1136 akt = fm->head;
1137 fm->message_pos = 0;
1110 1138
1111 //test if ack 0 was already received 1139 //test if ack 0 was already received
1112 while (akt != NULL){ 1140 while (akt != NULL)
1113 //if fragment is present, take next 1141 {
1114 if (akt->fragment_num == fm->message_pos) { 1142 //if fragment is present, take next
1115 fm->message_pos ++; 1143 if (akt->fragment_num == fm->message_pos)
1116 } 1144 {
1117 //next ack is bigger then the fragment number 1145 fm->message_pos++;
1118 //in case there is something like this: (acks) 1, 2, 5, 6, ... 1146 }
1119 //and we send 3 again, the next number should be 4 1147 //next ack is bigger then the fragment number
1120 else if (akt->fragment_num > fm->message_pos) { 1148 //in case there is something like this: (acks) 1, 2, 5, 6, ...
1121 break; 1149 //and we send 3 again, the next number should be 4
1122 } 1150 else if (akt->fragment_num > fm->message_pos)
1123 1151 {
1124 akt = akt->next; 1152 break;
1153 }
1125 1154
1126 } 1155 akt = akt->next;
1127 1156
1157 }
1128 1158
1129 } 1159 }
1130 1160
1131 copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader)) * fm->message_pos; 1161 copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader))
1132 fragheader.fragment_off_or_num = htons(fm->message_pos); 1162 * fm->message_pos;
1133 fragheader.message_id = htonl(session->message_id_out); 1163 fragheader.fragment_off_or_num = htons(fm->message_pos);
1164 fragheader.message_id = htonl(session->message_id_out);
1165
1166 // start should be smaller then the packet size
1167 GNUNET_assert(copyoffset < fm->message_size);
1168 copystart = fm->msg + copyoffset;
1169
1170 //size of the fragment is either the MTU - overhead
1171 //or the missing part of the message in case this is the last fragment
1172 copysize = GNUNET_MIN(fm->message_size - copyoffset,
1173 WLAN_MTU - sizeof(struct FragmentationHeader));
1174 fragheader.header.size = htons(copysize
1175 + sizeof(struct FragmentationHeader));
1176 fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT);
1177
1178 //get the next missing fragment
1179 akt = fm->head;
1180 fm->message_pos++;
1181
1182 //test if ack was already received
1183 while (akt != NULL)
1184 {
1185 //if fragment is present, take next
1186 if (akt->fragment_num == fm->message_pos)
1187 {
1188 fm->message_pos++;
1189 }
1190 //next ack is bigger then the fragment number
1191 //in case there is something like this: (acks) 1, 2, 5, 6, ...
1192 //and we send 3 again, the next number should be 4
1193 else if (akt->fragment_num > fm->message_pos)
1194 {
1195 break;
1196 }
1134 1197
1135 // start should be smaller then the packet size 1198 akt = akt->next;
1136 GNUNET_assert(copyoffset < fm->message_size); 1199 }
1137 copystart = fm->msg + copyoffset; 1200 }
1201 else
1202 {
1203 // there is no need to split
1204 copystart = fm->msg;
1205 copysize = fm->message_size;
1206 }
1138 1207
1139 //size of the fragment is either the MTU - overhead 1208 size += copysize;
1140 //or the missing part of the message in case this is the last fragment 1209 size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader)
1141 copysize = GNUNET_MIN(fm->message_size - copyoffset, 1210 + sizeof(struct GNUNET_MessageHeader);
1142 WLAN_MTU - sizeof(struct FragmentationHeader)); 1211 msgheader = GNUNET_malloc(size);
1143 fragheader.header.size = htons(copysize + sizeof(struct FragmentationHeader)); 1212 msgheader->size = htons(size);
1144 fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); 1213 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1145 1214
1215 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1216 getRadiotapHeader(radioHeader);
1146 1217
1147 //get the next missing fragment 1218 ieeewlanheader = (struct IeeeHeader *) &radioHeader[1];
1148 akt = fm->head; 1219 getWlanHeader(ieeewlanheader);
1149 fm->message_pos ++;
1150 1220
1151 //test if ack was already received 1221 //could be faster if content is just send and not copyed before
1152 while (akt != NULL){ 1222 //fragmentheader is needed
1153 //if fragment is present, take next 1223 if (fm->message_size > WLAN_MTU)
1154 if (akt->fragment_num == fm->message_pos) { 1224 {
1155 fm->message_pos ++; 1225 fragheader.message_crc = htons(getcrc16(copystart, copysize));
1156 } 1226 memcpy(&ieeewlanheader[1], &fragheader,
1157 //next ack is bigger then the fragment number 1227 sizeof(struct FragmentationHeader));
1158 //in case there is something like this: (acks) 1, 2, 5, 6, ... 1228 fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1];
1159 //and we send 3 again, the next number should be 4 1229 memcpy(&fragheaderptr[1], copystart, copysize);
1160 else if (akt->fragment_num > fm->message_pos) { 1230 }
1161 break; 1231 else
1162 } 1232 {
1233 memcpy(&ieeewlanheader[1], copystart, copysize);
1234 }
1163 1235
1164 akt = akt->next; 1236 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size);
1165 } 1237 if (bytes == GNUNET_SYSERR){
1166 } else { 1238 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1167 // there is no need to split 1239 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), errno, strerror(errno) );
1168 copystart = fm->msg;
1169 copysize = fm->message_size;
1170 }
1171
1172 size += copysize;
1173 size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader)
1174 + sizeof(struct GNUNET_MessageHeader);
1175 msgheader = GNUNET_malloc(size);
1176 msgheader->size = htons(size);
1177 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1178
1179 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1180 getRadiotapHeader(radioHeader);
1181
1182 ieeewlanheader = (struct IeeeHeader *) &radioHeader[1];
1183 getWlanHeader(ieeewlanheader);
1184
1185
1186 //could be faster if content is just send and not copyed before
1187 //fragmentheader is needed
1188 if (fm->message_size > WLAN_MTU){
1189 fragheader.message_crc = htons(getcrc16(copystart, copysize));
1190 memcpy(&ieeewlanheader[1],&fragheader, sizeof(struct FragmentationHeader));
1191 fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1];
1192 memcpy(&fragheaderptr[1],copystart,copysize);
1193 } else {
1194 memcpy(&ieeewlanheader[1],copystart,copysize);
1195 }
1196 1240
1197 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); 1241 }
1198 GNUNET_assert(bytes == size); 1242 GNUNET_assert(bytes != GNUNET_SYSERR);
1199 1243
1200 //check if this was the last fragment of this message, if true then queue at the end of the list 1244 if (bytes != size)
1201 if (copysize + copyoffset >= fm->message_size){ 1245 {
1202 GNUNET_assert(copysize + copyoffset == fm->message_size); 1246 finish = GNUNET_malloc(sizeof( struct Finish_send));
1247 finish->plugin = plugin;
1248 finish->msgheader = (char * ) msgheader + bytes;
1249 finish->size = size - bytes;
1250 finish->msgstart = msgheader;
1203 1251
1204 GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head, 1252 GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1205 plugin->pending_Fragment_Messages_tail, fm);
1206 1253
1207 GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Fragment_Messages_head, 1254 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
1208 plugin->pending_Fragment_Messages_tail, fm); 1255 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
1209 // if fragments have opimized timeouts 1256 &finish_sending, finish);
1210 //sort_fragment_into_queue(plugin,fm);
1211 1257
1212 } 1258 }
1213 check_next_fragment_timeout(plugin); 1259 else
1260 {
1261 GNUNET_assert(bytes == size);
1262
1263 GNUNET_free(msgheader);
1264 check_next_fragment_timeout(plugin);
1265 }
1266
1267 //check if this was the last fragment of this message, if true then queue at the end of the list
1268 if (copysize + copyoffset >= fm->message_size)
1269 {
1270 GNUNET_assert(copysize + copyoffset == fm->message_size);
1271
1272 GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head,
1273 plugin->pending_Fragment_Messages_tail, fm);
1274
1275 GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Fragment_Messages_head,
1276 plugin->pending_Fragment_Messages_tail, fm);
1277 // if fragments have opimized timeouts
1278 //sort_fragment_into_queue(plugin,fm);
1279
1280 }
1281
1282 }
1283}
1284
1285
1286static void
1287finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1288{
1289 struct Finish_send * finish;
1290 struct Plugin * plugin;
1291 ssize_t bytes;
1292
1293 finish = cls;
1294 plugin = finish->plugin;
1295
1296 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1297
1298 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, finish->msgheader, finish->size);
1299 GNUNET_assert(bytes != GNUNET_SYSERR);
1300
1301 GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1302 if (bytes != finish->size)
1303 {
1304
1305 finish->plugin = plugin;
1306 finish->msgheader = finish->msgheader + bytes;
1307 finish->size = finish->size - bytes;
1308 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
1309 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
1310 &finish_sending, finish);
1311 }
1312 else
1313 {
1314 GNUNET_free(finish->msgstart);
1315 GNUNET_free(finish);
1316 check_next_fragment_timeout(plugin);
1317 }
1214 1318
1215 } 1319}
1320
1321int
1322getRadiotapHeader(struct RadiotapHeader * Header){
1323 return GNUNET_YES;
1324};
1325
1326int
1327getWlanHeader(struct IeeeHeader * Header){
1328
1329 return GNUNET_YES;
1216} 1330}
1217 1331
1218 1332
@@ -1746,7 +1860,7 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h
1746 session_light->session = search_session(plugin, session_light->addr); 1860 session_light->session = search_session(plugin, session_light->addr);
1747 } 1861 }
1748 session = session_light->session; 1862 session = session_light->session;
1749 wlanheader = (struct WlanHeader *) &hdr[1]; 1863 wlanheader = (struct WlanHeader *) &hdr;
1750 tempmsg = (char*) &wlanheader[1]; 1864 tempmsg = (char*) &wlanheader[1];
1751 temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; 1865 temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1];
1752 1866
@@ -2149,6 +2263,8 @@ wlan_transport_start_wlan_helper(struct Plugin *plugin, int testmode)
2149 "Adding server_read_task for the wlan-helper\n"); 2263 "Adding server_read_task for the wlan-helper\n");
2150#endif 2264#endif
2151 2265
2266 sleep(2);
2267
2152 plugin->server_read_task = GNUNET_SCHEDULER_add_read_file( 2268 plugin->server_read_task = GNUNET_SCHEDULER_add_read_file(
2153 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle, 2269 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle,
2154 &wlan_plugin_helper_read, plugin); 2270 &wlan_plugin_helper_read, plugin);