diff --git a/CASA-auth-token/non-java/utilities/IpcLibs/linux/client/test/testClient.c b/CASA-auth-token/non-java/utilities/IpcLibs/linux/client/test/testClient.c index 0906aea9..ff8f9aba 100644 --- a/CASA-auth-token/non-java/utilities/IpcLibs/linux/client/test/testClient.c +++ b/CASA-auth-token/non-java/utilities/IpcLibs/linux/client/test/testClient.c @@ -192,6 +192,7 @@ ExecuteTests(void) } IpcClientShutdown(); + sleep(1); } else { diff --git a/CASA-auth-token/non-java/utilities/IpcLibs/linux/common/smartptr.h b/CASA-auth-token/non-java/utilities/IpcLibs/linux/common/smartptr.h index e848f94e..1cd05280 100644 --- a/CASA-auth-token/non-java/utilities/IpcLibs/linux/common/smartptr.h +++ b/CASA-auth-token/non-java/utilities/IpcLibs/linux/common/smartptr.h @@ -80,7 +80,6 @@ class ObjRef private: mutable unsigned long m_Count; - }; diff --git a/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/schannel.cpp b/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/schannel.cpp index dab840a0..bc58ab07 100644 --- a/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/schannel.cpp +++ b/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/schannel.cpp @@ -528,6 +528,8 @@ SChannel::sendReplyData( // // Notes: // +// Environment: +// // L2 //=======================================================================-- { @@ -536,6 +538,8 @@ SChannel::sendReplyData( struct msghdr sendmsgHdr = {0}; struct iovec ioVectors[2]; unsigned long bytesSent; + unsigned long totalBytesSent = 0; + unsigned long bytesToSend = sizeof(reqDataPktHdr) + serverDataLen; DbgTrace(1, "SChannel::sendReplyData- Start, Obj = %08X\n", this); @@ -554,34 +558,72 @@ SChannel::sendReplyData( // the server. ioVectors[0].iov_base = reqDataPktHdr; ioVectors[0].iov_len = sizeof(reqDataPktHdr); - ioVectors[1].iov_base = pServerData; + ioVectors[1].iov_base = (char*) pServerData; ioVectors[1].iov_len = serverDataLen; sendmsgHdr.msg_iov = ioVectors; sendmsgHdr.msg_iovlen = 2; - printf("SChannel::sendReplyData- Sending %d header bytes\n", sizeof(reqDataPktHdr)); - printf("SChannel::sendReplyData- Sending %d payload bytes\n", serverDataLen); while (1) { bytesSent = sendmsg(m_socket, &sendmsgHdr, MSG_NOSIGNAL); - if (bytesSent != SOCKET_ERROR - || errno != EINTR) + if (bytesSent == SOCKET_ERROR) { + // Check if we were interrupted during the transfer + if (errno == EINTR) + { + // Just try again + continue; + } + + // An unrecoverable error was encountered during the send operation, + // assume there was a communication failure. Close the socket to make + // sure that the connectionThread cleans up. + //printf("SChannel::sendReplyData- sendmsgn error, totalBytesSent = %d, bytesToSend = %d, errno = %d\n", totalBytesSent, bytesToSend, errno); + DbgTrace(0, "SChannel::sendReplyData- sendmsgn error, errno = %d\n", errno); + m_state = State_Disconnected; + shutdown(m_socket, SHUT_RDWR); + struct linger linger_opt = {1, 15}; + setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)); + closesocket(m_socket); + m_socket = INVALID_SOCKET; break; } - } - if (bytesSent != (sizeof(reqDataPktHdr) + serverDataLen)) - { - // The send was unsuccessful, assume there was a communication - // failure. Close the socket to make sure that the connectionThread - // cleans up. - m_state = State_Disconnected; - shutdown(m_socket, SHUT_RDWR); - struct linger linger_opt = {1, 15}; - setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)); - closesocket(m_socket); - m_socket = INVALID_SOCKET; + else + { + // Account for the bytes sent + totalBytesSent += bytesSent; + + // Check if we are done sending all of the data + if (totalBytesSent >= bytesToSend) + { + // We are done + break; + } + else + { + // Adjust the ioVector structure to send data not yet sent + if (totalBytesSent >= sizeof(reqDataPktHdr)) + { + // The packet header was sent, use only one ioVector. + int serverDataAlreadySent = totalBytesSent - sizeof(reqDataPktHdr); + ioVectors[0].iov_base = (char*) pServerData + serverDataAlreadySent; + ioVectors[0].iov_len = serverDataLen - serverDataAlreadySent; + sendmsgHdr.msg_iov = ioVectors; + sendmsgHdr.msg_iovlen = 1; + } + else + { + // Not all of the packet header was sent, use two ioVectors. + ioVectors[0].iov_base = (char*) reqDataPktHdr + totalBytesSent; + ioVectors[0].iov_len = sizeof(reqDataPktHdr) - totalBytesSent; + ioVectors[1].iov_base = (char*) pServerData; + ioVectors[1].iov_len = serverDataLen; + sendmsgHdr.msg_iov = ioVectors; + sendmsgHdr.msg_iovlen = 2; + } + } + } } // Return success even if the send failed to allow things to be cleaned up @@ -605,7 +647,7 @@ SChannel::sendReplyData( return retStatus; -} /*-- SChannel::sendData() --*/ +} /*-- SChannel::sendReplyData() --*/ //++======================================================================= @@ -621,12 +663,18 @@ SChannel::sendReplyError( // // Notes: // -// L1 +// Environment: +// +// L2 //=======================================================================-- { int retStatus = -1; char reqErrorPktHdr[ReqErrorPktHdrTemplate.length()]; + struct msghdr sendmsgHdr = {0}; + struct iovec ioVectors[1]; unsigned long bytesSent; + unsigned long totalBytesSent = 0; + unsigned long bytesToSend = sizeof(reqErrorPktHdr); DbgTrace(1, "SChannel::sendReplyError- Start, Obj = %08X\n", this); @@ -641,30 +689,59 @@ SChannel::sendReplyError( 0, reqErrorPktHdr) == 0) { - // Packet header was built, now sent it to the client. + // Packet header was built, now sent it along with the client data to + // the server. + ioVectors[0].iov_base = reqErrorPktHdr; + ioVectors[0].iov_len = sizeof(reqErrorPktHdr); + sendmsgHdr.msg_iov = ioVectors; + sendmsgHdr.msg_iovlen = 1; while (1) { - bytesSent = send(m_socket, - reqErrorPktHdr, - sizeof(reqErrorPktHdr), - MSG_NOSIGNAL); - if (bytesSent != SOCKET_ERROR - || errno != EINTR) + bytesSent = sendmsg(m_socket, + &sendmsgHdr, + MSG_NOSIGNAL); + if (bytesSent == SOCKET_ERROR) { + // Check if we were interrupted during the transfer + if (errno == EINTR) + { + // Just try again + continue; + } + + // An unrecoverable error was encountered during the send operation, + // assume there was a communication failure. Close the socket to make + // sure that the connectionThread cleans up. + //printf("SChannel::sendReplyError- sendmsgn error, totalBytesSent = %d, bytesToSend = %d, errno = %d\n", totalBytesSent, bytesToSend, errno); + DbgTrace(0, "SChannel::sendReplyError- sendmsgn error, errno = %d\n", errno); + m_state = State_Disconnected; + shutdown(m_socket, SHUT_RDWR); + struct linger linger_opt = {1, 15}; + setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)); + closesocket(m_socket); + m_socket = INVALID_SOCKET; break; } - } - if (bytesSent != sizeof(reqErrorPktHdr)) - { - // The send was unsuccessful, assume there was a communication - // failure. Close the socket to make sure that the connectionThread - // cleans up. - m_state = State_Disconnected; - shutdown(m_socket, SHUT_RDWR); - struct linger linger_opt = {1, 15}; - setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)); - closesocket(m_socket); - m_socket = INVALID_SOCKET; + else + { + // Account for the bytes sent + totalBytesSent += bytesSent; + + // Check if we are done sending all of the data + if (totalBytesSent >= bytesToSend) + { + // We are done + break; + } + else + { + // Adjust the ioVector structure to send data not yet sent + ioVectors[0].iov_base = (char*) reqErrorPktHdr + totalBytesSent; + ioVectors[0].iov_len = sizeof(reqErrorPktHdr) - totalBytesSent; + sendmsgHdr.msg_iov = ioVectors; + sendmsgHdr.msg_iovlen = 1; + } + } } // Return success even if the send failed to allow things to be cleaned up @@ -673,7 +750,7 @@ SChannel::sendReplyError( } else { - DbgTrace(0, "SChannel::sendReplyError- Error building Req Error Pkt Header, Obj = %08X\n", this); + DbgTrace(0, "SChannel::sendReplyError- Error building Req Data Pkt Header, Obj = %08X\n", this); } } else @@ -688,7 +765,7 @@ SChannel::sendReplyError( return retStatus; -} /*-- SChannel::sendData() --*/ +} /*-- SChannel::sendReplyError() --*/ //========================================================================= diff --git a/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/serverreq.cpp b/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/serverreq.cpp index b99c91e1..dfa021ac 100644 --- a/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/serverreq.cpp +++ b/CASA-auth-token/non-java/utilities/IpcLibs/linux/server/serverreq.cpp @@ -113,6 +113,9 @@ ServerReq::~ServerReq(void) if (m_pClientData) free(m_pClientData); + // Delete the SmartSChannel + delete m_pSmartSChannel; + // Decrement the object count InterlockedDecrement(&numServerReqObjects);