Logo Search packages:      
Sourcecode: netams version File versions  Download package

ds_raw.c

/*************************************************************************
***   Authentication, authorization, accounting + firewalling package
***   Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
***   Copyright 2002-2008 NeTAMS Development Team
***   This code is GPL v3
***   For latest version and more info, visit this project web page
***   located at http://www.netams.com
***
*************************************************************************/
/* $Id: ds_raw.c,v 1.20 2009-08-01 09:23:55 anton Exp $ */

#include "netams.h"
#include "ds_any.h"
#include "ds_raw.h"

/////////////////////////////////////////////////////////////////////////////////////
void ds_raw_cancel(void *ptr);
int DSAcctRAW(NetUnit *u, ds_raw_data *data, u_char instance);
///////////////////////////////////////////////////////////////////////////////////////hash
#ifndef WIPE_OPENSSL
unsigned DSRAW_hash(struct ds_raw_data *data) {
      return (unsigned)data->u->id;
}
int DSRAW_cmp(struct ds_raw_data *d1, struct ds_raw_data *d2) {
        return (d1->u == d2->u && d1->p == d2->p)?0:1;
}
void DSRAW_cleanup(struct ds_raw_data *data) {
        free(data);
}
/* Create the type-safe wrapper functions for use in the LHASH internals */
static IMPLEMENT_LHASH_HASH_FN(DSRAW_hash, struct ds_raw_data *);
static IMPLEMENT_LHASH_COMP_FN(DSRAW_cmp, struct ds_raw_data *);
static IMPLEMENT_LHASH_DOALL_FN(DSRAW_cleanup, struct ds_raw_data *);
#else
static unsigned int DSRAW_hash(const void *data){
      return ((struct ds_raw_data *)data)->u->id;
}
static int DSRAW_cmp(const void *d1, const void *d2){
        return (
            ((struct ds_raw_data *)d1)->u == ((struct ds_raw_data *)d2)->u &&
            ((struct ds_raw_data *)d1)->p == ((struct ds_raw_data *)d2)->p
            )?0:1;
}
void DSRAW_cleanup(void *data) {
        free(data);
}
#endif

/////////////////////////////////////////////////////////////////////////////////////
void ds_raw(Service_DS *ds) {
#ifndef WIPE_OPENSSL
      ds->ds_raw_hash=lh_new(LHASH_HASH_FN(DSRAW_hash), LHASH_COMP_FN(DSRAW_cmp));
#else
      ds->ds_raw_hash=g_hash_table_new_full(DSRAW_hash, DSRAW_cmp, DSRAW_cleanup, NULL);
#endif

      pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
      pthread_cleanup_push(ds_raw_cancel, (void *)ds->ds_raw_hash);

      aLog(D_INFO,"raw data processing for data-source:%u initialized\n",ds->instance);

      ds->Sleep();

      pthread_cleanup_pop(1);
}
/////////////////////////////////////////////////////////////////////////////////////
void ds_raw_cancel(void *ptr) {
#ifndef WIPE_OPENSSL
      LHASH *ds_raw_hash = (LHASH*) ptr;

      /* So to run "MEM_cleanup" against all items in a hash table ... */
      lh_doall(ds_raw_hash, LHASH_DOALL_FN(DSRAW_cleanup));
      lh_free(ds_raw_hash);
#else
      g_hash_table_destroy((GHashTable*)ptr);
#endif
}
/////////////////////////////////////////////////////////////////////////////////////
int cRawData (struct cli_def *cli, const char *cmd, char **argv, int argc){
      struct ds_raw_data data;
      bzero(&data, sizeof (struct ds_raw_data));

      data.data.from=time(NULL);
      data.data_type=RAW_DATA_UNKNOWN;

      for (u_char i=1; i<argc; i++) {

            if (STREQ(argv[i], "unit")){
                  i++;
                  data.u=aParseUnit(argv, &i);
            } if (STREQ(argv[i], "policy")){
                  i++;
                  data.p=aParsePolicy(argv, &i);
            } if (STREQ(argv[i], "in")){
                  data.data.in=bytesT2Q(argv[i+1]);
                  i++;
            } if (STREQ(argv[i], "out")){
                  data.data.out=bytesT2Q(argv[i+1]);
                  i++;
            } if (STREQ(argv[i], "time")){
                  unsigned long tmp;
                  sscanf(argv[i+1], "%lu", &tmp);
                  data.data.from=tmp;
                  i++;
            } if (STREQ(argv[i], "as-is")){
                  data.data_type=RAW_DATA_ASIS;
            } if (STREQ(argv[i], "incremental")){
                  data.data_type=RAW_DATA_INCREMENTAL;
            }
      }

      return cRawData_prepared(cli, &data);
}

int cRawData_prepared(struct cli_def *cli, ds_raw_data *data){

      struct timeval start;
      netams_gettimeofday(&start, NULL);

      if (!data->u) { cli_print(cli, "RAW data contains no unit information, aborting!"); return -1; }
      if (!data->p) {
            if (data->u->ap && data->u->ap->root && data->u->ap->root->next==NULL)
                  data->p=data->u->ap->root->policy;
            else {
                  cli_print(cli, "RAW data contains no policy information, aborting!");
                  return -1;
            }
      }

      Service_DS *ds=NULL;
      while((ds=(Service_DS*)Services->getServiceNextByType(SERVICE_DATASOURCE,ds))) {
            if (ds->pt_type==PT_RAW) break;
      }
      if (!ds) { cli_print(cli, "no RAW data-source service is present!"); return -1; }

      struct ds_raw_data *ds_data;

#ifndef WIPE_OPENSSL
      ds_data = (ds_raw_data*)lh_retrieve(ds->ds_raw_hash, data);
#else
      ds_data = (ds_raw_data*)g_hash_table_lookup(ds->ds_raw_hash, data);
#endif
      if(!ds_data) {
            //init raw_data for this unit and policy
            ds_data=(struct ds_raw_data*)aMalloc(sizeof(struct ds_raw_data));
            bcopy(data, ds_data, sizeof(struct ds_raw_data));

#ifndef WIPE_OPENSSL
            lh_insert(ds->ds_raw_hash, ds_data);
#else
            g_hash_table_insert(ds->ds_raw_hash, ds_data, ds_data);
#endif
            /* first incremental write should be avoided */
            if (data->data_type==RAW_DATA_INCREMENTAL) return 0;
      } else {
            ds_data->data.from=data->data.from;
            //do something with differenct between old and new values
            if (data->data_type==RAW_DATA_ASIS) { /* just update hash entry */
                  ds_data->data.in = data->data.in;
                  ds_data->data.out = data->data.out;
            }
            else if (data->data_type==RAW_DATA_INCREMENTAL) {
                  if (ds_data->data.in>data->data.in || ds_data->data.out>data->data.out) {
                        ds_data->data.in =  data->data.in;
                        ds_data->data.out =  data->data.out;
                        return 0;
                  }
                  data->data.in     -= ds_data->data.in;
                  data->data.out    -= ds_data->data.out;
                  ds_data->data.in += data->data.in;
                  ds_data->data.out += data->data.out;
            }
      }

      if(!data->p) return 0;

      if (!data->data.from) data->data.from=time(NULL);
      if (!data->u || !DSAcctRAW(data->u, data, ds->instance))
            return 0;

#ifdef DEBUG
      aDebug(DEBUG_DS_RAW, "unit %s(%06X) policy %s(%06X) in=%llu, out=%llu, time=%lu, type=%u, ds=%s:%u\n",
            data->u->name?data->u->name:"<\?\?>", data->u->id,
            data->p->name?data->p->name:"<\?\?>", data->p->id,
            data->data.in, data->data.out, data->data.from, data->data_type,
            ds->getName(), ds->instance);
#endif
      ds->Measure(&start, data->data.in + data->data.out);

      return 0;
}
/////////////////////////////////////////////////////////////////////////////////////
int DSAcctRAW(NetUnit *u, ds_raw_data *data, u_char instance) {
      policy_data *pd;
      if(u->ap == NULL || !(u->checkDSList(instance))
            || (pd = u->ap->Get(data->p))==NULL)
                  return 0;

      netams_rwlock_wrlock(&u->ap->rwlock);
      pd->timestamp     =     data->data.from;
      pd->flow.in       +=    data->data.in;
      pd->flow.out      +=    data->data.out;
      netams_rwlock_unlock(&u->ap->rwlock);

      //for parents
      NetUnit_group *gr;
      ELIST_FOR_EACH(u->parents, gr)
            DSAcctRAW(gr, data, instance);

      return 1;
}
/////////////////////////////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index