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