modules/rp/rp_load.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. make_sql2pack
  2. RP_sql_load_attr_space
  3. RP_sql_load_reg
  4. RP_asc_load

   1 /***************************************
   2   $Revision: 1.26 $
   3 
   4   Radix payload (rp) - user level functions for storing data in radix trees
   5 
   6   rp_load = loading the radix trees with data on startup
   7 
   8   Status: NOT REVIEWED, TESTED
   9   
  10   Design and implementation by: Marek Bukowy
  11   
  12   ******************/ /******************
  13   Copyright (c) 1999,2000,2001                    RIPE NCC
  14  
  15   All Rights Reserved
  16   
  17   Permission to use, copy, modify, and distribute this software and its
  18   documentation for any purpose and without fee is hereby granted,
  19   provided that the above copyright notice appear in all copies and that
  20   both that copyright notice and this permission notice appear in
  21   supporting documentation, and that the name of the author not be
  22   used in advertising or publicity pertaining to distribution of the
  23   software without specific, written prior permission.
  24   
  25   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  26   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  27   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  28   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  29   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  30   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  31   ***************************************/
  32 
  33 #include "rip.h"
  34 
  35 static
  36 er_ret_t
  37 make_sql2pack(SQ_result_set_t *result, SQ_row_t *row, 
     /* [<][>][^][v][top][bottom][index][help] */
  38               rp_upd_pack_t *pack, rp_attr_t  attr, ip_space_t space, 
  39               int colcount)
  40 {
  41   er_ret_t   conv = RP_OK;
  42   rp_uni_t   *uniptr = &(pack->uni);
  43   char       *idptr; /* initially set to the 0'th column */
  44   char       *col[5];
  45   unsigned   i;
  46 
  47   dieif(colcount>5); /* size of the col array */
  48 
  49   for(i=0; i<colcount; i++) {
  50     col[i] = SQ_get_column_string_nocopy(result, row, i);
  51     if (col[i] == NULL) {
  52       die;
  53     }
  54   }
  55 
  56   idptr = col[0];
  57 
  58   pack->type = attr;
  59   pack->d.origin = NULL;
  60   switch( attr ) {
  61   case A_IN:
  62     /*
  63       read 0-2 from inetnum
  64       0 - objectid
  65       1 - begin   
  66       2 - end     
  67     */
  68     uniptr->space = IP_V4;
  69     conv = IP_rang_f2b_v4( &(uniptr->u.in), col[1], col[2] );
  70     break;
  71   case A_RT:
  72     /*
  73       read 0-3 from route
  74       0 - objectid 
  75       1 - prefix    
  76       2 - prefix_length   
  77       3 - origin
  78     */
  79     uniptr->space = IP_V4;
  80     if( NOERR(conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] ))) {
  81       pack->d.origin = UT_strdup(col[3]);
  82     }
  83     break;
  84   case A_DN:
  85     if( space == IP_V4 ) {
  86     /*
  87       read 0-3 from inaddr
  88       0 - objectid 
  89       1 - prefix
  90       2 - prefix_length   
  91       3 - domain
  92     */
  93       conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] );
  94       uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
  95       pack->d.domain = UT_strdup(col[3]);
  96     }
  97     else {
  98       /* read 0-4 from ip6int
  99          0 - objectid 
 100          1 - msb
 101          2 - lsb
 102          3 - prefix_length 
 103          4 - domain
 104     */
 105       conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3] );
 106       uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
 107     
 108       pack->d.domain = UT_strdup(col[4]);
 109     }
 110     break;
 111   case A_I6: 
 112     /*
 113       read 0-3 from inaddr
 114       0 - objectid 
 115       1 - msb
 116       2 - lsb
 117       3 - prefix_length 
 118     */
 119     conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3]);
 120     uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
 121     break;
 122   default:
 123     /*    die; / * shouldn't have got here */
 124     conv = IP_INVARG;
 125   }
 126   
 127   if( sscanf(idptr, "%lu", &(pack->key) ) < 1 ) {
 128     conv = IP_INVARG;
 129   }
 130   
 131 
 132   for(i=0; i<colcount; i++) {
 133     /*    wr_free(col[i]);*/ ;
 134   }
 135   
 136   return conv;
 137 }
 138 
 139 static
 140 er_ret_t
 141 RP_sql_load_attr_space( rp_attr_t attr, ip_space_t space, 
     /* [<][>][^][v][top][bottom][index][help] */
 142                         rp_regid_t reg_id, SQ_connection_t *con
 143                         )
 144 {
 145   SQ_row_t *row;
 146   SQ_result_set_t *result;
 147   int objnr=0;
 148   rx_tree_t   *mytree;
 149   rp_upd_pack_t pack;
 150   int colcount;
 151   int sizedebug = ER_is_traced(FAC_RP, ASP_RP_LOAD_DET);
 152   char *v4 = DF_attrcode_radix_load_v4(attr);
 153   char *v6 = DF_attrcode_radix_load_v6(attr);
 154   char *vu = (space == IP_V4) ? v4 : v6;
 155   char *srcnam = ca_get_srcname(reg_id);
 156   const char *attr_code;
 157   char *activity;
 158 
 159   dieif( vu == NULL /* loading query undefined */ );
 160 #if 0
 161   if( attr==A_IN && space==IP_V4 ) {
 162     vu = "SELECT  object_id,begin_in,end_in FROM    inetnum WHERE   thread_id = 0 AND begin_in >= 3238002688 AND end_in < 3254779904 ";
 163   }
 164 #endif
 165 
 166   dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
 167  
 168   ER_inf_va(FAC_RP, ASP_RP_LOAD_DET, "loading using %s", vu);
 169   ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size before query = %x", sbrk(0));
 170   
 171   attr_code = DF_get_attribute_code(attr);
 172   activity = UT_malloc(strlen(srcnam) + strlen(attr_code) + 32);
 173   sprintf(activity, "%s/%s, query ", srcnam, attr_code);
 174   TA_setactivity(activity);
 175   TA_increment();
 176 
 177   if ( SQ_execute_query(con, vu, &result) == -1 ) { 
 178     fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
 179     die;
 180   }
 181   else { 
 182     colcount = SQ_get_column_count(result);
 183     
 184     ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, 
 185               "size after query = %x; columns = %d", sbrk(0), colcount);
 186     
 187     /* LOCKED when created, so no need to acquire lock here */
 188     
 189     while ( (row = SQ_row_next(result)) != NULL 
 190             && SQ_errno(con) == 0 ) {
 191       
 192       dieif( ! NOERR(make_sql2pack(result, row, &pack, attr, space, 
 193                                    colcount)) );
 194       
 195       if( ! NOERR(RP_pack_node_l(RX_OPER_CRE, &pack, mytree))) {
 196         fprintf(stderr,"%d:\t%ld\n", objnr, pack.key);
 197         die;
 198       }
 199       
 200       /* free allocated memory */
 201       if( pack.d.origin != NULL ) {
 202         UT_free(pack.d.origin);
 203         pack.d.origin = NULL;
 204       }
 205       
 206       objnr++;
 207       
 208       if( sizedebug ) {
 209         ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size after object %d = %x", 
 210                   objnr, sbrk(0));
 211       }
 212       
 213       if( objnr % 1000 == 0 ) {
 214 
 215           sprintf(activity, "%s/%s, %d done ", 
 216                   srcnam, attr_code, objnr);
 217           TA_setactivity(activity);
 218       }
 219     }
 220     /* XXX UNLOCK */
 221     TH_release_write_lockw( &(mytree->rwlock) );
 222   }
 223 
 224   if( SQ_errno(con) == 0 ) {
 225       SQ_free_result(result);
 226   } else {
 227       die;
 228   }
 229 
 230   ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN, "loaded %d objects into %s", objnr,
 231             DF_get_attribute_code(attr) );
 232  
 233   UT_free(activity);
 234   UT_free(srcnam);
 235   return RP_OK;
 236 }
 237 
 238 er_ret_t
 239 RP_sql_load_reg(rp_regid_t reg_id) 
     /* [<][>][^][v][top][bottom][index][help] */
 240 {
 241   
 242   er_ret_t err;
 243   SQ_connection_t *con;
 244   char *dbhost = ca_get_srcdbmachine(reg_id);
 245   char *dbname = ca_get_srcdbname(reg_id);
 246   char *dbuser = ca_get_srcdbuser(reg_id);
 247   char *dbpass = ca_get_srcdbpassword(reg_id);
 248   char *srcnam = ca_get_srcname(reg_id);
 249   unsigned dbport = ca_get_srcdbport(reg_id);
 250 
 251   TA_add( 0, "rx load");
 252 
 253   con = SQ_get_connection( dbhost, dbport, dbname, dbuser, dbpass );
 254 
 255   dieif ( SQ_execute_query(con, "LOCK TABLES     " 
 256      "route READ, inetnum READ, inet6num READ,   "
 257      "inaddr_arpa READ, domain READ, ip6int READ ",
 258                            NULL) == -1 );
 259 
 260   do {
 261     if( !NOERR(err=RP_sql_load_attr_space( A_RT, IP_V4, reg_id, con))) {
 262       break;
 263     }
 264     if( !NOERR(err=RP_sql_load_attr_space( A_IN, IP_V4, reg_id, con))) {
 265       break;
 266     }
 267     if( !NOERR(err=RP_sql_load_attr_space( A_I6, IP_V6, reg_id, con))) {
 268       break;
 269     }
 270     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V4, reg_id, con))) {
 271       break;
 272     }
 273     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V6, reg_id, con))) {
 274       break;
 275     }
 276     /* CONSTCOND */
 277   } while(0);
 278 
 279   dieif ( SQ_execute_query(con, "UNLOCK TABLES", NULL) == -1 );
 280 
 281   /* Close connection */
 282   SQ_close_connection(con);
 283 
 284   TA_delete();
 285 
 286   /* free junk */
 287   UT_free(dbhost);
 288   UT_free(dbname);
 289   UT_free(dbuser);
 290   UT_free(dbpass);
 291   UT_free(srcnam);
 292   return err;
 293 }
 294 
 295 
 296 /* 
 297    load the tree from an ascii file (short attr names).
 298    mainly for testing... 
 299 */
 300 er_ret_t
 301 RP_asc_load(char *filename, int maxobj, int operation, 
     /* [<][>][^][v][top][bottom][index][help] */
 302             rp_regid_t reg_id)
 303 {
 304   er_ret_t err;
 305   FILE *fp;
 306   char buf[1024];
 307   char fulltext[65536];
 308   int objnr = 0;
 309   unsigned len, oldlen=0, ranlen;
 310   char rangstr[IP_RANGSTR_MAX];
 311   int parsed = 0;
 312   int eor; /* end of record */
 313 
 314   
 315   if( (fp = fopen(filename,"r")) == NULL ) {
 316     perror(filename);
 317     die; 
 318   }
 319  
 320   do {
 321     fgets(buf, 128, fp);
 322 
 323     eor = ( strlen(buf) <= 1 || feof(fp) );
 324       
 325     if( strlen(buf) > 1 ) {
 326       len = strlen(buf);
 327       dieif( oldlen+len+1 > 65536 ); /* object too long */
 328       memcpy( fulltext+oldlen, buf, len);
 329       oldlen+=len;
 330       
 331       fulltext[oldlen]=0;
 332     }
 333     
 334     if( eor ) {              /* end of object: put into the database. */
 335       parsed++;
 336       
 337       /* see if it was just some whitespace junk and nothing more */
 338       if( *fulltext==0 ) {
 339         continue;  /* discard */
 340       }
 341 
 342       /* check if it's a radix object */
 343       do {
 344         char attrname[3];
 345         A_Type_t attrcode;
 346         
 347         if( fulltext[0] == '*' &&  fulltext[3] == ':' ) {
 348           strncpy(attrname, fulltext+1, 2);
 349           attrname[2]=0;
 350           
 351           if(strcmp(attrname, "XX") == 0 ) {
 352             /* object deleted */
 353             break;
 354           }
 355           
 356           if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
 357             fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
 358             break;
 359           }
 360           
 361           if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
 362             /* no interest to radix */
 363             break;
 364           }
 365         
 366           /* copy and translate the range */
 367           ranlen = index(fulltext+5,'\n')-fulltext-5;
 368           strncpy(rangstr, fulltext+5, ranlen);
 369           rangstr[ranlen]=0;
 370                
 371           if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,  
 372                                     fulltext, strlen(fulltext)+1, 0L )) ) {
 373             objnr++;
 374           }
 375           else {
 376             die; /* error putting into the radix tree */
 377             return err;
 378           }
 379           
 380         }
 381         /* CONSTCOND */
 382       } while(0);
 383       
 384       *fulltext=0;
 385       oldlen=0;
 386     }
 387   }
 388   while(!feof(fp) && objnr<maxobj);  
 389 
 390   return RP_OK;
 391 }

/* [<][>][^][v][top][bottom][index][help] */