tunsafe-clang15/network_common.h

154 lines
3.8 KiB
C
Raw Normal View History

#ifndef TUNSAFE_NETWORK_COMMON_H_
#define TUNSAFE_NETWORK_COMMON_H_
#include "netapi.h"
#include "crypto/chacha20poly1305.h"
class PacketProcessor;
class WgPacketObfuscator;
// A simple singlethreaded pool of packets used on windows where
// FreePacket / AllocPacket are multithreded and thus slightly slower
#if defined(OS_WIN)
class SimplePacketPool {
public:
explicit SimplePacketPool() {
freed_packets_ = NULL;
freed_packets_count_ = 0;
}
~SimplePacketPool() {
FreePacketList(freed_packets_);
}
Packet *AllocPacketFromPool() {
if (Packet *p = freed_packets_) {
freed_packets_ = Packet_NEXT(p);
freed_packets_count_--;
p->Reset();
return p;
}
return AllocPacket();
}
void FreePacketToPool(Packet *p) {
Packet_NEXT(p) = freed_packets_;
freed_packets_ = p;
freed_packets_count_++;
}
void FreeSomePackets() {
if (freed_packets_count_ > 32)
FreeSomePacketsInner();
}
void FreeSomePacketsInner();
int freed_packets_count_;
Packet *freed_packets_;
};
#else
class SimplePacketPool {
public:
Packet *AllocPacketFromPool() {
return AllocPacket();
}
void FreePacketToPool(Packet *packet) {
return FreePacket(packet);
}
};
#endif
class TcpPacketQueue {
public:
explicit TcpPacketQueue(SimplePacketPool *pool) : rqueue_bytes_(0), rqueue_(NULL), rqueue_end_(&rqueue_), pool_(pool) {}
~TcpPacketQueue();
Packet *Read(uint num);
Packet *ReadUpTo(uint num);
void Read(uint8 *dst, uint num);
uint PeekUint16();
void Add(Packet *packet);
uint32 size() const { return rqueue_bytes_; }
SimplePacketPool *pool() { return pool_; }
private:
// Total # of bytes queued
uint rqueue_bytes_;
// Buffered data
Packet *rqueue_, **rqueue_end_;
SimplePacketPool *pool_;
};
// Aids with prefixing and parsing incoming and outgoing
// packets with the tcp protocol header.
class TcpPacketHandler {
public:
enum {
kObfuscationMode_Unspecified = -1,
kObfuscationMode_None = 0,
kObfuscationMode_Encrypted = 1,
kObfuscationMode_TlsFirefox = 2,
kObfuscationMode_TlsChrome = 3,
kObfuscationMode_Autodetect = 4,
};
explicit TcpPacketHandler(SimplePacketPool *packet_pool, WgPacketObfuscator *obfuscator, bool is_incoming);
~TcpPacketHandler();
// Adds a tcp header to a data packet so it can be transmitted on the wire
void PrepareOutgoingPackets(Packet *p);
// Add a new chunk of incoming data to the packet list
void QueueIncomingPacket(Packet *p) {
queue_.Add(p);
}
// Attempt to extract the next packet, returns NULL when complete.
Packet *GetNextWireguardPacket();
bool error() const { return error_flag_; }
private:
void PrepareOutgoingPacketsNormal(Packet *p);
void PrepareOutgoingPacketsObfuscate(Packet *p);
void PrepareOutgoingPacketsTLS13(Packet *p);
void PrepareOutgoingPacketsWithHeader(Packet *p);
Packet *GetNextWireguardPacketNormal();
Packet *GetNextWireguardPacketObfuscate(TcpPacketQueue *queue);
Packet *GetNextWireguardPacketTLS13();
size_t CreateTls13ClientHello(uint8 *dst);
size_t CreateTls13ServerHello(uint8 *dst);
// Set if there's a fatal error
bool error_flag_;
uint8 obfuscation_mode_;
uint8 read_state_, write_state_, tls_read_state_;
bool decryptor_initialized_;
uint8 packet_header_[2];
// Number of data bytes left
uint tls_bytes_left_;
TcpPacketQueue queue_;
// There's a separate queue for tls since it unwraps stuff
TcpPacketQueue tls_queue_;
uint32 predicted_key_in_, predicted_key_out_;
uint64 predicted_serial_in_, predicted_serial_out_;
// For obfuscating
chacha20_streaming encryptor_, decryptor_;
uint8 tls_session_id_[32];
};
#endif // TUNSAFE_NETWORK_COMMON_H_