feat: worked some on the tcp client
found out ethtool helps make the program work with lxc sockets
This commit is contained in:
parent
f5b31954d4
commit
f092548a8c
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -719,12 +719,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.17"
|
version = "0.4.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "managed"
|
name = "managed"
|
||||||
@ -1219,11 +1216,10 @@ checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simple_logger"
|
name = "simple_logger"
|
||||||
version = "4.1.0"
|
version = "4.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e78beb34673091ccf96a8816fce8bfd30d1292c7621ca2bcb5f2ba0fae4f558d"
|
checksum = "2230cd5c29b815c9b699fb610b49a5ed65588f3509d9f0108be3a885da629333"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
|
||||||
"colored",
|
"colored",
|
||||||
"log",
|
"log",
|
||||||
"time",
|
"time",
|
||||||
@ -1419,10 +1415,12 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"libc",
|
"libc",
|
||||||
|
"log",
|
||||||
"nl-sys",
|
"nl-sys",
|
||||||
"packets",
|
"packets",
|
||||||
"pcap-sys",
|
"pcap-sys",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
"simple_logger",
|
||||||
"smoltcp",
|
"smoltcp",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
|
|||||||
@ -13,5 +13,7 @@ rand = "0.8.5"
|
|||||||
tokio = { version = "1.32.0", features = ["full"] }
|
tokio = { version = "1.32.0", features = ["full"] }
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
tokio-stream = { version = "0.1.14", features = ["full"] }
|
tokio-stream = { version = "0.1.14", features = ["full"] }
|
||||||
smoltcp = { version = "0.10.0", features = ["socket-tcp", "phy-raw_socket", "std", "async", "medium-ethernet", "proto-ipv4", "reassembly-buffer-size-65536", "fragmentation-buffer-size-65536", "proto-ipv4-fragmentation"] }
|
smoltcp = { version = "0.10", features = ["socket-tcp", "phy-raw_socket", "std", "async", "medium-ethernet", "proto-ipv4", "reassembly-buffer-size-65536", "fragmentation-buffer-size-65536", "proto-ipv4-fragmentation", "log", "verbose"] }
|
||||||
libc = "0.2.148"
|
libc = "0.2.148"
|
||||||
|
log = "0.4.20"
|
||||||
|
simple_logger = "4.2.0"
|
||||||
|
|||||||
@ -2,11 +2,12 @@ use std::{net::Ipv4Addr, os::fd::AsRawFd, sync::Arc};
|
|||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
use log::{debug, info, trace};
|
||||||
use nl_sys::{netlink, route};
|
use nl_sys::{netlink, route};
|
||||||
|
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{Config, Interface, Route, SocketSet},
|
iface::{Config, Interface, Route, SocketSet},
|
||||||
phy::{wait as phy_wait, Medium, RawSocket},
|
phy::{wait as phy_wait, Device, Medium, RawSocket},
|
||||||
socket::tcp,
|
socket::tcp,
|
||||||
time::Instant,
|
time::Instant,
|
||||||
wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address},
|
wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address},
|
||||||
@ -15,6 +16,11 @@ use tokio::io::{unix::AsyncFd, Interest};
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
simple_logger::SimpleLogger::new()
|
||||||
|
.with_level(log::LevelFilter::Trace)
|
||||||
|
.with_module_level("tcp_test", log::LevelFilter::Trace)
|
||||||
|
.init()?;
|
||||||
|
|
||||||
let ip = std::env::args()
|
let ip = std::env::args()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.next()
|
.next()
|
||||||
@ -45,6 +51,11 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let mut iface = Interface::new(config, &mut device, Instant::now());
|
let mut iface = Interface::new(config, &mut device, Instant::now());
|
||||||
iface.update_ip_addrs(|ip_addrs| {
|
iface.update_ip_addrs(|ip_addrs| {
|
||||||
let o = srcip.octets();
|
let o = srcip.octets();
|
||||||
|
debug!(
|
||||||
|
"source network ip: {}.{}.{}.{}/{src_snmask}",
|
||||||
|
o[0], o[1], o[2], o[3]
|
||||||
|
);
|
||||||
|
|
||||||
ip_addrs
|
ip_addrs
|
||||||
.push(IpCidr::new(
|
.push(IpCidr::new(
|
||||||
IpAddress::v4(o[0], o[1], o[2], o[3]),
|
IpAddress::v4(o[0], o[1], o[2], o[3]),
|
||||||
@ -55,21 +66,49 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
for route in routes.iter() {
|
for route in routes.iter() {
|
||||||
let Some(dst) = route.dst() else {
|
let Some(dst) = route.dst() else {
|
||||||
|
trace!("failed to get route destination");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(hop) = route.hop_iter().next() else {
|
let Some(hop) = route.hop_iter().next() else {
|
||||||
|
trace!("no next hop existed for {dst:?}");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if hop.ifindex() != ifindex {
|
if hop.ifindex() != ifindex {
|
||||||
|
trace!("hop doesn't match ifindex {ifindex}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(laddr) = hop.gateway() else {
|
let Some(laddr) = hop.gateway() else {
|
||||||
|
trace!("couldn't get gateway address for {dst:?}");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if laddr.atype() != Some(libc::AF_INET) {
|
if laddr.atype() != Some(libc::AF_INET) {
|
||||||
|
trace!("unable to load IP info for {dst:?}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dst.cidrlen() == 0 {
|
||||||
|
info!("setting default route via {:?}", &laddr);
|
||||||
|
iface
|
||||||
|
.routes_mut()
|
||||||
|
.add_default_ipv4_route(Ipv4Address::from_bytes(&laddr.hw_address()))?;
|
||||||
|
|
||||||
|
iface.routes_mut().update(|routes| {
|
||||||
|
let lip = laddr.hw_address();
|
||||||
|
_ = routes.push(Route {
|
||||||
|
cidr: IpCidr::new(IpAddress::v4(10, 0, 0, 0), 8),
|
||||||
|
via_router: IpAddress::v4(lip[0], lip[1], lip[2], lip[3]),
|
||||||
|
expires_at: None,
|
||||||
|
preferred_until: None,
|
||||||
|
});
|
||||||
|
_ = routes.push(Route {
|
||||||
|
cidr: IpCidr::new(IpAddress::v4(172, 16, 0, 0), 12),
|
||||||
|
via_router: IpAddress::v4(lip[0], lip[1], lip[2], lip[3]),
|
||||||
|
expires_at: None,
|
||||||
|
preferred_until: None,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
let Some(raddr) = route.dst() else {
|
let Some(raddr) = route.dst() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@ -77,15 +116,36 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if dst.cidrlen() == 0 {
|
|
||||||
iface
|
|
||||||
.routes_mut()
|
|
||||||
.add_default_ipv4_route(Ipv4Address::from_bytes(&laddr.hw_address()))?;
|
|
||||||
} else {
|
|
||||||
iface.routes_mut().update(|routes| {
|
|
||||||
let lip = laddr.hw_address();
|
let lip = laddr.hw_address();
|
||||||
let rip = raddr.hw_address();
|
let rip = raddr.hw_address();
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"queueing adding {}.{}.{}.{}/{} via {}.{}.{}.{}",
|
||||||
|
rip[0],
|
||||||
|
rip[1],
|
||||||
|
rip[2],
|
||||||
|
rip[3],
|
||||||
|
dst.cidrlen(),
|
||||||
|
lip[0],
|
||||||
|
lip[1],
|
||||||
|
lip[2],
|
||||||
|
lip[3]
|
||||||
|
);
|
||||||
|
|
||||||
|
iface.routes_mut().update(|routes| {
|
||||||
|
info!(
|
||||||
|
"adding {}.{}.{}.{}/{} via {}.{}.{}.{}",
|
||||||
|
rip[0],
|
||||||
|
rip[1],
|
||||||
|
rip[2],
|
||||||
|
rip[3],
|
||||||
|
dst.cidrlen(),
|
||||||
|
lip[0],
|
||||||
|
lip[1],
|
||||||
|
lip[2],
|
||||||
|
lip[3]
|
||||||
|
);
|
||||||
|
|
||||||
_ = routes.push(Route {
|
_ = routes.push(Route {
|
||||||
cidr: IpCidr::new(
|
cidr: IpCidr::new(
|
||||||
IpAddress::v4(rip[0], rip[1], rip[2], rip[3]),
|
IpAddress::v4(rip[0], rip[1], rip[2], rip[3]),
|
||||||
@ -99,8 +159,15 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tcp_rx_buffer = tcp::SocketBuffer::new(vec![0; 1500]);
|
debug!("routes added:");
|
||||||
let tcp_tx_buffer = tcp::SocketBuffer::new(vec![0; 1500]);
|
iface.routes_mut().update(|r| {
|
||||||
|
for r in r {
|
||||||
|
debug!("\t{r:?}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let tcp_rx_buffer = tcp::SocketBuffer::new(vec![0; 65536]);
|
||||||
|
let tcp_tx_buffer = tcp::SocketBuffer::new(vec![0; 65536]);
|
||||||
let tcp_socket = tcp::Socket::new(tcp_rx_buffer, tcp_tx_buffer);
|
let tcp_socket = tcp::Socket::new(tcp_rx_buffer, tcp_tx_buffer);
|
||||||
let mut sockets = SocketSet::new(vec![]);
|
let mut sockets = SocketSet::new(vec![]);
|
||||||
let tcp_handle = sockets.add(tcp_socket);
|
let tcp_handle = sockets.add(tcp_socket);
|
||||||
@ -117,15 +184,13 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
socket.connect(iface.context(), (ip, 54248), port)?;
|
socket.connect(iface.context(), (ip, 54248), port)?;
|
||||||
|
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
let interest = Interest::WRITABLE
|
/*let interest = Interest::WRITABLE
|
||||||
.add(Interest::READABLE)
|
.add(Interest::READABLE)
|
||||||
.add(Interest::ERROR)
|
.add(Interest::ERROR)
|
||||||
.add(Interest::PRIORITY);
|
.add(Interest::PRIORITY);
|
||||||
let afd = AsyncFd::with_interest(fd, interest)?;
|
let afd = AsyncFd::with_interest(fd, interest)?;*/
|
||||||
|
|
||||||
let mut tcp_active = false;
|
let mut tcp_active = false;
|
||||||
let mut tcp_data_sent = false;
|
|
||||||
let mut tcp_data_recvd = false;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let timestamp = Instant::now();
|
let timestamp = Instant::now();
|
||||||
@ -133,32 +198,36 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
|
let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
|
||||||
if socket.is_active() && !tcp_active {
|
if socket.is_active() && !tcp_active {
|
||||||
println!("connected!");
|
info!("connected!");
|
||||||
|
tcp_active = true;
|
||||||
} else if !socket.is_active() && tcp_active {
|
} else if !socket.is_active() && tcp_active {
|
||||||
println!("disconnected");
|
info!("disconnected");
|
||||||
break Ok(());
|
tcp_active = false;
|
||||||
}
|
}
|
||||||
tcp_active = socket.is_active();
|
tcp_active = socket.is_active();
|
||||||
|
|
||||||
if !tcp_data_sent && socket.can_send() {
|
if !socket.is_active() && !tcp_active {
|
||||||
socket.send_slice(b"ping")?;
|
socket.connect(iface.context(), (ip, 54248), port)?;
|
||||||
tcp_data_sent = true;
|
info!("connecting...");
|
||||||
}
|
}
|
||||||
if !tcp_data_recvd && socket.may_recv() {
|
|
||||||
|
if socket.can_send() {
|
||||||
|
socket.send_slice(b"ping")?;
|
||||||
|
info!("sent data!");
|
||||||
|
} else if socket.may_recv() {
|
||||||
socket.recv(|data| {
|
socket.recv(|data| {
|
||||||
if !data.is_empty() {
|
if !data.is_empty() {
|
||||||
match std::str::from_utf8(&data) {
|
match std::str::from_utf8(&data) {
|
||||||
Ok(s) => println!("Data received: {}", s),
|
Ok(s) => info!("Data received: {}", s),
|
||||||
Err(_) => println!("Data received: {:?}", data),
|
Err(_) => info!("Data received: {:?}", data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(data.len(), data)
|
(data.len(), data)
|
||||||
})?;
|
})?;
|
||||||
tcp_data_recvd = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// phy_wait(fd, iface.poll_delay(timestamp, &sockets))?;
|
phy_wait(fd, iface.poll_delay(timestamp, &sockets))?;
|
||||||
|
|
||||||
drop(afd.ready(interest).await?);
|
// drop(afd.ready(interest).await?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user