#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
Include dependency graph for http_active.c:

Go to the source code of this file.
Data Structures | |
| struct | connect |
Defines | |
| #define | max(a, b) ((a) >= (b) ? (a) : (b)) |
| #define | MAX_CONNECTIONS 1000 |
| #define | min(a, b) ((a) <= (b) ? (a) : (b)) |
Enumerations | |
| enum | client_states { PENDING_ACTIVE, ACTIVE, PENDING_IDLE, IDLE } |
| enum | event_types { SYN, ACT_REQ, ACT_RSP, END, REQ, RSP } |
Functions | |
| int | AddConnection (char *sp, char *dh, char *dp) |
| void | ClearConnections (void) |
| int | ConnectionsActive (void) |
| long | elapsed_ms (char *end, char *start) |
| void | error_line (char *s) |
| void | error_state (char *s) |
| int | FindConnection (char *sp, char *dh, char *dp) |
| void | log_IDLE (char *s) |
| void | log_REQ (void) |
| void | log_RSP (void) |
| void | main (int argc, char *argv[]) |
| int | RemoveConnection (char *sp, char *dh, char *dp) |
| void | set_connection (char *sp, char *dh, char *dp, enum event_types type) |
| static void | tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0) |
| void | Usage (char *s) |
Variables | |
| int | active_connections = 0 |
| enum client_states | client_state = PENDING_ACTIVE |
| connect | connections [MAX_CONNECTIONS] |
| char | current_src [25] = "" |
| char | dh [25] |
| char | dp [10] |
| FILE * | dumpFP |
| char | earliest_end [20] |
| enum event_types | event_type |
| char | fl [5] |
| char | gt [3] |
| char | idle_begin [20] |
| char | last_client_ts [20] |
| char | new_line [500] |
| FILE * | outFP |
| int | req |
| int | rsp |
| char | sh [25] |
| char | sp [10] |
| timeval | time_stamp = {0,0} |
| char | ts [20] |
|
|
Definition at line 74 of file http_active.c. |
|
|
Definition at line 127 of file http_active.c. Referenced by set_connection(). |
|
|
Definition at line 73 of file http_active.c. |
|
|
Definition at line 103 of file http_active.c. 00104 {PENDING_ACTIVE, ACTIVE, PENDING_IDLE, IDLE};
|
|
|
Definition at line 107 of file http_active.c.
|
|
||||||||||||||||
|
Definition at line 623 of file http_active.c. References active_connections, and connections. Referenced by set_connection(). 00624 { 00625 char connection[50]; 00626 int i; 00627 00628 strcpy(connection, sp); 00629 strcat(connection, dh); 00630 strcat(connection, dp); 00631 00632 /* check to see if connection already in the table; if not there, add it */ 00633 for (i = 0; i < active_connections; i++) 00634 { 00635 if (strcmp(connections[i].id, connection) == 0) 00636 break; 00637 } 00638 if (i < active_connections) 00639 return(-1); /* already there */ 00640 else 00641 { 00642 active_connections += 1; 00643 if (active_connections > MAX_CONNECTIONS) 00644 return (active_connections); /* table overflow */ 00645 strcpy(connections[i].id, connection); 00646 connections[i].activity = 0; 00647 connections[i].state = END; 00648 return (i); 00649 } 00650 }
|
|
|
Definition at line 561 of file http_active.c. References active_connections, connect::activity, connections, END, and connect::state. Referenced by main(). 00562 { 00563 int i; 00564 00565 for (i = 0; i < active_connections; i++) 00566 { 00567 strcpy(connections[i].id, ""); 00568 connections[i].activity = 0; 00569 connections[i].state = END; 00570 } 00571 active_connections = 0; 00572 }
|
|
|
Definition at line 577 of file http_active.c. References active_connections, connections, and count. Referenced by main(). 00578 { 00579 int count = 0; 00580 int i; 00581 00582 for (i = 0; i < active_connections; i++) 00583 count = count + connections[i].activity; 00584 00585 return (count); 00586 }
|
|
||||||||||||
|
Definition at line 754 of file http_active.c. References tvsub(). Referenced by check_tuple_reuse(), log_IDLE(), and main(). 00755 { 00756 struct timeval delta, end_time, start_time; 00757 long elapsed_time; 00758 00759 char end_tmp[20]; 00760 char start_tmp[20]; 00761 00762 char *cursor; 00763 char *cp; 00764 00765 strcpy(end_tmp, end); 00766 cursor = end_tmp; 00767 cp = (char *)strsep(&cursor, "." ); 00768 end_time.tv_sec = atoi(end_tmp); 00769 end_time.tv_usec = atoi(cursor); 00770 00771 strcpy(start_tmp, start); 00772 cursor = start_tmp; 00773 cp = (char *)strsep(&cursor, "." ); 00774 start_time.tv_sec = atoi(start_tmp); 00775 start_time.tv_usec = atoi(cursor); 00776 00777 tvsub(&delta, &end_time, &start_time); 00778 /* express as milliseconds */ 00779 elapsed_time = (delta.tv_sec * 1000) + (delta.tv_usec/1000); 00780 return (elapsed_time); 00781 }
Here is the call graph for this function: ![]() |
|
|
Definition at line 720 of file http_active.c. References outFP. Referenced by init_connection(), main(), and parse_dump_record(). 00721 { 00722 fprintf(outFP, "%s", s); 00723 }
|
|
|
Definition at line 725 of file http_active.c. References current_src, outFP, and ts. Referenced by check_ACK_advance(), check_tuple_reuse(), main(), and set_connection(). 00726 { 00727 fprintf(outFP, "%s %-15s %5s > %-15s %5s ERROR %s\n", 00728 ts, current_src, "*", "*", "*", s); 00729 00730 }
|
|
||||||||||||||||
|
Definition at line 594 of file http_active.c. References active_connections, and connections. Referenced by set_connection(). 00595 { 00596 char connection[50]; 00597 int i; 00598 00599 strcpy(connection, sp); 00600 strcat(connection, dh); 00601 strcat(connection, dp); 00602 00603 /* find the connection in the table */ 00604 for (i = 0; i < active_connections; i++) 00605 { 00606 if (strcmp(connections[i].id, connection) == 0) 00607 break; 00608 } 00609 if (i == active_connections) /* not there */ 00610 return(-1); 00611 else 00612 return (i); 00613 }
|
|
|
Definition at line 710 of file http_active.c. References current_src, elapsed, elapsed_ms(), idle_begin, and outFP. Referenced by main(). 00711 { 00712 int elapsed; 00713 00714 elapsed = (int) elapsed_ms(ts, idle_begin); 00715 fprintf(outFP, "%s %-15s %5s > %-15s %5s IDLE%12d %s\n", 00716 ts, current_src, "*", "*", "*", elapsed, idle_begin); 00717 00718 }
Here is the call graph for this function: ![]() |
|
|
Definition at line 697 of file http_active.c. References new_line, and outFP. Referenced by check_tuple_reuse(), log_connection(), and main().
|
|
|
Definition at line 703 of file http_active.c. References new_line, and outFP. Referenced by check_tuple_reuse(), log_connection(), and main().
|
|
||||||||||||
|
Definition at line 153 of file http_active.c. References ACT_REQ, ACT_RSP, ACTIVE, ClearConnections(), client_state, ConnectionsActive(), current_src, dh, dp, dumpFP, earliest_end, elapsed, elapsed_ms(), END, error_line(), event_type, fl, gt, IDLE, idle_begin, input_name, last_client_ts, log_IDLE(), log_REQ(), log_RSP(), new_line, outFP, output_name, PENDING_ACTIVE, PENDING_IDLE, REQ, RSP, set_connection(), sh, sp, SYN, ts, and Usage(). 00154 { 00155 int i; 00156 00157 char input_name[256] = ""; 00158 char output_name[256] = ""; 00159 long idle_limit = 2000; /* default threshold for idleness in millisec. */ 00160 long elapsed; 00161 00162 char parse_line[500]; 00163 char discard[50]; 00164 00165 char *cursor; 00166 char *vp; 00167 00168 /* Parse the command line */ 00169 i = 1; 00170 while (i < argc) { 00171 if (strcmp (argv[i], "-r") == 0) { 00172 if (++i >= argc) Usage (argv[0]); 00173 strcpy (input_name, argv[i]); 00174 } 00175 else if (strcmp (argv[i], "-w") == 0) { 00176 if (++i >= argc) Usage (argv[0]); 00177 strcpy (output_name, argv[i]); 00178 } 00179 else if (strcmp (argv[i], "-I") == 0) { 00180 if (++i >= argc) Usage (argv[0]); 00181 idle_limit = (long)atoi(argv[i]); 00182 } 00183 else 00184 Usage (argv[0]); 00185 i++; 00186 } 00187 00188 /* Open files */ 00189 if (strcmp(output_name, "") == 0) 00190 outFP = stdout; 00191 else 00192 { 00193 strcat(output_name, ".activity"); 00194 if ((outFP = fopen (output_name, "w")) == NULL) { 00195 fprintf (stderr, "error opening %s\n", output_name); 00196 exit (-1); 00197 } 00198 } 00199 00200 if (strcmp(input_name, "") == 0) 00201 dumpFP = stdin; 00202 else 00203 { 00204 if ((dumpFP = fopen (input_name, "r")) == NULL) { 00205 fprintf (stderr, "error opening %s\n", input_name); 00206 exit (-1); 00207 } 00208 } 00209 00210 /* Read each record in the input file. Look for a change in the 00211 source IP address (which indicates a new client). If a new 00212 client, log the end of an idle period (if any) for the old 00213 client and initialize the connection table for the new client. 00214 If a record for the current client has been read, classify the 00215 type of event it represent and process it to update the client 00216 and connection state. 00217 */ 00218 00219 while (!feof (dumpFP)) { 00220 /* Get and parse line of data */ 00221 if (fgets (new_line, sizeof(new_line), dumpFP) == NULL) 00222 break; 00223 /* get first line pieces */ 00224 00225 sscanf (new_line, "%s %s %s %s %s %s %s", 00226 &ts, &sh, &sp, >, &dh, &dp, &fl); 00227 00228 /* if an ERR line, just show it */ 00229 if (strcmp(fl, "ERR:") == 0) 00230 { 00231 error_line(new_line); 00232 continue; 00233 } 00234 00235 /* now get variable part starting with the ":" considering that */ 00236 /* interpretation of the remaining fields depends on the flag value */ 00237 /* This is necessary to find the ending timestamp for FIN, RST, and 00238 TRM events. 00239 */ 00240 00241 strcpy(parse_line, new_line); 00242 cursor = parse_line; 00243 vp = (char *)strsep(&cursor, ":" ); 00244 if ((cursor == (char *)NULL) || 00245 (vp == (char *)NULL)) 00246 { 00247 error_line(new_line); 00248 continue; 00249 } 00250 00251 /* Classify the event type by looking at the flag field from input 00252 records */ 00253 00254 if ((strcmp(fl, "REQ") == 0) || 00255 (strcmp(fl, "REQ-") == 0)) 00256 event_type = REQ; 00257 else 00258 { 00259 if ((strcmp(fl, "RSP") == 0) || 00260 (strcmp(fl, "RSP-") == 0)) 00261 event_type = RSP; 00262 else 00263 { 00264 if ((strcmp(fl, "FIN") == 0) || 00265 (strcmp(fl, "TRM") == 0) || 00266 (strcmp(fl, "RST") == 0)) 00267 { 00268 /* need the ending timestamp from these record types */ 00269 sscanf(cursor, "%s %s", &discard, &earliest_end); 00270 event_type = END; 00271 } 00272 else 00273 { 00274 if (strcmp(fl, "SYN") == 0) 00275 event_type = SYN; 00276 else 00277 { 00278 if (strcmp(fl, "ACT-REQ") == 0) 00279 event_type = ACT_REQ; 00280 else 00281 if (strcmp(fl, "ACT-RSP") == 0) 00282 event_type = ACT_RSP; 00283 } 00284 } 00285 } 00286 } 00287 00288 /* now use data from new trace record to update status */ 00289 /* first check to see if this is the same client host */ 00290 if (strcmp(current_src, sh) != 0) 00291 { 00292 if (client_state == IDLE) 00293 log_IDLE(last_client_ts); 00294 ClearConnections(); 00295 client_state = PENDING_ACTIVE; 00296 strcpy(current_src, sh); 00297 } 00298 00299 00300 /* update the connection status for this client's connection */ 00301 00302 set_connection(sp, dh, dp, event_type); 00303 00304 00305 /* The main processing for idle periods is done by maintaining a state 00306 variable (client_status) for the client and looking for specific input 00307 record types at different values of the state variable. The 00308 values of client_state and their implications are: 00309 PENDING_ACTIVE - A new client is started and remains PENDING_ACTIVE 00310 until an activity indication such as ACT-REQ, 00311 ACT-RSP, or REQ is seen in which case it enters 00312 the ACTIVE state. If there is an initial response, 00313 PENDING_IDLE is entered. 00314 ACTIVE - At least one request is outstanding and the state 00315 can only change if there is a response completion 00316 or connection termination. 00317 PENDING_IDLE - There are no requests outstanding but the idle 00318 period threshold has not elapsed since it entered 00319 the PENDING_IDLE state. 00320 IDLE - No outstanding requests for a period greater than 00321 the idle threshold. The IDLE (and PENDING_IDLE) 00322 states are exited on activity indication such as 00323 ACT-REQ, ACT-RSP, or REQ 00324 */ 00325 00326 switch (client_state) 00327 { 00328 case PENDING_ACTIVE: 00329 switch (event_type) 00330 { 00331 case SYN: 00332 break; 00333 case ACT_REQ: 00334 case ACT_RSP: 00335 client_state = ACTIVE; 00336 break; 00337 case REQ: 00338 client_state = ACTIVE; 00339 log_REQ(); 00340 break; 00341 case RSP: 00342 client_state = PENDING_IDLE; 00343 strcpy(idle_begin, ts); 00344 log_RSP(); 00345 break; 00346 case END: 00347 break; 00348 } 00349 break; 00350 00351 case ACTIVE: 00352 switch (event_type) 00353 { 00354 case SYN: 00355 case ACT_REQ: 00356 case ACT_RSP: 00357 break; 00358 case REQ: 00359 log_REQ(); 00360 break; 00361 case RSP: 00362 log_RSP(); 00363 if (ConnectionsActive() == 0) /* Any active connections?*/ 00364 { 00365 client_state = PENDING_IDLE; 00366 strcpy(idle_begin, ts); 00367 } 00368 break; 00369 case END: 00370 if (ConnectionsActive() == 0) /* Any active connections?*/ 00371 { 00372 client_state = PENDING_IDLE; 00373 strcpy(idle_begin, earliest_end); 00374 } 00375 break; 00376 } 00377 break; 00378 00379 case PENDING_IDLE: 00380 /* must start checking time, if > n seconds elapse since 00381 entering PENDING_IDLE state, enter IDLE state */ 00382 elapsed = elapsed_ms(ts, idle_begin); 00383 if (elapsed < idle_limit) 00384 { 00385 switch (event_type) 00386 { 00387 case SYN: 00388 case END: 00389 break; 00390 case ACT_REQ: 00391 case ACT_RSP: 00392 client_state = ACTIVE; 00393 break; 00394 case REQ: 00395 client_state = ACTIVE; 00396 log_REQ(); 00397 break; 00398 case RSP: 00399 log_RSP(); 00400 break; 00401 } 00402 break; /* ends case PENDING_IDLE */ 00403 } 00404 else /* it has crossed the idle threshold */ 00405 client_state = IDLE; 00406 /* NOTE: drop through to IDLE to handle the current event */ 00407 00408 case IDLE: 00409 switch (event_type) 00410 { 00411 case SYN: 00412 case END: 00413 break; 00414 case ACT_REQ: 00415 case ACT_RSP: 00416 client_state = ACTIVE; 00417 log_IDLE(ts); 00418 break; 00419 case REQ: 00420 client_state = ACTIVE; 00421 log_IDLE(ts); 00422 log_REQ(); 00423 break; 00424 case RSP: 00425 log_RSP(); 00426 break; 00427 break; /* ends case PENDING_IDLE */ 00428 } 00429 break; 00430 00431 default: 00432 break; 00433 } /* end switch */ 00434 00435 strcpy(last_client_ts, ts); 00436 00437 } /* end while (!feof ....) */ 00438 close (dumpFP); 00439 close (outFP); 00440 }
Here is the call graph for this function: ![]() |
|
||||||||||||||||
|
Definition at line 660 of file http_active.c. References active_connections, and connections. Referenced by set_connection(). 00661 { 00662 char connection[50]; 00663 int i, j; 00664 00665 strcpy(connection, sp); 00666 strcat(connection, dh); 00667 strcat(connection, dp); 00668 00669 /* find the connection in the table; if not there, error */ 00670 for (i = 0; i < active_connections; i++) 00671 { 00672 if (strcmp(connections[i].id, connection) == 0) 00673 break; 00674 } 00675 if (i == active_connections) 00676 return (-1); 00677 00678 /* move all active connections above this down by one with overwriting */ 00679 for (j = i + 1; j < active_connections; j++) 00680 { 00681 strcpy(connections[j-1].id, connections[j].id); 00682 connections[j-1].activity = connections[j].activity; 00683 connections[j-1].state = connections[j].state; 00684 } 00685 00686 /* clearing the top vacated slot is not strictly necessary but it may 00687 help with debugging */ 00688 strcpy(connections[active_connections - 1].id, ""); 00689 connections[active_connections - 1].activity = 0; 00690 connections[active_connections - 1].state = END; 00691 00692 active_connections -= 1; 00693 return (0); 00694 }
|
|
||||||||||||||||||||
|
Definition at line 444 of file http_active.c. References ACT_REQ, ACT_RSP, connect::activity, AddConnection(), connections, END, error_state(), FindConnection(), MAX_CONNECTIONS, RemoveConnection(), REQ, RSP, connect::state, and SYN. Referenced by main(). 00445 { 00446 00447 int cx; 00448 00449 /* A connection is identified by the host/port 3-tuple (the source IP 00450 address is not needed because only one client is handled at a time). 00451 The connection's status depends on the type of the event that caused 00452 the update. The following event type are defined with their effect 00453 on the connection's status: 00454 SYN, ACT-REQ, - The connection has begun (is an "active" 00455 ACT-RSP connection. Add it to the table as idle 00456 (activity == 0) if a SYN or with request/ 00457 response activity (activity == 1) for ACT-REQ 00458 or ACT-RSP. 00459 REQ - Find the connection in the table and mark it with 00460 an outstanding request (activity == 1). 00461 RSP - Find the connection in the table and mark it with 00462 a completed request (activity == 0). 00463 END - The connection has ended (is no longer an "active" 00464 connection). Remove it from the table. 00465 */ 00466 00467 switch (type) 00468 { 00469 case SYN: 00470 case ACT_REQ: 00471 case ACT_RSP: 00472 { 00473 cx = AddConnection(sp, dh, dp); 00474 if (cx < 0) /* already there */ 00475 { 00476 error_state("Add for existing connection"); 00477 return; 00478 } 00479 if (cx > MAX_CONNECTIONS) /* table overflow */ 00480 { 00481 error_state("Active connections exceeds maximum"); 00482 exit (-1); 00483 } 00484 connections[cx].state = type; 00485 if (type == SYN) 00486 connections[cx].activity = 0; 00487 else 00488 connections[cx].activity = 1; 00489 break; 00490 } 00491 00492 case REQ: 00493 { 00494 cx = FindConnection(sp, dh, dp); 00495 if (cx < 0) /* not there */ 00496 { 00497 error_state("REQ for non-existent connection"); 00498 return; 00499 } 00500 if ((connections[cx].state == RSP) || 00501 (connections[cx].state == ACT_REQ) || 00502 (connections[cx].state == SYN)) 00503 { 00504 connections[cx].activity = 1; 00505 connections[cx].state = REQ; 00506 } 00507 else 00508 error_state("REQ in invalid connection state"); 00509 00510 break; 00511 } 00512 00513 case RSP: 00514 { 00515 cx = FindConnection(sp, dh, dp); 00516 if (cx < 0) /* not there */ 00517 { 00518 error_state("RSP for non-existent connection"); 00519 return; 00520 } 00521 if ((connections[cx].state == REQ) || 00522 (connections[cx].state == ACT_RSP) || 00523 (connections[cx].state == SYN)) 00524 { 00525 connections[cx].activity = 0; 00526 connections[cx].state = RSP; 00527 } 00528 else 00529 error_state("RSP in invalid connection state"); 00530 00531 break; 00532 } 00533 00534 case END: 00535 { 00536 cx = FindConnection(sp, dh, dp); 00537 if (cx < 0) /* not there */ 00538 { 00539 error_state("End for non-existent connection"); 00540 return; 00541 } 00542 connections[cx].activity = 0; 00543 connections[cx].state = END; 00544 cx = RemoveConnection(sp, dh, dp); 00545 break; 00546 } 00547 default: 00548 break; 00549 00550 } 00551 }
Here is the call graph for this function: ![]() |
|
||||||||||||||||
|
Definition at line 737 of file http_active.c. Referenced by elapsed_ms(). 00739 { 00740 00741 tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 00742 tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 00743 if (tdiff->tv_usec < 0) 00744 { 00745 tdiff->tv_sec--; 00746 tdiff->tv_usec += 1000000; 00747 } 00748 }
|
|
|
Definition at line 76 of file http_active.c. Referenced by main(). 00077 { 00078 fprintf (stderr,"\nUsage: %s\n", s); 00079 fprintf (stderr," [-w file_name] (name for output file)\n"); 00080 fprintf (stderr," [-r file_name] (name for input file)\n"); 00081 fprintf (stderr," [-I idle_limit] (min inactivity interval)\n"); 00082 fprintf (stderr,"\n"); 00083 exit(-1); 00084 }
|
|
|
Definition at line 126 of file http_active.c. Referenced by AddConnection(), ClearConnections(), ConnectionsActive(), FindConnection(), and RemoveConnection(). |
|
|
Definition at line 105 of file http_active.c. Referenced by main(). |
|
|
Referenced by AddConnection(), ClearConnections(), ConnectionsActive(), FindConnection(), RemoveConnection(), and set_connection(). |
|
|
Definition at line 101 of file http_active.c. Referenced by error_state(), log_ACT(), log_END(), log_IDLE(), log_SYN(), and main(). |
|
|
|
Definition at line 98 of file http_active.c. Referenced by HDLC::ack(), HDLC::dataToSend(), HDLC::handleSREJ(), main(), and HDLC::sendMuch(). |
|
|
Definition at line 86 of file http_active.c. Referenced by main(). |
|
|
Definition at line 112 of file http_active.c. Referenced by main(). |
|
|
Definition at line 108 of file http_active.c. Referenced by main(). |
|
|
Definition at line 99 of file http_active.c. Referenced by main(), and parse_dump_record(). |
|
|
Definition at line 96 of file http_active.c. Referenced by main(). |
|
|
Definition at line 111 of file http_active.c. Referenced by log_IDLE(), and main(). |
|
|
Definition at line 113 of file http_active.c. Referenced by main(). |
|
|
Definition at line 135 of file http_active.c. |
|
|
Definition at line 86 of file http_active.c. Referenced by error_line(), error_state(), log_ACT(), log_END(), log_IDLE(), log_REQ(), log_RSP(), log_SYN(), and main(). |
|
|
Definition at line 90 of file http_active.c. Referenced by SrmNode::append(), MediaApp::get_data(), MediaServer::get_data(), and MediaCache::get_data(). |
|
|
Definition at line 91 of file http_active.c. Referenced by SSMSRMAgent::command(), and SSMSRMAgent::recv_rqst(). |
|
|
|
Definition at line 95 of file http_active.c. |
|
|
Definition at line 88 of file http_active.c. |
|
|
Definition at line 93 of file http_active.c. Referenced by begin_REQ(), begin_RSP(), check_tuple_reuse(), Network::command(), ArpAgent::dispatch(), error_state(), log_ACT(), log_SYN(), main(), more_REQ(), more_RSP(), TfrcAgent::recv(), and IvsReceiver::recv(). |
1.4.6