Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ else()
endif()

add_compile_definitions(FPTN_VERSION=\"${FPTN_VERSION}\")
add_compile_definitions(FPTN_MTU_SIZE=1400)
add_compile_definitions(FPTN_MTU_SIZE=1450)
add_compile_definitions(FPTN_DEFAULT_SNI=\"rutube.ru\")
add_compile_definitions(FPTN_IP_PACKET_MAX_SIZE=1300)
add_compile_definitions(FPTN_IP_PACKET_MAX_SIZE=1400)
add_compile_definitions(FPTN_ENABLE_PACKET_PADDING=1)
add_compile_definitions(FPTN_PROTOBUF_PROTOCOL_VERSION=0x01)
# client
Expand Down
84 changes: 84 additions & 0 deletions deploy/docker/Dockerfile.sourcebuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
FROM ubuntu:24.04 AS builder

ARG FPTN_VERSION=local

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC
ENV CONAN_HOME=/tmp/conan
ENV PIP_BREAK_SYSTEM_PACKAGES=1

RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
autoconf \
automake \
build-essential \
ca-certificates \
cmake \
curl \
git \
libelf-dev \
libpcap-dev \
libtool \
m4 \
meson \
ninja-build \
perl \
pkg-config \
python3 \
python3-pip \
unzip \
wget \
zip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

RUN pip3 install --no-cache-dir conan==2.24.0

WORKDIR /src
COPY . .

RUN sed -i "s/^FPTN_VERSION = \".*\"/FPTN_VERSION = \"${FPTN_VERSION}\"/" conanfile.py && \
conan profile detect --force && \
conan install . \
--output-folder=build \
--build=missing \
-o with_gui_client=False \
--settings build_type=Release \
-s compiler.cppstd=17 && \
cmake -S . -B build \
-DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release && \
cmake --build build --config Release --target fptn-server fptn-passwd -j"$(nproc)"

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC

EXPOSE 443/tcp

RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y unbound iproute2 iptables supervisor wget dnsmasq && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

RUN mkdir -p /etc/supervisor/conf.d

COPY --from=builder /src/build/src/fptn-server/fptn-server /usr/local/bin/fptn-server
COPY --from=builder /src/build/src/fptn-passwd/fptn-passwd /usr/local/bin/fptn-passwd
RUN chmod +x /usr/local/bin/fptn-server && \
chmod +x /usr/local/bin/fptn-passwd

COPY deploy/docker/config/supervisord.conf /etc/supervisor/supervisord.conf
COPY deploy/docker/config/supervisor/*.conf /etc/supervisor/conf.d/

COPY deploy/docker/scripts/start-fptn.sh /usr/local/bin/start-fptn.sh
COPY deploy/docker/scripts/start-dns-server.sh /usr/local/bin/start-dns-server.sh
COPY deploy/docker/scripts/token-generator.py /usr/local/bin/token-generator
RUN chmod +x /usr/local/bin/start-fptn.sh && \
chmod +x /usr/local/bin/token-generator && \
chmod +x /usr/local/bin/start-dns-server.sh

CMD ["/usr/bin/supervisord", "--nodaemon", "-c", "/etc/supervisor/supervisord.conf"]
2 changes: 1 addition & 1 deletion docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
services:
fptn-server:
restart: unless-stopped
image: fptnvpn/fptn-vpn-server:latest
image: astracat/fptn-vpn-server:latest
cap_add:
- NET_ADMIN
- SYS_MODULE
Expand Down
9 changes: 6 additions & 3 deletions src/common/data/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ Distributed under the MIT License (https://opensource.org/licenses/MIT)
namespace fptn::common::data {
class Channel {
public:
explicit Channel(std::size_t maxCapacity = 512) {
// Increase default capacity for high throughput
explicit Channel(std::size_t maxCapacity = 8192) {
buffer_.set_capacity(maxCapacity);
}
void Push(network::IPPacketPtr pkt) noexcept {
{
const std::unique_lock<std::mutex> lock(mutex_); // mutex

buffer_.push_back(std::move(pkt));
if (buffer_.size() < buffer_.capacity()) {
buffer_.push_back(std::move(pkt));
}
// If buffer full, drop packet (better than unbounded growth or blocking)
}
condvar_.notify_one();
}
Expand Down
62 changes: 28 additions & 34 deletions src/common/data/channel_async.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,25 @@ using boost::asio::use_awaitable;

class ChannelAsync {
public:
explicit ChannelAsync(boost::asio::io_context& ioc,
std::size_t maxCapacity = 512,
std::size_t threadPoolSize = 4)
: ioc_(ioc), pool_(threadPoolSize) {
buffer_.set_capacity(maxCapacity);
// Increased defaults for high throughput
explicit ChannelAsync(boost::asio::io_context& ioc)
: ioc_(ioc) {
// Capacity 8192
buffer_.set_capacity(8192);
}
void Push(network::IPPacketPtr pkt) {
{
const std::unique_lock<std::mutex> lock(mutex_);
buffer_.push_back(std::move(pkt));
if (buffer_.size() < buffer_.capacity()) {
buffer_.push_back(std::move(pkt));
}
}
condvar_.notify_one();

// Trigger async waiter if any
if (timer_) {
timer_->cancel();
}
}

network::IPPacketPtr WaitForPacket(
Expand All @@ -67,24 +74,29 @@ class ChannelAsync {
}

boost::asio::awaitable<std::optional<network::IPPacketPtr>>
WaitForPacketAsync(const std::chrono::milliseconds& duration) {
WaitForPacketAsync() {
// Optimistic check without creating timer
{
const std::unique_lock<std::mutex> lock(mutex_); // mutex

// exists
const std::unique_lock<std::mutex> lock(mutex_);
if (!buffer_.empty()) {
auto pkt = std::move(buffer_.front());
buffer_.pop_front();
co_return pkt;
}
}

// wait for timeout
co_await AsyncWaitUntil(duration);

// Wait for notification or timeout (e.g. 50ms to batch)
try {
timer_ = std::make_unique<boost::asio::steady_timer>(ioc_);
timer_->expires_after(std::chrono::milliseconds(50));
co_await timer_->async_wait(boost::asio::use_awaitable);
} catch (...) {
// Timer cancelled means data arrived
}

// Check again
{
const std::unique_lock<std::mutex> lock(mutex_); // mutex

const std::unique_lock<std::mutex> lock(mutex_);
if (!buffer_.empty()) {
auto pkt = std::move(buffer_.front());
buffer_.pop_front();
Expand All @@ -94,27 +106,9 @@ class ChannelAsync {
co_return std::nullopt;
}

boost::asio::awaitable<void> AsyncWaitUntil(
const std::chrono::steady_clock::duration& timeout) {
boost::asio::steady_timer timer(ioc_, timeout);

co_await timer.async_wait(boost::asio::use_awaitable);

// while (!mutex_.try_lock()) {
// if (std::chrono::steady_clock::now() - start >
// std::chrono::seconds(3)) {
// spdlog::error("Session::send: failed to acquire lock within
// timeout"); co_return false;
// }
// std::this_thread::yield(); // Yield to avoid busy waiting
// }

co_return;
}

protected:
boost::asio::io_context& ioc_;
boost::asio::thread_pool pool_;
std::unique_ptr<boost::asio::steady_timer> timer_;

mutable std::mutex mutex_;
std::condition_variable condvar_;
Expand Down
20 changes: 19 additions & 1 deletion src/common/utils/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Distributed under the MIT License (https://opensource.org/licenses/MIT)
#pragma once

#include <algorithm>
#include <cstring>
#include <ctime>
#include <random>
#include <ranges>
Expand All @@ -20,14 +21,31 @@ Distributed under the MIT License (https://opensource.org/licenses/MIT)
#include <boost/locale.hpp>

namespace fptn::common::utils {

inline void GenerateRandomBytes(std::uint8_t* buffer, std::size_t length) {
static thread_local std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<std::uint64_t> dist;

std::size_t i = 0;
for (; i + 8 <= length; i += 8) {
uint64_t rand_val = dist(gen);
std::memcpy(buffer + i, &rand_val, 8);
}
if (i < length) {
uint64_t rand_val = dist(gen);
std::memcpy(buffer + i, &rand_val, length - i);
}
}

inline std::string GenerateRandomString(int length) {
const std::string characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

std::mt19937 gen{std::random_device {}()};
static thread_local std::mt19937 gen{std::random_device {}()};
std::uniform_int_distribution<std::size_t> dist(0, characters.size() - 1);

std::string result;
result.reserve(length);
for (int i = 0; i < length; i++) {
result += characters[dist(gen)];
}
Expand Down
Loading