/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* * Copyright (c) 2001 University of Mannheim, Praktische Informatik IV * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Praktische Informatik IV, * University of Mannheim. * 4. Neither the name of Praktische Informatik IV nor of University of * Mannheim may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY U. MANNHEIM AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL U. MANNHEIM OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "agent.h" #include "packet.h" #include "ip.h" #include "timer-handler.h" #include "random.h" #define SMALLFLOAT 0.0000001 #define DEC_NO_REPORT 24 struct hdr_pcc { int seqno; //data sequence number double timestamp; // time this message was sent double timestamp_echo; // echo timestamp from last receiver report double timestamp_offset; // offset since sender received report int psize; //packet size int round_id ; //round id. double sendrate; //current send rate static int offset_; // offset for this header inline static int& offset() { return offset_; } inline static hdr_pcc* access(const Packet* p) { return (hdr_pcc*) p->access(offset_); } }; struct hdr_pcc_ack { double timestamp; //time this nack was sent double rate; //expected sending rate (eqn) double rtt; //smoothed RTT estimate of receiver int discard_after_seqno; //if >= 0, packets after this seqno are discarded by the receiver static int offset_; // offset for this header inline static int& offset() { return offset_; } inline static hdr_pcc_ack* access(const Packet* p) { return (hdr_pcc_ack*) p->access(offset_); } }; class PccAgent; class PccSendTimer : public TimerHandler { public: PccSendTimer(PccAgent *a) : TimerHandler() { a_ = a; } virtual void expire(Event *e); protected: PccAgent *a_; }; class PccNoFeedbackTimer : public TimerHandler { public: PccNoFeedbackTimer(PccAgent *a) : TimerHandler() { a_ = a; } virtual void expire(Event *e); protected: PccAgent *a_; }; class PccAgent : public Agent { friend PccSendTimer; friend PccNoFeedbackTimer; public: PccAgent(); void recv(Packet*, Handler*); void sendpkt(); void nextpkt(); int command(int argc, const char*const* argv); void start(); void stop(); void reduce_rate_on_no_feedback(); protected: PccSendTimer send_timer_; PccNoFeedbackTimer NoFeedbacktimer_; int seqno_; int psize_; double rate_; // send rate double rcvrate ; // TCP friendly rate from receiver int printStatus_; // to print status reports double inter_packet; // inter packet gap /* "accurate" estimates for formula */ double rtt_; /*EWMA version*/ double last_timestamp_, last_arrival_; int AppRate_; // constant send rate of the Application double overhead_; // if > 0, dither outgoing packets int ndatapack_; // number of packets sent int active_; // have we shut down? int round_id ; // round id int flowID; };