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