Remove ipzip stubs

This commit is contained in:
Ludvig Strigeus 2018-11-16 14:36:15 +01:00
parent 3ae15bcff5
commit 57642ca653
9 changed files with 70 additions and 139 deletions

View file

@ -197,7 +197,6 @@
<ClInclude Include="crypto\siphash\siphash.h" /> <ClInclude Include="crypto\siphash\siphash.h" />
<ClInclude Include="tunsafe_dnsresolve.h" /> <ClInclude Include="tunsafe_dnsresolve.h" />
<ClInclude Include="tunsafe_endian.h" /> <ClInclude Include="tunsafe_endian.h" />
<ClInclude Include="ipzip2\ipzip2.h" />
<ClInclude Include="netapi.h" /> <ClInclude Include="netapi.h" />
<ClInclude Include="network_win32_api.h" /> <ClInclude Include="network_win32_api.h" />
<ClInclude Include="network_win32_dnsblock.h" /> <ClInclude Include="network_win32_dnsblock.h" />
@ -221,7 +220,6 @@
<ClCompile Include="tunsafe_cpu.cpp" /> <ClCompile Include="tunsafe_cpu.cpp" />
<ClCompile Include="crypto\aesgcm\aesgcm.cpp" /> <ClCompile Include="crypto\aesgcm\aesgcm.cpp" />
<ClCompile Include="crypto\siphash\siphash.cpp" /> <ClCompile Include="crypto\siphash\siphash.cpp" />
<ClCompile Include="ipzip2\ipzip2.cpp" />
<ClCompile Include="network_win32_dnsblock.cpp" /> <ClCompile Include="network_win32_dnsblock.cpp" />
<ClCompile Include="tunsafe_ipaddr.cpp" /> <ClCompile Include="tunsafe_ipaddr.cpp" />
<ClCompile Include="tunsafe_threading.cpp" /> <ClCompile Include="tunsafe_threading.cpp" />

View file

@ -56,9 +56,6 @@
<ClInclude Include="netapi.h"> <ClInclude Include="netapi.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ipzip2\ipzip2.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tunsafe_types.h"> <ClInclude Include="tunsafe_types.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
@ -152,9 +149,6 @@
<ClCompile Include="wireguard_config.cpp"> <ClCompile Include="wireguard_config.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ipzip2\ipzip2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="crypto\aesgcm\aesgcm.cpp"> <ClCompile Include="crypto\aesgcm\aesgcm.cpp">
<Filter>crypto\aesgcm</Filter> <Filter>crypto\aesgcm</Filter>
</ClCompile> </ClCompile>

View file

@ -1,2 +0,0 @@
#include "stdafx.h"
// this is a placeholder for a packet compression algorithm not yet released.

View file

@ -1 +0,0 @@
// this is a placeholder for a packet compression algorithm not yet released.

View file

@ -19,7 +19,7 @@
#include "crypto/blake2s/blake2s.cpp" #include "crypto/blake2s/blake2s.cpp"
#include "crypto/siphash/siphash.cpp" #include "crypto/siphash/siphash.cpp"
#include "crypto/aesgcm/aesgcm.cpp" #include "crypto/aesgcm/aesgcm.cpp"
#include "ipzip2/ipzip2.cpp" #include "network_common.cpp"
#if defined(WITH_NETWORK_BSD) #if defined(WITH_NETWORK_BSD)
#include "network_bsd.cpp" #include "network_bsd.cpp"

View file

@ -12,7 +12,6 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "ipzip2/ipzip2.h"
#include "wireguard.h" #include "wireguard.h"
#include "wireguard_config.h" #include "wireguard_config.h"
#include "util.h" #include "util.h"
@ -104,31 +103,6 @@ void WireguardProcessor::ResetStats() {
memset(&stats_, 0, sizeof(stats_)); memset(&stats_, 0, sizeof(stats_));
} }
void WireguardProcessor::SetupCompressionHeader(WgPacketCompressionVer01 *c) {
memset(c, 0, sizeof(WgPacketCompressionVer01));
// Windows uses a ttl of 128 while other platforms use 64
#if defined(OS_WIN)
c->ttl = 128;
#else // defined(OS_WIN)
c->ttl = 64;
#endif // defined(OS_WIN)
WriteLE16(&c->version, EXT_PACKET_COMPRESSION_VER);
for (auto it = addresses_.begin(); it != addresses_.end(); ++it) {
if (it->size == 32) {
memcpy(c->ipv4_addr, it->addr, 4);
c->flags = ((it->cidr >> 3) & 3);
break;
}
}
for (auto it = addresses_.begin(); it != addresses_.end(); ++it) {
if (it->size == 128) {
memcpy(c->ipv6_addr, it->addr, 16);
break;
}
}
}
static WgCidrAddr WgCidrAddrFromIpAddr(const IpAddr &addr) { static WgCidrAddr WgCidrAddrFromIpAddr(const IpAddr &addr) {
WgCidrAddr r = {0}; WgCidrAddr r = {0};
if (addr.sin.sin_family == AF_INET) { if (addr.sin.sin_family == AF_INET) {
@ -208,8 +182,6 @@ bool WireguardProcessor::ConfigureTun() {
if (!tun_->Configure(std::move(config), &config_out)) if (!tun_->Configure(std::move(config), &config_out))
return false; return false;
SetupCompressionHeader(dev_.compression_header());
network_discovery_spoofing_ = config_out.enable_neighbor_discovery_spoofing; network_discovery_spoofing_ = config_out.enable_neighbor_discovery_spoofing;
memcpy(network_discovery_mac_, config_out.neighbor_discovery_spoofing_mac, 6); memcpy(network_discovery_mac_, config_out.neighbor_discovery_spoofing_mac, 6);
@ -438,22 +410,18 @@ void WireguardProcessor::WriteAndEncryptPacketToUdp_WillUnlock(WgPeer *peer, Pac
} else { } else {
peer->OnDataSent(); peer->OnDataSent();
#if WITH_HANDSHAKE_EXT // Attempt to compress the packet headers
// Attempt to compress the packet headers using ipzip. if (WITH_HANDSHAKE_EXT && keypair->compress_handler_) {
if (keypair->enabled_features[WG_FEATURE_ID_IPZIP]) { WgCompressHandler::CompressState st = keypair->compress_handler_->Compress(packet);
uint32 rv = IpzipCompress(data, (uint32)size, &keypair->ipzip_state_, 0); if (st == WgCompressHandler::COMPRESS_FAIL)
if (rv == (uint32)-1)
goto getout_discard; goto getout_discard;
if (rv == 0) if (st == WgCompressHandler::COMPRESS_NO)
goto add_padding; goto add_padding;
stats_.compression_hdr_saved_out += (int32)(size - rv); stats_.compression_hdr_saved_out += (int32)(size - packet->size);
data += (int32)(size - rv); data = packet->data;
size = rv; size = packet->size;
} else { } else {
add_padding: add_padding:
#else
{
#endif // WITH_HANDSHAKE_EXT
// Pad packet to a multiple of 16 bytes, but no more than the mtu bytes. // Pad packet to a multiple of 16 bytes, but no more than the mtu bytes.
unsigned padding = std::min<unsigned>((0 - size) & 15, (unsigned)mtu_ - (unsigned)size); unsigned padding = std::min<unsigned>((0 - size) & 15, (unsigned)mtu_ - (unsigned)size);
memset(data + size, 0, padding); memset(data + size, 0, padding);
@ -461,8 +429,7 @@ add_padding:
} }
} }
#if WITH_SHORT_HEADERS if (WITH_SHORT_HEADERS && keypair->enabled_features[WG_FEATURE_ID_SHORT_HEADER]) {
if (keypair->enabled_features[WG_FEATURE_ID_SHORT_HEADER]) {
size_t header_size; size_t header_size;
byte *write = data; byte *write = data;
uint8 tag = WG_SHORT_HEADER_BIT, inner_tag; uint8 tag = WG_SHORT_HEADER_BIT, inner_tag;
@ -530,9 +497,6 @@ add_padding:
ad_len = data - write_after_ack_header; ad_len = data - write_after_ack_header;
} else { } else {
need_big_packet: need_big_packet:
#else
{
#endif // #if WITH_SHORT_HEADERS
packet->size = (int)(size + sizeof(MessageData) + keypair->auth_tag_length); packet->size = (int)(size + sizeof(MessageData) + keypair->auth_tag_length);
peer->tx_bytes_ += packet->size; peer->tx_bytes_ += packet->size;
@ -859,7 +823,9 @@ void WireguardProcessor::HandleShortHeaderFormatPacket(uint32 tag, Packet *packe
if (tag & WG_SHORT_HEADER_ACK) if (tag & WG_SHORT_HEADER_ACK)
keypair->can_use_short_key_for_outgoing = (ack_tag & WG_ACK_HEADER_KEY_MASK) * WG_SHORT_HEADER_KEY_ID; keypair->can_use_short_key_for_outgoing = (ack_tag & WG_ACK_HEADER_KEY_MASK) * WG_SHORT_HEADER_KEY_ID;
HandleAuthenticatedDataPacket_WillUnlock(keypair, packet, data, bytes_left - keypair->auth_tag_length); packet->data = data;
packet->size = bytes_left - keypair->auth_tag_length;
HandleAuthenticatedDataPacket_WillUnlock(keypair, packet);
return; return;
getout_unlock: getout_unlock:
WG_RELEASE_LOCK(keypair->peer->mutex_); WG_RELEASE_LOCK(keypair->peer->mutex_);
@ -881,7 +847,7 @@ void WireguardProcessor::NotifyHandshakeComplete() {
procdel_->OnConnected(); procdel_->OnConnected();
} }
void WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet, uint8 *data, size_t data_size) { void WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet) {
WgPeer *peer = keypair->peer; WgPeer *peer = keypair->peer;
assert(peer->IsPeerLocked()); assert(peer->IsPeerLocked());
@ -901,6 +867,7 @@ void WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *key
peer->ScheduleNewHandshake(); peer->ScheduleNewHandshake();
} }
uint32 data_size = packet->size;
if (data_size == 0) { if (data_size == 0) {
peer->OnKeepaliveReceived(); peer->OnKeepaliveReceived();
WG_RELEASE_LOCK(peer->mutex_); WG_RELEASE_LOCK(peer->mutex_);
@ -909,22 +876,22 @@ void WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *key
peer->OnDataReceived(); peer->OnDataReceived();
WG_RELEASE_LOCK(peer->mutex_); WG_RELEASE_LOCK(peer->mutex_);
#if WITH_HANDSHAKE_EXT // Unpack the packet headers?
// Unpack the packet headers using ipzip if (WITH_HANDSHAKE_EXT && keypair->compress_handler_) {
if (keypair->enabled_features[WG_FEATURE_ID_IPZIP]) { WgCompressHandler::CompressState st = keypair->compress_handler_->Decompress(packet);
uint32 rv = IpzipDecompress(data, (uint32)data_size, &keypair->ipzip_state_, IPZIP_RECV_BY_CLIENT); if (st == WgCompressHandler::COMPRESS_FAIL)
if (rv == (uint32)-1)
goto getout; goto getout;
stats_.compression_hdr_saved_in += (int64)rv - data_size; if (st == WgCompressHandler::COMPRESS_YES)
data -= (int64)rv - data_size, data_size = rv; stats_.compression_hdr_saved_in += (int32)(packet->size - exch(data_size, packet->size));
} }
#endif // WITH_HANDSHAKE_EXT
// Verify that the packet is a valid ipv4 or ipv6 packet of proper length, // Verify that the packet is a valid ipv4 or ipv6 packet of proper length,
// with a source address that belongs to the peer. // with a source address that belongs to the peer.
WgPeer *peer_from_header; WgPeer *peer_from_header;
unsigned int ip_version, size_from_header; uint32 ip_version, size_from_header;
uint8 *data;
data = packet->data;
ip_version = *data >> 4; ip_version = *data >> 4;
if (ip_version == 4) { if (ip_version == 4) {
if (data_size < IPV4_HEADER_SIZE) if (data_size < IPV4_HEADER_SIZE)
@ -951,10 +918,9 @@ void WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *key
if (peer_from_header != peer || size_from_header > data_size) if (peer_from_header != peer || size_from_header > data_size)
goto getout_error_header; goto getout_error_header;
packet->data = data;
packet->size = size_from_header; packet->size = size_from_header;
stats_.tun_bytes_out += packet->size; stats_.tun_bytes_out += size_from_header;
stats_.tun_packets_out++; stats_.tun_packets_out++;
tun_->WriteTunPacket(packet); tun_->WriteTunPacket(packet);
@ -970,7 +936,7 @@ void WireguardProcessor::HandleDataPacket(Packet *packet) {
assert(dev_.IsMainOrDataThread()); assert(dev_.IsMainOrDataThread());
uint8 *data = packet->data; uint8 *data = packet->data;
size_t data_size = packet->size; uint32 data_size = packet->size;
uint32 key_id = ((MessageData*)data)->receiver_id; uint32 key_id = ((MessageData*)data)->receiver_id;
uint64 counter = ToLE64((((MessageData*)data)->counter)); uint64 counter = ToLE64((((MessageData*)data)->counter));
WgKeypair *keypair = dev_.LookupKeypairByKeyId(key_id); WgKeypair *keypair = dev_.LookupKeypairByKeyId(key_id);
@ -981,6 +947,9 @@ getout:
return; return;
} }
packet->data = data + sizeof(MessageData);
packet->size = data_size - sizeof(MessageData) - keypair->auth_tag_length;
if (!WgKeypairDecryptPayload(data + sizeof(MessageData), data_size - sizeof(MessageData), if (!WgKeypairDecryptPayload(data + sizeof(MessageData), data_size - sizeof(MessageData),
NULL, 0, counter, keypair)) { NULL, 0, counter, keypair)) {
stats_.error_mac++; stats_.error_mac++;
@ -1001,7 +970,8 @@ getout:
assert(!keypair->peer->marked_for_delete_); assert(!keypair->peer->marked_for_delete_);
WgPeer::CopyEndpointToPeer_Locked(keypair, &packet->addr); WgPeer::CopyEndpointToPeer_Locked(keypair, &packet->addr);
HandleAuthenticatedDataPacket_WillUnlock(keypair, packet, data + sizeof(MessageData), data_size - sizeof(MessageData) - keypair->auth_tag_length);
HandleAuthenticatedDataPacket_WillUnlock(keypair, packet);
} }
} }

View file

@ -115,11 +115,10 @@ private:
void HandleHandshakeCookiePacket(Packet *packet); void HandleHandshakeCookiePacket(Packet *packet);
void HandleDataPacket(Packet *packet); void HandleDataPacket(Packet *packet);
void HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet, uint8 *data, size_t data_size); void HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet);
void HandleShortHeaderFormatPacket(uint32 tag, Packet *packet); void HandleShortHeaderFormatPacket(uint32 tag, Packet *packet);
bool CheckIncomingHandshakeRateLimit(Packet *packet, bool overload); bool CheckIncomingHandshakeRateLimit(Packet *packet, bool overload);
bool HandleIcmpv6NeighborSolicitation(const byte *data, size_t data_size); bool HandleIcmpv6NeighborSolicitation(const byte *data, size_t data_size);
void SetupCompressionHeader(WgPacketCompressionVer01 *c);
void NotifyHandshakeComplete(); void NotifyHandshakeComplete();
ProcessorDelegate *procdel_; ProcessorDelegate *procdel_;

View file

@ -60,7 +60,6 @@ WgDevice::WgDevice() {
next_rng_slot_ = 0; next_rng_slot_ = 0;
main_thread_scheduled_ = NULL; main_thread_scheduled_ = NULL;
main_thread_scheduled_last_ = &main_thread_scheduled_; main_thread_scheduled_last_ = &main_thread_scheduled_;
memset(&compression_header_, 0, sizeof(compression_header_));
low_resolution_timestamp_ = cookie_secret_timestamp_ = OsGetMilliseconds(); low_resolution_timestamp_ = cookie_secret_timestamp_ = OsGetMilliseconds();
OsGetRandomBytes(cookie_secret_, sizeof(cookie_secret_)); OsGetRandomBytes(cookie_secret_, sizeof(cookie_secret_));
@ -791,6 +790,7 @@ void WgPeer::ParseMessageHandshakeCookie(WgDevice *dev, const MessageHandshakeCo
#if WITH_HANDSHAKE_EXT #if WITH_HANDSHAKE_EXT
size_t WgPeer::WriteHandshakeExtension(uint8 *dst, WgKeypair *keypair) { size_t WgPeer::WriteHandshakeExtension(uint8 *dst, WgKeypair *keypair) {
uint8 *dst_end = dst + MAX_SIZE_OF_HANDSHAKE_EXTENSION;
uint8 *dst_org = dst, value = 0; uint8 *dst_org = dst, value = 0;
// Include the supported features extension // Include the supported features extension
if (!IsOnlyZeros(features_, sizeof(features_))) { if (!IsOnlyZeros(features_, sizeof(features_))) {
@ -818,13 +818,10 @@ size_t WgPeer::WriteHandshakeExtension(uint8 *dst, WgKeypair *keypair) {
dst += ciphers; dst += ciphers;
} }
} }
if (features_[WG_FEATURE_ID_IPZIP]) { // Packet compression extension?
// Include the packet compression extension if (features_[WG_FEATURE_ID_IPZIP] && dev_->delegate_)
*dst++ = EXT_PACKET_COMPRESSION; dst += dev_->delegate_->WritePacketCompressionExtension(dst, dst_end - dst);
*dst++ = sizeof(WgPacketCompressionVer01);
memcpy(dst, &dev_->compression_header_, sizeof(WgPacketCompressionVer01));
dst += sizeof(WgPacketCompressionVer01);
}
return dst - dst_org; return dst - dst_org;
} }
@ -856,32 +853,7 @@ static uint32 ResolveCipherSuite(int tie, const uint8 *a, size_t a_size, const u
(tie == 0 && cipher_strengths[found_a] > cipher_strengths[found_b])) ? found_a : found_b; (tie == 0 && cipher_strengths[found_a] > cipher_strengths[found_b])) ? found_a : found_b;
} }
void WgKeypairSetupCompressionExtension(WgKeypair *keypair, const WgPacketCompressionVer01 *remotec) { bool WgPeer::ParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size_t data_size) {
const WgPacketCompressionVer01 *localc = keypair->peer->dev_->compression_header();
IpzipState *state = &keypair->ipzip_state_;
// Use is_initiator as tie-breaker on who's going to be the client side.
int flags_xor = 0;
if ((localc->flags & ~3) + 2 * keypair->is_initiator - 1 <= (remotec->flags & ~3))
std::swap(localc, remotec), flags_xor = 1;
state->flags_xor = flags_xor;
memcpy(state->client_addr_v4, localc->ipv4_addr, 4);
memcpy(state->client_addr_v6, localc->ipv6_addr, 16);
state->guess_ttl[0] = localc->ttl;
state->client_addr_v4_subnet_bytes = (localc->flags & 3);
WriteLE32(&state->client_addr_v4_netmask, 0xffffffff >> ((localc->flags & 3) * 8));
memcpy(state->server_addr_v4, remotec->ipv4_addr, 4);
memcpy(state->server_addr_v6, remotec->ipv6_addr, 16);
state->guess_ttl[1] = remotec->ttl;
state->server_addr_v4_subnet_bytes = (remotec->flags & 3);
WriteLE32(&state->server_addr_v4_netmask, 0xffffffff >> ((remotec->flags & 3) * 8));
}
bool WgKeypairParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size_t data_size) {
bool did_setup_compression = false;
while (data_size >= 2) { while (data_size >= 2) {
uint8 type = data[0], size = data[1]; uint8 type = data[0], size = data[1];
data += 2, data_size -= 2; data += 2, data_size -= 2;
@ -892,7 +864,7 @@ bool WgKeypairParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size
case EXT_CIPHER_SUITES: case EXT_CIPHER_SUITES:
keypair->cipher_suite = ResolveCipherSuite(keypair->peer->cipher_prio_ - (type - EXT_CIPHER_SUITES), keypair->cipher_suite = ResolveCipherSuite(keypair->peer->cipher_prio_ - (type - EXT_CIPHER_SUITES),
keypair->peer->ciphers_, keypair->peer->num_ciphers_, keypair->peer->ciphers_, keypair->peer->num_ciphers_,
data, data_size); data, size);
break; break;
case EXT_BOOLEAN_FEATURES: case EXT_BOOLEAN_FEATURES:
for (size_t i = 0, j = std::max<uint32>(WG_FEATURES_COUNT, size * 4); i != j; i++) { for (size_t i = 0, j = std::max<uint32>(WG_FEATURES_COUNT, size * 4); i != j; i++) {
@ -903,13 +875,8 @@ bool WgKeypairParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size
} }
break; break;
case EXT_PACKET_COMPRESSION: case EXT_PACKET_COMPRESSION:
if (size == sizeof(WgPacketCompressionVer01)) { if (keypair->enabled_features[WG_FEATURE_ID_IPZIP] && !keypair->compress_handler_ && keypair->peer->dev_->delegate_)
WgPacketCompressionVer01 *c = (WgPacketCompressionVer01*)data; keypair->compress_handler_ = keypair->peer->dev_->delegate_->ParsePacketCompressionExtension(keypair, data, size);
if (ReadLE16(&c->version) == EXT_PACKET_COMPRESSION_VER) {
WgKeypairSetupCompressionExtension(keypair, c);
did_setup_compression = true;
}
}
break; break;
} }
data += size, data_size -= size; data += size, data_size -= size;
@ -917,7 +884,8 @@ bool WgKeypairParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size
if (data_size != 0) if (data_size != 0)
return false; return false;
keypair->enabled_features[WG_FEATURE_ID_IPZIP] &= did_setup_compression; if (!keypair->compress_handler_)
keypair->enabled_features[WG_FEATURE_ID_IPZIP] = false;
keypair->auth_tag_length = (keypair->enabled_features[WG_FEATURE_ID_SHORT_MAC] ? 8 : CHACHA20POLY1305_AUTHTAGLEN); keypair->auth_tag_length = (keypair->enabled_features[WG_FEATURE_ID_SHORT_MAC] ? 8 : CHACHA20POLY1305_AUTHTAGLEN);
// RINFO("Cipher Suite = %d", keypair->cipher_suite); // RINFO("Cipher Suite = %d", keypair->cipher_suite);
@ -965,7 +933,7 @@ WgKeypair *WgPeer::CreateNewKeypair(bool is_initiator, const uint8 chaining_key[
kp->auth_tag_length = CHACHA20POLY1305_AUTHTAGLEN; kp->auth_tag_length = CHACHA20POLY1305_AUTHTAGLEN;
#if WITH_HANDSHAKE_EXT #if WITH_HANDSHAKE_EXT
if (!WgKeypairParseExtendedHandshake(kp, extfield, extfield_size)) { if (!ParseExtendedHandshake(kp, extfield, extfield_size)) {
fail: fail:
delete kp; delete kp;
return NULL; return NULL;

View file

@ -4,7 +4,6 @@
#include "tunsafe_types.h" #include "tunsafe_types.h"
#include "netapi.h" #include "netapi.h"
#include "ipzip2/ipzip2.h"
#include "tunsafe_config.h" #include "tunsafe_config.h"
#include "tunsafe_endian.h" #include "tunsafe_endian.h"
#include "tunsafe_threading.h" #include "tunsafe_threading.h"
@ -201,15 +200,6 @@ enum {
WG_BOOLEAN_FEATURE_ENFORCES = 0x3, WG_BOOLEAN_FEATURE_ENFORCES = 0x3,
}; };
struct WgPacketCompressionVer01 {
uint16 version; // Packet compressor version
uint8 ttl; // Guessed TTL
uint8 flags; // Subnet length and packet direction
uint8 ipv4_addr[4]; // IPV4 address of endpoint
uint8 ipv6_addr[16]; // IPV6 address of endpoint
};
STATIC_ASSERT(sizeof(WgPacketCompressionVer01) == 24, WgPacketCompressionVer01_wrong_size);
struct WgKeypair; struct WgKeypair;
class WgPeer; class WgPeer;
@ -303,6 +293,23 @@ struct WgPublicKeyHasher {
size_t operator()(const WgPublicKey&a) const; size_t operator()(const WgPublicKey&a) const;
}; };
class WgCompressHandler {
public:
virtual ~WgCompressHandler() {}
enum CompressState {
COMPRESS_FAIL = -1,
COMPRESS_NO = 0,
COMPRESS_YES = 1,
};
// Compress a packet.
virtual CompressState Compress(Packet *packet);
virtual CompressState Decompress(Packet *packet);
};
class WgDevice { class WgDevice {
friend class WgPeer; friend class WgPeer;
friend class WireguardProcessor; friend class WireguardProcessor;
@ -316,6 +323,12 @@ public:
// return true to try again or false to fail. The packet can be copied and saved // return true to try again or false to fail. The packet can be copied and saved
// to resume a handshake later on. // to resume a handshake later on.
virtual bool HandleUnknownPeerId(uint8 public_key[WG_PUBLIC_KEY_LEN], Packet *packet) = 0; virtual bool HandleUnknownPeerId(uint8 public_key[WG_PUBLIC_KEY_LEN], Packet *packet) = 0;
// Write out the compression header
virtual size_t WritePacketCompressionExtension(uint8 *data, size_t data_size) = 0;
// Parse the packet compression extension
virtual WgCompressHandler *ParsePacketCompressionExtension(WgKeypair *keypair, const uint8 *data, size_t data_size) = 0;
}; };
WgDevice(); WgDevice();
@ -346,7 +359,6 @@ public:
WgPeer *first_peer() { return peers_; } WgPeer *first_peer() { return peers_; }
const uint8 *public_key() const { return s_pub_; } const uint8 *public_key() const { return s_pub_; }
WgRateLimit *rate_limiter() { return &rate_limiter_; } WgRateLimit *rate_limiter() { return &rate_limiter_; }
WgPacketCompressionVer01 *compression_header() { return &compression_header_; }
bool is_private_key_initialized() { return is_private_key_initialized_; } bool is_private_key_initialized() { return is_private_key_initialized_; }
bool IsMainThread() { return CurrentThreadIdEquals(main_thread_id_); } bool IsMainThread() { return CurrentThreadIdEquals(main_thread_id_); }
@ -436,8 +448,6 @@ private:
WgRateLimit rate_limiter_; WgRateLimit rate_limiter_;
WgPacketCompressionVer01 compression_header_;
// For defering deletes until all worker threads are guaranteed not to use an object. // For defering deletes until all worker threads are guaranteed not to use an object.
MultithreadedDelayedDelete delayed_delete_; MultithreadedDelayedDelete delayed_delete_;
}; };
@ -447,8 +457,6 @@ class WgPeer {
friend class WgDevice; friend class WgDevice;
friend class WireguardProcessor; friend class WireguardProcessor;
friend class WgConfig; friend class WgConfig;
friend bool WgKeypairParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size_t data_size);
friend void WgKeypairSetupCompressionExtension(WgKeypair *keypair, const WgPacketCompressionVer01 *remotec);
public: public:
explicit WgPeer(WgDevice *dev); explicit WgPeer(WgDevice *dev);
~WgPeer(); ~WgPeer();
@ -496,6 +504,7 @@ public:
WgPeer *next_peer() { return next_peer_; } WgPeer *next_peer() { return next_peer_; }
private: private:
static bool ParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size_t data_size);
static WgKeypair *CreateNewKeypair(bool is_initiator, const uint8 key[WG_HASH_LEN], uint32 send_key_id, const uint8 *extfield, size_t extfield_size); static WgKeypair *CreateNewKeypair(bool is_initiator, const uint8 key[WG_HASH_LEN], uint32 send_key_id, const uint8 *extfield, size_t extfield_size);
void WriteMacToPacket(const uint8 *data, MessageMacs *mac); void WriteMacToPacket(const uint8 *data, MessageMacs *mac);
void CheckAndUpdateTimeOfNextKeyEvent(uint64 now); void CheckAndUpdateTimeOfNextKeyEvent(uint64 now);
@ -719,14 +728,12 @@ struct WgKeypair {
AesGcm128StaticContext *aes_gcm128_context_; AesGcm128StaticContext *aes_gcm128_context_;
WgCompressHandler *compress_handler_;
// -- all up to this point is initialized to zero // -- all up to this point is initialized to zero
// For replay detection of incoming packets // For replay detection of incoming packets
ReplayDetector replay_detector; ReplayDetector replay_detector;
#if WITH_HANDSHAKE_EXT
// State for packet compressor
IpzipState ipzip_state_;
#endif // WITH_HANDSHAKE_EXT
}; };
void WgKeypairEncryptPayload(uint8 *dst, const size_t src_len, void WgKeypairEncryptPayload(uint8 *dst, const size_t src_len,
@ -737,5 +744,3 @@ bool WgKeypairDecryptPayload(uint8 *dst, const size_t src_len,
const uint8 *ad, const size_t ad_len, const uint8 *ad, const size_t ad_len,
const uint64 nonce, WgKeypair *keypair); const uint64 nonce, WgKeypair *keypair);
bool WgKeypairParseExtendedHandshake(WgKeypair *keypair, const uint8 *data, size_t data_size);