add sendtox

wrapper sendmsg() and WSASendMsg()

Linux and Windows support IPv4 IP_PKTINFO.
BSD, Linux, and Windows support IPV6_PKTINFO

So far RTEMS and OSX, the extra sendto() overrides
will be ignored.
This commit is contained in:
Michael Davidsaver
2025-02-05 17:58:00 -08:00
parent a2b424cba2
commit 80c63888ed
4 changed files with 186 additions and 19 deletions
+52 -16
View File
@@ -220,6 +220,7 @@ void test_udp(int af)
}
A.enable_IP_PKTINFO();
B.enable_IP_PKTINFO();
try{
A.bind(bind_addr);
}catch(std::system_error& e){
@@ -237,24 +238,59 @@ void test_udp(int af)
testNotEq(send_addr.port(), 0);
testNotEq(send_addr.port(), bind_addr.port());
uint8_t msg[] = {0x12, 0x34, 0x56, 0x78};
int ret = sendto(B.sock, (char*)msg, sizeof(msg), 0, &bind_addr->sa, bind_addr.size());
testOk(ret==(int)sizeof(msg), "Send test ret==%d(%d)", ret, EVUTIL_SOCKET_ERROR());
{
uint8_t msg[] = {0x12, 0x34, 0x56, 0x78};
int ret = sendtox{B.sock, (char*)msg, sizeof(msg), &bind_addr}.call();
testOk(ret==(int)sizeof(msg), "Send test ret==%d(%d)", ret, EVUTIL_SOCKET_ERROR());
}
uint8_t rxbuf[8] = {};
SockAddr src;
SockAddr dest;
SockAddr reply_to, reply_from;
uint64_t reply_from_iface = 0;
{
testDiag("Call recvfrom()");
testDiag("Call recvfrom()");
ret = recvfromx{A.sock, (char*)rxbuf, sizeof(rxbuf), &src, &dest}.call();
// only the destination address is captured, not the port
if(dest.family()!=AF_UNSPEC)
dest.setPort(bind_addr.port());
uint8_t rxbuf[8] = {};
SockAddr src, dest;
auto rx(recvfromx{A.sock, (char*)rxbuf, sizeof(rxbuf), &src, &dest});
int ret = rx.call();
// only the destination address is captured, not the port
if(dest.family()!=AF_UNSPEC)
dest.setPort(bind_addr.port());
testOk(ret==4 && rxbuf[0]==0x12 && rxbuf[1]==0x34 && rxbuf[2]==0x56 && rxbuf[3]==0x78,
"Recv'd %d(%d) [%u, %u, %u, %u]", ret, EVUTIL_SOCKET_ERROR(), rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3]);
testEq(src, send_addr);
testEq(dest, bind_addr);
testOk(ret==4 && rxbuf[0]==0x12 && rxbuf[1]==0x34 && rxbuf[2]==0x56 && rxbuf[3]==0x78,
"Recv'd %d(%d) [%u, %u, %u, %u]", ret, EVUTIL_SOCKET_ERROR(), rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3]);
testEq(src, send_addr);
testEq(dest, bind_addr);
reply_to = src;
reply_from = dest;
reply_from_iface = rx.dstif;
}
{
testDiag("Call sendto() with source addr override");
uint8_t msg[] = {0x9a, 0xbc, 0xde, 0xf0};
// reply to "src" from "dest"
int ret = sendtox{A.sock, (char*)msg, sizeof(msg), &reply_to, &reply_from, reply_from_iface}.call();
testOk(ret==(int)sizeof(msg), "Send test ret==%d(%d)", ret, EVUTIL_SOCKET_ERROR());
}
{
testDiag("Call recvfrom()");
uint8_t rxbuf[8] = {};
SockAddr src, dest;
auto rx(recvfromx{B.sock, (char*)rxbuf, sizeof(rxbuf), &src, &dest});
int ret = rx.call();
// only the destination address is captured, not the port
if(dest.family()!=AF_UNSPEC)
dest.setPort(send_addr.port());
testOk(ret==4 && rxbuf[0]==0x9a && rxbuf[1]==0xbc && rxbuf[2]==0xde && rxbuf[3]==0xf0,
"Recv'd %d(%d) [%u, %u, %u, %u]", ret, EVUTIL_SOCKET_ERROR(), rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3]);
testEq(src, reply_from);
testEq(dest, reply_to);
}
}
void test_local_mcast()
@@ -510,7 +546,7 @@ MAIN(testsock)
{
SockAttach attach;
logger_config_env();
testPlan(93);
testPlan(101);
testSetup();
testStackID();
testEndPoint();