#include "wrapping_integers.hh" // Dummy implementation of a 32-bit wrapping integer // For Lab 2, please replace with a real implementation that passes the // automated checks run by `make check_lab2`. template void DUMMY_CODE(Targs &&.../* unused */) {} using namespace std; //! Transform an "absolute" 64-bit sequence number (zero-indexed) into a WrappingInt32 //! \param n The input absolute 64-bit sequence number //! \param isn The initial sequence number WrappingInt32 wrap(uint64_t n, WrappingInt32 isn) { uint32_t result = static_cast(n) + isn.raw_value(); return WrappingInt32{result}; } //! Transform a WrappingInt32 into an "absolute" 64-bit sequence number (zero-indexed) //! \param n The relative sequence number //! \param isn The initial sequence number //! \param checkpoint A recent absolute 64-bit sequence number //! \returns the 64-bit sequence number that wraps to `n` and is closest to `checkpoint` //! //! \note Each of the two streams of the TCP connection has its own ISN. One stream //! runs from the local TCPSender to the remote TCPReceiver and has one ISN, //! and the other stream runs from the remote TCPSender to the local TCPReceiver and //! has a different ISN. #define MODULO (1UL << 32) uint64_t unwrap(WrappingInt32 n, WrappingInt32 isn, uint64_t checkpoint) { // well, really ulgy impl // have to make sure that no overflow happens uint64_t tmp = static_cast(n.raw_value() - isn.raw_value()); tmp += (checkpoint >> 32) << 32; if (tmp > checkpoint) { if (tmp < MODULO || tmp - checkpoint < checkpoint - (tmp - MODULO)) { return tmp; } else { return tmp - MODULO; } } else { if (checkpoint - tmp < tmp + MODULO - checkpoint) { return tmp; } else { return tmp + MODULO; } } // actually, here is a tricky edge case: // what if two possible unwraps have the same distance to checkpoint? // For example, when n=2^16,isn=0,checkpoint=2^32 // I thought about this, and came up with a possible solution: // Mathematically, it is a problem, but in TCP's case, it is okay in that // it is impossible that window size reaches 2^16. }