|
|
|
|
@@ -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() --*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=========================================================================
|
|
|
|
|
|