Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bc5aa00

Browse files
committed
starting with multiplexing
1 parent cd74a71 commit bc5aa00

File tree

5 files changed

+117
-9
lines changed

5 files changed

+117
-9
lines changed

Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

muxer/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7+
tokio = { version = "1", features = ["full"] }
8+
common = {path = "../common" }

muxer/src/lib.rs

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,104 @@
1-
pub fn add(left: u64, right: u64) -> u64 {
2-
left + right
1+
use common::EncryptedStream;
2+
use std::collections::HashMap;
3+
use tokio::io::{AsyncBufReadExt, BufReader};
4+
5+
pub async fn negotiate_multiplexing_protocol(
6+
stream: &mut EncryptedStream,
7+
is_initiator: bool,
8+
supported_protocols: &HashMap<&'static str, Vec<&'static str>>,
9+
) {
10+
if is_initiator {
11+
println!("[negotiate_protocol] -> Sending /multistream/1.0.0");
12+
let _ = stream.send(b"/multistream/1.0.0\n").await;
13+
}
14+
15+
let response = stream.recv().await.unwrap();
16+
let proto = String::from_utf8_lossy(&response);
17+
println!(
18+
"[negotiate_protocol] <- Received negotiation protocol: {}",
19+
proto
20+
);
21+
22+
if proto.trim() == "/multistream/1.0.0" {
23+
if !is_initiator {
24+
println!("[negotiate_protocol] -> Sending /multistream/1.0.0");
25+
let _ = stream.send(b"/multistream/1.0.0\n").await;
26+
}
27+
println!("[negotiate_protocol] Entering subprotocol negotiation");
28+
if let Some(transport) = negotiate(stream, is_initiator, &supported_protocols)
29+
.await
30+
.unwrap()
31+
{
32+
println!("[negotiate_protocol] ✅ Agreed on protocol: {transport}");
33+
} else {
34+
eprintln!("[negotiate_protocol] ❌ Unimplemented protocol");
35+
}
36+
} else {
37+
eprintln!(
38+
"[negotiate_protocol] Unsupported negotiation protocol: {other}",
39+
other = proto
40+
);
41+
std::process::exit(1);
42+
}
343
}
444

5-
#[cfg(test)]
6-
mod tests {
7-
use super::*;
45+
async fn negotiate(
46+
stream: &mut EncryptedStream,
47+
is_initiator: bool,
48+
supported_protocols: &HashMap<&'static str, Vec<&'static str>>,
49+
) -> tokio::io::Result<Option<String>> {
50+
println!("[negotiate] Started negotiation, initiator={is_initiator}");
51+
52+
if is_initiator {
53+
let mut input = String::new();
54+
let mut stdin_reader = BufReader::new(tokio::io::stdin());
55+
println!(
56+
"[negotiate][initiator] Available protocols: {:?}",
57+
supported_protocols.get("multiplexing")
58+
);
59+
60+
stdin_reader.read_line(&mut input).await?;
61+
let proto = input.trim();
62+
println!("[negotiate][initiator] Proposing protocol: {proto}");
63+
64+
stream.send(format!("{proto}\n").as_bytes()).await?;
65+
66+
let response = stream.recv().await.unwrap();
67+
let line = String::from_utf8_lossy(&response);
68+
println!("[negotiate][initiator] <- Received response: {}", line);
69+
70+
if line.trim() == proto {
71+
println!("[negotiate][initiator] ✅ Negotiated protocol: {proto}");
72+
Ok(Some(proto.to_string()))
73+
} else {
74+
println!(
75+
"[negotiate][initiator] ❌ Protocol rejected by responder: {}",
76+
line.trim()
77+
);
78+
Ok(None)
79+
}
80+
} else {
81+
println!("[negotiate][responder] Waiting for initiator proposal");
82+
let response = stream.recv().await.unwrap();
83+
let line = String::from_utf8_lossy(&response);
84+
let proposal = line.trim();
85+
println!("[negotiate][responder] <- Received proposal: {proposal}");
886

9-
#[test]
10-
fn it_works() {
11-
let result = add(2, 2);
12-
assert_eq!(result, 4);
87+
if let Some(p) = supported_protocols.get("multiplexing") {
88+
if p.contains(&proposal) {
89+
println!("[negotiate][responder] ✅ Accepting proposal: {proposal}");
90+
stream.send(format!("{}\n", proposal).as_bytes()).await?;
91+
Ok(Some(proposal.to_string()))
92+
} else {
93+
eprintln!(
94+
"[negotiate][responder] ❌ Unsupported proposal: {proposal}, replying 'na'"
95+
);
96+
stream.send(b"na\n").await?;
97+
Ok(None)
98+
}
99+
} else {
100+
eprintln!("[negotiate][responder] ⚠️ No protocols found in supported_protocols");
101+
Ok(None)
102+
}
13103
}
14104
}

transport/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ negotiation = { path = "../negotiation/" }
1111
security = { path = "../security" }
1212
snow = "0.10"
1313
common = { path = "../common"}
14+
muxer = { path = "../muxer" }

transport/src/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use common::EncryptedStream;
2+
use muxer::negotiate_multiplexing_protocol;
23
use negotiation::negotiate_protocol;
34
use security::negotiate_security_protocol;
45
use std::{env, net::SocketAddr, sync::Arc};
@@ -75,6 +76,10 @@ async fn run_client(addr: &str) {
7576
writer: Mutex::new(writer),
7677
};
7778

79+
println!("[client] Starting multiplexing protocol negotiation...");
80+
negotiate_multiplexing_protocol(&mut stream, true, &supported_protocols()).await;
81+
println!("[client] Protocol negotiation complete");
82+
7883
println!("[client] Starting protocol negotiation...");
7984
negotiate_protocol(&mut stream, true, &supported_protocols()).await;
8085
println!("[client] Protocol negotiation complete");
@@ -147,6 +152,10 @@ async fn handle_connection(socket: TcpStream, addr: SocketAddr) {
147152
writer: Mutex::new(writer),
148153
};
149154

155+
println!("[server] Starting multiplexing protocol negotiation...");
156+
negotiate_multiplexing_protocol(&mut stream, false, &supported_protocols()).await;
157+
println!("[server] Protocol negotiation complete");
158+
150159
println!("[server] Starting protocol negotiation with {addr}");
151160
negotiate_protocol(&mut stream, false, &supported_protocols()).await;
152161
println!("[server] Protocol negotiation complete with {addr}");
@@ -182,5 +191,6 @@ fn supported_protocols() -> HashMap<&'static str, Vec<&'static str>> {
182191
HashMap::from([
183192
("security", vec!["/noise/xx"]),
184193
("protocol", vec!["/ping/1.0.0"]),
194+
("multiplexing", vec!["/yamux", "/mplex"]),
185195
])
186196
}

0 commit comments

Comments
 (0)