Browse Source

change sled to sqlite and remove lic

rustdesk 3 years ago
parent
commit
b3f39598a7

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
1
+* text=auto

+ 2 - 6
.gitignore

@@ -1,6 +1,2 @@
1
-/target
2
-**/*.rs.bk
3
-version.rs
4
-sled.db
5
-hbbs.sh
6
-hbbs.conf
1
+target
2
+id*

File diff suppressed because it is too large
+ 2121 - 501
Cargo.lock


+ 27 - 20
Cargo.toml

@@ -1,9 +1,10 @@
1 1
 [package]
2 2
 name = "hbbs"
3
-version = "1.1.4"
4
-authors = ["open-trade <info@opentradesolutions.com>"]
5
-edition = "2018"
6
-build= "build.rs"
3
+version = "1.1.5"
4
+authors = ["open-trade <info@rustdesk.com>"]
5
+edition = "2021"
6
+build = "build.rs"
7
+default-run = "hbbs"
7 8
 
8 9
 [[bin]]
9 10
 name = "hbbr"
@@ -17,22 +18,28 @@ serde_derive = "1.0"
17 18
 serde = "1.0"
18 19
 serde_json = "1.0"
19 20
 lazy_static = "1.4"
20
-clap = "2.33"
21
-rust-ini = "0.16"
22
-minreq = { version = "2.3.1", features = ["punycode"] }
21
+clap = "2"
22
+rust-ini = "0.18"
23
+minreq = { version = "2.4", features = ["punycode"] }
23 24
 machine-uid = "0.2"
24 25
 mac_address = "1.1"
25
-whoami = "0.9"
26
+whoami = "1.2"
26 27
 base64 = "0.13"
27
-cryptoxide = "0.3"
28
-
29
-[build-dependencies]
30
-hbb_common = { path = "libs/hbb_common" }
31
-
32
-[workspace]
33
-members = ["libs/hbb_common"]
34
-
35
-[dependencies.rocksdb]
36
-default-features = false
37
-features = ["lz4"]
38
-version = "0.15"
28
+axum = { version = "0.5", features = ["headers"] }
29
+sqlx = { git = "https://github.com/open-trade/sqlx", features = [ "runtime-tokio-rustls", "sqlite", "macros", "chrono", "json" ] }
30
+deadpool = "0.8"
31
+async-trait = "0.1"
32
+async-speed-limit = { git = "https://github.com/open-trade/async-speed-limit" }
33
+uuid = { version = "0.8", features = ["v4"] }
34
+bcrypt = "0.12"
35
+chrono = "0.4"
36
+jsonwebtoken = "8"
37
+headers = "0.3"
38
+once_cell = "1.8"
39
+sodiumoxide = "0.2"
40
+tokio-tungstenite = "0.17"
41
+tungstenite = "0.17"
42
+regex = "1.4"
43
+tower-http = { version = "0.2", features = ["fs", "trace", "cors"] }
44
+http = "0.2"
45
+flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset"] }

+ 0 - 4
Dockerfile

@@ -1,4 +0,0 @@
1
-FROM ubuntu:20.04
2
-COPY target/release/hbbs /usr/bin/hbbs
3
-COPY target/release/hbbr /usr/bin/hbbr
4
-WORKDIR /root

+ 23 - 0
README.md

@@ -0,0 +1,23 @@
1
+# RustDesk Server Program
2
+
3
+<<<<<<< HEAD
4
+Self-host your own RustDesk server, it is free and open source.
5
+
6
+```
7
+cargo build --release
8
+```
9
+
10
+Two executables will be generated in target/release.
11
+  - hbbs - RustDesk ID/Rendezvous server
12
+  - hbbr - RustDesk relay server
13
+
14
+[**Manual**](https://rustdesk.com/docs/en/self-host/)
15
+=======
16
+**Could you please also help finish below "RustDesk Self-Hosting Sever Survey"? So that we can make it better.**  https://forms.gle/9sDqAC5JBuB4b52S6
17
+
18
+If you are looking for an open source implementation, please go to [rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo).
19
+
20
+[Download](https://github.com/rustdesk/rustdesk-server/releases)
21
+
22
+[Doc](https://rustdesk.com/docs/en/self-host)
23
+>>>>>>> 5043b7ce7f5a2230661381cb9c63f84c60414035

BIN
db_v2.sqlite3


+ 0 - 1
libs/hbb_common

@@ -1 +0,0 @@
1
-Subproject commit ec453e5e65bdb3d082cca30416880e4ee0f3665a

+ 0 - 18
spk/INFO

@@ -1,18 +0,0 @@
1
-package="RustDesk Server"
2
-version="1.1.3"
3
-description="RustDesk is a remote desktop software allowing your own rendezvous/relay server. It attempts to make direct connect via TCP hole punch first, and then forward via relay server if direct connection fails. 4 ports are used. NAT test port: 21115(tcp), ID/rendezvous port: 21116(tcp/udp), relay port: 21117(tcp), Email: (), Key: ()"
4
-displayname="RustDesk Rendezvous/Relay Server"
5
-maintainer="CarrieZ Studio"
6
-maintainer_url="https://rustdesk.com/zh/"
7
-distributor="RustDesk & 裙下孤魂"
8
-support_url="https://rustdesk.com/contact/"
9
-arch="apollolake avoton braswell broadwell broadwellnk bromolow cedarview denverton dockerx64 geminilake grantley kvmx64 purley v1000 x86 x86_64"
10
-os_min_ver="6.1"
11
-reloadui="yes"
12
-startable="yes"
13
-thirdparty="yes"
14
-install_reboot="no"
15
-install_dep_packages=""
16
-install_conflict_packages=""
17
-extractsize=""
18
-checkport="no"

BIN
spk/PACKAGE_ICON.PNG


BIN
spk/PACKAGE_ICON_256.PNG


+ 0 - 54
spk/WIZARD_UIFILES/install_uifile

@@ -1,54 +0,0 @@
1
-[{
2
-    "step_title": "Install Settings",
3
-    "items": [{
4
-        "type": "textfield",
5
-        "desc": "Listening Ports",
6
-        "subitems": [{
7
-            "key": "hbbs_port",
8
-            "desc": "RustDesk ID Server Port",
9
-            "defaultValue": "21116",
10
-            "validator": {
11
-                "allowBlank": false,
12
-                "regex": {
13
-                    "expr": "/^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/",
14
-                    "errorText": "Digit number only"
15
-                }
16
-            }
17
-        }, {
18
-            "key": "hbbr_port",
19
-            "desc": "RustDesk Relay Server Port",
20
-            "defaultValue": "21117",
21
-            "validator": {
22
-                "allowBlank": false,
23
-                "regex": {
24
-                    "expr": "/^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/",
25
-                    "errorText": "Digit number only"
26
-                }
27
-            }
28
-        }]
29
-    },{
30
-        "type": "textfield",
31
-        "desc": "Registered email, check http://rustdesk.com/server for more information",
32
-        "subitems": [{
33
-            "key": "email",
34
-            "desc": "Email",
35
-            "validator": {
36
-                "allowBlank": false,
37
-                "regex": {
38
-                  "expr": "/^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/",
39
-                  "errorText": "Invalid email format"
40
-                }
41
-            }
42
-        }]
43
-    },{
44
-        "type": "textfield",
45
-        "desc": "Only allow the client with the same key",
46
-        "subitems": [{
47
-            "key": "key",
48
-            "desc": "Key",
49
-            "validator": {
50
-                "allowBlank": true
51
-            }
52
-        }]
53
-    }]
54
-    }]

+ 0 - 23
spk/scripts/RustDesk_Server.sc

@@ -1,23 +0,0 @@
1
-[RustDesk_Server_HBBR]
2
-title="RustDesk Server (HBBR_TCP)"
3
-desc="RustDesk Server"
4
-port_forward="yes"
5
-dst.ports="21117/tcp"
6
-
7
-[RustDesk_Server_HBBS_TCP]
8
-title="RustDesk Server (HBBS_TCP)"
9
-desc="RustDesk Server"
10
-port_forward="yes"
11
-dst.ports="21116/tcp"
12
-
13
-[RustDesk_Server_HBBS_UDP]
14
-title="RustDesk Server (HBBS_UDP)"
15
-desc="RustDesk Server"
16
-port_forward="yes"
17
-dst.ports="21116/udp"
18
-
19
-[RustDesk_Server_NAT_TCP]
20
-title="RustDesk Server (NAT_TCP)"
21
-desc="RustDesk Server"
22
-port_forward="yes"
23
-dst.ports="21115/tcp"

+ 0 - 167
spk/scripts/installer

@@ -1,167 +0,0 @@
1
-#!/bin/sh
2
-
3
-PACKAGE_NAME="$SYNOPKG_PKGNAME"
4
-PACKAGE_BASE="/var/packages/${PACKAGE_NAME}/target"
5
-PACKAGE_SSS="/var/packages/${PACKAGE_NAME}/scripts/start-stop-status"
6
-
7
-SERVICETOOL="/usr/syno/bin/servicetool"
8
-GETKEYVALUE="/usr/syno/bin/synogetkeyvalue"
9
-SETKEYVALUE="/usr/syno/bin/synosetkeyvalue"
10
-FWFILENAME="RustDesk_Server.sc"
11
-
12
-[ "${hbbr_port}" == "" ]  && hbbr_port="21117"
13
-[ "${hbbs_port}" == "" ]  && hbbs_port="21116"
14
-[ "${key}" == "" ]  && key=""
15
-[ "${email}" == "" ]  && email=""
16
-nat_port=`expr ${hbbs_port} - 1`
17
-
18
-preinst() {
19
-    exit 0
20
-}
21
-
22
-postinst() {
23
-    if [ "${SYNOPKG_PKG_STATUS}" == "INSTALL" ]; then
24
-        # 导入另一个RustDesk服务器数据
25
-        import_db="false"
26
-        import_all="false"
27
-        if [ "${rds_old_import_all}" == "true" ]; then
28
-            rds_old_import_db="true"
29
-            import_all="true"
30
-        elif [ "${rds_import_all}" == "true" ]; then
31
-            rds_import_db="true"
32
-            import_all="true"
33
-        fi
34
-        if [ "${rds_old_import_db}" == "true" ]; then
35
-            import_db="true"
36
-            PACKAGE_IMPORT_DIR="/var/packages/RustDesk_Server"
37
-        elif [ "${rds_import_db}" == "true" ]; then
38
-            import_db="true"
39
-            PACKAGE_IMPORT_DIR="/var/packages/RustDesk Server"
40
-        fi
41
-        if [ "${import_db}" == "true" ]; then
42
-            [ -x "${PACKAGE_IMPORT_DIR}/scripts/start-stop-status" ] \
43
-                && SYNOPKG_PKGNAME="RustDesk Server" "${PACKAGE_IMPORT_DIR}/scripts/start-stop-status" stop 2>&1
44
-            [ -f "${PACKAGE_IMPORT_DIR}/enabled" ] && rm -f "${PACKAGE_IMPORT_DIR}/enabled"
45
-            [ -d "${PACKAGE_IMPORT_DIR}/target/hbbs.db" ] && cp -prf "${PACKAGE_IMPORT_DIR}/target/hbbs.db" "${PACKAGE_BASE}"
46
-        fi
47
-        if [ "${import_all}" == "true" ]; then
48
-            [ -d "${PACKAGE_IMPORT_DIR}/target/logs" ] && cp -prf "${PACKAGE_IMPORT_DIR}/target/logs" "${PACKAGE_BASE}"
49
-        fi
50
-
51
-        # 添加应用配置
52
-				sed -i "s/relay port: 21117/relay port: ${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/INFO"
53
-				sed -i "s/ID\/rendezvous port: 21116/ID\/rendezvous port: ${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/INFO"
54
-				sed -i "s/NAT test port: 21115/NAT test port: ${nat_port}/" "/var/packages/${PACKAGE_NAME}/INFO"
55
-        sed -i "s/Key: ()/Key: (${key})/" "/var/packages/${PACKAGE_NAME}/INFO"
56
-        sed -i "s/Email: ()/Email: (${email})/" "/var/packages/${PACKAGE_NAME}/INFO"
57
-        sed -i "s/21117/${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}"
58
-        sed -i "s/21116/${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}"
59
-        sed -i "s/21115/${nat_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}"
60
-        sed -i "s/port=[^ ]*/port=${hbbr_port}/g" "${PACKAGE_BASE}/config/hbbr.conf"
61
-        sed -i "s/port=[^ ]*/port=${hbbs_port}/g" "${PACKAGE_BASE}/config/hbbs.conf"
62
-        sed -i "s/key=[^ ]*/key=${key}/g" "${PACKAGE_BASE}/config/hbbs.conf"
63
-        sed -i "s/email=[^ ]*/email=${email}/g" "${PACKAGE_BASE}/config/hbbs.conf"
64
-
65
-        # 添加防火墙配置
66
-        cat "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >"/tmp/${FWFILENAME}"
67
-        ${SERVICETOOL} --install-configure-file --package "/tmp/${FWFILENAME}" >/dev/null
68
-        rm -f "/tmp/${FWFILENAME}"
69
-
70
-        # 设置文件权限
71
-        chmod -R 755 "${PACKAGE_BASE}"/*
72
-		chmod -R 755 "/var/packages/${PACKAGE_NAME}/scripts"/*
73
-		chmod -R 755 "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES"/*
74
-        chmod 644 "/var/packages/${PACKAGE_NAME}/INFO"
75
-    fi
76
-
77
-    exit 0
78
-}
79
-
80
-preuninst() {
81
-    # 停用套件
82
-    "${PACKAGE_SSS}" stop
83
-
84
-    # 删除防火墙配置
85
-    if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ]; then
86
-        ${SERVICETOOL} --remove-configure-file --package "${FWFILENAME}" >/dev/null
87
-    fi
88
-
89
-    exit 0
90
-}
91
-
92
-postuninst() {
93
-    # 删除不必要的目录...
94
-    if [ -d "/usr/syno/etc/packages/${PACKAGE_NAME}" ]; then
95
-        rm -rf "/usr/syno/etc/packages/${PACKAGE_NAME}"
96
-    fi
97
-
98
-    exit 0
99
-}
100
-
101
-preupgrade() {
102
-    # 停用套件
103
-    "${PACKAGE_SSS}" stop
104
-
105
-#  Not working yet...
106
-#    # 检索旧设置...
107
-#    hbbr_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbr.conf" port`
108
-#    hbbs_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" port`
109
-#    sed -i "s/21117/${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES/upgrade_uifile"
110
-#    sed -i "s/21116/${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES/upgrade_uifile"
111
-##  Not working yet...
112
-
113
-    # 备份数据文件...
114
-    if [ -d "${SYNOPKG_PKGDEST}" ]; then
115
-        DIRS4BACKUP="data logs hbbs.db config"
116
-        for DIR in $DIRS4BACKUP; do
117
-            if [ -d "${SYNOPKG_PKGDEST}/${DIR}" ]; then
118
-                mkdir -p "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"
119
-                mv "${SYNOPKG_PKGDEST}/${DIR}"/* "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"
120
-                rmdir "${SYNOPKG_PKGDEST}/${DIR}"
121
-            elif [ -f "${SYNOPKG_PKGDEST}/${DIR}" ]; then
122
-                mv "${SYNOPKG_PKGDEST}/${DIR}" "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade"
123
-            fi
124
-        done
125
-    fi
126
-
127
-    exit 0
128
-}
129
-
130
-postupgrade() {
131
-    # 恢复数据文件...
132
-    if [ -d "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade" ]; then
133
-        for DIR in `ls "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade"`
134
-        do
135
-            if [ -d "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}" ]; then
136
-                [ ! -d "${SYNOPKG_PKGDEST}/${DIR}" ] && mkdir "${SYNOPKG_PKGDEST}/${DIR}"
137
-                mv "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"/* "${SYNOPKG_PKGDEST}/${DIR}"
138
-                rmdir "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"
139
-            elif [ -f "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}" ]; then
140
-                mv "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}" "${SYNOPKG_PKGDEST}"
141
-            fi
142
-        done
143
-        rmdir "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade"
144
-    fi
145
-
146
-    # 恢复设置...
147
-    hbbr_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbr.conf" port` >>/tmp/wakko.txt
148
-    hbbs_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" port` >>/tmp/wakko.txt
149
-    nat_port=`expr ${hbbs_port} - 1`
150
-    key=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" key` >>/tmp/wakko.txt
151
-    email=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" email` >>/tmp/wakko.txt
152
-    sed -i "s/relay port: 21117/relay port: ${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/INFO" >>/tmp/wakko.txt
153
-    sed -i "s/ID\/rendezvous port: 21116/ID\/rendezvous port: ${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/INFO" >>/tmp/wakko.txt
154
-    sed -i "s/NAT test port: 21115/NAT test port: ${nat_port}/" "/var/packages/${PACKAGE_NAME}/INFO" >>/tmp/wakko.txt
155
-    sed -i "s/Key: ()/Key: (${key})/" "/var/packages/${PACKAGE_NAME}/INFO"
156
-    sed -i "s/Email: ()/Email: (${email})/" "/var/packages/${PACKAGE_NAME}/INFO"
157
-    sed -i "s/21117/${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >>/tmp/wakko.txt
158
-    sed -i "s/21116/${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >>/tmp/wakko.txt
159
-    sed -i "s/21115/${nat_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >>/tmp/wakko.txt
160
-
161
-    # 设置文件权限
162
-    chmod -R 755 "/var/packages/${PACKAGE_NAME}/scripts"/*
163
-    chmod -R 755 "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES"/*
164
-    chmod 644 "/var/packages/${PACKAGE_NAME}/INFO"
165
-
166
-    exit 0
167
-}

+ 0 - 3
spk/scripts/postinst

@@ -1,3 +0,0 @@
1
-#!/bin/sh
2
-. "`dirname \"$0\"`/installer"
3
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE

+ 0 - 3
spk/scripts/postuninst

@@ -1,3 +0,0 @@
1
-#!/bin/sh
2
-. "`dirname \"$0\"`/installer"
3
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE

+ 0 - 3
spk/scripts/postupgrade

@@ -1,3 +0,0 @@
1
-#!/bin/sh
2
-. "`dirname \"$0\"`/installer"
3
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE

+ 0 - 3
spk/scripts/preinst

@@ -1,3 +0,0 @@
1
-#!/bin/sh
2
-. "`dirname \"$0\"`/installer"
3
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE

+ 0 - 3
spk/scripts/preuninst

@@ -1,3 +0,0 @@
1
-#!/bin/sh
2
-. "`dirname \"$0\"`/installer"
3
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE

+ 0 - 3
spk/scripts/preupgrade

@@ -1,3 +0,0 @@
1
-#!/bin/sh
2
-. "`dirname \"$0\"`/installer"
3
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE

+ 0 - 158
spk/scripts/start-stop-status

@@ -1,158 +0,0 @@
1
-#!/bin/sh
2
-
3
-
4
-sError="ERROR: "
5
-[ ! -z "$SYNOPKG_PKGNAME" ] && sError="<br />${sError}"
6
-TIMEOUT=120
7
-PACKAGE_NAME="RustDesk Server"
8
-PACKAGE_BASE="/var/packages/${PACKAGE_NAME}/target"
9
-HBBR_BIN="${PACKAGE_BASE}/bin/hbbr"
10
-HBBR_PORT=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbr.conf" port`
11
-HBBR_LOG="/var/log/hbbr.log"
12
-HBBS_BIN="${PACKAGE_BASE}/bin/hbbs"
13
-HBBS_PORT=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbs.conf" port`
14
-KEY=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbs.conf" key`
15
-EMAIL=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbs.conf" email`
16
-HBBS_LOG="/var/log/hbbs.log"
17
-PACKAGE_ENABLED="/var/packages/${PACKAGE_NAME}/enabled"
18
-PS_CMD="/bin/ps -w"
19
-DSM_MAJORVERSION=`synogetkeyvalue /etc.defaults/VERSION majorversion`
20
-if [[ $DSM_MAJORVERSION -gt 5 ]]; then
21
-    PS_CMD="$PS_CMD -x"
22
-fi
23
-
24
-CheckIfDaemonAlive() {
25
-    local PID="$1"
26
-    PROCESS_ALIVE="0"
27
-    [ -z "$PID" ] && return 1
28
-
29
-    kill -0 "$PID"
30
-    [ "0" == "$?" ] && PROCESS_ALIVE="1"
31
-}
32
-
33
-running_hbbr() {
34
-    local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbr | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
35
-    CheckIfDaemonAlive $PID
36
-    [ "0" == "$PROCESS_ALIVE" ] && return 1
37
-    return 0
38
-}
39
-
40
-running_hbbs() {
41
-    local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbs | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
42
-    CheckIfDaemonAlive $PID
43
-    [ "0" == "$PROCESS_ALIVE" ] && return 1
44
-    return 0
45
-}
46
-
47
-start() {  
48
-    [ "$SYNOPKG_TEMP_LOGFILE" == "" ] && SYNOPKG_TEMP_LOGFILE="/var/log/rustdeskserver.start.log"
49
-    LANG=C cd "$PACKAGE_BASE" && (nohup "$HBBR_BIN" -p $HBBR_PORT -k "$KEY" -m "$EMAIL" > "$HBBR_LOG" 2>&1 &) && (nohup "$HBBS_BIN" -p $HBBS_PORT -k "$KEY" -m "$EMAIL" > "$HBBS_LOG" 2>&1 &)
50
-
51
-
52
-    i=0
53
-    while true; do
54
-        if ! running_hbbr || ! running_hbbs ; then
55
-#           echo "WAIT: ${i}s of ${TIMEOUT}s"
56
-            sleep 5s
57
-            i=$((i+5))
58
-        else
59
-            break
60
-        fi
61
-        [ $i -ge $TIMEOUT ] && break
62
-    done
63
-
64
-    # 检查hbbr进程状态
65
-    if ! running_hbbr ; then
66
-        echo -e "${sError}hbbr process not running" | tee -a $SYNOPKG_TEMP_LOGFILE
67
-        stop
68
-        return 1
69
-    fi
70
-
71
-    # 检查hbbs进程状态
72
-    if ! running_hbbs ; then
73
-        echo -e "${sError}hbbs process not running" | tee -a $SYNOPKG_TEMP_LOGFILE
74
-        stop
75
-        return 1
76
-    fi
77
-
78
-    return 0
79
-}
80
-
81
-stop() {
82
-    [ "$SYNOPKG_TEMP_LOGFILE" == "" ] && SYNOPKG_TEMP_LOGFILE="/var/log/rustdeskserver.stop.log"
83
-    # 检查hbbr进程状态
84
-    if running_hbbr ; then
85
-        local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbr | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
86
-        [ -z "$PID" ] && return 0
87
-        kill -15 $PID
88
-        sleep 5s
89
-
90
-        # 检查hbbr进程状态
91
-        if running_hbbr ; then
92
-            kill -9 $PID
93
-            sleep 5s
94
-            if running_hbbr ; then
95
-                echo "${sError}Failed to kill hbbr process(pid=$PID)!" | tee -a $SYNOPKG_TEMP_LOGFILE
96
-                return 1
97
-            fi
98
-        fi
99
-    fi
100
-
101
-    # 检查hbbs进程状态
102
-    if running_hbbs ; then
103
-        local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbs | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
104
-        [ -z "$PID" ] && return 0
105
-        kill -15 $PID
106
-        sleep 5s
107
-
108
-        # 检查hbbs进程状态
109
-        if running_hbbs ; then
110
-            kill -9 $PID
111
-            sleep 5s
112
-            if running_hbbs ; then
113
-                echo "${sError}无法关闭hbbs进程 (pid=$PID)!" | tee -a $SYNOPKG_TEMP_LOGFILE
114
-                return 1
115
-            fi
116
-        fi
117
-    fi
118
-
119
-    return 0
120
-}
121
-
122
-case $1 in
123
-    start)
124
-        # 启动服务器
125
-        start
126
-        exit $?
127
-    ;;
128
-    stop)
129
-        # 关闭服务器
130
-        stop
131
-        exit $?
132
-    ;;
133
-    status)
134
-        # 检查套件开关
135
-        if [ ! -f "${PACKAGE_ENABLED}" ]; then
136
-            echo "${sError}package not started" | tee -a $SYNOPKG_TEMP_LOGFILE
137
-            exit 0
138
-        fi
139
-
140
-        # 检查hbbr进程状态
141
-        if ! running_hbbr ; then
142
-            echo "${sError}hbbr process killed" | tee -a $SYNOPKG_TEMP_LOGFILE
143
-            exit 1
144
-        fi
145
-
146
-        # 检查hbbs进程状态
147
-        if ! running_hbbs ; then
148
-            echo "${sError}hbbs process killed" | tee -a $SYNOPKG_TEMP_LOGFILE
149
-            exit 1
150
-        fi
151
-
152
-        exit 0
153
-    ;;
154
-    log)
155
-        echo "$PACKAGE_BASE/logs/server.log"
156
-        exit 0
157
-    ;;
158
-esac

+ 128 - 0
src/common.rs

@@ -0,0 +1,128 @@
1
+use clap::App;
2
+use hbb_common::{anyhow::Context, log, ResultType};
3
+use ini::Ini;
4
+use sodiumoxide::crypto::sign;
5
+use std::{
6
+    collections::HashMap,
7
+    io::prelude::*,
8
+    io::Read,
9
+    net::{IpAddr, SocketAddr},
10
+    time::{Instant, SystemTime},
11
+};
12
+
13
+pub(crate) fn get_expired_time() -> Instant {
14
+    let now = Instant::now();
15
+    now.checked_sub(std::time::Duration::from_secs(3600))
16
+        .unwrap_or(now)
17
+}
18
+
19
+pub(crate) fn test_if_valid_server(host: &str, name: &str) -> ResultType<SocketAddr> {
20
+    use std::net::ToSocketAddrs;
21
+    let res = if host.contains(":") {
22
+        host.to_socket_addrs()?.next().context("")
23
+    } else {
24
+        format!("{}:{}", host, 0)
25
+            .to_socket_addrs()?
26
+            .next()
27
+            .context("")
28
+    };
29
+    if res.is_err() {
30
+        log::error!("Invalid {} {}: {:?}", name, host, res);
31
+    }
32
+    res
33
+}
34
+
35
+pub(crate) fn get_servers(s: &str, tag: &str) -> Vec<String> {
36
+    let servers: Vec<String> = s
37
+        .split(",")
38
+        .filter(|x| !x.is_empty() && test_if_valid_server(x, tag).is_ok())
39
+        .map(|x| x.to_owned())
40
+        .collect();
41
+    log::info!("{}={:?}", tag, servers);
42
+    servers
43
+}
44
+
45
+#[inline]
46
+fn arg_name(name: &str) -> String {
47
+    name.to_uppercase().replace("_", "-")
48
+}
49
+
50
+pub fn init_args(args: &str, name: &str, about: &str) {
51
+    let matches = App::new(name)
52
+        .version(crate::version::VERSION)
53
+        .author("Purslane Ltd. <info@rustdesk.com>")
54
+        .about(about)
55
+        .args_from_usage(&args)
56
+        .get_matches();
57
+    if let Ok(v) = Ini::load_from_file(".env") {
58
+        if let Some(section) = v.section(None::<String>) {
59
+            section
60
+                .iter()
61
+                .for_each(|(k, v)| std::env::set_var(arg_name(k), v));
62
+        }
63
+    }
64
+    if let Some(config) = matches.value_of("config") {
65
+        if let Ok(v) = Ini::load_from_file(config) {
66
+            if let Some(section) = v.section(None::<String>) {
67
+                section
68
+                    .iter()
69
+                    .for_each(|(k, v)| std::env::set_var(arg_name(k), v));
70
+            }
71
+        }
72
+    }
73
+    for (k, v) in matches.args {
74
+        if let Some(v) = v.vals.get(0) {
75
+            std::env::set_var(arg_name(k), v.to_string_lossy().to_string());
76
+        }
77
+    }
78
+}
79
+
80
+#[inline]
81
+pub fn get_arg(name: &str) -> String {
82
+    get_arg_or(name, "".to_owned())
83
+}
84
+
85
+#[inline]
86
+pub fn get_arg_or(name: &str, default: String) -> String {
87
+    std::env::var(arg_name(name)).unwrap_or(default)
88
+}
89
+
90
+#[inline]
91
+pub fn now() -> u64 {
92
+    SystemTime::now()
93
+        .duration_since(SystemTime::UNIX_EPOCH)
94
+        .map(|x| x.as_secs())
95
+        .unwrap_or_default()
96
+}
97
+
98
+pub fn gen_sk() -> (String, Option<sign::SecretKey>) {
99
+    let sk_file = "id_ed25519";
100
+    if let Ok(mut file) = std::fs::File::open(sk_file) {
101
+        let mut contents = String::new();
102
+        if file.read_to_string(&mut contents).is_ok() {
103
+            let sk = base64::decode(&contents).unwrap_or_default();
104
+            if sk.len() == sign::SECRETKEYBYTES {
105
+                let mut tmp = [0u8; sign::SECRETKEYBYTES];
106
+                tmp[..].copy_from_slice(&sk);
107
+                let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]);
108
+                log::info!("Private key comes from {}", sk_file);
109
+                return (pk, Some(sign::SecretKey(tmp)));
110
+            }
111
+        }
112
+    } else {
113
+        let (pk, sk) = sign::gen_keypair();
114
+        let pub_file = format!("{}.pub", sk_file);
115
+        if let Ok(mut f) = std::fs::File::create(&pub_file) {
116
+            f.write_all(base64::encode(pk).as_bytes()).ok();
117
+            if let Ok(mut f) = std::fs::File::create(sk_file) {
118
+                let s = base64::encode(&sk);
119
+                if f.write_all(s.as_bytes()).is_ok() {
120
+                    log::info!("Private/public key written to {}/{}", sk_file, pub_file);
121
+                    log::debug!("Public key: {:?}", pk);
122
+                    return (base64::encode(pk), Some(sk));
123
+                }
124
+            }
125
+        }
126
+    }
127
+    ("".to_owned(), None)
128
+}

+ 231 - 0
src/database.rs

@@ -0,0 +1,231 @@
1
+use async_trait::async_trait;
2
+use hbb_common::{log, ResultType};
3
+use serde_json::value::Value;
4
+use sqlx::{
5
+    sqlite::SqliteConnectOptions, ConnectOptions, Connection, Error as SqlxError, SqliteConnection,
6
+};
7
+use std::{ops::DerefMut, str::FromStr};
8
+//use sqlx::postgres::PgPoolOptions;
9
+//use sqlx::mysql::MySqlPoolOptions;
10
+
11
+pub(crate) type DB = sqlx::Sqlite;
12
+pub(crate) type MapValue = serde_json::map::Map<String, Value>;
13
+pub(crate) type MapStr = std::collections::HashMap<String, String>;
14
+type Pool = deadpool::managed::Pool<DbPool>;
15
+
16
+pub struct DbPool {
17
+    url: String,
18
+}
19
+
20
+#[async_trait]
21
+impl deadpool::managed::Manager for DbPool {
22
+    type Type = SqliteConnection;
23
+    type Error = SqlxError;
24
+    async fn create(&self) -> Result<SqliteConnection, SqlxError> {
25
+        let mut opt = SqliteConnectOptions::from_str(&self.url).unwrap();
26
+        opt.log_statements(log::LevelFilter::Debug);
27
+        SqliteConnection::connect_with(&opt).await
28
+    }
29
+    async fn recycle(
30
+        &self,
31
+        obj: &mut SqliteConnection,
32
+    ) -> deadpool::managed::RecycleResult<SqlxError> {
33
+        Ok(obj.ping().await?)
34
+    }
35
+}
36
+
37
+#[derive(Clone)]
38
+pub struct Database {
39
+    pool: Pool,
40
+}
41
+
42
+#[derive(Default)]
43
+pub struct Peer {
44
+    pub guid: Vec<u8>,
45
+    pub id: String,
46
+    pub uuid: Vec<u8>,
47
+    pub pk: Vec<u8>,
48
+    pub user: Option<Vec<u8>>,
49
+    pub info: String,
50
+    pub status: Option<i64>,
51
+}
52
+
53
+impl Database {
54
+    pub async fn new(url: &str) -> ResultType<Database> {
55
+        if !std::path::Path::new(url).exists() {
56
+            std::fs::File::create(url).ok();
57
+        }
58
+        let n: usize = std::env::var("MAX_CONNECTIONS")
59
+            .unwrap_or("1".to_owned())
60
+            .parse()
61
+            .unwrap_or(1);
62
+        log::info!("MAX_CONNECTIONS={}", n);
63
+        let pool = Pool::new(
64
+            DbPool {
65
+                url: url.to_owned(),
66
+            },
67
+            n,
68
+        );
69
+        let _ = pool.get().await?; // test
70
+        let db = Database { pool };
71
+        db.create_tables().await?;
72
+        Ok(db)
73
+    }
74
+
75
+    async fn create_tables(&self) -> ResultType<()> {
76
+        sqlx::query!(
77
+            "
78
+            create table if not exists peer (
79
+                guid blob primary key not null,
80
+                id varchar(100) not null,
81
+                uuid blob not null,
82
+                pk blob not null,
83
+                created_at datetime not null default(current_timestamp),
84
+                user blob,
85
+                status tinyint,
86
+                note varchar(300),
87
+                info text not null
88
+            ) without rowid;
89
+            create unique index if not exists index_peer_id on peer (id);
90
+            create index if not exists index_peer_user on peer (user);
91
+            create index if not exists index_peer_created_at on peer (created_at);
92
+            create index if not exists index_peer_status on peer (status);
93
+        "
94
+        )
95
+        .execute(self.pool.get().await?.deref_mut())
96
+        .await?;
97
+        Ok(())
98
+    }
99
+
100
+    pub async fn get_peer(&self, id: &str) -> ResultType<Option<Peer>> {
101
+        Ok(sqlx::query_as!(
102
+            Peer,
103
+            "select guid, id, uuid, pk, user, status, info from peer where id = ?",
104
+            id
105
+        )
106
+        .fetch_optional(self.pool.get().await?.deref_mut())
107
+        .await?)
108
+    }
109
+
110
+    pub async fn get_peer_id(&self, guid: &[u8]) -> ResultType<Option<String>> {
111
+        Ok(sqlx::query!("select id from peer where guid = ?", guid)
112
+            .fetch_optional(self.pool.get().await?.deref_mut())
113
+            .await?
114
+            .map(|x| x.id))
115
+    }
116
+
117
+    #[inline]
118
+    pub async fn get_conn(&self) -> ResultType<deadpool::managed::Object<DbPool>> {
119
+        Ok(self.pool.get().await?)
120
+    }
121
+
122
+    pub async fn update_peer(&self, payload: MapValue, guid: &[u8]) -> ResultType<()> {
123
+        let mut conn = self.get_conn().await?;
124
+        let mut tx = conn.begin().await?;
125
+        if let Some(v) = payload.get("note") {
126
+            let v = get_str(v);
127
+            sqlx::query!("update peer set note = ? where guid = ?", v, guid)
128
+                .execute(&mut tx)
129
+                .await?;
130
+        }
131
+        tx.commit().await?;
132
+        Ok(())
133
+    }
134
+
135
+    pub async fn insert_peer(
136
+        &self,
137
+        id: &str,
138
+        uuid: &Vec<u8>,
139
+        pk: &Vec<u8>,
140
+        info: &str,
141
+    ) -> ResultType<Vec<u8>> {
142
+        let guid = uuid::Uuid::new_v4().as_bytes().to_vec();
143
+        sqlx::query!(
144
+            "insert into peer(guid, id, uuid, pk, info) values(?, ?, ?, ?, ?)",
145
+            guid,
146
+            id,
147
+            uuid,
148
+            pk,
149
+            info
150
+        )
151
+        .execute(self.pool.get().await?.deref_mut())
152
+        .await?;
153
+        Ok(guid)
154
+    }
155
+
156
+    pub async fn update_pk(
157
+        &self,
158
+        guid: &Vec<u8>,
159
+        id: &str,
160
+        pk: &Vec<u8>,
161
+        info: &str,
162
+    ) -> ResultType<()> {
163
+        sqlx::query!(
164
+            "update peer set id=?, pk=?, info=? where guid=?",
165
+            id,
166
+            pk,
167
+            info,
168
+            guid
169
+        )
170
+        .execute(self.pool.get().await?.deref_mut())
171
+        .await?;
172
+        Ok(())
173
+    }
174
+}
175
+
176
+#[cfg(test)]
177
+mod tests {
178
+    use hbb_common::tokio;
179
+    #[test]
180
+    fn test_insert() {
181
+        insert();
182
+    }
183
+
184
+    #[tokio::main(flavor = "multi_thread")]
185
+    async fn insert() {
186
+        let db = super::Database::new("test.sqlite3").await.unwrap();
187
+        let mut jobs = vec![];
188
+        for i in 0..10000 {
189
+            let cloned = db.clone();
190
+            let id = i.to_string();
191
+            let a = tokio::spawn(async move {
192
+                let empty_vec = Vec::new();
193
+                cloned
194
+                    .insert_peer(&id, &empty_vec, &empty_vec, "")
195
+                    .await
196
+                    .unwrap();
197
+            });
198
+            jobs.push(a);
199
+        }
200
+        for i in 0..10000 {
201
+            let cloned = db.clone();
202
+            let id = i.to_string();
203
+            let a = tokio::spawn(async move {
204
+                cloned.get_peer(&id).await.unwrap();
205
+            });
206
+            jobs.push(a);
207
+        }
208
+        hbb_common::futures::future::join_all(jobs).await;
209
+    }
210
+}
211
+
212
+#[inline]
213
+pub fn guid2str(guid: &Vec<u8>) -> String {
214
+    let mut bytes = [0u8; 16];
215
+    bytes[..].copy_from_slice(&guid);
216
+    uuid::Uuid::from_bytes(bytes).to_string()
217
+}
218
+
219
+pub(crate) fn get_str(v: &Value) -> Option<&str> {
220
+    match v {
221
+        Value::String(v) => {
222
+            let v = v.trim();
223
+            if v.is_empty() {
224
+                None
225
+            } else {
226
+                Some(v)
227
+            }
228
+        }
229
+        _ => None,
230
+    }
231
+}

+ 20 - 13
src/hbbr.rs

@@ -1,34 +1,41 @@
1 1
 use clap::App;
2
+mod common;
2 3
 mod relay_server;
3
-use hbb_common::{env_logger::*, ResultType};
4
+use flexi_logger::*;
5
+use hbb_common::{config::RELAY_PORT, ResultType};
4 6
 use relay_server::*;
5
-use std::sync::{Arc, Mutex};
6
-mod lic;
7
+mod version;
7 8
 
8 9
 fn main() -> ResultType<()> {
9
-    init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
10
+    let _logger = Logger::try_with_env_or_str("info")?
11
+        .log_to_stdout()
12
+        .format(opt_format)
13
+        .write_mode(WriteMode::Async)
14
+        .start()?;
10 15
     let args = format!(
11 16
         "-p, --port=[NUMBER(default={})] 'Sets the listening port'
12 17
         -k, --key=[KEY] 'Only allow the client with the same key'
13
-        {}
14 18
         ",
15
-        DEFAULT_PORT,
16
-        lic::EMAIL_ARG
19
+        RELAY_PORT,
17 20
     );
18 21
     let matches = App::new("hbbr")
19
-        .version(hbbs::VERSION)
20
-        .author("CarrieZ Studio<info@rustdesk.com>")
22
+        .version(version::VERSION)
23
+        .author("Purslane Ltd. <info@rustdesk.com>")
21 24
         .about("RustDesk Relay Server")
22 25
         .args_from_usage(&args)
23 26
         .get_matches();
24
-    if !lic::check_lic(matches.value_of("email").unwrap_or(""), hbbs::VERSION) {
27
+    if let Ok(v) = ini::Ini::load_from_file(".env") {
28
+        if let Some(section) = v.section(None::<String>) {
29
+            section.iter().for_each(|(k, v)| std::env::set_var(k, v));
30
+        }
31
+    }
32
+    #[cfg(not(debug_assertions))]
33
+    if !lic::check_lic(matches.value_of("email").unwrap_or(""), version::VERSION) {
25 34
         return Ok(());
26 35
     }
27
-    let stop: Arc<Mutex<bool>> = Default::default();
28 36
     start(
29
-        matches.value_of("port").unwrap_or(DEFAULT_PORT),
37
+        matches.value_of("port").unwrap_or(&RELAY_PORT.to_string()),
30 38
         matches.value_of("key").unwrap_or(""),
31
-        stop,
32 39
     )?;
33 40
     Ok(())
34 41
 }

+ 3 - 3
src/lib.rs

@@ -1,6 +1,6 @@
1 1
 mod rendezvous_server;
2
-mod sled_async;
3 2
 pub use rendezvous_server::*;
4
-use sled_async::*;
3
+pub mod common;
4
+mod database;
5
+mod peer;
5 6
 mod version;
6
-pub use version::*;

+ 0 - 170
src/lic.rs

@@ -1,170 +0,0 @@
1
-use hbb_common::{bail, log, ResultType, rand::{self, Rng}};
2
-use serde_derive::{Deserialize, Serialize};
3
-use std::io::prelude::*;
4
-use std::path::Path;
5
-
6
-#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
7
-pub struct Machine {
8
-    #[serde(default)]
9
-    hostname: String,
10
-    #[serde(default)]
11
-    uid: String,
12
-    #[serde(default)]
13
-    mac: String,
14
-}
15
-
16
-#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
17
-pub struct Post {
18
-    #[serde(default)]
19
-    machine: String,
20
-    #[serde(default)]
21
-    email: String,
22
-    #[serde(default)]
23
-    status: String,
24
-    #[serde(default)]
25
-    version: String,
26
-    #[serde(default)]
27
-    next_check_time: u64,
28
-    #[serde(default)]
29
-    nonce: String,
30
-    #[serde(default)]
31
-    tip: String,
32
-}
33
-
34
-const LICENSE_FILE: &'static str = ".license.txt";
35
-
36
-pub fn check_lic(email: &str, version: &str) -> bool {
37
-    if email.is_empty() {
38
-        log::error!("Registered email required (-m option). Please pay and register on https://rustdesk.com/server.");
39
-        return false;
40
-    }
41
-
42
-    let is_docker = std::path::Path::new("/.dockerenv").exists();
43
-    let machine = if is_docker { "".to_owned() } else { get_lic() };
44
-    if !is_docker {
45
-        let path = Path::new(LICENSE_FILE);
46
-        if Path::is_file(&path) {
47
-            let contents = std::fs::read_to_string(&path).unwrap_or("".to_owned());
48
-            if verify(&contents, &machine) {
49
-                async_check_email(&machine, email, version, 0);
50
-                return true;
51
-            }
52
-        }
53
-    }
54
-
55
-    match check_email(machine.clone(), email.to_owned(), version.to_owned()) {
56
-        Ok(v) => {
57
-            async_check_email(&machine, email, version, v);
58
-            return true;
59
-        }
60
-        Err(err) => {
61
-            log::error!("{}", err);
62
-            return false;
63
-        }
64
-    }
65
-}
66
-
67
-fn async_check_email(machine: &str, email: &str, version: &str, wait: u64) {
68
-    let machine = machine.to_owned();
69
-    let email = email.to_owned();
70
-    let version = version.to_owned();
71
-    std::thread::spawn(move || {
72
-        let mut wait = wait;
73
-        loop {
74
-            let machine = machine.clone();
75
-            let email = email.clone();
76
-            let version = version.clone();
77
-            std::thread::sleep(std::time::Duration::from_secs(wait));
78
-            match check_email(machine, email, version) {
79
-                Ok(v) => {
80
-                    wait = v;
81
-                }
82
-                Err(err) => {
83
-                    log::error!("{}", err);
84
-                    std::process::exit(-1);
85
-                }
86
-            }
87
-        }
88
-    });
89
-}
90
-
91
-fn write_lic(lic: &str) {
92
-    if let Ok(mut f) = std::fs::File::create(LICENSE_FILE) {
93
-        f.write_all(lic.as_bytes()).ok();
94
-        f.sync_all().ok();
95
-    }
96
-}
97
-
98
-fn check_email(machine: String, email: String, version: String) -> ResultType<u64> {
99
-    log::info!("Checking email with the license server ...");
100
-    let mut rng = rand::thread_rng();
101
-    let nonce: usize = rng.gen();
102
-    let nonce = nonce.to_string();
103
-    let resp = minreq::post("http://rustdesk.com/api/check-email")
104
-        .with_body(
105
-            serde_json::to_string(&Post {
106
-                machine: machine.clone(),
107
-                version,
108
-                email,
109
-                nonce: nonce.clone(),
110
-                ..Default::default()
111
-            })
112
-            .unwrap(),
113
-        )
114
-        .send()?;
115
-    if resp.reason_phrase == "OK" {
116
-        let p: Post = serde_json::from_str(&resp.as_str()?)?;
117
-        if !p.status.is_empty() {
118
-            std::fs::remove_file(LICENSE_FILE).ok();
119
-            bail!("{}", p.status);
120
-        }
121
-        if p.nonce.is_empty() {
122
-            bail!("Verification failure: nonce required");
123
-        }
124
-        if !verify(&p.nonce, &nonce) {
125
-            bail!("Verification failure: nonce mismatch");
126
-        }
127
-        if !machine.is_empty() {
128
-            if !verify(&p.machine, &machine) {
129
-                bail!("Verification failure");
130
-            }
131
-            write_lic(&p.machine);
132
-        }
133
-        log::info!("License OK");
134
-        if !p.tip.is_empty() {
135
-            log::info!("{}", p.tip);
136
-        }
137
-        let mut wait = p.next_check_time;
138
-        if wait == 0 {
139
-            wait = 3600 * 24 * 30;
140
-        }
141
-
142
-        Ok(wait)
143
-    } else {
144
-        bail!("Server error: {}", resp.reason_phrase);
145
-    }
146
-}
147
-
148
-fn get_lic() -> String {
149
-    let hostname = whoami::hostname();
150
-    let uid = machine_uid::get().unwrap_or("".to_owned());
151
-    let mac = if let Ok(Some(ma)) = mac_address::get_mac_address() {
152
-        base64::encode(ma.bytes())
153
-    } else {
154
-        "".to_owned()
155
-    };
156
-    serde_json::to_string(&Machine { hostname, uid, mac }).unwrap()
157
-}
158
-
159
-fn verify(enc_str: &str, msg: &str) -> bool {
160
-    if let Ok(data) = base64::decode(enc_str) {
161
-        let key =
162
-            b"\xf1T\xc0\x1c\xffee\x86,S*\xd9.\x91\xcd\x85\x12:\xec\xa9 \x99:\x8a\xa2S\x1f Yy\x93R";
163
-        cryptoxide::ed25519::verify(msg.as_bytes(), &key[..], &data)
164
-    } else {
165
-        false
166
-    }
167
-}
168
-
169
-pub const EMAIL_ARG: &'static str =
170
-    "-m, --email=[EMAIL] 'Sets your email address registered with RustDesk'";

+ 21 - 65
src/main.rs

@@ -1,15 +1,18 @@
1 1
 // https://tools.ietf.org/rfc/rfc5128.txt
2 2
 // https://blog.csdn.net/bytxl/article/details/44344855
3 3
 
4
-use clap::App;
5
-use hbb_common::{env_logger::*, log, ResultType};
6
-use hbbs::*;
7
-mod lic;
8
-use ini::Ini;
9
-use std::sync::{Arc, Mutex};
4
+use flexi_logger::*;
5
+use hbb_common::{bail, config::RENDEZVOUS_PORT, ResultType};
6
+use hbbs::{common::*, *};
7
+
8
+const RMEM: usize = 0;
10 9
 
11 10
 fn main() -> ResultType<()> {
12
-    init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
11
+    let _logger = Logger::try_with_env_or_str("info")?
12
+        .log_to_stdout()
13
+        .format(opt_format)
14
+        .write_mode(WriteMode::Async)
15
+        .start()?;
13 16
     let args = format!(
14 17
         "-c --config=[FILE] +takes_value 'Sets a custom config file'
15 18
         -p, --port=[NUMBER(default={})] 'Sets the listening port'
@@ -18,66 +21,19 @@ fn main() -> ResultType<()> {
18 21
         -u, --software-url=[URL] 'Sets download url of RustDesk software of newest version'
19 22
         -r, --relay-servers=[HOST] 'Sets the default relay servers, seperated by colon'
20 23
         -C, --change-id=[BOOL(default=Y)] 'Sets if support to change id'
21
-        {}
24
+        -M, --rmem=[NUMBER(default={})] 'Sets UDP recv buffer size, set system rmem_max first, e.g., sudo sysctl -w net.core.rmem_max=52428800. vi /etc/sysctl.conf, net.core.rmem_max=52428800, sudo sysctl –p'
22 25
         -k, --key=[KEY] 'Only allow the client with the same key'",
23
-        DEFAULT_PORT,
24
-        lic::EMAIL_ARG
26
+        RENDEZVOUS_PORT,
27
+        RMEM,
25 28
     );
26
-    let matches = App::new("hbbs")
27
-        .version(crate::VERSION)
28
-        .author("CarrieZ Studio<info@rustdesk.com>")
29
-        .about("RustDesk ID/Rendezvous Server")
30
-        .args_from_usage(&args)
31
-        .get_matches();
32
-    let mut section = None;
33
-    let conf; // for holding section
34
-    if let Some(config) = matches.value_of("config") {
35
-        if let Ok(v) = Ini::load_from_file(config) {
36
-            conf = v;
37
-            section = conf.section(None::<String>);
38
-        }
39
-    }
40
-    let get_arg = |name: &str, default: &str| -> String {
41
-        if let Some(v) = matches.value_of(name) {
42
-            return v.to_owned();
43
-        } else if let Some(section) = section {
44
-            if let Some(v) = section.get(name) {
45
-                return v.to_owned();
46
-            }
47
-        }
48
-        return default.to_owned();
49
-    };
50
-    if !lic::check_lic(&get_arg("email", ""), crate::VERSION) {
51
-        return Ok(());
29
+    init_args(&args, "hbbs", "RustDesk ID/Rendezvous Server");
30
+    let port = get_arg_or("port", RENDEZVOUS_PORT.to_string()).parse::<i32>()?;
31
+    if port < 3 {
32
+        bail!("Invalid port");
52 33
     }
53
-    let port = get_arg("port", DEFAULT_PORT);
54
-    let relay_servers: Vec<String> = get_arg("relay-servers", "")
55
-        .split(",")
56
-        .filter(|x| !x.is_empty() && test_if_valid_server(x, "relay-server").is_ok())
57
-        .map(|x| x.to_owned())
58
-        .collect();
59
-    let serial: i32 = get_arg("serial", "").parse().unwrap_or(0);
60
-    let id_change_support: bool = get_arg("change-id", "Y").to_uppercase() == "Y";
61
-    let rendezvous_servers: Vec<String> = get_arg("rendezvous-servers", "")
62
-        .split(",")
63
-        .filter(|x| !x.is_empty() && test_if_valid_server(x, "rendezvous-server").is_ok())
64
-        .map(|x| x.to_owned())
65
-        .collect();
66
-    let addr = format!("0.0.0.0:{}", port);
67
-    let addr2 = format!("0.0.0.0:{}", port.parse::<i32>().unwrap_or(0) - 1);
68
-    log::info!("serial={}", serial);
69
-    log::info!("rendezvous-servers={:?}", rendezvous_servers);
70
-    let stop: Arc<Mutex<bool>> = Default::default();
71
-    RendezvousServer::start(
72
-        &addr,
73
-        &addr2,
74
-        relay_servers,
75
-        serial,
76
-        rendezvous_servers,
77
-        get_arg("software-url", ""),
78
-        &get_arg("key", ""),
79
-        stop,
80
-        id_change_support,
81
-    )?;
34
+    let rmem = get_arg("rmem").parse::<usize>().unwrap_or(RMEM);
35
+    let serial: i32 = get_arg("serial").parse().unwrap_or(0);
36
+    let id_change_support: bool = get_arg_or("change-id", "Y".to_owned()).to_uppercase() == "Y";
37
+    RendezvousServer::start(port, serial, &get_arg("key"), id_change_support, rmem)?;
82 38
     Ok(())
83 39
 }

+ 185 - 0
src/peer.rs

@@ -0,0 +1,185 @@
1
+use crate::common::*;
2
+use crate::database;
3
+use hbb_common::{
4
+    log,
5
+    rendezvous_proto::*,
6
+    tokio::sync::{Mutex, RwLock},
7
+    ResultType,
8
+};
9
+use serde_derive::{Deserialize, Serialize};
10
+use std::{collections::HashMap, collections::HashSet, net::SocketAddr, sync::Arc, time::Instant};
11
+
12
+lazy_static::lazy_static! {
13
+    pub(crate) static ref IP_BLOCKER: Mutex<HashMap<String, ((u32, Instant), (HashSet<String>, Instant))>> = Default::default();
14
+    pub(crate) static ref USER_STATUS: RwLock<HashMap<Vec<u8>, Arc<(Option<Vec<u8>>, bool)>>> = Default::default();
15
+    pub(crate) static ref IP_CHANGES: Mutex<HashMap<String, (Instant, HashMap<String, i32>)>> = Default::default();
16
+}
17
+pub static IP_CHANGE_DUR: u64 = 180;
18
+pub static IP_CHANGE_DUR_X2: u64 = IP_CHANGE_DUR * 2;
19
+pub static DAY_SECONDS: u64 = 3600 * 24;
20
+pub static IP_BLOCK_DUR: u64 = 60;
21
+
22
+#[derive(Debug, Default, Serialize, Deserialize, Clone)]
23
+pub(crate) struct PeerInfo {
24
+    #[serde(default)]
25
+    pub(crate) ip: String,
26
+}
27
+
28
+#[derive(Clone, Debug)]
29
+pub(crate) struct Peer {
30
+    pub(crate) socket_addr: SocketAddr,
31
+    pub(crate) last_reg_time: Instant,
32
+    pub(crate) guid: Vec<u8>,
33
+    pub(crate) uuid: Vec<u8>,
34
+    pub(crate) pk: Vec<u8>,
35
+    pub(crate) user: Option<Vec<u8>>,
36
+    pub(crate) info: PeerInfo,
37
+    pub(crate) disabled: bool,
38
+    pub(crate) reg_pk: (u32, Instant), // how often register_pk
39
+}
40
+
41
+impl Default for Peer {
42
+    fn default() -> Self {
43
+        Self {
44
+            socket_addr: "0.0.0.0:0".parse().unwrap(),
45
+            last_reg_time: get_expired_time(),
46
+            guid: Vec::new(),
47
+            uuid: Vec::new(),
48
+            pk: Vec::new(),
49
+            info: Default::default(),
50
+            user: None,
51
+            disabled: false,
52
+            reg_pk: (0, get_expired_time()),
53
+        }
54
+    }
55
+}
56
+
57
+pub(crate) type LockPeer = Arc<RwLock<Peer>>;
58
+
59
+#[derive(Clone)]
60
+pub(crate) struct PeerMap {
61
+    map: Arc<RwLock<HashMap<String, LockPeer>>>,
62
+    pub(crate) db: database::Database,
63
+}
64
+
65
+impl PeerMap {
66
+    pub(crate) async fn new() -> ResultType<Self> {
67
+        let db = std::env::var("DB_URL").unwrap_or({
68
+            #[allow(unused_mut)]
69
+            let mut db = "db_v2.sqlite3".to_owned();
70
+            #[cfg(all(windows, not(debug_assertions)))]
71
+            {
72
+                if let Some(path) = hbb_common::config::Config::icon_path().parent() {
73
+                    db = format!("{}\\{}", path.to_str().unwrap_or("."), db);
74
+                }
75
+            }
76
+            #[cfg(not(windows))]
77
+            {
78
+                db = format!("./{}", db);
79
+            }
80
+            db
81
+        });
82
+        log::info!("DB_URL={}", db);
83
+        let pm = Self {
84
+            map: Default::default(),
85
+            db: database::Database::new(&db).await?,
86
+        };
87
+        Ok(pm)
88
+    }
89
+
90
+    #[inline]
91
+    pub(crate) async fn update_pk(
92
+        &mut self,
93
+        id: String,
94
+        peer: LockPeer,
95
+        addr: SocketAddr,
96
+        uuid: Vec<u8>,
97
+        pk: Vec<u8>,
98
+        ip: String,
99
+    ) -> register_pk_response::Result {
100
+        log::info!("update_pk {} {:?} {:?} {:?}", id, addr, uuid, pk);
101
+        let (info_str, guid) = {
102
+            let mut w = peer.write().await;
103
+            w.socket_addr = addr;
104
+            w.uuid = uuid.clone();
105
+            w.pk = pk.clone();
106
+            w.last_reg_time = Instant::now();
107
+            w.info.ip = ip;
108
+            (
109
+                serde_json::to_string(&w.info).unwrap_or_default(),
110
+                w.guid.clone(),
111
+            )
112
+        };
113
+        if guid.is_empty() {
114
+            match self.db.insert_peer(&id, &uuid, &pk, &info_str).await {
115
+                Err(err) => {
116
+                    log::error!("db.insert_peer failed: {}", err);
117
+                    return register_pk_response::Result::SERVER_ERROR;
118
+                }
119
+                Ok(guid) => {
120
+                    peer.write().await.guid = guid;
121
+                }
122
+            }
123
+        } else {
124
+            if let Err(err) = self.db.update_pk(&guid, &id, &pk, &info_str).await {
125
+                log::error!("db.update_pk failed: {}", err);
126
+                return register_pk_response::Result::SERVER_ERROR;
127
+            }
128
+            log::info!("pk updated instead of insert");
129
+        }
130
+        register_pk_response::Result::OK
131
+    }
132
+
133
+    #[inline]
134
+    pub(crate) async fn get(&self, id: &str) -> Option<LockPeer> {
135
+        let p = self.map.read().await.get(id).map(|x| x.clone());
136
+        if p.is_some() {
137
+            return p;
138
+        } else {
139
+            if let Ok(Some(v)) = self.db.get_peer(id).await {
140
+                let peer = Peer {
141
+                    guid: v.guid,
142
+                    uuid: v.uuid,
143
+                    pk: v.pk,
144
+                    user: v.user,
145
+                    info: serde_json::from_str::<PeerInfo>(&v.info).unwrap_or_default(),
146
+                    disabled: v.status == Some(0),
147
+                    ..Default::default()
148
+                };
149
+                let peer = Arc::new(RwLock::new(peer));
150
+                self.map.write().await.insert(id.to_owned(), peer.clone());
151
+                return Some(peer);
152
+            }
153
+        }
154
+        None
155
+    }
156
+
157
+    #[inline]
158
+    pub(crate) async fn get_or(&self, id: &str) -> LockPeer {
159
+        if let Some(p) = self.get(id).await {
160
+            return p;
161
+        }
162
+        let mut w = self.map.write().await;
163
+        if let Some(p) = w.get(id) {
164
+            return p.clone();
165
+        }
166
+        let tmp = LockPeer::default();
167
+        w.insert(id.to_owned(), tmp.clone());
168
+        tmp
169
+    }
170
+
171
+    #[inline]
172
+    pub(crate) async fn get_in_memory(&self, id: &str) -> Option<LockPeer> {
173
+        self.map.read().await.get(id).map(|x| x.clone())
174
+    }
175
+
176
+    #[inline]
177
+    pub(crate) async fn is_in_memory(&self, id: &str) -> bool {
178
+        self.map.read().await.contains_key(id)
179
+    }
180
+
181
+    #[inline]
182
+    pub(crate) async fn remove(&self, id: &str) {
183
+        self.map.write().await.remove(id);
184
+    }
185
+}

+ 0 - 930
src/protos/message.rs

@@ -1,930 +0,0 @@
1
-// This file is generated by rust-protobuf 2.10.2. Do not edit
2
-// @generated
3
-
4
-// https://github.com/rust-lang/rust-clippy/issues/702
5
-#![allow(unknown_lints)]
6
-#![allow(clippy::all)]
7
-
8
-#![cfg_attr(rustfmt, rustfmt_skip)]
9
-
10
-#![allow(box_pointers)]
11
-#![allow(dead_code)]
12
-#![allow(missing_docs)]
13
-#![allow(non_camel_case_types)]
14
-#![allow(non_snake_case)]
15
-#![allow(non_upper_case_globals)]
16
-#![allow(trivial_casts)]
17
-#![allow(unsafe_code)]
18
-#![allow(unused_imports)]
19
-#![allow(unused_results)]
20
-//! Generated file from `message.proto`
21
-
22
-use protobuf::Message as Message_imported_for_functions;
23
-use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
24
-
25
-/// Generated files are compatible only with the same version
26
-/// of protobuf runtime.
27
-// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_10_2;
28
-
29
-#[derive(PartialEq,Clone,Default)]
30
-pub struct RegisterPeer {
31
-    // message fields
32
-    pub hbb_addr: ::std::string::String,
33
-    // special fields
34
-    pub unknown_fields: ::protobuf::UnknownFields,
35
-    pub cached_size: ::protobuf::CachedSize,
36
-}
37
-
38
-impl<'a> ::std::default::Default for &'a RegisterPeer {
39
-    fn default() -> &'a RegisterPeer {
40
-        <RegisterPeer as ::protobuf::Message>::default_instance()
41
-    }
42
-}
43
-
44
-impl RegisterPeer {
45
-    pub fn new() -> RegisterPeer {
46
-        ::std::default::Default::default()
47
-    }
48
-
49
-    // string hbb_addr = 1;
50
-
51
-
52
-    pub fn get_hbb_addr(&self) -> &str {
53
-        &self.hbb_addr
54
-    }
55
-    pub fn clear_hbb_addr(&mut self) {
56
-        self.hbb_addr.clear();
57
-    }
58
-
59
-    // Param is passed by value, moved
60
-    pub fn set_hbb_addr(&mut self, v: ::std::string::String) {
61
-        self.hbb_addr = v;
62
-    }
63
-
64
-    // Mutable pointer to the field.
65
-    // If field is not initialized, it is initialized with default value first.
66
-    pub fn mut_hbb_addr(&mut self) -> &mut ::std::string::String {
67
-        &mut self.hbb_addr
68
-    }
69
-
70
-    // Take field
71
-    pub fn take_hbb_addr(&mut self) -> ::std::string::String {
72
-        ::std::mem::replace(&mut self.hbb_addr, ::std::string::String::new())
73
-    }
74
-}
75
-
76
-impl ::protobuf::Message for RegisterPeer {
77
-    fn is_initialized(&self) -> bool {
78
-        true
79
-    }
80
-
81
-    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
82
-        while !is.eof()? {
83
-            let (field_number, wire_type) = is.read_tag_unpack()?;
84
-            match field_number {
85
-                1 => {
86
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.hbb_addr)?;
87
-                },
88
-                _ => {
89
-                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
90
-                },
91
-            };
92
-        }
93
-        ::std::result::Result::Ok(())
94
-    }
95
-
96
-    // Compute sizes of nested messages
97
-    #[allow(unused_variables)]
98
-    fn compute_size(&self) -> u32 {
99
-        let mut my_size = 0;
100
-        if !self.hbb_addr.is_empty() {
101
-            my_size += ::protobuf::rt::string_size(1, &self.hbb_addr);
102
-        }
103
-        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
104
-        self.cached_size.set(my_size);
105
-        my_size
106
-    }
107
-
108
-    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
109
-        if !self.hbb_addr.is_empty() {
110
-            os.write_string(1, &self.hbb_addr)?;
111
-        }
112
-        os.write_unknown_fields(self.get_unknown_fields())?;
113
-        ::std::result::Result::Ok(())
114
-    }
115
-
116
-    fn get_cached_size(&self) -> u32 {
117
-        self.cached_size.get()
118
-    }
119
-
120
-    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
121
-        &self.unknown_fields
122
-    }
123
-
124
-    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
125
-        &mut self.unknown_fields
126
-    }
127
-
128
-    fn as_any(&self) -> &dyn (::std::any::Any) {
129
-        self as &dyn (::std::any::Any)
130
-    }
131
-    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
132
-        self as &mut dyn (::std::any::Any)
133
-    }
134
-    fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
135
-        self
136
-    }
137
-
138
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
139
-        Self::descriptor_static()
140
-    }
141
-
142
-    fn new() -> RegisterPeer {
143
-        RegisterPeer::new()
144
-    }
145
-
146
-    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
147
-        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
148
-            lock: ::protobuf::lazy::ONCE_INIT,
149
-            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
150
-        };
151
-        unsafe {
152
-            descriptor.get(|| {
153
-                let mut fields = ::std::vec::Vec::new();
154
-                fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
155
-                    "hbb_addr",
156
-                    |m: &RegisterPeer| { &m.hbb_addr },
157
-                    |m: &mut RegisterPeer| { &mut m.hbb_addr },
158
-                ));
159
-                ::protobuf::reflect::MessageDescriptor::new::<RegisterPeer>(
160
-                    "RegisterPeer",
161
-                    fields,
162
-                    file_descriptor_proto()
163
-                )
164
-            })
165
-        }
166
-    }
167
-
168
-    fn default_instance() -> &'static RegisterPeer {
169
-        static mut instance: ::protobuf::lazy::Lazy<RegisterPeer> = ::protobuf::lazy::Lazy {
170
-            lock: ::protobuf::lazy::ONCE_INIT,
171
-            ptr: 0 as *const RegisterPeer,
172
-        };
173
-        unsafe {
174
-            instance.get(RegisterPeer::new)
175
-        }
176
-    }
177
-}
178
-
179
-impl ::protobuf::Clear for RegisterPeer {
180
-    fn clear(&mut self) {
181
-        self.hbb_addr.clear();
182
-        self.unknown_fields.clear();
183
-    }
184
-}
185
-
186
-impl ::std::fmt::Debug for RegisterPeer {
187
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
188
-        ::protobuf::text_format::fmt(self, f)
189
-    }
190
-}
191
-
192
-impl ::protobuf::reflect::ProtobufValue for RegisterPeer {
193
-    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
194
-        ::protobuf::reflect::ProtobufValueRef::Message(self)
195
-    }
196
-}
197
-
198
-#[derive(PartialEq,Clone,Default)]
199
-pub struct PeekPeer {
200
-    // message fields
201
-    pub hbb_addr: ::std::string::String,
202
-    // special fields
203
-    pub unknown_fields: ::protobuf::UnknownFields,
204
-    pub cached_size: ::protobuf::CachedSize,
205
-}
206
-
207
-impl<'a> ::std::default::Default for &'a PeekPeer {
208
-    fn default() -> &'a PeekPeer {
209
-        <PeekPeer as ::protobuf::Message>::default_instance()
210
-    }
211
-}
212
-
213
-impl PeekPeer {
214
-    pub fn new() -> PeekPeer {
215
-        ::std::default::Default::default()
216
-    }
217
-
218
-    // string hbb_addr = 1;
219
-
220
-
221
-    pub fn get_hbb_addr(&self) -> &str {
222
-        &self.hbb_addr
223
-    }
224
-    pub fn clear_hbb_addr(&mut self) {
225
-        self.hbb_addr.clear();
226
-    }
227
-
228
-    // Param is passed by value, moved
229
-    pub fn set_hbb_addr(&mut self, v: ::std::string::String) {
230
-        self.hbb_addr = v;
231
-    }
232
-
233
-    // Mutable pointer to the field.
234
-    // If field is not initialized, it is initialized with default value first.
235
-    pub fn mut_hbb_addr(&mut self) -> &mut ::std::string::String {
236
-        &mut self.hbb_addr
237
-    }
238
-
239
-    // Take field
240
-    pub fn take_hbb_addr(&mut self) -> ::std::string::String {
241
-        ::std::mem::replace(&mut self.hbb_addr, ::std::string::String::new())
242
-    }
243
-}
244
-
245
-impl ::protobuf::Message for PeekPeer {
246
-    fn is_initialized(&self) -> bool {
247
-        true
248
-    }
249
-
250
-    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
251
-        while !is.eof()? {
252
-            let (field_number, wire_type) = is.read_tag_unpack()?;
253
-            match field_number {
254
-                1 => {
255
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.hbb_addr)?;
256
-                },
257
-                _ => {
258
-                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
259
-                },
260
-            };
261
-        }
262
-        ::std::result::Result::Ok(())
263
-    }
264
-
265
-    // Compute sizes of nested messages
266
-    #[allow(unused_variables)]
267
-    fn compute_size(&self) -> u32 {
268
-        let mut my_size = 0;
269
-        if !self.hbb_addr.is_empty() {
270
-            my_size += ::protobuf::rt::string_size(1, &self.hbb_addr);
271
-        }
272
-        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
273
-        self.cached_size.set(my_size);
274
-        my_size
275
-    }
276
-
277
-    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
278
-        if !self.hbb_addr.is_empty() {
279
-            os.write_string(1, &self.hbb_addr)?;
280
-        }
281
-        os.write_unknown_fields(self.get_unknown_fields())?;
282
-        ::std::result::Result::Ok(())
283
-    }
284
-
285
-    fn get_cached_size(&self) -> u32 {
286
-        self.cached_size.get()
287
-    }
288
-
289
-    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
290
-        &self.unknown_fields
291
-    }
292
-
293
-    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
294
-        &mut self.unknown_fields
295
-    }
296
-
297
-    fn as_any(&self) -> &dyn (::std::any::Any) {
298
-        self as &dyn (::std::any::Any)
299
-    }
300
-    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
301
-        self as &mut dyn (::std::any::Any)
302
-    }
303
-    fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
304
-        self
305
-    }
306
-
307
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
308
-        Self::descriptor_static()
309
-    }
310
-
311
-    fn new() -> PeekPeer {
312
-        PeekPeer::new()
313
-    }
314
-
315
-    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
316
-        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
317
-            lock: ::protobuf::lazy::ONCE_INIT,
318
-            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
319
-        };
320
-        unsafe {
321
-            descriptor.get(|| {
322
-                let mut fields = ::std::vec::Vec::new();
323
-                fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
324
-                    "hbb_addr",
325
-                    |m: &PeekPeer| { &m.hbb_addr },
326
-                    |m: &mut PeekPeer| { &mut m.hbb_addr },
327
-                ));
328
-                ::protobuf::reflect::MessageDescriptor::new::<PeekPeer>(
329
-                    "PeekPeer",
330
-                    fields,
331
-                    file_descriptor_proto()
332
-                )
333
-            })
334
-        }
335
-    }
336
-
337
-    fn default_instance() -> &'static PeekPeer {
338
-        static mut instance: ::protobuf::lazy::Lazy<PeekPeer> = ::protobuf::lazy::Lazy {
339
-            lock: ::protobuf::lazy::ONCE_INIT,
340
-            ptr: 0 as *const PeekPeer,
341
-        };
342
-        unsafe {
343
-            instance.get(PeekPeer::new)
344
-        }
345
-    }
346
-}
347
-
348
-impl ::protobuf::Clear for PeekPeer {
349
-    fn clear(&mut self) {
350
-        self.hbb_addr.clear();
351
-        self.unknown_fields.clear();
352
-    }
353
-}
354
-
355
-impl ::std::fmt::Debug for PeekPeer {
356
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
357
-        ::protobuf::text_format::fmt(self, f)
358
-    }
359
-}
360
-
361
-impl ::protobuf::reflect::ProtobufValue for PeekPeer {
362
-    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
363
-        ::protobuf::reflect::ProtobufValueRef::Message(self)
364
-    }
365
-}
366
-
367
-#[derive(PartialEq,Clone,Default)]
368
-pub struct PeekPeerResponse {
369
-    // message fields
370
-    pub socket_addr: ::std::vec::Vec<u8>,
371
-    // special fields
372
-    pub unknown_fields: ::protobuf::UnknownFields,
373
-    pub cached_size: ::protobuf::CachedSize,
374
-}
375
-
376
-impl<'a> ::std::default::Default for &'a PeekPeerResponse {
377
-    fn default() -> &'a PeekPeerResponse {
378
-        <PeekPeerResponse as ::protobuf::Message>::default_instance()
379
-    }
380
-}
381
-
382
-impl PeekPeerResponse {
383
-    pub fn new() -> PeekPeerResponse {
384
-        ::std::default::Default::default()
385
-    }
386
-
387
-    // bytes socket_addr = 1;
388
-
389
-
390
-    pub fn get_socket_addr(&self) -> &[u8] {
391
-        &self.socket_addr
392
-    }
393
-    pub fn clear_socket_addr(&mut self) {
394
-        self.socket_addr.clear();
395
-    }
396
-
397
-    // Param is passed by value, moved
398
-    pub fn set_socket_addr(&mut self, v: ::std::vec::Vec<u8>) {
399
-        self.socket_addr = v;
400
-    }
401
-
402
-    // Mutable pointer to the field.
403
-    // If field is not initialized, it is initialized with default value first.
404
-    pub fn mut_socket_addr(&mut self) -> &mut ::std::vec::Vec<u8> {
405
-        &mut self.socket_addr
406
-    }
407
-
408
-    // Take field
409
-    pub fn take_socket_addr(&mut self) -> ::std::vec::Vec<u8> {
410
-        ::std::mem::replace(&mut self.socket_addr, ::std::vec::Vec::new())
411
-    }
412
-}
413
-
414
-impl ::protobuf::Message for PeekPeerResponse {
415
-    fn is_initialized(&self) -> bool {
416
-        true
417
-    }
418
-
419
-    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
420
-        while !is.eof()? {
421
-            let (field_number, wire_type) = is.read_tag_unpack()?;
422
-            match field_number {
423
-                1 => {
424
-                    ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.socket_addr)?;
425
-                },
426
-                _ => {
427
-                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
428
-                },
429
-            };
430
-        }
431
-        ::std::result::Result::Ok(())
432
-    }
433
-
434
-    // Compute sizes of nested messages
435
-    #[allow(unused_variables)]
436
-    fn compute_size(&self) -> u32 {
437
-        let mut my_size = 0;
438
-        if !self.socket_addr.is_empty() {
439
-            my_size += ::protobuf::rt::bytes_size(1, &self.socket_addr);
440
-        }
441
-        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
442
-        self.cached_size.set(my_size);
443
-        my_size
444
-    }
445
-
446
-    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
447
-        if !self.socket_addr.is_empty() {
448
-            os.write_bytes(1, &self.socket_addr)?;
449
-        }
450
-        os.write_unknown_fields(self.get_unknown_fields())?;
451
-        ::std::result::Result::Ok(())
452
-    }
453
-
454
-    fn get_cached_size(&self) -> u32 {
455
-        self.cached_size.get()
456
-    }
457
-
458
-    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
459
-        &self.unknown_fields
460
-    }
461
-
462
-    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
463
-        &mut self.unknown_fields
464
-    }
465
-
466
-    fn as_any(&self) -> &dyn (::std::any::Any) {
467
-        self as &dyn (::std::any::Any)
468
-    }
469
-    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
470
-        self as &mut dyn (::std::any::Any)
471
-    }
472
-    fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
473
-        self
474
-    }
475
-
476
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
477
-        Self::descriptor_static()
478
-    }
479
-
480
-    fn new() -> PeekPeerResponse {
481
-        PeekPeerResponse::new()
482
-    }
483
-
484
-    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
485
-        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
486
-            lock: ::protobuf::lazy::ONCE_INIT,
487
-            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
488
-        };
489
-        unsafe {
490
-            descriptor.get(|| {
491
-                let mut fields = ::std::vec::Vec::new();
492
-                fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
493
-                    "socket_addr",
494
-                    |m: &PeekPeerResponse| { &m.socket_addr },
495
-                    |m: &mut PeekPeerResponse| { &mut m.socket_addr },
496
-                ));
497
-                ::protobuf::reflect::MessageDescriptor::new::<PeekPeerResponse>(
498
-                    "PeekPeerResponse",
499
-                    fields,
500
-                    file_descriptor_proto()
501
-                )
502
-            })
503
-        }
504
-    }
505
-
506
-    fn default_instance() -> &'static PeekPeerResponse {
507
-        static mut instance: ::protobuf::lazy::Lazy<PeekPeerResponse> = ::protobuf::lazy::Lazy {
508
-            lock: ::protobuf::lazy::ONCE_INIT,
509
-            ptr: 0 as *const PeekPeerResponse,
510
-        };
511
-        unsafe {
512
-            instance.get(PeekPeerResponse::new)
513
-        }
514
-    }
515
-}
516
-
517
-impl ::protobuf::Clear for PeekPeerResponse {
518
-    fn clear(&mut self) {
519
-        self.socket_addr.clear();
520
-        self.unknown_fields.clear();
521
-    }
522
-}
523
-
524
-impl ::std::fmt::Debug for PeekPeerResponse {
525
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
526
-        ::protobuf::text_format::fmt(self, f)
527
-    }
528
-}
529
-
530
-impl ::protobuf::reflect::ProtobufValue for PeekPeerResponse {
531
-    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
532
-        ::protobuf::reflect::ProtobufValueRef::Message(self)
533
-    }
534
-}
535
-
536
-#[derive(PartialEq,Clone,Default)]
537
-pub struct Message {
538
-    // message oneof groups
539
-    pub union: ::std::option::Option<Message_oneof_union>,
540
-    // special fields
541
-    pub unknown_fields: ::protobuf::UnknownFields,
542
-    pub cached_size: ::protobuf::CachedSize,
543
-}
544
-
545
-impl<'a> ::std::default::Default for &'a Message {
546
-    fn default() -> &'a Message {
547
-        <Message as ::protobuf::Message>::default_instance()
548
-    }
549
-}
550
-
551
-#[derive(Clone,PartialEq,Debug)]
552
-pub enum Message_oneof_union {
553
-    register_peer(RegisterPeer),
554
-    peek_peer(PeekPeer),
555
-    peek_peer_response(PeekPeerResponse),
556
-}
557
-
558
-impl Message {
559
-    pub fn new() -> Message {
560
-        ::std::default::Default::default()
561
-    }
562
-
563
-    // .hbb.RegisterPeer register_peer = 6;
564
-
565
-
566
-    pub fn get_register_peer(&self) -> &RegisterPeer {
567
-        match self.union {
568
-            ::std::option::Option::Some(Message_oneof_union::register_peer(ref v)) => v,
569
-            _ => RegisterPeer::default_instance(),
570
-        }
571
-    }
572
-    pub fn clear_register_peer(&mut self) {
573
-        self.union = ::std::option::Option::None;
574
-    }
575
-
576
-    pub fn has_register_peer(&self) -> bool {
577
-        match self.union {
578
-            ::std::option::Option::Some(Message_oneof_union::register_peer(..)) => true,
579
-            _ => false,
580
-        }
581
-    }
582
-
583
-    // Param is passed by value, moved
584
-    pub fn set_register_peer(&mut self, v: RegisterPeer) {
585
-        self.union = ::std::option::Option::Some(Message_oneof_union::register_peer(v))
586
-    }
587
-
588
-    // Mutable pointer to the field.
589
-    pub fn mut_register_peer(&mut self) -> &mut RegisterPeer {
590
-        if let ::std::option::Option::Some(Message_oneof_union::register_peer(_)) = self.union {
591
-        } else {
592
-            self.union = ::std::option::Option::Some(Message_oneof_union::register_peer(RegisterPeer::new()));
593
-        }
594
-        match self.union {
595
-            ::std::option::Option::Some(Message_oneof_union::register_peer(ref mut v)) => v,
596
-            _ => panic!(),
597
-        }
598
-    }
599
-
600
-    // Take field
601
-    pub fn take_register_peer(&mut self) -> RegisterPeer {
602
-        if self.has_register_peer() {
603
-            match self.union.take() {
604
-                ::std::option::Option::Some(Message_oneof_union::register_peer(v)) => v,
605
-                _ => panic!(),
606
-            }
607
-        } else {
608
-            RegisterPeer::new()
609
-        }
610
-    }
611
-
612
-    // .hbb.PeekPeer peek_peer = 7;
613
-
614
-
615
-    pub fn get_peek_peer(&self) -> &PeekPeer {
616
-        match self.union {
617
-            ::std::option::Option::Some(Message_oneof_union::peek_peer(ref v)) => v,
618
-            _ => PeekPeer::default_instance(),
619
-        }
620
-    }
621
-    pub fn clear_peek_peer(&mut self) {
622
-        self.union = ::std::option::Option::None;
623
-    }
624
-
625
-    pub fn has_peek_peer(&self) -> bool {
626
-        match self.union {
627
-            ::std::option::Option::Some(Message_oneof_union::peek_peer(..)) => true,
628
-            _ => false,
629
-        }
630
-    }
631
-
632
-    // Param is passed by value, moved
633
-    pub fn set_peek_peer(&mut self, v: PeekPeer) {
634
-        self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer(v))
635
-    }
636
-
637
-    // Mutable pointer to the field.
638
-    pub fn mut_peek_peer(&mut self) -> &mut PeekPeer {
639
-        if let ::std::option::Option::Some(Message_oneof_union::peek_peer(_)) = self.union {
640
-        } else {
641
-            self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer(PeekPeer::new()));
642
-        }
643
-        match self.union {
644
-            ::std::option::Option::Some(Message_oneof_union::peek_peer(ref mut v)) => v,
645
-            _ => panic!(),
646
-        }
647
-    }
648
-
649
-    // Take field
650
-    pub fn take_peek_peer(&mut self) -> PeekPeer {
651
-        if self.has_peek_peer() {
652
-            match self.union.take() {
653
-                ::std::option::Option::Some(Message_oneof_union::peek_peer(v)) => v,
654
-                _ => panic!(),
655
-            }
656
-        } else {
657
-            PeekPeer::new()
658
-        }
659
-    }
660
-
661
-    // .hbb.PeekPeerResponse peek_peer_response = 8;
662
-
663
-
664
-    pub fn get_peek_peer_response(&self) -> &PeekPeerResponse {
665
-        match self.union {
666
-            ::std::option::Option::Some(Message_oneof_union::peek_peer_response(ref v)) => v,
667
-            _ => PeekPeerResponse::default_instance(),
668
-        }
669
-    }
670
-    pub fn clear_peek_peer_response(&mut self) {
671
-        self.union = ::std::option::Option::None;
672
-    }
673
-
674
-    pub fn has_peek_peer_response(&self) -> bool {
675
-        match self.union {
676
-            ::std::option::Option::Some(Message_oneof_union::peek_peer_response(..)) => true,
677
-            _ => false,
678
-        }
679
-    }
680
-
681
-    // Param is passed by value, moved
682
-    pub fn set_peek_peer_response(&mut self, v: PeekPeerResponse) {
683
-        self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer_response(v))
684
-    }
685
-
686
-    // Mutable pointer to the field.
687
-    pub fn mut_peek_peer_response(&mut self) -> &mut PeekPeerResponse {
688
-        if let ::std::option::Option::Some(Message_oneof_union::peek_peer_response(_)) = self.union {
689
-        } else {
690
-            self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer_response(PeekPeerResponse::new()));
691
-        }
692
-        match self.union {
693
-            ::std::option::Option::Some(Message_oneof_union::peek_peer_response(ref mut v)) => v,
694
-            _ => panic!(),
695
-        }
696
-    }
697
-
698
-    // Take field
699
-    pub fn take_peek_peer_response(&mut self) -> PeekPeerResponse {
700
-        if self.has_peek_peer_response() {
701
-            match self.union.take() {
702
-                ::std::option::Option::Some(Message_oneof_union::peek_peer_response(v)) => v,
703
-                _ => panic!(),
704
-            }
705
-        } else {
706
-            PeekPeerResponse::new()
707
-        }
708
-    }
709
-}
710
-
711
-impl ::protobuf::Message for Message {
712
-    fn is_initialized(&self) -> bool {
713
-        if let Some(Message_oneof_union::register_peer(ref v)) = self.union {
714
-            if !v.is_initialized() {
715
-                return false;
716
-            }
717
-        }
718
-        if let Some(Message_oneof_union::peek_peer(ref v)) = self.union {
719
-            if !v.is_initialized() {
720
-                return false;
721
-            }
722
-        }
723
-        if let Some(Message_oneof_union::peek_peer_response(ref v)) = self.union {
724
-            if !v.is_initialized() {
725
-                return false;
726
-            }
727
-        }
728
-        true
729
-    }
730
-
731
-    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
732
-        while !is.eof()? {
733
-            let (field_number, wire_type) = is.read_tag_unpack()?;
734
-            match field_number {
735
-                6 => {
736
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
737
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
738
-                    }
739
-                    self.union = ::std::option::Option::Some(Message_oneof_union::register_peer(is.read_message()?));
740
-                },
741
-                7 => {
742
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
743
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
744
-                    }
745
-                    self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer(is.read_message()?));
746
-                },
747
-                8 => {
748
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
749
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
750
-                    }
751
-                    self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer_response(is.read_message()?));
752
-                },
753
-                _ => {
754
-                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
755
-                },
756
-            };
757
-        }
758
-        ::std::result::Result::Ok(())
759
-    }
760
-
761
-    // Compute sizes of nested messages
762
-    #[allow(unused_variables)]
763
-    fn compute_size(&self) -> u32 {
764
-        let mut my_size = 0;
765
-        if let ::std::option::Option::Some(ref v) = self.union {
766
-            match v {
767
-                &Message_oneof_union::register_peer(ref v) => {
768
-                    let len = v.compute_size();
769
-                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
770
-                },
771
-                &Message_oneof_union::peek_peer(ref v) => {
772
-                    let len = v.compute_size();
773
-                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
774
-                },
775
-                &Message_oneof_union::peek_peer_response(ref v) => {
776
-                    let len = v.compute_size();
777
-                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
778
-                },
779
-            };
780
-        }
781
-        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
782
-        self.cached_size.set(my_size);
783
-        my_size
784
-    }
785
-
786
-    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
787
-        if let ::std::option::Option::Some(ref v) = self.union {
788
-            match v {
789
-                &Message_oneof_union::register_peer(ref v) => {
790
-                    os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
791
-                    os.write_raw_varint32(v.get_cached_size())?;
792
-                    v.write_to_with_cached_sizes(os)?;
793
-                },
794
-                &Message_oneof_union::peek_peer(ref v) => {
795
-                    os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?;
796
-                    os.write_raw_varint32(v.get_cached_size())?;
797
-                    v.write_to_with_cached_sizes(os)?;
798
-                },
799
-                &Message_oneof_union::peek_peer_response(ref v) => {
800
-                    os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?;
801
-                    os.write_raw_varint32(v.get_cached_size())?;
802
-                    v.write_to_with_cached_sizes(os)?;
803
-                },
804
-            };
805
-        }
806
-        os.write_unknown_fields(self.get_unknown_fields())?;
807
-        ::std::result::Result::Ok(())
808
-    }
809
-
810
-    fn get_cached_size(&self) -> u32 {
811
-        self.cached_size.get()
812
-    }
813
-
814
-    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
815
-        &self.unknown_fields
816
-    }
817
-
818
-    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
819
-        &mut self.unknown_fields
820
-    }
821
-
822
-    fn as_any(&self) -> &dyn (::std::any::Any) {
823
-        self as &dyn (::std::any::Any)
824
-    }
825
-    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
826
-        self as &mut dyn (::std::any::Any)
827
-    }
828
-    fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
829
-        self
830
-    }
831
-
832
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
833
-        Self::descriptor_static()
834
-    }
835
-
836
-    fn new() -> Message {
837
-        Message::new()
838
-    }
839
-
840
-    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
841
-        static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
842
-            lock: ::protobuf::lazy::ONCE_INIT,
843
-            ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
844
-        };
845
-        unsafe {
846
-            descriptor.get(|| {
847
-                let mut fields = ::std::vec::Vec::new();
848
-                fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, RegisterPeer>(
849
-                    "register_peer",
850
-                    Message::has_register_peer,
851
-                    Message::get_register_peer,
852
-                ));
853
-                fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, PeekPeer>(
854
-                    "peek_peer",
855
-                    Message::has_peek_peer,
856
-                    Message::get_peek_peer,
857
-                ));
858
-                fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, PeekPeerResponse>(
859
-                    "peek_peer_response",
860
-                    Message::has_peek_peer_response,
861
-                    Message::get_peek_peer_response,
862
-                ));
863
-                ::protobuf::reflect::MessageDescriptor::new::<Message>(
864
-                    "Message",
865
-                    fields,
866
-                    file_descriptor_proto()
867
-                )
868
-            })
869
-        }
870
-    }
871
-
872
-    fn default_instance() -> &'static Message {
873
-        static mut instance: ::protobuf::lazy::Lazy<Message> = ::protobuf::lazy::Lazy {
874
-            lock: ::protobuf::lazy::ONCE_INIT,
875
-            ptr: 0 as *const Message,
876
-        };
877
-        unsafe {
878
-            instance.get(Message::new)
879
-        }
880
-    }
881
-}
882
-
883
-impl ::protobuf::Clear for Message {
884
-    fn clear(&mut self) {
885
-        self.union = ::std::option::Option::None;
886
-        self.union = ::std::option::Option::None;
887
-        self.union = ::std::option::Option::None;
888
-        self.unknown_fields.clear();
889
-    }
890
-}
891
-
892
-impl ::std::fmt::Debug for Message {
893
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
894
-        ::protobuf::text_format::fmt(self, f)
895
-    }
896
-}
897
-
898
-impl ::protobuf::reflect::ProtobufValue for Message {
899
-    fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
900
-        ::protobuf::reflect::ProtobufValueRef::Message(self)
901
-    }
902
-}
903
-
904
-static file_descriptor_proto_data: &'static [u8] = b"\
905
-    \n\rmessage.proto\x12\x03hbb\"$\n\x0cRegisterPeer\x12\x12\n\x08hbb_addr\
906
-    \x18\x01\x20\x01(\tB\0:\0\"\x20\n\x08PeekPeer\x12\x12\n\x08hbb_addr\x18\
907
-    \x01\x20\x01(\tB\0:\0\"+\n\x10PeekPeerResponse\x12\x15\n\x0bsocket_addr\
908
-    \x18\x01\x20\x01(\x0cB\0:\0\"\x9f\x01\n\x07Message\x12,\n\rregister_peer\
909
-    \x18\x06\x20\x01(\x0b2\x11.hbb.RegisterPeerH\0B\0\x12$\n\tpeek_peer\x18\
910
-    \x07\x20\x01(\x0b2\r.hbb.PeekPeerH\0B\0\x125\n\x12peek_peer_response\x18\
911
-    \x08\x20\x01(\x0b2\x15.hbb.PeekPeerResponseH\0B\0B\x07\n\x05union:\0B\0b\
912
-    \x06proto3\
913
-";
914
-
915
-static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
916
-    lock: ::protobuf::lazy::ONCE_INIT,
917
-    ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
918
-};
919
-
920
-fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
921
-    ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
922
-}
923
-
924
-pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
925
-    unsafe {
926
-        file_descriptor_proto_lazy.get(|| {
927
-            parse_descriptor_proto()
928
-        })
929
-    }
930
-}

+ 569 - 45
src/relay_server.rs

@@ -1,114 +1,638 @@
1
+use async_speed_limit::Limiter;
2
+use async_trait::async_trait;
1 3
 use hbb_common::{
4
+    allow_err, bail,
5
+    bytes::{Bytes, BytesMut},
6
+    futures_util::{sink::SinkExt, stream::StreamExt},
2 7
     log,
3 8
     protobuf::Message as _,
4 9
     rendezvous_proto::*,
5 10
     sleep,
6 11
     tcp::{new_listener, FramedStream},
12
+    timeout,
7 13
     tokio::{
8 14
         self,
9
-        net::TcpListener,
15
+        io::{AsyncReadExt, AsyncWriteExt},
16
+        net::{TcpListener, TcpStream},
17
+        sync::{Mutex, RwLock},
10 18
         time::{interval, Duration},
11 19
     },
12 20
     ResultType,
13 21
 };
22
+use sodiumoxide::crypto::sign;
14 23
 use std::{
15
-    collections::HashMap,
24
+    collections::{HashMap, HashSet},
25
+    io::prelude::*,
26
+    io::Error,
16 27
     net::SocketAddr,
17
-    sync::{Arc, Mutex},
18 28
 };
19 29
 
30
+type Usage = (usize, usize, usize, usize);
31
+
20 32
 lazy_static::lazy_static! {
21
-    static ref PEERS: Arc<Mutex<HashMap<String, FramedStream>>> = Arc::new(Mutex::new(HashMap::new()));
33
+    static ref PEERS: Mutex<HashMap<String, Box<dyn StreamTrait>>> = Default::default();
34
+    static ref USAGE: RwLock<HashMap<String, Usage>> = Default::default();
35
+    static ref BLACKLIST: RwLock<HashSet<String>> = Default::default();
36
+    static ref BLOCKLIST: RwLock<HashSet<String>> = Default::default();
22 37
 }
23 38
 
24
-pub const DEFAULT_PORT: &'static str = "21117";
39
+static mut DOWNGRADE_THRESHOLD: f64 = 0.66;
40
+static mut DOWNGRADE_START_CHECK: usize = 1800_000; // in ms
41
+static mut LIMIT_SPEED: usize = 4 * 1024 * 1024; // in bit/s
42
+static mut TOTAL_BANDWIDTH: usize = 1024 * 1024 * 1024; // in bit/s
43
+static mut SINGLE_BANDWIDTH: usize = 16 * 1024 * 1024; // in bit/s
44
+const BLACKLIST_FILE: &'static str = "blacklist.txt";
45
+const BLOCKLIST_FILE: &'static str = "blocklist.txt";
25 46
 
26
-#[tokio::main(basic_scheduler)]
27
-pub async fn start(port: &str, key: &str, stop: Arc<Mutex<bool>>) -> ResultType<()> {
28
-    if !key.is_empty() {
29
-        log::info!("Key: {}", key);
47
+#[tokio::main(flavor = "multi_thread")]
48
+pub async fn start(port: &str, key: &str) -> ResultType<()> {
49
+    let key = get_server_sk(key);
50
+    if let Ok(mut file) = std::fs::File::open(BLACKLIST_FILE) {
51
+        let mut contents = String::new();
52
+        if file.read_to_string(&mut contents).is_ok() {
53
+            for x in contents.split("\n") {
54
+                if let Some(ip) = x.trim().split(' ').nth(0) {
55
+                    BLACKLIST.write().await.insert(ip.to_owned());
56
+                }
57
+            }
58
+        }
59
+    }
60
+    log::info!(
61
+        "#blacklist({}): {}",
62
+        BLACKLIST_FILE,
63
+        BLACKLIST.read().await.len()
64
+    );
65
+    if let Ok(mut file) = std::fs::File::open(BLOCKLIST_FILE) {
66
+        let mut contents = String::new();
67
+        if file.read_to_string(&mut contents).is_ok() {
68
+            for x in contents.split("\n") {
69
+                if let Some(ip) = x.trim().split(' ').nth(0) {
70
+                    BLOCKLIST.write().await.insert(ip.to_owned());
71
+                }
72
+            }
73
+        }
30 74
     }
75
+    log::info!(
76
+        "#blocklist({}): {}",
77
+        BLOCKLIST_FILE,
78
+        BLOCKLIST.read().await.len()
79
+    );
31 80
     let addr = format!("0.0.0.0:{}", port);
32 81
     log::info!("Listening on tcp {}", addr);
33
-    let mut listener = new_listener(addr, false).await?;
82
+    let addr2 = format!("0.0.0.0:{}", port.parse::<u16>().unwrap() + 2);
83
+    log::info!("Listening on websocket {}", addr2);
34 84
     loop {
35
-        if *stop.lock().unwrap() {
36
-            sleep(0.1).await;
37
-            continue;
38
-        }
39 85
         log::info!("Start");
40
-        io_loop(&mut listener, key, stop.clone()).await;
86
+        io_loop(
87
+            new_listener(&addr, false).await?,
88
+            new_listener(&addr2, false).await?,
89
+            &key,
90
+        )
91
+        .await;
41 92
     }
42 93
 }
43 94
 
44
-async fn io_loop(listener: &mut TcpListener, key: &str, stop: Arc<Mutex<bool>>) {
45
-    let mut timer = interval(Duration::from_millis(100));
95
+fn check_params() {
96
+    let tmp = std::env::var("DOWNGRADE_THRESHOLD")
97
+        .map(|x| x.parse::<f64>().unwrap_or(0.))
98
+        .unwrap_or(0.);
99
+    if tmp > 0. {
100
+        unsafe {
101
+            DOWNGRADE_THRESHOLD = tmp;
102
+        }
103
+    }
104
+    unsafe { log::info!("DOWNGRADE_THRESHOLD: {}", DOWNGRADE_THRESHOLD) };
105
+    let tmp = std::env::var("DOWNGRADE_START_CHECK")
106
+        .map(|x| x.parse::<usize>().unwrap_or(0))
107
+        .unwrap_or(0);
108
+    if tmp > 0 {
109
+        unsafe {
110
+            DOWNGRADE_START_CHECK = tmp * 1000;
111
+        }
112
+    }
113
+    unsafe { log::info!("DOWNGRADE_START_CHECK: {}s", DOWNGRADE_START_CHECK / 1000) };
114
+    let tmp = std::env::var("LIMIT_SPEED")
115
+        .map(|x| x.parse::<f64>().unwrap_or(0.))
116
+        .unwrap_or(0.);
117
+    if tmp > 0. {
118
+        unsafe {
119
+            LIMIT_SPEED = (tmp * 1024. * 1024.) as usize;
120
+        }
121
+    }
122
+    unsafe { log::info!("LIMIT_SPEED: {}Mb/s", LIMIT_SPEED as f64 / 1024. / 1024.) };
123
+    let tmp = std::env::var("TOTAL_BANDWIDTH")
124
+        .map(|x| x.parse::<f64>().unwrap_or(0.))
125
+        .unwrap_or(0.);
126
+    if tmp > 0. {
127
+        unsafe {
128
+            TOTAL_BANDWIDTH = (tmp * 1024. * 1024.) as usize;
129
+        }
130
+    }
131
+    unsafe {
132
+        log::info!(
133
+            "TOTAL_BANDWIDTH: {}Mb/s",
134
+            TOTAL_BANDWIDTH as f64 / 1024. / 1024.
135
+        )
136
+    };
137
+    let tmp = std::env::var("SINGLE_BANDWIDTH")
138
+        .map(|x| x.parse::<f64>().unwrap_or(0.))
139
+        .unwrap_or(0.);
140
+    if tmp > 0. {
141
+        unsafe {
142
+            SINGLE_BANDWIDTH = (tmp * 1024. * 1024.) as usize;
143
+        }
144
+    }
145
+    unsafe {
146
+        log::info!(
147
+            "SINGLE_BANDWIDTH: {}Mb/s",
148
+            SINGLE_BANDWIDTH as f64 / 1024. / 1024.
149
+        )
150
+    };
151
+}
152
+
153
+async fn check_cmd(cmd: &str, limiter: Limiter) -> String {
154
+    let mut res = "".to_owned();
155
+    let mut fds = cmd.trim().split(" ");
156
+    match fds.next() {
157
+        Some("h") => {
158
+            res = format!(
159
+                "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
160
+                "blacklist-add(ba) <ip>",
161
+                "blacklist-remove(br) <ip>",
162
+                "blacklist(b) <ip>",
163
+                "blocklist-add(Ba) <ip>",
164
+                "blocklist-remove(Br) <ip>",
165
+                "blocklist(B) <ip>",
166
+                "downgrade-threshold(dt) [value]",
167
+                "downgrade-start-check(t) [value(second)]",
168
+                "limit-speed(ls) [value(Mb/s)]",
169
+                "total-bandwidth(tb) [value(Mb/s)]",
170
+                "single-bandwidth(sb) [value(Mb/s)]",
171
+                "usage(u)"
172
+            )
173
+        }
174
+        Some("blacklist-add" | "ba") => {
175
+            if let Some(ip) = fds.next() {
176
+                for ip in ip.split("|") {
177
+                    BLACKLIST.write().await.insert(ip.to_owned());
178
+                }
179
+            }
180
+        }
181
+        Some("blacklist-remove" | "br") => {
182
+            if let Some(ip) = fds.next() {
183
+                if ip == "all" {
184
+                    BLACKLIST.write().await.clear();
185
+                } else {
186
+                    for ip in ip.split("|") {
187
+                        BLACKLIST.write().await.remove(ip);
188
+                    }
189
+                }
190
+            }
191
+        }
192
+        Some("blacklist" | "b") => {
193
+            if let Some(ip) = fds.next() {
194
+                res = format!("{}\n", BLACKLIST.read().await.get(ip).is_some());
195
+            } else {
196
+                for ip in BLACKLIST.read().await.clone().into_iter() {
197
+                    res += &format!("{}\n", ip);
198
+                }
199
+            }
200
+        }
201
+        Some("blocklist-add" | "Ba") => {
202
+            if let Some(ip) = fds.next() {
203
+                for ip in ip.split("|") {
204
+                    BLOCKLIST.write().await.insert(ip.to_owned());
205
+                }
206
+            }
207
+        }
208
+        Some("blocklist-remove" | "Br") => {
209
+            if let Some(ip) = fds.next() {
210
+                if ip == "all" {
211
+                    BLOCKLIST.write().await.clear();
212
+                } else {
213
+                    for ip in ip.split("|") {
214
+                        BLOCKLIST.write().await.remove(ip);
215
+                    }
216
+                }
217
+            }
218
+        }
219
+        Some("blocklist" | "B") => {
220
+            if let Some(ip) = fds.next() {
221
+                res = format!("{}\n", BLOCKLIST.read().await.get(ip).is_some());
222
+            } else {
223
+                for ip in BLOCKLIST.read().await.clone().into_iter() {
224
+                    res += &format!("{}\n", ip);
225
+                }
226
+            }
227
+        }
228
+        Some("downgrade-threshold" | "dt") => {
229
+            if let Some(v) = fds.next() {
230
+                if let Ok(v) = v.parse::<f64>() {
231
+                    if v > 0. {
232
+                        unsafe {
233
+                            DOWNGRADE_THRESHOLD = v;
234
+                        }
235
+                    }
236
+                }
237
+            } else {
238
+                unsafe {
239
+                    res = format!("{}\n", DOWNGRADE_THRESHOLD);
240
+                }
241
+            }
242
+        }
243
+        Some("downgrade-start-check" | "t") => {
244
+            if let Some(v) = fds.next() {
245
+                if let Ok(v) = v.parse::<usize>() {
246
+                    if v > 0 {
247
+                        unsafe {
248
+                            DOWNGRADE_START_CHECK = v * 1000;
249
+                        }
250
+                    }
251
+                }
252
+            } else {
253
+                unsafe {
254
+                    res = format!("{}s\n", DOWNGRADE_START_CHECK / 1000);
255
+                }
256
+            }
257
+        }
258
+        Some("limit-speed" | "ls") => {
259
+            if let Some(v) = fds.next() {
260
+                if let Ok(v) = v.parse::<f64>() {
261
+                    if v > 0. {
262
+                        unsafe {
263
+                            LIMIT_SPEED = (v * 1024. * 1024.) as _;
264
+                        }
265
+                    }
266
+                }
267
+            } else {
268
+                unsafe {
269
+                    res = format!("{}Mb/s\n", LIMIT_SPEED as f64 / 1024. / 1024.);
270
+                }
271
+            }
272
+        }
273
+        Some("total-bandwidth" | "tb") => {
274
+            if let Some(v) = fds.next() {
275
+                if let Ok(v) = v.parse::<f64>() {
276
+                    if v > 0. {
277
+                        unsafe {
278
+                            TOTAL_BANDWIDTH = (v * 1024. * 1024.) as _;
279
+                            limiter.set_speed_limit(TOTAL_BANDWIDTH as _);
280
+                        }
281
+                    }
282
+                }
283
+            } else {
284
+                unsafe {
285
+                    res = format!("{}Mb/s\n", TOTAL_BANDWIDTH as f64 / 1024. / 1024.);
286
+                }
287
+            }
288
+        }
289
+        Some("single-bandwidth" | "sb") => {
290
+            if let Some(v) = fds.next() {
291
+                if let Ok(v) = v.parse::<f64>() {
292
+                    if v > 0. {
293
+                        unsafe {
294
+                            SINGLE_BANDWIDTH = (v * 1024. * 1024.) as _;
295
+                        }
296
+                    }
297
+                }
298
+            } else {
299
+                unsafe {
300
+                    res = format!("{}Mb/s\n", SINGLE_BANDWIDTH as f64 / 1024. / 1024.);
301
+                }
302
+            }
303
+        }
304
+        Some("usage" | "u") => {
305
+            let mut tmp: Vec<(String, Usage)> = USAGE
306
+                .read()
307
+                .await
308
+                .iter()
309
+                .map(|x| (x.0.clone(), x.1.clone()))
310
+                .collect();
311
+            tmp.sort_by(|a, b| ((b.1).1).partial_cmp(&(a.1).1).unwrap());
312
+            for (ip, (elapsed, total, highest, speed)) in tmp {
313
+                if elapsed <= 0 {
314
+                    continue;
315
+                }
316
+                res += &format!(
317
+                    "{}: {}s {:.2}MB {}kb/s {}kb/s {}kb/s\n",
318
+                    ip,
319
+                    elapsed / 1000,
320
+                    total as f64 / 1024. / 1024. / 8.,
321
+                    highest,
322
+                    total / elapsed,
323
+                    speed
324
+                );
325
+            }
326
+        }
327
+        _ => {}
328
+    }
329
+    res
330
+}
331
+
332
+async fn io_loop(listener: TcpListener, listener2: TcpListener, key: &str) {
333
+    check_params();
334
+    let limiter = <Limiter>::new(unsafe { TOTAL_BANDWIDTH as _ });
46 335
     loop {
47 336
         tokio::select! {
48
-            Ok((stream, addr)) = listener.accept() => {
49
-                let key = key.to_owned();
50
-                tokio::spawn(async move {
51
-                    make_pair(FramedStream::from(stream), addr, &key).await.ok();
52
-                });
337
+            res = listener.accept() => {
338
+                match res {
339
+                    Ok((stream, addr))  => {
340
+                        stream.set_nodelay(true).ok();
341
+                        handle_connection(stream, addr, &limiter, key, false).await;
342
+                    }
343
+                    Err(err) => {
344
+                       log::error!("listener.accept failed: {}", err);
345
+                       break;
346
+                    }
347
+                }
53 348
             }
54
-            _ = timer.tick() => {
55
-                if *stop.lock().unwrap() {
56
-                    log::info!("Stopped");
57
-                    break;
349
+            res = listener2.accept() => {
350
+                match res {
351
+                    Ok((stream, addr))  => {
352
+                        stream.set_nodelay(true).ok();
353
+                        handle_connection(stream, addr, &limiter, key, true).await;
354
+                    }
355
+                    Err(err) => {
356
+                       log::error!("listener2.accept failed: {}", err);
357
+                       break;
358
+                    }
58 359
                 }
59 360
             }
60 361
         }
61 362
     }
62 363
 }
63 364
 
64
-async fn make_pair(stream: FramedStream, addr: SocketAddr, key: &str) -> ResultType<()> {
365
+async fn handle_connection(
366
+    stream: TcpStream,
367
+    addr: SocketAddr,
368
+    limiter: &Limiter,
369
+    key: &str,
370
+    ws: bool,
371
+) {
372
+    let ip = addr.ip().to_string();
373
+    if !ws && ip == "127.0.0.1" {
374
+        let limiter = limiter.clone();
375
+        tokio::spawn(async move {
376
+            let mut stream = stream;
377
+            let mut buffer = [0; 64];
378
+            if let Ok(Ok(n)) = timeout(1000, stream.read(&mut buffer[..])).await {
379
+                if let Ok(data) = std::str::from_utf8(&buffer[..n]) {
380
+                    let res = check_cmd(data, limiter).await;
381
+                    stream.write(res.as_bytes()).await.ok();
382
+                }
383
+            }
384
+        });
385
+        return;
386
+    }
387
+    if BLOCKLIST.read().await.get(&ip).is_some() {
388
+        log::info!("{} blocked", ip);
389
+        return;
390
+    }
391
+    let key = key.to_owned();
392
+    let limiter = limiter.clone();
393
+    tokio::spawn(async move {
394
+        allow_err!(make_pair(stream, addr, &key, limiter, ws).await);
395
+    });
396
+}
397
+
398
+async fn make_pair(
399
+    stream: TcpStream,
400
+    addr: SocketAddr,
401
+    key: &str,
402
+    limiter: Limiter,
403
+    ws: bool,
404
+) -> ResultType<()> {
405
+    if ws {
406
+        make_pair_(
407
+            tokio_tungstenite::accept_async(stream).await?,
408
+            addr,
409
+            key,
410
+            limiter,
411
+        )
412
+        .await;
413
+    } else {
414
+        make_pair_(FramedStream::from(stream, addr), addr, key, limiter).await;
415
+    }
416
+    Ok(())
417
+}
418
+
419
+async fn make_pair_(stream: impl StreamTrait, addr: SocketAddr, key: &str, limiter: Limiter) {
65 420
     let mut stream = stream;
66
-    if let Some(Ok(bytes)) = stream.next_timeout(30_000).await {
421
+    if let Ok(Some(Ok(bytes))) = timeout(30_000, stream.recv()).await {
67 422
         if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
68 423
             if let Some(rendezvous_message::Union::request_relay(rf)) = msg_in.union {
69 424
                 if !key.is_empty() && rf.licence_key != key {
70
-                    return Ok(());
425
+                    return;
71 426
                 }
72 427
                 if !rf.uuid.is_empty() {
73
-                    let peer = PEERS.lock().unwrap().remove(&rf.uuid);
74
-                    if let Some(peer) = peer {
75
-                        log::info!("Forward request {} from {} got paired", rf.uuid, addr);
76
-                        return relay(stream, peer).await;
428
+                    let mut peer = PEERS.lock().await.remove(&rf.uuid);
429
+                    if let Some(peer) = peer.as_mut() {
430
+                        log::info!("Relayrequest {} from {} got paired", rf.uuid, addr);
431
+                        let id = format!("{}:{}", addr.ip(), addr.port());
432
+                        USAGE.write().await.insert(id.clone(), Default::default());
433
+                        if !stream.is_ws() && !peer.is_ws() {
434
+                            peer.set_raw();
435
+                            stream.set_raw();
436
+                            log::info!("Both are raw");
437
+                        }
438
+                        if let Err(err) = relay(addr, &mut stream, peer, limiter, id.clone()).await
439
+                        {
440
+                            log::info!("Relay of {} closed: {}", addr, err);
441
+                        } else {
442
+                            log::info!("Relay of {} closed", addr);
443
+                        }
444
+                        USAGE.write().await.remove(&id);
77 445
                     } else {
78 446
                         log::info!("New relay request {} from {}", rf.uuid, addr);
79
-                        PEERS.lock().unwrap().insert(rf.uuid.clone(), stream);
447
+                        PEERS.lock().await.insert(rf.uuid.clone(), Box::new(stream));
80 448
                         sleep(30.).await;
81
-                        PEERS.lock().unwrap().remove(&rf.uuid);
449
+                        PEERS.lock().await.remove(&rf.uuid);
82 450
                     }
83 451
                 }
84 452
             }
85 453
         }
86 454
     }
87
-    Ok(())
88 455
 }
89 456
 
90
-async fn relay(stream: FramedStream, peer: FramedStream) -> ResultType<()> {
91
-    let mut peer = peer;
92
-    let mut stream = stream;
93
-    peer.set_raw();
94
-    stream.set_raw();
457
+async fn relay(
458
+    addr: SocketAddr,
459
+    stream: &mut impl StreamTrait,
460
+    peer: &mut Box<dyn StreamTrait>,
461
+    total_limiter: Limiter,
462
+    id: String,
463
+) -> ResultType<()> {
464
+    let ip = addr.ip().to_string();
465
+    let mut tm = std::time::Instant::now();
466
+    let mut elapsed = 0;
467
+    let mut total = 0;
468
+    let mut total_s = 0;
469
+    let mut highest_s = 0;
470
+    let mut downgrade: bool = false;
471
+    let mut blacked: bool = false;
472
+    let limiter = <Limiter>::new(unsafe { SINGLE_BANDWIDTH as _ });
473
+    let blacklist_limiter = <Limiter>::new(unsafe { LIMIT_SPEED as _ });
474
+    let downgrade_threshold =
475
+        (unsafe { SINGLE_BANDWIDTH as f64 * DOWNGRADE_THRESHOLD } / 1000.) as usize; // in bit/ms
476
+    let mut timer = interval(Duration::from_secs(3));
477
+    let mut last_recv_time = std::time::Instant::now();
95 478
     loop {
96 479
         tokio::select! {
97
-            res = peer.next() => {
480
+            res = peer.recv() => {
98 481
                 if let Some(Ok(bytes)) = res {
99
-                    stream.send_bytes(bytes.into()).await?;
482
+                    last_recv_time = std::time::Instant::now();
483
+                    let nb = bytes.len() * 8;
484
+                    if blacked || downgrade {
485
+                        blacklist_limiter.consume(nb).await;
486
+                    } else {
487
+                        limiter.consume(nb).await;
488
+                    }
489
+                    total_limiter.consume(nb).await;
490
+                    total += nb;
491
+                    total_s += nb;
492
+                    if bytes.len() > 0 {
493
+                        stream.send_raw(bytes.into()).await?;
494
+                    }
100 495
                 } else {
101 496
                     break;
102 497
                 }
103 498
             },
104
-            res = stream.next() => {
499
+            res = stream.recv() => {
105 500
                 if let Some(Ok(bytes)) = res {
106
-                    peer.send_bytes(bytes.into()).await?;
501
+                    last_recv_time = std::time::Instant::now();
502
+                    let nb = bytes.len() * 8;
503
+                    if blacked || downgrade {
504
+                        blacklist_limiter.consume(nb).await;
505
+                    } else {
506
+                        limiter.consume(nb).await;
507
+                    }
508
+                    total_limiter.consume(nb).await;
509
+                    total += nb;
510
+                    total_s += nb;
511
+                    if bytes.len() > 0 {
512
+                        peer.send_raw(bytes.into()).await?;
513
+                    }
107 514
                 } else {
108 515
                     break;
109 516
                 }
110 517
             },
518
+            _ = timer.tick() => {
519
+                if last_recv_time.elapsed().as_secs() > 30 {
520
+                    bail!("Timeout");
521
+                }
522
+            }
523
+        }
524
+
525
+        let n = tm.elapsed().as_millis() as usize;
526
+        if n >= 1_000 {
527
+            if BLOCKLIST.read().await.get(&ip).is_some() {
528
+                log::info!("{} blocked", ip);
529
+                break;
530
+            }
531
+            blacked = BLACKLIST.read().await.get(&ip).is_some();
532
+            tm = std::time::Instant::now();
533
+            let speed = total_s / (n as usize);
534
+            if speed > highest_s {
535
+                highest_s = speed;
536
+            }
537
+            elapsed += n;
538
+            USAGE.write().await.insert(
539
+                id.clone(),
540
+                (elapsed as _, total as _, highest_s as _, speed as _),
541
+            );
542
+            total_s = 0;
543
+            if elapsed > unsafe { DOWNGRADE_START_CHECK } && !downgrade {
544
+                if total > elapsed * downgrade_threshold {
545
+                    downgrade = true;
546
+                    log::info!(
547
+                        "Downgrade {}, exceed downgrade threshold {}bit/ms in {}ms",
548
+                        id,
549
+                        downgrade_threshold,
550
+                        elapsed
551
+                    );
552
+                }
553
+            }
111 554
         }
112 555
     }
113 556
     Ok(())
114 557
 }
558
+
559
+fn get_server_sk(key: &str) -> String {
560
+    let mut key = key.to_owned();
561
+    if let Ok(sk) = base64::decode(&key) {
562
+        if sk.len() == sign::SECRETKEYBYTES {
563
+            log::info!("The key is a crypto private key");
564
+            key = base64::encode(&sk[(sign::SECRETKEYBYTES / 2)..]);
565
+        }
566
+    }
567
+
568
+    if key == "-" || key == "_" {
569
+        let (pk, _) = crate::common::gen_sk();
570
+        key = pk;
571
+    }
572
+
573
+    if !key.is_empty() {
574
+        log::info!("Key: {}", key);
575
+    }
576
+
577
+    key
578
+}
579
+
580
+#[async_trait]
581
+trait StreamTrait: Send + Sync + 'static {
582
+    async fn recv(&mut self) -> Option<Result<BytesMut, Error>>;
583
+    async fn send_raw(&mut self, bytes: Bytes) -> ResultType<()>;
584
+    fn is_ws(&self) -> bool;
585
+    fn set_raw(&mut self);
586
+}
587
+
588
+#[async_trait]
589
+impl StreamTrait for FramedStream {
590
+    async fn recv(&mut self) -> Option<Result<BytesMut, Error>> {
591
+        self.next().await
592
+    }
593
+
594
+    async fn send_raw(&mut self, bytes: Bytes) -> ResultType<()> {
595
+        self.send_bytes(bytes).await
596
+    }
597
+
598
+    fn is_ws(&self) -> bool {
599
+        false
600
+    }
601
+
602
+    fn set_raw(&mut self) {
603
+        self.set_raw();
604
+    }
605
+}
606
+
607
+#[async_trait]
608
+impl StreamTrait for tokio_tungstenite::WebSocketStream<TcpStream> {
609
+    async fn recv(&mut self) -> Option<Result<BytesMut, Error>> {
610
+        if let Some(msg) = self.next().await {
611
+            match msg {
612
+                Ok(msg) => {
613
+                    match msg {
614
+                        tungstenite::Message::Binary(bytes) => {
615
+                            Some(Ok(bytes[..].into())) // to-do: poor performance
616
+                        }
617
+                        _ => Some(Ok(BytesMut::new())),
618
+                    }
619
+                }
620
+                Err(err) => Some(Err(Error::new(std::io::ErrorKind::Other, err.to_string()))),
621
+            }
622
+        } else {
623
+            None
624
+        }
625
+    }
626
+
627
+    async fn send_raw(&mut self, bytes: Bytes) -> ResultType<()> {
628
+        Ok(self
629
+            .send(tungstenite::Message::Binary(bytes.to_vec()))
630
+            .await?) // to-do: poor performance
631
+    }
632
+
633
+    fn is_ws(&self) -> bool {
634
+        true
635
+    }
636
+
637
+    fn set_raw(&mut self) {}
638
+}

File diff suppressed because it is too large
+ 870 - 426
src/rendezvous_server.rs


+ 0 - 101
src/sled_async.rs

@@ -1,101 +0,0 @@
1
-use hbb_common::{
2
-    allow_err, log,
3
-    tokio::{self, sync::mpsc},
4
-    ResultType,
5
-};
6
-use rocksdb::DB;
7
-
8
-#[derive(Debug)]
9
-enum Action {
10
-    Insert((String, Vec<u8>)),
11
-    Get((String, mpsc::Sender<Option<Vec<u8>>>)),
12
-    _Close,
13
-}
14
-
15
-#[derive(Clone)]
16
-pub struct SledAsync {
17
-    tx: Option<mpsc::UnboundedSender<Action>>,
18
-    path: String,
19
-}
20
-
21
-impl SledAsync {
22
-    pub fn new(path: &str, run: bool) -> ResultType<Self> {
23
-        let mut res = Self {
24
-            tx: None,
25
-            path: path.to_owned(),
26
-        };
27
-        if run {
28
-            res.run()?;
29
-        }
30
-        Ok(res)
31
-    }
32
-
33
-    pub fn run(&mut self) -> ResultType<std::thread::JoinHandle<()>> {
34
-        let (tx, rx) = mpsc::unbounded_channel::<Action>();
35
-        self.tx = Some(tx);
36
-        let db = DB::open_default(&self.path)?;
37
-        Ok(std::thread::spawn(move || {
38
-            Self::io_loop(db, rx);
39
-            log::debug!("Exit SledAsync loop");
40
-        }))
41
-    }
42
-
43
-    #[tokio::main(basic_scheduler)]
44
-    async fn io_loop(db: DB, rx: mpsc::UnboundedReceiver<Action>) {
45
-        let mut rx = rx;
46
-        while let Some(x) = rx.recv().await {
47
-            match x {
48
-                Action::Insert((key, value)) => {
49
-                    allow_err!(db.put(&key, &value));
50
-                }
51
-                Action::Get((key, sender)) => {
52
-                    let mut sender = sender;
53
-                    allow_err!(
54
-                        sender
55
-                            .send(if let Ok(v) = db.get(key) { v } else { None })
56
-                            .await
57
-                    );
58
-                }
59
-                Action::_Close => break,
60
-            }
61
-        }
62
-    }
63
-
64
-    pub fn _close(self, j: std::thread::JoinHandle<()>) {
65
-        if let Some(tx) = &self.tx {
66
-            allow_err!(tx.send(Action::_Close));
67
-        }
68
-        allow_err!(j.join());
69
-    }
70
-
71
-    pub async fn get(&mut self, key: String) -> Option<Vec<u8>> {
72
-        if let Some(tx) = &self.tx {
73
-            let (tx_once, mut rx) = mpsc::channel::<Option<Vec<u8>>>(1);
74
-            allow_err!(tx.send(Action::Get((key, tx_once))));
75
-            if let Some(v) = rx.recv().await {
76
-                return v;
77
-            }
78
-        }
79
-        None
80
-    }
81
-
82
-    #[inline]
83
-    pub fn deserialize<'a, T: serde::Deserialize<'a>>(v: &'a Option<Vec<u8>>) -> Option<T> {
84
-        if let Some(v) = v {
85
-            if let Ok(v) = std::str::from_utf8(v) {
86
-                if let Ok(v) = serde_json::from_str::<T>(&v) {
87
-                    return Some(v);
88
-                }
89
-            }
90
-        }
91
-        None
92
-    }
93
-
94
-    pub fn insert<T: serde::Serialize>(&mut self, key: String, v: T) {
95
-        if let Some(tx) = &self.tx {
96
-            if let Ok(v) = serde_json::to_vec(&v) {
97
-                allow_err!(tx.send(Action::Insert((key, v))));
98
-            }
99
-        }
100
-    }
101
-}

+ 1 - 0
src/version.rs

@@ -0,0 +1 @@
1
+pub const VERSION: &str = "1.1.5";