## 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.20 $
       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
      36 #include "ca_configFns.h"
      37 #include "ca_dictSyms.h"
      38 #include "ca_macros.h"
      39 #include "ca_srcAttribs.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   int        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
     169   dieif( vu == NULL /* loading query undefined */ );
     170
     171   dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
     172
     173   ER_inf_va(FAC_RP, ASP_RP_LOAD_DET, "loading using %s", vu);
     174   ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size before query = %x", sbrk(0));
     175
     176   if ( SQ_execute_query(con, vu, &result) == -1 ) {
     177     fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
     178     die;
     179   }
     180   else {
     181     colcount = SQ_get_column_count(result);
     182
     183     ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET,
     184               "size after query = %x; columns = %d", sbrk(0), colcount);
     185
     186     /* LOCKED when created, so no need to acquire lock here */
     187
     188     while ( (row = SQ_row_next(result)) != NULL
     189             && SQ_errno(con) == 0 ) {
     190
     191       dieif( ! NOERR(make_sql2pack(result, row, &pack, attr, space,
     192                                    colcount)) );
     193
     194       if( ! NOERR(RP_pack_node_l(RX_OPER_CRE, &pack, mytree))) {
     195         fprintf(stderr,"%d:\t%ld\n", objnr, pack.key);
     196         die;
     197       }
     198
     199       /* free allocated memory */
     200       if( pack.d.origin != NULL ) {
     201         wr_free(pack.d.origin);
     202         pack.d.origin = NULL;
     203       }
     204
     205       objnr++;
     206
     207       if( sizedebug ) {
     208         ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size after object %d = %x",
     209                   objnr, sbrk(0));
     210       }
     211
     212     }
     213     /* XXX UNLOCK */
     214     TH_release_write_lock( &(mytree->rwlock) );
     215   }
     216
     217   if( SQ_errno(con) == 0 ) {
     218       SQ_free_result(result);
     219   } else {
     220       die;
     221   }
     222
     223   ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN, "loaded %d objects into %s", objnr,
     224             DF_get_attribute_code(attr) );
     225
     226
     227   return RP_OK;
     228 }
     229
     230 er_ret_t
     231 RP_sql_load_reg(rp_regid_t reg_id)
         /* [<][>][^][v][top][bottom][index][help] */
     232 {
     233
     234   er_ret_t err;
     235   SQ_connection_t *con;
     236   char *dbhost = ca_get_srcdbmachine(reg_id);
     237   char *dbname = ca_get_srcdbname(reg_id);
     238   char *dbuser = ca_get_srcdbuser(reg_id);
     239   char *dbpass = ca_get_srcdbpassword(reg_id);
     240   char *srcnam = ca_get_srcname(reg_id);
     241
     242   con = SQ_get_connection( dbhost, ca_get_srcdbport(reg_id),
     243                                       dbname, dbuser, dbpass );
     244
     245   dieif ( SQ_execute_query(con, "LOCK TABLES     "
     246      "route READ, inetnum READ, inet6num READ,   "
     247      "inaddr_arpa READ, domain READ, ip6int READ ",
     248                            NULL) == -1 );
     249
     250   do {
     251     if( !NOERR(err=RP_sql_load_attr_space( A_RT, IP_V4, reg_id, con))) {
     252       break;
     253     }
     254     if( !NOERR(err=RP_sql_load_attr_space( A_IN, IP_V4, reg_id, con))) {
     255       break;
     256     }
     257     if( !NOERR(err=RP_sql_load_attr_space( A_I6, IP_V6, reg_id, con))) {
     258       break;
     259     }
     260     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V4, reg_id, con))) {
     261       break;
     262     }
     263     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V6, reg_id, con))) {
     264       break;
     265     }
     266     /* CONSTCOND */
     267   } while(0);
     268
     269   dieif ( SQ_execute_query(con, "UNLOCK TABLES", NULL) == -1 );
     270
     271   /* Close connection */
     272   SQ_close_connection(con);
     273
     274   /* free junk */
     275   wr_free(dbhost);
     276   wr_free(dbname);
     277   wr_free(dbuser);
     278   wr_free(dbpass);
     279   wr_free(srcnam);
     280   return err;
     281 }
     282
     283
     284 /*
     285    load the tree from an ascii file (short attr names).
     286    mainly for testing...
     287 */
     288 er_ret_t
     289 RP_asc_load(char *filename, int maxobj, int operation,
         /* [<][>][^][v][top][bottom][index][help] */
     290             rp_regid_t reg_id)
     291 {
     292   er_ret_t err;
     293   FILE *fp;
     294   char buf[1024];
     295   char fulltext[65536];
     296   int objnr = 0;
     297   int len, oldlen=0;
     298   int ranlen;
     299   char rangstr[IP_RANGSTR_MAX];
     300   int parsed = 0;
     301   int eor; /* end of record */
     302
     303
     304   if( (fp = fopen(filename,"r")) == NULL ) {
     305     perror(filename);
     306     die;
     307   }
     308
     309   do {
     310     fgets(buf, 128, fp);
     311
     312     eor = ( strlen(buf) <= 1 || feof(fp) );
     313
     314     if( strlen(buf) > 1 ) {
     315       len = strlen(buf);
     316       dieif( oldlen+len+1 > 65536 ); /* object too long */
     317       memcpy( fulltext+oldlen, buf, len);
     318       oldlen+=len;
     319
     320       fulltext[oldlen]=0;
     321     }
     322
     323     if( eor ) {              /* end of object: put into the database. */
     324       parsed++;
     325
     326       /* see if it was just some whitespace junk and nothing more */
     327       if( *fulltext==0 ) {
     328         continue;  /* discard */
     329       }
     330
     331       /* check if it's a radix object */
     332       do {
     333         char attrname[3];
     334         A_Type_t attrcode;
     335
     336         if( fulltext[0] == '*' &&  fulltext[3] == ':' ) {
     337           strncpy(attrname, fulltext+1, 2);
     338           attrname[2]=0;
     339
     340           if(strcmp(attrname, "XX") == 0 ) {
     341             /* object deleted */
     342             break;
     343           }
     344
     345           if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
     346             fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
     347             break;
     348           }
     349
     350           if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
     351             /* no interest to radix */
     352             break;
     353           }
     354
     355           /* copy and translate the range */
     356           ranlen = index(fulltext+5,'\n')-fulltext-5;
     357           strncpy(rangstr, fulltext+5, ranlen);
     358           rangstr[ranlen]=0;
     359
     360           if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,
     361                                     fulltext, strlen(fulltext)+1, 0L )) ) {
     362             objnr++;
     363           }
     364           else {
     365             die; /* error putting into the radix tree */
     366             return err;
     367           }
     368
     369         }
     370         /* CONSTCOND */
     371       } while(0);
     372
     373       *fulltext=0;
     374       oldlen=0;
     375     }
     376   }
     377   while(!feof(fp) && objnr<maxobj);
     378
     379   return RP_OK;
     380 }

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