Author: mturk
Date: Tue Dec 15 10:16:49 2009
New Revision: 890740
URL: http://svn.apache.org/viewvc?rev=890740&view=rev
Log:
Drop exces packet during cping/cpong. We should probably do that for
SEND_HEADERS as well
Modified:
tomcat/jk/trunk/native/common/jk_ajp_common.c
Modified: tomcat/jk/trunk/native/common/jk_ajp_common.c
URL:
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.c?rev=890740&r1=890739&r2=890740&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp_common.c (original)
+++ tomcat/jk/trunk/native/common/jk_ajp_common.c Tue Dec 15 10:16:49 2009
@@ -828,6 +828,7 @@
*/
static int ajp_handle_cping_cpong(ajp_endpoint_t * ae, int timeout,
jk_logger_t *l)
{
+ int i;
int cmd;
jk_msg_buf_t *msg;
@@ -858,38 +859,65 @@
return JK_FALSE;
}
- /* wait for Pong reply for timeout milliseconds
- */
- if (jk_is_input_event(ae->sd, timeout, l) == JK_FALSE) {
- ae->last_errno = errno;
- jk_log(l, JK_LOG_INFO, "timeout in reply cpong");
- /* We can't trust this connection any more. */
- jk_shutdown_socket(ae->sd, l);
- ae->sd = JK_INVALID_SOCKET;
- JK_TRACE_EXIT(l);
- return JK_FALSE;
- }
+ for (i = 0; i < 2; i++) {
+ /* wait for Pong reply for timeout milliseconds
+ */
+ if (jk_is_input_event(ae->sd, timeout, l) == JK_FALSE) {
+ ae->last_errno = errno;
+ jk_log(l, JK_LOG_INFO, "timeout in reply cpong");
+ /* We can't trust this connection any more. */
+ jk_shutdown_socket(ae->sd, l);
+ ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
+ JK_TRACE_EXIT(l);
+ return JK_FALSE;
+ }
- /* Read and check for Pong reply
- */
- if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) {
- jk_log(l, JK_LOG_INFO,
- "awaited reply cpong, not received");
- JK_TRACE_EXIT(l);
- return JK_FALSE;
- }
+ /* Read and check for Pong reply
+ */
+ if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) {
+ jk_log(l, JK_LOG_INFO,
+ "awaited reply cpong, not received");
+ JK_TRACE_EXIT(l);
+ return JK_FALSE;
+ }
- if ((cmd = jk_b_get_byte(msg)) != AJP13_CPONG_REPLY) {
- jk_log(l, JK_LOG_WARNING,
- "awaited reply cpong, received %d instead",
- cmd);
- /* We can't trust this connection any more. */
- jk_shutdown_socket(ae->sd, l);
- ae->sd = JK_INVALID_SOCKET;
- JK_TRACE_EXIT(l);
- return JK_FALSE;
- }
+ if ((cmd = jk_b_get_byte(msg)) != AJP13_CPONG_REPLY) {
+ /* If the respose was not CPONG it means that
+ * the previous response was not consumed by the
+ * client but the AJP messages was already in
+ * the network buffer.
+ * silently drop this single extra packet instead
+ * recycling the connection
+ */
+ if (i || ae->last_op == JK_AJP13_END_RESPONSE ||
+ cmd < JK_AJP13_SEND_BODY_CHUNK ||
+ cmd > AJP13_CPONG_REPLY) {
+ jk_log(l, JK_LOG_WARNING,
+ "awaited reply cpong, received %d instead. "
+ "Closing connection",
+ cmd);
+ /* We can't trust this connection any more. */
+ jk_shutdown_socket(ae->sd, l);
+ ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
+ JK_TRACE_EXIT(l);
+ return JK_FALSE;
+ }
+ else {
+ jk_log(l, JK_LOG_INFO,
+ "awaited reply cpong, received %d instead. "
+ "Retrying next packet",
+ cmd);
+ }
+ }
+ else {
+ ae->last_op = AJP13_CPONG_REPLY;
+ /* We have received Pong reply */
+ break;
+ }
+ }
JK_TRACE_EXIT(l);
return JK_TRUE;
}
@@ -948,6 +976,7 @@
/* Close the socket if unable to logon */
jk_shutdown_socket(ae->sd, l);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
}
}
/* XXX: Should we send a cping also after logon to validate the
connection? */
@@ -1083,6 +1112,7 @@
/* because we might have send already parts of the request. */
jk_shutdown_socket(ae->sd, l);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
return JK_FATAL_ERROR;
}
@@ -1102,6 +1132,7 @@
"sendfull for socket %d returned %d (errno=%d)",
ae->sd, rc, ae->last_errno);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
return JK_FALSE;
@@ -1154,6 +1185,7 @@
ae->last_errno);
}
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
return JK_FALSE;
}
@@ -1178,6 +1210,7 @@
/* We can't trust this connection any more. */
jk_shutdown_socket(ae->sd, l);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
return JK_AJP_PROTOCOL_ERROR;
}
@@ -1200,6 +1233,7 @@
/* We can't trust this connection any more. */
jk_shutdown_socket(ae->sd, l);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
return JK_AJP_PROTOCOL_ERROR;
}
@@ -1217,6 +1251,7 @@
/* We can't trust this connection any more. */
jk_shutdown_socket(ae->sd, l);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
return JK_AJP_PROTOCOL_ERROR;
}
@@ -1246,6 +1281,7 @@
ae->last_errno);
}
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
JK_TRACE_EXIT(l);
/* Although we have a connection, this is effectively a protocol error.
* We received the AJP header packet, but not the packet payload
@@ -1408,7 +1444,8 @@
/* Check if the previous request really ended
*/
- if (ae->last_op != JK_AJP13_END_RESPONSE) {
+ if (ae->last_op != JK_AJP13_END_RESPONSE &&
+ ae->last_op != AJP13_CPONG_REPLY) {
jk_log(l, JK_LOG_INFO,
"(%s) did not receive END_RESPONSE, "
"closing socket %d",
@@ -1429,6 +1466,7 @@
"socket %d is not connected any more (errno=%d)",
ae->worker->name, ae->sd, ae->last_errno);
ae->sd = JK_INVALID_SOCKET;
+ ae->last_op = JK_AJP13_END_RESPONSE;
err = JK_TRUE;
err_conn++;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]