00001 #include "scoreboard.h"
00002 #include "util_math.h"
00003
00004 static SCORE_ENTRY s_init_entry;
00005
00006
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
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
00055 sbp->ipv4_table = sfxhash_new(rows,
00056 sizeof(u_int32_t),
00057 sizeof(SCORE_ENTRY),
00058 memcap,
00059 1,
00060 scoreboard_anrfree,
00061 scoreboard_usrfree,
00062 1);
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
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
00124
00125
00126
00127
00128
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
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
00162
00163
00164
00165
00166
00167
00168
00169
00170
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
00198
00199 return FLOW_BADJUJU;
00200 }
00201
00202 return FLOW_SUCCESS;
00203 }
00204
00205
00206
00207
00208
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
00259
00260
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
00277
00278
00279
00280
00281
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
00298
00299
00300
00301
00302
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
00321
00322
00323
00324
00325
00326
00327
00328 static int scoreboard_anrfree(void *key, void *data)
00329 {
00330 return 0;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 static int scoreboard_usrfree(void *key, void *data)
00344 {
00345 return 0;
00346 }
00347
00348
00349
00350
00351
00352
00353
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
00365
00366
00367
00368
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
00380
00381
00382
00383
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 }