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

st_hash.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: st_hash.c,v 1.34 2009-07-06 19:21:36 anton Exp $ */

#ifdef USE_HASH
#include "netams.h"
#include "st_any.h"

#ifndef LINUX
#include <db.h>
#else
#include <db1/db.h>
#endif
//////////////////////////////////////////////////////////////////////////
int stSaveHashRaw(DB *db, char *key, char *value);
u_char stLoadHashRaw(DB *db, char *key, char *value);
//////////////////////////////////////////////////////////////////////////
class HASH_Storage: public Storage {
      public:
            char *db_path; // where our database are? (to check for HDD space)
            
            char *raw;  //filename of temporary raw file
            char *summary; //filename of temporary summary file

            DB *db_raw;
            DB *db_summary;

            HASH_Storage(storage_type type, u_char id);
            ~HASH_Storage();
                        
            void ShowCfg(struct cli_def *cli, u_char flags);
            int ProcessCfg(struct cli_def *cli, char **argv, int argc, u_char no_flag);
            int StoreMSG(Message *msg);

            void* Open(st_conn_type type);
            void Close(st_conn_type type);
            int stLoad(st_conn_type type,
                  void* (*FillData)(void *res, void *row, char* (*getRowData)(void*, void* , u_char))=NULL);
};
//////////////////////////////////////////////////////////////////////////
Storage* InitHashStorage(storage_type st_type, u_char instance) {
      return (Storage*) new HASH_Storage(st_type, instance);
}
//////////////////////////////////////////////////////////////////////////
HASH_Storage::HASH_Storage(storage_type type, u_char id):Storage(type, id) {
      db_path=NULL;
      raw=summary=NULL;
      db_raw=db_summary=NULL;
}

HASH_Storage::~HASH_Storage() {
      if(db_path)  aFree(db_path);
      if(raw)    aFree(raw);
      if(summary) aFree(summary);
}

int HASH_Storage::ProcessCfg(struct cli_def *cli, char **param, int argc, u_char no_flag){
      if (STRARG(param[0], "path")) {
            if(db_path) aFree(db_path);
            db_path=set_string(param[1]);
            
            if(raw) aFree(raw); raw=NULL;
            if(summary) aFree(summary); summary=NULL;

            print_to_string(&raw, "%s/netams-raw.db", db_path);
            print_to_string(&summary, "%s/netams-sumary.db", db_path);

            cli_error(cli, "path is set to %s", db_path);
      } else 
            return CLI_ERROR;
      
      return CLI_OK;
}

void HASH_Storage::ShowCfg(struct cli_def *cli, u_char flags){
      cli_print(cli, "type hash");
      if (db_path) cli_print(cli, "path %s", db_path);
}

void* HASH_Storage::Open(st_conn_type conn_type){
      // first, we will determine the path to hash files
      // two ways - the directory where config file is, or what is specified in 'path' variable
      
      void *fd=FD[conn_type];
      if(fd) return fd;

      char *hash_file;

      switch(conn_type) {
            case ST_CONN_RAW:
                  hash_file=raw;
                  break;
            case ST_CONN_SUMMARY:
                  hash_file=summary;
                  break;
            default:
                  return NULL;
      }     

      struct stat sb;
      if(stat(hash_file, &sb) == 0) { 
            if (!sb.st_size) { 
                  unlink(hash_file); 
                  aLog(D_INFO, "stOpenHash(%s)%d: old archive truncated\n", hash_file, instance);
            }
      } 

      fd=dbopen(hash_file, O_CREAT|O_RDWR, S_IRWXU, DB_HASH, NULL);
      if (fd==NULL) 
            aLog(D_ERR, "stOpenHash:%u(%s) %s , continue closed\n", instance, hash_file, strerror(errno));
      else 
            aDebug(DEBUG_STORAGE, "hash-%s:%u database opened at %s\n", st_table_name[conn_type], instance, hash_file); 

      FD[conn_type]=(void*)fd;
      return (void*)fd;
}     
//////////////////////////////////////////////////////////////////////////
void HASH_Storage::Close(st_conn_type conn_type){
      void *fd=FD[conn_type];

      if(!fd) return;

      DB *db=(DB*)fd;
      if(db->close(db)<0)
            aLog(D_ERR, "HASH:%u can't close: %s\n",instance, strerror(errno));
      else
            aDebug(DEBUG_STORAGE, "HASH:%u closed\n", instance); 
      
      FD[conn_type]=NULL;
}
//////////////////////////////////////////////////////////////////////////
int HASH_Storage::StoreMSG(Message *msg){
      char key[80], value[80];
      Message_Store *smsg = (Message_Store*)msg;

      if(msg == NULL) {
            Close(ST_CONN_RAW);
            Close(ST_CONN_SUMMARY);
            db_raw=db_summary=NULL;
            return 1;
      }

      switch (smsg->prefix){
            case 'F':
                  if(!db_raw) {
                        db_raw=(DB*)Open(ST_CONN_RAW);
                        if(!db_raw) {
                              aLog(D_ERR, "Can't open HASH:%u for raw: %s\n",
                                    instance,strerror(errno));
                              return -1;
                        }
                  }
                  snprintf(key, 80, "%06X-%06X-%u-%u ", smsg->netunit, smsg->ap, smsg->data->from, smsg->ts);
                  snprintf(value, 80, "%qu %qu ", smsg->data->in, smsg->data->out);
                  stSaveHashRaw(db_raw, key, value);
            break;
            case 'M':
            case 'W':
            case 'D':
            case 'H':
                  if(!db_summary) {
                        db_summary=(DB*)Open(ST_CONN_SUMMARY);
                        if(!db_summary) {
                              aLog(D_ERR, "Can't open HASH:%u for summary: %s\n",
                                    instance,strerror(errno));    
                              return -1;
                        }
                  }
                  snprintf(key, 80, "%c-%06X-%06X-%u ", smsg->prefix, smsg->netunit, smsg->ap, smsg->data->from);
                  snprintf(value, 80, "%qu %qu ", smsg->data->in, smsg->data->out);
                  stSaveHashRaw(db_summary, key, value);
                  break;
      }
      return 1;
}                        
//////////////////////////////////////////////////////////////////////////
int stSaveHashRaw(DB *db, char *key, char *value){
      DBT k, v;
      int i;

      k.size=strlen(key); 
      k.data=key; 
      v.size=strlen(value); 
      v.data=value;

      i=db->put(db, &k, &v, 0);

      aDebug(DEBUG_STORAGE, "HASH->HDD '%s'.'%s'%s\n", key, value, !i?"":strerror(errno));

      return i;
}
//////////////////////////////////////////////////////////////////////////
int HASH_Storage::stLoad(st_conn_type type,
      void* (*FillData)(void *res, void *row, char* (*getRowData)(void*, void* , u_char)))
{
      DB *db;
      int res=0;
      
      if(!(db=(DB*)Open(ST_CONN_SUMMARY))) {
            return -1;
      }

      NetUnit *u;
      char key[80], value[80];

      netams_rwlock_wrlock(&Units->rwlock);
      for (u=(NetUnit*)Units->root; u!=NULL; u=(NetUnit*)u->next) {
            if(u->ap == NULL) continue;

            netams_rwlock_wrlock(&u->ap->rwlock);
            for(policy_data *pd=u->ap->root; pd!=NULL; pd=pd->next) {
                  aDebug(DEBUG_STORAGE, "ST<-HASH rd st:%u unit:%06X acct:%06X\n",
                        instance, u->id, pd->policy->id);

                  pstat *cps[5] = { NULL, &(pd->h), &(pd->d), &(pd->w), &(pd->m)};

                  //protect counters
                  netams_rwlock_wrlock(&u->ap->rwlock);
                  for(u_char i=1; i<5; i++) {
                        snprintf(key, 80, "%c-%06X-%06X-%u ",
                              pstat_prefix[i], u->id, pd->policy->id, cps[i]->from);
                        bzero(value, 80);
                        if(stLoadHashRaw(db, key, value)) {
                              unsigned long long in;
                              unsigned long long out;
                              sscanf(value, "%qu %qu", &in, &out);
            
                              //update counters
                              cps[i]->in+=in;
                              cps[i]->out+=out;
                              res++;
                        } else {
                              aLog(D_WARN, "Can't read data from HASH:%u\n", instance);
                              res=0;
                              break;
                        }
                  }
                  netams_rwlock_unlock(&u->ap->rwlock);
                  if(res==0) break;
            }
      }
      netams_rwlock_unlock(&Units->rwlock);
      return res;
}
//////////////////////////////////////////////////////////////////////////
u_char stLoadHashRaw(DB *db, char *key, char *value){
      DBT k, v;
      int i; 

      k.size=strlen(key); 
      k.data=key; 
      v.size=strlen(value); 
      i=db->get(db, &k, &v, 0);
      if (i==0) { 
            memcpy(value, v.data, v.size);
            aDebug(DEBUG_STORAGE, "HASH<-HDD '%s'.'%s'\n", key, value);
      }
      else if (i==1) { 
            strcpy(value, "0 0 0 ");
            aDebug(DEBUG_STORAGE, "HASH<-HDD '%s'.notfound\n", key);
      }
      else {
            aDebug(DEBUG_STORAGE, "HASH<-HDD %s\n", strerror(errno));
            return 0;
      }
      return 1;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
#endif

Generated by  Doxygen 1.6.0   Back to index