diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 840ca8d7b..22e875da1 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -449,12 +449,41 @@ void MySQL_Data_Stream::shut_hard() { } } +/** + * @brief Checks data flow conditions and handles exceptional cases + * + * This function performs critical checks on the data flow state of a MySQL data stream connection. + * It handles two main scenarios: + * 1. Data present in both input and output queues simultaneously (bidirectional data) + * 2. Backend connection establishment completion + * + * @note For permanent fast-forward sessions (SESSION_FORWARD_TYPE_PERMANENT), bidirectional data + * generates a warning but continues operation. All other session types treat this as a fatal error. + * + * @warning In non-fast-forward sessions, bidirectional data will trigger: + * - Error logging + * - Soft shutdown of the connection + * - Core dump generation for debugging + * + * For backend connections (MYDS_BACKEND) during establishment: + * - Checks socket error status after a POLLOUT event + * - On success: Associates socket fd with MySQL_Connection + * - On error: Performs soft shutdown and logs perror() + * + * @see generate_coredump() + * @see shut_soft() + */ void MySQL_Data_Stream::check_data_flow() { if ( (PSarrayIN->len || queue_data(queueIN) ) && ( PSarrayOUT->len || queue_data(queueOUT) ) ){ - // there is data at both sides of the data stream: this is considered a fatal error - proxy_error("Session=%p, DataStream=%p -- Data at both ends of a MySQL data stream: IN <%d bytes %d packets> , OUT <%d bytes %d packets>\n", sess, this, PSarrayIN->len , queue_data(queueIN) , PSarrayOUT->len , queue_data(queueOUT)); - shut_soft(); - generate_coredump(); + if (sess && sess->status == FAST_FORWARD && sess->session_fast_forward == SESSION_FORWARD_TYPE_PERMANENT) { + // Permanent fast-forward sessions: log warning but continue + proxy_warning("Session=%p, DataStream=%p -- Data at both ends of a MySQL data stream: IN <%d bytes %d packets> , OUT <%d bytes %d packets>\n", sess, this, queue_data(queueIN), PSarrayIN->len, queue_data(queueOUT), PSarrayOUT->len); + } else { + // All other sessions: treat as fatal error + proxy_error("Session=%p, DataStream=%p -- Data at both ends of a MySQL data stream: IN <%d bytes %d packets> , OUT <%d bytes %d packets>\n", sess, this, queue_data(queueIN), PSarrayIN->len, queue_data(queueOUT), PSarrayOUT->len); + shut_soft(); + generate_coredump(); + } } if ((myds_type==MYDS_BACKEND) && myconn && (myconn->fd==0) && (revents & POLLOUT)) { int rc;