congestvpn/VpnPacket.hpp

84 lines
2.8 KiB
C++

#pragma once
/** A packet to be transmitted or received over the VPN socket */
#include <cstdlib>
#include <memory>
#include "ip_header.hpp"
/** VPN packet layout:
*
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | 1B | 1B | 1B | 1B | 1B | 1B | 1B | 1B |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Sequence number [4B] | Sending timestamp (μs) [4B] |
* +---------------------------------------------------------------+
* | Nested packet (payload) |
* +---------------------------------------------------------------+
*/
class VpnPeer;
class VpnPacket {
public:
static const size_t VPN_HEADER_BYTES;
VpnPacket(size_t mtu);
~VpnPacket();
/// Set packet peer -- used for sequence numbers
void set_peer(std::shared_ptr<VpnPeer> peer) { _peer = peer; }
/// Try to parse the packet as IPv6, return `false` upon failure.
bool parse_as_ipv6();
bool ipv6_parsed() const { return _ipv6_parsed; }
const IPv6Header& get_ipv6_header() const { return _ipv6_header; }
const char* get_payload() const { return _data + VPN_HEADER_BYTES; }
char* get_payload() { return _data + VPN_HEADER_BYTES; }
size_t get_payload_space() const {
return _data_space - VPN_HEADER_BYTES; }
size_t get_payload_size() const {
return _data_size - VPN_HEADER_BYTES; }
void set_payload_size(size_t payload_size) {
_data_size = payload_size + VPN_HEADER_BYTES; }
const char* get_data() const { return _data; }
char* get_data() { return _data; }
size_t get_data_space() const { return _data_space; }
size_t get_data_size() const { return _data_size; }
void set_data_size(size_t data_size) { _data_size = data_size; }
uint32_t get_seqno() const;
uint32_t get_sending_timestamp() const;
uint32_t get_reception_timestamp() const { return _reception_timestamp; }
/** Fill the headers of the packet. This method must be called as close
* to the time the packet is actually sent as possible, as it handles
* timestamps. */
void prepare_for_sending();
/** Do what must be done at reception, eg. keep the reception
* timestamp. This method must be called as close to the time the
* packet is actually received as possible, as it handles timestamps.
*/
void upon_reception();
private: // methods
inline uint32_t next_seqno();
private:
std::shared_ptr<VpnPeer> _peer;
char* _data;
size_t _data_space, _data_size;
bool _ipv6_parsed;
IPv6Header _ipv6_header;
uint32_t _reception_timestamp;
static uint32_t _next_general_seqno;
};