mirror of
https://github.com/rustdesk/rustdesk-server.git
synced 2026-03-12 07:04:42 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
753c774380 | ||
|
|
f626f82a94 | ||
|
|
011b316183 | ||
|
|
24620c0a07 | ||
|
|
fa2b42db76 | ||
|
|
099aaa6b55 | ||
|
|
85af668a4f | ||
|
|
74cb82c8a2 | ||
|
|
1b440b61e7 | ||
|
|
6aa0019f8d | ||
|
|
506b0b5364 | ||
|
|
bf3e9471a6 | ||
|
|
d878222fc1 |
80
.github/workflows/build.yaml
vendored
80
.github/workflows/build.yaml
vendored
@@ -44,9 +44,11 @@ jobs:
|
|||||||
- name: Install toolchain
|
- name: Install toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: nightly
|
toolchain: "1.62"
|
||||||
override: true
|
override: true
|
||||||
default: true
|
default: true
|
||||||
|
components: rustfmt
|
||||||
|
profile: minimal
|
||||||
target: ${{ matrix.job.target }}
|
target: ${{ matrix.job.target }}
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -56,53 +58,95 @@ jobs:
|
|||||||
args: --release --all-features --target=${{ matrix.job.target }}
|
args: --release --all-features --target=${{ matrix.job.target }}
|
||||||
use-cross: true
|
use-cross: true
|
||||||
|
|
||||||
# - name: Run tests
|
- name: Exec chmod
|
||||||
# run: cargo test --verbose
|
run: chmod -v a+x target/${{ matrix.job.target }}/release/*
|
||||||
|
|
||||||
- name: Publish Artifacts
|
- name: Publish Artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: binaries-${{ matrix.job.name }}
|
name: binaries-linux-${{ matrix.job.name }}
|
||||||
path: |
|
path: |
|
||||||
target/${{ matrix.job.target }}/release/hbbr
|
target/${{ matrix.job.target }}/release/hbbr
|
||||||
target/${{ matrix.job.target }}/release/hbbs
|
target/${{ matrix.job.target }}/release/hbbs
|
||||||
target/${{ matrix.job.target }}/release/rustdesk-utils
|
target/${{ matrix.job.target }}/release/rustdesk-utils
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
build-win:
|
||||||
|
name: Build - windows
|
||||||
|
runs-on: windows-2019
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: "1.62"
|
||||||
|
override: true
|
||||||
|
default: true
|
||||||
|
components: rustfmt
|
||||||
|
profile: minimal
|
||||||
|
target: x86_64-pc-windows-msvc
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --release --all-features --target=x86_64-pc-windows-msvc
|
||||||
|
use-cross: true
|
||||||
|
|
||||||
|
- name: Publish Artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: binaries-windows-x86_64
|
||||||
|
path: |
|
||||||
|
target\x86_64-pc-windows-msvc\release\hbbr.exe
|
||||||
|
target\x86_64-pc-windows-msvc\release\hbbs.exe
|
||||||
|
target\x86_64-pc-windows-msvc\release\rustdesk-utils.exe
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
# github (draft) release with all binaries
|
# github (draft) release with all binaries
|
||||||
release:
|
release:
|
||||||
|
|
||||||
name: Github release
|
name: Github release
|
||||||
needs: build
|
needs:
|
||||||
|
- build
|
||||||
|
- build-win
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
job:
|
job:
|
||||||
- { name: "amd64" }
|
- { os: "linux", name: "amd64" }
|
||||||
- { name: "arm64v8" }
|
- { os: "linux", name: "arm64v8" }
|
||||||
- { name: "armv7" }
|
- { os: "linux", name: "armv7" }
|
||||||
- { name: "i386" }
|
- { os: "linux", name: "i386" }
|
||||||
|
- { os: "windows", name: "x86_64" }
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Download binaries (${{ matrix.job.name }})
|
- name: Download binaries (${{ matrix.job.os }} - ${{ matrix.job.name }})
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: binaries-${{ matrix.job.name }}
|
name: binaries-${{ matrix.job.os }}-${{ matrix.job.name }}
|
||||||
path: ${{ matrix.job.name }}
|
path: ${{ matrix.job.name }}
|
||||||
|
|
||||||
- name: Pack files (${{ matrix.job.name }})
|
- name: Exec chmod
|
||||||
|
run: chmod -v a+x ${{ matrix.job.name }}/*
|
||||||
|
|
||||||
|
- name: Pack files (${{ matrix.job.os }} - ${{ matrix.job.name }})
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y zip
|
DEBIAN_FRONTEND=noninteractive sudo apt install -y zip
|
||||||
zip ${{ matrix.job.name }}/rustdesk-server-linux-${{ matrix.job.name }}.zip ${{ matrix.job.name }}/hbbr ${{ matrix.job.name }}/hbbs ${{ matrix.job.name }}/rustdesk-utils
|
zip ${{ matrix.job.name }}/rustdesk-server-${{ matrix.job.os }}-${{ matrix.job.name }}.zip ${{ matrix.job.name }}/*
|
||||||
|
|
||||||
- name: Create Release (${{ matrix.job.name }})
|
- name: Create Release (${{ matrix.job.os }} - (${{ matrix.job.name }})
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
files: ${{ matrix.job.name }}/rustdesk-server-linux-${{ matrix.job.name }}.zip
|
files: ${{ matrix.job.name }}/rustdesk-server-${{ matrix.job.os }}-${{ matrix.job.name }}.zip
|
||||||
|
|
||||||
# docker build and push of single-arch images
|
# docker build and push of single-arch images
|
||||||
docker:
|
docker:
|
||||||
@@ -127,7 +171,7 @@ jobs:
|
|||||||
- name: Download binaries
|
- name: Download binaries
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: binaries-${{ matrix.job.name }}
|
name: binaries-linux-${{ matrix.job.name }}
|
||||||
path: docker/rootfs/usr/bin
|
path: docker/rootfs/usr/bin
|
||||||
|
|
||||||
- name: Make binaries executable
|
- name: Make binaries executable
|
||||||
@@ -247,7 +291,7 @@ jobs:
|
|||||||
- name: Download binaries
|
- name: Download binaries
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: binaries-${{ matrix.job.name }}
|
name: binaries-linux-${{ matrix.job.name }}
|
||||||
path: docker-classic/
|
path: docker-classic/
|
||||||
|
|
||||||
- name: Make binaries executable
|
- name: Make binaries executable
|
||||||
@@ -314,7 +358,7 @@ jobs:
|
|||||||
- name: Download binaries
|
- name: Download binaries
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: binaries-${{ matrix.job.name }}
|
name: binaries-linux-${{ matrix.job.name }}
|
||||||
path: debian-build/${{ matrix.job.name }}/bin
|
path: debian-build/${{ matrix.job.name }}/bin
|
||||||
|
|
||||||
- name: Build package for ${{ matrix.job.name }} arch
|
- name: Build package for ${{ matrix.job.name }} arch
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ http = "0.2"
|
|||||||
flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset"] }
|
flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset"] }
|
||||||
ipnetwork = "0.20"
|
ipnetwork = "0.20"
|
||||||
local-ip-address = "0.4"
|
local-ip-address = "0.4"
|
||||||
|
dns-lookup = "1.0.8"
|
||||||
|
ping = "0.4.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
hbb_common = { path = "libs/hbb_common" }
|
hbb_common = { path = "libs/hbb_common" }
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ docker run --name hbbr --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-serv
|
|||||||
|
|
||||||
or without --net=host, but P2P direct connection can not work.
|
or without --net=host, but P2P direct connection can not work.
|
||||||
|
|
||||||
|
For systems using SELinux, replacing `/root` by `/root:z` is required for the containers to run correctly. Alternatively, SELinux container separation can be disabled completely adding the option `--security-opt label=disable`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --name hbbs -p 21115:21115 -p 21116:21116 -p 21116:21116/udp -p 21118:21118 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbs -r <relay-server-ip[:port]>
|
docker run --name hbbs -p 21115:21115 -p 21116:21116 -p 21116:21116/udp -p 21118:21118 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbs -r <relay-server-ip[:port]>
|
||||||
docker run --name hbbr -p 21117:21117 -p 21119:21119 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr
|
docker run --name hbbr -p 21117:21117 -p 21119:21119 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr
|
||||||
|
|||||||
@@ -693,7 +693,7 @@ const PEERS: &str = "peers";
|
|||||||
|
|
||||||
impl PeerConfig {
|
impl PeerConfig {
|
||||||
pub fn load(id: &str) -> PeerConfig {
|
pub fn load(id: &str) -> PeerConfig {
|
||||||
let _ = CONFIG.read().unwrap(); // for lock
|
let _unused = CONFIG.read().unwrap(); // for lock
|
||||||
match confy::load_path(&Self::path(id)) {
|
match confy::load_path(&Self::path(id)) {
|
||||||
Ok(config) => config,
|
Ok(config) => config,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -704,7 +704,7 @@ impl PeerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn store(&self, id: &str) {
|
pub fn store(&self, id: &str) {
|
||||||
let _ = CONFIG.read().unwrap(); // for lock
|
let _unused = CONFIG.read().unwrap(); // for lock
|
||||||
if let Err(err) = confy::store_path(Self::path(id), self) {
|
if let Err(err) = confy::store_path(Self::path(id), self) {
|
||||||
log::error!("Failed to store config: {}", err);
|
log::error!("Failed to store config: {}", err);
|
||||||
}
|
}
|
||||||
@@ -845,7 +845,7 @@ pub struct LanPeers {
|
|||||||
|
|
||||||
impl LanPeers {
|
impl LanPeers {
|
||||||
pub fn load() -> LanPeers {
|
pub fn load() -> LanPeers {
|
||||||
let _ = CONFIG.read().unwrap(); // for lock
|
let _unused = CONFIG.read().unwrap(); // for lock
|
||||||
match confy::load_path(&Config::file_("_lan_peers")) {
|
match confy::load_path(&Config::file_("_lan_peers")) {
|
||||||
Ok(peers) => peers,
|
Ok(peers) => peers,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|||||||
@@ -759,15 +759,11 @@ impl RendezvousServer {
|
|||||||
) -> ResultType<()> {
|
) -> ResultType<()> {
|
||||||
let mut states = BytesMut::zeroed((peers.len() + 7) / 8);
|
let mut states = BytesMut::zeroed((peers.len() + 7) / 8);
|
||||||
for i in 0..peers.len() {
|
for i in 0..peers.len() {
|
||||||
let peer_id = &peers[i];
|
if let Some(peer) = self.pm.get_in_memory(&peers[i]).await {
|
||||||
// bytes index from left to right
|
let elapsed = peer.read().await.last_reg_time.elapsed().as_millis() as i32;
|
||||||
let states_idx = i / 8;
|
// bytes index from left to right
|
||||||
let bit_idx = 7 - i % 8;
|
let states_idx = i / 8;
|
||||||
if let Some(peer) = self.pm.get_in_memory(&peer_id).await {
|
let bit_idx = 7 - i % 8;
|
||||||
let (elapsed, _) = {
|
|
||||||
let r = peer.read().await;
|
|
||||||
(r.last_reg_time.elapsed().as_millis() as i32, r.socket_addr)
|
|
||||||
};
|
|
||||||
if elapsed < REG_TIMEOUT {
|
if elapsed < REG_TIMEOUT {
|
||||||
states[states_idx] |= 0x01 << bit_idx;
|
states[states_idx] |= 0x01 << bit_idx;
|
||||||
}
|
}
|
||||||
|
|||||||
88
src/utils.rs
88
src/utils.rs
@@ -1,8 +1,11 @@
|
|||||||
|
use dns_lookup::{lookup_addr, lookup_host};
|
||||||
use hbb_common::{bail, ResultType};
|
use hbb_common::{bail, ResultType};
|
||||||
use sodiumoxide::crypto::sign;
|
use sodiumoxide::crypto::sign;
|
||||||
use std::env;
|
use std::{
|
||||||
use std::process;
|
env,
|
||||||
use std::str;
|
net::{IpAddr, TcpStream},
|
||||||
|
process, str,
|
||||||
|
};
|
||||||
|
|
||||||
fn print_help() {
|
fn print_help() {
|
||||||
println!(
|
println!(
|
||||||
@@ -10,7 +13,8 @@ fn print_help() {
|
|||||||
rustdesk-util [command]\n
|
rustdesk-util [command]\n
|
||||||
Available Commands:
|
Available Commands:
|
||||||
genkeypair Generate a new keypair
|
genkeypair Generate a new keypair
|
||||||
validatekeypair [public key] [secret key] Validate an existing keypair"
|
validatekeypair [public key] [secret key] Validate an existing keypair
|
||||||
|
doctor [rustdesk-server] Check for server connection problems"
|
||||||
);
|
);
|
||||||
process::exit(0x0001);
|
process::exit(0x0001);
|
||||||
}
|
}
|
||||||
@@ -68,6 +72,76 @@ fn validate_keypair(pk: &str, sk: &str) -> ResultType<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn doctor_tcp(address: std::net::IpAddr, port: &str, desc: &str) {
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
let conn = format!("{}:{}", address, port);
|
||||||
|
if let Ok(_stream) = TcpStream::connect(conn.as_str()) {
|
||||||
|
let elapsed = std::time::Instant::now().duration_since(start);
|
||||||
|
println!(
|
||||||
|
"TCP Port {} ({}): OK in {} ms",
|
||||||
|
port,
|
||||||
|
desc,
|
||||||
|
elapsed.as_millis()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
println!("TCP Port {} ({}): ERROR", port, desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn doctor_ip(server_ip_address: std::net::IpAddr, server_address: Option<&str>) {
|
||||||
|
println!("\nChecking IP address: {}", server_ip_address);
|
||||||
|
println!("Is IPV4: {}", server_ip_address.is_ipv4());
|
||||||
|
println!("Is IPV6: {}", server_ip_address.is_ipv6());
|
||||||
|
|
||||||
|
// reverse dns lookup
|
||||||
|
// TODO: (check) doesn't seem to do reverse lookup on OSX...
|
||||||
|
let reverse = lookup_addr(&server_ip_address).unwrap();
|
||||||
|
if server_address.is_some() {
|
||||||
|
if reverse == server_address.unwrap() {
|
||||||
|
println!("Reverse DNS lookup: '{}' MATCHES server address", reverse);
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"Reverse DNS lookup: '{}' DOESN'T MATCH server address '{}'",
|
||||||
|
reverse,
|
||||||
|
server_address.unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ICMP ping?
|
||||||
|
|
||||||
|
// port check TCP (UDP is hard to check)
|
||||||
|
doctor_tcp(server_ip_address, "21114", "API");
|
||||||
|
doctor_tcp(server_ip_address, "21115", "hbbs extra port for nat test");
|
||||||
|
doctor_tcp(server_ip_address, "21116", "hbbs");
|
||||||
|
doctor_tcp(server_ip_address, "21117", "hbbr tcp");
|
||||||
|
doctor_tcp(server_ip_address, "21118", "hbbs websocket");
|
||||||
|
doctor_tcp(server_ip_address, "21119", "hbbr websocket");
|
||||||
|
|
||||||
|
// TODO: key check
|
||||||
|
}
|
||||||
|
|
||||||
|
fn doctor(server_address_unclean: &str) {
|
||||||
|
let server_address3 = server_address_unclean.trim();
|
||||||
|
let server_address2 = server_address3.to_lowercase();
|
||||||
|
let server_address = server_address2.as_str();
|
||||||
|
println!("Checking server: {}\n", server_address);
|
||||||
|
let server_ipaddr = server_address.parse::<IpAddr>();
|
||||||
|
if server_ipaddr.is_err() {
|
||||||
|
// the passed string is not an ip address
|
||||||
|
let ips: Vec<std::net::IpAddr> = lookup_host(server_address).unwrap();
|
||||||
|
println!("Found {} IP addresses: ", ips.iter().count());
|
||||||
|
|
||||||
|
ips.iter().for_each(|ip| println!(" - {ip}"));
|
||||||
|
|
||||||
|
ips.iter().for_each(|ip| doctor_ip(*ip, Some(server_address)));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// user requested an ip address
|
||||||
|
doctor_ip(server_ipaddr.unwrap(), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<_> = env::args().collect();
|
let args: Vec<_> = env::args().collect();
|
||||||
if args.len() <= 1 {
|
if args.len() <= 1 {
|
||||||
@@ -88,6 +162,12 @@ fn main() {
|
|||||||
}
|
}
|
||||||
println!("Key pair is VALID");
|
println!("Key pair is VALID");
|
||||||
}
|
}
|
||||||
|
"doctor" => {
|
||||||
|
if args.len() <= 2 {
|
||||||
|
error_then_help("You must supply the rustdesk-server address");
|
||||||
|
}
|
||||||
|
doctor(args[2].as_str());
|
||||||
|
}
|
||||||
_ => print_help(),
|
_ => print_help(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user