/*--------------------------------------------------------------- 
 * Copyright (c) 1999,2000,2001,2002,2003                              
 * The Board of Trustees of the University of Illinois            
 * All Rights Reserved.                                           
 *--------------------------------------------------------------- 
 * Permission is hereby granted, free of charge, to any person    
 * obtaining a copy of this software (Iperf) and associated       
 * documentation files (the "Software"), to deal in the Software  
 * without restriction, including without limitation the          
 * rights to use, copy, modify, merge, publish, distribute,        
 * sublicense, and/or sell copies of the Software, and to permit     
 * persons to whom the Software is furnished to do
 * so, subject to the following conditions: 
 *
 *     
 * Redistributions of source code must retain the above 
 * copyright notice, this list of conditions and 
 * the following disclaimers. 
 *
 *     
 * Redistributions in binary form must reproduce the above 
 * copyright notice, this list of conditions and the following 
 * disclaimers in the documentation and/or other materials 
 * provided with the distribution. 
 * 
 *     
 * Neither the names of the University of Illinois, NCSA, 
 * nor the names of its contributors may be used to endorse 
 * or promote products derived from this Software without
 * specific prior written permission. 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT 
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 * ________________________________________________________________
 * National Laboratory for Applied Network Research 
 * National Center for Supercomputing Applications 
 * University of Illinois at Urbana-Champaign 
 * http://www.ncsa.uiuc.edu
 * ________________________________________________________________ 
 *
 * Reporter.c
 * by Kevin Gibbs <kgibbs@nlanr.net>
 *
 * ________________________________________________________________ */

#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "Thread.h"
#include "Locale.h"
#include "PerfSocket.hpp"
#include "SocketAddr.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
  The following 4 functions are provided for Reporting
  styles that do not have all the reporting formats. For
  instance the provided CSV format does not have a settings
  report so it uses settings_notimpl.
  */
void* connection_notimpl( Connection_Info * nused, int nuse ) { 
    return NULL; 
}
void settings_notimpl( ReporterData * nused ) { }
void statistics_notimpl( Transfer_Info * nused ) { }
void serverstatistics_notimpl( Connection_Info *nused1, Transfer_Info *nused2 ) { }

// To add a reporting style include its header here.
#include "report_default.h"
#include "report_CSV.h"

// The following array of report structs contains the
// pointers required for reporting in different reporting
// styles. To add a reporting style add a report struct
// below.
report_connection connection_reports[kReport_MAXIMUM] = {
    reporter_reportpeer,
    CSV_peer
};

report_settings settings_reports[kReport_MAXIMUM] = {
    reporter_reportsettings,
    settings_notimpl
};

report_statistics statistics_reports[kReport_MAXIMUM] = {
    reporter_printstats,
    CSV_stats
};

report_serverstatistics serverstatistics_reports[kReport_MAXIMUM] = {
    reporter_serverstats,
    CSV_serverstats
};

report_statistics multiple_reports[kReport_MAXIMUM] = {
    reporter_multistats,
    CSV_stats
};

char buffer[64]; // Buffer for printing
ReportHeader *ReportRoot = NULL;
extern Condition ReportCond;
extern Condition ReportDoneCond;
int reporter_process_report ( ReportHeader *report );
void process_report ( ReportHeader *report );
int reporter_handle_packet( ReportHeader *report );
int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force );
int reporter_print( ReporterData *stats, int type, int end );
void PrintMSS( ReporterData *stats );

MultiHeader* InitMulti( thread_Settings *agent, int inID ) {
    MultiHeader *multihdr = NULL;
    if ( agent->mThreads > 1 || agent->mThreadMode == kMode_Server ) {
        if ( isMultipleReport( agent ) ) {
            multihdr = malloc(sizeof(MultiHeader) +  sizeof(ReporterData) +
                              NUM_MULTI_SLOTS * sizeof(Transfer_Info));
        } else {
            multihdr = malloc(sizeof(MultiHeader));
        }
        if ( multihdr != NULL ) {
            memset( multihdr, 0, sizeof(MultiHeader) );
            Condition_Initialize( &multihdr->barrier );
            multihdr->groupID = inID;
            multihdr->threads = agent->mThreads;
            if ( isMultipleReport( agent ) ) {
                int i;
                ReporterData *data = NULL;
                multihdr->report = (ReporterData*)(multihdr + 1);
                memset(multihdr->report, 0, sizeof(ReporterData));
                multihdr->data = (Transfer_Info*)(multihdr->report + 1);
                data = multihdr->report;
                for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
                    multihdr->data[i].startTime = -1;
                    multihdr->data[i].transferID = inID;
                    multihdr->data[i].groupID = -2;
                }
                data->type = TRANSFER_REPORT;
                if ( agent->mInterval != 0.0 ) {
                    struct timeval *interval = &data->intervalTime;
                    interval->tv_sec = (long) agent->mInterval;
                    interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec) 
                                                * rMillion);
                }
                data->mHost = agent->mHost;
                data->mLocalhost = agent->mLocalhost;
                data->mBufLen = agent->mBufLen;
                data->mMSS = agent->mMSS;
                data->mTCPWin = agent->mTCPWin;
                data->flags = agent->flags;
                data->mThreadMode = agent->mThreadMode;
                data->mode = agent->mReportMode;
                data->info.mFormat = agent->mFormat;
                data->info.mTTL = agent->mTTL;
                if ( isUDP( agent ) ) {
                    multihdr->report->info.mUDP = (char)agent->mThreadMode;
                }
                if ( isConnectionReport( agent ) ) {
                    data->type |= CONNECTION_REPORT;
                    data->connection.peer = agent->peer;
                    data->connection.size_peer = agent->size_peer;
                    SockAddr_setPortAny( &data->connection.peer );
                    data->connection.local = agent->local;
                    data->connection.size_local = agent->size_local;
                    SockAddr_setPortAny( &data->connection.local );
                }
            }
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
    return multihdr;
}

/*
 * BarrierClient allows for multiple stream clients to be syncronized
 */
void BarrierClient( ReportHeader *agent ) {
    Condition_Lock(agent->multireport->barrier);
    agent->multireport->threads--;
    if ( agent->multireport->threads == 0 ) {
        // last one set time and wake up everyone
        gettimeofday( &(agent->multireport->startTime), NULL );
        Condition_Broadcast( &agent->multireport->barrier );
    } else {
        Condition_Wait( &agent->multireport->barrier );
    }
    agent->multireport->threads++;
    Condition_Unlock( agent->multireport->barrier );
    agent->report.startTime = agent->multireport->startTime;
    agent->report.nextTime = agent->report.startTime;
    TimeAdd( agent->report.nextTime, agent->report.intervalTime );
}

/*
 * InitReport is called by a transfer agent (client or
 * server) to setup the needed structures to communicate
 * traffic.
 */
ReportHeader* InitReport( thread_Settings *agent ) {
    ReportHeader *reporthdr = NULL;
    ReporterData *data = NULL;
    if ( isDataReport( agent ) ) {
        /*
         * Create in one big chunk
         */
        reporthdr = malloc( sizeof(ReportHeader) +
                            NUM_REPORT_STRUCTS * sizeof(ReportStruct) );
        if ( reporthdr != NULL ) {
            // Only need to make sure the headers are clean
            memset( reporthdr, 0, sizeof(ReportHeader));
            reporthdr->data = (ReportStruct*)(reporthdr+1);
            reporthdr->multireport = agent->multihdr;
            data = &reporthdr->report;
            reporthdr->reporterindex = NUM_REPORT_STRUCTS - 1;
            data->info.transferID = agent->mSock;
            data->info.groupID = (agent->multihdr != NULL ? agent->multihdr->groupID 
                                                          : -1);
            data->type = TRANSFER_REPORT;
            if ( agent->mInterval != 0.0 ) {
                struct timeval *interval = &data->intervalTime;
                interval->tv_sec = (long) agent->mInterval;
                interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec) 
                                            * rMillion);
            }
            data->mHost = agent->mHost;
            data->mLocalhost = agent->mLocalhost;
            data->mBufLen = agent->mBufLen;
            data->mMSS = agent->mMSS;
            data->mTCPWin = agent->mTCPWin;
            data->flags = agent->flags;
            data->mThreadMode = agent->mThreadMode;
            data->mode = agent->mReportMode;
            data->info.mFormat = agent->mFormat;
            data->info.mTTL = agent->mTTL;
            if ( isUDP( agent ) ) {
                reporthdr->report.info.mUDP = (char)agent->mThreadMode;
            }
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
    if ( isConnectionReport( agent ) ) {
        if ( reporthdr == NULL ) {
            /*
             * Create in one big chunk
             */
            reporthdr = malloc( sizeof(ReportHeader) );
            if ( reporthdr != NULL ) {
                // Only need to make sure the headers are clean
                memset( reporthdr, 0, sizeof(ReportHeader));
                data = &reporthdr->report;
                data->info.transferID = agent->mSock;
                data->info.groupID = -1;
            } else {
                FAIL(1, "Out of Memory!!\n", agent);
            }
        }
        if ( reporthdr != NULL ) {
            data->type |= CONNECTION_REPORT;
            data->connection.peer = agent->peer;
            data->connection.size_peer = agent->size_peer;
            data->connection.local = agent->local;
            data->connection.size_local = agent->size_local;
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
    if ( isConnectionReport( agent ) || isDataReport( agent ) ) {

#ifdef HAVE_THREAD
        /*
         * Update the ReportRoot to include this report.
         */
        if ( reporthdr->report.mThreadMode == kMode_Client &&
             reporthdr->multireport != NULL ) {
            // syncronize watches on my mark......
            BarrierClient( reporthdr );
        } else {
            if ( reporthdr->multireport != NULL && isMultipleReport( agent )) {
                reporthdr->multireport->threads++;
                if ( reporthdr->multireport->report->startTime.tv_sec == 0 ) {
                    gettimeofday( &(reporthdr->multireport->report->startTime), NULL );
                }
                reporthdr->report.startTime = reporthdr->multireport->report->startTime;
            } else {
                // set start time
                gettimeofday( &(reporthdr->report.startTime), NULL );
            }
            reporthdr->report.nextTime = reporthdr->report.startTime;
            TimeAdd( reporthdr->report.nextTime, reporthdr->report.intervalTime );
        }
        Condition_Lock( ReportCond );
        reporthdr->next = ReportRoot;
        ReportRoot = reporthdr;
        Condition_Signal( &ReportCond );
        Condition_Unlock( ReportCond );
#else
        // set start time
        gettimeofday( &(reporthdr->report.startTime), NULL );
        /*
         * Process the report in this thread
         */
        reporthdr->next = NULL;
        process_report ( reporthdr );
#endif 
    }
    if ( !isDataReport( agent ) ) {
        reporthdr = NULL;
    }
    return reporthdr;
}

/*
 * ReportPacket is called by a transfer agent to record
 * the arrival or departure of a "packet" (for TCP it 
 * will actually represent many packets). This needs to
 * be as simple and fast as possible as it gets called for
 * every "packet".
 */
void ReportPacket( ReportHeader* agent, ReportStruct *packet ) {
    if ( agent != NULL ) {
        int index = agent->reporterindex;
        /*
         * First find the appropriate place to put the information
         */
        if ( agent->agentindex == NUM_REPORT_STRUCTS ) {
            // Just need to make sure that reporter is not on the first
            // item
            while ( index == 0 ) {
                Condition_Signal( &ReportCond );
                Condition_Wait( &ReportDoneCond );
                index = agent->reporterindex;
            }
            agent->agentindex = 0;
        }
        // Need to make sure that reporter is not about to be "lapped"
        while ( index - 1 == agent->agentindex ) {
            Condition_Signal( &ReportCond );
            Condition_Wait( &ReportDoneCond );
            index = agent->reporterindex;
        }

        // Put the information there
        memcpy( agent->data + agent->agentindex, packet, sizeof(ReportStruct) );
        
        // Updating agentindex MUST be the last thing done
        agent->agentindex++;
#ifndef HAVE_THREAD
        /*
         * Process the report in this thread
         */
        process_report ( agent );
#endif 
    }
}

/*
 * CloseReport is called by a transfer agent to finalize
 * the report and signal transfer is over.
 */
void CloseReport( ReportHeader *agent, ReportStruct *packet ) {
    if ( agent != NULL) {

        /*
         * Using PacketID of -1 ends reporting
         */
        packet->packetID = -1;
        packet->packetLen = 0;
        ReportPacket( agent, packet );
        packet->packetID = agent->report.cntDatagrams;
    }
}

/*
 * EndReport signifies the agent no longer is interested
 * in the report. Calls to GetReport will no longer be
 * filled
 */
void EndReport( ReportHeader *agent ) {
    if ( agent != NULL ) {
        int index = agent->reporterindex;
        while ( index != -1 ) {
            thread_rest();
            index = agent->reporterindex;
        }
        agent->agentindex = -1;
#ifndef HAVE_THREAD
        /*
         * Process the report in this thread
         */
        process_report ( agent );
#endif
    }
}

/*
 * GetReport is called by the agent after a CloseReport
 * but before an EndReport to get the stats generated
 * by the reporter thread.
 */
Transfer_Info *GetReport( ReportHeader *agent ) {
    int index = agent->reporterindex;
    while ( index != -1 ) {
        thread_rest();
        index = agent->reporterindex;
    }
    return &agent->report.info;
}

/*
 * ReportSettings will generate a summary report for
 * settings being used with Listeners or Clients
 */
void ReportSettings( thread_Settings *agent ) {
    if ( isSettingsReport( agent ) ) {
        /*
         * Create in one big chunk
         */
        ReportHeader *reporthdr = malloc( sizeof(ReportHeader) );
    
        if ( reporthdr != NULL ) {
            ReporterData *data = &reporthdr->report;
            data->info.transferID = agent->mSock;
            data->info.groupID = -1;
            reporthdr->agentindex = -1;
            reporthdr->reporterindex = -1;
        
            data->mHost = agent->mHost;
            data->mLocalhost = agent->mLocalhost;
            data->mode = agent->mReportMode;
            data->type = SETTINGS_REPORT;
            data->mBufLen = agent->mBufLen;
            data->mMSS = agent->mMSS;
            data->mTCPWin = agent->mTCPWin;
            data->flags = agent->flags;
            data->mThreadMode = agent->mThreadMode;
            data->mPort = agent->mPort;
            data->info.mFormat = agent->mFormat;
            data->info.mTTL = agent->mTTL;
            data->connection.peer = agent->peer;
            data->connection.size_peer = agent->size_peer;
            data->connection.local = agent->local;
            data->connection.size_local = agent->size_local;
    
    #ifdef HAVE_THREAD
            /*
             * Update the ReportRoot to include this report.
             */
            Condition_Lock( ReportCond );
            reporthdr->next = ReportRoot;
            ReportRoot = reporthdr;
            Condition_Signal( &ReportCond );
            Condition_Unlock( ReportCond );
    #else
            /*
             * Process the report in this thread
             */
            reporthdr->next = NULL;
            process_report ( reporthdr );
    #endif 
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
}

/*
 * ReportServerUDP will generate a report of the UDP
 * statistics as reported by the server on the client
 * side.
 */
void ReportServerUDP( thread_Settings *agent, server_hdr *server ) {
    if ( (ntohl(server->flags) & HEADER_VERSION1) != 0 &&
         isServerReport( agent ) ) {
        /*
         * Create in one big chunk
         */
        ReportHeader *reporthdr = malloc( sizeof(ReportHeader) );
        Transfer_Info *stats = &reporthdr->report.info;

        if ( reporthdr != NULL ) {
            stats->transferID = agent->mSock;
            stats->groupID = (agent->multihdr != NULL ? agent->multihdr->groupID 
                                                      : -1);
            reporthdr->agentindex = -1;
            reporthdr->reporterindex = -1;

            reporthdr->report.type = SERVER_RELAY_REPORT;
            reporthdr->report.mode = agent->mReportMode;
            stats->mFormat = agent->mFormat;
            stats->jitter = ntohl( server->jitter1 );
            stats->jitter += ntohl( server->jitter2 ) / (double)rMillion;
            stats->TotalLen = (((max_size_t) ntohl( server->total_len1 )) << 32) +
                                  ntohl( server->total_len2 ); 
            stats->startTime = 0;
            stats->endTime = ntohl( server->stop_sec );
            stats->endTime += ntohl( server->stop_usec ) / (double)rMillion;
            stats->cntError = ntohl( server->error_cnt );
            stats->cntOutofOrder = ntohl( server->outorder_cnt );
            stats->cntDatagrams = ntohl( server->datagrams );
            stats->mUDP = (char)kMode_Server;
            reporthdr->report.connection.peer = agent->local;
            reporthdr->report.connection.size_peer = agent->size_local;
            reporthdr->report.connection.local = agent->peer;
            reporthdr->report.connection.size_local = agent->size_peer;
            
#ifdef HAVE_THREAD
            /*
             * Update the ReportRoot to include this report.
             */
            Condition_Lock( ReportCond );
            reporthdr->next = ReportRoot;
            ReportRoot = reporthdr;
            Condition_Signal( &ReportCond );
            Condition_Unlock( ReportCond );
#else
            /*
             * Process the report in this thread
             */
            reporthdr->next = NULL;
            process_report ( reporthdr );
#endif 
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
}

/*
 * This function is called only when the reporter thread
 * This function is the loop that the reporter thread processes
 */
void reporter_spawn( thread_Settings *thread ) {
    do {
        // This section allows for safe exiting with Ctrl-C
        Condition_Lock ( ReportCond );
        if ( ReportRoot == NULL ) {
            // Allow main thread to exit if Ctrl-C is received
            thread_setignore();
            Condition_Wait ( &ReportCond );
            // Stop main thread from exiting until done with all reports
            thread_unsetignore();
        }
        Condition_Unlock ( ReportCond );

again:
        if ( ReportRoot != NULL ) {
            ReportHeader *temp = ReportRoot;
            //Condition_Unlock ( ReportCond );
            if ( reporter_process_report ( temp ) ) {
                // This section allows for more reports to be added while
                // the reporter is processing reports without needing to
                // stop the reporter or immediately notify it
                Condition_Lock ( ReportCond );
                if ( temp == ReportRoot ) {
                    // no new reports
                    ReportRoot = temp->next;
                } else {
                    // new reports added
                    ReportHeader *itr = ReportRoot;
                    while ( itr->next != temp ) {
                        itr = itr->next;
                    }
                    itr->next = temp->next;
                }
                // finished with report so free it
                free( temp );
                Condition_Unlock ( ReportCond );
                Condition_Signal( &ReportDoneCond );
                if (ReportRoot)
                    goto again;
            }
            Condition_Signal( &ReportDoneCond );
            usleep(10000);
        } else {
            //Condition_Unlock ( ReportCond );
        }
    } while ( 1 );
}

/*
 * Used for single threaded reporting
 */
void process_report ( ReportHeader *report ) {
    if ( report != NULL ) {
        if ( reporter_process_report( report ) ) {
            free( report );
        }
    }
}

/*
 * Process reports starting with "reporthdr"
 */
int reporter_process_report ( ReportHeader *reporthdr ) {
    int need_free = 0;

    // Recursively process reports
    if ( reporthdr->next != NULL ) {
        if ( reporter_process_report( reporthdr->next ) ) {
            // If we are done with this report then free it
            ReportHeader *temp = reporthdr->next;
            reporthdr->next = reporthdr->next->next;
            free( temp );
        }
    }

    if ( (reporthdr->report.type & SETTINGS_REPORT) != 0 ) {
        reporthdr->report.type &= ~SETTINGS_REPORT;
        return reporter_print( &reporthdr->report, SETTINGS_REPORT, 1 );
    } else if ( (reporthdr->report.type & CONNECTION_REPORT) != 0 ) {
        reporthdr->report.type &= ~CONNECTION_REPORT;
        reporter_print( &reporthdr->report, CONNECTION_REPORT,
                               (reporthdr->report.type == 0 ? 1 : 0) );
        if ( reporthdr->multireport != NULL && isMultipleReport( (&reporthdr->report) )) {
            if ( (reporthdr->multireport->report->type & CONNECTION_REPORT) != 0 ) {
                reporthdr->multireport->report->type &= ~CONNECTION_REPORT;
                reporter_print( reporthdr->multireport->report, CONNECTION_REPORT,
                                (reporthdr->report.type == 0 ? 1 : 0) );
            }
        }
    } else if ( (reporthdr->report.type & SERVER_RELAY_REPORT) != 0 ) {
        reporthdr->report.type &= ~SERVER_RELAY_REPORT;
        return reporter_print( &reporthdr->report, SERVER_RELAY_REPORT, 1 );
    }
    if ( (reporthdr->report.type & TRANSFER_REPORT) != 0 ) {
        // If there are more packets to process then handle them
        if ( reporthdr->reporterindex >= 0 ) {
            // Need to make sure we do not pass the "agent"
            while ( reporthdr->reporterindex != reporthdr->agentindex - 1 ) {
                if ( reporthdr->reporterindex == NUM_REPORT_STRUCTS - 1 ) {
                    if ( reporthdr->agentindex == 0 ) {
                        break;
                    } else {
                        reporthdr->reporterindex = 0;
                    }
                } else {
                    reporthdr->reporterindex++;
                }
                if ( reporter_handle_packet( reporthdr ) ) {
                    // No more packets to process
                    reporthdr->reporterindex = -1;
                    break;
                }
            }
        }
        // If the agent is done with the report then free it
        if ( reporthdr->agentindex == -1 ) {
            need_free = 1;
        }
    }
    return need_free;
}

/*
 * Updates connection stats
 */
int reporter_handle_packet( ReportHeader *reporthdr ) {
    ReportStruct *packet = &reporthdr->data[reporthdr->reporterindex];
    ReporterData *data = &reporthdr->report;
    Transfer_Info *stats = &reporthdr->report.info;
    int finished = 0;

    data->cntDatagrams++;
    // If this is the last packet set the endTime
    if ( packet->packetID < 0 ) {
        data->packetTime = packet->packetTime;
        finished = 1;
        if ( reporthdr->report.mThreadMode != kMode_Client ) {
            data->TotalLen += packet->packetLen;
        }
    } else {
        // update recieved amount and time
        data->packetTime = packet->packetTime;
        reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
        data->TotalLen += packet->packetLen;
        if ( packet->packetID != 0 ) {
            // UDP packet
            double transit;
            double deltaTransit;
            
            // from RFC 1889, Real Time Protocol (RTP) 
            // J = J + ( | D(i-1,i) | - J ) / 16 
            transit = TimeDifference( packet->packetTime, packet->sentTime );
            if ( data->lastTransit != 0.0 ) {
                deltaTransit = transit - data->lastTransit;
                if ( deltaTransit < 0.0 ) {
                    deltaTransit = -deltaTransit;
                }
                stats->jitter += (deltaTransit - stats->jitter) / (16.0);
            }
            data->lastTransit = transit;
    
            // packet loss occured if the datagram numbers aren't sequential 
            if ( packet->packetID != data->PacketID + 1 ) {
                if ( packet->packetID < data->PacketID + 1 ) {
                    data->cntOutofOrder++;
                } else {
                    data->cntError += packet->packetID - data->PacketID - 1;
                }
            }
            // never decrease datagramID (e.g. if we get an out-of-order packet) 
            if ( packet->packetID > data->PacketID ) {
                data->PacketID = packet->packetID;
            }
        }
    }

    // Print a report if appropriate
    return reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
}

/*
 * Handles summing of threads
 */
void reporter_handle_multiple_reports( MultiHeader *reporthdr, Transfer_Info *stats, int force ) {
    if ( reporthdr != NULL ) {
        if ( reporthdr->threads > 1 ) {
            int i;
            Transfer_Info *current = NULL;
            // Search for start Time
            for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
                current = &reporthdr->data[i];
                if ( current->startTime == stats->startTime ) {
                    break;
                }
            }
            if ( current->startTime != stats->startTime ) {
                // Find first available
                for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
                    current = &reporthdr->data[i];
                    if ( current->startTime < 0 ) {
                        break;
                    }
                }
                current->cntDatagrams = stats->cntDatagrams;
                current->cntError = stats->cntError;
                current->cntOutofOrder = stats->cntOutofOrder;
                current->TotalLen = stats->TotalLen;
                current->mFormat = stats->mFormat;
                current->endTime = stats->endTime;
                current->jitter = stats->jitter;
                current->startTime = stats->startTime;
                current->free = 1;
            } else {
                current->cntDatagrams += stats->cntDatagrams;
                current->cntError += stats->cntError;
                current->cntOutofOrder += stats->cntOutofOrder;
                current->TotalLen += stats->TotalLen;
                current->mFormat = stats->mFormat;
                if ( current->endTime < stats->endTime ) {
                    current->endTime = stats->endTime;
                }
                if ( current->jitter < stats->jitter ) {
                    current->jitter = stats->jitter;
                }
                current->free++;
                if ( current->free == reporthdr->threads ) {
                    void *reserved = reporthdr->report->info.reserved_delay;
                    current->free = force;
                    memcpy( &reporthdr->report->info, current, sizeof(Transfer_Info) );
                    current->startTime = -1;
                    reporthdr->report->info.reserved_delay = reserved;
                    reporter_print( reporthdr->report, MULTIPLE_REPORT, force );
                }
            }
        }
    }
}

/*
 * Prints reports conditionally
 */
int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force ) {
    if ( force != 0 ) {
        stats->info.cntOutofOrder = stats->cntOutofOrder;
        // assume most of the time out-of-order packets are not
        // duplicate packets, so conditionally subtract them from the lost packets.
        stats->info.cntError = stats->cntError;
        if ( stats->info.cntError > stats->info.cntOutofOrder ) {
            stats->info.cntError -= stats->info.cntOutofOrder;
        }
        stats->info.cntDatagrams = (isUDP(stats) ? stats->PacketID : stats->cntDatagrams);
        stats->info.TotalLen = stats->TotalLen;
        stats->info.startTime = 0;
        stats->info.endTime = TimeDifference( stats->packetTime, stats->startTime );
        stats->info.free = 1;
        reporter_print( stats, TRANSFER_REPORT, force );
        if ( isMultipleReport(stats) ) {
            reporter_handle_multiple_reports( multireport, &stats->info, force );
        }
    } else while ((stats->intervalTime.tv_sec != 0 || 
                   stats->intervalTime.tv_usec != 0) && 
                  TimeDifference( stats->nextTime, 
                                  stats->packetTime ) < 0 ) {
        stats->info.cntOutofOrder = stats->cntOutofOrder - stats->lastOutofOrder;
        stats->lastOutofOrder = stats->cntOutofOrder;
        // assume most of the time out-of-order packets are not
        // duplicate packets, so conditionally subtract them from the lost packets.
        stats->info.cntError = stats->cntError - stats->lastError;
        if ( stats->info.cntError > stats->info.cntOutofOrder ) {
            stats->info.cntError -= stats->info.cntOutofOrder;
        }
        stats->lastError = stats->cntError;
        stats->info.cntDatagrams = (isUDP( stats ) ? stats->PacketID - stats->lastDatagrams :
                                                     stats->cntDatagrams - stats->lastDatagrams);
        stats->lastDatagrams = (isUDP( stats ) ? stats->PacketID : stats->cntDatagrams);
        stats->info.TotalLen = stats->TotalLen - stats->lastTotal;
        stats->lastTotal = stats->TotalLen;
        stats->info.startTime = stats->info.endTime;
        stats->info.endTime = TimeDifference( stats->nextTime, stats->startTime );
        TimeAdd( stats->nextTime, stats->intervalTime );
        stats->info.free = 0;
        reporter_print( stats, TRANSFER_REPORT, force );
        if ( isMultipleReport(stats) ) {
            reporter_handle_multiple_reports( multireport, &stats->info, force );
        }
    }
    return force;
}

/*
 * This function handles multiple format printing by sending to the
 * appropriate dispatch function
 */
int reporter_print( ReporterData *stats, int type, int end ) {
    switch ( type ) {
        case TRANSFER_REPORT:
            statistics_reports[stats->mode]( &stats->info );
            if ( end != 0 && isPrintMSS( stats ) && !isUDP( stats ) ) {
                PrintMSS( stats );
            }
            break;
        case SERVER_RELAY_REPORT:
            serverstatistics_reports[stats->mode]( &stats->connection, &stats->info );
            break;
        case SETTINGS_REPORT:
            settings_reports[stats->mode]( stats );
            break;
        case CONNECTION_REPORT:
            stats->info.reserved_delay = connection_reports[stats->mode]( 
                                               &stats->connection,
                                               stats->info.transferID );
            break;
        case MULTIPLE_REPORT:
            multiple_reports[stats->mode]( &stats->info );
            break;
        default:
            fprintf( stderr, "Printing type not implemented! No Output\n" );
    }
    fflush( stdout );
    return end;
}

/* -------------------------------------------------------------------
 * Report the MSS and MTU, given the MSS (or a guess thereof)
 * ------------------------------------------------------------------- */

// compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
// 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.

#define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS  &&  inMSS >= (inMTU-80)

void PrintMSS( ReporterData *stats ) {
    int inMSS = getsock_tcp_mss( stats->info.transferID );

    if ( inMSS <= 0 ) {
        printf( report_mss_unsupported, stats->info.transferID );
    } else {
        char* net;
        int mtu = 0;

        if ( checkMSS_MTU( inMSS, 1500 ) ) {
            net = "ethernet";
            mtu = 1500;
        } else if ( checkMSS_MTU( inMSS, 4352 ) ) {
            net = "FDDI";
            mtu = 4352;
        } else if ( checkMSS_MTU( inMSS, 9180 ) ) {
            net = "ATM";
            mtu = 9180;
        } else if ( checkMSS_MTU( inMSS, 65280 ) ) {
            net = "HIPPI";
            mtu = 65280;
        } else if ( checkMSS_MTU( inMSS, 576 ) ) {
            net = "minimum";
            mtu = 576;
            printf( warn_no_pathmtu );
        } else {
            mtu = inMSS + 40;
            net = "unknown interface";
        }

        printf( report_mss,
                stats->info.transferID, inMSS, mtu, net );
    }
}
// end ReportMSS

#ifdef __cplusplus
} /* end extern "C" */
#endif
