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.10 $
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 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 #include <stdio.h>
39 #include "ud_int.h"
40 #include "protocol_mirror.h"
41
42 void pm_get_source_info(GString *gbuff, ip_addr_t *client_address, char *source, ca_dbSource_t *source_hdl);
43
44 /************************************************************
45 * PM_get_minmax_serial() *
46 * *
47 * Returns the min or max serial number. *
48 * *
49 * Returns: *
50 * min (max=0) or max (max=1) serial number *
51 * -1 in case of an error *
52 * *
53 * Note: *
54 * min serial= MIN(serial_id)+1 *
55 * MIN(serial_id) represents legacy RIPE.CURRENSERIAL *
56 * of the snapshot *
57 * *
58 *************************************************************/
59 long PM_get_minmax_serial(SQ_connection_t *sql_connection, int max)
/* [<][>][^][v][top][bottom][index][help] */
60 {
61 char query[STR_M];
62 SQ_result_set_t *sql_result;
63 SQ_row_t *sql_row;
64 char *sql_str;
65 long current_serial;
66 char *minmax;
67 int sql_err;
68
69 if(max==1)minmax="max"; else minmax="min";
70
71 sprintf(query, "SELECT %s(serial_id) FROM serials ", minmax);
72
73 //fprintf(stderr, "D:<get_field_str>:query: %s\n", query);
74 sql_err = SQ_execute_query(sql_connection, query, &sql_result);
75
76 if(sql_err) {
77 ER_perror(FAC_PM, PM_NOSQLC,"%s[%s]", SQ_error(sql_connection), query);
78 die;
79 }
80
81
82 if ((sql_row = SQ_row_next(sql_result)) != NULL) {
83 sql_str = SQ_get_column_string(sql_result, sql_row, 0);
84
85 /* We must process all the rows of the result,*/
86 /* otherwise we'll have them as part of the next qry */
87 while ( (sql_row = SQ_row_next(sql_result)) != NULL) {
88 ER_perror(FAC_PM, PM_NOSQLC,"duplicate PK [%s]", query);
89 if(sql_str)free(sql_str); sql_str=NULL;
90 }
91 }
92 else sql_str=NULL;
93
94 if(sql_result){ SQ_free_result(sql_result); sql_result=NULL; }
95
96 if(sql_str) {
97 current_serial = atol(sql_str);
98 if(max!=1)current_serial++;
99 free(sql_str);
100 }
101 else current_serial=-1;
102
103 return(current_serial);
104
105 }
106
107 /************************************************************
108 * int atlast(long serial_number)
109 * -1 - sql error
110 *
111 ***********************************************************/
112
113 static int atlast(SQ_connection_t *sql_connection, long serial_number)
/* [<][>][^][v][top][bottom][index][help] */
114 {
115 char *sql_str;
116 char str_id[STR_S];
117 int atlast=-1;
118
119
120 sprintf(str_id, "%ld", serial_number);
121 sql_str= get_field_str(sql_connection, "atlast", "serials", "serial_id", str_id, NULL);
122 if(sql_str) {
123 atlast = atoi(sql_str);
124 free(sql_str);
125 }
126
127 return(atlast);
128
129 }
130
131
132 /************************************************************
133 * int getop(long serial_number)
134 * -1 - sql error
135 *
136 * **********************************************************/
137
138 static int getop(SQ_connection_t *sql_connection, long serial_number)
/* [<][>][^][v][top][bottom][index][help] */
139 {
140 char *sql_str;
141 char str_id[STR_S];
142 int op=-1;
143
144
145 sprintf(str_id, "%ld", serial_number);
146 sql_str= get_field_str(sql_connection, "operation", "serials", "serial_id", str_id, NULL);
147 if(sql_str) {
148 op = atoi(sql_str);
149 free(sql_str);
150 }
151
152 return(op);
153
154 }
155
156
157 /************************************************************
158 * char *PM_get_serial_object() *
159 * *
160 * Returns text block corresponding to the requested serial *
161 * *
162 * Returns: *
163 * operation (ADD/DEL) and text object *
164 * NULL in case of an error *
165 * *
166 * Note: *
167 * returned string should be freed by the caller *
168 * *
169 *************************************************************/
170 char *PM_get_serial_object(SQ_connection_t *sql_connection, long serial_number, int *operation)
/* [<][>][^][v][top][bottom][index][help] */
171 {
172 char *table;
173 SQ_result_set_t * sql_result;
174 SQ_row_t *sql_row;
175 char *sql_str;
176 char query[STR_M];
177 int sql_err;
178 int location;
179
180 switch(location=atlast(sql_connection, serial_number)){
181
182 case 0: table="history";
183 break;
184 case 1: table="last";
185 break;
186 case 2: table="failed_transaction";
187 break;
188 default: return(NULL);
189
190 }
191
192 if(location == 2)
193 sprintf(query, "SELECT object FROM %s "
194 "WHERE serial_id=%ld ",
195 table, serial_number);
196 else
197 sprintf(query, "SELECT %s.object FROM %s, serials "
198 "WHERE serials.serial_id=%ld "
199 "AND serials.object_id=%s.object_id "
200 "AND serials.sequence_id=%s.sequence_id ", table, table, serial_number, table, table);
201
202
203 sql_err = SQ_execute_query(sql_connection, query, &sql_result);
204
205 if(sql_err) {
206 ER_perror(FAC_PM, PM_NOSQLC,"%s[%s]", SQ_error(sql_connection), query);
207 die;
208 }
209
210
211 if ((sql_row = SQ_row_next(sql_result)) != NULL) {
212 sql_str = SQ_get_column_string(sql_result, sql_row, 0);
213
214 /* We must process all the rows of the result,*/
215 /* otherwise we'll have them as part of the next qry */
216 while ( (sql_row = SQ_row_next(sql_result)) != NULL) {
217 ER_perror(FAC_PM, PM_NOSQLC,"duplicate PK [%s]", query);
218 if(sql_str)free(sql_str); sql_str=NULL;
219 }
220 }
221 else sql_str=NULL;
222
223 if(sql_result){ SQ_free_result(sql_result); sql_result=NULL; }
224
225 *operation=getop(sql_connection, serial_number);
226
227 return(sql_str);
228
229 }
230
231 /************************************************************
232 * void pm_get_source_info() *
233 * *
234 * Fills supplied buffer with information about the source *
235 * *
236 * Returns text block corresponding to the requested source *
237 * Format: *
238 * <source>:<can_mirror>:min_serial-max_serial *
239 * source - name of the source (e.g. RIPE, RADB, etc.) *
240 * can_mirror *
241 * 'Y' if the client is allowed to mirror the source *
242 * 'N' if not *
243 * 'N' if there is no serials (then the range starts at 0)*
244 * *
245 * *
246 *************************************************************/
247 void pm_get_source_info(GString *gbuff, ip_addr_t *client_address, char *source, ca_dbSource_t *source_hdl)
/* [<][>][^][v][top][bottom][index][help] */
248 {
249
250 char *db_host = ca_get_srcdbmachine(source_hdl);
251 int db_port = ca_get_srcdbport(source_hdl);
252 char *db_name = ca_get_srcdbname(source_hdl);
253 char *db_user = ca_get_srcdbuser(source_hdl);
254 char *db_passwd = ca_get_srcdbpassword(source_hdl);
255 int version = ca_get_srcnrtmprotocolvers(source_hdl);
256 SQ_connection_t *db_connection;
257 long min_serial, max_serial;
258 char can_mirror;
259
260 /* Connect to the database */
261 db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
262 min_serial=PM_get_oldest_serial(db_connection);
263 max_serial=PM_get_current_serial(db_connection);
264
265 /* If it cannot be morrored at all - N, but range starts with 0 */
266 /* If the client is allowed to mirror - Y */
267 /* Otherwise - N */
268 if(min_serial>max_serial) {
269 can_mirror='N';
270 min_serial=0;
271 }
272 else {
273 if(AA_can_mirror(client_address, source )) can_mirror='Y';
274 else can_mirror='N';
275 }
276 g_string_sprintfa(gbuff, "%s:%d:%c:%lu-%lu\n", source, version, can_mirror, min_serial, max_serial);
277
278 free(db_host);
279 free(db_name);
280 free(db_user);
281 free(db_passwd);
282 SQ_close_connection(db_connection);
283 }
284
285 /************************************************************
286 * GString *PM_get_nrtm_sources() *
287 * *
288 * Fills supplied buffer with information about the sources *
289 * *
290 * *
291 * Note: *
292 * returned GString should be freed by the caller *
293 * *
294 *************************************************************/
295 GString *PM_get_nrtm_sources(ip_addr_t *client_address, char *source)
/* [<][>][^][v][top][bottom][index][help] */
296 {
297 GString *gbuff=g_string_sized_new(STR_L);
298 int nsource;
299 ca_dbSource_t *source_hdl;
300
301 if(source){
302 source_hdl = ca_get_SourceHandleByName(source);
303 if (source_hdl)pm_get_source_info(gbuff, client_address, source, source_hdl);
304 } else
305 for(nsource=0; (source_hdl = ca_get_SourceHandleByPosition(nsource))!=NULL ; nsource++){
306 source=ca_get_srcname(source_hdl);
307 pm_get_source_info(gbuff, client_address, source, source_hdl);
308 free(source);
309 }
310
311 g_string_sprintfa(gbuff, "\n\n");
312 return(gbuff);
313 }