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: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org