示例#1
0
文件: lastseen.c 项目: JarleB/core
/**
 * @brief removes all traces of host 'ip' from lastseen DB
 *
 * @param[in]     ip : either in (SHA/MD5 format)
 * @param[in,out] digest: return corresponding digest of input host.
 *                        If NULL, return nothing
 * @retval true if entry was deleted, false otherwise
 */
bool DeleteIpFromLastSeen(const char *ip, char *digest)
{
    DBHandle *db;
    bool res = false;

    if (!OpenDB(&db, dbid_lastseen))
    {
        Log(LOG_LEVEL_ERR, "Unable to open lastseen database");
        return false;
    }

    char bufkey[CF_BUFSIZE + 1];
    char bufhost[CF_BUFSIZE + 1];

    strcpy(bufhost, "a");
    strlcat(bufhost, ip, CF_BUFSIZE);

    char key[CF_BUFSIZE];
    if (ReadDB(db, bufhost, &key, sizeof(key)) == true)
    {
        strcpy(bufkey, "k");
        strlcat(bufkey, key, CF_BUFSIZE);
        if (HasKeyDB(db, bufkey, strlen(bufkey) + 1) == false)
        {
            res = false;
            goto clean;
        }
        else
        {
            if (digest != NULL)
            {
                strcpy(digest, bufkey);
            }
            DeleteDB(db, bufkey);
            DeleteDB(db, bufhost);
            res = true;
        }
    }
    else
    {
        res = false;
        goto clean;
    }

    strcpy(bufkey, "qi");
    strlcat(bufkey, key, CF_BUFSIZE);
    DeleteDB(db, bufkey);

    strcpy(bufkey, "qo");
    strlcat(bufkey, key, CF_BUFSIZE);
    DeleteDB(db, bufkey);

clean:
    CloseDB(db);
    return res;
}
示例#2
0
bool RemoveHostFromLastSeen(const char *hostkey)
{
    DBHandle *db;
    if (!OpenDB(&db, dbid_lastseen))
    {
        CfOut(cf_error, "", "Unable to open lastseen database");
        return false;
    }

    /* Lookup corresponding address entry */

    char hostkey_key[CF_BUFSIZE];
    snprintf(hostkey_key, CF_BUFSIZE, "k%s", hostkey);
    char address[CF_BUFSIZE];

    if (ReadDB(db, hostkey_key, &address, sizeof(address)) == true)
    {
        /* Remove address entry */
        char address_key[CF_BUFSIZE];
        snprintf(address_key, CF_BUFSIZE, "a%s", address);

        DeleteDB(db, address_key);
    }

    /* Remove quality-of-connection entries */

    char quality_key[CF_BUFSIZE];

    snprintf(quality_key, CF_BUFSIZE, "qi%s", hostkey);
    DeleteDB(db, quality_key);

    snprintf(quality_key, CF_BUFSIZE, "qo%s", hostkey);
    DeleteDB(db, quality_key);

    /* Remove main entry */

    DeleteDB(db, hostkey_key);

    CloseDB(db);

    return true;
}
示例#3
0
static void NotePerformance(char *eventname, time_t t, double value)
{
    CF_DB *dbp;
    Event e, newe;
    double lastseen;
    int lsea = SECONDS_PER_WEEK;
    time_t now = time(NULL);

    CfDebug("PerformanceEvent(%s,%.1f s)\n", eventname, value);

    if (!OpenDB(&dbp, dbid_performance))
    {
        return;
    }

    if (ReadDB(dbp, eventname, &e, sizeof(e)))
    {
        lastseen = now - e.t;
        newe.t = t;

        newe.Q = QAverage(e.Q, value, 0.3);

        /* Have to kickstart variance computation, assume 1% to start  */

        if (newe.Q.var <= 0.0009)
        {
            newe.Q.var = newe.Q.expect / 100.0;
        }
    }
    else
    {
        lastseen = 0.0;
        newe.t = t;
        newe.Q.q = value;
        newe.Q.dq = 0;
        newe.Q.expect = value;
        newe.Q.var = 0.001;
    }

    if (lastseen > (double) lsea)
    {
        CfDebug("Performance record %s expired\n", eventname);
        DeleteDB(dbp, eventname);
    }
    else
    {
        CfOut(cf_verbose, "", "Performance(%s): time=%.4lf secs, av=%.4lf +/- %.4lf\n", eventname, value, newe.Q.expect,
              sqrt(newe.Q.var));
        WriteDB(dbp, eventname, &newe, sizeof(newe));
    }

    CloseDB(dbp);
}
示例#4
0
void EvalContextHeapPersistentRemove(const char *context)
{
    CF_DB *dbp;

    if (!OpenDB(&dbp, dbid_state))
    {
        return;
    }

    DeleteDB(dbp, context);
    Log(LOG_LEVEL_DEBUG, "Deleted persistent class '%s'", context);
    CloseDB(dbp);
}
示例#5
0
void EvalContextHeapPersistentRemove(const char *context)
{
    CF_DB *dbp;

    if (!OpenDB(&dbp, dbid_state))
    {
        return;
    }

    DeleteDB(dbp, context);
    CfDebug("Deleted any persistent state %s\n", context);
    CloseDB(dbp);
}
示例#6
0
文件: lastseen.c 项目: JarleB/core
static bool Address2HostkeyInDB(DBHandle *db, const char *address, char *result)
{
    char address_key[CF_BUFSIZE];
    char hostkey[CF_BUFSIZE];

    /* Address key: "a" + address */
    snprintf(address_key, CF_BUFSIZE, "a%s", address);

    if (!ReadDB(db, address_key, &hostkey, sizeof(hostkey)))
    {
        return false;
    }

    char hostkey_key[CF_BUFSIZE];
    char back_address[CF_BUFSIZE];

    /* Hostkey key: "k" + hostkey */
    snprintf(hostkey_key, CF_BUFSIZE, "k%s", hostkey);

    if (!ReadDB(db, hostkey_key, &back_address, sizeof(back_address)))
    {
        /* There is no key -> address mapping. Remove reverse mapping and return failure. */
        DeleteDB(db, address_key);
        return false;
    }

    if (strcmp(address, back_address) != 0)
    {
        /* Forward and reverse mappings do not match. Remove reverse mapping and return failure. */
        DeleteDB(db, address_key);
        return false;
    }

    strlcpy(result, hostkey, CF_BUFSIZE);
    return true;
}
示例#7
0
文件: locks.c 项目: shaunamarie/core
static int RemoveLock(char *name)
{
    CF_DB *dbp;

    if ((dbp = OpenLock()) == NULL)
    {
        return -1;
    }

    ThreadLock(cft_lock);
    DeleteDB(dbp, name);
    ThreadUnlock(cft_lock);

    CloseLock(dbp);
    return 0;
}
示例#8
0
int main(int argc, char *argv[])
{
	int err = 0;
	char path[] = "database.sqlite3";
	sqlite3 * db;
	err = sqlite3_open(path, &db);
	if(SQLITE_OK != err)
	{
		return -1;
	}
	SelectDB(db, "select str from xx");
	InsertDB(db, "insert  or replace into xx values ('007','kkk','5pp')");
	UpdateDB(db, "update xx set str='007' where sss='lll'");
	DeleteDB(db, "delete from xx where str='789'");
	printf("----------!!----------\n");
	OperateDB(db, "create table if not exists nimei(woqu TEXT)");
	SelectDB(db, "select * from xx");

	return 0;
}
示例#9
0
static void test_reverse_missing_forward(void **context)
{
    setup();

    UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);

    DBHandle *db;
    OpenDB(&db, dbid_lastseen);

    assert_int_equal(DeleteDB(db, "kSHA-12345"), true);

    /* Check that resolution return false */
    char result[CF_BUFSIZE];
    assert_int_equal(Address2Hostkey("127.0.0.64", result), false);

    /* Check that entry is removed */
    assert_int_equal(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1), false);

    CloseDB(db);
}
示例#10
0
void PurgeHashes(char *path, Attributes attr, Promise *pp)
/* Go through the database and purge records about non-existent files */
{
    CF_DB *dbp;
    CF_DBC *dbcp;
    struct stat statbuf;
    int ksize, vsize;
    char *key;
    void *value;

    if (!OpenDB(&dbp,dbid_checksums))
    {
        return;
    }

    if (path)
    {
        if (cfstat(path, &statbuf) == -1)
        {
            DeleteDB(dbp, path);
        }
        CloseDB(dbp);
        return;
    }

/* Acquire a cursor for the database. */

    if (!NewDBCursor(dbp, &dbcp))
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", " !! Unable to scan hash database");
        CloseDB(dbp);
        return;
    }

    /* Walk through the database and print out the key/data pairs. */

    while (NextDB(dbp, dbcp, &key, &ksize, &value, &vsize))
    {
        char *obj = (char *) key + CF_INDEX_OFFSET;

        if (cfstat(obj, &statbuf) == -1)
        {
            if (attr.change.update)
            {
                DBCursorDeleteEntry(dbcp);
            }
            else
            {
                cfPS(OUTPUT_LEVEL_ERROR, CF_WARN, "", pp, attr, "ALERT: File %s no longer exists!", obj);
            }

            LogHashChange(obj, cf_file_removed, "File removed", pp);
        }

        memset(&key, 0, sizeof(key));
        memset(&value, 0, sizeof(value));
    }

    DeleteDBCursor(dbp, dbcp);
    CloseDB(dbp);
}
示例#11
0
void NoteClassUsage(AlphaList baselist, int purge)
{
    CF_DB *dbp;
    CF_DBC *dbcp;
    void *stored;
    char *key;
    int ksize, vsize;
    Event e, entry, newe;
    double lsea = SECONDS_PER_WEEK * 52;        /* expire after (about) a year */
    time_t now = time(NULL);
    Item *list = NULL;
    const Item *ip;
    double lastseen;
    double vtrue = 1.0;         /* end with a rough probability */

/* Only do this for the default policy, too much "downgrading" otherwise */

    if (MINUSF)
    {
        return;
    }

    AlphaListIterator it = AlphaListIteratorInit(&baselist);

    for (ip = AlphaListIteratorNext(&it); ip != NULL; ip = AlphaListIteratorNext(&it))
    {
        if ((IGNORECLASS(ip->name)))
        {
            CfDebug("Ignoring class %s (not packing)", ip->name);
            continue;
        }

        IdempPrependItem(&list, ip->name, NULL);
    }

    if (!OpenDB(&dbp, dbid_classes))
    {
        return;
    }

/* First record the classes that are in use */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        if (ReadDB(dbp, ip->name, &e, sizeof(e)))
        {
            CfDebug("FOUND %s with %lf\n", ip->name, e.Q.expect);
            lastseen = now - e.t;
            newe.t = now;

            newe.Q = QAverage(e.Q, vtrue, 0.7);
        }
        else
        {
            lastseen = 0.0;
            newe.t = now;
            /* With no data it's 50/50 what we can say */
            newe.Q = QDefinite(0.5 * vtrue);
        }

        if (lastseen > lsea)
        {
            CfDebug("Class usage record %s expired\n", ip->name);
            DeleteDB(dbp, ip->name);
        }
        else
        {
            WriteDB(dbp, ip->name, &newe, sizeof(newe));
        }
    }

/* Then update with zero the ones we know about that are not active */

    if (purge)
    {
/* Acquire a cursor for the database and downgrade classes that did not
 get defined this time*/

        if (!NewDBCursor(dbp, &dbcp))
        {
            CfOut(cf_inform, "", " !! Unable to scan class db");
            CloseDB(dbp);
            DeleteItemList(list);
            return;
        }

        memset(&entry, 0, sizeof(entry));

        while (NextDB(dbp, dbcp, &key, &ksize, &stored, &vsize))
        {
            time_t then;
            char eventname[CF_BUFSIZE];

            memset(eventname, 0, CF_BUFSIZE);
            strncpy(eventname, (char *) key, ksize);

            if (stored != NULL)
            {
                memcpy(&entry, stored, sizeof(entry));

                then = entry.t;
                lastseen = now - then;

                if (lastseen > lsea)
                {
                    CfDebug("Class usage record %s expired\n", eventname);
                    DBCursorDeleteEntry(dbcp);
                }
                else if (!IsItemIn(list, eventname))
                {
                    newe.t = then;

                    newe.Q = QAverage(entry.Q, 0, 0.5);

                    if (newe.Q.expect <= 0.0001)
                    {
                        CfDebug("Deleting class %s as %lf is zero\n", eventname, newe.Q.expect);
                        DBCursorDeleteEntry(dbcp);
                    }
                    else
                    {
                        CfDebug("Downgrading class %s from %lf to %lf\n", eventname, entry.Q.expect, newe.Q.expect);
                        DBCursorWriteEntry(dbcp, &newe, sizeof(newe));
                    }
                }
            }
        }

        DeleteDBCursor(dbp, dbcp);
    }

    CloseDB(dbp);
    DeleteItemList(list);
}
示例#12
0
PromiseResult PurgeHashes(EvalContext *ctx, char *path, Attributes attr, const Promise *pp)
/* Go through the database and purge records about non-existent files */
{
    CF_DB *dbp;
    CF_DBC *dbcp;
    struct stat statbuf;
    int ksize, vsize;
    char *key;
    void *value;

    if (!OpenDB(&dbp,dbid_checksums))
    {
        return PROMISE_RESULT_NOOP;
    }

    if (path)
    {
        if (stat(path, &statbuf) == -1)
        {
            DeleteDB(dbp, path);
        }
        CloseDB(dbp);
        return PROMISE_RESULT_NOOP;
    }

/* Acquire a cursor for the database. */

    if (!NewDBCursor(dbp, &dbcp))
    {
        Log(LOG_LEVEL_INFO, "Unable to scan hash database");
        CloseDB(dbp);
        return PROMISE_RESULT_NOOP;
    }

    /* Walk through the database and print out the key/data pairs. */

    PromiseResult result = PROMISE_RESULT_NOOP;
    while (NextDB(dbcp, &key, &ksize, &value, &vsize))
    {
        char *obj = (char *) key + CF_INDEX_OFFSET;

        if (stat(obj, &statbuf) == -1)
        {
            if (attr.change.update)
            {
                DBCursorDeleteEntry(dbcp);
            }
            else
            {
                cfPS(ctx, LOG_LEVEL_NOTICE, PROMISE_RESULT_WARN, pp, attr, "File '%s' no longer exists", obj);
                result = PromiseResultUpdate(result, PROMISE_RESULT_WARN);
            }

            LogHashChange(obj, FILE_STATE_REMOVED, "File removed", pp);
        }
    }

    DeleteDBCursor(dbcp);
    CloseDB(dbp);

    return result;
}
示例#13
0
void RecordPerformance(char *eventname,time_t t,double value)

{ DB *dbp;
  DB_ENV *dbenv = NULL;
  char name[CF_BUFSIZE];
  struct Event e,newe;
  double lastseen,delta2;
  int lsea = CF_WEEK;
  time_t now = time(NULL);

Debug("PerformanceEvent(%s,%.1f s)\n",eventname,value);

snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_PERFORMANCE);

if ((errno = db_create(&dbp,dbenv,0)) != 0)
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open performance database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

#ifdef CF_OLD_DB
if ((errno = (dbp->open)(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#else
if ((errno = (dbp->open)(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#endif
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open performance database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

if (ReadDB(dbp,eventname,&e,sizeof(e)))
   {
   lastseen = now - e.t;
   newe.t = t;
   newe.Q.q = value;
   newe.Q.expect = GAverage(value,e.Q.expect,0.3);
   delta2 = (value - e.Q.expect)*(value - e.Q.expect);
   newe.Q.var = GAverage(delta2,e.Q.var,0.3);

   /* Have to kickstart variance computation, assume 1% to start  */
   
   if (newe.Q.var <= 0.0009)
      {
      newe.Q.var =  newe.Q.expect / 100.0;
      }
   }
else
   {
   lastseen = 0.0;
   newe.t = t;
   newe.Q.q = value;
   newe.Q.expect = value;
   newe.Q.var = 0.001;
   }

if (lastseen > (double)lsea)
   {
   Verbose("Performance record %s expired\n",eventname);
   DeleteDB(dbp,eventname);   
   }
else
   {
   Verbose("Performance(%s): time=%.4f secs, av=%.4f +/- %.4f\n",eventname,value,newe.Q.expect,sqrt(newe.Q.var));
   WriteDB(dbp,eventname,&newe,sizeof(newe));
   }

dbp->close(dbp,0);
}
示例#14
0
void CheckFriendConnections(int hours)

/* Go through the database of recent connections and check for
   Long Time No See ...*/

{ DBT key,value;
  DB *dbp;
  DBC *dbcp;
  DB_ENV *dbenv = NULL;
  int ret, secs = CF_TICKS_PER_HOUR*hours, criterion, overdue, regex=false;
  time_t now = time(NULL),lsea = -1, tthen, then = 0;
  char name[CF_BUFSIZE],hostname[CF_BUFSIZE],datebuf[CF_MAXVARSIZE];
  char addr[CF_BUFSIZE],type[CF_BUFSIZE], *regexp;
  struct QPoint entry;
  double average = 0.0, var = 0.0, ticksperminute = 60.0;
  double ticksperhour = (double)CF_TICKS_PER_HOUR,ticksperday = (double)CF_TICKS_PER_DAY;
  regex_t rx,rxcache;
  regmatch_t pmatch;

if (regexp = GetMacroValue(CONTEXTID,"IgnoreFriendRegex"))
   {
   Verbose("IgnoreFriendRegex %s\n\n",regexp);
   if ((ret = regcomp(&rx,regexp,REG_EXTENDED)) != 0)
      {
      regerror(ret,&rx,name,1023);
      snprintf(OUTPUT,CF_BUFSIZE,"Regular expression error %d for %s: %s\n",ret,regexp,name);
      CfLog(cfinform,OUTPUT,"");
      regex = false;
      }
   else
      {
      regex = true;
      }
   }
 
Verbose("CheckFriendConnections(%d)\n",hours);
snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_LASTDB_FILE);

if ((errno = db_create(&dbp,dbenv,0)) != 0)
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

#ifdef CF_OLD_DB
if ((errno = (dbp->open)(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#else
if ((errno = (dbp->open)(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#endif
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

/* Acquire a cursor for the database. */

if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0)
   {
   CfLog(cferror,"Error reading from last-seen database","");
   dbp->err(dbp, ret, "DB->cursor");
   return;
   }

 /* Walk through the database and print out the key/data pairs. */

memset(&key, 0, sizeof(key));
memset(&value, 0, sizeof(value));

while (dbcp->c_get(dbcp, &key, &value, DB_NEXT) == 0)
   {
   memset(&entry, 0, sizeof(entry)); 

   strcpy(hostname,(char *)key.data);

   if (value.data != NULL)
      {
      memcpy(&entry,value.data,sizeof(entry));
      then = (time_t)entry.q;
      average = (double)entry.expect;
      var = (double)entry.var;
      }
   else
      {
      continue;
      }

   /* Got data, now get expiry criterion */

   if (secs == 0)
      {
      /* Twice the average delta is significant */
      criterion = (now - then > (int)(average+2.0*sqrt(var)+0.5));
      overdue = now - then - (int)(average);
      }
   else
      {
      criterion = (now - then > secs);
      overdue =  (now - then - secs);
      }

   if (GetMacroValue(CONTEXTID,"LastSeenExpireAfter"))
      {
      lsea = atoi(GetMacroValue(CONTEXTID,"LastSeenExpireAfter"));
      lsea *= CF_TICKS_PER_DAY;
      }

   if (lsea < 0)
      {
      lsea = (time_t)CF_WEEK/7;
      }

   if (regex)
      {
      if (regexec(&rx,IPString2Hostname(hostname+1),1,&pmatch,0) == 0)
         {
         if ((pmatch.rm_so == 0) && (pmatch.rm_eo == strlen(hostname+1)))
            {
            Verbose("Not judging friend %s\n",hostname);
            criterion = false;
            lsea = CF_INFINITY;
            }
         }
      }
   
   tthen = (time_t)then;

   snprintf(datebuf,CF_BUFSIZE-1,"%s",ctime(&tthen));
   datebuf[strlen(datebuf)-9] = '\0';                     /* Chop off second and year */

   snprintf(addr,15,"%s",hostname+1);

   switch(*hostname)
      {
      case '+':
          snprintf(type,CF_BUFSIZE,"last responded to hails");
          break;
      case'-':
          snprintf(type,CF_BUFSIZE,"last hailed us");
          break;
      }

   snprintf(OUTPUT,CF_BUFSIZE,"Host %s i.e. %s %s @ [%s] (overdue by %d mins)",
            IPString2Hostname(hostname+1),
            addr,
            type,
            datebuf,
            overdue/(int)ticksperminute);

   if (criterion)
      {
      CfLog(cferror,OUTPUT,"");
      }
   else
      {
      CfLog(cfverbose,OUTPUT,"");
      }

   snprintf(OUTPUT,CF_BUFSIZE,"i.e. (%.2f) hrs ago, Av %.2f +/- %.2f hrs\n",
            ((double)(now-then))/ticksperhour,
            average/ticksperhour,
            sqrt(var)/ticksperhour);
   
   if (criterion)
      {
      CfLog(cferror,OUTPUT,"");
      }
   else
      {
      CfLog(cfverbose,OUTPUT,"");
      }
   
   if ((now-then) > lsea)
      {
      snprintf(OUTPUT,CF_BUFSIZE,"Giving up on host %s -- too long since last seen",IPString2Hostname(hostname+1));
      CfLog(cferror,OUTPUT,"");
      DeleteDB(dbp,hostname);
      }

   memset(&value,0,sizeof(value));
   memset(&key,0,sizeof(key)); 
   }
 
dbcp->c_close(dbcp);
dbp->close(dbp,0);
}
示例#15
0
void LastSeen(char *hostname,enum roles role)

{ DB *dbp,*dbpent;
  DB_ENV *dbenv = NULL, *dbenv2 = NULL;
  char name[CF_BUFSIZE],databuf[CF_BUFSIZE];
  time_t now = time(NULL);
  struct QPoint q,newq;
  double lastseen,delta2;
  int lsea = -1;

if (strlen(hostname) == 0)
   {
   snprintf(OUTPUT,CF_BUFSIZE,"LastSeen registry for empty hostname with role %d",role);
   CfLog(cflogonly,OUTPUT,"");
   return;
   }

Debug("LastSeen(%s) reg\n",hostname);

/* Tidy old versions - temporary */
snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_OLDLASTDB_FILE);
unlink(name);

if ((errno = db_create(&dbp,dbenv,0)) != 0)
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't init last-seen database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_LASTDB_FILE);

#ifdef CF_OLD_DB
if ((errno = (dbp->open)(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#else
if ((errno = (dbp->open)(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#endif
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

/* Now open special file for peer entropy record - INRIA intermittency */
snprintf(name,CF_BUFSIZE-1,"%s/%s.%s",CFWORKDIR,CF_LASTDB_FILE,hostname);

if ((errno = db_create(&dbpent,dbenv2,0)) != 0)
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't init last-seen database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

#ifdef CF_OLD_DB
if ((errno = (dbpent->open)(dbpent,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#else
if ((errno = (dbpent->open)(dbpent,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#endif
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }


#ifdef HAVE_PTHREAD_H  
if (pthread_mutex_lock(&MUTEX_GETADDR) != 0)
   {
   CfLog(cferror,"pthread_mutex_lock failed","unlock");
   exit(1);
   }
#endif

switch (role)
   {
   case cf_accept:
       snprintf(databuf,CF_BUFSIZE-1,"-%s",Hostname2IPString(hostname));
       break;
   case cf_connect:
       snprintf(databuf,CF_BUFSIZE-1,"+%s",Hostname2IPString(hostname));
       break;
   }

#ifdef HAVE_PTHREAD_H  
if (pthread_mutex_unlock(&MUTEX_GETADDR) != 0)
   {
   CfLog(cferror,"pthread_mutex_unlock failed","unlock");
   exit(1);
   }
#endif


if (GetMacroValue(CONTEXTID,"LastSeenExpireAfter"))
   {
   lsea = atoi(GetMacroValue(CONTEXTID,"LastSeenExpireAfter"));
   lsea *= CF_TICKS_PER_DAY;
   }

if (lsea < 0)
   {
   lsea = CF_WEEK;
   }
   
if (ReadDB(dbp,databuf,&q,sizeof(q)))
   {
   lastseen = (double)now - q.q;
   newq.q = (double)now;                   /* Last seen is now-then */
   newq.expect = GAverage(lastseen,q.expect,0.3);
   delta2 = (lastseen - q.expect)*(lastseen - q.expect);
   newq.var = GAverage(delta2,q.var,0.3);
   }
else
   {
   lastseen = 0.0;
   newq.q = (double)now;
   newq.expect = 0.0;
   newq.var = 0.0;
   }

#ifdef HAVE_PTHREAD_H  
if (pthread_mutex_lock(&MUTEX_GETADDR) != 0)
   {
   CfLog(cferror,"pthread_mutex_lock failed","unlock");
   exit(1);
   }
#endif

if (lastseen > (double)lsea)
   {
   Verbose("Last seen %s expired\n",databuf);
   DeleteDB(dbp,databuf);   
   }
else
   {
   WriteDB(dbp,databuf,&newq,sizeof(newq));
   WriteDB(dbpent,GenTimeKey(now),&newq,sizeof(newq));
   }

#ifdef HAVE_PTHREAD_H  
if (pthread_mutex_unlock(&MUTEX_GETADDR) != 0)
   {
   CfLog(cferror,"pthread_mutex_unlock failed","unlock");
   exit(1);
   }
#endif

dbp->close(dbp,0);
dbpent->close(dbpent,0);
}
示例#16
0
void RecordClassUsage()

{ DB *dbp;
  DB_ENV *dbenv = NULL;
  DBC *dbcp;
  DBT key,stored;
  char name[CF_BUFSIZE];
  struct Event e,entry,newe;
  double lsea = CF_WEEK * 52; /* expire after a year */
  time_t now = time(NULL);
  struct Item *ip,*list = NULL;
  double lastseen,delta2;
  double vtrue = 1.0;      /* end with a rough probability */

Debug("RecordClassUsage\n");

for (ip = VHEAP; ip != NULL; ip=ip->next)
   {
   if (!IsItemIn(list,ip->name))
      {
      PrependItem(&list,ip->name,NULL);
      }
   }

for (ip = VALLADDCLASSES; ip != NULL; ip=ip->next)
   {
   if (!IsItemIn(list,ip->name))
      {
      PrependItem(&list,ip->name,NULL);
      }
   }
   
snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_CLASSUSAGE);

if ((errno = db_create(&dbp,dbenv,0)) != 0)
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open performance database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

#ifdef CF_OLD_DB
if ((errno = (dbp->open)(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#else
if ((errno = (dbp->open)(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
#endif
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open performance database %s\n",name);
   CfLog(cferror,OUTPUT,"db_open");
   return;
   }

/* First record the classes that are in use */

for (ip = list; ip != NULL; ip=ip->next)
   {
   if (ReadDB(dbp,ip->name,&e,sizeof(e)))
      {
      lastseen = now - e.t;
      newe.t = now;
      newe.Q.q = vtrue;
      newe.Q.expect = GAverage(vtrue,e.Q.expect,0.5);
      delta2 = (vtrue - e.Q.expect)*(vtrue - e.Q.expect);
      newe.Q.var = GAverage(delta2,e.Q.var,0.5);
      }
   else
      {
      lastseen = 0.0;
      newe.t = now;
      newe.Q.q = 0.5*vtrue;
      newe.Q.expect = 0.5*vtrue;  /* With no data it's 50/50 what we can say */
      newe.Q.var = 0.000;
      }
   
   if (lastseen > lsea)
      {
      Verbose("Class usage record %s expired\n",ip->name);
      DeleteDB(dbp,ip->name);   
      }
   else
      {
      Debug("Upgrading %s %f\n",ip->name,newe.Q.expect);
      WriteDB(dbp,ip->name,&newe,sizeof(newe));
      }
   }

/* Then update with zero the ones we know about that are not active */

/* Acquire a cursor for the database. */

if ((errno = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0)
   {
   Debug("Error reading from class database: ");
   dbp->err(dbp, errno, "DB->cursor");
   return;
   }

 /* Initialize the key/data return pair. */
 
memset(&key, 0, sizeof(key));
memset(&stored, 0, sizeof(stored));
memset(&entry, 0, sizeof(entry)); 

while (dbcp->c_get(dbcp, &key, &stored, DB_NEXT) == 0)
   {
   double measure,av,var;
   time_t then;
   char tbuf[CF_BUFSIZE],eventname[CF_BUFSIZE];

   strcpy(eventname,(char *)key.data);

   if (stored.data != NULL)
      {
      memcpy(&entry,stored.data,sizeof(entry));
      
      then    = entry.t;
      measure = entry.Q.q;
      av = entry.Q.expect;
      var = entry.Q.var;
      lastseen = now - then;
            
      snprintf(tbuf,CF_BUFSIZE-1,"%s",ctime(&then));
      tbuf[strlen(tbuf)-9] = '\0';                     /* Chop off second and year */

      if (lastseen > lsea)
         {
         Verbose("Class usage record %s expired\n",eventname);
         DeleteDB(dbp,eventname);   
         }
      else if (!IsItemIn(list,eventname))
         {
         newe.t = then;
         newe.Q.q = 0;
         newe.Q.expect = GAverage(0.0,av,0.5);
         delta2 = av*av;
         newe.Q.var = GAverage(delta2,var,0.5);
         Debug("Downgrading class %s from %lf to %lf\n",eventname,entry.Q.expect,newe.Q.expect);
         WriteDB(dbp,eventname,&newe,sizeof(newe));         
         }
      }
   }

dbp->close(dbp,0);
}
示例#17
0
void UpdateLastSeen() // This function is temporarily or permanently deprecated

{ double lsea = LASTSEENEXPIREAFTER;
  int intermittency = false,qsize,ksize;
  struct CfKeyHostSeen q,newq; 
  double lastseen,delta2;
  void *stored;
  CF_DB *dbp = NULL,*dbpent = NULL;
  CF_DBC *dbcp;
  char name[CF_BUFSIZE],*key;
  struct Rlist *rp;
  struct CfKeyBinding *kp;
  time_t now = time(NULL);
  static time_t then;
  
if (now < then + 300 && then > 0 && then <= now + 300)
   {
   // Rate limiter
   return;
   }

then = now;

CfOut(cf_verbose,""," -> Writing last-seen observations");

ThreadLock(cft_server_keyseen);

if (SERVER_KEYSEEN == NULL)
   {
   ThreadUnlock(cft_server_keyseen);
   CfOut(cf_verbose,""," -> Keyring is empty");
   return;
   }

if (BooleanControl("control_agent",CFA_CONTROLBODY[cfa_intermittency].lval))
   {
   CfOut(cf_inform,""," -> Recording intermittency");
   intermittency = true;
   }

snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_LASTDB_FILE);
MapName(name);

if (!OpenDB(name,&dbp))
   {
   ThreadUnlock(cft_server_keyseen);
   return;
   }

/* First scan for hosts that have moved address and purge their records so that
   the database always has a 1:1 relationship between keyhash and IP address    */

if (!NewDBCursor(dbp,&dbcp))
   {
   ThreadUnlock(cft_server_keyseen);
   CfOut(cf_inform,""," !! Unable to scan class db");
   return;
   }

while(NextDB(dbp,dbcp,&key,&ksize,&stored,&qsize))
   {
   memcpy(&q,stored,sizeof(q));

   lastseen = (double)now - q.Q.q;

   if (lastseen > lsea)
      {
      CfOut(cf_verbose,""," -> Last-seen record for %s expired after %.1lf > %.1lf hours\n",key,lastseen/3600,lsea/3600);
      DeleteDB(dbp,key);
      }

   for (rp = SERVER_KEYSEEN; rp !=  NULL; rp=rp->next)
      {
      kp = (struct CfKeyBinding *) rp->item;
      
      if ((strcmp(q.address,kp->address) == 0) && (strcmp(key+1,kp->name+1) != 0))
         {
         CfOut(cf_verbose,""," ! Deleting %s's address (%s=%d) as this host %s seems to have moved elsewhere (%s=5d)",key,kp->address,strlen(kp->address),kp->name,q.address,strlen(q.address));
         DeleteDB(dbp,key);
         }
      }

   }

DeleteDBCursor(dbp,dbcp);

/* Now perform updates with the latest data */

for (rp = SERVER_KEYSEEN; rp !=  NULL; rp=rp->next)
   {
   kp = (struct CfKeyBinding *) rp->item;

   now = kp->timestamp;
   
   if (intermittency)
      {
      /* Open special file for peer entropy record - INRIA intermittency */
      snprintf(name,CF_BUFSIZE-1,"%s/lastseen/%s.%s",CFWORKDIR,CF_LASTDB_FILE,kp->name);
      MapName(name);
      
      if (!OpenDB(name,&dbpent))
         {
         continue;
         }
      }
   
   if (ReadDB(dbp,kp->name,&q,sizeof(q)))
      {
      lastseen = (double)now - q.Q.q;
      
      if (q.Q.q <= 0)
         {
         lastseen = 300;
         q.Q.expect = 0;
         q.Q.var = 0;
         }
      
      newq.Q.q = (double)now;
      newq.Q.expect = GAverage(lastseen,q.Q.expect,0.4);
      delta2 = (lastseen - q.Q.expect)*(lastseen - q.Q.expect);
      newq.Q.var = GAverage(delta2,q.Q.var,0.4);
      strncpy(newq.address,kp->address,CF_ADDRSIZE-1);
      }
   else
      {
      lastseen = 0.0;
      newq.Q.q = (double)now;
      newq.Q.expect = 0.0;
      newq.Q.var = 0.0;
      strncpy(newq.address,kp->address,CF_ADDRSIZE-1);
      }
   
   if (lastseen > lsea)
      {
      CfOut(cf_verbose,""," -> Last-seen record for %s expired after %.1lf > %.1lf hours\n",kp->name,lastseen/3600,lsea/3600);
      DeleteDB(dbp,kp->name);
      }
   else
      {
      char timebuf[26];
      CfOut(cf_verbose,""," -> Last saw %s (alias %s) at %s (noexpiry %.1lf <= %.1lf)\n",kp->name,kp->address,cf_strtimestamp_local(now,timebuf),lastseen/3600,lsea/3600);

      WriteDB(dbp,kp->name,&newq,sizeof(newq));
      
      if (intermittency)
         {
         WriteDB(dbpent,GenTimeKey(now),&newq,sizeof(newq));
         }
      }
   
   if (intermittency && dbpent)
      {
      CloseDB(dbpent);
      }
   }

ThreadUnlock(cft_server_keyseen);
}
示例#18
0
static void VerifyFriendConnections(int hours,struct Attributes a,struct Promise *pp)

/* Go through the database of recent connections and check for
   Long Time No See ...*/

{ CF_DB *dbp;
  CF_DBC *dbcp;
  char *key;
  void *value;
  int ksize,vsize;
  int secs = SECONDS_PER_HOUR*hours, criterion, overdue;
  time_t now = time(NULL),lsea = (time_t)CF_WEEK, tthen, then;
  char name[CF_BUFSIZE],hostname[CF_BUFSIZE],datebuf[CF_MAXVARSIZE];
  char addr[CF_BUFSIZE],type[CF_BUFSIZE],output[CF_BUFSIZE];
  struct QPoint entry;
  double average = 0.0, var = 0.0, ticksperminute = 60.0;
  double ticksperhour = (double)SECONDS_PER_HOUR;

CfOut(cf_verbose,"","CheckFriendConnections(%d)\n",hours);
snprintf(name,CF_BUFSIZE-1,"%s/lastseen/%s",CFWORKDIR,CF_LASTDB_FILE);
MapName(name);

if (!OpenDB(name,&dbp))
   {
   return;
   }

/* Acquire a cursor for the database. */

if (!NewDBCursor(dbp,&dbcp))
   {
   CfOut(cf_inform,""," !! Unable to scan friend db");
   return;
   }

 /* Walk through the database and print out the key/data pairs. */

while(NextDB(dbp,dbcp,&key,&ksize,&value,&vsize))
   {
   memset(&entry, 0, sizeof(entry)); 

   strncpy(hostname,(char *)key,ksize);

   if (value != NULL)
      {
      memcpy(&entry,value,sizeof(entry));
      then = (time_t)entry.q;
      average = (double)entry.expect;
      var = (double)entry.var;
      }
   else
      {
      continue;
      }

   if (then == 0)
      {
      continue; // No data
      }
   
   /* Got data, now get expiry criterion */

   if (secs == 0)
      {
      /* Twice the average delta is significant */
      criterion = (now - then > (int)(average+2.0*sqrt(var)+0.5));
      overdue = now - then - (int)(average);
      }
   else
      {
      criterion = (now - then > secs);
      overdue =  (now - then - secs);
      }

   if (LASTSEENEXPIREAFTER < 0)
      {
      lsea = (time_t)CF_WEEK;
      }
   else
      {
      lsea = LASTSEENEXPIREAFTER;
      }

   if (a.report.friend_pattern)
      {
      if (FullTextMatch(a.report.friend_pattern,IPString2Hostname(hostname+1)))
         {
         CfOut(cf_verbose,"","Not judging friend %s\n",hostname);
         criterion = false;
         lsea = CF_INFINITY;
         }
      }
   
   tthen = (time_t)then;

   snprintf(datebuf,CF_MAXVARSIZE-1,"%s",cf_ctime(&tthen));
   datebuf[strlen(datebuf)-9] = '\0';                     /* Chop off second and year */

   snprintf(addr,15,"%s",hostname+1);

   switch(*hostname)
      {
      case '+':
          snprintf(type,CF_BUFSIZE,"last responded to hails");
          break;
      case'-':
          snprintf(type,CF_BUFSIZE,"last hailed us");
          break;
      }

   snprintf(output,CF_BUFSIZE,"Host %s i.e. %s %s @ [%s] (overdue by %d mins)",
            IPString2Hostname(hostname+1),
            addr,
            type,
            datebuf,
            overdue/(int)ticksperminute);

   if (criterion)
      {
      CfOut(cf_error,"",output);
      }
   else
      {
      CfOut(cf_verbose,"",output);
      }

   snprintf(output,CF_BUFSIZE,"i.e. (%.2f) hrs ago, Av %.2f +/- %.2f hrs\n",
            ((double)(now-then))/ticksperhour,
            average/ticksperhour,
            sqrt(var)/ticksperhour);
   
   if (criterion)
      {
      CfOut(cf_error,"",output);
      }
   else
      {
      CfOut(cf_verbose,"",output);
      }

   if (now - then > lsea)
      {
      CfOut(cf_error,"","Giving up on host %s -- %d hours since last seen",IPString2Hostname(hostname+1),hours);
      DeleteDB(dbp,hostname);
      }
  
   memset(&value,0,sizeof(value));
   memset(&key,0,sizeof(key)); 
   }

DeleteDBCursor(dbp,dbcp);
CloseDB(dbp);
}