Commit 58b27aeb authored by atj's avatar atj
Browse files

Add crc32 checking to make sure file didn't get borked.

parent da48b501
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <boost/archive/text_oarchive.hpp>
#include "Builder.h"
#include <boost/progress.hpp>
#include <boost/crc.hpp>
#include <memory.h>

namespace asio = boost::asio;
@@ -98,6 +99,7 @@ public:
        auto bytes_remaining = total_size;
        std::vector<char> buffer_storage(chunk_size);
        auto buffer = asio::buffer(buffer_storage);
        boost::crc_32_type csc_result;

        do {
            auto bytes_to_receive = std::min(bytes_remaining, chunk_size);
@@ -106,6 +108,8 @@ public:

            file.write(buffer_storage.data(), bytes_received);

            csc_result.process_bytes(buffer_storage.data(), bytes_received);

            bytes_remaining -= bytes_received;

            if(print_progress) {
@@ -114,6 +118,17 @@ public:

        } while (bytes_remaining);

        // After we've read the file we read the checksum and throw if they do not match
        auto checksum = csc_result.checksum();
        auto checksum_size = sizeof(boost::crc_32_type::value_type);

        boost::crc_32_type::value_type sent_checksum;
        asio::async_read(socket, asio::buffer(&sent_checksum, checksum_size), asio::transfer_exactly(checksum_size), handler);

        if(checksum != sent_checksum) {
            throw std::runtime_error("Error, file checksums do not match");
        }

        file.close();
    }

@@ -185,11 +200,14 @@ public:
        auto bytes_remaining = file_size;
        std::vector<char> buffer_storage(chunk_size);
        auto buffer = asio::buffer(buffer_storage);
        boost::crc_32_type csc_result;
        do {
            auto bytes_to_send = std::min(bytes_remaining, chunk_size);

            file.read(buffer_storage.data(), bytes_to_send);

            csc_result.process_bytes(buffer_storage.data(), bytes_to_send);

            auto bytes_sent = asio::async_write(socket, buffer, asio::transfer_exactly(bytes_to_send), handler);

            bytes_remaining -= bytes_sent;
@@ -200,6 +218,12 @@ public:
        } while (bytes_remaining);

        file.close();

        // After we've sent the file we send the checksum
        // This would make more logical sense in the header but would require us to traverse a potentialy large file twice
        auto checksum = csc_result.checksum();
        auto checksum_size = sizeof(boost::crc_32_type::value_type);
        asio::async_write(socket, asio::buffer(&checksum, checksum_size), asio::transfer_exactly(checksum_size), handler);
    }

    template <typename Handler>
+24 −0
Original line number Diff line number Diff line
@@ -72,17 +72,27 @@ void Messenger::send_file(boost::filesystem::path file_path) {
    auto bytes_remaining = file_size;
    std::vector<char> buffer_storage(chunk_size);
    auto buffer = asio::buffer(buffer_storage);
    boost::crc_32_type csc_result;

    do {
        auto bytes_to_send = std::min(bytes_remaining, chunk_size);

        file.read(buffer_storage.data(), bytes_to_send);

        csc_result.process_bytes(buffer_storage.data(), bytes_to_send);

        auto bytes_sent = asio::write(socket, buffer, asio::transfer_exactly(bytes_to_send));

        bytes_remaining -= bytes_sent;
    } while (bytes_remaining);

    file.close();

    // After we've sent the file we send the checksum
    // This would make more logical sense in the header but would require us to traverse a potentialy large file twice
    auto checksum = csc_result.checksum();
    auto checksum_size = sizeof(boost::crc_32_type::value_type);
    asio::write(socket, asio::buffer(&checksum, checksum_size), asio::transfer_exactly(checksum_size));
}

// Receive a string message
@@ -121,6 +131,7 @@ void Messenger::receive_file(boost::filesystem::path file_path) {
    auto bytes_remaining = total_size;
    std::vector<char> buffer_storage(chunk_size);
    auto buffer = asio::buffer(buffer_storage);
    boost::crc_32_type csc_result;

    do {
        auto bytes_to_receive = std::min(bytes_remaining, chunk_size);
@@ -129,11 +140,24 @@ void Messenger::receive_file(boost::filesystem::path file_path) {

        file.write(buffer_storage.data(), bytes_received);

        csc_result.process_bytes(buffer_storage.data(), bytes_received);

        bytes_remaining -= bytes_received;

    } while (bytes_remaining);

    file.close();

    // After we've read the file we read the checksum and throw if they do not match
    auto checksum = csc_result.checksum();
    auto checksum_size = sizeof(boost::crc_32_type::value_type);

    boost::crc_32_type::value_type sent_checksum;
    asio::read(socket, asio::buffer(&sent_checksum, checksum_size), asio::transfer_exactly(checksum_size));

    if(checksum != sent_checksum) {
        throw std::runtime_error("Error, file checksums do not match");
    }
}

Builder Messenger::receive_builder() {