1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use core::net::SocketAddr;
use super::op::OpImpl;
use crate::client::ClientSocketOp;
use crate::manager::SocketError;
use crate::stack::sock_holder::SocketStore;
use crate::stack::socket_callbacks::SocketCallbacks;
use crate::stack::socket_callbacks::{AsyncOp, AsyncState};
use crate::transfer::Xfer;
use crate::Handle;
use crate::StackError;
// Pure UDP receive operation state
#[derive(Debug)]
pub struct UdpReceiveOp<'buffer> {
handle: Handle,
buffer: &'buffer mut [u8],
}
impl<'buffer> UdpReceiveOp<'buffer> {
pub fn new(handle: Handle, buffer: &'buffer mut [u8]) -> Self {
Self { handle, buffer }
}
}
impl<X: Xfer> OpImpl<X> for UdpReceiveOp<'_> {
type Output = (usize, SocketAddr);
type Error = StackError;
fn poll_impl(
&mut self,
manager: &mut crate::manager::Manager<X>,
callbacks: &mut SocketCallbacks,
) -> Result<Option<Self::Output>, Self::Error> {
let (sock, op) = callbacks
.udp_sockets
.get(self.handle)
.ok_or(StackError::SocketNotFound)?;
let socket = *sock;
// Handle partial data from a previous operation first
if let ClientSocketOp::AsyncOp(
AsyncOp::RecvFrom(Some(ref mut recv_result)),
AsyncState::Done,
) = op
{
if recv_result.return_offset < recv_result.recv_len {
let remaining_data = recv_result.recv_len - recv_result.return_offset;
let copy_len = remaining_data.min(self.buffer.len());
self.buffer[..copy_len].copy_from_slice(
&callbacks.recv_buffer
[recv_result.return_offset..recv_result.return_offset + copy_len],
);
recv_result.return_offset += copy_len;
let from_addr = recv_result.from_addr;
if recv_result.return_offset >= recv_result.recv_len {
*op = ClientSocketOp::None;
}
return Ok(Some((copy_len, SocketAddr::V4(from_addr))));
}
}
match op {
ClientSocketOp::AsyncOp(AsyncOp::RecvFrom(Some(recv_result)), _) => {
match recv_result.error {
SocketError::NoError => {
let recv_len = recv_result.recv_len;
let from_addr = recv_result.from_addr;
if recv_len == 0 {
// Zero-length datagram - clear state and return immediately
recv_result.return_offset = 0;
*op = ClientSocketOp::None;
return Ok(Some((0, SocketAddr::V4(from_addr))));
}
let copy_len = recv_len.min(self.buffer.len());
self.buffer[..copy_len].copy_from_slice(&callbacks.recv_buffer[..copy_len]);
recv_result.return_offset = copy_len;
if copy_len >= recv_len {
*op = ClientSocketOp::None;
}
Ok(Some((copy_len, SocketAddr::V4(from_addr))))
}
SocketError::Timeout => {
// Set operation state BEFORE calling send_recvfrom to avoid reentrancy races
let prev_op = core::mem::replace(
op,
ClientSocketOp::AsyncOp(
AsyncOp::RecvFrom(None),
AsyncState::Pending(None),
),
);
// Now call send_recvfrom - if it fails, revert to previous state
match manager.send_recvfrom(socket, socket.get_recv_timeout()) {
Ok(()) => Ok(None),
Err(e) => {
// Revert to previous state on failure
*op = prev_op;
Err(StackError::ReceiveFailed(e))
}
}
}
error => {
*op = ClientSocketOp::None;
Err(StackError::OpFailed(error))
}
}
}
ClientSocketOp::AsyncOp(AsyncOp::RecvFrom(None), AsyncState::Pending(_)) => Ok(None),
_ => {
// Not initialized, so start the operation
// Set operation state BEFORE calling send_recvfrom to avoid reentrancy races
let prev_op = core::mem::replace(
op,
ClientSocketOp::AsyncOp(AsyncOp::RecvFrom(None), AsyncState::Pending(None)),
);
// Now call send_recvfrom - if it fails, revert to previous state
match manager.send_recvfrom(socket, socket.get_recv_timeout()) {
Ok(()) => Ok(None),
Err(e) => {
// Revert to previous state on failure
*op = prev_op;
Err(StackError::ReceiveFailed(e))
}
}
}
}
}
}