diff options
author | irungentoo <irungentoo@gmail.com> | 2015-03-13 12:40:21 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2015-03-13 12:40:21 -0400 |
commit | 669975c226a385c1d0ffee8384abd776c7962d53 (patch) | |
tree | 52aee018d871fb87118c59c89d94e1509899c821 | |
parent | eec1042695378c8e7fa2dc02970c79b9caddcf3d (diff) |
tox_file_send_chunk() must now send data the same length as requested
in the requested chunk callback.
For zero size transfers if the data sent is not the same length, the
file is assumed to be done.
-rw-r--r-- | toxcore/Messenger.c | 44 | ||||
-rw-r--r-- | toxcore/Messenger.h | 2 | ||||
-rw-r--r-- | toxcore/tox.c | 2 | ||||
-rw-r--r-- | toxcore/tox.h | 23 |
4 files changed, 44 insertions, 27 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 2914cf36..607630b6 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -1196,6 +1196,28 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber, | |||
1196 | return 0; | 1196 | return 0; |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | /* return packet number on success. | ||
1200 | * return -1 on failure. | ||
1201 | */ | ||
1202 | static int64_t send_file_data_packet(const Messenger *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, | ||
1203 | uint16_t length) | ||
1204 | { | ||
1205 | if (friend_not_valid(m, friendnumber)) | ||
1206 | return -1; | ||
1207 | |||
1208 | uint8_t packet[2 + length]; | ||
1209 | packet[0] = PACKET_ID_FILE_DATA; | ||
1210 | packet[1] = filenumber; | ||
1211 | |||
1212 | if (length) { | ||
1213 | memcpy(packet + 2, data, length); | ||
1214 | } | ||
1215 | |||
1216 | return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, | ||
1217 | m->friendlist[friendnumber].friendcon_id), packet, sizeof(packet), 1); | ||
1218 | } | ||
1219 | |||
1220 | #define MAX_FILE_DATA_SIZE (MAX_CRYPTO_DATA_SIZE - 2) | ||
1199 | #define MIN_SLOTS_FREE (CRYPTO_MIN_QUEUE_LENGTH / 4) | 1221 | #define MIN_SLOTS_FREE (CRYPTO_MIN_QUEUE_LENGTH / 4) |
1200 | /* Send file data. | 1222 | /* Send file data. |
1201 | * | 1223 | * |
@@ -1204,7 +1226,7 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber, | |||
1204 | * return -2 if friend not online. | 1226 | * return -2 if friend not online. |
1205 | * return -3 if filenumber invalid. | 1227 | * return -3 if filenumber invalid. |
1206 | * return -4 if file transfer not transferring. | 1228 | * return -4 if file transfer not transferring. |
1207 | * return -5 if trying to send too much data. | 1229 | * return -5 if bad data size. |
1208 | * return -6 if packet queue full. | 1230 | * return -6 if packet queue full. |
1209 | * return -7 if wrong position. | 1231 | * return -7 if wrong position. |
1210 | */ | 1232 | */ |
@@ -1228,13 +1250,17 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin | |||
1228 | if (ft->paused != FILE_PAUSE_NOT) | 1250 | if (ft->paused != FILE_PAUSE_NOT) |
1229 | return -4; | 1251 | return -4; |
1230 | 1252 | ||
1231 | if (length > MAX_CRYPTO_DATA_SIZE - 2) | 1253 | if (length > MAX_FILE_DATA_SIZE) |
1232 | return -5; | 1254 | return -5; |
1233 | 1255 | ||
1234 | if (ft->size) { | 1256 | if (ft->size) { |
1235 | if (ft->size - ft->transferred < length) { | 1257 | if (ft->size - ft->transferred < length) { |
1236 | return -5; | 1258 | return -5; |
1237 | } | 1259 | } |
1260 | |||
1261 | if (length != MAX_FILE_DATA_SIZE && (ft->transferred + length) != ft->size) { | ||
1262 | return -5; | ||
1263 | } | ||
1238 | } | 1264 | } |
1239 | 1265 | ||
1240 | if (position != ft->transferred) { | 1266 | if (position != ft->transferred) { |
@@ -1246,13 +1272,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin | |||
1246 | m->friendlist[friendnumber].friendcon_id)) < MIN_SLOTS_FREE) | 1272 | m->friendlist[friendnumber].friendcon_id)) < MIN_SLOTS_FREE) |
1247 | return -6; | 1273 | return -6; |
1248 | 1274 | ||
1249 | uint8_t packet[2 + length]; | 1275 | int64_t ret = send_file_data_packet(m, friendnumber, filenumber, data, length); |
1250 | packet[0] = PACKET_ID_FILE_DATA; | ||
1251 | packet[1] = filenumber; | ||
1252 | memcpy(packet + 2, data, length); | ||
1253 | |||
1254 | int64_t ret = write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, | ||
1255 | m->friendlist[friendnumber].friendcon_id), packet, sizeof(packet), 1); | ||
1256 | 1276 | ||
1257 | if (ret != -1) { | 1277 | if (ret != -1) { |
1258 | //TODO record packet ids to check if other received complete file. | 1278 | //TODO record packet ids to check if other received complete file. |
@@ -1262,7 +1282,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin | |||
1262 | --ft->slots_allocated; | 1282 | --ft->slots_allocated; |
1263 | } | 1283 | } |
1264 | 1284 | ||
1265 | if (length == 0 || ft->size == ft->transferred) { | 1285 | if (length != MAX_FILE_DATA_SIZE || ft->size == ft->transferred) { |
1266 | ft->status = FILESTATUS_FINISHED; | 1286 | ft->status = FILESTATUS_FINISHED; |
1267 | ft->last_packet_number = ret; | 1287 | ft->last_packet_number = ret; |
1268 | } | 1288 | } |
@@ -1346,7 +1366,7 @@ static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber) | |||
1346 | if (free_slots == 0) | 1366 | if (free_slots == 0) |
1347 | break; | 1367 | break; |
1348 | 1368 | ||
1349 | uint16_t length = MAX_CRYPTO_DATA_SIZE - 2; | 1369 | uint16_t length = MAX_FILE_DATA_SIZE; |
1350 | 1370 | ||
1351 | if (ft->size) { | 1371 | if (ft->size) { |
1352 | if (ft->size == ft->requested) { | 1372 | if (ft->size == ft->requested) { |
@@ -1980,7 +2000,7 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
1980 | 2000 | ||
1981 | ft->transferred += file_data_length; | 2001 | ft->transferred += file_data_length; |
1982 | 2002 | ||
1983 | if (ft->size && ft->transferred >= ft->size) { | 2003 | if ((ft->size && ft->transferred >= ft->size) || file_data_length != MAX_FILE_DATA_SIZE) { |
1984 | file_data_length = 0; | 2004 | file_data_length = 0; |
1985 | file_data = NULL; | 2005 | file_data = NULL; |
1986 | position = ft->transferred; | 2006 | position = ft->transferred; |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 0cbef76d..5dec83df 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -637,7 +637,7 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber, | |||
637 | * return -2 if friend not online. | 637 | * return -2 if friend not online. |
638 | * return -3 if filenumber invalid. | 638 | * return -3 if filenumber invalid. |
639 | * return -4 if file transfer not transferring. | 639 | * return -4 if file transfer not transferring. |
640 | * return -5 if trying to send too much data. | 640 | * return -5 if bad data size. |
641 | * return -6 if packet queue full. | 641 | * return -6 if packet queue full. |
642 | * return -7 if wrong position. | 642 | * return -7 if wrong position. |
643 | */ | 643 | */ |
diff --git a/toxcore/tox.c b/toxcore/tox.c index c527ce96..5dfac2c8 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -960,7 +960,7 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, | |||
960 | return 0; | 960 | return 0; |
961 | 961 | ||
962 | case -5: | 962 | case -5: |
963 | SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_TOO_LARGE); | 963 | SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH); |
964 | return 0; | 964 | return 0; |
965 | 965 | ||
966 | case -6: | 966 | case -6: |
diff --git a/toxcore/tox.h b/toxcore/tox.h index d23065ff..eb6b4f31 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -1645,11 +1645,11 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK { | |||
1645 | */ | 1645 | */ |
1646 | TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING, | 1646 | TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING, |
1647 | /** | 1647 | /** |
1648 | * Attempted to send more data than requested. The requested data size is | 1648 | * Attempted to send more or less data than requested. The requested data size is |
1649 | * adjusted according to maximum transmission unit and the expected end of | 1649 | * adjusted according to maximum transmission unit and the expected end of |
1650 | * the file. Trying to send more will result in no data being sent. | 1650 | * the file. Trying to send less or more than requested will return this error. |
1651 | */ | 1651 | */ |
1652 | TOX_ERR_FILE_SEND_CHUNK_TOO_LARGE, | 1652 | TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH, |
1653 | /** | 1653 | /** |
1654 | * Packet queue is full. | 1654 | * Packet queue is full. |
1655 | */ | 1655 | */ |
@@ -1664,12 +1664,12 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK { | |||
1664 | * Send a chunk of file data to a friend. | 1664 | * Send a chunk of file data to a friend. |
1665 | * | 1665 | * |
1666 | * This function is called in response to the `file_request_chunk` callback. The | 1666 | * This function is called in response to the `file_request_chunk` callback. The |
1667 | * length parameter should be equal to or less than the one received though the | 1667 | * length parameter should be equal to the one received though the callback. |
1668 | * callback. If it is zero, the transfer is assumed complete. For files with | 1668 | * If it is zero, the transfer is assumed complete. For files with known size, |
1669 | * known size, Core will know that the transfer is complete after the last byte | 1669 | * Core will know that the transfer is complete after the last byte has been |
1670 | * has been received, so it is not necessary (though not harmful) to send a | 1670 | * received, so it is not necessary (though not harmful) to send a zero-length |
1671 | * zero-length chunk to terminate. For streams, it is necessary for the last | 1671 | * chunk to terminate. For streams, core will know that the transfer is finished |
1672 | * chunk sent to be zero-length. | 1672 | * if a chunk with length less than the length requested in the callback is sent. |
1673 | * | 1673 | * |
1674 | * @return true on success. | 1674 | * @return true on success. |
1675 | */ | 1675 | */ |
@@ -1694,10 +1694,7 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, | |||
1694 | * In response to receiving this callback, the client should call the function | 1694 | * In response to receiving this callback, the client should call the function |
1695 | * `tox_file_send_chunk` with the requested chunk. If the number of bytes sent | 1695 | * `tox_file_send_chunk` with the requested chunk. If the number of bytes sent |
1696 | * through that function is zero, the file transfer is assumed complete. A | 1696 | * through that function is zero, the file transfer is assumed complete. A |
1697 | * client may choose to send less than requested, if it is reading from a | 1697 | * client must send the full length of data requested with this callback. |
1698 | * stream that doesn't have more data, yet, and it still wants to send some | ||
1699 | * data to the other side. However, this will generally be less efficient than | ||
1700 | * waiting for a full chunk size of data to be ready. | ||
1701 | * | 1698 | * |
1702 | * @param friend_number The friend number of the receiving friend for this file. | 1699 | * @param friend_number The friend number of the receiving friend for this file. |
1703 | * @param file_number The file transfer identifier returned by tox_file_send. | 1700 | * @param file_number The file transfer identifier returned by tox_file_send. |