static inline pkt * admin_version_comment_pkt(mysql_session_t *sess) { pkt *p; //proxy_mysql_thread_t *thrLD=pthread_getspecific(tsd_key); p=mypkt_alloc(); // hardcoded, we send " (ProxySQL) " p->length=81; //p->data=l_alloc(thrLD->sfp, p->length); p->data=l_alloc(p->length); //p->data=g_slice_alloc0(p->length); memcpy(p->data,"\x01\x00\x00\x01\x01\x27\x00\x00\x02\x03\x64\x65\x66\x00\x00\x00\x11\x40\x40\x76\x65\x72\x73\x69\x6f\x6e\x5f\x63\x6f\x6d\x6d\x65\x6e\x74\x00\x0c\x21\x00\x18\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x05\x00\x00\x03\xfe\x00\x00\x02\x00\x0b\x00\x00\x04\x0a\x28\x50\x72\x6f\x78\x79\x53\x51\x4c\x29\x05\x00\x00\x05\xfe\x00\x00\x02\x00",p->length); return p; }
void PtrSizeArray::expand(unsigned int more) { if ( (len+more) > size ) { unsigned int new_size=l_near_pow_2(len+more); //void *new_pdata=malloc(new_size*sizeof(PtrSize_t)); void *new_pdata=l_alloc(new_size*sizeof(PtrSize_t)); if (pdata) { memcpy(new_pdata,pdata,size*sizeof(PtrSize_t)); //free(pdata); l_free(size*sizeof(PtrSize_t),pdata); } size=new_size; pdata=(PtrSize_t *)new_pdata; } }
unsigned char * MySQL_Data_Stream::resultset2buffer(bool del) { unsigned int i; unsigned int l=0; unsigned char *mybuff=(unsigned char *)l_alloc(resultset_length); PtrSize_t *ps; for (i=0;i<resultset->len;i++) { ps=resultset->index(i); memcpy(mybuff+l,ps->ptr,ps->size); if (del) l_free(ps->size,ps->ptr); l+=ps->size; } //while (resultset->len) resultset->remove_index(resultset->len-1,NULL); return mybuff; };
void MySQL_Data_Stream::buffer2resultset(unsigned char *ptr, unsigned int size) { unsigned char *__ptr=ptr; mysql_hdr hdr; unsigned int l; void *pkt; while (__ptr<ptr+size) { memcpy(&hdr,__ptr,sizeof(mysql_hdr)); //Copy4B(&hdr,__ptr); l=hdr.pkt_length+sizeof(mysql_hdr); pkt=l_alloc(l); memcpy(pkt,__ptr,l); resultset->add(pkt,l); __ptr+=l; } };
void PtrArray::expand(unsigned int more) { if ( (len+more) > size ) { unsigned int new_size=l_near_pow_2(len+more); void *new_pdata=( use_l_alloc ? l_alloc(new_size*sizeof(void *)) : malloc(new_size*sizeof(void *)) ); memset(new_pdata,0,new_size*sizeof(void *)); //void *new_pdata=malloc(new_size*sizeof(void *)); //void *new_pdata=l_alloc(new_size*sizeof(void *)); if (pdata) { memcpy(new_pdata,pdata,size*sizeof(void *)); ( use_l_alloc ? l_free(size*sizeof(void *),pdata) : free(pdata) ); //free(pdata); //l_free(size*sizeof(void *),pdata); } size=new_size; pdata=(void **)new_pdata; } }
/* Initializes @p with @pttfile and @conf. * * Returns 0 on success; a negative enum errcode otherwise. * Returns -err_internal if @p is the NULL pointer. */ static struct parser *p_alloc(const char *pttfile, const struct pt_config *conf) { size_t n; struct parser *p; if (!conf) return NULL; if (!pttfile) return NULL; p = calloc(1, sizeof(*p)); if (!p) return NULL; p->y = yasm_alloc(pttfile); if (!p->y) goto error; n = strlen(p->y->fileroot) + 1; p->ptfilename = malloc(n+strlen(pt_suffix)); if (!p->ptfilename) goto error; strcpy(p->ptfilename, p->y->fileroot); strcat(p->ptfilename, pt_suffix); p->pd = pd_alloc(pd_len); if (!p->pd) goto error; p->pt_labels = l_alloc(); if (!p->pt_labels) goto error; p->conf = conf; return p; error: p_free(p); return NULL; }
int l_append(struct label *l, const char *name, uint64_t addr) { int errcode; if (bug_on(!l)) return -err_internal; if (bug_on(!name)) return -err_internal; /* skip to the last label. */ while (l->next) l = l->next; /* append a new label. */ l->next = l_alloc(); if (!l->next) return -err_no_mem; /* save the name. */ l->next->name = duplicate_str(name); if (!l->next->name) { errcode = -err_no_mem; goto error; } /* save the address. */ l->next->addr = addr; return 0; error: free(l->next->name); free(l->next); l->next = NULL; return errcode; }
Query_Processor_Output * Query_Processor::process_mysql_query(MySQL_Session *sess, void *ptr, unsigned int size, bool delete_original) { Query_Processor_Output *ret=NULL; unsigned int len=size-sizeof(mysql_hdr)-1; char *query=(char *)l_alloc(len+1); memcpy(query,(char *)ptr+sizeof(mysql_hdr)+1,len); query[len]=0; if (__sync_add_and_fetch(&version,0) > _thr_SQP_version) { // update local rules; proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Detected a changed in version. Global:%d , local:%d . Refreshing...\n", version, _thr_SQP_version); spin_rdlock(&rwlock); _thr_SQP_version=__sync_add_and_fetch(&version,0); __reset_rules(_thr_SQP_rules); QP_rule_t *qr1; QP_rule_t *qr2; for (std::vector<QP_rule_t *>::iterator it=rules.begin(); it!=rules.end(); ++it) { qr1=*it; if (qr1->active) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Copying Query Rule id: %d\n", qr1->rule_id); qr2=new_query_rule(qr1->rule_id, qr1->active, qr1->username, qr1->schemaname, qr1->flagIN, qr1->match_pattern, qr1->negate_match_pattern, qr1->flagOUT, qr1->replace_pattern, qr1->destination_hostgroup, qr1->cache_ttl, qr1->reconnect, qr1->timeout, qr1->delay, qr1->apply); qr2->parent=qr1; // pointer to parent to speed up parent update (hits) if (qr2->match_pattern) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Compiling regex for rule_id: %d, match_pattern: \n", qr2->rule_id, qr2->match_pattern); qr2->regex_engine=(void *)compile_query_rule(qr2); } _thr_SQP_rules->push_back(qr2); } } spin_rdunlock(&rwlock); // unlock should be after the copy } QP_rule_t *qr; re2_t *re2p; int flagIN=0; for (std::vector<QP_rule_t *>::iterator it=_thr_SQP_rules->begin(); it!=_thr_SQP_rules->end(); ++it) { qr=*it; if (qr->flagIN != flagIN) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 6, "query rule %d has no matching flagIN\n", qr->rule_id); continue; } if (qr->username && strlen(qr->username)) { if (strcmp(qr->username,sess->client_myds->myconn->userinfo->username)!=0) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has no matching username\n", qr->rule_id); continue; } } if (qr->schemaname && strlen(qr->schemaname)) { if (strcmp(qr->schemaname,sess->client_myds->myconn->userinfo->schemaname)!=0) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has no matching schemaname\n", qr->rule_id); continue; } } re2p=(re2_t *)qr->regex_engine; if (qr->match_pattern) { bool rc; if (ret && ret->new_query) { // if we already rewrote the query, process the new query //std::string *s=ret->new_query; rc=RE2::PartialMatch(ret->new_query->c_str(),*re2p->re); } else { // we never rewrote the query rc=RE2::PartialMatch(query,*re2p->re); } if ((rc==true && qr->negate_match_pattern==true) || ( rc==false && qr->negate_match_pattern==false )) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has no matching pattern\n", qr->rule_id); continue; } } // if we arrived here, we have a match if (ret==NULL) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "this is the first time we find a match\n"); // create struct //ret=(QP_out_t *)l_alloc(sizeof(QP_out_t)); ret=new Query_Processor_Output(); // initalized all values ret->ptr=NULL; ret->size=0; ret->destination_hostgroup=-1; ret->cache_ttl=-1; ret->reconnect=-1; ret->timeout=-1; ret->delay=-1; ret->new_query=NULL; } qr->hits++; // this is done without atomic function because it updates only the local variables /* { // FIXME: this block of code is only for testing if ((qr->hits%20)==0) { spin_rdlock(&rwlock); if (__sync_add_and_fetch(&version,0) == _thr_SQP_version) { // extra safety check to avoid race conditions __sync_fetch_and_add(&qr->parent->hits,20); } */ /* QP_rule_t *qrg; for (std::vector<QP_rule_t *>::iterator it=rules.begin(); it!=rules.end(); ++it) { qrg=*it; if (qrg->rule_id==qr->rule_id) { __sync_fetch_and_add(&qrg->hits,20); break; } } */ /* spin_rdunlock(&rwlock); } } */ if (qr->flagOUT >= 0) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has changed flagOUT\n", qr->rule_id); flagIN=qr->flagOUT; //sess->query_info.flagOUT=flagIN; } if (qr->reconnect >= 0) { // Note: negative reconnect means this rule doesn't change proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has set reconnect: %d. Query will%s be rexecuted if connection is lost\n", qr->rule_id, qr->reconnect, (qr->reconnect == 0 ? " NOT" : "" )); ret->reconnect=qr->reconnect; } if (qr->timeout >= 0) { // Note: negative timeout means this rule doesn't change proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has set timeout: %d. Query will%s be interrupted if exceeding %dms\n", qr->rule_id, qr->timeout, (qr->timeout == 0 ? " NOT" : "" ) , qr->timeout); ret->timeout=qr->timeout; } if (qr->delay >= 0) { // Note: negative delay means this rule doesn't change proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has set delay: %d. Session will%s be paused for %dms\n", qr->rule_id, qr->delay, (qr->delay == 0 ? " NOT" : "" ) , qr->delay); ret->delay=qr->delay; } if (qr->cache_ttl >= 0) { // Note: negative TTL means this rule doesn't change proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has set cache_ttl: %d. Query will%s hit the cache\n", qr->rule_id, qr->cache_ttl, (qr->cache_ttl == 0 ? " NOT" : "" )); ret->cache_ttl=qr->cache_ttl; } if (qr->destination_hostgroup >= 0) { // Note: negative hostgroup means this rule doesn't change proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has set destination hostgroup: %d\n", qr->rule_id, qr->destination_hostgroup); ret->destination_hostgroup=qr->destination_hostgroup; } if (qr->replace_pattern) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d on match_pattern \"%s\" has a replace_pattern \"%s\" to apply\n", qr->rule_id, qr->match_pattern, qr->replace_pattern); if (ret->new_query==NULL) ret->new_query=new std::string(query); RE2::Replace(ret->new_query,qr->match_pattern,qr->replace_pattern); } if (qr->apply==true) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d is the last one to apply: exit!\n", qr->rule_id); goto __exit_process_mysql_query; } } __exit_process_mysql_query: // FIXME : there is too much data being copied around l_free(len+1,query); return ret; };
void * MySQL_Backend::operator new(size_t size) { return l_alloc(size); }
void * PtrArray::operator new(size_t size, bool b) { return l_alloc(size); }
void admin_COM_QUERY(mysql_session_t *sess, pkt *p) { int rc; sqlite3 *defaultdb; if (sess->admin==1) { defaultdb=sqlite3admindb; } else { //admin==2 defaultdb=sqlite3monitordb; } //proxy_mysql_thread_t *thrLD=pthread_getspecific(tsd_key); // enter admin mode // configure the session to not send data to servers using a hack: pretend the result set is cached sess->mysql_query_cache_hit=TRUE; sess->query_to_cache=FALSE; update_runtime_statistics(sess->admin); if (strncasecmp("SHOW TABLES", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { char *str="SELECT name AS tables FROM sqlite_master WHERE type='table'"; //g_slice_free1(p->length, p->data); //l_free(thrLD->sfp,p->length, p->data); l_free(p->length, p->data); int l=strlen(str); //p->data=l_alloc(thrLD->sfp, l+sizeof(mysql_hdr)+1); p->data=l_alloc(l+sizeof(mysql_hdr)+1); //p->data=g_slice_alloc0(l+sizeof(mysql_hdr)+1); p->length=l+sizeof(mysql_hdr)+1; memset(p->data+sizeof(mysql_hdr), MYSQL_COM_QUERY, 1); memcpy(p->data+sizeof(mysql_hdr)+1,str,l); } { static char *strA="SHOW CREATE TABLE "; static char *strB="SELECT name AS 'table' , sql AS 'Create Table' FROM sqlite_master WHERE type='table' AND name='%s'"; int strAl=strlen(strA); if (strncasecmp("SHOW CREATE TABLE ", p->data+sizeof(mysql_hdr)+1, strAl)==0) { int strBl=strlen(strB); int tblnamelen=p->length-sizeof(mysql_hdr)-1-strAl; int l=strBl+tblnamelen-2; char *buff=g_malloc0(l); snprintf(buff,l,strB,p->data+sizeof(mysql_hdr)+1+strAl); buff[l-1]='\''; //g_slice_free1(p->length, p->data); //l_free(thrLD->sfp,p->length, p->data); l_free(p->length, p->data); //p->data=l_alloc(thrLD->sfp, l+sizeof(mysql_hdr)+1); p->data=l_alloc(l+sizeof(mysql_hdr)+1); //p->data=g_slice_alloc0(l+sizeof(mysql_hdr)+1); p->length=l+sizeof(mysql_hdr)+1; memset(p->data+sizeof(mysql_hdr), MYSQL_COM_QUERY, 1); memcpy(p->data+sizeof(mysql_hdr)+1,buff,l); g_free(buff); } } if (strncmp("select @@version_comment limit 1", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { // mysql client in interactive mode sends "select @@version_comment limit 1" : we treat this as a special case // drop the packet from client mypkt_free1(p); // prepare a new packet to send to the client pkt *np=NULL; np=admin_version_comment_pkt(sess); MY_SESS_ADD_PKT_OUT_CLIENT(np); //l_ptr_array_add(sess->client_myds->output.pkts, np); return; } if (sess->admin==1) { // in the admin module, not in the monitoring module if (strncasecmp("FLUSH QUERY CACHE", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=fdb_truncate_all(&QC); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); return; } if (strncasecmp("FLUSH DEBUG", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_flush_debug_levels_db_to_mem(sqlite3admindb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); if (glovars.admin_sync_disk_on_flush==1) sqlite3_config_sync_mem_to_disk(); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } if (strncasecmp("FLUSH USERS", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_flush_users_db_to_mem(sqlite3admindb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); if (glovars.admin_sync_disk_on_flush==1) sqlite3_config_sync_mem_to_disk(); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } if (strncasecmp("FLUSH QUERY RULES", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_flush_query_rules_db_to_mem(sqlite3admindb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); if (glovars.admin_sync_disk_on_flush==1) sqlite3_config_sync_mem_to_disk(); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } if (strncasecmp("FLUSH DEFAULT HOSTGROUPS", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_flush_default_hostgroups_db_to_mem(sqlite3admindb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); if (glovars.admin_sync_disk_on_flush==1) sqlite3_config_sync_mem_to_disk(); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } if (strncasecmp("FLUSH HOSTGROUPS", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_flush_servers_db_to_mem(sqlite3admindb,0); int warnings=force_remove_servers(); if ( affected_rows>=0 ) { pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,warnings); MY_SESS_ADD_PKT_OUT_CLIENT(ok); if (glovars.admin_sync_disk_on_flush==1) sqlite3_config_sync_mem_to_disk(); //l_ptr_array_add(sess->client_myds->output.pkts, ok); } else { // TODO: send some error } return; } // if (strncasecmp("REMOVE SERVERS", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { // } if (strncasecmp("SHUTDOWN", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { glovars.shutdown=1; pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,0,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); if (glovars.admin_sync_disk_on_shutdown==1) sqlite3_config_sync_mem_to_disk(); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } /* if (strncasecmp("DUMP RUNTIME HOSTGROUPS", p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { //int affected_rows=sqlite3_dump_runtime_hostgroups(); int affected_rows; affected_rows=sqlite3_dump_runtime_hostgroups(sqlite3configdb); affected_rows=sqlite3_dump_runtime_hostgroups(sqlite3admindb); affected_rows=sqlite3_dump_runtime_hostgroups(sqlite3monitordb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } */ if (strncasecmp(DUMP_RUNTIME_QUERY_RULES, p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows; //int affected_rows=sqlite3_dump_runtime_query_rules(); affected_rows=sqlite3_dump_runtime_query_rules(defaultdb); //affected_rows=sqlite3_dump_runtime_query_rules(sqlite3configdb); //affected_rows=sqlite3_dump_runtime_query_rules(sqlite3admindb); //affected_rows=sqlite3_dump_runtime_query_rules(sqlite3monitordb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } if (strncasecmp(DUMP_RUNTIME_QUERY_CACHE, p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows; affected_rows=sqlite3_dump_runtime_query_cache(defaultdb); //affected_rows=sqlite3_dump_runtime_query_cache(sqlite3configdb); //affected_rows=sqlite3_dump_runtime_query_cache(sqlite3admindb); //affected_rows=sqlite3_dump_runtime_query_cache(sqlite3monitordb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } if (strncasecmp(DUMP_RUNTIME_DEFAULT_HOSTGROUPS, p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_dump_runtime_default_hostgroups(defaultdb); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); return; } if (strncasecmp(CONFIG_SYNC_MEM_TO_DISK, p->data+sizeof(mysql_hdr)+1, p->length-sizeof(mysql_hdr)-1)==0) { int affected_rows=sqlite3_config_sync_mem_to_disk(); pkt *ok=mypkt_alloc(); myproto_ok_pkt(ok,1,affected_rows,0,2,0); MY_SESS_ADD_PKT_OUT_CLIENT(ok); //l_ptr_array_add(sess->client_myds->output.pkts, ok); return; } } rc=mysql_pkt_to_sqlite_exec(p, sess); mypkt_free1(p); if (rc==-1) { sess->healthy=0; } // sess->healthy=0; // for now, always return; }
void * MySQL_Data_Stream::operator new(size_t size) { return l_alloc(size); }
void MySQL_Data_Stream::generate_compressed_packet() { #define MAX_COMPRESSED_PACKET_SIZE 10*1024*1024 unsigned int total_size=0; unsigned int i=0; PtrSize_t *p=NULL; while (i<PSarrayOUT->len && total_size<MAX_COMPRESSED_PACKET_SIZE) { p=PSarrayOUT->index(i); total_size+=p->size; if (i==0) { mysql_hdr hdr; memcpy(&hdr,p->ptr,sizeof(mysql_hdr)); if (hdr.pkt_id==0) { myconn->compression_pkt_id=-1; } } i++; } if (i>=2) { // we successfully read at least 2 packets if (total_size>MAX_COMPRESSED_PACKET_SIZE) { // total_size is too big, we remove the last packet read total_size-=p->size; } } if (total_size <= MAX_COMPRESSED_PACKET_SIZE) { // this worked in the past . it applies for small packets uLong sourceLen=total_size; Bytef *source=(Bytef *)l_alloc(total_size); uLongf destLen=total_size*120/100+12; Bytef *dest=(Bytef *)malloc(destLen); i=0; total_size=0; while (total_size<sourceLen) { //p=PSarrayOUT->index(i); PtrSize_t p2; PSarrayOUT->remove_index(0,&p2); memcpy(source+total_size,p2.ptr,p2.size); //i++; total_size+=p2.size; l_free(p2.size,p2.ptr); } //PSarrayOUT->remove_index_range(0,i); int rc=compress(dest, &destLen, source, sourceLen); assert(rc==Z_OK); l_free(total_size, source); queueOUT.pkt.size=destLen+7; queueOUT.pkt.ptr=l_alloc(queueOUT.pkt.size); mysql_hdr hdr; hdr.pkt_length=destLen; hdr.pkt_id=++myconn->compression_pkt_id; //hdr.pkt_id=1; memcpy((unsigned char *)queueOUT.pkt.ptr,&hdr,sizeof(mysql_hdr)); hdr.pkt_length=total_size; memcpy((unsigned char *)queueOUT.pkt.ptr+4,&hdr,3); memcpy((unsigned char *)queueOUT.pkt.ptr+7,dest,destLen); free(dest); } else { // if we reach here, it means we have one single packet larger than MAX_COMPRESSED_PACKET_SIZE PtrSize_t p2; PSarrayOUT->remove_index(0,&p2); unsigned int len1=MAX_COMPRESSED_PACKET_SIZE/2; unsigned int len2=p2.size-len1; uLongf destLen1; uLongf destLen2; Bytef *dest1; Bytef *dest2; int rc; mysql_hdr hdr; destLen1=len1*120/100+12; dest1=(Bytef *)malloc(destLen1+7); destLen2=len2*120/100+12; dest2=(Bytef *)malloc(destLen2+7); rc=compress(dest1+7, &destLen1, (const unsigned char *)p2.ptr, len1); assert(rc==Z_OK); rc=compress(dest2+7, &destLen2, (const unsigned char *)p2.ptr+len1, len2); assert(rc==Z_OK); hdr.pkt_length=destLen1; hdr.pkt_id=++myconn->compression_pkt_id; memcpy(dest1,&hdr,sizeof(mysql_hdr)); hdr.pkt_length=len1; memcpy((char *)dest1+sizeof(mysql_hdr),&hdr,3); hdr.pkt_length=destLen2; hdr.pkt_id=++myconn->compression_pkt_id; memcpy(dest2,&hdr,sizeof(mysql_hdr)); hdr.pkt_length=len2; memcpy((char *)dest2+sizeof(mysql_hdr),&hdr,3); queueOUT.pkt.size=destLen1+destLen2+7+7; queueOUT.pkt.ptr=l_alloc(queueOUT.pkt.size); memcpy((char *)queueOUT.pkt.ptr,dest1,destLen1+7); memcpy((char *)queueOUT.pkt.ptr+destLen1+7,dest2,destLen2+7); free(dest1); free(dest2); l_free(p2.size,p2.ptr); } }
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; }
void * l_alloc0(size_t size) { void *p=l_alloc(size); memset(p,0,size); return p; }
struct yasm *yasm_alloc(const char *pttfile) { char *tmp; size_t n; struct yasm *y; if (bug_on(!pttfile)) return NULL; y = calloc(1, sizeof(*y)); if (!y) return NULL; y->fl = fl_alloc(); if (!y->fl) goto error; y->st_asm = st_alloc(); if (!y->st_asm) goto error; y->fileroot = duplicate_str(pttfile); if (!y->fileroot) goto error; y->pttfile = duplicate_str(pttfile); if (!y->pttfile) goto error; tmp = strrchr(y->fileroot, '.'); if (tmp) *tmp = '\0'; tmp = strrchr(y->fileroot, path_separator); if (tmp) { tmp += 1; memmove(y->fileroot, tmp, strlen(tmp)+1); } y->binfile = malloc(strlen(y->fileroot)+strlen(bin_suffix)+1); if (!y->binfile) goto error; y->lstfile = malloc(strlen(y->fileroot)+strlen(lst_suffix)+1); if (!y->lstfile) goto error; n = strlen(y->fileroot); strcpy(y->binfile, y->fileroot); strcpy(y->binfile+n, bin_suffix); strcpy(y->lstfile, y->fileroot); strcpy(y->lstfile+n, lst_suffix); y->l = l_alloc(); if (!y->l) goto error; return y; error: yasm_free(y); return 0; }
void * PtrSizeArray::operator new(size_t size) { return l_alloc(size); }