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

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