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 | }