/* ------------------------------------------------------------------------ * * * * ------------------------------------------------------------------------ */ void io_multi_start(struct fqueue *fifoptr) { queue_zero(fifoptr); }
int MySQL_Data_Stream::buffer2array() { int ret=0; bool fast_mode=sess->session_fast_forward; if (queue_data(queueIN)==0) return ret; if ((queueIN.pkt.size==0) && queue_data(queueIN)<sizeof(mysql_hdr)) { queue_zero(queueIN); } if (fast_mode) { queueIN.pkt.size=queue_data(queueIN); ret=queueIN.pkt.size; queueIN.pkt.ptr=l_alloc(queueIN.pkt.size); memcpy(queueIN.pkt.ptr, queue_r_ptr(queueIN) , queueIN.pkt.size); queue_r(queueIN, queueIN.pkt.size); PSarrayIN->add(queueIN.pkt.ptr,queueIN.pkt.size); queueIN.pkt.size=0; return ret; } /**/ if (myconn->get_status_compression()==true) { if ((queueIN.pkt.size==0) && queue_data(queueIN)>=7) { proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Reading the header of a new compressed packet\n"); memcpy(&queueIN.hdr,queue_r_ptr(queueIN), sizeof(mysql_hdr)); queue_r(queueIN,sizeof(mysql_hdr)); queueIN.pkt.size=queueIN.hdr.pkt_length+sizeof(mysql_hdr)+3; queueIN.pkt.ptr=l_alloc(queueIN.pkt.size); memcpy(queueIN.pkt.ptr, &queueIN.hdr, sizeof(mysql_hdr)); // immediately copy the header into the packet memcpy((unsigned char *)queueIN.pkt.ptr+sizeof(mysql_hdr), queue_r_ptr(queueIN), 3); // copy 3 bytes, the length of the uncompressed payload queue_r(queueIN,3); queueIN.partial=7; mysql_hdr *_hdr; _hdr=(mysql_hdr *)queueIN.pkt.ptr; myconn->compression_pkt_id=_hdr->pkt_id; ret+=7; } } else { /**/ if ((queueIN.pkt.size==0) && queue_data(queueIN)>=sizeof(mysql_hdr)) { proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Reading the header of a new packet\n"); memcpy(&queueIN.hdr,queue_r_ptr(queueIN),sizeof(mysql_hdr)); pkt_sid=queueIN.hdr.pkt_id; queue_r(queueIN,sizeof(mysql_hdr)); queueIN.pkt.size=queueIN.hdr.pkt_length+sizeof(mysql_hdr); queueIN.pkt.ptr=l_alloc(queueIN.pkt.size); memcpy(queueIN.pkt.ptr, &queueIN.hdr, sizeof(mysql_hdr)); // immediately copy the header into the packet queueIN.partial=sizeof(mysql_hdr); ret+=sizeof(mysql_hdr); // if (myconn->get_status_compression()==true) { // mysql_hdr *_hdr; // _hdr=(mysql_hdr *)queueIN.pkt.ptr; // myconn->compression_pkt_id=_hdr->pkt_id; // } } } if ((queueIN.pkt.size>0) && queue_data(queueIN)) { int b= ( queue_data(queueIN) > (queueIN.pkt.size - queueIN.partial) ? (queueIN.pkt.size - queueIN.partial) : queue_data(queueIN) ); proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Copied %d bytes into packet\n", b); memcpy((unsigned char *)queueIN.pkt.ptr + queueIN.partial, queue_r_ptr(queueIN),b); queue_r(queueIN,b); queueIN.partial+=b; ret+=b; } if ((queueIN.pkt.size>0) && (queueIN.pkt.size==queueIN.partial) ) { if (myconn->get_status_compression()==true) { Bytef *dest; uLongf destLen; proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Copied the whole compressed packet\n"); unsigned int progress=0; unsigned int datalength; unsigned int payload_length=0; unsigned char *u; u=(unsigned char *)queueIN.pkt.ptr; payload_length=*(u+6); payload_length=payload_length*256+*(u+5); payload_length=payload_length*256+*(u+4); unsigned char *_ptr=(unsigned char *)queueIN.pkt.ptr+7; if (payload_length) { // the payload is compressed destLen=payload_length; dest=(Bytef *)l_alloc(destLen); int rc=uncompress(dest, &destLen, _ptr, queueIN.pkt.size-7); assert(rc==Z_OK); datalength=payload_length; // change _ptr to the new buffer _ptr=dest; } else { // the payload is not compressed datalength=queueIN.pkt.size-7; } while (progress<datalength) { if (CompPktIN.partial==0) { mysql_hdr _a; assert(datalength >= progress + sizeof(mysql_hdr)); // FIXME: this is a too optimistic assumption memcpy(&_a,_ptr+progress,sizeof(mysql_hdr)); CompPktIN.pkt.size=_a.pkt_length+sizeof(mysql_hdr); CompPktIN.pkt.ptr=(unsigned char *)l_alloc(CompPktIN.pkt.size); if ((datalength-progress) >= CompPktIN.pkt.size) { // we can copy the whole packet memcpy(CompPktIN.pkt.ptr, _ptr+progress, CompPktIN.pkt.size); CompPktIN.partial=0; // stays 0 progress+=CompPktIN.pkt.size; PSarrayIN->add(CompPktIN.pkt.ptr, CompPktIN.pkt.size); CompPktIN.pkt.ptr=NULL; // sanity } else { // not enough data for the whole packet memcpy(CompPktIN.pkt.ptr, _ptr+progress, (datalength-progress)); CompPktIN.partial+=(datalength-progress); progress=datalength; // we reached the end } } else { if ((datalength-progress) >= (CompPktIN.pkt.size-CompPktIN.partial)) { // we can copy till the end of the packet memcpy((char *)CompPktIN.pkt.ptr + CompPktIN.partial , _ptr+progress, CompPktIN.pkt.size - CompPktIN.partial); CompPktIN.partial=0; progress+= CompPktIN.pkt.size - CompPktIN.partial; PSarrayIN->add(CompPktIN.pkt.ptr, CompPktIN.pkt.size); CompPktIN.pkt.ptr=NULL; // sanity } else { // not enough data for the whole packet memcpy((char *)CompPktIN.pkt.ptr + CompPktIN.partial , _ptr+progress , (datalength-progress)); CompPktIN.partial+=(datalength-progress); progress=datalength; // we reached the end } } // mysql_hdr _a; // memcpy(&_a,_ptr+progress,sizeof(mysql_hdr)); // unsigned int size=_a.pkt_length+sizeof(mysql_hdr); // unsigned char *ptrP=(unsigned char *)l_alloc(size); // memcpy(ptrP,_ptr+progress,size); // progress+=size; // PSarrayIN->add(ptrP,size); } if (payload_length) { l_free(destLen,dest); } l_free(queueIN.pkt.size,queueIN.pkt.ptr); pkts_recv++; queueIN.pkt.size=0; queueIN.pkt.ptr=NULL; } else { PSarrayIN->add(queueIN.pkt.ptr,queueIN.pkt.size); pkts_recv++; queueIN.pkt.size=0; queueIN.pkt.ptr=NULL; } } return ret; }