modules/pm/pm_serials.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. PM_get_minmax_serial
  2. atlast
  3. getop
  4. PM_get_serial_object
  5. pm_get_source_info
  6. PM_get_nrtm_sources

   1 /***************************************
   2   $Revision: 1.14 $
   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 #include "protocol_whois.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)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   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           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           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)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        free(db_host);
 293        free(db_name);
 294        free(db_user);
 295        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        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 }

/* [<][>][^][v][top][bottom][index][help] */