rsrv: ignore CA client version older than v4.4

RSRV ignore search and version messages
from CA minor versions older than 4.
This commit is contained in:
Michael Davidsaver
2016-07-30 10:35:49 -04:00
parent 2dd16f4362
commit 95fd255dd6
3 changed files with 60 additions and 41 deletions

View File

@@ -28,7 +28,8 @@
#define CA_VERSION_STRING( MINOR_REVISION ) \
( capStrOfX ( CA_MAJOR_PROTOCOL_REVISION ) "." capStrOfX ( MINOR_REVISION ) )
#define CA_UKN_MINOR_VERSION 0u /* unknown minor version */
#if CA_MAJOR_PROTOCOL_REVISION == 4u
#define CA_MINIMUM_SUPPORTED_VERSION 4u
# define CA_VSUPPORTED(MINOR) ((MINOR)>=CA_MINIMUM_SUPPORTED_VERSION)
# define CA_V41(MINOR) ((MINOR)>=1u)
# define CA_V42(MINOR) ((MINOR)>=2u)
# define CA_V43(MINOR) ((MINOR)>=3u)
@@ -42,35 +43,6 @@
# define CA_V411(MINOR) ((MINOR)>=11u) /* sequence numbers in UDP version command */
# define CA_V412(MINOR) ((MINOR)>=12u) /* TCP-based search requests */
# define CA_V413(MINOR) ((MINOR)>=13u) /* Allow zero length in requests. */
#elif CA_MAJOR_PROTOCOL_REVISION > 4u
# define CA_V41(MINOR) ( 1u )
# define CA_V42(MINOR) ( 1u )
# define CA_V43(MINOR) ( 1u )
# define CA_V44(MINOR) ( 1u )
# define CA_V45(MINOR) ( 1u )
# define CA_V46(MINOR) ( 1u )
# define CA_V47(MINOR) ( 1u )
# define CA_V48(MINOR) ( 1u )
# define CA_V49(MINOR) ( 1u )
# define CA_V410(MINOR) ( 1u )
# define CA_V411(MINOR) ( 1u )
# define CA_V412(MINOR) ( 1u )
# define CA_V413(MINOR) ( 1u )
#else
# define CA_V41(MINOR) ( 0u )
# define CA_V42(MINOR) ( 0u )
# define CA_V43(MINOR) ( 0u )
# define CA_V44(MINOR) ( 0u )
# define CA_V45(MINOR) ( 0u )
# define CA_V46(MINOR) ( 0u )
# define CA_V47(MINOR) ( 0u )
# define CA_V48(MINOR) ( 0u )
# define CA_V49(MINOR) ( 0u )
# define CA_V410(MINOR) ( 0u )
# define CA_V411(MINOR) ( 0u )
# define CA_V412(MINOR) ( 0u )
# define CA_V413(MINOR) ( 0u )
#endif
/*
* These port numbers are only used if the CA repeater and

View File

@@ -360,6 +360,13 @@ static int tcp_version_action ( caHdrLargeArray *mp, void *pPayload,
unsigned epicsPriorityNew;
unsigned epicsPrioritySelf;
client->minor_version_number = mp->m_count;
if (!CA_VSUPPORTED(mp->m_count)) {
DLOG ( 2, ( "CAS: Ignore version from unsupported client %u\n", mp->m_count ) );
return RSRV_ERROR;
}
if ( mp->m_dataType > CA_PROTO_PRIORITY_MAX ) {
return RSRV_ERROR;
}
@@ -2197,8 +2204,14 @@ static void search_fail_reply ( caHdrLargeArray *mp, void *pPayload, struct clie
*/
static int udp_version_action ( caHdrLargeArray *mp, void *pPayload, struct client *client )
{
client->minor_version_number = mp->m_count;
if (!CA_VSUPPORTED(mp->m_count)) {
DLOG ( 2, ( "CAS: Ignore version from unsupported client %u\n", mp->m_count ) );
return RSRV_ERROR;
}
if ( mp->m_count != 0 ) {
client->minor_version_number = mp->m_count;
if ( CA_V411 ( mp->m_count ) ) {
client->seqNoOfReq = mp->m_cid;
}
@@ -2248,6 +2261,11 @@ static int search_reply_udp ( caHdrLargeArray *mp, void *pPayload, struct client
size_t spaceNeeded;
size_t reasonableMonitorSpace = 10;
if (!CA_VSUPPORTED(mp->m_count)) {
DLOG ( 2, ( "CAS: Ignore search from unsupported client %u\n", mp->m_count ) );
return RSRV_ERROR;
}
/*
* check the sanity of the message
*/
@@ -2359,6 +2377,11 @@ static int search_reply_tcp (
size_t spaceNeeded;
size_t reasonableMonitorSpace = 10;
if (!CA_VSUPPORTED(mp->m_count)) {
DLOG ( 2, ( "CAS: Ignore search from unsupported client %u\n", mp->m_count ) );
return RSRV_ERROR;
}
/*
* check the sanity of the message
*/
@@ -2542,15 +2565,37 @@ int camessage ( struct client *client )
pBody = ( void * ) ( mp + 1 );
}
/* ignore deprecated clients, but let newer clients identify themselves. */
if (msg.m_cmmd!=CA_PROTO_VERSION && !CA_VSUPPORTED(client->minor_version_number)) {
if (client->proto==IPPROTO_TCP) {
/* log and error for too old clients, but keep the connection open to avoid a
* re-connect loop.
*/
send_err ( &msg, ECA_DEFUNCT, client,
"CAS: Client version %u too old", client->minor_version_number );
log_header ( "CAS: Client version too old",
client, &msg, 0, nmsg );
client->recvBytesToDrain = msgsize - bytes_left;
client->recv.stk = client->recv.cnt;
status = RSRV_OK;
} else {
/* silently ignore UDP from old clients */
status = RSRV_ERROR;
}
break;
}
/*
* disconnect clients that dont send 8 byte
* aligned payloads
*/
if ( msgsize & 0x7 ) {
send_err ( &msg, ECA_INTERNAL, client,
"CAS: Missaligned protocol rejected" );
log_header ( "CAS: Missaligned protocol rejected",
client, &msg, 0, nmsg );
if (client->proto==IPPROTO_TCP) {
send_err ( &msg, ECA_INTERNAL, client,
"CAS: Missaligned protocol rejected" );
log_header ( "CAS: Missaligned protocol rejected",
client, &msg, 0, nmsg );
}
status = RSRV_ERROR;
break;
}
@@ -2564,11 +2609,13 @@ int camessage ( struct client *client )
if ( msgsize > client->recv.maxstk ) {
casExpandRecvBuffer ( client, msgsize );
if ( msgsize > client->recv.maxstk ) {
send_err ( &msg, ECA_TOLARGE, client,
"CAS: Server unable to load large request message. Max bytes=%lu",
rsrvSizeofLargeBufTCP );
log_header ( "CAS: server unable to load large request message",
client, &msg, 0, nmsg );
if (client->proto==IPPROTO_TCP) {
send_err ( &msg, ECA_TOLARGE, client,
"CAS: Server unable to load large request message. Max bytes=%lu",
rsrvSizeofLargeBufTCP );
log_header ( "CAS: server unable to load large request message",
client, &msg, 0, nmsg );
}
assert ( client->recv.cnt <= client->recv.maxstk );
assert ( msgsize >= bytes_left );
client->recvBytesToDrain = msgsize - bytes_left;

View File

@@ -197,7 +197,7 @@ void cast_server(void *pParm)
client->recv.stk = 0ul;
epicsTimeGetCurrent(&client->time_at_last_recv);
client->minor_version_number = 0;
client->minor_version_number = CA_UKN_MINOR_VERSION;
client->seqNoOfReq = 0;
/*