Implemented better testing and fixed skipepd frames
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "MemoryOperationsHelper.h"
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace MARTe {
|
||||
@@ -26,6 +27,7 @@ UDPSClient::UDPSClient()
|
||||
maxPayloadSize(UDPS_CLIENT_DEFAULT_MAX_PAYLOAD),
|
||||
cpuMask(0xFFFFFFFFu),
|
||||
stackSize(65536u),
|
||||
recvBufferSize(UDPS_CLIENT_DEFAULT_RECV_BUFFER),
|
||||
listener(NULL_PTR(UDPSClientListener *)),
|
||||
threadService(*this),
|
||||
connected(false),
|
||||
@@ -98,6 +100,9 @@ bool UDPSClient::Initialise(StructuredDataI &data) {
|
||||
(void) data.Read("CPUMask", cpuMask);
|
||||
(void) data.Read("StackSize", stackSize);
|
||||
|
||||
recvBufferSize = UDPS_CLIENT_DEFAULT_RECV_BUFFER;
|
||||
(void) data.Read("RecvBufferSize", recvBufferSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -209,6 +214,23 @@ bool UDPSClient::Connect() {
|
||||
return ok;
|
||||
}
|
||||
|
||||
void UDPSClient::SetRecvBufferSize(BasicUDPSocket &sock) {
|
||||
/* BasicUDPSocket exposes no SO_RCVBUF API; the OS default (Linux
|
||||
* rmem_default, typically ~208 KiB) is easily overrun by high-throughput
|
||||
* sources, causing silent kernel-level datagram drops. Work around this
|
||||
* by calling setsockopt() directly on the raw handle. Best-effort: a
|
||||
* failure here just leaves the OS default in place. */
|
||||
Handle fd = sock.GetReadHandle();
|
||||
if (fd >= 0) {
|
||||
int32 sz = static_cast<int32>(recvBufferSize);
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)) != 0) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
"UDPSClient: Could not set SO_RCVBUF to %u bytes.",
|
||||
recvBufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool UDPSClient::ConnectUnicast() {
|
||||
// Open a local UDP socket bound to an ephemeral port
|
||||
if (!recvSocket.Open()) {
|
||||
@@ -216,6 +238,7 @@ bool UDPSClient::ConnectUnicast() {
|
||||
"UDPSClient: Could not open receive socket.");
|
||||
return false;
|
||||
}
|
||||
SetRecvBufferSize(recvSocket);
|
||||
|
||||
if (!recvSocket.Listen(0u)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
@@ -256,6 +279,7 @@ bool UDPSClient::ConnectMulticast() {
|
||||
"UDPSClient: Could not open multicast socket.");
|
||||
return false;
|
||||
}
|
||||
SetRecvBufferSize(mcastSocket);
|
||||
|
||||
bool ok = mcastSocket.Listen(dataPort);
|
||||
if (!ok) {
|
||||
@@ -378,6 +402,15 @@ bool UDPSClient::ReceiveAndProcess() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* HI-6: guard against FD_SETSIZE overflow */
|
||||
if (fd < 0 || fd >= FD_SETSIZE ||
|
||||
(tcpFd >= 0 && tcpFd >= FD_SETSIZE)) {
|
||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||
"UDPSClient: fd >= FD_SETSIZE (%d/%d) — skipping select.",
|
||||
fd, tcpFd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fd_set rset;
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(fd, &rset);
|
||||
|
||||
Reference in New Issue
Block a user