## 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.24 $
       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                              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 #include <rp.h>
      33 #include <mysql_driver.h>
      34 #include <constants.h>
      35 #include "ca_configFns.h"
      36 #include "ca_dictionary.h"
      37 #include "ca_macros.h"
      38 #include "ca_srcAttribs.h"
      39 #include "ta.h"
      40
      41 static
      42 er_ret_t
      43 make_sql2pack(SQ_result_set_t *result, SQ_row_t *row,
         /* [<][>][^][v][top][bottom][index][help] */
      44               rp_upd_pack_t *pack, rp_attr_t  attr, ip_space_t space,
      45               int colcount)
      46 {
      47   er_ret_t   conv = RP_OK;
      48   rp_uni_t   *uniptr = &(pack->uni);
      49   char       *idptr; /* initially set to the 0'th column */
      50   char       *col[5];
      51   unsigned   i;
      52
      53   dieif(colcount>5); /* size of the col array */
      54
      55   for(i=0; i<colcount; i++) {
      56     col[i] = SQ_get_column_string_nocopy(result, row, i);
      57     if (col[i] == NULL) {
      58       die;
      59     }
      60   }
      61
      62   idptr = col[0];
      63
      64   pack->type = attr;
      65   pack->d.origin = NULL;
      66   switch( attr ) {
      67   case A_IN:
      68     /*
      69       read 0-2 from inetnum
      70       0 - objectid
      71       1 - begin
      72       2 - end
      73     */
      74     uniptr->space = IP_V4;
      75     conv = IP_rang_f2b_v4( &(uniptr->u.in), col[1], col[2] );
      76     break;
      77   case A_RT:
      78     /*
      79       read 0-3 from route
      80       0 - objectid
      81       1 - prefix
      82       2 - prefix_length
      83       3 - origin
      84     */
      85     uniptr->space = IP_V4;
      86     if( NOERR(conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] ))) {
      87       dieif(wr_malloc( (void **) &(pack->d.origin), strlen(col[3])+1)
      88             != UT_OK);
      89
      90       strcpy(pack->d.origin, col[3]);
      91     }
      92     break;
      93   case A_DN:
      94     if( space == IP_V4 ) {
      95     /*
      96       read 0-3 from inaddr
      97       0 - objectid
      98       1 - prefix
      99       2 - prefix_length
     100       3 - domain
     101     */
     102       conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] );
     103       uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
     104       dieif(wr_malloc( (void **) &(pack->d.domain), strlen(col[3])+1)
     105             != UT_OK);
     106       strcpy(pack->d.domain, col[3]);
     107     }
     108     else {
     109       /* read 0-4 from ip6int
     110          0 - objectid
     111          1 - msb
     112          2 - lsb
     113          3 - prefix_length
     114          4 - domain
     115     */
     116       conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3] );
     117       uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
     118
     119       dieif(wr_malloc( (void **) &(pack->d.domain), strlen(col[4])+1)
     120             != UT_OK);
     121       strcpy(pack->d.domain, col[4]);
     122     }
     123     break;
     124   case A_I6:
     125     /*
     126       read 0-3 from inaddr
     127       0 - objectid
     128       1 - msb
     129       2 - lsb
     130       3 - prefix_length
     131     */
     132     conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3]);
     133     uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
     134     break;
     135   default:
     136     /*    die; / * shouldn't have got here */
     137     conv = IP_INVARG;
     138   }
     139
     140   if( sscanf(idptr, "%lu", &(pack->key) ) < 1 ) {
     141     conv = IP_INVARG;
     142   }
     143
     144
     145   for(i=0; i<colcount; i++) {
     146     /*    wr_free(col[i]);*/ ;
     147   }
     148
     149   return conv;
     150 }
     151
     152 static
     153 er_ret_t
     154 RP_sql_load_attr_space( rp_attr_t attr, ip_space_t space,
         /* [<][>][^][v][top][bottom][index][help] */
     155                         rp_regid_t reg_id, SQ_connection_t *con
     156                         )
     157 {
     158   SQ_row_t *row;
     159   SQ_result_set_t *result;
     160   int objnr=0;
     161   rx_tree_t   *mytree;
     162   rp_upd_pack_t pack;
     163   int colcount;
     164   int sizedebug = ER_is_traced(FAC_RP, ASP_RP_LOAD_DET);
     165   char *v4 = DF_attrcode_radix_load_v4(attr);
     166   char *v6 = DF_attrcode_radix_load_v6(attr);
     167   char *vu = (space == IP_V4) ? v4 : v6;
     168   char *srcnam = ca_get_srcname(reg_id);
     169   char activity[64];
     170
     171   dieif( vu == NULL /* loading query undefined */ );
     172 #if 0
     173   if( attr==A_IN && space==IP_V4 ) {
     174     vu = "SELECT  object_id,begin_in,end_in FROM    inetnum WHERE   thread_id = 0 AND begin_in >= 3238002688 AND end_in < 3254779904 ";
     175   }
     176 #endif
     177
     178   dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
     179
     180   ER_inf_va(FAC_RP, ASP_RP_LOAD_DET, "loading using %s", vu);
     181   ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size before query = %x", sbrk(0));
     182
     183   sprintf(activity, "%s/%s, query ", srcnam, DF_get_attribute_code(attr));
     184   TA_setactivity(activity);
     185   TA_increment();
     186
     187   if ( SQ_execute_query(con, vu, &result) == -1 ) {
     188     fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
     189     die;
     190   }
     191   else {
     192     colcount = SQ_get_column_count(result);
     193
     194     ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET,
     195               "size after query = %x; columns = %d", sbrk(0), colcount);
     196
     197     /* LOCKED when created, so no need to acquire lock here */
     198
     199     while ( (row = SQ_row_next(result)) != NULL
     200             && SQ_errno(con) == 0 ) {
     201
     202       dieif( ! NOERR(make_sql2pack(result, row, &pack, attr, space,
     203                                    colcount)) );
     204
     205       if( ! NOERR(RP_pack_node_l(RX_OPER_CRE, &pack, mytree))) {
     206         fprintf(stderr,"%d:\t%ld\n", objnr, pack.key);
     207         die;
     208       }
     209
     210       /* free allocated memory */
     211       if( pack.d.origin != NULL ) {
     212         wr_free(pack.d.origin);
     213         pack.d.origin = NULL;
     214       }
     215
     216       objnr++;
     217
     218       if( sizedebug ) {
     219         ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size after object %d = %x",
     220                   objnr, sbrk(0));
     221       }
     222
     223       if( objnr % 1000 == 0 ) {
     224
     225           sprintf(activity, "%s/%s, %d done ",
     226                   srcnam, DF_get_attribute_code(attr), objnr);
     227           TA_setactivity(activity);
     228       }
     229     }
     230     /* XXX UNLOCK */
     231     TH_release_write_lockw( &(mytree->rwlock) );
     232   }
     233
     234   if( SQ_errno(con) == 0 ) {
     235       SQ_free_result(result);
     236   } else {
     237       die;
     238   }
     239
     240   ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN, "loaded %d objects into %s", objnr,
     241             DF_get_attribute_code(attr) );
     242
     243   wr_free(srcnam);
     244   return RP_OK;
     245 }
     246
     247 er_ret_t
     248 RP_sql_load_reg(rp_regid_t reg_id)
         /* [<][>][^][v][top][bottom][index][help] */
     249 {
     250
     251   er_ret_t err;
     252   SQ_connection_t *con;
     253   char *dbhost = ca_get_srcdbmachine(reg_id);
     254   char *dbname = ca_get_srcdbname(reg_id);
     255   char *dbuser = ca_get_srcdbuser(reg_id);
     256   char *dbpass = ca_get_srcdbpassword(reg_id);
     257   char *srcnam = ca_get_srcname(reg_id);
     258   unsigned dbport = ca_get_srcdbport(reg_id);
     259
     260   TA_add( 0, "rx load");
     261
     262   con = SQ_get_connection( dbhost, dbport, dbname, dbuser, dbpass );
     263
     264   dieif ( SQ_execute_query(con, "LOCK TABLES     "
     265      "route READ, inetnum READ, inet6num READ,   "
     266      "inaddr_arpa READ, domain READ, ip6int READ ",
     267                            NULL) == -1 );
     268
     269   do {
     270     if( !NOERR(err=RP_sql_load_attr_space( A_RT, IP_V4, reg_id, con))) {
     271       break;
     272     }
     273     if( !NOERR(err=RP_sql_load_attr_space( A_IN, IP_V4, reg_id, con))) {
     274       break;
     275     }
     276     if( !NOERR(err=RP_sql_load_attr_space( A_I6, IP_V6, reg_id, con))) {
     277       break;
     278     }
     279     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V4, reg_id, con))) {
     280       break;
     281     }
     282     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V6, reg_id, con))) {
     283       break;
     284     }
     285     /* CONSTCOND */
     286   } while(0);
     287
     288   dieif ( SQ_execute_query(con, "UNLOCK TABLES", NULL) == -1 );
     289
     290   /* Close connection */
     291   SQ_close_connection(con);
     292
     293   TA_delete();
     294
     295   /* free junk */
     296   wr_free(dbhost);
     297   wr_free(dbname);
     298   wr_free(dbuser);
     299   wr_free(dbpass);
     300   wr_free(srcnam);
     301   return err;
     302 }
     303
     304
     305 /*
     306    load the tree from an ascii file (short attr names).
     307    mainly for testing...
     308 */
     309 er_ret_t
     310 RP_asc_load(char *filename, int maxobj, int operation,
         /* [<][>][^][v][top][bottom][index][help] */
     311             rp_regid_t reg_id)
     312 {
     313   er_ret_t err;
     314   FILE *fp;
     315   char buf[1024];
     316   char fulltext[65536];
     317   int objnr = 0;
     318   unsigned len, oldlen=0, ranlen;
     319   char rangstr[IP_RANGSTR_MAX];
     320   int parsed = 0;
     321   int eor; /* end of record */
     322
     323
     324   if( (fp = fopen(filename,"r")) == NULL ) {
     325     perror(filename);
     326     die;
     327   }
     328
     329   do {
     330     fgets(buf, 128, fp);
     331
     332     eor = ( strlen(buf) <= 1 || feof(fp) );
     333
     334     if( strlen(buf) > 1 ) {
     335       len = strlen(buf);
     336       dieif( oldlen+len+1 > 65536 ); /* object too long */
     337       memcpy( fulltext+oldlen, buf, len);
     338       oldlen+=len;
     339
     340       fulltext[oldlen]=0;
     341     }
     342
     343     if( eor ) {              /* end of object: put into the database. */
     344       parsed++;
     345
     346       /* see if it was just some whitespace junk and nothing more */
     347       if( *fulltext==0 ) {
     348         continue;  /* discard */
     349       }
     350
     351       /* check if it's a radix object */
     352       do {
     353         char attrname[3];
     354         A_Type_t attrcode;
     355
     356         if( fulltext[0] == '*' &&  fulltext[3] == ':' ) {
     357           strncpy(attrname, fulltext+1, 2);
     358           attrname[2]=0;
     359
     360           if(strcmp(attrname, "XX") == 0 ) {
     361             /* object deleted */
     362             break;
     363           }
     364
     365           if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
     366             fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
     367             break;
     368           }
     369
     370           if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
     371             /* no interest to radix */
     372             break;
     373           }
     374
     375           /* copy and translate the range */
     376           ranlen = index(fulltext+5,'\n')-fulltext-5;
     377           strncpy(rangstr, fulltext+5, ranlen);
     378           rangstr[ranlen]=0;
     379
     380           if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,
     381                                     fulltext, strlen(fulltext)+1, 0L )) ) {
     382             objnr++;
     383           }
     384           else {
     385             die; /* error putting into the radix tree */
     386             return err;
     387           }
     388
     389         }
     390         /* CONSTCOND */
     391       } while(0);
     392
     393       *fulltext=0;
     394       oldlen=0;
     395     }
     396   }
     397   while(!feof(fp) && objnr<maxobj);
     398
     399   return RP_OK;
     400 }

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