Example #1
0
void
QueueLoggerSampling::logQueue(Queue& queue, QueueEvent ev, Packet &pkt) {
	if (_queue==NULL) _queue=&queue;
	assert(&queue==_queue);
	_lastq = queue._queuesize;
	if (!_seenQueueInD) {
		_seenQueueInD=true;
		_minQueueInD=queue._queuesize;
		_maxQueueInD=_minQueueInD;
		_lastDroppedInD=0;
		_lastIdledInD=0;
		_numIdledInD=0;
		_numDropsInD=0;
		}
	else {
		_minQueueInD=min(_minQueueInD,queue._queuesize);
		_maxQueueInD=max(_maxQueueInD,queue._queuesize);
		}
	simtime_picosec now = eventlist().now();
	simtime_picosec dt_ps = now-_lastlook;
	double dt = timeAsSec(dt_ps);
	_lastlook = now;
	switch(ev) {
		case PKT_SERVICE: // we've just been working
			break;
		case PKT_ENQUEUE:
			_cumarr += timeAsSec(queue.drainTime(&pkt));
			if (queue._queuesize>pkt.size()) // we've just been working
				{}
			else { // we've just been idling 
				mem_b idledwork = queue.serviceCapacity(dt_ps);
				_cumidle += dt; 
				_lastIdledInD = idledwork;
				_numIdledInD++;
				}
			break;
		case PKT_DROP: // assume we've just been working
			assert(queue._queuesize>=pkt.size()); // it is possible to drop when queue is idling, but this logger can't make sense of it
			double localdroptime = timeAsSec(queue.drainTime(&pkt));
			_cumarr += localdroptime;
			_cumdrop += localdroptime;
			_lastDroppedInD = pkt.size();
			_numDropsInD++;
			break;
		}
	}
Example #2
0
void
QueueLoggerSampling::doNextEvent() 
	{
	eventlist().sourceIsPendingRel(*this,_period);
	if (_queue==NULL) return;
	mem_b queuebuff = _queue->_maxsize;
	if (!_seenQueueInD) { // queue size hasn't changed in the past D time units
		_logfile->writeRecord(QUEUE_APPROX,_queue->id,QUEUE_RANGE,(double)_lastq,(double)_lastq,(double)_lastq);
		_logfile->writeRecord(QUEUE_APPROX,_queue->id,QUEUE_OVERFLOW,0,0,(double)queuebuff);
		}
	else { // queue size has changed
		_logfile->writeRecord(QUEUE_APPROX,_queue->id,QUEUE_RANGE,(double)_lastq,(double)_minQueueInD,(double)_maxQueueInD);
		_logfile->writeRecord(QUEUE_APPROX,_queue->id,QUEUE_OVERFLOW,-(double)_lastIdledInD,(double)_lastDroppedInD,(double)queuebuff);
		}
	_seenQueueInD=false;
	simtime_picosec now = eventlist().now();
	simtime_picosec dt_ps = now-_lastlook;
	_lastlook = now;
	if ((_queue!=NULL) & (_queue->_queuesize==0)) _cumidle += timeAsSec(dt_ps); // if the queue is empty, we've just been idling
	_logfile->writeRecord(QUEUE_RECORD,_queue->id,CUM_TRAFFIC,_cumarr,_cumidle,_cumdrop);
	}
Example #3
0
int main(int argc, char **argv) {
    EventList eventlist;
    eventlist.setEndtime(timeFromSec(5000));
    Clock c(timeFromSec(50/100.), eventlist);
    int algo = UNCOUPLED;
    double epsilon = 1;
    int crt = 2;

    if (argc>1) {
        if (!strcmp(argv[1],"UNCOUPLED"))
            algo = UNCOUPLED;
        else if (!strcmp(argv[1],"COUPLED_INC"))
            algo = COUPLED_INC;
        else if (!strcmp(argv[1],"FULLY_COUPLED"))
            algo = FULLY_COUPLED;
        else if (!strcmp(argv[1],"COUPLED_TCP"))
            algo = COUPLED_TCP;
        else if (!strcmp(argv[1],"COUPLED_EPSILON")) {
            algo = COUPLED_EPSILON;
            if (argc>2) {
                epsilon = atof(argv[2]);
                crt++;
                printf("Using epsilon %f\n",epsilon);
            }
        }
        else
            exit_error(argv[0]);
    }
    linkspeed_bps SERVICE1 = speedFromPktps(400);
    linkspeed_bps SERVICE2;
    if (argc>crt)
        SERVICE2 = speedFromPktps(atoi(argv[crt++]));
    else
        SERVICE2 = speedFromPktps(400);

    simtime_picosec RTT1=timeFromMs(100);
    simtime_picosec RTT2;
    if (argc>crt)
        RTT2 = timeFromMs(atoi(argv[crt]));
    else
        RTT2 = timeFromMs(100);

    mem_b BUFFER1=memFromPkt(RANDOM_BUFFER+timeAsSec(RTT1)*speedAsPktps(SERVICE1));//NUMFLOWS * targetwnd);
    mem_b BUFFER2=memFromPkt(RANDOM_BUFFER+timeAsSec(RTT2)*speedAsPktps(SERVICE2));//NUMFLOWS * targetwnd);

    srand(time(NULL));

    // prepare the loggers
    stringstream filename(ios_base::out);
    filename << "../data/logout." << speedAsPktps(SERVICE2) << "pktps." <<timeAsMs(RTT2) << "ms."<< rand();
    cout << "Outputting to " << filename.str() << endl;
    Logfile logfile(filename.str(),eventlist);

    logfile.setStartTime(timeFromSec(0.5));
    QueueLoggerSimple logQueue = QueueLoggerSimple();
    logfile.addLogger(logQueue);
    //	QueueLoggerSimple logPQueue1 = QueueLoggerSimple(); logfile.addLogger(logPQueue1);
    //QueueLoggerSimple logPQueue3 = QueueLoggerSimple(); logfile.addLogger(logPQueue3);
    QueueLoggerSimple logPQueue = QueueLoggerSimple();
    logfile.addLogger(logPQueue);
    MultipathTcpLoggerSimple mlogger = MultipathTcpLoggerSimple();
    logfile.addLogger(mlogger);

    //TrafficLoggerSimple logger;
    //logfile.addLogger(logger);
    SinkLoggerSampling sinkLogger = SinkLoggerSampling(timeFromMs(1000),eventlist);

    logfile.addLogger(sinkLogger);


    QueueLoggerSampling qs1 = QueueLoggerSampling(timeFromMs(1000),eventlist);
    logfile.addLogger(qs1);
    QueueLoggerSampling qs2 = QueueLoggerSampling(timeFromMs(1000),eventlist);
    logfile.addLogger(qs2);

    TcpLoggerSimple* logTcp = NULL;

    logTcp = new TcpLoggerSimple();
    logfile.addLogger(*logTcp);

    // Build the network
    Pipe pipe1(RTT1, eventlist);
    pipe1.setName("pipe1");
    logfile.writeName(pipe1);
    Pipe pipe2(RTT2, eventlist);
    pipe2.setName("pipe2");
    logfile.writeName(pipe2);
    Pipe pipe_back(timeFromMs(.1), eventlist);
    pipe_back.setName("pipe_back");
    logfile.writeName(pipe_back);

    RandomQueue queue1(SERVICE1, BUFFER1, eventlist,&qs1,memFromPkt(RANDOM_BUFFER));
    queue1.setName("Queue1");
    logfile.writeName(queue1);

    RandomQueue queue2(SERVICE2, BUFFER2, eventlist,&qs2,memFromPkt(RANDOM_BUFFER));
    queue2.setName("Queue2");
    logfile.writeName(queue2);
    Queue pqueue2(SERVICE2*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL);
    pqueue2.setName("PQueue2");
    logfile.writeName(pqueue2);
    Queue pqueue3(SERVICE1*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL);
    pqueue3.setName("PQueue3");
    logfile.writeName(pqueue3);
    Queue pqueue4(SERVICE2*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL);
    pqueue4.setName("PQueue4");
    logfile.writeName(pqueue4);

    Queue* pqueue;

    Queue queue_back(max(SERVICE1,SERVICE2)*4, memFromPkt(1000), eventlist,NULL);
    queue_back.setName("queue_back");
    logfile.writeName(queue_back);

    TcpRtxTimerScanner tcpRtxScanner(timeFromMs(10), eventlist);

    //TCP flows on path 1
    TcpSrc* tcpSrc;
    TcpSink* tcpSnk;
    route_t* routeout;
    route_t* routein;
    double extrastarttime;

    for (int i=0; i<TCP_1; i++) {
        tcpSrc = new TcpSrc(NULL,NULL,eventlist);
        tcpSrc->setName("Tcp1");
        logfile.writeName(*tcpSrc);
        tcpSnk = new TcpSink();
        tcpSnk->setName("Tcp1");
        logfile.writeName(*tcpSnk);

        tcpRtxScanner.registerTcp(*tcpSrc);

        // tell it the route
        pqueue = new Queue(SERVICE1*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL);
        pqueue->setName("PQueue1_"+ntoa(i));
        logfile.writeName(*pqueue);

        routeout = new route_t();
        routeout->push_back(pqueue);
        routeout->push_back(&queue1);
        routeout->push_back(&pipe1);
        routeout->push_back(tcpSnk);

        routein  = new route_t();
        routein->push_back(tcpSrc);

        extrastarttime = drand()*50;
        tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime));
        sinkLogger.monitorSink(tcpSnk);
    }

    //TCP flow on path 2
    for (int i=0; i<TCP_2; i++) {
        tcpSrc = new TcpSrc(NULL,NULL,eventlist);
        tcpSrc->setName("Tcp2");
        logfile.writeName(*tcpSrc);
        tcpSnk = new TcpSink();
        tcpSnk->setName("Tcp2");
        logfile.writeName(*tcpSnk);

        tcpRtxScanner.registerTcp(*tcpSrc);

        pqueue = new Queue(SERVICE2*2, memFromPkt(FEEDER_BUFFER), eventlist,NULL);
        pqueue->setName("PQueue2_"+ntoa(i));
        logfile.writeName(*pqueue);

        // tell it the route
        routeout = new route_t();
        routeout->push_back(pqueue);
        routeout->push_back(&queue2);
        routeout->push_back(&pipe2);
        routeout->push_back(tcpSnk);

        routein  = new route_t(); //routein->push_back(&queue_back); routein->push_back(&pipe_back);
        routein->push_back(tcpSrc);
        extrastarttime = 50*drand();
        tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime));
        sinkLogger.monitorSink(tcpSnk);
    }

    MultipathTcpSrc* mtcp;
    if (algo==COUPLED_EPSILON)
        mtcp = new MultipathTcpSrc(algo,eventlist,&mlogger,epsilon);
    else
        mtcp = new MultipathTcpSrc(algo,eventlist,&mlogger);

    //MTCP flow 1
    tcpSrc = new TcpSrc(NULL,NULL,eventlist);
    tcpSrc->setName("Subflow1");
    logfile.writeName(*tcpSrc);
    tcpSnk = new TcpSink();
    tcpSnk->setName("Subflow1");
    logfile.writeName(*tcpSnk);

    tcpRtxScanner.registerTcp(*tcpSrc);

    // tell it the route
    routeout = new route_t();
    routeout->push_back(&pqueue3);
    routeout->push_back(&queue1);
    routeout->push_back(&pipe1);
    routeout->push_back(tcpSnk);

    routein  = new route_t();
    //routein->push_back(&queue_back); routein->push_back(&pipe_back);
    routein->push_back(tcpSrc);
    extrastarttime = 50*drand();

    //join multipath connection
    mtcp->addSubflow(tcpSrc);

    tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime));
    sinkLogger.monitorSink(tcpSnk);

    //MTCP flow 2
    tcpSrc = new TcpSrc(NULL,NULL,eventlist);
    tcpSrc->setName("Subflow2");
    logfile.writeName(*tcpSrc);
    tcpSnk = new TcpSink();
    tcpSnk->setName("Subflow2");
    logfile.writeName(*tcpSnk);
    tcpRtxScanner.registerTcp(*tcpSrc);

    // tell it the route
    routeout = new route_t();
    routeout->push_back(&pqueue4);
    routeout->push_back(&queue2);
    routeout->push_back(&pipe2);
    routeout->push_back(tcpSnk);

    routein  = new route_t();
    //routein->push_back(&queue_back); routein->push_back(&pipe_back);
    routein->push_back(tcpSrc);
    extrastarttime = 50*drand();

    //join multipath connection
    mtcp->addSubflow(tcpSrc);

    tcpSrc->connect(*routeout,*routein,*tcpSnk,timeFromMs(extrastarttime));
    sinkLogger.monitorSink(tcpSnk);

    // Record the setup
    int pktsize = TcpPacket::DEFAULTDATASIZE;
    logfile.write("# pktsize="+ntoa(pktsize)+" bytes");
    logfile.write("# bottleneckrate1="+ntoa(speedAsPktps(SERVICE1))+" pkt/sec");
    logfile.write("# bottleneckrate2="+ntoa(speedAsPktps(SERVICE2))+" pkt/sec");
    logfile.write("# buffer1="+ntoa((double)(queue1._maxsize)/((double)pktsize))+" pkt");
    logfile.write("# buffer2="+ntoa((double)(queue2._maxsize)/((double)pktsize))+" pkt");
    double rtt = timeAsSec(RTT1);
    logfile.write("# rtt="+ntoa(rtt));
    rtt = timeAsSec(RTT2);
    logfile.write("# rtt="+ntoa(rtt));
    logfile.write("# numflows="+ntoa(NUMFLOWS));
    logfile.write("# targetwnd="+ntoa(targetwnd));

    // GO!
    while (eventlist.doNextEvent()) {}
}
Example #4
0
int
main (int argc, char **argv)
{
        eventlist.setEndtime (timeFromSec (200));
        Clock c (timeFromSec (50 / 100.), eventlist);
        int algo = COUPLED_EPSILON;
        double epsilon = 1;
        int param = 0;
        stringstream filename (ios_base::out);
        uint64_t pktperflow = 1048576LL/1000 + 1;
        if (argc > 1) {
                int i = 1;

                if (!strcmp (argv[1], "-o")) {
                        filename << argv[2];
                        i += 2;
                } else {
                        filename << "logout.dat";
                }

                if (argc > i && !strcmp (argv[i], "-sub")) {
                        subflow_count = atoi (argv[i + 1]);
                        i += 2;
                }

                if (argc > i && !strcmp (argv[i], "-flowM")) {
                        pktperflow = atoi (argv[i + 1])*1048576LL/1000;
                        i += 2;
                        cout << "Using subflow count " << subflow_count << endl;
                }
                if (argc > i && !strcmp (argv[i], "-param")) {
                        param = atoi (argv[i + 1]);
                        i += 2;
                        cout << "Using subflow count " << subflow_count << endl;
                }


                if (argc > i) {
                        epsilon = -1;

                        if (!strcmp (argv[i], "UNCOUPLED")) {
                                algo = UNCOUPLED;
                        } else if (!strcmp (argv[i], "COUPLED_INC")) {
                                algo = COUPLED_INC;
                        } else if (!strcmp (argv[i], "FULLY_COUPLED")) {
                                algo = FULLY_COUPLED;
                        } else if (!strcmp (argv[i], "COUPLED_TCP")) {
                                algo = COUPLED_TCP;
                        } else if (!strcmp (argv[i], "COUPLED_SCALABLE_TCP")) {
                                algo = COUPLED_SCALABLE_TCP;
                        } else if (!strcmp (argv[i], "COUPLED_EPSILON")) {
                                algo = COUPLED_EPSILON;

                                if (argc > i + 1) {
                                        epsilon = atof (argv[i + 1]);
                                }

                                printf ("Using epsilon %f\n", epsilon);
                        } else {
                                exit_error (argv[0]);
                        }
                }
        }

        srand (time (NULL));
        cout << "Using algo=" << algo << " epsilon=" << epsilon << endl;
        // prepare the loggers
        cout << "Logging to " << filename.str () << endl;
        //Logfile
        Logfile logfile (filename.str (), eventlist);
#if PRINT_PATHS
        filename << ".paths";
        cout << "Logging path choices to " << filename.str () << endl;
        std::ofstream paths (filename.str ().c_str ());

        if (!paths) {
                cout << "Can't open for writing paths file!" << endl;
                exit (1);
        }

#endif
        int tot_subs = 0;
        int cnt_con = 0;
        lg = &logfile;
        logfile.setStartTime (timeFromSec (0));
        SinkLoggerSampling sinkLogger =
                SinkLoggerSampling (timeFromMs (1000), eventlist);
        logfile.addLogger (sinkLogger);
        //TcpLoggerSimple logTcp;logfile.addLogger(logTcp);
        TcpSrc *tcpSrc;
        TcpSink *tcpSnk;
        //CbrSrc* cbrSrc;
        //CbrSink* cbrSnk;
        route_t *routeout, *routein;
        double extrastarttime;
        TcpRtxTimerScanner tcpRtxScanner (timeFromMs (10), eventlist);
        MultipathTcpSrc *mtcp;
        vector<MultipathTcpSrc*> mptcpVector;
        int dest;
#if USE_FIRST_FIT

        if (subflow_count == 1) {
                ff = new FirstFit (timeFromMs (FIRST_FIT_INTERVAL), eventlist);
        }

#endif
#ifdef FAT_TREE
        FatTreeTopology *top = new FatTreeTopology (&logfile, &eventlist, ff);
#endif
#ifdef OV_FAT_TREE
        OversubscribedFatTreeTopology *top =
                new OversubscribedFatTreeTopology (&logfile, &eventlist, ff);
#endif
#ifdef MH_FAT_TREE
        MultihomedFatTreeTopology *top =
                new MultihomedFatTreeTopology (&logfile, &eventlist, ff);
#endif
#ifdef STAR
        StarTopology *top = new StarTopology (&logfile, &eventlist, ff);
#endif
#ifdef BCUBE
        BCubeTopology *top = new BCubeTopology (&logfile, &eventlist, ff);
        cout << "BCUBE " << K << endl;
#endif
#ifdef VL2
        VL2Topology *top = new VL2Topology (&logfile, &eventlist, ff);
#endif
        vector < route_t * >***net_paths;
        net_paths = new vector < route_t * >**[N];
        int *is_dest = new int[N];

        for (int i = 0; i < N; i++) {
                is_dest[i] = 0;
                net_paths[i] = new vector < route_t * >*[N];

                for (int j = 0; j < N; j++) {
                        net_paths[i][j] = NULL;
                }
        }

        if (ff) {
                ff->net_paths = net_paths;
        }

        vector < int >*destinations;
        // Permutation connections
        ConnectionMatrix *conns = new ConnectionMatrix (N);
        //conns->setLocalTraffic(top);
        //cout << "Running perm with " << param << " connections" << endl;
        //conns->setPermutation(param);
        //conns->setStaggeredPermutation(top,(double)param/100.0);
        //conns->setStaggeredRandom(top,512,1);
//    conns->setHotspot(param,512/param);
        conns->setStride (3,0);
        //conns->setManytoMany(128);
        //conns->setVL2();
        //conns->setRandom(param);
        map < int, vector < int >*>::iterator it;
        int connID = 0;

        for (it = conns->connections.begin (); it != conns->connections.end ();
             it++) {
                int src = (*it).first;
                destinations = (vector < int >*) (*it).second;
                vector < int >subflows_chosen;

                for (unsigned int dst_id = 0; dst_id < destinations->size (); dst_id++) {
                        connID++;
                        dest = destinations->at (dst_id);

                        if (!net_paths[src][dest]) {
                                net_paths[src][dest] = top->get_paths (src, dest);
                        }

                        /*bool cbr = 1;
                           if (cbr){
                           cbrSrc = new CbrSrc(eventlist,speedFromPktps(7999),timeFromMs(0),timeFromMs(0));
                           cbrSnk = new CbrSink();

                           cbrSrc->setName("cbr_" + ntoa(src) + "_" + ntoa(dest)+"_"+ntoa(dst_id));
                           logfile.writeName(*cbrSrc);

                           cbrSnk->setName("cbr_sink_" + ntoa(src) + "_" + ntoa(dest)+"_"+ntoa(dst_id));
                           logfile.writeName(*cbrSnk);

                           // tell it the route
                           if (net_paths[src][dest]->size()==1){
                           choice = 0;
                           }
                           else {
                           choice = rand()%net_paths[src][dest]->size();
                           }

                           routeout = new route_t(*(net_paths[src][dest]->at(choice)));
                           routeout->push_back(cbrSnk);

                           cbrSrc->connect(*routeout, *cbrSnk, timeFromMs(0));
                           } */
                        {
                                //we should create multiple connections. How many?
                                //if (connID%3!=0)
                                //continue;
                                for (int connection = 0; connection < 1; connection++) {
                                        if (algo == COUPLED_EPSILON) {
                                                mtcp = new MultipathTcpSrc (algo, eventlist, NULL, epsilon);
                                        } else {
                                                mtcp = new MultipathTcpSrc (algo, eventlist, NULL);
                                        }

                                        mptcpVector.push_back(mtcp);
                                        //uint64_t bb = generateFlowSize();
                                        //      if (subflow_control)
                                        //subflow_control->add_flow(src,dest,mtcp);
                                        subflows_chosen.clear ();
                                        int it_sub;
                                        int crt_subflow_count = subflow_count;
                                        tot_subs += crt_subflow_count;
                                        cnt_con++;
                                        it_sub =
                                                crt_subflow_count >
                                                net_paths[src][dest]->
                                                size ()? net_paths[src][dest]->size () : crt_subflow_count;
                                        int use_all = it_sub == net_paths[src][dest]->size ();

                                        //if (connID%10!=0)
                                        //it_sub = 1;
                                        uint64_t pktpersubflow = pktperflow / it_sub;

                                        for (int inter = 0; inter < it_sub; inter++) {
                                                //              if (connID%10==0){
                                                tcpSrc = new TcpSrc (NULL, NULL, eventlist);
                                                tcpSrc->set_max_packets(pktpersubflow);
                                                tcpSnk = new TcpSink ();
                                                /*}
                                                   else {
                                                   tcpSrc = new TcpSrcTransfer(NULL,NULL,eventlist,bb,net_paths[src][dest]);
                                                   tcpSnk = new TcpSinkTransfer();
                                                   } */
                                                //if (connection==1)
                                                //tcpSrc->set_app_limit(9000);
                                                tcpSrc->setName ("mtcp_" + ntoa (src) + "_" +
                                                                 ntoa (inter) + "_" + ntoa (dest) + "(" +
                                                                 ntoa (connection) + ")");
                                                logfile.writeName (*tcpSrc);
                                                tcpSnk->setName ("mtcp_sink_" + ntoa (src) + "_" +
                                                                 ntoa (inter) + "_" + ntoa (dest) + "(" +
                                                                 ntoa (connection) + ")");
                                                logfile.writeName (*tcpSnk);
                                                tcpRtxScanner.registerTcp (*tcpSrc);
                                                /*int found;
                                                   do {
                                                   found = 0;

                                                   //if (net_paths[src][dest]->size()==K*K/4 && it_sub <= K/2)
                                                   //choice = rand()%(K/2);
                                                   //else
                                                   choice = rand()%net_paths[src][dest]->size();

                                                   for (unsigned int cnt = 0;cnt<subflows_chosen.size();cnt++){
                                                   if (subflows_chosen.at(cnt)==choice){
                                                   found = 1;
                                                   break;
                                                   }
                                                   }
                                                   }while(found);
                                                   // */
                                                int choice = 0;
#ifdef FAT_TREE
                                                choice = rand () % net_paths[src][dest]->size ();
#endif
#ifdef OV_FAT_TREE
                                                choice = rand () % net_paths[src][dest]->size ();
#endif
#ifdef MH_FAT_TREE

                                                if (use_all) {
                                                        choice = inter;
                                                } else {
                                                        choice = rand () % net_paths[src][dest]->size ();
                                                }

#endif
#ifdef VL2
                                                choice = rand () % net_paths[src][dest]->size ();
#endif
#ifdef STAR
                                                choice = 0;
#endif
#ifdef BCUBE
                                                //choice = inter;
                                                int min = -1, max = -1, minDist = 1000, maxDist = 0;

                                                if (subflow_count == 1) {
                                                        //find shortest and longest path
                                                        for (int dd = 0; dd < net_paths[src][dest]->size ();
                                                             dd++) {
                                                                if (net_paths[src][dest]->at (dd)->size () <
                                                                    minDist) {
                                                                        minDist =
                                                                                net_paths[src][dest]->at (dd)->size ();
                                                                        min = dd;
                                                                }

                                                                if (net_paths[src][dest]->at (dd)->size () >
                                                                    maxDist) {
                                                                        maxDist =
                                                                                net_paths[src][dest]->at (dd)->size ();
                                                                        max = dd;
                                                                }
                                                        }

                                                        choice = min;
                                                } else {
                                                        choice = rand () % net_paths[src][dest]->size ();
                                                }

#endif
                                                //cout << "Choice "<<choice<<" out of "<<net_paths[src][dest]->size();
                                                subflows_chosen.push_back (choice);

                                                /*if (net_paths[src][dest]->size()==K*K/4 && it_sub<=K/2){
                                                   int choice2 = rand()%(K/2); */
                                                if (choice >= net_paths[src][dest]->size ()) {
                                                        printf ("Weird path choice %d out of %u\n", choice,
                                                                net_paths[src][dest]->size ());
                                                        exit (1);
                                                }

#if PRINT_PATHS
                                                paths << "Route from " << ntoa (src) << " to " <<
                                                      ntoa (dest) << "  (" << choice << ") -> ";
                                                print_path (paths, net_paths[src][dest]->at (choice));
#endif
                                                routeout =
                                                        new route_t (*(net_paths[src][dest]->at (choice)));
                                                routeout->push_back (tcpSnk);
                                                routein = new route_t ();
                                                routein->push_back (tcpSrc);
                                                extrastarttime = 50 * drand ();
                                                //join multipath connection
                                                mtcp->addSubflow (tcpSrc);

                                                if (inter == 0) {
                                                        mtcp->setName ("multipath" + ntoa (src) + "_" +
                                                                       ntoa (dest) + "(" + ntoa (connection) +
                                                                       ")");
                                                        logfile.writeName (*mtcp);
                                                }

                                                tcpSrc->connect (*routeout, *routein, *tcpSnk,
                                                                 timeFromMs (extrastarttime));
#ifdef PACKET_SCATTER
                                                tcpSrc->set_paths (net_paths[src][dest]);
                                                cout << "Using PACKET SCATTER!!!!" << endl << end;
#endif

                                                if (ff && !inter) {
                                                        ff->add_flow (src, dest, tcpSrc);
                                                }

                                                sinkLogger.monitorSink (tcpSnk);
                                        }
                                }
                        }
                }
        }

        //ShortFlows* sf = new ShortFlows(2560, eventlist, net_paths,conns,lg, &tcpRtxScanner);
        cout << "Mean number of subflows " << ntoa ((double) tot_subs /
                        cnt_con) << endl;
        // Record the setup
        int pktsize = TcpPacket::DEFAULTDATASIZE;
        logfile.write ("# pktsize=" + ntoa (pktsize) + " bytes");
        logfile.write ("# subflows=" + ntoa (subflow_count));
        logfile.write ("# hostnicrate = " + ntoa (HOST_NIC) + " pkt/sec");
        logfile.write ("# corelinkrate = " + ntoa (HOST_NIC * CORE_TO_HOST) +
                       " pkt/sec");
        //logfile.write("# buffer = " + ntoa((double) (queues_na_ni[0][1]->_maxsize) / ((double) pktsize)) + " pkt");
        double rtt = timeAsSec (timeFromUs (RTT));
        logfile.write ("# rtt =" + ntoa (rtt));
        // GO!
        double last = 0.0;

        while (eventlist.doNextEvent ()) {
                if (timeAsMs(eventlist.now())>last+10.0) {
                        cout << (last =  timeAsMs(eventlist.now()))   << endl;

                        for (vector<MultipathTcpSrc*>::iterator iA = mptcpVector.begin(); iA!=mptcpVector.end(); iA++) {
                                cout << (*iA)->compute_total_bytes()*0.001*0.001 <<" ";
                        }

                        cout << endl;
                }
        }
}