mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
gnrc_sock: consider all pktsnip for gnrc_neterr reporting
As analyzed in #12678 there are cases where different reports can be generated for the different snips of the packet send via the `sock`. To catch all errors generated by the stack, the sock has to subscribe for all snips of the packet sent. If any of the snips reports an error distinct from `GNRC_NETERR_SUCCESS` or the previous one, we report that status instead of just the first we receive. This way we are ensured to have the first error reported by the stack for the given packet.
This commit is contained in:
parent
f092c27356
commit
8992dce4da
@ -120,6 +120,9 @@ ssize_t gnrc_sock_send(gnrc_pktsnip_t *payload, sock_ip_ep_t *local,
|
||||
kernel_pid_t iface = KERNEL_PID_UNDEF;
|
||||
gnrc_nettype_t type;
|
||||
size_t payload_len = gnrc_pkt_len(payload);
|
||||
#ifdef MODULE_GNRC_NETERR
|
||||
unsigned status_subs = 0;
|
||||
#endif
|
||||
|
||||
if (local->family != remote->family) {
|
||||
gnrc_pktbuf_release(payload);
|
||||
@ -172,7 +175,14 @@ ssize_t gnrc_sock_send(gnrc_pktsnip_t *payload, sock_ip_ep_t *local,
|
||||
LL_PREPEND(pkt, netif);
|
||||
}
|
||||
#ifdef MODULE_GNRC_NETERR
|
||||
gnrc_neterr_reg(pkt); /* no error should occur since pkt was created here */
|
||||
/* cppcheck-suppress uninitvar
|
||||
* (reason: pkt is initialized in AF_INET6 case above, otherwise function
|
||||
* will return early) */
|
||||
for (gnrc_pktsnip_t *ptr = pkt; ptr != NULL; ptr = ptr->next) {
|
||||
/* no error should occur since pkt was created here */
|
||||
gnrc_neterr_reg(ptr);
|
||||
status_subs++;
|
||||
}
|
||||
#endif
|
||||
if (!gnrc_netapi_dispatch_send(type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
|
||||
/* this should not happen, but just in case */
|
||||
@ -180,6 +190,9 @@ ssize_t gnrc_sock_send(gnrc_pktsnip_t *payload, sock_ip_ep_t *local,
|
||||
return -EBADMSG;
|
||||
}
|
||||
#ifdef MODULE_GNRC_NETERR
|
||||
uint32_t last_status = GNRC_NETERR_SUCCESS;
|
||||
|
||||
while (status_subs--) {
|
||||
msg_t err_report;
|
||||
err_report.type = 0;
|
||||
|
||||
@ -189,8 +202,22 @@ ssize_t gnrc_sock_send(gnrc_pktsnip_t *payload, sock_ip_ep_t *local,
|
||||
msg_try_send(&err_report, sched_active_pid);
|
||||
}
|
||||
}
|
||||
if (err_report.content.value != GNRC_NETERR_SUCCESS) {
|
||||
return (int)(-err_report.content.value);
|
||||
if (err_report.content.value != last_status) {
|
||||
int res = (int)(-err_report.content.value);
|
||||
|
||||
for (unsigned i = 0; i < status_subs; i++) {
|
||||
err_report.type = 0;
|
||||
/* remove remaining status reports from queue */
|
||||
while (err_report.type != GNRC_NETERR_MSG_TYPE) {
|
||||
msg_try_receive(&err_report);
|
||||
if (err_report.type != GNRC_NETERR_MSG_TYPE) {
|
||||
msg_try_send(&err_report, sched_active_pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
last_status = err_report.content.value;
|
||||
}
|
||||
#endif
|
||||
return payload_len;
|
||||
|
Loading…
Reference in New Issue
Block a user