Source File ud/ud_main.c

    1    | /***************************************
    2    |   $Revision: 1.40 $
    3    |
    4    |   Wrapper for NRTM client
    5    |
    6    |   Status: NOT REVUED, NOT TESTED
    7    |
    8    |  Author(s):       Andrei Robachevsky
    9    |
    10   |   ******************/ /******************
    11   |   Modification History:
    12   |         andrei (17/01/2000) Created.
    13   |   ******************/ /******************
    14   |   Copyright (c) 2000,2001,2002                      RIPE NCC
    15   |
    16   |   All Rights Reserved
    17   |
    18   |   Permission to use, copy, modify, and distribute this software and its
    19   |   documentation for any purpose and without fee is hereby granted,
    20   |   provided that the above copyright notice appear in all copies and that
    21   |   both that copyright notice and this permission notice appear in
    22   |   supporting documentation, and that the name of the author not be
    23   |   used in advertising or publicity pertaining to distribution of the
    24   |   software without specific, written prior permission.
    25   |
    26   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    27   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    28   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    29   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    30   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    31   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    32   |  ***************************************/
    33   |
    34   | #include "rip.h"
    35   |
    36   | #include <sys/types.h>
    37   | #include <sys/socket.h>
    38   | #include <netinet/in.h>
    39   | #include <arpa/inet.h>
    40   | #include <fcntl.h>
    41   | #include <signal.h>
    42   | #include <sys/poll.h>
    43   |
    44   |
    45   | /* here we store sockets for update threads */
    46   | /* they are from SV module */
    47   | extern int SV_update_sock[];
    48   |
    49   | /* here is the shutdown pipe for update threads */
    50   | /* also from SV module (apologies for breaking encapsulation) */
    51   | extern int SV_shutdown_recv_fd;
    52   |
    53   | /* Response time to swtching updates on and off */
    54   | #define TIMEOUT 60
    55   |
    56   | /* timeout between successive attempts to establish connection with server */
    57   | #define PM_CONNECTION_TIMEOUT 10
    58   |
    59   | /* Maximum number of objects(serials) we can consume at a time */
    60   | #define SBUNCH 1000
    61   |
    62   | /* Timeout in seconds when reading (writing) from DBupdate */
    63   | #define STREAM_TIMEOUT 120
    64   |
    65   | /************************************************************
    66   | * int get_NRTM_fd()                                         *
    67   | *                                                           *
    68   | * Gets the NRTM stream                                      *
    69   | *                                                           *
    70   | * First tries to request the serials from the NRTM server   *
    71   | * If the name of the server appears to be not a network name*
    72   | * it tries to open the file with this name                  *
    73   | *                                                           *
    74   | * nrtm - pointer to _nrtm structure                         *
    75   | * upto_last - if==1 then requests to download serials using *
    76   | * LAST keyword                                              *
    77   | *                                                           *
    78   | * Returns:                                                  *
    79   | * A file descriptor for a data stream                       *
    80   | * -1 - error                                                *
    81   | *                                                           *
    82   | ************************************************************/
    83   | int get_NRTM_fd(struct _nrtm *nrtm, int upto_last, char *source)
    84   | {
    85   | int sockfd;
    86   | struct hostent *hptr;
    87   | struct sockaddr_in serv_addr;
    88   | struct in_addr *paddr;
    89   | char host_info[STR_XXL];
    90   | GString *line_buff;
    91   | int fd;
    92   | int ret;
    93   | struct hostent result;
    94   | int error;
    95   | int network;
    96   |
    97   | /* fprintf(stderr, "Making connection to NRTM server ...\n");*/
    98   |  if ((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1){
    99   |    ER_perror(FAC_UD, UD_FS, "cannot create socket");
    100  |    return(-1);
    101  |  }
    102  | #ifdef __linux__
    103  |  if(gethostbyname_r(nrtm->server,  &result, host_info, sizeof(host_info), &hptr, &error)<0)  hptr=NULL;
    104  | #else/* default is Solaris implementation */
    105  |  hptr=gethostbyname_r(nrtm->server,  &result, host_info, sizeof(host_info), &error);
    106  | #endif
    107  |
    108  |  /* Check if it is a network stream or a file */
    109  |  if (hptr) { /* this is a network stream*/
    110  |    paddr=(struct in_addr *)hptr->h_addr;
    111  |    bzero(&serv_addr, sizeof(serv_addr));
    112  |    serv_addr.sin_family=AF_INET;
    113  |    serv_addr.sin_port=nrtm->port;
    114  |    memcpy(&serv_addr.sin_addr, paddr, sizeof(struct in_addr));
    115  | /*   fprintf(stderr,"Trying %s port %d\n", inet_ntoa(serv_addr.sin_addr), nrtm->port);*/
    116  |    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))==-1) {
    117  |      ER_perror(FAC_UD, UD_FS, "cannot connect, errno:%d", errno);
    118  |      close(sockfd);
    119  |      return(-1);
    120  |    }
    121  | /*   fprintf(stderr, "Sending Invitation\n"); */
    122  |
    123  |    /* Request all available serials (upto LAST), or SBUNCH of them */
    124  |    line_buff = g_string_sized_new(STR_L);
    125  |    if(upto_last==1)
    126  |       g_string_sprintf(line_buff, "-g %s:%d:%ld-LAST\n", source, nrtm->version, nrtm->current_serial+1);
    127  |    else if(upto_last==-1) /* persistent mirroring */
    128  |       g_string_sprintf(line_buff, "-k -g %s:%d:%ld-LAST\n", source, nrtm->version, nrtm->current_serial+1);
    129  |    else
    130  |       g_string_sprintf(line_buff, "-g %s:%d:%ld-%ld\n", source, nrtm->version, nrtm->current_serial+1, nrtm->current_serial+SBUNCH);
    131  |    ret=SK_write(sockfd, line_buff->str, line_buff->len, NULL, NULL );
    132  |    g_string_free(line_buff, TRUE);
    133  |    if(ret != 1) {
    134  | 	   ER_perror(FAC_UD, UD_FS, "cannot write");
    135  | 	   close(sockfd);
    136  | 	   return(-1);
    137  |    }
    138  |    fd=sockfd;
    139  |    network=1;
    140  | /*   fprintf(stderr, "Returning stream pointer\n"); */
    141  |  }
    142  |  else { /* this is a file stream*/
    143  |    network=0;
    144  |    close(sockfd);
    145  | /*   fprintf(stderr, "Trying file ...\n");*/
    146  |    if((fd=open(nrtm->server, O_RDONLY, 0666))==-1) {
    147  |       ER_perror(FAC_UD, UD_FS, "cannot open");
    148  |       return(-1);
    149  |    }
    150  |  }
    151  |  return(fd);
    152  | }
    153  |
    154  |
    155  |
    156  | /************************************************************
    157  | *  void UD_do_nrtm()                                        *
    158  | *                                                           *
    159  | * Processes NRTM stream                                     *
    160  | *                                                           *
    161  | * It cycles requesting objects from the NRTM server,        *
    162  | * processing them and then sleeping a specified amount of   *
    163  | * time.                                                     *
    164  | *                                                           *
    165  | * It starts by requesting SBUNCH number of serials and does *
    166  | * so untill no serials are received (actually a warning     *
    167  | * is received saying that the requested range is invalid)   *
    168  | * This approach avoids excessive load on the NRTM server    *
    169  | *                                                           *
    170  | * After that it requests serials using LAST keyward keeping *
    171  | * almost in sync with the server                            *
    172  | *                                                           *
    173  | ************************************************************/
    174  |
    175  | void UD_do_nrtm(void *arg)
    176  | {
    177  | int source = (int)arg;
    178  | UD_stream_t ud_stream;
    179  | struct _nrtm *nrtm;
    180  | int nrtm_delay;
    181  | int do_update=1;
    182  | int do_server;
    183  | int nrtm_fd;
    184  | int num_ok;
    185  | int upto_last;
    186  | GString *ta_activity;
    187  | ca_dbSource_t *source_hdl = ca_get_SourceHandleByPosition(source);
    188  | char *db_host, *db_name, *db_user, *db_passwd;
    189  | int db_port;
    190  | /* get source we are going to mirror */
    191  | char *source_name = ca_get_srcname(source_hdl);
    192  |
    193  |   { /* set up the lohgging path */
    194  |    int res;
    195  |    char *er_ud_def = ca_get_er_ud_def; /* something like 'RIPUPDLOG basename' */
    196  |    GString *er_def;
    197  |    char *erret = NULL;
    198  |
    199  |    er_def = g_string_sized_new(256);
    200  |    g_string_sprintf(er_def, "%s %s", er_ud_def, source_name);
    201  |    fprintf(stderr, "[%s]\n", er_def->str);
    202  |    if( (res = ER_macro_spec(er_def->str, &erret)) != 0 ) {
    203  |         fputs(erret, stderr);
    204  |         die;
    205  |         /* or some other error handling */
    206  |    }
    207  |    UT_free(erret); /* the response is allocated and must be freed */
    208  |    g_string_free(er_def, TRUE);
    209  |    UT_free(er_ud_def);
    210  |   }
    211  |
    212  |   /* load the dictionary */
    213  |   rpsl_load_dictionary(RPSL_DICT_CORE);
    214  |
    215  |   nrtm=UT_calloc(1, sizeof(struct _nrtm));
    216  |   if(nrtm==NULL) {
    217  | 	  ER_perror(FAC_UD, UD_MEM, "cannot allocate memory");
    218  | 	  die;
    219  |   }
    220  | /* get mode of operation: protected/unprotected (dummy) */
    221  |   memset(&ud_stream, 0, sizeof(ud_stream));
    222  |   ud_stream.source_hdl=source_hdl;
    223  |   ud_stream.ud_mode=ca_get_srcmode(source_hdl);
    224  |   nrtm_delay=ca_get_srcnrtmdelay(source_hdl);
    225  |   /* Zero delay means persistent connection */
    226  |   if (nrtm_delay==0) ud_stream.ud_mode |= B_PERSIST_MIRR;
    227  |
    228  |   fprintf(stderr, "Mode of operation:\n");
    229  |   if(IS_DUMMY_ALLOWED(ud_stream.ud_mode))fprintf(stderr, "* dummy allowed\n");
    230  |   else fprintf(stderr, "* dummy not allowed\n");
    231  |
    232  |   if(IS_UPDATE(ud_stream.ud_mode))fprintf(stderr, "* DBupdate\n");
    233  |   else if(IS_NRTM_CLNT(ud_stream.ud_mode)) {
    234  |
    235  | 	   if(IS_PERSIST_MIRR(ud_stream.ud_mode))fprintf(stderr, "* NRTM: persistent conection\n");
    236  | 	   else fprintf(stderr, "* NRTM\n");
    237  | 	}
    238  |         else fprintf(stderr, "* STATIC\n");
    239  |
    240  |   if(IS_STANDALONE(ud_stream.ud_mode))fprintf(stderr, "* running standalone\n");
    241  |    else fprintf(stderr, "* running as a server\n");
    242  |
    243  |   if(IS_NO_NHR(ud_stream.ud_mode))fprintf(stderr, "* NHR is not maintained\n");
    244  |    else fprintf(stderr, "* NHR is maintained\n");
    245  |
    246  |
    247  | /* get mirror server */
    248  |   nrtm->server=ca_get_srcnrtmhost(source_hdl);
    249  |
    250  |
    251  | /* get mirror port */
    252  |   nrtm->port = htons(ca_get_srcnrtmport(source_hdl));
    253  |   printf("XXX nrtm_port=%d\n", ntohs(nrtm->port));
    254  |
    255  | /* get mirror version */
    256  |   nrtm->version=ca_get_srcnrtmprotocolvers(source_hdl);
    257  |
    258  |
    259  | /* get error log facility */
    260  | /*   logfilename=ca_get_srcnrtmlog(source_hdl); */
    261  |
    262  |    db_host = ca_get_srcdbmachine(source_hdl);
    263  |    db_port = ca_get_srcdbport(source_hdl);
    264  |    db_name = ca_get_srcdbname(source_hdl);
    265  |    db_user = ca_get_srcdbuser(source_hdl);
    266  |    db_passwd = ca_get_srcdbpassword(source_hdl);
    267  |
    268  | /* Connect to the database */
    269  |   ER_dbg_va(FAC_UD, ASP_UD_SQL, "%s making SQL connection to %s@%s ...", UD_TAG, db_name, db_host);
    270  |   ud_stream.db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
    271  |
    272  |
    273  |   if(! ud_stream.db_connection) {
    274  |     ER_perror(FAC_UD, UD_SQL, "no connection to SQL server");
    275  |     die;
    276  |   }
    277  |
    278  |   ud_stream.num_skip=0;
    279  |   ud_stream.load_pass=0;
    280  |   ud_stream.nrtm=nrtm;
    281  |
    282  |   if(IS_PERSIST_MIRR(ud_stream.ud_mode))upto_last=-1; /* the faster the better */
    283  |   else upto_last=0; /* let's start gradually if the backlog is > SBUNCH (1000) serials*/
    284  |
    285  | /*+++ main cycle +++*/
    286  |
    287  |  do {
    288  |   do_update=CO_get_do_update();
    289  |   if(do_update) {
    290  |
    291  |    /* Check connection to the database and try to reconnect */
    292  |    if(SQ_ping(ud_stream.db_connection)) {
    293  |     ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "%s connection to SQL server timed out - reistablishing", UD_TAG);
    294  |    }
    295  |
    296  |   /* get current serial */
    297  |    nrtm->current_serial=PM_get_current_serial(ud_stream.db_connection);
    298  |
    299  |    if(nrtm->current_serial == -1) {
    300  |       ER_perror(FAC_UD, UD_SQL, "cannot obtain current serial: %ld", nrtm->current_serial);
    301  |      die;
    302  |    }
    303  |
    304  |    ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "%s connecting to NRTM server [%s:%d] (current serial=%ld)",
    305  |                                     UD_TAG, nrtm->server, ntohs(nrtm->port), nrtm->current_serial);
    306  |
    307  |   /* Get file descriptor of the data stream (RPSL format, use mirror reflector to convert if needed)*/
    308  |     nrtm_fd=get_NRTM_fd(nrtm, upto_last, source_name);
    309  |     if (nrtm_fd==-1) {
    310  |      ER_inf_va(FAC_UD, ASP_UD_OBJ, "%s Cannot open data stream. Trying...", UD_TAG);
    311  |      SV_sleep(PM_CONNECTION_TIMEOUT);
    312  |      continue;
    313  |     }
    314  |
    315  |
    316  |     /* make a record for thread accounting */
    317  |     TA_add(nrtm_fd, "nrtm_clnt");
    318  |     ta_activity = g_string_sized_new(STR_M);
    319  |     g_string_sprintf(ta_activity, "[%s]%ld->",
    320  |                      source_name, nrtm->current_serial);
    321  |     TA_setactivity(ta_activity->str);
    322  |
    323  |
    324  |    ud_stream.condat.sock = nrtm_fd;
    325  |    ud_stream.log.num_ok=0;
    326  |    ud_stream.log.num_failed=0;
    327  |
    328  |
    329  |    ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s starting processing stream", UD_TAG);
    330  |
    331  | /***************** process stream ****************/
    332  |
    333  |       num_ok=UD_process_stream(&ud_stream);
    334  |
    335  | /***************** process stream ****************/
    336  |
    337  |    ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s processing stream finished", UD_TAG);
    338  |
    339  |   /* close the socket of the NRTM stream */
    340  |    close(ud_stream.condat.sock);
    341  |
    342  |
    343  |
    344  |    ER_inf_va(FAC_UD, ASP_UD_OBJ, "%s forwarded to serial:%ld", UD_TAG, (nrtm->current_serial+num_ok));
    345  |
    346  |    /* set activity for thread record */
    347  |    g_string_sprintf(ta_activity, "[%s]->%ld",
    348  |                     source_name, (nrtm->current_serial+num_ok));
    349  |    TA_setactivity(ta_activity->str);
    350  |    g_string_free(ta_activity, TRUE);
    351  |
    352  | /* if we are NOT in persistent mode */
    353  |    if(!IS_PERSIST_MIRR(ud_stream.ud_mode)) {
    354  |      /* Now we can process serials in normal way (upto LAST)*/
    355  |      if(num_ok==0) upto_last=1;
    356  |      /* get delay */
    357  |      nrtm_delay=ca_get_srcnrtmdelay(source_hdl);
    358  |    } else
    359  |      /* we need to delay the next attempt not to have a birst of requests */
    360  |      nrtm_delay=TIMEOUT;
    361  |      /* sleep the delay seconds or untill the shutdown requested */
    362  |      SV_sleep(nrtm_delay);
    363  |
    364  |   } /* if do_updates */
    365  |   else SV_sleep(TIMEOUT);
    366  |
    367  |
    368  |   TA_delete();
    369  |
    370  |  } while((do_server=CO_get_do_server()));  /* main cycle */
    371  |
    372  | /*   fclose(ud_stream.log.logfile);*/
    373  |    UT_free(source_name);
    374  | /* free data associated with nrtm structure */
    375  |  if(nrtm) {
    376  |    UT_free(nrtm->server);
    377  |    UT_free(nrtm);
    378  |  }
    379  |
    380  |  /* That's all. Close connection to the DB */
    381  |  SQ_close_connection(ud_stream.db_connection);
    382  |  UT_free(db_host);
    383  |  UT_free(db_name);
    384  |  UT_free(db_user);
    385  |  UT_free(db_passwd);
    386  |
    387  |  ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s NRTM client stopped", UD_TAG);
    388  | } /* UD_do_nrtm() */
    389  |
    390  | /************************************************************
    391  | *  void UD_do_updates()                                     *
    392  | *                                                           *
    393  | * Processes updates                                         *
    394  | *                                                           *
    395  | * It cycles accepting connections and processing them       *
    396  | * (interactive server). This assures that there is only     *
    397  | * one write thread per database/source.                     *
    398  | *                                                           *
    399  | ************************************************************/
    400  |
    401  | void UD_do_updates(void *arg)
    402  | {
    403  | int source = (int)arg;
    404  | int listening_socket = SV_update_sock[source];
    405  | int connected_socket;
    406  | UD_stream_t ud_stream;
    407  | int do_update=1;
    408  | int num_ok;
    409  | ca_dbSource_t *source_hdl = ca_get_SourceHandleByPosition(source);
    410  | char *db_host, *db_name, *db_user, *db_passwd;
    411  | int db_port;
    412  | ip_addr_t address;
    413  | char *source_name;
    414  | struct pollfd pfd[2];
    415  |
    416  |    source_name = ca_get_srcname(source_hdl);
    417  |
    418  |   { /* set up the lohgging path */
    419  |    /* get source we are going to update */
    420  |    int res;
    421  |    char *er_ud_def = ca_get_er_ud_def; /* something like 'RIPUPDLOG basename' */
    422  |    GString *er_def;
    423  |    char *erret = NULL;
    424  |
    425  |
    426  |    er_def = g_string_sized_new(256);
    427  |    g_string_sprintf(er_def, "%s %s", er_ud_def, source_name);
    428  |    if( (res = ER_macro_spec(er_def->str, &erret)) != 0 ) {
    429  |         fputs(erret, stderr);
    430  |         die;
    431  |         /* or some other error handling */
    432  |    }
    433  |    UT_free(erret); /* the response is allocated and must be freed */
    434  |    g_string_free(er_def, TRUE);
    435  |    UT_free(er_ud_def);
    436  |   }
    437  |
    438  |   /* load the dictionary */
    439  |     rpsl_load_dictionary(RPSL_DICT_CORE);
    440  |
    441  |
    442  | /* get mode of operation: protected/unprotected (dummy) */
    443  |   memset(&ud_stream, 0, sizeof(ud_stream));
    444  |   ud_stream.source_hdl=source_hdl;
    445  |   ud_stream.ud_mode=ca_get_srcmode(source_hdl);
    446  |
    447  |   fprintf(stderr, "Mode of operation:\n");
    448  |   if(IS_DUMMY_ALLOWED(ud_stream.ud_mode))fprintf(stderr, "* dummy allowed\n");
    449  |    else fprintf(stderr, "* dummy not allowed\n");
    450  |   if(IS_UPDATE(ud_stream.ud_mode))fprintf(stderr, "* DBupdate\n");
    451  |    else fprintf(stderr, "* NRTM\n");
    452  |   if(IS_STANDALONE(ud_stream.ud_mode))fprintf(stderr, "* running standalone\n");
    453  |    else fprintf(stderr, "* running as a server\n");
    454  |
    455  |
    456  | /* get the database */
    457  |   db_host = ca_get_srcdbmachine(source_hdl);
    458  |   db_port = ca_get_srcdbport(source_hdl);
    459  |   db_name = ca_get_srcdbname(source_hdl);
    460  |   db_user = ca_get_srcdbuser(source_hdl);
    461  |   db_passwd = ca_get_srcdbpassword(source_hdl);
    462  |
    463  | /* Connect to the database */
    464  |   ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s making SQL connection to %s@%s ...", UD_TAG, db_name, db_host);
    465  |   ud_stream.db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
    466  |
    467  |   if(! ud_stream.db_connection) {
    468  |    ER_perror(FAC_UD, UD_SQL, "no connection to SQL server\n");
    469  |    die;
    470  |   }
    471  |
    472  |
    473  |   ud_stream.condat.rd_timeout.tv_sec=STREAM_TIMEOUT;
    474  |   ud_stream.num_skip=0;
    475  |   ud_stream.load_pass=0;
    476  |   ud_stream.nrtm=NULL;
    477  |
    478  |   /* set up poll structure */
    479  |   pfd[0].fd = listening_socket;
    480  |   pfd[0].events = POLLIN;
    481  |   pfd[1].fd = SV_shutdown_recv_fd;
    482  |   pfd[1].events = POLLIN;
    483  |
    484  | /*+++ main cycle +++*/
    485  |
    486  | do { /* be alive while do_server is 1. do_server is turned off by SIGINT */
    487  |
    488  |    /* make a record for thread accounting */
    489  |    TA_add(listening_socket, "update");
    490  |    TA_setactivity("waiting");
    491  |
    492  |    /* check for input */
    493  |    if (poll(pfd, 2, -1) == -1) {
    494  |         ER_perror(FAC_SV, 1, "UD_do_updates got error %d on poll; %s",
    495  |                   errno, strerror(errno));
    496  |         continue;
    497  |    }
    498  |
    499  |    /* shutdown */
    500  |    if (pfd[1].revents != 0) break;
    501  |
    502  |    /* accept connection */
    503  |    connected_socket = SK_accept_connection(listening_socket);
    504  |    if(connected_socket==-1) continue;
    505  |
    506  |    /* check if the client is authorised to update */
    507  |    SK_getpeerip(connected_socket, &address);
    508  |    if(!AA_can_ripupdate(&address, source_name)){
    509  |    char *hostaddress;
    510  |    sk_conn_st condat;
    511  |    char buff[STR_L];
    512  |
    513  |     memset( &condat, 0, sizeof(sk_conn_st));
    514  |     condat.wr_timeout.tv_sec=STREAM_TIMEOUT;
    515  |     condat.sock = connected_socket;
    516  |     SK_getpeerip(connected_socket, &(condat.rIP));
    517  |     memcpy( &(condat.eIP), &(condat.rIP), sizeof(ip_addr_t));
    518  |     hostaddress = SK_getpeername(connected_socket);
    519  |     condat.ip = hostaddress;
    520  |
    521  |     ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "[%s] --  Not authorized to update the source %s", hostaddress, source_name);
    522  |     sprintf(buff, "\n%%ERROR:406: not authorized to update the database\n\n\n");
    523  |     SK_cd_puts(&condat, buff);
    524  |     SK_cd_close(&(condat));
    525  |
    526  |     UT_free(hostaddress);
    527  |     /* start the next loop */
    528  |     continue;
    529  |    }
    530  |
    531  |    /* make a record for thread accounting */
    532  |    TA_delete(); /* Delete 'waiting' record */
    533  |    TA_add(connected_socket, "update");
    534  |
    535  |
    536  |    ud_stream.condat.sock = connected_socket;
    537  |    ud_stream.condat.rtc = 0;
    538  |
    539  |
    540  |    ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s Connection accepted...", UD_TAG);
    541  |
    542  |    ud_stream.log.num_ok=0;
    543  |    ud_stream.log.num_failed=0;
    544  |
    545  |
    546  |    while((do_update=CO_get_do_update())!=1) {
    547  | 	   TA_setactivity("suspended");
    548  | 	   /* if shutdown was requested - break */
    549  | 	   if(SV_sleep(3*TIME_SLICE)) break;
    550  |    }
    551  |
    552  |    if(do_update) {
    553  |      /* Check connection to the database and try to reconnect*/
    554  |      if(SQ_ping(ud_stream.db_connection)) {
    555  |        ER_perror(FAC_UD, UD_SQL, "%s", SQ_error(ud_stream.db_connection));
    556  |        die;
    557  |      }
    558  |
    559  |      ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s starting processing object", UD_TAG);
    560  |
    561  |      /***************** process stream ****************/
    562  |
    563  |       num_ok=UD_process_stream(&ud_stream);
    564  |
    565  |      /***************** process stream ****************/
    566  |
    567  |       ER_dbg_va(FAC_UD, ASP_UD_OBJ, "%s processing object finished", UD_TAG);
    568  |
    569  |      /* close the socket of the NRTM stream */
    570  |      close(ud_stream.condat.sock);
    571  |
    572  |    }  /* if do_update*/
    573  |
    574  |
    575  |    TA_delete();
    576  |
    577  | } while (CO_get_do_server());  /* main cycle */
    578  |
    579  | /*   fclose(ud_stream.log.logfile); */
    580  |  /* That's all. Close connection to the DB */
    581  |  SQ_close_connection(ud_stream.db_connection);
    582  |  UT_free(db_host);
    583  |  UT_free(db_name);
    584  |  UT_free(db_user);
    585  |  UT_free(db_passwd);
    586  |  UT_free(source_name);
    587  |
    588  |
    589  |  ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "%s update server stopped", UD_TAG);
    590  | } /* UD_do_update() */
    591  |
    592  |
    593  |
    594  |