diff --git a/modules/libcom/test/osiSockTest.c b/modules/libcom/test/osiSockTest.c index 6672cdbd3..39777fc10 100644 --- a/modules/libcom/test/osiSockTest.c +++ b/modules/libcom/test/osiSockTest.c @@ -77,15 +77,76 @@ void udpSockTest(void) } +static +int doBind(int expect, SOCKET S, unsigned* port) +{ + osiSockAddr addr; + int ret; + + memset(&addr, 0, sizeof(addr)); + addr.ia.sin_family = AF_INET; + addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.ia.sin_port = htons(*port); + + ret = bind(S, &addr.sa, sizeof(addr.ia)); + if(ret) { + testOk(expect==1, "bind() to %u error %d, %d", *port, ret, SOCKERRNO); + return 1; + } else { + osiSocklen_t slen = sizeof(addr); + ret = getsockname(S, &addr.sa, &slen); + if(ret) { + testFail("Unable to find sock name after binding"); + return 1; + } else { + *port = ntohs(addr.ia.sin_port); + testOk(expect==0, "bind() to port %u", *port); + return 0; + } + } +} + +void udpSockFanoutTest(void) +{ + SOCKET A, B, C; + unsigned port=0; /* choose random port */ + + A = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); + B = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); + C = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); + + if(A==INVALID_SOCKET || B==INVALID_SOCKET || C==INVALID_SOCKET) + testAbort("Insufficient sockets"); + + /* not A */ + epicsSocketEnableAddressUseForDatagramFanout(B); + epicsSocketEnableAddressUseForDatagramFanout(C); + + testDiag("First test if epicsSocketEnableAddressUseForDatagramFanout() is necessary"); + + doBind(0, A, &port); + doBind(1, B, &port); /* expect failure */ + + epicsSocketDestroy(A); + + testDiag("Now the real test"); + doBind(0, B, &port); + doBind(0, C, &port); + + epicsSocketDestroy(B); + epicsSocketDestroy(C); +} + MAIN(osiSockTest) { int status; - testPlan(14); + testPlan(18); status = osiSockAttach(); testOk(status, "osiSockAttach"); udpSockTest(); + udpSockFanoutTest(); osiSockRelease(); return testDone();