Set tun MTU based on VpnPacket max payload
This commit is contained in:
parent
94f42d08c0
commit
79dbf23784
5 changed files with 39 additions and 0 deletions
|
@ -72,6 +72,31 @@ TunDevice::~TunDevice() {
|
||||||
close(_fd);
|
close(_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t TunDevice::get_mtu() const {
|
||||||
|
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // Any socket will do
|
||||||
|
|
||||||
|
struct ifreq ifr;
|
||||||
|
ifr.ifr_addr.sa_family = AF_INET6;
|
||||||
|
strncpy(ifr.ifr_name, _dev_name.c_str(), sizeof(ifr.ifr_name)-1);
|
||||||
|
if (ioctl(sockfd, SIOCGIFMTU, (caddr_t)&ifr) < 0)
|
||||||
|
return 0;
|
||||||
|
close(sockfd);
|
||||||
|
return ifr.ifr_mtu;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TunDevice::set_mtu(uint16_t mtu) {
|
||||||
|
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // Any socket will do
|
||||||
|
|
||||||
|
struct ifreq ifr;
|
||||||
|
ifr.ifr_addr.sa_family = AF_INET6;
|
||||||
|
strncpy(ifr.ifr_name, _dev_name.c_str(), sizeof(ifr.ifr_name)-1);
|
||||||
|
ifr.ifr_mtu = mtu;
|
||||||
|
if (ioctl(sockfd, SIOCSIFMTU, (caddr_t)&ifr) < 0)
|
||||||
|
return false;
|
||||||
|
close(sockfd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
size_t TunDevice::poll_packet(char* read_buffer, size_t buf_size, int timeout) {
|
size_t TunDevice::poll_packet(char* read_buffer, size_t buf_size, int timeout) {
|
||||||
int poll_rc = poll(&_poll_fd, 1, timeout);
|
int poll_rc = poll(&_poll_fd, 1, timeout);
|
||||||
if(poll_rc < 0) {
|
if(poll_rc < 0) {
|
||||||
|
|
|
@ -29,6 +29,12 @@ class TunDevice {
|
||||||
const std::string& get_dev_name() const { return _dev_name; }
|
const std::string& get_dev_name() const { return _dev_name; }
|
||||||
int get_fd() const { return _fd; }
|
int get_fd() const { return _fd; }
|
||||||
|
|
||||||
|
/** Get the interface's MTU */
|
||||||
|
uint16_t get_mtu() const;
|
||||||
|
|
||||||
|
/** Set the interface's MTU */
|
||||||
|
bool set_mtu(uint16_t mtu);
|
||||||
|
|
||||||
/* Reads a packet from the device.
|
/* Reads a packet from the device.
|
||||||
* Timeouts after `timeout` ms, or never if `timeout < 0`.
|
* Timeouts after `timeout` ms, or never if `timeout < 0`.
|
||||||
* Upon timeout, returns 0.
|
* Upon timeout, returns 0.
|
||||||
|
|
|
@ -16,6 +16,7 @@ static const size_t VPN_MTU = 1460; // TODO determine this -- issue #3
|
||||||
UdpVpn::UdpVpn()
|
UdpVpn::UdpVpn()
|
||||||
: _stopped(false), _vpn_mtu(VPN_MTU), _tun_dev("cvpn%d"), _peer(nullptr)
|
: _stopped(false), _vpn_mtu(VPN_MTU), _tun_dev("cvpn%d"), _peer(nullptr)
|
||||||
{
|
{
|
||||||
|
_tun_dev.set_mtu(VpnPacket::get_tunnelled_mtu(_vpn_mtu));
|
||||||
_socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
_socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if(_socket < 0)
|
if(_socket < 0)
|
||||||
throw UdpVpn::InitializationError("Cannot create socket", errno, true);
|
throw UdpVpn::InitializationError("Cannot create socket", errno, true);
|
||||||
|
|
|
@ -30,6 +30,10 @@ VpnPacketTLV VpnPacket::first_tlv() {
|
||||||
return VpnPacketTLV(*this, 0);
|
return VpnPacketTLV(*this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t VpnPacket::get_tunnelled_mtu(size_t udp_mtu) {
|
||||||
|
return udp_mtu - VPN_HEADER_BYTES - TLV_HEADER_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t VpnPacket::get_seqno() const {
|
uint32_t VpnPacket::get_seqno() const {
|
||||||
return *(uint32_t*)(_data + DATA_SEQNO_POS);
|
return *(uint32_t*)(_data + DATA_SEQNO_POS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,9 @@ class VpnPacket {
|
||||||
|
|
||||||
VpnPacketTLV first_tlv();
|
VpnPacketTLV first_tlv();
|
||||||
|
|
||||||
|
/// Get the maximal payload space for a given tunnel MTU
|
||||||
|
static size_t get_tunnelled_mtu(size_t udp_mtu);
|
||||||
|
|
||||||
/// Set packet peer -- used for sequence numbers
|
/// Set packet peer -- used for sequence numbers
|
||||||
void set_peer(VpnPeer* peer) { _peer = peer; }
|
void set_peer(VpnPeer* peer) { _peer = peer; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue