mirror of
https://github.com/cubixle/radius-rs.git
synced 2026-04-30 16:38:45 +01:00
Add client impl
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
|
use crate::client::ClientError::{FailedConnection, FailedParsingUDPResponse, FailedRadiusPacketEncoding, FailedReceivingResponse, FailedSendingPacket, FailedUdpSocketBinding};
|
||||||
|
use crate::packet::Packet;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ClientError {
|
||||||
|
#[error("failed to bind a UDP socket => `{0}`")]
|
||||||
|
FailedUdpSocketBinding(String),
|
||||||
|
#[error("failed to connect to `{0}` => `{1}`")]
|
||||||
|
FailedConnection(String, String),
|
||||||
|
#[error("failed to encode a RADIUS request => `{0}`")]
|
||||||
|
FailedRadiusPacketEncoding(String),
|
||||||
|
#[error("failed to send a UDP datagram to `{0}` => `{1}`")]
|
||||||
|
FailedSendingPacket(String, String),
|
||||||
|
#[error("failed to receive the UDP response from `{0}` => `{1}`")]
|
||||||
|
FailedReceivingResponse(String, String),
|
||||||
|
#[error("failed to parse a UDP response into a RADIUS packet => `{0}`")]
|
||||||
|
FailedParsingUDPResponse(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Client {}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
const MAX_DATAGRAM_SIZE: usize = 65507;
|
||||||
|
|
||||||
|
pub async fn send_packet(remote_addr: &SocketAddr, request_packet: &Packet) -> Result<Packet, ClientError> {
|
||||||
|
// TODO retransmission
|
||||||
|
|
||||||
|
let local_addr: SocketAddr = if remote_addr.is_ipv4() {
|
||||||
|
"0.0.0.0:0"
|
||||||
|
} else {
|
||||||
|
"[::]:0"
|
||||||
|
}.parse().unwrap();
|
||||||
|
|
||||||
|
let conn = match UdpSocket::bind(local_addr).await {
|
||||||
|
Ok(conn) => conn,
|
||||||
|
Err(e) => return Err(FailedUdpSocketBinding(e.to_string())),
|
||||||
|
};
|
||||||
|
match conn.connect(remote_addr).await {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => return Err(FailedConnection(remote_addr.to_string(), e.to_string()))
|
||||||
|
};
|
||||||
|
|
||||||
|
let request_data = match request_packet.encode() {
|
||||||
|
Ok(encoded) => encoded,
|
||||||
|
Err(e) => return Err(FailedRadiusPacketEncoding(e.to_string()))
|
||||||
|
};
|
||||||
|
|
||||||
|
match conn.send(request_data.as_slice()).await {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => return Err(FailedSendingPacket(remote_addr.to_string(), e.to_string()))
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buf = vec![0; Self::MAX_DATAGRAM_SIZE];
|
||||||
|
let len = match conn.recv(&mut buf).await {
|
||||||
|
Ok(len) => len,
|
||||||
|
Err(e) => return Err(FailedReceivingResponse(remote_addr.to_string(), e.to_string()))
|
||||||
|
};
|
||||||
|
|
||||||
|
match Packet::parse(&buf[..len].to_vec(), request_packet.get_secret()) {
|
||||||
|
Ok(response_packet) => Ok(response_packet),
|
||||||
|
Err(e) => Err(FailedParsingUDPResponse(e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,3 +9,4 @@ pub mod server;
|
|||||||
pub mod secret_provider;
|
pub mod secret_provider;
|
||||||
pub mod request_handler;
|
pub mod request_handler;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
|
pub mod client;
|
||||||
|
|||||||
+5
-1
@@ -29,10 +29,14 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_identifier(&self) -> u8 {
|
pub fn get_identifier(&self) -> u8 {
|
||||||
self.identifier
|
self.identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_secret(&self) -> &Vec<u8> {
|
||||||
|
&self.secret
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse(bs: &Vec<u8>, secret: &Vec<u8>) -> Result<Self, String> {
|
pub fn parse(bs: &Vec<u8>, secret: &Vec<u8>) -> Result<Self, String> {
|
||||||
if bs.len() < 20 {
|
if bs.len() < 20 {
|
||||||
return Err("radius packet doesn't have enough length of bytes; that has to be at least 20 bytes".to_owned());
|
return Err("radius packet doesn't have enough length of bytes; that has to be at least 20 bytes".to_owned());
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ impl Server {
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("failed to parse given request data to pack into the RADIUS packet; {}", e);
|
error!("failed to parse given request data to pack into the RADIUS packet; {}", e);
|
||||||
debug!("failed request data => {:?}", request_data);
|
debug!("failed request data => {:?}", request_data);
|
||||||
|
// TODO error handler?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user