Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
R
railgun-routing-server
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Railgun
railgun-routing-server
Commits
a07d1f23
Commit
a07d1f23
authored
Jan 06, 2026
by
nanamicat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
delay
parent
43872183
Pipeline
#42420
passed with stages
in 53 seconds
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
30 additions
and
38 deletions
+30
-38
src/main.rs
src/main.rs
+4
-2
src/quality.rs
src/quality.rs
+3
-8
src/router.rs
src/router.rs
+23
-28
No files found.
src/main.rs
View file @
a07d1f23
...
...
@@ -66,6 +66,7 @@ async fn main() -> Result<()> {
let
socket
=
UdpSocket
::
bind
(
config
.udp_bind
)
.await
?
;
println!
(
"UDP listening on {}"
,
config
.udp_bind
);
let
mut
buf
=
[
0u8
;
u16
::
MAX
as
usize
];
// Max UDP size
let
start
=
Instant
::
now
();
loop
{
let
(
len
,
addr
)
=
socket
.recv_from
(
&
mut
buf
)
.await
?
;
...
...
@@ -81,14 +82,15 @@ async fn main() -> Result<()> {
if
updating
.router_id
!=
0
&&
!
routers
.get
(
&
updating
.router_id
)
.context
(
"router not found"
)
?
.is_online
()
{
updating
.router_id
=
0
;
}
tracing
::
info
!
(
"recv {:?}"
,
uplink
);
tracing
::
debug
!
(
"recv {:?}"
,
uplink
);
// 处理收到的消息
if
let
Some
(
router
)
=
routers
.get_mut
(
&
uplink
.id
)
&&
let
Some
(
downlink
)
=
router
.on_message
(
&
mut
uplink
,
addr
,
&
mut
updating
,
now
)
{
tracing
::
info
!
(
"sync to {}: {:?}"
,
router
.id
,
downlink
);
tracing
::
debug
!
(
"sync to {}: {:?}"
,
router
.id
,
downlink
);
send
(
&
downlink
,
&
mut
buf
,
&
socket
,
&
addr
)
.await
?
;
}
else
if
updating
.router_id
==
0
&&
now
.duration_since
(
start
)
>=
TIMEOUT
// 刚启动时静默,先学习
&&
let
Some
(
router
)
=
routers
.get
(
&
uplink
.id
)
&&
let
Some
(
downlink
)
=
router
.update
(
&
routers
,
&
connections
)
{
...
...
src/quality.rs
View file @
a07d1f23
...
...
@@ -10,13 +10,6 @@ pub struct Quality {
}
impl
Quality
{
pub
const
UNREACHABLE
:
Quality
=
Quality
{
delay
:
0
,
jitter
:
0
,
reliability
:
0.0
,
cost
:
0
,
};
pub
fn
concat
(
&
mut
self
,
next
:
&
PeerQuality
,
cost
:
u32
)
{
self
.delay
+=
next
.delay
as
i32
;
self
.jitter
+=
next
.jitter
as
u32
;
...
...
@@ -33,8 +26,10 @@ impl Quality {
self
.delay
+
((
1.0
-
self
.reliability
)
*
10000.0
)
.round
()
as
i32
+
self
.cost
as
i32
}
}
}
pub
(
crate
)
fn
default
()
->
Self
{
impl
Default
for
Quality
{
fn
default
()
->
Self
{
Self
{
delay
:
0
,
jitter
:
0
,
...
...
src/router.rs
View file @
a07d1f23
...
...
@@ -97,6 +97,7 @@ impl Router {
self
.via
.append
(
&
mut
uplink
.via
);
self
.plan
.append
(
&
mut
uplink
.plan
);
self
.online
(
addr
,
now
);
tracing
::
info!
(
"router {} full via={:?}"
,
self
.id
,
self
.via
);
}
None
}
...
...
@@ -136,19 +137,24 @@ impl Router {
for
to
in
routers
.values
()
.filter
(|
&
r
|
r
!=
self
)
{
let
current_router
=
routers
.get
(
self
.via
.get
(
&
to
.id
)
.unwrap
())
.unwrap
();
let
current_metric
=
self
.route_quality
(
to
,
current_router
,
routers
,
connections
)
.m
etric
(
);
let
current_metric
=
self
.route_quality
(
to
,
current_router
,
routers
,
connections
)
.m
ap_or
(
i32
::
MAX
,
|
r
|
r
.metric
()
);
let
candidate
:
Vec
<
(
&
Router
,
i32
)
>
=
connections
[
&
self
.id
]
.keys
()
.map
(|
id
|
routers
.get
(
id
)
.unwrap
())
.
map
(|
r
|
(
r
,
self
.route_quality
(
to
,
r
,
routers
,
connections
)
.metric
(
)))
.
filter_map
(|
r
|
self
.route_quality
(
to
,
r
,
routers
,
connections
)
.map
(|
q
|
(
r
,
q
.metric
()
)))
.collect
();
let
(
best_router
,
best_metric
)
=
candidate
.iter
()
.min_by_key
(|(
_
,
m
)|
m
)
.unwrap
();
let
best_router
=
if
*
best_metric
==
i32
::
MAX
{
to
}
else
{
best_router
};
match
candidate
.iter
()
.min_by_key
(|(
_
,
m
)|
m
)
{
None
if
current_router
!=
to
=>
{
// 无论如何都不可达就标记为直连
if
current_router
!=
best_router
&&
(
*
best_metric
==
i32
::
MAX
||
*
best_metric
+
THROTTLE
<
current_metric
)
{
changed_via
.insert
(
to
.id
,
to
.id
);
}
Some
((
best_router
,
best_metric
))
if
current_router
!=
*
best_router
&&
(
*
best_metric
+
THROTTLE
<
current_metric
)
=>
{
changed_via
.insert
(
to
.id
,
best_router
.id
);
}
_
=>
{}
}
}
if
changed_via
.len
()
>
0
{
...
...
@@ -164,34 +170,23 @@ impl Router {
}
}
pub
fn
route_quality
(
&
self
,
to
:
&
Router
,
via
:
&
Router
,
routers
:
&
BTreeMap
<
u8
,
Router
>
,
connections
:
&
BTreeMap
<
u8
,
BTreeMap
<
u8
,
ConnectionData
>>
)
->
Quality
{
pub
fn
route_quality
(
&
self
,
to
:
&
Router
,
via
:
&
Router
,
routers
:
&
BTreeMap
<
u8
,
Router
>
,
connections
:
&
BTreeMap
<
u8
,
BTreeMap
<
u8
,
ConnectionData
>>
)
->
Option
<
Quality
>
{
assert
!
(
self
!=
to
);
assert
!
(
self
!=
via
);
let
mut
result
:
Quality
=
Quality
::
default
();
let
mut
route
=
vec!
[
self
,
via
];
let
mut
result
:
Quality
=
Default
::
default
();
let
mut
route
=
vec!
[
self
];
let
mut
current
=
self
;
let
mut
next
=
via
;
loop
{
if
!
next
.is_online
()
{
return
Quality
::
UNREACHABLE
;
}
// 不通的情况 via 会标记为直连,实际不可达
match
next
.peers
.get
(
&
current
.id
)
{
None
=>
return
Quality
::
UNREACHABLE
,
while
current
!=
to
{
let
next
=
if
current
==
self
{
via
}
else
{
&
routers
[
&
current
.via
[
&
to
.id
]]
};
match
next
.peers
.get
(
&
current
.id
)
.filter
(|
_
|
next
.is_online
()
&&
!
route
.contains
(
&
next
))
{
None
=>
return
None
,
Some
(
quality
)
if
quality
.reliability
==
0
=>
return
None
,
Some
(
quality
)
=>
result
.concat
(
quality
,
connections
[
&
current
.id
][
&
next
.id
]
.metric
),
}
// Next hop
current
=
next
;
next
=
&
routers
[
&
current
.via
[
&
to
.id
]];
// 检查环路
if
route
.contains
(
&
next
)
{
return
Quality
::
UNREACHABLE
;
}
route
.push
(
next
);
current
=
next
;
}
Some
(
result
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment