in native/common/jk_ajp_common.c [1345:1502]
int ajp_connection_tcp_get_message(ajp_endpoint_t * ae,
jk_msg_buf_t *msg, jk_log_context_t *l)
{
unsigned char head[AJP_HEADER_LEN];
int rc;
int msglen;
unsigned int header;
char buf[64];
JK_TRACE_ENTER(l);
ae->last_errno = 0;
/* If recvfull gets an error, it implicitely closes the socket.
* We will invalidate the endpoint connection.
*/
rc = jk_tcp_socket_recvfull(ae->sd, head, AJP_HEADER_LEN, l);
/* If the return code is not negative
* then we always get back the correct number of bytes.
*/
if (rc < 0) {
if (rc == JK_SOCKET_EOF) {
ae->last_errno = EPIPE;
jk_log(l, JK_LOG_INFO,
"(%s) can't receive the response header message from tomcat, "
"tomcat (%s) has forced a connection close for socket %d",
ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr,
buf, sizeof(buf)), ae->sd);
}
else {
ae->last_errno = -rc;
jk_log(l, JK_LOG_INFO,
"(%s) can't receive the response header message from tomcat, "
"network problems or tomcat (%s) is down (errno=%d)",
ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr,
buf, sizeof(buf)), ae->last_errno);
}
ajp_abort_endpoint(ae, JK_FALSE, l);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
ae->endpoint.rd += (jk_uint64_t)rc;
header = ((unsigned int)head[0] << 8) | head[1];
if (ae->proto == AJP13_PROTO) {
if (header != AJP13_SW_HEADER) {
if (header == AJP14_SW_HEADER) {
jk_log(l, JK_LOG_ERROR,
"(%s) received AJP14 reply on an AJP13 connection from %s",
ae->worker->name,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf,
sizeof(buf)));
}
else {
jk_log(l, JK_LOG_ERROR,
"(%s) wrong message format 0x%04x from %s",
ae->worker->name, header,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf,
sizeof(buf)));
}
/* We've got a protocol error.
* We can't trust this connection any more.
*/
ajp_abort_endpoint(ae, JK_TRUE, l);
JK_TRACE_EXIT(l);
return JK_AJP_PROTOCOL_ERROR;
}
}
else if (ae->proto == AJP14_PROTO) {
if (header != AJP14_SW_HEADER) {
if (header == AJP13_SW_HEADER) {
jk_log(l, JK_LOG_ERROR,
"(%s) received AJP13 reply on an AJP14 connection from %s",
ae->worker->name,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf,
sizeof(buf)));
}
else {
jk_log(l, JK_LOG_ERROR,
"(%s) wrong message format 0x%04x from %s",
ae->worker->name, header,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf,
sizeof(buf)));
}
/* We've got a protocol error.
* We can't trust this connection any more.
*/
ajp_abort_endpoint(ae, JK_TRUE, l);
JK_TRACE_EXIT(l);
return JK_AJP_PROTOCOL_ERROR;
}
}
msglen = ((head[2] & 0xff) << 8);
msglen += (head[3] & 0xFF);
if (msglen > msg->maxlen) {
jk_log(l, JK_LOG_ERROR,
"(%s) wrong message size %d %d from %s",
ae->worker->name, msglen, msg->maxlen,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)));
/* We've got a protocol error.
* We can't trust this connection any more.
*/
ajp_abort_endpoint(ae, JK_TRUE, l);
JK_TRACE_EXIT(l);
return JK_AJP_PROTOCOL_ERROR;
}
msg->len = msglen;
msg->pos = 0;
/* If recvfull gets an error, it implicitely closes the socket.
* We will invalidate the endpoint connection.
*/
rc = jk_tcp_socket_recvfull(ae->sd, msg->buf, msglen, l);
/* If the return code is not negative
* then we always get back the correct number of bytes.
*/
if (rc < 0) {
if (rc == JK_SOCKET_EOF) {
ae->last_errno = EPIPE;
jk_log(l, JK_LOG_ERROR,
"(%s) can't receive the response body message from tomcat, "
"tomcat (%s) has forced a connection close for socket %d",
ae->worker->name,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)),
ae->sd);
}
else {
ae->last_errno = -rc;
jk_log(l, JK_LOG_ERROR,
"(%s) can't receive the response body message from tomcat, "
"network problems or tomcat (%s) is down (errno=%d)",
ae->worker->name,
jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)),
ae->last_errno);
}
ajp_abort_endpoint(ae, JK_FALSE, l);
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
*/
return JK_AJP_PROTOCOL_ERROR;
}
ae->endpoint.rd += (jk_uint64_t)rc;
if (JK_IS_DEBUG_LEVEL(l)) {
if (ae->proto == AJP13_PROTO)
jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp13", msg);
else if (ae->proto == AJP14_PROTO)
jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp14", msg);
}
JK_TRACE_EXIT(l);
return JK_TRUE;
}