diff --git a/configure/RULES.ioc b/configure/RULES.ioc index da314a406..fa0482ec0 100644 --- a/configure/RULES.ioc +++ b/configure/RULES.ioc @@ -14,7 +14,7 @@ build$(DIVIDER)$(ARCH) build: buildInstall install$(DIVIDER)$(ARCH) install: buildInstall $(ARCH): buildInstall -ifeq ($(filter $(ARCH),$(BUILD_ARCHS)),$(ARCH)) +ifeq ($(filter $(ARCH),$(BUILD_ARCHS)),$(strip $(ARCH))) buildInstall$(DIVIDER)$(ARCH) buildInstall: $(TARGETS) clean$(DIVIDER)$(ARCH) clean: @@ -35,4 +35,3 @@ envPaths: $(wildcard $(TOP)/configure/RELEASE*) \ realclean: $(RM) cdCommands envPaths dllPath.bat relPaths.sh - diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index cdcd6f77e..ef1f99358 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -21,6 +21,17 @@ +

Server bind issue on Windows

+ +

When a National Instruments network variables CA server is already running on +a Windows system and an IOC or PCAS server is started, the IOC's attempt to +bind a TCP socket to the CA server port number fails, but Windows returns a +different error status value than the IOC is expecting in that circumstance +(because the National Instruments code requests exclusive use of that port, +unlike the EPICS code) so the IOC fails to start properly. The relevent EPICS +bind() checks have now been updated so the IOC will request that a dynamic port +number be allocated for this TCP socket instead when this happens.

+

Checking Periodic Scan Rates

Code has been added to the IOC startup to better protect it against bad @@ -1533,7 +1544,7 @@ The iocLogServer was moved into the same directory (src/libCom/log) as the log client code.

3 -The Access Security code has been divided, with the parts not related to the +The Access Security code has been divided, with the parts not related to the database (lexer/parser and trap registration) becoming part of libCom. The remaining components are included in the dbCore library

diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc b/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc index 41ce6de8d..2c2cb5bef 100644 --- a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc +++ b/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ // @@ -32,7 +32,7 @@ const unsigned caServerConnectPendQueueSize = 5u; // // casIntfIO::casIntfIO() // -casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : +casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : sock ( INVALID_SOCKET ), addr ( addrIn.getSockIP() ) { @@ -40,80 +40,79 @@ casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : osiSocklen_t addrSize; bool portChange; - if ( ! osiSockAttach () ) { - throw S_cas_internal; - } + if ( ! osiSockAttach () ) { + throw S_cas_internal; + } - /* - * Setup the server socket - */ - this->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if (this->sock==INVALID_SOCKET) { + /* + * Setup the server socket + */ + this->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); + if (this->sock == INVALID_SOCKET) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - printf ( "No socket error was %s\n", sockErrBuf ); - throw S_cas_noFD; - } + printf ( "No socket error was %s\n", sockErrBuf ); + throw S_cas_noFD; + } epicsSocketEnableAddressReuseDuringTimeWaitState ( this->sock ); - status = bind ( this->sock, - reinterpret_cast (&this->addr), - sizeof(this->addr) ); - if (status<0) { - if (SOCKERRNO == SOCK_EADDRINUSE) { - // - // enable assignment of a default port - // (so the getsockname() call below will - // work correctly) - // - this->addr.sin_port = ntohs (0); - status = bind( + status = bind ( this->sock, + reinterpret_cast (&this->addr), + sizeof(this->addr) ); + if (status < 0) { + if (SOCKERRNO == SOCK_EADDRINUSE || + SOCKERRNO == SOCK_EACCES) { + // + // enable assignment of a default port + // (so the getsockname() call below will + // work correctly) + // + this->addr.sin_port = ntohs (0); + status = bind( this->sock, reinterpret_cast (&this->addr), sizeof(this->addr) ); - } - if (status<0) { + } + if (status < 0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - ipAddrToA (&this->addr, buf, sizeof(buf)); - errPrintf ( S_cas_bindFail, - __FILE__, __LINE__, - "- bind TCP IP addr=%s failed because %s", - buf, sockErrBuf ); + char buf[64]; + ipAddrToA (&this->addr, buf, sizeof(buf)); + errlogPrintf ( "CAS: Socket bind TCP to %s failed with %s", + buf, sockErrBuf ); epicsSocketDestroy (this->sock); - throw S_cas_bindFail; - } + throw S_cas_bindFail; + } portChange = true; - } + } else { portChange = false; } - addrSize = ( osiSocklen_t ) sizeof (this->addr); - status = getsockname ( - this->sock, - reinterpret_cast ( &this->addr ), + addrSize = ( osiSocklen_t ) sizeof (this->addr); + status = getsockname ( + this->sock, + reinterpret_cast ( &this->addr ), &addrSize ); - if (status) { + if (status) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: getsockname() error %s\n", - sockErrBuf ); + errlogPrintf ( "CAS: getsockname() error %s\n", + sockErrBuf ); epicsSocketDestroy (this->sock); - throw S_cas_internal; - } + throw S_cas_internal; + } - // - // be sure of this now so that we can fetch the IP - // address and port number later - // + // + // be sure of this now so that we can fetch the IP + // address and port number later + // assert (this->addr.sin_family == AF_INET); if ( portChange ) { errlogPrintf ( "cas warning: Configured TCP port was unavailable.\n"); - errlogPrintf ( "cas warning: Using dynamically assigned TCP port %hu,\n", + errlogPrintf ( "cas warning: Using dynamically assigned TCP port %hu,\n", ntohs (this->addr.sin_port) ); errlogPrintf ( "cas warning: but now two or more servers share the same UDP port.\n"); errlogPrintf ( "cas warning: Depending on your IP kernel this server may not be\n" ); @@ -121,12 +120,12 @@ casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : } status = listen(this->sock, caServerConnectPendQueueSize); - if(status < 0) { + if (status < 0) { char sockErrBuf[64]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: listen() error %s\n", sockErrBuf ); + errlogPrintf ( "CAS: listen() error %s\n", sockErrBuf ); epicsSocketDestroy (this->sock); - throw S_cas_internal; + throw S_cas_internal; } } @@ -135,17 +134,17 @@ casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : // casIntfIO::~casIntfIO() { - if (this->sock != INVALID_SOCKET) { - epicsSocketDestroy (this->sock); - } + if (this->sock != INVALID_SOCKET) { + epicsSocketDestroy (this->sock); + } - osiSockRelease (); + osiSockRelease (); } // // newStreamIO::newStreamClient() // -casStreamOS *casIntfIO::newStreamClient ( caServerI & cas, +casStreamOS *casIntfIO::newStreamClient ( caServerI & cas, clientBufMemoryManager & bufMgr ) const { static bool oneMsgFlag = false; @@ -175,14 +174,14 @@ casStreamOS *casIntfIO::newStreamClient ( caServerI & cas, args.sock = newSock; casStreamOS * pOS = new casStreamOS ( cas, bufMgr, args ); if ( ! pOS ) { - errMessage ( S_cas_noMemory, + errMessage ( S_cas_noMemory, "unable to create data structures for a new client" ); epicsSocketDestroy ( newSock ); } else { if ( cas.getDebugLevel() > 0u ) { char pName[64u]; - + pOS->hostName ( pName, sizeof ( pName ) ); errlogPrintf ( "CAS: allocated client object for \"%s\"\n", pName ); } @@ -197,7 +196,7 @@ void casIntfIO::setNonBlocking() { int status; osiSockIoctl_t yes = true; - + status = socket_ioctl(this->sock, FIONBIO, &yes); if ( status < 0 ) { char sockErrBuf[64]; diff --git a/src/ioc/rsrv/caservertask.c b/src/ioc/rsrv/caservertask.c index a8c590452..a18abafe2 100644 --- a/src/ioc/rsrv/caservertask.c +++ b/src/ioc/rsrv/caservertask.c @@ -232,16 +232,17 @@ SOCKET* rsrv_grab_tcp(unsigned short *port) ok = 0; break; } - /* if SOCK_EADDRINUSE then try again with a different port number. - * otherwise, fail hard + /* if SOCK_EADDRINUSE or SOCK_EACCES try again with a different + * port number, otherwise fail hard. */ - if(errcode!=SOCK_EADDRINUSE) { + if (errcode != SOCK_EADDRINUSE && + errcode != SOCK_EACCES) { char name[40]; char sockErrBuf[64]; 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 was %s\n", name, sockErrBuf ); } ok = 0; @@ -852,7 +853,7 @@ static void log_one_client (struct client *client, unsigned level) printf( "\tUnprocessed request bytes = %u, Undelivered response bytes = %u\n", client->recv.cnt - client->recv.stk, - client->send.stk ); + client->send.stk ); printf( "\tState = %s%s%s\n", state[client->disconnect?1:0], diff --git a/src/libCom/osi/os/Darwin/osdSock.h b/src/libCom/osi/os/Darwin/osdSock.h index e9426a79f..1d4556eee 100644 --- a/src/libCom/osi/os/Darwin/osdSock.h +++ b/src/libCom/osi/os/Darwin/osdSock.h @@ -1,7 +1,7 @@ /*************************************************************************\ * Copyright (c) 2002 The University of Saskatchewan * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* * Author: Eric Norum @@ -38,6 +38,7 @@ typedef socklen_t osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED diff --git a/src/libCom/osi/os/Linux/osdSock.h b/src/libCom/osi/os/Linux/osdSock.h index b32a16044..614f3f98d 100644 --- a/src/libCom/osi/os/Linux/osdSock.h +++ b/src/libCom/osi/os/Linux/osdSock.h @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* @@ -42,6 +42,7 @@ typedef socklen_t osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED @@ -72,4 +73,3 @@ typedef socklen_t osiSocklen_t; #define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) #endif /*osdSockH*/ - diff --git a/src/libCom/osi/os/RTEMS/osdSock.h b/src/libCom/osi/os/RTEMS/osdSock.h index dce24645f..930ed0e72 100644 --- a/src/libCom/osi/os/RTEMS/osdSock.h +++ b/src/libCom/osi/os/RTEMS/osdSock.h @@ -1,7 +1,7 @@ /*************************************************************************\ * Copyright (c) 2002 The University of Saskatchewan * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* * RTEMS osdSock.h @@ -35,7 +35,7 @@ int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, str #ifdef __cplusplus } #endif - + typedef int SOCKET; #define INVALID_SOCKET (-1) #define SOCKERRNO errno @@ -49,6 +49,7 @@ typedef socklen_t osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED @@ -75,7 +76,7 @@ typedef socklen_t osiSocklen_t; #ifndef INADDR_NONE # define INADDR_NONE (0xffffffff) -#endif +#endif /* * For shutdown() diff --git a/src/libCom/osi/os/WIN32/osdSock.h b/src/libCom/osi/os/WIN32/osdSock.h index e685f6564..d92e18755 100644 --- a/src/libCom/osi/os/WIN32/osdSock.h +++ b/src/libCom/osi/os/WIN32/osdSock.h @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ #ifndef osdSockH @@ -14,7 +14,7 @@ #include /* - * winsock2.h changes the structure alignment to 4 if + * winsock2.h changes the structure alignment to 4 if * WIN32 isnt set which can be a source of confusion */ #ifndef WIN32 @@ -48,6 +48,7 @@ typedef int osiSocklen_t; #define SOCK_ENOBUFS WSAENOBUFS #define SOCK_ECONNRESET WSAECONNRESET #define SOCK_ETIMEDOUT WSAETIMEDOUT +#define SOCK_EACCES WSAEACCES #define SOCK_EADDRINUSE WSAEADDRINUSE #define SOCK_EADDRNOTAVAIL WSAEADDRNOTAVAIL #define SOCK_ECONNREFUSED WSAECONNREFUSED diff --git a/src/libCom/osi/os/cygwin32/osdSock.h b/src/libCom/osi/os/cygwin32/osdSock.h index 324e75c3f..d642cad44 100644 --- a/src/libCom/osi/os/cygwin32/osdSock.h +++ b/src/libCom/osi/os/cygwin32/osdSock.h @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* * cygwin32 specific include @@ -49,6 +49,7 @@ typedef int osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED @@ -67,4 +68,3 @@ typedef int osiSocklen_t; #define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) #endif /*osdSockH*/ - diff --git a/src/libCom/osi/os/freebsd/osdSock.h b/src/libCom/osi/os/freebsd/osdSock.h index a950b996c..fe28d4cd5 100644 --- a/src/libCom/osi/os/freebsd/osdSock.h +++ b/src/libCom/osi/os/freebsd/osdSock.h @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ #ifndef osdSockH @@ -29,7 +29,7 @@ #define IPPORT_USERRESERVED 5000 #endif - + typedef int SOCKET; #define INVALID_SOCKET (-1) #define SOCKERRNO errno @@ -43,6 +43,7 @@ typedef socklen_t osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED @@ -77,4 +78,3 @@ typedef socklen_t osiSocklen_t; #endif #endif /*osdSockH*/ - diff --git a/src/libCom/osi/os/iOS/osdSock.h b/src/libCom/osi/os/iOS/osdSock.h index f3a15c88d..0b3b3f6c1 100644 --- a/src/libCom/osi/os/iOS/osdSock.h +++ b/src/libCom/osi/os/iOS/osdSock.h @@ -39,6 +39,7 @@ typedef socklen_t osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED diff --git a/src/libCom/osi/os/solaris/osdSock.h b/src/libCom/osi/os/solaris/osdSock.h index 1ea493680..a39c6c3d3 100644 --- a/src/libCom/osi/os/solaris/osdSock.h +++ b/src/libCom/osi/os/solaris/osdSock.h @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* @@ -39,7 +39,7 @@ typedef int osiSockIoctl_t; #if SOLARIS > 6 || defined ( _SOCKLEN_T ) typedef uint32_t osiSocklen_t; -#else +#else typedef int osiSocklen_t; #endif @@ -51,6 +51,7 @@ typedef int osiSockIoctl_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED @@ -80,9 +81,8 @@ typedef int osiSockIoctl_t; #ifndef INADDR_NONE # define INADDR_NONE (0xffffffff) -#endif +#endif #define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) #endif /*osdSockH*/ - diff --git a/src/libCom/osi/os/vxWorks/osdSock.h b/src/libCom/osi/os/vxWorks/osdSock.h index f0260c5a8..80464ef87 100644 --- a/src/libCom/osi/os/vxWorks/osdSock.h +++ b/src/libCom/osi/os/vxWorks/osdSock.h @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* * vxWorks specific socket include @@ -44,7 +44,7 @@ int sysClkRateGet(void); #ifdef __cplusplus } #endif - + typedef int SOCKET; #define INVALID_SOCKET (-1) #define SOCKERRNO errno @@ -72,6 +72,7 @@ typedef int osiSocklen_t; #define SOCK_ENOBUFS ENOBUFS #define SOCK_ECONNRESET ECONNRESET #define SOCK_ETIMEDOUT ETIMEDOUT +#define SOCK_EACCES EACCES #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL #define SOCK_ECONNREFUSED ECONNREFUSED @@ -93,7 +94,7 @@ typedef int osiSocklen_t; #ifndef INADDR_NONE # define INADDR_NONE (0xffffffff) -#endif +#endif #if defined(_SIZEOF_ADDR_IFREQ) # define ifreq_size(pifreq) _SIZEOF_ADDR_IFREQ(*pifreq) @@ -104,5 +105,3 @@ typedef int osiSocklen_t; #endif #endif /*osdSockH*/ - -