diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 111c604d3..3a3f0d3be 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -584,6 +584,11 @@ of its CALLBACK objects.

+

Add osiSockOptMcastLoop_t and osiSockTest

+ +

Added a new OS-independent typedef for multicast socket options, and a test +file to check their correct operation.

+

Support for CONFIG_SITE.local in Base

This feature is mostly meant for use by developers; configuration diff --git a/src/ca/client/udpiiu.cpp b/src/ca/client/udpiiu.cpp index 33741aad0..73d4ee4cb 100644 --- a/src/ca/client/udpiiu.cpp +++ b/src/ca/client/udpiiu.cpp @@ -180,7 +180,7 @@ udpiiu::udpiiu ( #ifdef IP_ADD_MEMBERSHIP { - int flag = 1; + osiSockOptMcastLoop_t flag = 1; if ( setsockopt ( this->sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof ( flag ) ) == -1 ) { char sockErrBuf[64]; diff --git a/src/ioc/rsrv/camsgtask.c b/src/ioc/rsrv/camsgtask.c index e2a0d3e18..04a7e780e 100644 --- a/src/ioc/rsrv/camsgtask.c +++ b/src/ioc/rsrv/camsgtask.c @@ -59,7 +59,7 @@ void camsgtask ( void *pParm ) epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("CAS: ioctl error - %s\n", + errlogPrintf("CAS: FIONREAD error: %s\n", sockErrBuf); cas_send_bs_msg(client, TRUE); } diff --git a/src/ioc/rsrv/caserverio.c b/src/ioc/rsrv/caserverio.c index 7250ae6db..20a1c1c5b 100644 --- a/src/ioc/rsrv/caserverio.c +++ b/src/ioc/rsrv/caserverio.c @@ -114,7 +114,7 @@ void cas_send_bs_msg ( struct client *pclient, int lock_needed ) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: TCP send to %s failed - %s\n", + errlogPrintf ( "CAS: TCP send to %s failed: %s\n", buf, sockErrBuf); } pclient->disconnect = TRUE; @@ -140,7 +140,7 @@ void cas_send_bs_msg ( struct client *pclient, int lock_needed ) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAS: Socket shutdown error - %s\n", + errlogPrintf ("CAS: Socket shutdown error: %s\n", sockErrBuf ); } } @@ -218,7 +218,7 @@ void cas_send_dg_msg ( struct client * pclient ) epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); ipAddrToDottedIP ( &pclient->addr, buf, sizeof(buf) ); - errlogPrintf( "CAS: UDP send to %s failed - %s\n", + errlogPrintf( "CAS: UDP send to %s failed: %s\n", buf, sockErrBuf); } diff --git a/src/ioc/rsrv/caservertask.c b/src/ioc/rsrv/caservertask.c index 9a032d25e..3a493e7f1 100644 --- a/src/ioc/rsrv/caservertask.c +++ b/src/ioc/rsrv/caservertask.c @@ -73,7 +73,7 @@ static void req_server (void *pParm) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: Listen error %s\n", + errlogPrintf ( "CAS: Listen error: %s\n", sockErrBuf ); epicsSocketDestroy (IOC_sock); epicsThreadSuspendSelf (); @@ -95,7 +95,7 @@ static void req_server (void *pParm) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("CAS: Client accept error was \"%s\"\n", + errlogPrintf("CAS: Client accept error: %s\n", sockErrBuf ); epicsThreadSleep(15.0); continue; @@ -140,7 +140,7 @@ int tryBind(SOCKET sock, const osiSockAddr* addr, const char *name) { epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: %s bind error: \"%s\"\n", + errlogPrintf ( "CAS: %s bind error: %s\n", name, sockErrBuf ); epicsThreadSuspendSelf (); } @@ -205,7 +205,7 @@ SOCKET* rsrv_grab_tcp(unsigned short *port) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: getsockname error was \"%s\"\n", + errlogPrintf ( "CAS: getsockname error: %s\n", sockErrBuf ); epicsThreadSuspendSelf (); ok = 0; @@ -244,7 +244,7 @@ SOCKET* rsrv_grab_tcp(unsigned short *port) epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); ipAddrToDottedIP(&scratch.ia, name, sizeof(name)); - cantProceed( "CAS: Socket bind %s error was %s\n", + cantProceed( "CAS: Socket bind %s error: %s\n", name, sockErrBuf ); } ok = 0; @@ -310,13 +310,14 @@ void rsrv_build_addr_lists(void) } #ifdef IP_ADD_MEMBERSHIP { - int flag = 1; + osiSockOptMcastLoop_t flag = 1; if (setsockopt(beaconSocket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&flag, sizeof(flag))<0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("rsrv: failed to set mcast loopback\n"); + errlogPrintf("CAS: failed to set mcast loopback: %s\n", + sockErrBuf); } } #endif @@ -665,7 +666,7 @@ int rsrv_init (void) epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); ipAddrToDottedIP (&temp, name, sizeof(name)); - fprintf(stderr, "CAS: Socket mcast join %s to %s failed with \"%s\"\n", + errlogPrintf("CAS: Socket mcast join %s to %s failed: %s\n", ifaceName, name, sockErrBuf ); } } diff --git a/src/ioc/rsrv/cast_server.c b/src/ioc/rsrv/cast_server.c index be5ec15c6..4039d0f6f 100644 --- a/src/ioc/rsrv/cast_server.c +++ b/src/ioc/rsrv/cast_server.c @@ -176,7 +176,7 @@ void cast_server(void *pParm) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - epicsPrintf ("CAS: UDP recv error (errno=%s)\n", + epicsPrintf ("CAS: UDP recv error: %s\n", sockErrBuf); epicsThreadSleep(1.0); } diff --git a/src/ioc/rsrv/online_notify.c b/src/ioc/rsrv/online_notify.c index d1d557943..b2547c464 100644 --- a/src/ioc/rsrv/online_notify.c +++ b/src/ioc/rsrv/online_notify.c @@ -87,8 +87,8 @@ void rsrv_online_notify_task(void *pParm) char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); ipAddrToDottedIP (&pAddr->addr.ia, buf, sizeof(buf)); - errlogPrintf ( "%s: CA beacon (send to \"%s\") error was \"%s\"\n", - __FILE__, buf, sockErrBuf); + errlogPrintf ( "CAS: CA beacon send to %s error: %s\n", + buf, sockErrBuf); } else { assert (status == sizeof(msg)); diff --git a/src/libCom/osi/os/Darwin/osdSock.h b/src/libCom/osi/os/Darwin/osdSock.h index 1d4556eee..e7c344062 100644 --- a/src/libCom/osi/os/Darwin/osdSock.h +++ b/src/libCom/osi/os/Darwin/osdSock.h @@ -31,6 +31,7 @@ typedef int SOCKET; #define socket_ioctl(A,B,C) ioctl(A,B,C) typedef int osiSockIoctl_t; typedef socklen_t osiSocklen_t; +typedef int osiSockOptMcastLoop_t; #define FD_IN_FDSET(FD) ((FD)=0) #ifndef SHUT_RD #define SHUT_RD 0 diff --git a/src/libCom/osi/os/freebsd/osdSock.h b/src/libCom/osi/os/freebsd/osdSock.h index fe28d4cd5..b402ec120 100644 --- a/src/libCom/osi/os/freebsd/osdSock.h +++ b/src/libCom/osi/os/freebsd/osdSock.h @@ -36,6 +36,7 @@ typedef int SOCKET; #define socket_ioctl(A,B,C) ioctl(A,B,C) typedef int osiSockIoctl_t; typedef socklen_t osiSocklen_t; +typedef int osiSockOptMcastLoop_t; #define FD_IN_FDSET(FD) ((FD)=0) diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile index 04438854c..a7d85c11e 100755 --- a/src/libCom/test/Makefile +++ b/src/libCom/test/Makefile @@ -12,6 +12,7 @@ include $(TOP)/configure/CONFIG PROD_LIBS += Com PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32 +PROD_SYS_LIBS_solaris += socket nsl TESTPROD_HOST += epicsUnitTestTest epicsUnitTestTest_SRCS += epicsUnitTestTest.c @@ -48,8 +49,6 @@ TESTS += epicsMathTest TESTPROD_HOST += epicsMMIOTest epicsMMIOTest_SRCS += epicsMMIOTest.c -epicsMMIOTest_SYS_LIBS_solaris = socket -epicsMMIOTest_SYS_LIBS_WIN32 = ws2_32 user32 testHarness_SRCS += epicsMMIOTest.c TESTS += epicsMMIOTest @@ -65,8 +64,6 @@ TESTS += epicsEnvTest TESTPROD_HOST += epicsErrlogTest epicsErrlogTest_SRCS += epicsErrlogTest.c -epicsErrlogTest_SYS_LIBS_solaris = socket -epicsErrlogTest_SYS_LIBS_WIN32 = ws2_32 user32 testHarness_SRCS += epicsErrlogTest.c TESTS += epicsErrlogTest @@ -82,8 +79,6 @@ TESTS += epicsStdlibTest TESTPROD_HOST += epicsSockResolveTest epicsSockResolveTest_SRCS += epicsSockResolveTest.c -epicsSockResolveTest_SYS_LIBS_solaris = socket -epicsSockResolveTest_SYS_LIBS_WIN32 = ws2_32 user32 testHarness_SRCS += epicsSockResolveTest.c TESTS += epicsSockResolveTest @@ -195,9 +190,6 @@ TESTS += taskwdTest TESTPROD_HOST += blockingSockTest blockingSockTest_SRCS += blockingSockTest.cpp testHarness_SRCS += blockingSockTest.cpp -# needed when its an object library build -blockingSockTest_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 -blockingSockTest_SYS_LIBS_solaris = socket TESTS += blockingSockTest TESTPROD_HOST += epicsMessageQueueTest @@ -215,6 +207,11 @@ ipAddrToAsciiTest_SRCS += ipAddrToAsciiTest.cpp testHarness_SRCS += ipAddrToAsciiTest.cpp TESTS += ipAddrToAsciiTest +TESTPROD_HOST += osiSockTest +osiSockTest_SRCS += osiSockTest.c +testHarness_SRCS += osiSockTest.c +TESTS += osiSockTest + # The testHarness runs all the test programs in a known working order. testHarness_SRCS += epicsRunLibComTests.c @@ -259,4 +256,3 @@ cvtFastPerform_SRCS += cvtFastPerform.cpp testHarness_SRCS += cvtFastPerform.cpp include $(TOP)/configure/RULES - diff --git a/src/libCom/test/epicsRunLibComTests.c b/src/libCom/test/epicsRunLibComTests.c index c4a76e777..29c5eda3f 100644 --- a/src/libCom/test/epicsRunLibComTests.c +++ b/src/libCom/test/epicsRunLibComTests.c @@ -51,6 +51,7 @@ int epicsInlineTest(void); int ipAddrToAsciiTest(void); int macDefExpandTest(void); int macLibTest(void); +int osiSockTest(void); int ringBytesTest(void); int ringPointerTest(void); int taskwdTest(void); @@ -104,6 +105,7 @@ void epicsRunLibComTests(void) runTest(ipAddrToAsciiTest); runTest(macDefExpandTest); runTest(macLibTest); + runTest(osiSockTest); runTest(ringBytesTest); runTest(ringPointerTest); runTest(taskwdTest); diff --git a/src/libCom/test/osiSockTest.c b/src/libCom/test/osiSockTest.c new file mode 100644 index 000000000..39eb0ba2b --- /dev/null +++ b/src/libCom/test/osiSockTest.c @@ -0,0 +1,74 @@ +/*************************************************************************\ +* Copyright (c) 2017 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include +#include + +#include "osiSock.h" +#include "epicsUnitTest.h" +#include "testMain.h" + +/* This could easily be generalized to test more options */ +void udpBroadcast(SOCKET s, int put) +{ + int status; + int flag = put; + osiSocklen_t len = sizeof(flag); + + status = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&flag, len); + testOk(status >= 0, "setsockopt BROADCAST := %d", put); + + status = getsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&flag, &len); + testOk(status >= 0 && len == sizeof(flag) && !flag == !put, + "getsockopt BROADCAST => %d", flag); +} + +void multiCastLoop(SOCKET s, int put) +{ + int status; + osiSockOptMcastLoop_t flag = put; + osiSocklen_t len = sizeof(flag); + + status = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, + (char *)&flag, len); + testOk(status >= 0, "setsockopt MULTICAST_LOOP := %d", put); + + status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&flag, &len); + testOk(status >= 0 && len == sizeof(flag) && !flag == !put, + "getsockopt MULTICAST_LOOP => %d", (int) flag); +} + +void udpSockTest(void) +{ + SOCKET s; + + s = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); + testOk(s != INVALID_SOCKET, "epicsSocketCreate INET, DGRAM, 0"); + + udpBroadcast(s, 1); + udpBroadcast(s, 0); + + multiCastLoop(s, 1); + multiCastLoop(s, 0); + + epicsSocketDestroy(s); +} + + +MAIN(osiSockTest) +{ + int status; + testPlan(10); + + status = osiSockAttach(); + testOk(status, "osiSockAttach"); + + udpSockTest(); + + osiSockRelease(); + return testDone(); +}