congestvpn/VpnPacket.hpp

84 lines
2.8 KiB
C++
Raw Normal View History

2020-06-05 17:30:35 +02:00
#pragma once
/** A packet to be transmitted or received over the VPN socket */
#include <cstdlib>
2020-06-10 18:49:36 +02:00
#include <memory>
2020-06-05 17:30:35 +02:00
#include "ip_header.hpp"
2020-06-10 18:49:36 +02:00
/** VPN packet layout:
*
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | 1B | 1B | 1B | 1B | 1B | 1B | 1B | 1B |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Sequence number [4B] | Sending timestamp (μs) [4B] |
* +---------------------------------------------------------------+
* | Nested packet (payload) |
* +---------------------------------------------------------------+
*/
class VpnPeer;
2020-06-05 17:30:35 +02:00
class VpnPacket {
public:
2020-06-10 18:49:36 +02:00
static const size_t VPN_HEADER_BYTES;
2020-06-05 17:30:35 +02:00
VpnPacket(size_t mtu);
~VpnPacket();
2020-06-10 18:49:36 +02:00
/// Set packet peer -- used for sequence numbers
void set_peer(std::shared_ptr<VpnPeer> peer) { _peer = peer; }
2020-06-05 17:30:35 +02:00
/// 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; }
2020-06-10 18:49:36 +02:00
const char* get_payload() const { return _data + VPN_HEADER_BYTES; }
char* get_payload() { return _data + VPN_HEADER_BYTES; }
2020-06-05 17:30:35 +02:00
size_t get_payload_space() const {
2020-06-10 18:49:36 +02:00
return _data_space - VPN_HEADER_BYTES; }
2020-06-05 17:30:35 +02:00
size_t get_payload_size() const {
2020-06-10 18:49:36 +02:00
return _data_size - VPN_HEADER_BYTES; }
2020-06-05 17:30:35 +02:00
void set_payload_size(size_t payload_size) {
2020-06-10 18:49:36 +02:00
_data_size = payload_size + VPN_HEADER_BYTES; }
2020-06-05 17:30:35 +02:00
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; }
2020-06-10 18:49:36 +02:00
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();
2020-06-05 17:30:35 +02:00
private:
2020-06-10 18:49:36 +02:00
std::shared_ptr<VpnPeer> _peer;
2020-06-05 17:30:35 +02:00
char* _data;
size_t _data_space, _data_size;
bool _ipv6_parsed;
IPv6Header _ipv6_header;
2020-06-10 18:49:36 +02:00
uint32_t _reception_timestamp;
static uint32_t _next_general_seqno;
2020-06-05 17:30:35 +02:00
};