tests/rx/rx_test.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- CO_get_query_logging
- CO_get_query_logfile
- put_inet_sql
- put_route_sql
- put_inetnums
- put_prefixes
- main
#include <rxroutines.h>
#include <iproutines.h>
#include <stdio.h>
#include <memwrap.h>
#include <numconv.h>
#include "mysql_driver.h"
#define RIPE_REG 17
#define MY_TREE_FAM RX_FAM_IN
#define STR_L 1023
#define HOST "rowan.ripe.net"
#define DATABASE_PORT 3306
#define DATABASE "RIPE"
#define USER "dbint"
#define PASSWD "reimp"
#define QUERY_IN "select * from inetnum where in_id > "
#define QUERY_RT "select * from route where rt_id > "
int Query_logging=0;
char *Query_logfile="stdout";
int CO_get_query_logging() {
/* [<][>][^][v][top][bottom][index][help] */
return Query_logging;
} /* CO_get_query_logging() */
char *CO_get_query_logfile() {
/* [<][>][^][v][top][bottom][index][help] */
return Query_logfile;
} /* CO_get_query_logfile() */
void put_inet_sql(rx_tree_t *mytree, char * startobj, int maxobj )
/* [<][>][^][v][top][bottom][index][help] */
{
SQ_row_t *row;
int retrieved_objects=0;
SQ_connection_t *con;
SQ_result_set_t *result;
int objnr=1;
int brk=0;
char qry[1024];
/* Make connection */
con = SQ_get_connection(HOST, DATABASE_PORT, DATABASE, USER, PASSWD);
// compose the query
strcpy(qry, QUERY_IN);
strcat(qry, startobj);
fprintf(stderr,"the query is: \n%s\n", qry);
result = SQ_execute_query(con, qry);
if (result == NULL) {
fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
}
else {
while ( (row = SQ_row_next(result)) != NULL
&& objnr<=maxobj) {
ip_range_t myrang;
rx_dataleaf_t *leafptr;
unsigned in_id;
char *col[4];
int i;
memset(&myrang, 0, sizeof(ip_range_t));
myrang.begin.space = myrang.end.space = IP_V4;
for(i=0; i<4; i++) {
col[i] = SQ_get_column_string( row, i);
if (col[i] == NULL) {
die;
}
}
// get the data: range and payload (id and netname)
// begin of range
// if( sscanf(col[1], "%u", &myrang.begin.words[0] ) < 1 ) {
if( ut_dec_2_uns(col[1], &myrang.begin.words[0] ) < 0 ) {
die;
}
free(col[1]);
// end of range
// if( sscanf(col[2], "%u", &myrang.end.words[0] ) < 1 ) {
if( ut_dec_2_uns(col[2], &myrang.end.words[0] ) < 0 ) {
die;
}
free(col[2]);
// payload
if( wr_calloc( (void **)& leafptr, sizeof(rx_dataleaf_t), 1)
!= UT_OK) {
die;
}
// fulltext id
// if( sscanf(col[0], "%u", &in_id ) < 1 ) {
if( ut_dec_2_uns(col[0], &in_id ) < 0 ) {
die;
}
free(col[0]);
leafptr->data_key = in_id;
// netname - already allocated in SQ_get_column_string,
// just save the pointer
leafptr->data_ptr = col[3];
leafptr->data_len = strlen(col[3])+1;
if( RX_inum_node( RX_OPER_CRE, &myrang, mytree, leafptr ) != RX_OK ) {
fprintf(stderr,"%d:\t%d\t%s\n", objnr, in_id, col[3]);
die;
}
objnr++;
}
}
SQ_free_result(result);
/* Close connection */
SQ_close_connection(con);
}
void put_route_sql(rx_tree_t *mytree, char * startobj, int maxobj )
/* [<][>][^][v][top][bottom][index][help] */
{
SQ_row_t *row;
int retrieved_objects=0;
SQ_connection_t *con;
SQ_result_set_t *result;
int objnr=1;
int brk=0;
char qry[1024];
/* Make connection */
con = SQ_get_connection(HOST, DATABASE_PORT, DATABASE, USER, PASSWD);
// compose the query
strcpy(qry, QUERY_RT);
strcat(qry, startobj);
fprintf(stderr,"the query is: \n%s\n", qry);
result = SQ_execute_query(con, qry);
if (result == NULL) {
fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
}
else {
while ( (row = SQ_row_next(result)) != NULL
&& objnr<=maxobj) {
ip_prefix_t mypref;
rx_dataleaf_t *leafptr;
int rt_id;
char *col[4];
int i;
memset(&mypref, 0, sizeof(ip_prefix_t));
mypref.ip.space = IP_V4;
for(i=0; i<4; i++) {
col[i] = SQ_get_column_string( row, i);
if (col[i] == NULL) {
die;
}
}
// get the data: prefix and payload (id and origin)
// prefix ip
if( sscanf(col[1], "%u", &mypref.ip.words[0] ) < 1 ) {
die;
}
free(col[1]);
// prefix length
if( sscanf(col[2], "%u", &mypref.bits ) < 1 ) {
die;
}
free(col[2]);
// payload: goes into a dataleaf
if( wr_calloc( (void **)& leafptr, sizeof(rx_dataleaf_t), 1)
!= UT_OK) {
die;
}
// fulltext id
if( sscanf(col[0], "%u", &rt_id ) < 1 ) {
die;
}
free(col[0]);
leafptr->data_key = rt_id;
// origin - already allocated in SQ_get_column_string,
// just save the pointer
leafptr->data_ptr = col[3];
leafptr->data_len = strlen(col[3])+1;
if( RX_bin_node( RX_OPER_CRE, &mypref, mytree, leafptr ) != RX_OK ) {
fprintf(stderr,"%d:\t%d\t%s\n", objnr, rt_id, col[3]);
die;
}
objnr++;
}
}
SQ_free_result(result);
/* Close connection */
SQ_close_connection(con);
}
void put_inetnums(rx_tree_t *mytree, FILE *fp, int maxobj)
/* [<][>][^][v][top][bottom][index][help] */
{
char buf[1024];
char *fulltext=NULL;
int objnr = 0;
int len, oldlen=0;
int cnt;
int ranlen;
char rangstr[IP_RANGSTR_MAX];
rx_dataleaf_t *leafptr;
er_ret_t err;
while(!feof(fp) && objnr<maxobj) {
fgets(buf, 128, fp);
if(strlen(buf)>1) {
len = strlen(buf);
if( wr_realloc( (void **)& fulltext, fulltext, len+oldlen + 1)
!= UT_OK) {
die;
}
memcpy( fulltext+oldlen, buf, len);
oldlen+=len;
fulltext[oldlen]=0;
}
else {
// end of object: put into the database.
// see if it was just some whitespace junk and nothing more
if( fulltext==NULL ) {
continue; // discard
}
// but check if it's an object first :)
if( strncmp(fulltext, "*in: ", 5) != 0 ) {
fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
wr_free(fulltext);
}
else {
int rang_ok;
// copy and translate the range
ranlen = index(fulltext+5,'\n')-fulltext-5;
strncpy(rangstr, fulltext+5, ranlen);
rangstr[ranlen]=0;
if (RX_asc_node( RX_OPER_CRE, rangstr,
RIPE_REG, IP_V4, MY_TREE_FAM, fulltext ) == RX_OK ) {
objnr++;
}
else {
die; // error putting into the radix tree
}
}
fulltext=NULL;
oldlen=0;
}
}
}
void put_prefixes(rx_tree_t *mytree, FILE *fp, int maxobj)
/* [<][>][^][v][top][bottom][index][help] */
{
char buf[1024];
char *fulltext=NULL;
int objnr = 0;
int len, oldlen=0;
int preflen;
char pref[IP_PREFSTR_MAX];
ip_prefix_t mypref;
rx_dataleaf_t *leafptr;
while(!feof(fp) && objnr<maxobj) {
fgets(buf, 128, fp);
if(strlen(buf)>1) {
len = strlen(buf);
if( wr_realloc( (void **)& fulltext, fulltext, len+oldlen + 1)
!= UT_OK) {
die;
}
memcpy( fulltext+oldlen, buf, len);
oldlen+=len;
fulltext[oldlen]=0;
}
else {
// end of object: put into the database.
// see if it was just some whitespace junk and nothing more
if( fulltext==NULL ) {
continue; // discard
}
// but check if it's an object first :)
if( strncmp(fulltext, "*rt: ", 5) != 0 ) {
fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
wr_free(fulltext);
}
else {
// copy and translate the prefix
preflen = index(fulltext+5,'\n')-fulltext-5;
strncpy(pref, fulltext+5, preflen);
pref[preflen]=0;
if( RX_asc_node( RX_OPER_CRE, pref,
RIPE_REG, IP_V4, MY_TREE_FAM, fulltext ) == RX_OK ) {
objnr++;
}
}
fulltext=NULL;
oldlen=0;
}
}
}
int main(int argc, char **argv)
/* [<][>][^][v][top][bottom][index][help] */
{
ip_prefix_t mypref;
rx_tree_t *mytree;
ip_prefix_t *querypref;
GList *datlist, *qitem, *preflist;
int maxline=0;
char buf[1024];
er_path_t erlogstr;
FILE *fp;
int i, par_a, par_b=0, search_mode;
char pref[IP_PREFSTR_MAX];
er_ret_t err;
int cnt;
char *key;
ER_init(argc, argv);
erlogstr.fdes = stderr;
erlogstr.asp = 0;
erlogstr.sev = ER_SEV_W;
erlogstr.mode = ER_M_SEVCHAR | ER_M_TEXTLONG ;
ER_setpath(& erlogstr);
puts("creating a tree...");
IP_pref_e2b(&mypref, "0.0.0.0/0");
if (RX_space_cre(RIPE_REG, IP_V4, MY_TREE_FAM, "0.0.0.0/0",
RX_MEM_RAMONLY, RX_SUB_NONE) != RX_OK)
puts("error!!!");
rx_space_list();
fputs("-----------------------------------------------------------------\n",
stderr);
if( RX_get_tree ( &mytree, RIPE_REG, IP_V4, MY_TREE_FAM) != RX_OK ) {
die;
}
#if 0
if( argc<3 ) {
fputs("arguments: number_of_lines filename", stderr);
die;
} else {
maxline = atoi(argv[1]);
if( (fp = fopen(argv[2],"r")) == NULL ) {
perror(argv[0]);
die;
}
else
{
put_inetnums(mytree, fp, maxline);
// put_prefixes(mytree, fp, maxline);
}
}
#else
if( argc!=3 ) {
fputs("arguments: startobj number_of_lines", stderr);
die;
} else {
maxline = atoi(argv[2]);
put_inet_sql(mytree, argv[1], maxline);
}
#endif
rx_space_list();
// consistency check
if( mytree->num_nodes > 0 ) {
fprintf(stderr, "tree consistency check: ");
cnt = rx_walk_tree(mytree->top_ptr, NULL, RX_WALK_CNTGLU,
255, 0, 0, NULL, &err);
if( cnt != mytree->num_nodes ) {
fprintf(stderr,
" %d nodes instead of %d found\n",
cnt, mytree->num_nodes);
}
else {
fprintf(stderr, "OK\n");
}
}
// exit(0);
// rx_tree_print( mytree );
// change the loglevel
erlogstr.asp = ASP_RX_SRCH_DET | ASP_RX_STKBLD_DET;
ER_setpath(& erlogstr);
// search
while(!feof(stdin)) {
printf("\nsearch> ");
fgets(buf, 128, stdin);
par_a=1;
key = buf;
if( *key == '\0' ) {
continue;
}
// chop \n
*index(buf,'\n') = '\0';
if( strcmp(key, "exit") == 0 ) {
exit(0);
}
if( strncmp(key, "show ", 5) == 0 ) {
int depth;
extern er_ret_t rx_walk_hook_printnode();
key+=5;
/* tree inspection */
if( strncmp(key, "tree", 4) == 0 ) {
// show tree <n>, default n = 255
key+=4;
if( sscanf(key, "%d", &depth) < 1 ) {
depth = 255;
}
rx_walk_tree(mytree->top_ptr, rx_walk_hook_printnode,
RX_WALK_CNTGLU, // print also glue nodes
depth, 0, 0, NULL, &err);
/* err will be handled below */
printf("got status %x\n", err);
ER_perror(FAC_RX, err);
continue;
}
}
else {
/* ordinary query */
/* take switches */
if( *key=='-' ) {
switch( *(++key) ) {
case 'd':
search_mode = RX_SRCH_EXLESS; // default
break;
case 'e':
search_mode = RX_SRCH_EXACT;
break;
case 'm':
search_mode = RX_SRCH_MORE;
key++;
if( ! isdigit( *key ) ) {
puts("invalid syntax");
continue;
} else {
sscanf( key, "%d", &par_a);
}
break;
case 'l':
search_mode = RX_SRCH_LESS;
key++;
if( ! isdigit( *key ) ) {
puts("invalid syntax");
continue;
} else {
sscanf( key, "%d", &par_a);
}
break;
case 'r':
search_mode = RX_SRCH_RANG;
key++;
if( ! isdigit( *key ) ) {
puts("invalid syntax");
continue;
}
else {
sscanf( key, "%d", &par_a);
}
break;
case 's':
search_mode = RX_SRCH_DBLS;
key++;
if( ! isdigit( *key ) ) {
puts("invalid syntax");
continue;
} else {
sscanf( key, "%d", &par_a);
}
break;
}
if( (key=index(buf, ' ')) == NULL ) {
// empty query
continue;
}
else {
key++;
}
}
else {
search_mode = RX_SRCH_EXLESS; // default search mode
}
// zero the datlist (the one for answers).
datlist = NULL;
err = RX_asc_search(search_mode, par_a, par_b, key,
RIPE_REG, IP_V4, MY_TREE_FAM, &datlist, RX_ANS_ALL);
}
printf("got status %x\n", err);
ER_perror(FAC_RX, err);
switch( err ) {
case RX_OK:
puts("### answers:");
for(i=0; i<g_list_length(datlist); i++) {
rx_datcpy_t *datcpy = g_list_nth_data(datlist, i);
char rangstr[IP_RANGSTR_MAX];
if( MY_TREE_FAM == RX_FAM_IN ) {
if(IP_rang_b2a( &(datcpy->leafcpy.iprange), rangstr, IP_RANGSTR_MAX)
!= IP_OK ) {
die;
}
if( datcpy->leafcpy.composed ) {
strcat(rangstr, " \tc");
}
} else {
rangstr[0] = '\0';
}
printf("\n%d: [%u]\t%s\n%s",i, datcpy->leafcpy.data_key,
rangstr, (char *) datcpy->leafcpy.data_ptr );
wr_free(datcpy->leafcpy.data_ptr );
}
g_list_foreach(datlist, rx_free_list_element, NULL);
g_list_free(datlist);
break;
case IP_INVARG:
fputs("conversion error", stderr);
break;
default:
die;
}
}
return 0;
}