[Tcpick-project] [PATCH] disordered first payloads / connection incarnations (2)
Status: Beta
Brought to you by:
duskdruid
From: Takashi W. <re...@sp...> - 2009-06-30 10:47:39
|
===== file: patch-tcpick-0.2.1-6-watanabe1.24.part2of2 ===== diff -rupN deb-orig/tcpick-0.2.1/src/tracker.c tcpick-0.2.1/src/tracker.c --- deb-orig/tcpick-0.2.1/src/tracker.c 2009-06-30 09:02:57.000000000 +0900 +++ tcpick-0.2.1/src/tracker.c 2009-06-30 09:04:59.000000000 +0900 @@ -28,27 +28,81 @@ #include "tcpick.h" #include "extern.h" -struct CONN * first_conn = NULL; /*all connections, ends on a 0*/ -struct CONN * last_conn = NULL; +struct CONN_DESC * first_conn = NULL; /*all connections, ends on a 0*/ +struct CONN_DESC * last_conn = NULL; + +/* The first SYN of the 3-way handshake is of the client */ +#define FOUND_CONN(conn) ( \ + conn->client.ip.s_addr == ippacket->ip_src.s_addr && \ + conn->server.ip.s_addr == ippacket->ip_dst.s_addr && \ + conn->client.port == tcppacket->source && \ + conn->server.port == tcppacket->dest \ + ) + +#define THIS_IS_TRACKER_C "tracker.c" +#define ASSERT_LASTCHILD_EXISTS(conn){ \ + if(conn->lastincar == NULL) \ + suicide(THIS_IS_TRACKER_C, "The lastincar doesn't exist."); \ + } + +#define UPDATE_LASTINCAR(conn_ptr, new){ \ + conn_ptr->lastincar = new; \ + conn_ptr->client.lastincar = & (conn_ptr->lastincar->client); \ + conn_ptr->server.lastincar = & (conn_ptr->lastincar->server); \ + } + /* If you forgot to update {client,server}.lastincar, you would encounter a reproducible horrible bus error at a [cm]alloc call */ int -status_switch(struct CONN * prev, enum STATUS status) +status_switch(struct CONN_DESC * prev_conn, enum STATUS status) { -#define CURR (prev->next) - display_status( stdout, CURR, status ); + display_status( stdout, CURRENT_CONN, status ); if ( status == CLOSED || status == RESET || status == EXPIRED ) - rmconn( prev ); + rmconn( prev_conn, 0 ); else - CURR->status = status; + CURRENT_CONN->lastincar->status = status; } +/* lastincar related */ int -newconn( struct CONN * prev_ring ) +newincar( struct CONN_DESC * prev_conn ) +{ + struct CONN_INCAR * cinc; + cinc = S_malloc( sizeof *cinc ); + memset(cinc, 0, sizeof *cinc ); + + CURRENT_CONN->count_cycles++; + + if( CURRENT_CONN->lastincar != NULL ){ + cinc->prev = CURRENT_CONN->lastincar; + } + UPDATE_LASTINCAR(CURRENT_CONN, cinc); + + CURRENT_CONN->lastincar->cyclenum = CURRENT_CONN->count_cycles; + + CURRENT_CONN->lastincar->client.sip = ntohl(tcppacket->seq) + 1; + /* insert a dummy unack data to prevent the flush from skipping the first packet(s) */ + addfr( & (CURRENT_CONN->lastincar->client.unack), + CURRENT_CONN->lastincar->client.wlen, + 0, + "", + 0 ); + CURRENT_CONN->lastincar->client.max_off = 0; + + CURRENT_CONN->lastincar->client.oth = & (CURRENT_CONN->lastincar->server); + CURRENT_CONN->lastincar->server.oth = & (CURRENT_CONN->lastincar->client); + + CURRENT_CONN->lastincar->lasttime = time(NULL); + + status_switch( prev_conn, SYN_SENT ); +} + +int +newconn() /* allocates a new connection */ { - struct CONN * conn; + struct CONN_DESC * prev_conn = first_conn; if( flags.trackonly != -1 ) { if( flags.trackonly_first && @@ -59,53 +113,148 @@ newconn( struct CONN * prev_ring ) else count_opened++; } + + while( CURRENT_CONN ){ + if( FOUND_CONN( CURRENT_CONN ) ){ + newincar( prev_conn ); + return 0; + } + + prev_conn = prev_conn->next; + } + count_conns++; - conn = ( struct CONN * )S_calloc( sizeof( struct CONN ), 1 ); - - prev_ring->next = conn; /* and the chain becomes longer... :) + CURRENT_CONN = S_malloc( sizeof *CURRENT_CONN ); + memset(CURRENT_CONN, 0, sizeof *CURRENT_CONN ); + /* and the chain becomes longer... :) thank you mainman for this good idea! */ - last_conn = conn; + last_conn = CURRENT_CONN; - conn->client.side = CLIENT; - conn->server.side = SERVER; + CURRENT_CONN->client.side = CLIENT; + CURRENT_CONN->server.side = SERVER; - conn->client.ip.s_addr = ippacket->ip_src.s_addr; - conn->server.ip.s_addr = ippacket->ip_dst.s_addr; - conn->client.port = tcppacket->source; - conn->server.port = tcppacket->dest; - - conn->client.sip = ntohl(tcppacket->seq) + 1; + CURRENT_CONN->client.ip.s_addr = ippacket->ip_src.s_addr; + CURRENT_CONN->server.ip.s_addr = ippacket->ip_dst.s_addr; + CURRENT_CONN->client.port = tcppacket->source; + CURRENT_CONN->server.port = tcppacket->dest; + + CURRENT_CONN->client.oth = & (CURRENT_CONN->server); + CURRENT_CONN->server.oth = & (CURRENT_CONN->client); - conn->client.oth = & (conn->server); - conn->server.oth = & (conn->client); + CURRENT_CONN->num = count_conns; + CURRENT_CONN->count_cycles = 0; + + newincar( prev_conn ); + return 1; +} + + +void +getHexStr(char * cp, u_char * pay, int len) +{ + for( ; len > 0; cp += 3, ++pay, --len ){ + sprintf(cp, " %02X", *pay); + } + *cp = '\0'; +} + +void +checkUnack( struct CONN_DESC * conn_ptr, struct HOST_DESC * hdesc ) +{ + struct FRAGMENT * unack = hdesc->lastincar->unack; + if( unack->len == 0 ) + return; + + char *buf = S_malloc( (unack->len * 3 + 1) * sizeof *buf ); + getHexStr(buf, unack->payload, unack->len); + + err("[REMAINING @ conn#%d side=%d] len = %d, payload =%s\n", conn_ptr->num, hdesc->side, unack->len, buf); + + S_free( buf ); +} + +int +free_hincar( struct CONN_DESC * conn_ptr, struct HOST_DESC * hdesc, int freedescfilename ) +/* frees the host descriptor and closes the file */ +{ +#define FREE_HINCAR "free_hincar@tracker.c" + struct HOST_INCAR * hinc = hdesc->lastincar; + struct FRAGMENT * tmp; + + if( hinc->file ) { + fclose( hinc->file ); + if (flags.writer.type == UNIQUE) + hinc->oth->file = NULL; + } + if( hinc->filename && freedescfilename ) { + S_free( hinc->filename ); + hinc->filename = NULL; + } + + if( hinc->lockfilename ) { + unlink( hinc->lockfilename ); + S_free( hinc->lockfilename ); + hinc->lockfilename = NULL; + } - conn->num = count_conns; + while( hinc->unack ) { /* FIXME: hinc->unack should be just NULL when closes! + * I should check it! */ + checkUnack( conn_ptr, hdesc ); + S_free( hinc->unack->payload ); + hinc->unack->payload = NULL; + tmp = hinc->unack; + hinc->unack = hinc->unack->next; + S_free( tmp ); + } +} - conn->lasttime = time(NULL); +int +rmincar( struct CONN_DESC * conn_ptr ) +{ + struct CONN_INCAR * cinc; + + /* confirming the unack data to be flushed */ + flush_ack( & ( conn_ptr->client ), conn_ptr); + flush_ack( & ( conn_ptr->server ), conn_ptr); - status_switch( prev_ring, SYN_SENT ); + free_hincar( conn_ptr, &(conn_ptr->client), 1); + if (flags.writer.type == UNIQUE) free_hincar( conn_ptr, &(conn_ptr->server), 0); + else free_hincar( conn_ptr, &(conn_ptr->server), 1); + + cinc = conn_ptr->lastincar; + UPDATE_LASTINCAR(conn_ptr, cinc->prev); + + S_free( cinc ); } -int rmconn( struct CONN * prev_ring ) +int +rmconn( struct CONN_DESC * prev_conn, int recur ) /* removes from the linked-list and deallocates a connection - * prev_ring + * prev_conn */ { - struct CONN * curr = prev_ring->next; - struct CONN * conn; - - prev_ring->next = curr->next; - if( curr->next == NULL ) - last_conn = prev_ring; - - free_desc( &(curr->client), 1); - if (flags.writer.type == UNIQUE) free_desc( &(curr->server), 0); - else free_desc( &(curr->server), 1); - S_free( curr ); + struct CONN_DESC * curr = CURRENT_CONN; + struct CONN_DESC * conn; + + if( curr == NULL ) + suicide(THIS_IS_TRACKER_C, "curr is NULL."); + + do { + rmincar(curr); + }while( recur && curr->lastincar != NULL ); + + if( curr->lastincar == NULL ){ + CURRENT_CONN = curr->next; + if( CURRENT_CONN == NULL ) + last_conn = prev_conn; + + S_free( curr ); + } + conn = first_conn; - + if( flags.exitclosed ) { if( flags.exitclosed_first ) { /* -Ef */ while( conn->num > flags.exitclosed ) { @@ -120,38 +269,10 @@ int rmconn( struct CONN * prev_ring ) } } - if( flags.trackonly && + if( flags.trackonly > 0 && (! flags.trackonly_first) ) count_opened--; -} -int free_desc( struct HOST_DESC * desc, int freedescfilename ) -/* frees the host descriptor and closes the file */ -{ - struct FRAGMENT * tmp; - - if( desc->file ) { - fclose( desc->file ); - if (flags.writer.type == UNIQUE) - desc->oth->file = NULL; - } - if( desc->filename && freedescfilename ) { - S_free( desc->filename ); - desc->filename = NULL; - } - - if( desc->lockfilename ) { - unlink( desc->lockfilename ); - S_free( desc->lockfilename ); - desc->lockfilename = NULL; - } - - while( desc->unack ) { /* FIXME: desc->unack should be just NULL when closes! - * I should check it! */ - S_free( desc->unack->payload ); - desc->unack->payload = NULL; - tmp = desc->unack; - desc->unack = desc->unack->next; - S_free( tmp ); - } + return 1; } + diff -rupN deb-orig/tcpick-0.2.1/src/verify.c tcpick-0.2.1/src/verify.c --- deb-orig/tcpick-0.2.1/src/verify.c 2005-01-14 00:35:33.000000000 +0900 +++ tcpick-0.2.1/src/verify.c 2009-06-30 09:04:59.000000000 +0900 @@ -29,23 +29,9 @@ #include "tcpick.h" #include "extern.h" -#define CURRENT_CONN (prev_conn->next) - -#define ACK_OFF ntohl( tcppacket->ack_seq ) - Desc->oth->sip +#define ACK_OFF ntohl( tcppacket->ack_seq ) - hdesc->oth->lastincar->sip /* FIXME: to def.h? */ -#define IS_CLIENT_SENDER \ - CURRENT_CONN->client.ip.s_addr == ippacket->ip_src.s_addr && \ - CURRENT_CONN->server.ip.s_addr == ippacket->ip_dst.s_addr && \ - CURRENT_CONN->client.port == tcppacket->source && \ - CURRENT_CONN->server.port == tcppacket->dest - -#define IS_SERVER_SENDER \ - CURRENT_CONN->client.ip.s_addr == ippacket->ip_dst.s_addr && \ - CURRENT_CONN->server.ip.s_addr == ippacket->ip_src.s_addr && \ - CURRENT_CONN->client.port == tcppacket->dest && \ - CURRENT_CONN->server.port == tcppacket->source - #define IS_SYN_SENT \ tcppacket->syn == 1 && \ tcppacket->ack == 0 @@ -53,71 +39,75 @@ #define IS_SYN_RECEIVED \ tcppacket->syn == 1 && \ tcppacket->ack == 1 && \ - Desc->side == SERVER && \ - CURRENT_CONN->status == SYN_SENT + hdesc->side == SERVER && \ + CURRENT_CONN->lastincar->status == SYN_SENT #define IS_ESTABLISHING \ tcppacket->syn == 0 && \ tcppacket->ack == 1 && \ - Desc->side == CLIENT && \ - CURRENT_CONN->status == SYN_RECEIVED && \ - CURRENT_CONN->client.sip == ntohl( tcppacket->seq ) + hdesc->side == CLIENT && \ + CURRENT_CONN->lastincar->status == SYN_RECEIVED && \ + CURRENT_CONN->lastincar->client.sip == ntohl( tcppacket->seq ) #define IS_DATA_FLOW 1 #define IS_FIN_WAIT_1 \ tcppacket->fin == 1 && \ - CURRENT_CONN->status == ESTABLISHED + CURRENT_CONN->lastincar->status == ESTABLISHED #define IS_FIN_WAIT_2__CLOSE_WAIT \ tcppacket->ack == 1 && \ tcppacket->fin == 0 && \ - CURRENT_CONN->status == FIN_WAIT_1 && \ - CURRENT_CONN->closer != Desc->side + CURRENT_CONN->lastincar->status == FIN_WAIT_1 && \ + CURRENT_CONN->lastincar->closer != hdesc->side #define IS_TIME_WAIT__LAST_ACK \ tcppacket->ack == 1 && \ tcppacket->fin == 1 && \ - ( CURRENT_CONN->status == FIN_WAIT_2__CLOSE_WAIT || \ - CURRENT_CONN->status == FIN_WAIT_1 ) && \ - CURRENT_CONN->closer != Desc->side + ( CURRENT_CONN->lastincar->status == FIN_WAIT_2__CLOSE_WAIT || \ + CURRENT_CONN->lastincar->status == FIN_WAIT_1 ) && \ + CURRENT_CONN->lastincar->closer != hdesc->side #define IS_CLOSING \ tcppacket->ack == 1 && \ tcppacket->fin == 0 && \ - CURRENT_CONN->status == TIME_WAIT__LAST_ACK && \ - CURRENT_CONN->closer == Desc->side + CURRENT_CONN->lastincar->status == TIME_WAIT__LAST_ACK && \ + CURRENT_CONN->lastincar->closer == hdesc->side #define IS_RESET \ tcppacket->rst == 1 __inline__ int -established_packet ( struct CONN * conn_ptr, struct HOST_DESC * Desc) +established_packet ( struct CONN_DESC * conn_ptr, struct HOST_DESC * hdesc) /* called by verify() packets of established connections come here */ { register u_int32_t off; if( payload_len ) { - off = ntohl( tcppacket->seq ) - Desc->sip ; + off = ntohl( tcppacket->seq ) - hdesc->lastincar->sip ; /* unacknowledged data */ - addfr( & (Desc->unack), - Desc->wlen, + addfr( & (hdesc->lastincar->unack), + hdesc->lastincar->wlen, off, payload, payload_len ); + } + if( ACK_OFF > hdesc->oth->lastincar->max_off ){ + hdesc->oth->lastincar->max_off = ACK_OFF; + } + if( payload_len == 0) { /* acknowledge data */ - flush_ack ( Desc->oth, conn_ptr, ACK_OFF ); - } - else if( tcppacket->psh ) { + flush_ack ( hdesc->oth, conn_ptr ); + }else if( tcppacket->psh ) { /* PUSH data */ - flush_ack ( Desc, conn_ptr, ACK_OFF ); - } + flush_ack ( hdesc, conn_ptr ); + } } @@ -127,31 +117,31 @@ verify() this is the engine that matches the packets with their connection */ { - register struct HOST_DESC * Desc = NULL; + register struct HOST_DESC * hdesc = NULL; - register struct CONN * prev_conn; + register struct CONN_DESC * prev_conn; prev_conn = first_conn; /* SYN-SENT: (outside of the loop because the * loop is used for sessions just tracked) */ if( IS_SYN_SENT ) { - newconn( last_conn ); + newconn(); return(1); } if(! CURRENT_CONN ) return 0 ; - while (! Desc ) { + while (! hdesc ) { /* cycle until it finds a connection that matches on server or client side */ if ( IS_CLIENT_SENDER ) - Desc = & (CURRENT_CONN->client); + hdesc = & (CURRENT_CONN->client); else if ( IS_SERVER_SENDER ) - Desc = & (CURRENT_CONN->server); + hdesc = & (CURRENT_CONN->server); else { prev_conn = prev_conn->next; if(! CURRENT_CONN ) @@ -160,13 +150,20 @@ verify() } /* update time of last packet in connection */ - CURRENT_CONN->lasttime = time(NULL); + CURRENT_CONN->lastincar->lasttime = time(NULL); /* when this point is reached, we have found the right matching connection */ if( IS_SYN_RECEIVED ) { - CURRENT_CONN->server.sip = ntohl(tcppacket->seq) + 1; + CURRENT_CONN->lastincar->server.sip = ntohl(tcppacket->seq) + 1; + /* insert a dummy unack data to prevent the flush from skipping the first packet(s) */ + addfr( & (CURRENT_CONN->lastincar->server.unack), + CURRENT_CONN->lastincar->server.wlen, + 0, + "", + 0 ); + CURRENT_CONN->lastincar->server.max_off = 0; status_switch( prev_conn, SYN_RECEIVED ); return 1; } @@ -181,13 +178,13 @@ verify() /* data or ack packets */ if( IS_DATA_FLOW ) { if( REBUILD ) - established_packet ( CURRENT_CONN, Desc ); + established_packet ( CURRENT_CONN, hdesc ); } /* first FIN sent */ if( IS_FIN_WAIT_1 ) { status_switch( prev_conn, FIN_WAIT_1 ); - CURRENT_CONN->closer = Desc->side; + CURRENT_CONN->lastincar->closer = hdesc->side; return 1; } @@ -219,3 +216,16 @@ verify() /* nice work :^) */ } + +void +confirmFlush(){ + register struct CONN_DESC * prev_conn; + int i; + + prev_conn = first_conn; + for(i = 0; CURRENT_CONN; ++i ){ + rmconn( prev_conn, 1 ); + } + msg( 1, c_DONE, + "confirmFlush: done flushing the remaing connections. %d connections removed.", i ); +} diff -rupN deb-orig/tcpick-0.2.1/src/write.c tcpick-0.2.1/src/write.c --- deb-orig/tcpick-0.2.1/src/write.c 2009-06-30 09:02:57.000000000 +0900 +++ tcpick-0.2.1/src/write.c 2009-06-30 09:04:59.000000000 +0900 @@ -32,7 +32,7 @@ #include "lookup.h" __inline__ char * -avail_filename(struct CONN * conn_ptr, +avail_filename(struct CONN_DESC * conn_ptr, enum PART side, char * ext) /* finds an available name for the connection file, @@ -40,10 +40,10 @@ avail_filename(struct CONN * conn_ptr, to invent a different filename */ { - char * client_server; - char * base_name; - char * dir_name; - char * test_name; + char client_server[STATIC_CHAR_BUF_SIZE]; /* FIXME: [0.2.1-6 20090630] S_malloc related */ + char base_name[STATIC_CHAR_BUF_SIZE]; /* FIXME: [0.2.1-6 20090630] S_malloc related */ + char dir_name[STATIC_CHAR_BUF_SIZE]; /* FIXME: [0.2.1-6 20090630] S_malloc related */ + char test_name[STATIC_CHAR_BUF_SIZE]; /* FIXME: [0.2.1-6 20090630] S_malloc related */ char * ret; struct stat stat_struct; /* this gets the name of the host */ @@ -52,14 +52,9 @@ avail_filename(struct CONN * conn_ptr, int server_port=conn_ptr->server.port; int num = 0; - client_server = (char *)S_calloc(MAX_FILENAME_LENGHT,1); - base_name = (char *)S_calloc(MAX_FILENAME_LENGHT,1); - dir_name = (char *)S_calloc(MAX_FILENAME_LENGHT,1); - test_name = (char *)S_calloc(MAX_FILENAME_LENGHT,1); - if (flags.dirs > 0) { /* -D option */ - sprintf(dir_name,"%06u", conn_ptr->num / flags.dirs); + sprintf(dir_name,"%06u", conn_ptr->num / flags.dirs); /* FIXME: need cyclenum? */ if( stat(dir_name, &stat_struct) == -1 ) { switch (errno) { case ENOENT: @@ -93,7 +88,7 @@ avail_filename(struct CONN * conn_ptr, sprintf(base_name, "%s/tcpick_%s.both", dir_name, client_server); break; case 2: - sprintf(base_name, "%s/tcpick_%06u_%s.both", dir_name, conn_ptr->num, client_server); + sprintf(base_name, "%s/tcpick_%06u_%06u_%s.both", dir_name, conn_ptr->num, conn_ptr->lastincar->cyclenum, client_server); /* FIXME: need cyclenum? */ break; } } else { /* flags.writer.type == SEPARATE, @@ -120,12 +115,12 @@ avail_filename(struct CONN * conn_ptr, switch( side ) { case CLIENT: - sprintf(base_name, "%s/tcpick_%06u_%s.clnt", dir_name, conn_ptr->num, client_server); + sprintf(base_name, "%s/tcpick_%06u_%06u_%s.clnt", dir_name, conn_ptr->num, conn_ptr->lastincar->cyclenum, client_server); /* FIXME: need cyclenum? */ break; case SERVER: - sprintf(base_name,"%s/tcpick_%06u_%s.serv", dir_name, conn_ptr->num, client_server); + sprintf(base_name,"%s/tcpick_%06u_%06u_%s.serv", dir_name, conn_ptr->num, conn_ptr->lastincar->cyclenum, client_server); /* FIXME: need cyclenum? */ break; } break; @@ -141,59 +136,55 @@ avail_filename(struct CONN * conn_ptr, /* returning the right pointer and freeing wasted memory */ #ifdef HAVE_STRNDUP - ret = (char *)strndup( test_name, MAX_FILENAME_LENGHT ); + ret = (char *)S_strndup( test_name, MAX_FILENAME_LENGHT ); #else - ret = (char *)strdup( test_name ); + ret = (char *)S_strdup( test_name ); #endif - S_free( test_name ); - S_free( dir_name ); - S_free( base_name ); - S_free( client_server ); return ret; } void -open_file( struct CONN * conn_ptr, - struct HOST_DESC * desc ) +open_file( struct CONN_DESC * conn_ptr, + struct HOST_DESC * hdesc ) { static char * s; FILE * lockfile; /* preparing for the connection side file */ if(flags.writer.type == UNIQUE - && desc->oth->file != NULL ) { + && hdesc->oth->lastincar->file != NULL ) { /* user want a unique output file, and it was just opened! */ - desc->file = desc->oth->file; - desc->filename = desc->oth->filename; + hdesc->lastincar->file = hdesc->oth->lastincar->file; + hdesc->lastincar->filename = hdesc->oth->lastincar->filename; } else { - s = (char *)avail_filename( conn_ptr, desc->side, "dat" ); + s = (char *)avail_filename( conn_ptr, hdesc->side, "dat" ); - desc->file = fopen( s , "a" ); - if( desc->file == NULL ) + hdesc->lastincar->file = fopen( s , "a" ); + if( hdesc->lastincar->file == NULL ) fault("open_file", "fopen returned NULL"); - desc->filename = s; + hdesc->lastincar->filename = s; - s = (char *)avail_filename( conn_ptr, desc->side, "lck"); + s = (char *)avail_filename( conn_ptr, hdesc->side, "lck"); lockfile = fopen( s , "a" ); if( lockfile == NULL ) fault("open_file", "fopen returned NULL"); fclose(lockfile); - desc->lockfilename = s; + hdesc->lastincar->lockfilename = s; } return; } __inline__ int -flowflush ( struct CONN * conn_ptr, - struct HOST_DESC * desc, +flowflush ( struct CONN_DESC * conn_ptr, + struct HOST_DESC * hdesc, u_char * buf, int buflen ) /* data that are acknowledged come here in order to be written to their file, or to stdout */ { /* -b set of options */ - if ( desc->side == flags.display_rebuild.side ) + if ( hdesc->side == flags.display_rebuild.side ) out_flavour ( flags.display_rebuild.flavour, stdout, buf, buflen ); @@ -204,33 +195,33 @@ flowflush ( struct CONN * conn_ptr, stdout, buf, buflen ); /* -w set of options */ - if ( desc->side == flags.writer.side ) { + if ( hdesc->side == flags.writer.side ) { - if(! desc->file ) - open_file( conn_ptr, desc ); + if(! hdesc->lastincar->file ) + open_file( conn_ptr, hdesc ); out_flavour ( flags.writer.flavour, - desc->file, buf, buflen ); + hdesc->lastincar->file, buf, buflen ); } else if ( flags.writer.side == BOTH ) { - if(! desc->file ) - open_file( conn_ptr, desc ); + if(! hdesc->lastincar->file ) + open_file( conn_ptr, hdesc ); if ( flags.writer.banner == 1 ) { /* -wb */ /* FIXME: add it to `-b' too? Do a function for this? */ - fprintf(desc->file, - (desc->side == CLIENT) + fprintf(hdesc->lastincar->file, + (hdesc->side == CLIENT) ? "\n[client] %d:%d (%d)\n" : "\n[server] %d:%d (%d)\n", - desc->wlen, - desc->wlen + buflen, + hdesc->lastincar->wlen, + hdesc->lastincar->wlen + buflen, buflen); } out_flavour ( flags.writer.flavour, - desc->file, buf, buflen ); + hdesc->lastincar->file, buf, buflen ); } } |