Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

scoreboard.c

Go to the documentation of this file.
00001 #include "scoreboard.h"
00002 #include "util_math.h" /* calc % */
00003 
00004 static SCORE_ENTRY s_init_entry; /* static entry that will always be zeroed out at init */
00005 
00006 /* utility */
00007 static void sb_init_entry(void);
00008 static int scoreboard_anrfree(void *key, void *data);
00009 static int scoreboard_usrfree(void *key, void *data);
00010 
00011 static INLINE int scoreboard_lru(SCOREBOARD *sbp, SCORE_ENTRY **sepp);
00012 static INLINE int scoreboard_mru(SCOREBOARD *sbp, SCORE_ENTRY **sepp);
00013 
00014 
00015 /** 
00016  * Create a new scoreboard for tracking nodes.
00017  * 
00018  * @param sbp scoreboard to initialize
00019  * @param at_thr active talker thresholds
00020  * @param sc_thr scanner thresholds (may not be needed)
00021  * @param kind tracker location for this table 
00022  * @param description table description
00023  * @param rows number of rows to populate the initial HASHTABLE() with
00024  * @param memcap bytes we can spend on this scoreboard
00025  * 
00026  * @return FLOW_SUCCESS on success, else failure
00027  */
00028 int scoreboard_init(SCOREBOARD *sbp,
00029                     char *description,
00030                     TRACKER_POSITION kind,
00031                     unsigned int rows,
00032                     int memcap)
00033 {
00034     
00035     if(!sbp || !description)
00036     {
00037         return FLOW_ENULL;
00038     }
00039     
00040     if(rows < 1)
00041         return FLOW_EINVALID;
00042 
00043     if(memcap < (sizeof(SCORE_ENTRY) + sizeof(SFXHASH_NODE)))
00044         return FLOW_EINVALID;
00045 
00046     /* initialize s_init_entry*/
00047     sb_init_entry();
00048 
00049     memset(sbp, 0, sizeof(SCOREBOARD));
00050 
00051     snprintf(sbp->description, SDESC_SIZE - 1, description);
00052     sbp->description[SDESC_SIZE - 1] = '\0';
00053      
00054     /* what size should we do? */
00055     sbp->ipv4_table = sfxhash_new(rows,               /* # of rows in HT*/
00056                                   sizeof(u_int32_t),    /* size of the key  */
00057                                   sizeof(SCORE_ENTRY), /* data size */
00058                                   memcap,              /* how much memory is alloted */
00059                                   1,                   /* auto recover nodes */
00060                                   scoreboard_anrfree, /* autorecovery function */
00061                                   scoreboard_usrfree, /* free function for the data */
00062                                   1);                 /* recycle old nodes */
00063 
00064     if(sbp->ipv4_table == NULL)
00065     {
00066         flow_printf("Unable to create scoreboard table!\n");
00067         return FLOW_ENOMEM;
00068     }
00069 
00070     sbp->kind = kind;
00071 
00072     return FLOW_SUCCESS;
00073 }
00074 
00075 int scoreboard_destroy(SCOREBOARD *sbp)
00076 {
00077     if(!sbp || !sbp->ipv4_table)
00078     {
00079         return FLOW_ENULL;
00080     }
00081 
00082     sfxhash_delete(sbp->ipv4_table);
00083 
00084     sbp->ipv4_table = NULL;
00085     
00086     return FLOW_SUCCESS;    
00087 }
00088 
00089 int scoreboard_add(SCOREBOARD *sbp, u_int32_t *address, SCORE_ENTRY **sepp)
00090 {
00091     int ret;
00092     
00093     if(!sbp)
00094     {
00095         return FLOW_ENULL;
00096     }
00097 
00098     ret = sfxhash_add(sbp->ipv4_table, address, &s_init_entry);
00099 
00100     switch(ret)
00101     {
00102     case SFXHASH_OK:
00103         if(scoreboard_mru(sbp,sepp) != FLOW_SUCCESS)
00104         {
00105             /* something's wrong because we just added this thing!\n */
00106             flow_printf("sba: Unable to find a key I just added!\n");
00107             return FLOW_BADJUJU;
00108         }
00109 
00110         return FLOW_SUCCESS;
00111         
00112     case SFXHASH_NOMEM:
00113         return FLOW_ENOMEM;
00114     case SFXHASH_INTABLE:
00115     default:
00116         return FLOW_EINVALID;
00117     }
00118   
00119     return FLOW_SUCCESS;    
00120 }
00121 
00122 /** 
00123  * Remove a node from the scoreboard
00124  * 
00125  * @param sbp scoreboard to modify
00126  * @param address address to remove
00127  * 
00128  * @return FLOW_SUCCESS on success
00129  */
00130 int scoreboard_remove(SCOREBOARD *sbp, u_int32_t *address)
00131 {
00132     if(!sbp)
00133     {
00134         return FLOW_ENULL;
00135     }
00136 
00137     if(sfxhash_remove(sbp->ipv4_table, address) != 0)
00138     {
00139         return FLOW_NOTFOUND;
00140     }
00141     
00142     return FLOW_SUCCESS;    
00143 }
00144 
00145 int scoreboard_find(SCOREBOARD *sbp, u_int32_t *address, SCORE_ENTRY **sepp)
00146 {
00147     if(!sbp || !address || !sepp)
00148         return FLOW_ENULL;
00149 
00150     /* printf("looking for %s\n", inet_ntoa(*(struct in_addr *) address)); */
00151 
00152     *sepp = sfxhash_find(sbp->ipv4_table, address);
00153 
00154     if(*sepp == NULL)
00155         return FLOW_NOTFOUND;
00156     
00157     return FLOW_SUCCESS;
00158 }
00159 
00160 /** 
00161  * Move a scoreboard entry from one table to the other
00162  *
00163  * @todo This actually can probably be done faster with the rindex
00164  *       stuff and a SFXHASH_NODE interface.
00165  * 
00166  * @param dst where to move the address to
00167  * @param src where to move the address from
00168  * @param address the address to move
00169  * 
00170  * @return FLOW_SUCCESS on success
00171  */
00172 int scoreboard_move(SCOREBOARD *dst, SCOREBOARD *src, u_int32_t *address)
00173 {
00174     SCORE_ENTRY *src_entry, *dst_entry;
00175     
00176     if(!src || !dst)
00177     {
00178         return FLOW_ENULL;
00179     }
00180 
00181     if(scoreboard_find(src, address, &src_entry) != FLOW_SUCCESS)
00182     {
00183         return FLOW_NOTFOUND;
00184     }
00185 
00186     if(scoreboard_add(dst, address, &dst_entry) != FLOW_SUCCESS)
00187     {
00188         return FLOW_EINVALID;
00189     }
00190 
00191     memcpy(dst_entry,src_entry,sizeof(SCORE_ENTRY));
00192 
00193     dst_entry->position = dst->kind;
00194     
00195     if(scoreboard_remove(src, address) != FLOW_SUCCESS)
00196     {
00197         /* small problem here in that we have 2 versions of the same
00198            thing going on */           
00199         return FLOW_BADJUJU;
00200     }
00201     
00202     return FLOW_SUCCESS;
00203 }
00204 
00205 /** 
00206  * Print out the entirety of the scoreboard
00207  * 
00208  * @param ssp unique tracker
00209  */
00210 void scoreboard_dump(SCOREBOARD *ssp)
00211 {
00212     SFXHASH_NODE *nodep;
00213 
00214     if(ssp && ssp->ipv4_table)
00215     {
00216         for( nodep = sfxhash_ghead(ssp->ipv4_table);
00217              nodep != NULL;
00218              nodep = sfxhash_gnext(nodep) )
00219         {
00220             u_int32_t  *address = (u_int32_t *) nodep->key;
00221             SCORE_ENTRY *entry = (SCORE_ENTRY *) nodep->data;
00222             flowps_entry_print(entry, address);
00223         }
00224     }
00225     else
00226     {
00227         flow_printf("nothing to dump!\n");
00228     }
00229 }
00230 
00231 
00232 void scoreboard_stats(SCOREBOARD *sbp, int dumpall)
00233 {
00234     unsigned total = sfxhash_find_total(sbp->ipv4_table);
00235     unsigned fail = sfxhash_find_fail(sbp->ipv4_table);
00236     unsigned success = sfxhash_find_success(sbp->ipv4_table);
00237     
00238     flow_printf("SCOREBOARD_STATS: %s\n", (char *) sbp->description);
00239     flow_printf("   Memcap: %u  Overhead Bytes: %u\n",
00240                 sbp->ipv4_table->mc.memcap,
00241                 sfxhash_overhead_bytes(sbp->ipv4_table));
00242     
00243     flow_printf("   Finds: %u (Sucessful: %u(%%%lf) Unsucessful: %u(%%%lf))\n",
00244                 total,
00245                 success, calc_percent(success,total),
00246                 fail, calc_percent(fail,total));
00247 
00248     flow_printf("   Nodes: %u\n", sfxhash_count(sbp->ipv4_table));
00249     
00250     flow_printf("   Recovered Nodes: %u\n", sfxhash_anr_count(sbp->ipv4_table));
00251     flow_printf("   Score Entry Size:: %u\n", sizeof(SCORE_ENTRY));
00252 
00253     if(dumpall)
00254         scoreboard_dump(sbp);
00255 }
00256 
00257 /** 
00258  * initialize the static s_init_entry variable once and only
00259  * once. This is used to zero out the key so that if the compiler pads
00260  * the structure, we still have 0's in this keylookup.
00261  * 
00262  */
00263 static void sb_init_entry(void)
00264 {
00265     static int init_once = 1;
00266 
00267     if(init_once)
00268     {
00269         init_once = 0;
00270         memset(&s_init_entry, 0, sizeof(SCORE_ENTRY));
00271     }
00272     
00273 }
00274 
00275 /** 
00276  * Get the most recently used flow from the cache
00277  * 
00278  * @param sbp scoreboard to find
00279  * @param sepp score entry pointer to fill in
00280  * 
00281  * @return FLOW_SUCCESS on sucess
00282  */
00283 static INLINE int scoreboard_mru(SCOREBOARD *sbp, SCORE_ENTRY **sepp)
00284 {
00285     if(!sbp || !sepp)
00286         return FLOW_EINVALID;
00287 
00288     *sepp = sfxhash_mru(sbp->ipv4_table);
00289 
00290     if(*sepp == NULL)
00291         return FLOW_NOTFOUND;
00292     
00293     return FLOW_SUCCESS;
00294 }
00295 
00296 /** 
00297  * Get the least recently used flow from the cache
00298  * 
00299  * @param sbp scoreboard to find
00300  * @param sepp score entry pointer to fill in
00301  * 
00302  * @return FLOW_SUCCESS on sucess
00303  */
00304 static INLINE int scoreboard_lru(SCOREBOARD *sbp, SCORE_ENTRY **sepp)
00305 {
00306     if(!sbp || !sepp)
00307         return FLOW_EINVALID;
00308 
00309     *sepp = sfxhash_lru(sbp->ipv4_table);
00310 
00311     if(*sepp == NULL)
00312         return FLOW_NOTFOUND;
00313     
00314     return FLOW_SUCCESS;
00315 }
00316 
00317 
00318 
00319 /** 
00320  * Automatically recover nodes and make sure that all the other
00321  * references are taken care of.
00322  * 
00323  * @param key hash key
00324  * @param data scoreboard entry
00325  * 
00326  * @return 0 if this node can be removed
00327  */
00328 static int scoreboard_anrfree(void *key, void *data)
00329 {
00330     return 0;
00331 }
00332 
00333 
00334 /** 
00335  * Automatically recover nodes and make sure that all the other
00336  * references are taken care of.
00337  * 
00338  * @param key hash key
00339  * @param data scoreboard entry
00340  * 
00341  * @return 0 if this node can be removed
00342  */
00343 static int scoreboard_usrfree(void *key, void *data)
00344 {
00345     return 0;
00346 }
00347 
00348 /** 
00349  * get the memcap
00350  * 
00351  * @param sbp scoreboard ptr to return the memcap of
00352  * 
00353  * @return memcap or -1
00354  */
00355 int scoreboard_memcap(SCOREBOARD *sbp)
00356 {
00357     if(sbp != NULL && sbp->ipv4_table != NULL)        
00358         return sbp->ipv4_table->mc.memcap;
00359 
00360     return -1;            
00361 }
00362 
00363 /** 
00364  * get the row count
00365  * 
00366  * @param sbp scoreboard ptr to return the memcap of
00367  * 
00368  * @return nrows or -1
00369  */
00370 int scoreboard_row_count(SCOREBOARD *sbp)
00371 {
00372     if(sbp != NULL && sbp->ipv4_table != NULL)        
00373         return sbp->ipv4_table->nrows;
00374 
00375     return -1;            
00376 }
00377 
00378 /** 
00379  * get the overhead # of bytes
00380  * 
00381  * @param sbp scoreboard ptr to return the memcap of
00382  * 
00383  * @return nrows or -1
00384  */
00385 
00386 int scoreboard_overhead_bytes(SCOREBOARD *sbp)
00387 {
00388     if(sbp != NULL && sbp->ipv4_table != NULL)
00389         return sfxhash_overhead_bytes(sbp->ipv4_table);
00390 
00391     return -1;            
00392 
00393 }

Generated on Sun May 14 14:51:15 2006 by  doxygen 1.4.2