## 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.16 $
       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,2001,2002                    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
      39 #include "rip.h"
      40
      41 #include <stdio.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) UT_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   UT_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           UT_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           UT_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) UT_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        UT_free(db_host);
     293        UT_free(db_name);
     294        UT_free(db_user);
     295        UT_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        UT_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] */