Subject: |
[Merge] lp:~anj/epics-base/cas-intf-addr-list into lp:epics-base |
From: |
Andrew Johnson <[email protected]> |
To: |
[email protected] |
Date: |
Thu, 06 Mar 2014 22:29:44 -0000 |
Andrew Johnson has proposed merging lp:~anj/epics-base/cas-intf-addr-list into lp:epics-base.
Requested reviews:
EPICS Core Developers (epics-core)
For more details, see:
https://code.launchpad.net/~anj/epics-base/cas-intf-addr-list/+merge/209803
Partially support EPICS_CAS_INTF_ADDR_LIST in rsrv.
This branch parses the environment parameter into a new global ELLIST.
If the resulting list is empty it adds a single entry of INADDR_ANY.
A warning message is printed if the list contains multiple entries.
The TCP and UDP servers then bind to the first entry in the list.
This approach can be extended to handle multiple entries in the future.
Did I miss anything?
--
https://code.launchpad.net/~anj/epics-base/cas-intf-addr-list/+merge/209803
Your team EPICS Core Developers is requested to review the proposed merge of lp:~anj/epics-base/cas-intf-addr-list into lp:epics-base.
=== modified file 'documentation/RELEASE_NOTES.html'
--- documentation/RELEASE_NOTES.html 2014-02-21 21:49:15 +0000
+++ documentation/RELEASE_NOTES.html 2014-03-06 22:28:58 +0000
@@ -15,6 +15,13 @@
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
<!-- Insert new items immediately below here ... -->
+<h3>Implement EPICS_CAS_INTF_ADDR_LIST in rsrv</h3>
+
+<p>The IOC server can now bind to a single IP address (and optional port number)
+read from the standard environment parameter EPICS_CAS_INTF_ADDR_LIST.
+Additional addresses included in that parameter after the first will be ignored
+and a warning message displayed at iocInit time.</p>
+
<h3>Added echo command to iocsh</h3>
<p>The single argument string may contain escaped characters, which will be
=== modified file 'src/ca/client/CAref.html'
--- src/ca/client/CAref.html 2013-11-07 23:57:09 +0000
+++ src/ca/client/CAref.html 2014-03-06 22:28:58 +0000
@@ -796,7 +796,7 @@
</tr>
<tr>
<td>EPICS_CAS_BEACON_ADDR_LIST</td>
- <td>{N.N.N.NN.N.N.N:P...}</td>
+ <td>{N.N.N.N N.N.N.N:P ...}</td>
<td>EPICS_CA_ADDR_LIST<sup>1</sup></td>
</tr>
<tr>
@@ -811,12 +811,12 @@
</tr>
<tr>
<td>EPICS_CAS_INTF_ADDR_LIST</td>
- <td>{N.N.N.NN.N.N.N:P...}</td>
+ <td>{N.N.N.N N.N.N.N:P ...}</td>
<td><none></td>
</tr>
<tr>
<td>EPICS_CAS_IGNORE_ADDR_LIST</td>
- <td>{N.N.N.NN.N.N.N:P...}</td>
+ <td>{N.N.N.N N.N.N.N:P ...}</td>
<td><none></td>
</tr>
</tbody>
@@ -874,8 +874,13 @@
addresses in EPICS_CAS_INTF_ADDR_LIST and also to the broadcast addresses of
the corresponding LAN interfaces will be accepted by the server. By default,
the CA server is accessible from all network interfaces configured into its
-host. <em>In R3.14 and previous releases the CA server employed by iocCore does
-not implement this feature</em>.</p>
+host.</p>
+
+<p>In R3.14 and previous releases the CA server employed by iocCore did not
+implement the EPICS_CAS_INTF_ADDR_LIST feature. In this release the iocCore
+server will read the first IP address from the parameter variable and use that
+to select which interface to bind to. Any additional IP addresses will be
+ignored and a warning message displayed during IOC initialization.</p>
<h4>Ignoring Process Variable Name Resolution Requests From Certain Hosts</h4>
=== modified file 'src/ioc/rsrv/caservertask.c'
--- src/ioc/rsrv/caservertask.c 2012-07-17 19:36:34 +0000
+++ src/ioc/rsrv/caservertask.c 2014-03-06 22:28:58 +0000
@@ -63,8 +63,9 @@
unsigned priorityOfSelf = epicsThreadGetPrioritySelf ();
unsigned priorityOfBeacons;
epicsThreadBooleanStatus tbs;
+ osiSockAddrNode *pNode;
struct sockaddr_in serverAddr; /* server's address */
- osiSocklen_t addrSize;
+ osiSocklen_t addrSize = (osiSocklen_t) sizeof(struct sockaddr_in);
int status;
SOCKET clientSock;
epicsThreadId tid;
@@ -85,6 +86,24 @@
(unsigned short) CA_SERVER_PORT );
}
+ addAddrToChannelAccessAddressList ( &casIntfAddrList,
+ &EPICS_CAS_INTF_ADDR_LIST, ca_server_port, 0 );
+ if (ellCount(&casIntfAddrList) == 0) {
+ pNode = (osiSockAddrNode *) calloc ( 1, sizeof(*pNode) );
+ pNode->addr.ia.sin_family = AF_INET;
+ pNode->addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
+ pNode->addr.ia.sin_port = htons ( ca_server_port );
+ ellAdd ( &casIntfAddrList, &pNode->node );
+ }
+ else {
+ if (ellCount ( &casIntfAddrList ) > 1)
+ epicsPrintf ("CAS: Multiple entries in EPICS_CAS_INTF_ADDR_LIST, "
+ "only the first will be used.\n");
+ pNode = (osiSockAddrNode *) ellFirst ( &casIntfAddrList );
+ }
+
+ memcpy ( &serverAddr, &pNode->addr.ia, addrSize );
+
if (IOC_sock != 0 && IOC_sock != INVALID_SOCKET) {
epicsSocketDestroy ( IOC_sock );
}
@@ -100,50 +119,43 @@
epicsSocketEnableAddressReuseDuringTimeWaitState ( IOC_sock );
- /* Zero the sock_addr structure */
- memset ( (void *) &serverAddr, 0, sizeof ( serverAddr ) );
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);
- serverAddr.sin_port = htons ( ca_server_port );
-
/* get server's Internet address */
- status = bind ( IOC_sock, (struct sockaddr *) &serverAddr, sizeof ( serverAddr ) );
- if ( status < 0 ) {
- if ( SOCKERRNO == SOCK_EADDRINUSE ) {
- /*
- * enable assignment of a default port
- * (so the getsockname() call below will
- * work correctly)
- */
- serverAddr.sin_port = ntohs (0);
- status = bind ( IOC_sock,
- (struct sockaddr *) &serverAddr, sizeof ( serverAddr ) );
- }
- if ( status < 0 ) {
+
+ status = bind(IOC_sock, (struct sockaddr *) &serverAddr, addrSize);
+ if ( status < 0 ) {
+ if ( SOCKERRNO == SOCK_EADDRINUSE ) {
+ /*
+ * enable assignment of a default port
+ * (so the getsockname() call below will
+ * work correctly)
+ */
+ serverAddr.sin_port = ntohs (0);
+ status = bind(IOC_sock, (struct sockaddr *) &serverAddr, addrSize);
+ }
+ if ( status < 0 ) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ( "CAS: Socket bind error was \"%s\"\n",
sockErrBuf );
epicsThreadSuspendSelf ();
- }
+ }
portChange = 1;
- }
+ }
else {
portChange = 0;
}
- addrSize = ( osiSocklen_t ) sizeof ( serverAddr );
- status = getsockname ( IOC_sock,
- (struct sockaddr *)&serverAddr, &addrSize);
- if ( status ) {
+ status = getsockname ( IOC_sock,
+ (struct sockaddr *)&serverAddr, &addrSize);
+ if ( status ) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
- errlogPrintf ( "CAS: getsockname() error %s\n",
- sockErrBuf );
+ errlogPrintf ( "CAS: getsockname() error %s\n",
+ sockErrBuf );
epicsThreadSuspendSelf ();
- }
+ }
ca_server_port = ntohs (serverAddr.sin_port);
@@ -274,6 +286,7 @@
}
}
freeListInitPvt ( &rsrvLargeBufFreeListTCP, rsrvSizeofLargeBufTCP, 1 );
+ ellInit ( &casIntfAddrList );
ellInit ( &beaconAddrList );
prsrv_cast_client = NULL;
pCaBucket = NULL;
@@ -948,16 +961,16 @@
void casStatsFetch ( unsigned *pChanCount, unsigned *pCircuitCount )
{
- LOCK_CLIENTQ;
+ LOCK_CLIENTQ;
{
int circuitCount = ellCount ( &clientQ );
if ( circuitCount < 0 ) {
- *pCircuitCount = 0;
+ *pCircuitCount = 0;
}
else {
- *pCircuitCount = (unsigned) circuitCount;
+ *pCircuitCount = (unsigned) circuitCount;
}
*pChanCount = rsrvChannelCount;
}
- UNLOCK_CLIENTQ;
+ UNLOCK_CLIENTQ;
}
=== modified file 'src/ioc/rsrv/cast_server.c'
--- src/ioc/rsrv/cast_server.c 2009-07-09 16:37:24 +0000
+++ src/ioc/rsrv/cast_server.c 2014-03-06 22:28:58 +0000
@@ -115,23 +115,14 @@
*/
void cast_server(void *pParm)
{
- struct sockaddr_in sin;
+ osiSockAddrNode *paddrNode;
+ struct sockaddr_in sin;
int status;
int count=0;
struct sockaddr_in new_recv_addr;
osiSocklen_t recv_addr_size;
- unsigned short port;
osiSockIoctl_t nchars;
- if ( envGetConfigParamPtr ( &EPICS_CAS_SERVER_PORT ) ) {
- port = envGetInetPortConfigParam ( &EPICS_CAS_SERVER_PORT,
- (unsigned short) CA_SERVER_PORT );
- }
- else {
- port = envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT,
- (unsigned short) CA_SERVER_PORT );
- }
-
recv_addr_size = sizeof(new_recv_addr);
if( IOC_cast_sock!=0 && IOC_cast_sock!=INVALID_SOCKET ) {
@@ -174,13 +165,11 @@
#endif
epicsSocketEnableAddressUseForDatagramFanout ( IOC_cast_sock );
-
- /* Zero the sock_addr structure */
- memset((char *)&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
- sin.sin_port = htons(port);
-
+
+ paddrNode = (osiSockAddrNode *) ellFirst ( &casIntfAddrList );
+
+ memcpy(&sin, &paddrNode->addr.ia, sizeof (sin));
+
/* get server's Internet address */
if( bind(IOC_cast_sock, (struct sockaddr *)&sin, sizeof (sin)) < 0){
char sockErrBuf[64];
@@ -245,7 +234,8 @@
* see if the next message is for this same client.
*/
if (prsrv_cast_client->send.stk>sizeof(caHdr)) {
- status = memcmp( (void *)&prsrv_cast_client->addr, (void *)&new_recv_addr, recv_addr_size);
+ status = memcmp(&prsrv_cast_client->addr,
+ &new_recv_addr, recv_addr_size);
if(status){
/*
* if the address is different
=== modified file 'src/ioc/rsrv/server.h'
--- src/ioc/rsrv/server.h 2012-06-22 23:16:26 +0000
+++ src/ioc/rsrv/server.h 2014-03-06 22:28:58 +0000
@@ -165,6 +165,7 @@
GLBLTYPE unsigned short ca_server_port;
GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST beaconAddrList;
+GLBLTYPE ELLLIST casIntfAddrList;
GLBLTYPE epicsMutexId clientQlock;
GLBLTYPE struct client *prsrv_cast_client;
GLBLTYPE BUCKET *pCaBucket;
- Navigate by Date:
- Prev:
Jenkins build is back to normal : epics-base-3.14-win32s #3 APS Jenkins
- Next:
epicsStr[n]CaseCmp() Andrew Johnson
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
<2014>
2015
2016
2017
2018
2019
2020
2021
2022
2023
- Navigate by Thread:
- Prev:
Jenkins build is back to normal : epics-base-3.14-win32s #3 APS Jenkins
- Next:
epicsStr[n]CaseCmp() Andrew Johnson
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
<2014>
2015
2016
2017
2018
2019
2020
2021
2022
2023
|