28 Commits

Author SHA1 Message Date
rustdesk
79f0eb497b trim private key 2024-01-31 11:30:42 +08:00
Paolo Asperti
94ae51458c fix Pk size check (#361)
* more descriptive error

* fix key size check
2024-01-31 11:21:00 +08:00
rustdesk
778c89efb1 bump to 1.1.10-3 2024-01-31 11:20:04 +08:00
rustdesk
a7a0fa7cb5 bump to 1.1.10-2 2024-01-30 19:23:36 +08:00
RustDesk
2d8f6ae4f4 Update changelog 2024-01-30 19:16:44 +08:00
RustDesk
324dfd6a1f fix https://github.com/rustdesk/rustdesk-server/issues/306 2024-01-30 19:02:30 +08:00
RustDesk
70242e6eb2 Update common.rs 2024-01-30 18:29:04 +08:00
RustDesk
42cdfb0885 Merge pull request #348 from paspo/pk-check
private key size check
2024-01-30 18:24:04 +08:00
paspo
cea8403dbc private key size check 2024-01-30 11:18:43 +01:00
RustDesk
0ebfc09f8b Merge pull request #333 from ledeuns/patch-1
Update mac_address
2023-12-25 08:49:52 +08:00
Denis Fondras
2e06125974 Update mac_address
The latest version of mac_address allows to compile rustdesk-server on OpenBSD
2023-12-24 18:21:51 +01:00
RustDesk
fc775102ff Delete .github/workflows/test-selfhosted.yaml 2023-12-22 20:03:30 +08:00
RustDesk
891f388040 Merge pull request #328 from paspo/slim-docker-classic
minimal docker classic images
2023-12-07 17:09:11 +08:00
paspo
8b7f3491b1 minimal docker classic images 2023-12-07 08:15:00 +01:00
rustdesk
27ac9dec56 remove docker again 2023-12-06 02:05:33 +08:00
rustdesk
acf2c6d787 try archlinux/archlinux:base-devel 2023-12-06 01:19:57 +08:00
rustdesk
5f137710be do not use docker for the runner 2023-12-06 00:33:52 +08:00
rustdesk
1a6016f08f specify image 2023-12-06 00:28:59 +08:00
rustdesk
f67e8991ef test self-hosted runner 2023-12-05 23:43:41 +08:00
rustdesk
d81010224d remove sign 2023-12-05 17:22:40 +08:00
rustdesk
4c27143125 bump 1.1.9 2023-12-05 17:09:07 +08:00
rustdesk
9461bbe8f3 remove unused 2023-12-01 11:33:16 +08:00
rustdesk
1142cf105b Fix #324 to remove unsafe 2023-12-01 11:32:07 +08:00
RustDesk
5133af1863 Merge pull request #320 from tschettervictor/patch-1
Update rustdesk-hbbs
2023-11-17 11:44:29 +08:00
tschettervictor
7c7d554609 Update rustdesk-hbbs
typo
2023-11-16 18:27:01 -07:00
RustDesk
272a094fde Delete ask-a-question.md 2023-08-08 10:18:04 +08:00
RustDesk
b33d7954be Merge pull request #292 from dinger1986/master
Update README.md
2023-08-04 16:43:06 +08:00
dinger1986
f519be8e92 Update README.md 2023-08-04 09:23:02 +01:00
16 changed files with 106 additions and 274 deletions

View File

@@ -1,14 +0,0 @@
---
name: Ask a question
about: Ask the community for help
title: ''
labels: 'question'
assignees: ''
---
This is the place for generic questions. Please stay on topic and be polite.
**Notes**
- Please write in english only. If you provide some images in different languages, you're required to write a translation in english.
- In any case, **NEVER** put here the content if your `id_ed25519` file

View File

@@ -113,6 +113,7 @@ jobs:
- name: Sign exe files - name: Sign exe files
uses: GermanBluefox/code-sign-action@v7 uses: GermanBluefox/code-sign-action@v7
if: false
with: with:
certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}' certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}'
password: '${{ secrets.WINDOWS_PFX_PASSWORD }}' password: '${{ secrets.WINDOWS_PFX_PASSWORD }}'
@@ -141,6 +142,7 @@ jobs:
- name: Sign UI setup file - name: Sign UI setup file
uses: GermanBluefox/code-sign-action@v7 uses: GermanBluefox/code-sign-action@v7
if: false
with: with:
certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}' certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}'
password: '${{ secrets.WINDOWS_PFX_PASSWORD }}' password: '${{ secrets.WINDOWS_PFX_PASSWORD }}'

6
Cargo.lock generated
View File

@@ -779,7 +779,7 @@ dependencies = [
[[package]] [[package]]
name = "hbbs" name = "hbbs"
version = "1.1.8" version = "1.1.10-3"
dependencies = [ dependencies = [
"async-speed-limit", "async-speed-limit",
"async-trait", "async-trait",
@@ -1111,9 +1111,9 @@ dependencies = [
[[package]] [[package]]
name = "mac_address" name = "mac_address"
version = "1.1.3" version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d1bc1084549d60725ccc53a2bfa07f67fe4689fda07b05a36531f2988104a" checksum = "4863ee94f19ed315bf3bc00299338d857d4b5bc856af375cc97d237382ad3856"
dependencies = [ dependencies = [
"nix", "nix",
"winapi", "winapi",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "hbbs" name = "hbbs"
version = "1.1.8" version = "1.1.10-3"
authors = ["rustdesk <info@rustdesk.com>"] authors = ["rustdesk <info@rustdesk.com>"]
edition = "2021" edition = "2021"
build = "build.rs" build = "build.rs"
@@ -26,7 +26,7 @@ clap = "2"
rust-ini = "0.18" rust-ini = "0.18"
minreq = { version = "2.4", features = ["punycode"] } minreq = { version = "2.4", features = ["punycode"] }
machine-uid = "0.2" machine-uid = "0.2"
mac_address = "1.1" mac_address = "1.1.5"
whoami = "1.2" whoami = "1.2"
base64 = "0.13" base64 = "0.13"
axum = { version = "0.5", features = ["headers"] } axum = { version = "0.5", features = ["headers"] }

View File

@@ -34,6 +34,8 @@ Three executables will be generated in target/release.
You can find updated binaries on the [releases](https://github.com/rustdesk/rustdesk-server/releases) page. You can find updated binaries on the [releases](https://github.com/rustdesk/rustdesk-server/releases) page.
If you want extra features [RustDesk Server Pro](https://rustdesk.com/pricing.html) might suit you better.
If you want to develop your own server, [rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo) might be a better and simpler start for you than this repo. If you want to develop your own server, [rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo) might be a better and simpler start for you than this repo.
## Docker images ## Docker images

Binary file not shown.

12
debian/changelog vendored
View File

@@ -1,3 +1,15 @@
rustdesk-server (1.1.10-3) UNRELEASED; urgency=medium
* fix on -2
rustdesk-server (1.1.10-2) UNRELEASED; urgency=medium
* fix hangup signal exit when run with nohup
* some minors
rustdesk-server (1.1.9) UNRELEASED; urgency=medium
* remove unsafe
rustdesk-server (1.1.8) UNRELEASED; urgency=medium rustdesk-server (1.1.8) UNRELEASED; urgency=medium
* fix test_hbbs and mask in lan * fix test_hbbs and mask in lan

View File

@@ -1,4 +1,4 @@
FROM ubuntu:20.04 FROM scratch
COPY hbbs /usr/bin/hbbs COPY hbbs /usr/bin/hbbs
COPY hbbr /usr/bin/hbbr COPY hbbr /usr/bin/hbbr
WORKDIR /root WORKDIR /root

View File

@@ -1,5 +1,4 @@
pub mod compress; pub mod compress;
pub mod platform;
pub mod protos; pub mod protos;
pub use bytes; pub use bytes;
use config::Config; use config::Config;

View File

@@ -1,157 +0,0 @@
use crate::ResultType;
lazy_static::lazy_static! {
pub static ref DISTRO: Distro = Distro::new();
}
pub struct Distro {
pub name: String,
pub version_id: String,
}
impl Distro {
fn new() -> Self {
let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release".to_owned())
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
let version_id =
run_cmds("awk -F'=' '/^VERSION_ID=/ {print $2}' /etc/os-release".to_owned())
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
Self { name, version_id }
}
}
pub fn get_display_server() -> String {
let mut session = get_values_of_seat0([0].to_vec())[0].clone();
if session.is_empty() {
// loginctl has not given the expected output. try something else.
if let Ok(sid) = std::env::var("XDG_SESSION_ID") {
// could also execute "cat /proc/self/sessionid"
session = sid;
}
if session.is_empty() {
session = run_cmds("cat /proc/self/sessionid".to_owned()).unwrap_or_default();
}
}
get_display_server_of_session(&session)
}
fn get_display_server_of_session(session: &str) -> String {
let mut display_server = if let Ok(output) =
run_loginctl(Some(vec!["show-session", "-p", "Type", session]))
// Check session type of the session
{
let display_server = String::from_utf8_lossy(&output.stdout)
.replace("Type=", "")
.trim_end()
.into();
if display_server == "tty" {
// If the type is tty...
if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "TTY", session]))
// Get the tty number
{
let tty: String = String::from_utf8_lossy(&output.stdout)
.replace("TTY=", "")
.trim_end()
.into();
if let Ok(xorg_results) = run_cmds(format!("ps -e | grep \"{tty}.\\\\+Xorg\""))
// And check if Xorg is running on that tty
{
if xorg_results.trim_end() != "" {
// If it is, manually return "x11", otherwise return tty
return "x11".to_owned();
}
}
}
}
display_server
} else {
"".to_owned()
};
if display_server.is_empty() || display_server == "tty" {
// loginctl has not given the expected output. try something else.
if let Ok(sestype) = std::env::var("XDG_SESSION_TYPE") {
display_server = sestype;
}
}
// If the session is not a tty, then just return the type as usual
display_server
}
pub fn get_values_of_seat0(indices: Vec<usize>) -> Vec<String> {
if let Ok(output) = run_loginctl(None) {
for line in String::from_utf8_lossy(&output.stdout).lines() {
if line.contains("seat0") {
if let Some(sid) = line.split_whitespace().next() {
if is_active(sid) {
return indices
.into_iter()
.map(|idx| line.split_whitespace().nth(idx).unwrap_or("").to_owned())
.collect::<Vec<String>>();
}
}
}
}
}
// some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73
if let Ok(output) = run_loginctl(None) {
for line in String::from_utf8_lossy(&output.stdout).lines() {
if let Some(sid) = line.split_whitespace().next() {
let d = get_display_server_of_session(sid);
if is_active(sid) && d != "tty" {
return indices
.into_iter()
.map(|idx| line.split_whitespace().nth(idx).unwrap_or("").to_owned())
.collect::<Vec<String>>();
}
}
}
}
return indices
.iter()
.map(|_x| "".to_owned())
.collect::<Vec<String>>();
}
fn is_active(sid: &str) -> bool {
if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "State", sid])) {
String::from_utf8_lossy(&output.stdout).contains("active")
} else {
false
}
}
pub fn run_cmds(cmds: String) -> ResultType<String> {
let output = std::process::Command::new("sh")
.args(vec!["-c", &cmds])
.output()?;
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
#[cfg(not(feature = "flatpak"))]
fn run_loginctl(args: Option<Vec<&str>>) -> std::io::Result<std::process::Output> {
let mut cmd = std::process::Command::new("loginctl");
if let Some(a) = args {
return cmd.args(a).output();
}
cmd.output()
}
#[cfg(feature = "flatpak")]
fn run_loginctl(args: Option<Vec<&str>>) -> std::io::Result<std::process::Output> {
let mut l_args = String::from("loginctl");
if let Some(a) = args {
l_args = format!("{} {}", l_args, a.join(" "));
}
std::process::Command::new("flatpak-spawn")
.args(vec![String::from("--host"), l_args])
.output()
}

View File

@@ -1,2 +0,0 @@
#[cfg(target_os = "linux")]
pub mod linux;

View File

@@ -35,7 +35,7 @@ command=/usr/sbin/daemon
procname=/usr/local/sbin/hbbs procname=/usr/local/sbin/hbbs
rustdesk_hbbs_chdir=/var/db/rustdesk-server rustdesk_hbbs_chdir=/var/db/rustdesk-server
command_args="-p ${pidfile} -o /var/log/rustdesk-hbbs.log ${procname} ${rustdesk_hbbs_args}" command_args="-p ${pidfile} -o /var/log/rustdesk-hbbs.log ${procname} ${rustdesk_hbbs_args}"
## If you want the daemon do its log over syslog comment out the above line and remove the comment from the below replacement ## If you want the daemon to do its log over syslog, comment out the above line and remove the comment from the below replacement
#command_args="-p ${pidfile} -T ${name} ${procname} ${rustdesk_hbbs_args}" #command_args="-p ${pidfile} -T ${name} ${procname} ${rustdesk_hbbs_args}"
start_precmd=rustdesk_hbbs_startprecmd start_precmd=rustdesk_hbbs_startprecmd

View File

@@ -78,7 +78,7 @@ pub fn init_args(args: &str, name: &str, about: &str) {
} }
} }
for (k, v) in matches.args { for (k, v) in matches.args {
if let Some(v) = v.vals.get(0) { if let Some(v) = v.vals.first() {
std::env::set_var(arg_name(k), v.to_string_lossy().to_string()); std::env::set_var(arg_name(k), v.to_string_lossy().to_string());
} }
} }
@@ -113,13 +113,18 @@ pub fn gen_sk(wait: u64) -> (String, Option<sign::SecretKey>) {
if let Ok(mut file) = std::fs::File::open(sk_file) { if let Ok(mut file) = std::fs::File::open(sk_file) {
let mut contents = String::new(); let mut contents = String::new();
if file.read_to_string(&mut contents).is_ok() { if file.read_to_string(&mut contents).is_ok() {
let sk = base64::decode(&contents).unwrap_or_default(); let contents = contents.trim();
let sk = base64::decode(contents).unwrap_or_default();
if sk.len() == sign::SECRETKEYBYTES { if sk.len() == sign::SECRETKEYBYTES {
let mut tmp = [0u8; sign::SECRETKEYBYTES]; let mut tmp = [0u8; sign::SECRETKEYBYTES];
tmp[..].copy_from_slice(&sk); tmp[..].copy_from_slice(&sk);
let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]); let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]);
log::info!("Private key comes from {}", sk_file); log::info!("Private key comes from {}", sk_file);
return (pk, Some(sign::SecretKey(tmp))); return (pk, Some(sign::SecretKey(tmp)));
} else {
// don't use log here, since it is async
println!("Fatal error: malformed private key in {sk_file}.");
std::process::exit(1);
} }
} }
} else { } else {
@@ -156,8 +161,6 @@ pub async fn listen_signal() -> Result<()> {
use hbb_common::tokio::signal::unix::{signal, SignalKind}; use hbb_common::tokio::signal::unix::{signal, SignalKind};
tokio::spawn(async { tokio::spawn(async {
let mut s = signal(SignalKind::hangup())?;
let hangup = s.recv();
let mut s = signal(SignalKind::terminate())?; let mut s = signal(SignalKind::terminate())?;
let terminate = s.recv(); let terminate = s.recv();
let mut s = signal(SignalKind::interrupt())?; let mut s = signal(SignalKind::interrupt())?;
@@ -166,9 +169,6 @@ pub async fn listen_signal() -> Result<()> {
let quit = s.recv(); let quit = s.recv();
tokio::select! { tokio::select! {
_ = hangup => {
log::info!("signal hangup");
}
_ = terminate => { _ = terminate => {
log::info!("signal terminate"); log::info!("signal terminate");
} }

View File

@@ -25,6 +25,7 @@ use std::{
io::prelude::*, io::prelude::*,
io::Error, io::Error,
net::SocketAddr, net::SocketAddr,
sync::atomic::{AtomicUsize, Ordering},
}; };
type Usage = (usize, usize, usize, usize); type Usage = (usize, usize, usize, usize);
@@ -36,11 +37,11 @@ lazy_static::lazy_static! {
static ref BLOCKLIST: RwLock<HashSet<String>> = Default::default(); static ref BLOCKLIST: RwLock<HashSet<String>> = Default::default();
} }
static mut DOWNGRADE_THRESHOLD: f64 = 0.66; static DOWNGRADE_THRESHOLD_100: AtomicUsize = AtomicUsize::new(66); // 0.66
static mut DOWNGRADE_START_CHECK: usize = 1_800_000; // in ms static DOWNGRADE_START_CHECK: AtomicUsize = AtomicUsize::new(1_800_000); // in ms
static mut LIMIT_SPEED: usize = 4 * 1024 * 1024; // in bit/s static LIMIT_SPEED: AtomicUsize = AtomicUsize::new(4 * 1024 * 1024); // in bit/s
static mut TOTAL_BANDWIDTH: usize = 1024 * 1024 * 1024; // in bit/s static TOTAL_BANDWIDTH: AtomicUsize = AtomicUsize::new(1024 * 1024 * 1024); // in bit/s
static mut SINGLE_BANDWIDTH: usize = 16 * 1024 * 1024; // in bit/s static SINGLE_BANDWIDTH: AtomicUsize = AtomicUsize::new(16 * 1024 * 1024); // in bit/s
const BLACKLIST_FILE: &str = "blacklist.txt"; const BLACKLIST_FILE: &str = "blacklist.txt";
const BLOCKLIST_FILE: &str = "blocklist.txt"; const BLOCKLIST_FILE: &str = "blocklist.txt";
@@ -99,57 +100,53 @@ fn check_params() {
.map(|x| x.parse::<f64>().unwrap_or(0.)) .map(|x| x.parse::<f64>().unwrap_or(0.))
.unwrap_or(0.); .unwrap_or(0.);
if tmp > 0. { if tmp > 0. {
unsafe { DOWNGRADE_THRESHOLD_100.store((tmp * 100.) as _, Ordering::SeqCst);
DOWNGRADE_THRESHOLD = tmp;
}
} }
unsafe { log::info!("DOWNGRADE_THRESHOLD: {}", DOWNGRADE_THRESHOLD) }; log::info!(
"DOWNGRADE_THRESHOLD: {}",
DOWNGRADE_THRESHOLD_100.load(Ordering::SeqCst) as f64 / 100.
);
let tmp = std::env::var("DOWNGRADE_START_CHECK") let tmp = std::env::var("DOWNGRADE_START_CHECK")
.map(|x| x.parse::<usize>().unwrap_or(0)) .map(|x| x.parse::<usize>().unwrap_or(0))
.unwrap_or(0); .unwrap_or(0);
if tmp > 0 { if tmp > 0 {
unsafe { DOWNGRADE_START_CHECK.store(tmp * 1000, Ordering::SeqCst);
DOWNGRADE_START_CHECK = tmp * 1000;
}
} }
unsafe { log::info!("DOWNGRADE_START_CHECK: {}s", DOWNGRADE_START_CHECK / 1000) }; log::info!(
"DOWNGRADE_START_CHECK: {}s",
DOWNGRADE_START_CHECK.load(Ordering::SeqCst) / 1000
);
let tmp = std::env::var("LIMIT_SPEED") let tmp = std::env::var("LIMIT_SPEED")
.map(|x| x.parse::<f64>().unwrap_or(0.)) .map(|x| x.parse::<f64>().unwrap_or(0.))
.unwrap_or(0.); .unwrap_or(0.);
if tmp > 0. { if tmp > 0. {
unsafe { LIMIT_SPEED.store((tmp * 1024. * 1024.) as usize, Ordering::SeqCst);
LIMIT_SPEED = (tmp * 1024. * 1024.) as usize;
}
} }
unsafe { log::info!("LIMIT_SPEED: {}Mb/s", LIMIT_SPEED as f64 / 1024. / 1024.) }; log::info!(
"LIMIT_SPEED: {}Mb/s",
LIMIT_SPEED.load(Ordering::SeqCst) as f64 / 1024. / 1024.
);
let tmp = std::env::var("TOTAL_BANDWIDTH") let tmp = std::env::var("TOTAL_BANDWIDTH")
.map(|x| x.parse::<f64>().unwrap_or(0.)) .map(|x| x.parse::<f64>().unwrap_or(0.))
.unwrap_or(0.); .unwrap_or(0.);
if tmp > 0. { if tmp > 0. {
unsafe { TOTAL_BANDWIDTH.store((tmp * 1024. * 1024.) as usize, Ordering::SeqCst);
TOTAL_BANDWIDTH = (tmp * 1024. * 1024.) as usize;
}
} }
unsafe {
log::info!( log::info!(
"TOTAL_BANDWIDTH: {}Mb/s", "TOTAL_BANDWIDTH: {}Mb/s",
TOTAL_BANDWIDTH as f64 / 1024. / 1024. TOTAL_BANDWIDTH.load(Ordering::SeqCst) as f64 / 1024. / 1024.
) );
};
let tmp = std::env::var("SINGLE_BANDWIDTH") let tmp = std::env::var("SINGLE_BANDWIDTH")
.map(|x| x.parse::<f64>().unwrap_or(0.)) .map(|x| x.parse::<f64>().unwrap_or(0.))
.unwrap_or(0.); .unwrap_or(0.);
if tmp > 0. { if tmp > 0. {
unsafe { SINGLE_BANDWIDTH.store((tmp * 1024. * 1024.) as usize, Ordering::SeqCst);
SINGLE_BANDWIDTH = (tmp * 1024. * 1024.) as usize;
}
} }
unsafe { log::info!(
log::info!( "SINGLE_BANDWIDTH: {}Mb/s",
"SINGLE_BANDWIDTH: {}Mb/s", SINGLE_BANDWIDTH.load(Ordering::SeqCst) as f64 / 1024. / 1024.
SINGLE_BANDWIDTH as f64 / 1024. / 1024. )
)
};
} }
async fn check_cmd(cmd: &str, limiter: Limiter) -> String { async fn check_cmd(cmd: &str, limiter: Limiter) -> String {
@@ -233,76 +230,68 @@ async fn check_cmd(cmd: &str, limiter: Limiter) -> String {
if let Some(v) = fds.next() { if let Some(v) = fds.next() {
if let Ok(v) = v.parse::<f64>() { if let Ok(v) = v.parse::<f64>() {
if v > 0. { if v > 0. {
unsafe { DOWNGRADE_THRESHOLD_100.store((v * 100.) as _, Ordering::SeqCst);
DOWNGRADE_THRESHOLD = v;
}
} }
} }
} else { } else {
unsafe { res = format!(
res = format!("{DOWNGRADE_THRESHOLD}\n"); "{}\n",
} DOWNGRADE_THRESHOLD_100.load(Ordering::SeqCst) as f64 / 100.
);
} }
} }
Some("downgrade-start-check" | "t") => { Some("downgrade-start-check" | "t") => {
if let Some(v) = fds.next() { if let Some(v) = fds.next() {
if let Ok(v) = v.parse::<usize>() { if let Ok(v) = v.parse::<usize>() {
if v > 0 { if v > 0 {
unsafe { DOWNGRADE_START_CHECK.store(v * 1000, Ordering::SeqCst);
DOWNGRADE_START_CHECK = v * 1000;
}
} }
} }
} else { } else {
unsafe { res = format!("{}s\n", DOWNGRADE_START_CHECK.load(Ordering::SeqCst) / 1000);
res = format!("{}s\n", DOWNGRADE_START_CHECK / 1000);
}
} }
} }
Some("limit-speed" | "ls") => { Some("limit-speed" | "ls") => {
if let Some(v) = fds.next() { if let Some(v) = fds.next() {
if let Ok(v) = v.parse::<f64>() { if let Ok(v) = v.parse::<f64>() {
if v > 0. { if v > 0. {
unsafe { LIMIT_SPEED.store((v * 1024. * 1024.) as _, Ordering::SeqCst);
LIMIT_SPEED = (v * 1024. * 1024.) as _;
}
} }
} }
} else { } else {
unsafe { res = format!(
res = format!("{}Mb/s\n", LIMIT_SPEED as f64 / 1024. / 1024.); "{}Mb/s\n",
} LIMIT_SPEED.load(Ordering::SeqCst) as f64 / 1024. / 1024.
);
} }
} }
Some("total-bandwidth" | "tb") => { Some("total-bandwidth" | "tb") => {
if let Some(v) = fds.next() { if let Some(v) = fds.next() {
if let Ok(v) = v.parse::<f64>() { if let Ok(v) = v.parse::<f64>() {
if v > 0. { if v > 0. {
unsafe { TOTAL_BANDWIDTH.store((v * 1024. * 1024.) as _, Ordering::SeqCst);
TOTAL_BANDWIDTH = (v * 1024. * 1024.) as _; limiter.set_speed_limit(TOTAL_BANDWIDTH.load(Ordering::SeqCst) as _);
limiter.set_speed_limit(TOTAL_BANDWIDTH as _);
}
} }
} }
} else { } else {
unsafe { res = format!(
res = format!("{}Mb/s\n", TOTAL_BANDWIDTH as f64 / 1024. / 1024.); "{}Mb/s\n",
} TOTAL_BANDWIDTH.load(Ordering::SeqCst) as f64 / 1024. / 1024.
);
} }
} }
Some("single-bandwidth" | "sb") => { Some("single-bandwidth" | "sb") => {
if let Some(v) = fds.next() { if let Some(v) = fds.next() {
if let Ok(v) = v.parse::<f64>() { if let Ok(v) = v.parse::<f64>() {
if v > 0. { if v > 0. {
unsafe { SINGLE_BANDWIDTH.store((v * 1024. * 1024.) as _, Ordering::SeqCst);
SINGLE_BANDWIDTH = (v * 1024. * 1024.) as _;
}
} }
} }
} else { } else {
unsafe { res = format!(
res = format!("{}Mb/s\n", SINGLE_BANDWIDTH as f64 / 1024. / 1024.); "{}Mb/s\n",
} SINGLE_BANDWIDTH.load(Ordering::SeqCst) as f64 / 1024. / 1024.
);
} }
} }
Some("usage" | "u") => { Some("usage" | "u") => {
@@ -336,7 +325,7 @@ async fn check_cmd(cmd: &str, limiter: Limiter) -> String {
async fn io_loop(listener: TcpListener, listener2: TcpListener, key: &str) { async fn io_loop(listener: TcpListener, listener2: TcpListener, key: &str) {
check_params(); check_params();
let limiter = <Limiter>::new(unsafe { TOTAL_BANDWIDTH as _ }); let limiter = <Limiter>::new(TOTAL_BANDWIDTH.load(Ordering::SeqCst) as _);
loop { loop {
tokio::select! { tokio::select! {
res = listener.accept() => { res = listener.accept() => {
@@ -475,10 +464,11 @@ async fn relay(
let mut highest_s = 0; let mut highest_s = 0;
let mut downgrade: bool = false; let mut downgrade: bool = false;
let mut blacked: bool = false; let mut blacked: bool = false;
let limiter = <Limiter>::new(unsafe { SINGLE_BANDWIDTH as _ }); let sb = SINGLE_BANDWIDTH.load(Ordering::SeqCst) as f64;
let blacklist_limiter = <Limiter>::new(unsafe { LIMIT_SPEED as _ }); let limiter = <Limiter>::new(sb);
let blacklist_limiter = <Limiter>::new(LIMIT_SPEED.load(Ordering::SeqCst) as _);
let downgrade_threshold = let downgrade_threshold =
(unsafe { SINGLE_BANDWIDTH as f64 * DOWNGRADE_THRESHOLD } / 1000.) as usize; // in bit/ms (sb * DOWNGRADE_THRESHOLD_100.load(Ordering::SeqCst) as f64 / 100. / 1000.) as usize; // in bit/ms
let mut timer = interval(Duration::from_secs(3)); let mut timer = interval(Duration::from_secs(3));
let mut last_recv_time = std::time::Instant::now(); let mut last_recv_time = std::time::Instant::now();
loop { loop {
@@ -546,7 +536,7 @@ async fn relay(
(elapsed as _, total as _, highest_s as _, speed as _), (elapsed as _, total as _, highest_s as _, speed as _),
); );
total_s = 0; total_s = 0;
if elapsed > unsafe { DOWNGRADE_START_CHECK } if elapsed > DOWNGRADE_START_CHECK.load(Ordering::SeqCst)
&& !downgrade && !downgrade
&& total > elapsed * downgrade_threshold && total > elapsed * downgrade_threshold
{ {

View File

@@ -35,6 +35,7 @@ use sodiumoxide::crypto::sign;
use std::{ use std::{
collections::HashMap, collections::HashMap,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
sync::Arc, sync::Arc,
time::Instant, time::Instant,
}; };
@@ -55,10 +56,10 @@ enum Sink {
} }
type Sender = mpsc::UnboundedSender<Data>; type Sender = mpsc::UnboundedSender<Data>;
type Receiver = mpsc::UnboundedReceiver<Data>; type Receiver = mpsc::UnboundedReceiver<Data>;
static mut ROTATION_RELAY_SERVER: usize = 0; static ROTATION_RELAY_SERVER: AtomicUsize = AtomicUsize::new(0);
type RelayServers = Vec<String>; type RelayServers = Vec<String>;
static CHECK_RELAY_TIMEOUT: u64 = 3_000; static CHECK_RELAY_TIMEOUT: u64 = 3_000;
static mut ALWAYS_USE_RELAY: bool = false; static ALWAYS_USE_RELAY: AtomicBool = AtomicBool::new(false);
#[derive(Clone)] #[derive(Clone)]
struct Inner { struct Inner {
@@ -147,13 +148,11 @@ impl RendezvousServer {
.to_uppercase() .to_uppercase()
== "Y" == "Y"
{ {
unsafe { ALWAYS_USE_RELAY.store(true, Ordering::SeqCst);
ALWAYS_USE_RELAY = true;
}
} }
log::info!( log::info!(
"ALWAYS_USE_RELAY={}", "ALWAYS_USE_RELAY={}",
if unsafe { ALWAYS_USE_RELAY } { if ALWAYS_USE_RELAY.load(Ordering::SeqCst) {
"Y" "Y"
} else { } else {
"N" "N"
@@ -711,7 +710,7 @@ impl RendezvousServer {
let peer_is_lan = self.is_lan(peer_addr); let peer_is_lan = self.is_lan(peer_addr);
let is_lan = self.is_lan(addr); let is_lan = self.is_lan(addr);
let mut relay_server = self.get_relay_server(addr.ip(), peer_addr.ip()); let mut relay_server = self.get_relay_server(addr.ip(), peer_addr.ip());
if unsafe { ALWAYS_USE_RELAY } || (peer_is_lan ^ is_lan) { if ALWAYS_USE_RELAY.load(Ordering::SeqCst) || (peer_is_lan ^ is_lan) {
if peer_is_lan { if peer_is_lan {
// https://github.com/rustdesk/rustdesk-server/issues/24 // https://github.com/rustdesk/rustdesk-server/issues/24
relay_server = self.inner.local_ip.clone() relay_server = self.inner.local_ip.clone()
@@ -905,10 +904,7 @@ impl RendezvousServer {
} else if self.relay_servers.len() == 1 { } else if self.relay_servers.len() == 1 {
return self.relay_servers[0].clone(); return self.relay_servers[0].clone();
} }
let i = unsafe { let i = ROTATION_RELAY_SERVER.fetch_add(1, Ordering::SeqCst) % self.relay_servers.len();
ROTATION_RELAY_SERVER += 1;
ROTATION_RELAY_SERVER % self.relay_servers.len()
};
self.relay_servers[i].clone() self.relay_servers[i].clone()
} }
@@ -1027,13 +1023,17 @@ impl RendezvousServer {
Some("always-use-relay" | "aur") => { Some("always-use-relay" | "aur") => {
if let Some(rs) = fds.next() { if let Some(rs) = fds.next() {
if rs.to_uppercase() == "Y" { if rs.to_uppercase() == "Y" {
unsafe { ALWAYS_USE_RELAY = true }; ALWAYS_USE_RELAY.store(true, Ordering::SeqCst);
} else { } else {
unsafe { ALWAYS_USE_RELAY = false }; ALWAYS_USE_RELAY.store(false, Ordering::SeqCst);
} }
self.tx.send(Data::RelayServers0(rs.to_owned())).ok(); self.tx.send(Data::RelayServers0(rs.to_owned())).ok();
} else { } else {
let _ = writeln!(res, "ALWAYS_USE_RELAY: {:?}", unsafe { ALWAYS_USE_RELAY }); let _ = writeln!(
res,
"ALWAYS_USE_RELAY: {:?}",
ALWAYS_USE_RELAY.load(Ordering::SeqCst)
);
} }
} }
Some("test-geo" | "tg") => { Some("test-geo" | "tg") => {

View File

@@ -15,7 +15,7 @@
!define PRODUCT_NAME "rustdesk_server" !define PRODUCT_NAME "rustdesk_server"
!define PRODUCT_DESCRIPTION "Installer for ${PRODUCT_NAME}" !define PRODUCT_DESCRIPTION "Installer for ${PRODUCT_NAME}"
!define COPYRIGHT "Copyright © 2021" !define COPYRIGHT "Copyright © 2021"
!define VERSION "1.1.8" !define VERSION "1.1.10"
VIProductVersion "${VERSION}.0" VIProductVersion "${VERSION}.0"
VIAddVersionKey "ProductName" "${PRODUCT_NAME}" VIAddVersionKey "ProductName" "${PRODUCT_NAME}"