27b75b83de
- Hybrid TCP mode, uses both TCP and UDP - Simplified TCP protocol - Modified obfuscator to support padding - Obfuscation over TCP - Refactor parts of Win32 code to be more similar to BSD
154 lines
No EOL
3.8 KiB
C++
154 lines
No EOL
3.8 KiB
C++
#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_
|