Fixed a few problems in the IpcLibs.
This commit is contained in:
		| @@ -192,6 +192,7 @@ ExecuteTests(void) | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       IpcClientShutdown(); |       IpcClientShutdown(); | ||||||
|  |       sleep(1); | ||||||
|    } |    } | ||||||
|    else |    else | ||||||
|    { |    { | ||||||
|   | |||||||
| @@ -80,7 +80,6 @@ class ObjRef | |||||||
|    private: |    private: | ||||||
|  |  | ||||||
|    mutable unsigned long m_Count; |    mutable unsigned long m_Count; | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -528,6 +528,8 @@ SChannel::sendReplyData( | |||||||
| // | // | ||||||
| //  Notes: | //  Notes: | ||||||
| // | // | ||||||
|  | //  Environment: | ||||||
|  | // | ||||||
| // L2 | // L2 | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
| { | { | ||||||
| @@ -536,6 +538,8 @@ SChannel::sendReplyData( | |||||||
|    struct msghdr  sendmsgHdr = {0}; |    struct msghdr  sendmsgHdr = {0}; | ||||||
|    struct iovec   ioVectors[2]; |    struct iovec   ioVectors[2]; | ||||||
|    unsigned long  bytesSent; |    unsigned long  bytesSent; | ||||||
|  |    unsigned long  totalBytesSent = 0; | ||||||
|  |    unsigned long  bytesToSend = sizeof(reqDataPktHdr) + serverDataLen; | ||||||
|  |  | ||||||
|    DbgTrace(1, "SChannel::sendReplyData- Start, Obj = %08X\n", this); |    DbgTrace(1, "SChannel::sendReplyData- Start, Obj = %08X\n", this); | ||||||
|  |  | ||||||
| @@ -554,34 +558,72 @@ SChannel::sendReplyData( | |||||||
|          // the server. |          // the server. | ||||||
|          ioVectors[0].iov_base = reqDataPktHdr; |          ioVectors[0].iov_base = reqDataPktHdr; | ||||||
|          ioVectors[0].iov_len = sizeof(reqDataPktHdr); |          ioVectors[0].iov_len = sizeof(reqDataPktHdr); | ||||||
|          ioVectors[1].iov_base = pServerData; |          ioVectors[1].iov_base = (char*) pServerData; | ||||||
|          ioVectors[1].iov_len = serverDataLen; |          ioVectors[1].iov_len = serverDataLen; | ||||||
|          sendmsgHdr.msg_iov = ioVectors; |          sendmsgHdr.msg_iov = ioVectors; | ||||||
|          sendmsgHdr.msg_iovlen = 2; |          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) |          while (1) | ||||||
|          { |          { | ||||||
|             bytesSent = sendmsg(m_socket, |             bytesSent = sendmsg(m_socket, | ||||||
|                                 &sendmsgHdr, |                                 &sendmsgHdr, | ||||||
|                                 MSG_NOSIGNAL); |                                 MSG_NOSIGNAL); | ||||||
|             if (bytesSent != SOCKET_ERROR |             if (bytesSent == SOCKET_ERROR) | ||||||
|                 || errno != EINTR) |  | ||||||
|             { |             { | ||||||
|  |                // 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; |                break; | ||||||
|             } |             } | ||||||
|          } |             else | ||||||
|          if (bytesSent != (sizeof(reqDataPktHdr) + serverDataLen)) |             { | ||||||
|          { |                // Account for the bytes sent | ||||||
|             // The send was unsuccessful, assume there was a communication |                totalBytesSent += bytesSent; | ||||||
|             // failure. Close the socket to make sure that the connectionThread |  | ||||||
|             // cleans up. |                // Check if we are done sending all of the data | ||||||
|             m_state = State_Disconnected; |                if (totalBytesSent >= bytesToSend) | ||||||
|             shutdown(m_socket, SHUT_RDWR); |                { | ||||||
|             struct linger linger_opt = {1, 15}; |                   // We are done | ||||||
|             setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)); |                   break; | ||||||
|             closesocket(m_socket); |                } | ||||||
|             m_socket = INVALID_SOCKET; |                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 |          // Return success even if the send failed to allow things to be cleaned up | ||||||
| @@ -605,7 +647,7 @@ SChannel::sendReplyData( | |||||||
|  |  | ||||||
|    return retStatus; |    return retStatus; | ||||||
|  |  | ||||||
| }  /*-- SChannel::sendData() --*/ | }  /*-- SChannel::sendReplyData() --*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| //++======================================================================= | //++======================================================================= | ||||||
| @@ -621,12 +663,18 @@ SChannel::sendReplyError( | |||||||
| // | // | ||||||
| //  Notes: | //  Notes: | ||||||
| // | // | ||||||
| // L1 | //  Environment: | ||||||
|  | // | ||||||
|  | // L2 | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
| { | { | ||||||
|    int            retStatus = -1; |    int            retStatus = -1; | ||||||
|    char           reqErrorPktHdr[ReqErrorPktHdrTemplate.length()]; |    char           reqErrorPktHdr[ReqErrorPktHdrTemplate.length()]; | ||||||
|  |    struct msghdr  sendmsgHdr = {0}; | ||||||
|  |    struct iovec   ioVectors[1]; | ||||||
|    unsigned long  bytesSent; |    unsigned long  bytesSent; | ||||||
|  |    unsigned long  totalBytesSent = 0; | ||||||
|  |    unsigned long  bytesToSend = sizeof(reqErrorPktHdr); | ||||||
|  |  | ||||||
|    DbgTrace(1, "SChannel::sendReplyError- Start, Obj = %08X\n", this); |    DbgTrace(1, "SChannel::sendReplyError- Start, Obj = %08X\n", this); | ||||||
|  |  | ||||||
| @@ -641,30 +689,59 @@ SChannel::sendReplyError( | |||||||
|                                             0, |                                             0, | ||||||
|                                             reqErrorPktHdr) == 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) |          while (1) | ||||||
|          { |          { | ||||||
|             bytesSent = send(m_socket, |             bytesSent = sendmsg(m_socket, | ||||||
|                              reqErrorPktHdr, |                                 &sendmsgHdr, | ||||||
|                              sizeof(reqErrorPktHdr), |                                 MSG_NOSIGNAL); | ||||||
|                              MSG_NOSIGNAL); |             if (bytesSent == SOCKET_ERROR) | ||||||
|             if (bytesSent != SOCKET_ERROR |  | ||||||
|                 || errno != EINTR) |  | ||||||
|             { |             { | ||||||
|  |                // 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; |                break; | ||||||
|             } |             } | ||||||
|          } |             else | ||||||
|          if (bytesSent != sizeof(reqErrorPktHdr)) |             { | ||||||
|          { |                // Account for the bytes sent | ||||||
|             // The send was unsuccessful, assume there was a communication |                totalBytesSent += bytesSent; | ||||||
|             // failure. Close the socket to make sure that the connectionThread |  | ||||||
|             // cleans up. |                // Check if we are done sending all of the data | ||||||
|             m_state = State_Disconnected; |                if (totalBytesSent >= bytesToSend) | ||||||
|             shutdown(m_socket, SHUT_RDWR); |                { | ||||||
|             struct linger linger_opt = {1, 15}; |                   // We are done | ||||||
|             setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)); |                   break; | ||||||
|             closesocket(m_socket); |                } | ||||||
|             m_socket = INVALID_SOCKET; |                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 |          // Return success even if the send failed to allow things to be cleaned up | ||||||
| @@ -673,7 +750,7 @@ SChannel::sendReplyError( | |||||||
|       } |       } | ||||||
|       else |       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 |    else | ||||||
| @@ -688,7 +765,7 @@ SChannel::sendReplyError( | |||||||
|  |  | ||||||
|    return retStatus; |    return retStatus; | ||||||
|  |  | ||||||
| }  /*-- SChannel::sendData() --*/ | }  /*-- SChannel::sendReplyError() --*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| //========================================================================= | //========================================================================= | ||||||
|   | |||||||
| @@ -113,6 +113,9 @@ ServerReq::~ServerReq(void) | |||||||
|    if (m_pClientData) |    if (m_pClientData) | ||||||
|       free(m_pClientData); |       free(m_pClientData); | ||||||
|  |  | ||||||
|  |    // Delete the SmartSChannel | ||||||
|  |    delete m_pSmartSChannel; | ||||||
|  |  | ||||||
|    // Decrement the object count |    // Decrement the object count | ||||||
|    InterlockedDecrement(&numServerReqObjects); |    InterlockedDecrement(&numServerReqObjects); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user