Fixing errors caused by the merge with develop.

This commit is contained in:
Markus Makela 2015-03-05 11:14:12 +02:00
parent 880adca73e
commit d98dd6e15f
4 changed files with 205 additions and 230 deletions

View File

@ -619,182 +619,6 @@ modutil_count_signal_packets(GWBUF *reply, int use_ok, int n_found)
return(eof + err);
}
void resultset_free(RESULTSET* rset)
{
RSET_ROW *row,*tmp;
int i;
row = rset->head;
while(row)
{
tmp = row;
row = row->next;
for(i = 0;i<rset->columns;i++)
{
free(tmp->data[i]);
}
free(tmp);
}
free(rset);
}
char* get_lenenc_str(void* data, int* len)
{
unsigned char* ptr = data;
char* rval;
long size, offset;
if(data == NULL || len == NULL)
{
return NULL;
}
if(*ptr < 251)
{
size = *ptr;
offset = 1;
}
else
{
switch(*(ptr))
{
case 0xfb:
*len = 1;
return NULL;
case 0xfc:
size = *(ptr + 1) + (*(ptr + 2) << 8);
offset = 2;
break;
case 0xfd:
size = *ptr + (*(ptr + 2) << 8) + (*(ptr + 3) << 16);
offset = 3;
break;
case 0xfe:
size = *ptr + ((*(ptr + 2) << 8)) + (*(ptr + 3) << 16) +
(*(ptr + 4) << 24) + (*(ptr + 5) << 32) + (*(ptr + 6) << 40) +
(*(ptr + 7) << 48) + (*(ptr + 8) << 56);
offset = 8;
break;
default:
return NULL;
}
}
rval = malloc(sizeof(char)*(size+1));
if(rval)
{
memcpy(rval,ptr + offset,size);
memset(rval + size,0,1);
}
*len = size + offset;
return rval;
}
RESULTSET*
modutil_get_rows(GWBUF* buffer)
{
RESULTSET* result;
RSET_ROW* row;
int columns,plen,slen,i,offset;
unsigned char *ptr,*end;
if(buffer == NULL)
{
return NULL;
}
ptr = (unsigned char*) buffer->start;
end = (unsigned char*) buffer->end;
if(!PTR_IS_RESULTSET(ptr))
{
return NULL;
}
columns = *(ptr + 4);
if((result = calloc(1, sizeof(RESULTSET))) == NULL)
{
return NULL;
}
result->columns = columns;
while(ptr < end)
{
plen = MYSQL_GET_PACKET_LEN(ptr) + 4;
if(PTR_IS_EOF(ptr))
{
break;
}
ptr += plen;
}
ptr += plen;
while(ptr < end)
{
plen = MYSQL_GET_PACKET_LEN(ptr) + 4;
if(PTR_IS_EOF(ptr) || PTR_IS_ERR(ptr))
{
/*
* The final EOF/ERR packet was found so the result set is parsed.
*/
return result;
}
if(ptr + plen > end)
{
/*
* There is a partial packet in the buffer and this is not a complete
* result set. This is considered as an error and will cause the
* deallocation of the resultset.
*/
resultset_free(result);
result = NULL;
break;
}
if((row = calloc(1,sizeof(RSET_ROW))) == NULL)
{
resultset_free(result);
result = NULL;
break;
}
if((row->data = malloc(sizeof(char*)*columns)) == NULL)
{
free(row);
resultset_free(result);
result = NULL;
break;
}
offset = 4;
for(i = 0;i<columns;i++)
{
row->data[i] = get_lenenc_str(ptr + offset,&slen);
offset += slen;
}
row->next = result->head;
result->rows++;
result->head = row;
ptr += plen;
}
return result;
}
/**
* Create parse error and EPOLLIN event to event queue of the backend DCB.
* When event is notified the error message is processed as error reply and routed

View File

@ -41,17 +41,6 @@
#define PTR_IS_LOCAL_INFILE(b) (b[4] == 0xfb)
#define IS_FULL_RESPONSE(buf) (modutil_count_signal_packets(buf,0,0) == 2)
typedef struct rset_row_t{
char** data;
struct rset_row_t* next;
} RSET_ROW;
typedef struct rset_t{
int rows;
int columns;
RSET_ROW* head;
}RESULTSET;
extern int modutil_is_SQL(GWBUF *);
extern int modutil_is_SQL_prepare(GWBUF *);
extern int modutil_extract_SQL(GWBUF *, char **, int *);
@ -74,6 +63,5 @@ GWBUF *modutil_create_mysql_err_msg(
const char *msg);
int modutil_count_signal_packets(GWBUF*,int,int);
void resultset_free(RESULTSET* rset);
RESULTSET* modutil_get_rows(GWBUF*);
#endif

View File

@ -243,6 +243,69 @@ static int hashcmpfun(
return strcmp(i1,i2);
}
/**
* Convert a length encoded string into a C string.
* @param data Pointer to the first byte of the string
* @param len Pointer to an integer where the length of the string will be stored. On errors this will be set to -1.
* @return Pointer to the newly allocated string or NULL if the value is NULL or an error occurred
*/
char* get_lenenc_str(void* data, int* len)
{
unsigned char* ptr = (unsigned char*)data;
char* rval;
long size, offset;
if(data == NULL || len == NULL)
{
*len = -1;
return NULL;
}
if(*ptr < 251)
{
size = *ptr;
offset = 1;
}
else
{
switch(*(ptr))
{
case 0xfb:
*len = 1;
return NULL;
case 0xfc:
size = *(ptr + 1) + (*(ptr + 2) << 8);
offset = 2;
break;
case 0xfd:
size = *ptr + (*(ptr + 2) << 8) + (*(ptr + 3) << 16);
offset = 3;
break;
case 0xfe:
size = *ptr + ((*(ptr + 2) << 8)) + (*(ptr + 3) << 16) +
(*(ptr + 4) << 24) + (*(ptr + 5) << 32) + (*(ptr + 6) << 40) +
(*(ptr + 7) << 48) + (*(ptr + 8) << 56);
offset = 8;
break;
default:
return NULL;
}
}
rval = malloc(sizeof(char)*(size+1));
if(rval)
{
memcpy(rval,ptr + offset,size);
memset(rval + size,0,1);
}
*len = size + offset;
return rval;
}
/**
* Parses a response set to a SHOW DATABASES query and inserts them into the
* router client session's database hashtable. The name of the database is used
@ -256,29 +319,47 @@ static int hashcmpfun(
bool parse_showdb_response(ROUTER_CLIENT_SES* rses, char* target, GWBUF* buf)
{
bool rval = false;
RESULTSET* rset;
RSET_ROW* row;
unsigned char* ptr;
if(PTR_IS_RESULTSET(((unsigned char*)buf->start)) &&
modutil_count_signal_packets(buf,0,0) == 2)
{
rset = modutil_get_rows(buf);
if(rset && rset->columns == 1)
ptr = (unsigned char*)buf->start;
if(ptr[4] != 1)
{
row = rset->head;
while(row)
{
if(hashtable_add(rses->dbhash,row->data[0],target))
{
skygw_log_write(LOGFILE_TRACE,"schemarouter: <%s, %s>",target,row->data[0]);
}
row = row->next;
}
resultset_free(rset);
rval = true;
/** Something else came back, discard and return with an error*/
return false;
}
/** Skip column definitions */
while(!PTR_IS_EOF(ptr))
{
ptr += gw_mysql_get_byte3(ptr) + 4;
}
/** Skip first EOF packet */
ptr += gw_mysql_get_byte3(ptr) + 4;
while(!PTR_IS_EOF(ptr))
{
int payloadlen = gw_mysql_get_byte3(ptr);
int packetlen = payloadlen + 4;
int len = 0;
char* data = get_lenenc_str(ptr+4,&len);
if(data)
{
if(hashtable_add(rses->dbhash,data,target))
{
skygw_log_write(LOGFILE_TRACE,"schemarouter: <%s, %s>",target,data);
}
free(data);
}
ptr += packetlen;
}
rval = true;
}
return rval;

View File

@ -258,6 +258,69 @@ hashcmpfun(
return strcmp(i1, i2);
}
/**
* Convert a length encoded string into a C string.
* @param data Pointer to the first byte of the string
* @param len Pointer to an integer where the length of the string will be stored. On errors this will be set to -1.
* @return Pointer to the newly allocated string or NULL if the value is NULL or an error occurred
*/
char* get_lenenc_str(void* data, int* len)
{
unsigned char* ptr = (unsigned char*)data;
char* rval;
long size, offset;
if(data == NULL || len == NULL)
{
*len = -1;
return NULL;
}
if(*ptr < 251)
{
size = *ptr;
offset = 1;
}
else
{
switch(*(ptr))
{
case 0xfb:
*len = 1;
return NULL;
case 0xfc:
size = *(ptr + 1) + (*(ptr + 2) << 8);
offset = 2;
break;
case 0xfd:
size = *ptr + (*(ptr + 2) << 8) + (*(ptr + 3) << 16);
offset = 3;
break;
case 0xfe:
size = *ptr + ((*(ptr + 2) << 8)) + (*(ptr + 3) << 16) +
(*(ptr + 4) << 24) + (*(ptr + 5) << 32) + (*(ptr + 6) << 40) +
(*(ptr + 7) << 48) + (*(ptr + 8) << 56);
offset = 8;
break;
default:
return NULL;
}
}
rval = malloc(sizeof(char)*(size+1));
if(rval)
{
memcpy(rval,ptr + offset,size);
memset(rval + size,0,1);
}
*len = size + offset;
return rval;
}
/**
* Handle the result returned from a SHOW DATABASES query. Parse the result set
* and associate these databases to the service that returned them.
@ -269,32 +332,51 @@ hashcmpfun(
bool
parse_mapping_response(ROUTER_CLIENT_SES* rses, char* target, GWBUF* buf)
{
bool rval = false;
RESULTSET* rset;
RSET_ROW* row;
bool rval = false;
unsigned char* ptr;
if(PTR_IS_RESULTSET(((unsigned char*) buf->start)) && // TODO: update to handle larger response sets
modutil_count_signal_packets(buf, 0, 0) == 2)
{
rset = modutil_get_rows(buf);
if(rset && rset->columns == 1)
{
row = rset->head;
if(PTR_IS_RESULTSET(((unsigned char*)buf->start)) &&
modutil_count_signal_packets(buf,0,0) == 2)
{
ptr = (char*)buf->start;
while(row)
{
if(hashtable_add(rses->dbhash, row->data[0], target))
{
skygw_log_write(LOGFILE_TRACE,"shardrouter: <%s, %s>",target,row->data[0]);
}
row = row->next;
}
resultset_free(rset);
rval = true;
}
}
if(ptr[5] != 1)
{
/** Something else came back, discard and return with an error*/
return false;
}
return rval;
/** Skip column definitions */
while(!PTR_IS_EOF(ptr))
{
ptr += gw_mysql_get_byte3(ptr) + 4;
}
/** Skip first EOF packet */
ptr += gw_mysql_get_byte3(ptr) + 4;
while(!PTR_IS_EOF(ptr))
{
int payloadlen = gw_mysql_get_byte3(ptr);
int packetlen = payloadlen + 4;
int len = 0;
char* data = get_lenenc_str(ptr+4,&len);
if(data)
{
if(hashtable_add(rses->dbhash,data,target))
{
skygw_log_write(LOGFILE_TRACE,"shardrouter: <%s, %s>",target,data);
}
free(data);
}
ptr += packetlen;
}
rval = true;
}
return rval;
}
/**