Skip to content

Commit

Permalink
更新多线程相关配置
Browse files Browse the repository at this point in the history
  • Loading branch information
lanthora committed Jul 7, 2024
1 parent adba15e commit 03d5c2d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 52 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.18.4)

project(candy LANGUAGES C CXX VERSION 5.9.4)
project(candy LANGUAGES C CXX VERSION 5.10.0)

option(CANDY_NOEXE "Don't build executable")
option(CANDY_DEVEL "Build development library")
Expand Down
55 changes: 12 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ scripts/build-standalone.sh

## 如何使用

### 接入测试网络
详细用法请参考[配置文件](candy.cfg).

客户端的[默认配置](candy.cfg)会连到测试网络并被随机分配一个地址.
### 接入测试网络

客户端会缓存服务端分配的地址,并在下次启动时优先申请使用这个地址,地址保存在 `/var/lib/candy` 目录下,启动容器服务前需要在 Host 创建一个目录用于映射,否则容器重启丢失数据将导致重新分配地址.
使用默认配置启动即可接入测试网络.客户端会缓存服务端分配的地址,并在下次启动时优先申请使用这个地址,地址保存在 `/var/lib/candy` 目录下,启动容器服务前需要在 Host 创建一个目录用于映射,否则容器重启丢失数据将导致重新分配地址.

创建与容器内相同的目录以方便理解.

Expand All @@ -128,7 +128,13 @@ mkdir -p /var/lib/candy
以容器的方式接入测试网络

```bash
docker run --rm --privileged=true --net=host --volume /var/lib/candy:/var/lib/candy docker.io/lanthora/candy:latest
docker run --detach --restart=always --privileged=true --net=host --volume /var/lib/candy:/var/lib/candy docker.io/lanthora/candy:latest
```

以 Linux 发行版 [Service](candy.service) 的方式接入测试网络

```bash
systemctl enable --now candy
```

当成功部署两个及以上客户端后,客户端之间可以相互访问.得益于路由功能,网络中的客户端数量越多,访问时延越低.
Expand All @@ -149,7 +155,7 @@ candy --help
candy -c /path/to/candy.cfg
```

#### 服务端
#### 服务端基本配置

监听所有网卡的 80 端口,客户端连接后自动在 10.0.0.0/24 子网分配地址,并设置登录口令为 123456

Expand All @@ -164,15 +170,7 @@ dhcp = "10.0.0.0/24"
password = "123456"
```

配置[多局域网组网](docs/muti-lan-interconn.md)

```ini
# 进入设备网络 10.0.0.1/32 且目的网络为 192.168.2.0/24 的 IP 报文通过 10.0.0.2 转发,
# 通过分号分割的多条规则,配置中禁止出现空白符.
sdwan = "10.0.0.1/32,192.168.2.0/24,10.0.0.2;10.0.0.2/32,192.168.1.0/24,10.0.0.1"
```

#### 客户端
#### 客户端基本配置

与上述服务端匹配的客户端配置

Expand All @@ -190,37 +188,8 @@ tun = "10.0.0.1/24"
name = "test"
# STUN 服务器,用于获取建立对等连接所需的公网信息,不配置此项表示不启用对等连接
stun = "stun://stun.canets.org"
# 指定对等连接监听的本地 UDP 端口,不配置此项表示由操作系统随机分配
port = 0
```

配置客户端中继

```ini
# 路由功能在对等连接的基础上工作,对等连接是被动启动,
# 有些设备本可以作为中继,但由于此前没有与中继设备的流量导致无法使用路由.
# 此配置以秒为单位周期性的尝试让网络中的其他设备与本设备建立对等连接.
# 不添加此配置或者配置为 0 表示不启用主动发现.
discovery = 300

# 当消息通过本机作为中继转发时在本机内部消耗的代价.
# 此配置以毫秒为单位与直连设备间的真实时延求和作为以本机为路由的代价广播.
# 不配置或者配置配置为 0 表示不启用路由加速.
route = 5
```

配置局域网内对等链接

```ini
# 用于建立对等连接的本机局域网 IP 地址,不配置此项时将尝试自动获取.
# 有多个物理网卡时建议手动配置.
localhost = "127.0.0.1"
```

## 未来规划

目前已经达成了最初的目标: __让装了客户端的设备之间可以通过虚拟 IP 相互访问__.对于 C++ 版本,将尽可能维持稳定,不添加新功能.

## 相关项目

- [Cucurbita](https://hub.docker.com/r/lanthora/cucurbita): Candy Server with Web Control Interface
Expand Down
4 changes: 4 additions & 0 deletions candy.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,7 @@ route = 5
# detected. When there are multiple physical network cards, the detection
# results may not be the best. You can specify it manually.
#localhost = "127.0.0.1"

# [Optional] Number of worker threads
# Default is 0 means no independent worker threads are enabled
#workers=0
29 changes: 21 additions & 8 deletions src/core/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ int Client::setWorkers(int number) {
number = std::min(number, int(Poco::Environment::processorCount()));
number = std::max(number, 0);
this->workers = number;
spdlog::debug("workers: {}", this->workers);
if (this->workers) {
spdlog::debug("workers: {}", this->workers);
}
return 0;
}

Expand Down Expand Up @@ -183,13 +185,13 @@ int Client::shutdown() {

// Common
int Client::startWorkerThreads() {
for (size_t i = 0; i < this->workers; ++i) {
for (int i = 0; i < this->workers; ++i) {
this->udpMsgWorkerThreads.emplace_back([&] {
while (this->running) {
UdpMessage message;
{
static const auto timeout = std::chrono::seconds(1);
std::unique_lock<std::mutex> lock(this->udpMsgQueueMutex);
auto timeout = std::chrono::seconds(1);
if (!this->udpMsgQueueCondition.wait_for(lock, timeout, [this] { return !this->udpMsgQueue.empty(); })) {
continue;
}
Expand All @@ -204,7 +206,7 @@ int Client::startWorkerThreads() {
while (this->running) {
std::string message;
{
auto timeout = std::chrono::seconds(1);
static const auto timeout = std::chrono::seconds(1);
std::unique_lock<std::mutex> lock(this->tunMsgQueueMutex);
if (!this->tunMsgQueueCondition.wait_for(lock, timeout, [this] { return !this->tunMsgQueue.empty(); })) {
continue;
Expand All @@ -225,12 +227,25 @@ int Client::stopWorkerThreads() {
t.join();
}
}
{
std::unique_lock<std::mutex> lock(this->udpMsgQueueMutex);
while (!this->udpMsgQueue.empty()) {
this->udpMsgQueue.pop();
}
}
this->udpMsgWorkerThreads.clear();

for (std::thread &t : this->tunMsgWorkerThreads) {
if (t.joinable()) {
t.join();
}
}
this->udpMsgWorkerThreads.clear();
{
std::unique_lock<std::mutex> lock(this->tunMsgQueueMutex);
while (!this->tunMsgQueue.empty()) {
this->tunMsgQueue.pop();
}
}
this->tunMsgWorkerThreads.clear();
return 0;
}
Expand Down Expand Up @@ -355,11 +370,9 @@ void Client::handleWebSocketMessage() {
}

void Client::recvUdpMessage() {
int error;

while (this->running) {
UdpMessage message;
error = this->udpHolder.read(message);
int error = this->udpHolder.read(message);
if (error == 0) {
continue;
}
Expand Down

0 comments on commit 03d5c2d

Please sign in to comment.