## 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] */