modules/rp/rp_load.c

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

DEFINITIONS

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.28 $
   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,2002               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 #ifndef NO_A_I6
 268     if( !NOERR(err=RP_sql_load_attr_space( A_I6, IP_V6, reg_id, con))) {
 269       break;
 270     }
 271 #endif
 272 #ifndef NO_A_DN
 273     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V4, reg_id, con))) {
 274       break;
 275     }
 276     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V6, reg_id, con))) {
 277       break;
 278     }
 279 #endif
 280     /* CONSTCOND */
 281   } while(0);
 282 
 283   dieif ( SQ_execute_query(con, "UNLOCK TABLES", NULL) == -1 );
 284 
 285   /* Close connection */
 286   SQ_close_connection(con);
 287 
 288   TA_delete();
 289 
 290   /* free junk */
 291   UT_free(dbhost);
 292   UT_free(dbname);
 293   UT_free(dbuser);
 294   UT_free(dbpass);
 295   UT_free(srcnam);
 296   return err;
 297 }
 298 
 299 
 300 /* 
 301    load the tree from an ascii file (short attr names).
 302    mainly for testing... 
 303 */
 304 er_ret_t
 305 RP_asc_load(char *filename, int maxobj, int operation, 
     /* [<][>][^][v][top][bottom][index][help] */
 306             rp_regid_t reg_id)
 307 {
 308   er_ret_t err;
 309   FILE *fp;
 310   char buf[1024];
 311   char fulltext[65536];
 312   int objnr = 0;
 313   unsigned len, oldlen=0, ranlen;
 314   char rangstr[IP_RANGSTR_MAX];
 315   int parsed = 0;
 316   int eor; /* end of record */
 317 
 318   
 319   if( (fp = fopen(filename,"r")) == NULL ) {
 320     perror(filename);
 321     die; 
 322   }
 323  
 324   do {
 325     fgets(buf, 128, fp);
 326 
 327     eor = ( strlen(buf) <= 1 || feof(fp) );
 328       
 329     if( strlen(buf) > 1 ) {
 330       len = strlen(buf);
 331       dieif( oldlen+len+1 > 65536 ); /* object too long */
 332       memcpy( fulltext+oldlen, buf, len);
 333       oldlen+=len;
 334       
 335       fulltext[oldlen]=0;
 336     }
 337     
 338     if( eor ) {              /* end of object: put into the database. */
 339       parsed++;
 340       
 341       /* see if it was just some whitespace junk and nothing more */
 342       if( *fulltext==0 ) {
 343         continue;  /* discard */
 344       }
 345 
 346       /* check if it's a radix object */
 347       do {
 348         char attrname[3];
 349         A_Type_t attrcode;
 350         
 351         if( fulltext[0] == '*' &&  fulltext[3] == ':' ) {
 352           strncpy(attrname, fulltext+1, 2);
 353           attrname[2]=0;
 354           
 355           if(strcmp(attrname, "XX") == 0 ) {
 356             /* object deleted */
 357             break;
 358           }
 359           
 360           if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
 361             fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
 362             break;
 363           }
 364           
 365           if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
 366             /* no interest to radix */
 367             break;
 368           }
 369         
 370           /* copy and translate the range */
 371           ranlen = index(fulltext+5,'\n')-fulltext-5;
 372           strncpy(rangstr, fulltext+5, ranlen);
 373           rangstr[ranlen]=0;
 374                
 375           if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,  
 376                                     fulltext, strlen(fulltext)+1, 0L )) ) {
 377             objnr++;
 378           }
 379           else {
 380             die; /* error putting into the radix tree */
 381             return err;
 382           }
 383           
 384         }
 385         /* CONSTCOND */
 386       } while(0);
 387       
 388       *fulltext=0;
 389       oldlen=0;
 390     }
 391   }
 392   while(!feof(fp) && objnr<maxobj);  
 393 
 394   return RP_OK;
 395 }

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