modules/pm/pm_serials.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- PM_get_minmax_serial
- atlast
- getop
- PM_get_serial_object
- pm_get_source_info
- PM_get_nrtm_sources
1 /***************************************
2 $Revision: 1.16 $
3
4 Near real-time mirror server module (pm). NRTM protocol.
5
6 Status: NOT REVUED, NOT TESTED
7
8 +html+ <DL COMPACT>
9 +html+ <DT>Online References:
10 +html+ <DD><UL>
11 +html+ </UL>
12 +html+ </DL>
13 +html+ <PRE>
14 Author:
15 andrei
16 +html+ </PRE>
17
18 ******************/ /******************
19 Copyright (c) 2000,2001,2002 RIPE NCC
20
21 All Rights Reserved
22
23 Permission to use, copy, modify, and distribute this software and its
24 documentation for any purpose and without fee is hereby granted,
25 provided that the above copyright notice appear in all copies and that
26 both that copyright notice and this permission notice appear in
27 supporting documentation, and that the name of the author not be
28 used in advertising or publicity pertaining to distribution of the
29 software without specific, written prior permission.
30
31 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
32 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
33 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
34 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
35 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 ***************************************/
38
39 #include "rip.h"
40
41 #include <stdio.h>
42
43 void pm_get_source_info(GString *gbuff, ip_addr_t *client_address, char *source, ca_dbSource_t *source_hdl);
44
45 /************************************************************
46 * PM_get_minmax_serial() *
47 * *
48 * Returns the min or max serial number. *
49 * *
50 * Returns: *
51 * min (max=0) or max (max=1) serial number *
52 * -1 in case of an error *
53 * *
54 * Note: *
55 * min serial= MIN(serial_id)+1 *
56 * MIN(serial_id) represents legacy RIPE.CURRENSERIAL *
57 * of the snapshot *
58 * *
59 *************************************************************/
60 long PM_get_minmax_serial(SQ_connection_t *sql_connection, int max)
/* [<][>][^][v][top][bottom][index][help] */
61 {
62 char query[STR_M];
63 SQ_result_set_t *sql_result;
64 SQ_row_t *sql_row;
65 char *sql_str;
66 long current_serial;
67 char *minmax;
68 int sql_err;
69
70 if(max==1)minmax="max"; else minmax="min";
71
72 /* get the lock to ensure that queries are not stopped */
73 /* which means access to the database is allowed */
74 PW_record_query_start();
75
76 sprintf(query, "SELECT %s(serial_id) FROM serials ", minmax);
77
78 //fprintf(stderr, "D:<get_field_str>:query: %s\n", query);
79 sql_err = SQ_execute_query(sql_connection, query, &sql_result);
80
81 if(sql_err) {
82 ER_perror(FAC_PM, PM_NOSQLC,"%s[%s]", SQ_error(sql_connection), query);
83 die;
84 }
85
86
87 if ((sql_row = SQ_row_next(sql_result)) != NULL) {
88 sql_str = SQ_get_column_string(sql_result, sql_row, 0);
89
90 /* We must process all the rows of the result,*/
91 /* otherwise we'll have them as part of the next qry */
92 while ( (sql_row = SQ_row_next(sql_result)) != NULL) {
93 ER_perror(FAC_PM, PM_NOSQLC,"duplicate PK [%s]", query);
94 if(sql_str) UT_free(sql_str); sql_str=NULL;
95 }
96 }
97 else sql_str=NULL;
98
99 if(sql_result){ SQ_free_result(sql_result); sql_result=NULL; }
100
101 if(sql_str) {
102 current_serial = atol(sql_str);
103 if(max!=1)current_serial++;
104 UT_free(sql_str);
105 }
106 else current_serial=-1;
107
108 /* release the lock */
109 PW_record_query_end();
110
111
112 return(current_serial);
113
114 }
115
116 /************************************************************
117 * int atlast(long serial_number)
118 * -1 - sql error
119 *
120 ***********************************************************/
121
122 static int atlast(SQ_connection_t *sql_connection, long serial_number)
/* [<][>][^][v][top][bottom][index][help] */
123 {
124 char *sql_str;
125 char str_id[STR_S];
126 int atlast=-1;
127
128 sprintf(str_id, "%ld", serial_number);
129 sql_str= get_field_str(sql_connection, "atlast", "serials", "serial_id", str_id, NULL);
130 if(sql_str) {
131 atlast = atoi(sql_str);
132 UT_free(sql_str);
133 }
134
135 return(atlast);
136
137 }
138
139
140 /************************************************************
141 * int getop(long serial_number)
142 * -1 - sql error
143 *
144 * **********************************************************/
145
146 static int getop(SQ_connection_t *sql_connection, long serial_number)
/* [<][>][^][v][top][bottom][index][help] */
147 {
148 char *sql_str;
149 char str_id[STR_S];
150 int op=-1;
151
152 sprintf(str_id, "%ld", serial_number);
153 sql_str= get_field_str(sql_connection, "operation", "serials", "serial_id", str_id, NULL);
154 if(sql_str) {
155 op = atoi(sql_str);
156 UT_free(sql_str);
157 }
158
159 return(op);
160
161 }
162
163
164 /************************************************************
165 * char *PM_get_serial_object() *
166 * *
167 * Returns text block corresponding to the requested serial *
168 * *
169 * Returns: *
170 * operation (ADD/DEL) and text object *
171 * NULL in case of an error *
172 * *
173 * Note: *
174 * returned string should be freed by the caller *
175 * *
176 *************************************************************/
177 char *PM_get_serial_object(SQ_connection_t *sql_connection, long serial_number, int *operation)
/* [<][>][^][v][top][bottom][index][help] */
178 {
179 char *table;
180 SQ_result_set_t * sql_result;
181 SQ_row_t *sql_row;
182 char *sql_str;
183 char query[STR_M];
184 int sql_err;
185 int location;
186
187 /* get the lock to ensure that queries are not stopped */
188 /* which means access to the database is allowed */
189 PW_record_query_start();
190
191 switch(location=atlast(sql_connection, serial_number)){
192
193 case 0: table="history";
194 break;
195 case 1: table="last";
196 break;
197 case 2: table="failed_transaction";
198 break;
199 default: return(NULL);
200
201 }
202
203 if(location == 2)
204 sprintf(query, "SELECT object FROM %s "
205 "WHERE serial_id=%ld ",
206 table, serial_number);
207 else
208 sprintf(query, "SELECT %s.object FROM %s, serials "
209 "WHERE serials.serial_id=%ld "
210 "AND serials.object_id=%s.object_id "
211 "AND serials.sequence_id=%s.sequence_id ", table, table, serial_number, table, table);
212
213
214 sql_err = SQ_execute_query(sql_connection, query, &sql_result);
215
216 if(sql_err) {
217 ER_perror(FAC_PM, PM_NOSQLC,"%s[%s]", SQ_error(sql_connection), query);
218 die;
219 }
220
221
222 if ((sql_row = SQ_row_next(sql_result)) != NULL) {
223 sql_str = SQ_get_column_string(sql_result, sql_row, 0);
224
225 /* We must process all the rows of the result,*/
226 /* otherwise we'll have them as part of the next qry */
227 while ( (sql_row = SQ_row_next(sql_result)) != NULL) {
228 ER_perror(FAC_PM, PM_NOSQLC,"duplicate PK [%s]", query);
229 if(sql_str) UT_free(sql_str); sql_str=NULL;
230 }
231 }
232 else sql_str=NULL;
233
234 if(sql_result){ SQ_free_result(sql_result); sql_result=NULL; }
235
236 *operation=getop(sql_connection, serial_number);
237
238 /* release the lock */
239 PW_record_query_end();
240
241 return(sql_str);
242
243 }
244
245 /************************************************************
246 * void pm_get_source_info() *
247 * *
248 * Fills supplied buffer with information about the source *
249 * *
250 * Returns text block corresponding to the requested source *
251 * Format: *
252 * <source>:<can_mirror>:min_serial-max_serial *
253 * source - name of the source (e.g. RIPE, RADB, etc.) *
254 * can_mirror *
255 * 'Y' if the client is allowed to mirror the source *
256 * 'N' if not *
257 * 'N' if there is no serials (then the range starts at 0)*
258 * *
259 * *
260 *************************************************************/
261 void pm_get_source_info(GString *gbuff, ip_addr_t *client_address, char *source, ca_dbSource_t *source_hdl)
/* [<][>][^][v][top][bottom][index][help] */
262 {
263
264 char *db_host = ca_get_srcdbmachine(source_hdl);
265 int db_port = ca_get_srcdbport(source_hdl);
266 char *db_name = ca_get_srcdbname(source_hdl);
267 char *db_user = ca_get_srcdbuser(source_hdl);
268 char *db_passwd = ca_get_srcdbpassword(source_hdl);
269 int version = ca_get_srcnrtmprotocolvers(source_hdl);
270 SQ_connection_t *db_connection;
271 long min_serial, max_serial;
272 char can_mirror;
273
274 /* Connect to the database */
275 db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
276 min_serial=PM_get_oldest_serial(db_connection);
277 max_serial=PM_get_current_serial(db_connection) - SAFE_BACKLOG;
278
279 /* If it cannot be morrored at all - N, but range starts with 0 */
280 /* If the client is allowed to mirror - Y */
281 /* Otherwise - N */
282 if(min_serial>max_serial) {
283 can_mirror='N';
284 min_serial=0;
285 }
286 else {
287 if(AA_can_mirror(client_address, source )) can_mirror='Y';
288 else can_mirror='N';
289 }
290 g_string_sprintfa(gbuff, "%s:%d:%c:%lu-%lu\n", source, version, can_mirror, min_serial, max_serial);
291
292 UT_free(db_host);
293 UT_free(db_name);
294 UT_free(db_user);
295 UT_free(db_passwd);
296 SQ_close_connection(db_connection);
297 }
298
299 /************************************************************
300 * GString *PM_get_nrtm_sources() *
301 * *
302 * Fills supplied buffer with information about the sources *
303 * *
304 * *
305 * Note: *
306 * returned GString should be freed by the caller *
307 * *
308 *************************************************************/
309 GString *PM_get_nrtm_sources(ip_addr_t *client_address, char *source)
/* [<][>][^][v][top][bottom][index][help] */
310 {
311 GString *gbuff=g_string_sized_new(STR_L);
312 int nsource;
313 ca_dbSource_t *source_hdl;
314
315 if(source){
316 source_hdl = ca_get_SourceHandleByName(source);
317 if (source_hdl)pm_get_source_info(gbuff, client_address, source, source_hdl);
318 } else
319 for(nsource=0; (source_hdl = ca_get_SourceHandleByPosition(nsource))!=NULL ; nsource++){
320 source=ca_get_srcname(source_hdl);
321 pm_get_source_info(gbuff, client_address, source, source_hdl);
322 UT_free(source);
323 }
324 /* one extra line, another one will be put bt PW or PM */
325 g_string_sprintfa(gbuff, "\n");
326 return(gbuff);
327 }