Ejemplo n.º 1
0
void NS_CLASS aodv_socket_send(AODV_msg * aodv_msg, struct in_addr dst,
			       int len, u_int8_t ttl, struct dev_info *dev)
{
    int retval = 0;
    struct timeval now;
    /* Rate limit stuff: */

#ifndef NS_PORT

    struct sockaddr_in dst_addr;

    if (wait_on_reboot && aodv_msg->type == AODV_RREP)
	return;

    memset(&dst_addr, 0, sizeof(dst_addr));
    dst_addr.sin_family = AF_INET;
    dst_addr.sin_addr = dst;
    dst_addr.sin_port = htons(AODV_PORT);

    /* Set ttl */
    if (setsockopt(dev->sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {
	alog(LOG_WARNING, 0, __FUNCTION__, "ERROR setting ttl!");
	return;
    }
#else

    /*
       NS_PORT: Sending of AODV_msg messages to other AODV-UU routing agents
       by encapsulating them in a Packet.

       Note: This method is _only_ for sending AODV packets to other routing
       agents, _not_ for forwarding "regular" IP packets!
     */

    /* If we are in waiting phase after reboot, don't send any RREPs */
    if (wait_on_reboot && aodv_msg->type == AODV_RREP)
	return;

    /*
       NS_PORT: Don't allocate packet until now. Otherwise packet uid
       (unique ID) space is unnecessarily exhausted at the beginning of
       the simulation, resulting in uid:s starting at values greater than 0.
     */
    Packet *p = allocpkt();
    struct hdr_cmn *ch = HDR_CMN(p);
    struct hdr_ip *ih = HDR_IP(p);
    hdr_aodvuu *ah = HDR_AODVUU(p);

    // Clear AODVUU part of packet
    memset(ah, '\0', ah->size());

    // Copy message contents into packet
    memcpy(ah, aodv_msg, len);

    // Set common header fields
    ch->ptype() = PT_AODVUU;
    ch->direction() = hdr_cmn::DOWN;
    ch->size() = IP_HDR_LEN + len;
    ch->iface() = -2;
    ch->error() = 0;
    ch->prev_hop_ = (nsaddr_t) dev->ipaddr.s_addr;

    // Set IP header fields
    ih->saddr() = (nsaddr_t) dev->ipaddr.s_addr;
    ih->daddr() = (nsaddr_t) dst.s_addr;
    ih->ttl() = ttl;

    // Note: Port number for routing agents, not AODV port number!
    ih->sport() = RT_PORT;
    ih->dport() = RT_PORT;

    // Fake success
    retval = len;
#endif				/* NS_PORT */

    /* If rate limiting is enabled, check if we are sending either a
       RREQ or a RERR. In that case, drop the outgoing control packet
       if the time since last transmit of that type of packet is less
       than the allowed RATE LIMIT time... */

    if (ratelimit) {

	gettimeofday(&now, NULL);

	switch (aodv_msg->type) {
	case AODV_RREQ:
	    if (num_rreq == (RREQ_RATELIMIT - 1)) {
		if (timeval_diff(&now, &rreq_ratel[0]) < 1000) {
		    DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RREQ %ld ms",
			  timeval_diff(&now, &rreq_ratel[0]));
		    return;
		} else {
		    memmove(rreq_ratel, &rreq_ratel[1],
			    sizeof(struct timeval) * (num_rreq - 1));
		    memcpy(&rreq_ratel[num_rreq - 1], &now,
			   sizeof(struct timeval));
		}
	    } else {
		memcpy(&rreq_ratel[num_rreq], &now, sizeof(struct timeval));
		num_rreq++;
	    }
	    break;
	case AODV_RERR:
	    if (num_rerr == (RERR_RATELIMIT - 1)) {
		if (timeval_diff(&now, &rerr_ratel[0]) < 1000) {
		    DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RERR %ld ms",
			  timeval_diff(&now, &rerr_ratel[0]));
		    return;
		} else {
		    memmove(rerr_ratel, &rerr_ratel[1],
			    sizeof(struct timeval) * (num_rerr - 1));
		    memcpy(&rerr_ratel[num_rerr - 1], &now,
			   sizeof(struct timeval));
		}
	    } else {
		memcpy(&rerr_ratel[num_rerr], &now, sizeof(struct timeval));
		num_rerr++;
	    }
	    break;
	}
    }

    /* If we broadcast this message we update the time of last broadcast
       to prevent unnecessary broadcasts of HELLO msg's */
    if (dst.s_addr == AODV_BROADCAST) {

	gettimeofday(&this_host.bcast_time, NULL);

#ifdef NS_PORT
	ch->addr_type() = NS_AF_NONE;

	sendPacket(p, dst, 0.0);
#else

	retval = sendto(dev->sock, send_buf, len, 0,
			(struct sockaddr *) &dst_addr, sizeof(dst_addr));

	if (retval < 0) {

	    alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to bc %s",
		 ip_to_str(dst));
	    return;
	}
#endif

    } else {

#ifdef NS_PORT
	ch->addr_type() = NS_AF_INET;
	/* We trust the decision of next hop for all AODV messages... */

	if (dst.s_addr == AODV_BROADCAST)
	    sendPacket(p, dst, 0.001 * Random::uniform());
	else
	    sendPacket(p, dst, 0.0);
#else
	retval = sendto(dev->sock, send_buf, len, 0,
			(struct sockaddr *) &dst_addr, sizeof(dst_addr));

	if (retval < 0) {
	    alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s",
		 ip_to_str(dst));
	    return;
	}
#endif
    }

    /* Do not print hello msgs... */
    if (!(aodv_msg->type == AODV_RREP && (dst.s_addr == AODV_BROADCAST)))
	DEBUG(LOG_INFO, 0, "AODV msg to %s ttl=%d size=%u",
	      ip_to_str(dst), ttl, retval, len);

    return;
}
Ejemplo n.º 2
0
void NS_CLASS aodv_socket_send(AODV_msg * aodv_msg, u_int32_t dst, int len,
			       u_int8_t ttl, struct dev_info *dev)
{
    int retval = 0;
    struct timeval now;
    /* Rate limit stuff: */
  
#ifndef NS_PORT
    struct sockaddr_in dst_addr;

#ifdef RAW_SOCKET
    struct iphdr *iph;
    struct udphdr *udph;

    if (wait_on_reboot && aodv_msg->type == AODV_RREP)
	return;

    /* Create a IP header around the packet... The AODV msg is already
       located in the send buffer and referenced by the in parameter
       "aodv_msg". */
    iph = (struct iphdr *) send_buf;
    iph->tot_len = htons(IPHDR_SIZE + sizeof(struct udphdr) + len);
    iph->saddr = htonl(dev->ipaddr);
    iph->daddr = htonl(dst);
    iph->ttl = ttl;

    udph = (struct udphdr *) (send_buf + IPHDR_SIZE);

    udph->len = htons(len + sizeof(struct udphdr));

#else

    /* If we are in waiting phase after reboot, don't send any control
       messages */
    if (wait_on_reboot)
	return;

    /* Set the ttl we want to send with */
    if (setsockopt(dev->sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {
	log(LOG_WARNING, 0, __FUNCTION__, "Failed to set TTL!!!");
	return;
    }
#endif				/* RAW_SOCKET */

    memset(&dst_addr, 0, sizeof(dst_addr));
    dst_addr.sin_family = AF_INET;
    dst_addr.sin_addr.s_addr = htonl(dst);
    dst_addr.sin_port = htons(AODV_PORT);

#else

    /*
       NS_PORT: Sending of AODV_msg messages to other AODV-UU routing agents
       by encapsulating them in a Packet.

       Note: This method is _only_ for sending AODV packets to other routing
       agents, _not_ for forwarding "regular" IP packets!
     */

    /* If we are in waiting phase after reboot, don't send any RREPs */
    if (wait_on_reboot && aodv_msg->type == AODV_RREP)
	return;

    /*
       NS_PORT: Don't allocate packet until now. Otherwise packet uid
       (unique ID) space is unnecessarily exhausted at the beginning of
       the simulation, resulting in uid:s starting at values greater than 0.
     */
    Packet *p = allocpkt();
    struct hdr_cmn *ch = HDR_CMN(p);
    struct hdr_ip *ih = HDR_IP(p);
    hdr_aodvuu *ah = HDR_AODVUU(p);

    // Clear AODVUU part of packet
    memset(ah, '\0', ah->size());

    // Copy message contents into packet
    memcpy(ah, aodv_msg, len);

    // Set common header fields
    ch->ptype() = PT_AODVUU;
    ch->direction() = hdr_cmn::DOWN;
    ch->size() = IP_HDR_LEN + len;
    ch->iface() = -2;
    ch->error() = 0;
    ch->prev_hop_ = (nsaddr_t) dev->ipaddr;

    // Set IP header fields
    ih->saddr() = (nsaddr_t) dev->ipaddr;
    ih->daddr() = (nsaddr_t) dst;
    ih->ttl() = ttl;

    // Note: Port number for routing agents, not AODV port number!
    ih->sport() = RT_PORT;
    ih->dport() = RT_PORT;

    // Fake success
    retval = len;
#endif				/* NS_PORT */

    /* If rate limiting is enabled, check if we are sending either a
       RREQ or a RERR. In that case, drop the outgoing control packet
       if the time since last transmit of that type of packet is less
       than the allowed RATE LIMIT time... */

    if (ratelimit) {
    
	gettimeofday(&now, NULL);
    
	switch (aodv_msg->type) {
	case AODV_RREQ:
	    if (timeval_diff(&now, &time_last_rreq) < 1000 / RREQ_RATELIMIT) {
		DEBUG(LOG_DEBUG, 0, "Dropping RREQ due to RATELIMIT %ld ms",
		      timeval_diff(&now, &time_last_rreq));
		return;
	    }
	    memcpy(&time_last_rreq, &now, sizeof(struct timeval));
	    break;
	case AODV_RERR:
	    if (timeval_diff(&now, &time_last_rerr) < 1000 / RERR_RATELIMIT) {

		DEBUG(LOG_DEBUG, 0, "Dropping RERR due to RATELIMIT %ld ms",
		      timeval_diff(&now, &time_last_rerr));
		return;
	    }
	    memcpy(&time_last_rerr, &now, sizeof(struct timeval));
	    break;
	}
    }
    

/* Alternative RATE LIMIT ALGORITHM: This algorithm will start to
 * count time (forward 1 second) from the first packet sent. If more
 * than RATELIMIT allowed packets are sent during that period, the
 * last packet is dropped and the packet counter and time are
 * reset. The time and packet count are also reset if 1 second lasts
 * without the limit being reached... The problem is that if there are
 * many packets at the end of an "interval" and at the start of the
 * next, although the limit is not reached in either interval, there
 * can be more than RATELIMIT packets sent if the second half of the
 * first interval is joined with the first of the following
 * interval... */
    
   /*  if (ratelimit) { */

/* 	gettimeofday(&now, NULL); */

/* 	switch (aodv_msg->type) { */
/* 	case AODV_RREQ: */
/* 	    if (timeval_diff(&now, &time_last_rreq) > 1000) { */
/* 		num_rreq = 1; */
/* 		memcpy(&time_last_rreq, &now, sizeof(struct timeval)); */
/* 	    } else { */
/* 		num_rreq++; */
/* 		DEBUG(LOG_DEBUG, 0, "RATELIMIT RREQ: time=%ld ms num=%d", */
/* 		      timeval_diff(&now, &time_last_rreq), num_rreq); */
/* 		if (num_rreq > RREQ_RATELIMIT) { */
/* 		    num_rreq = 0; */
/* 		    DEBUG(LOG_DEBUG, 0, "Dropping RREQ due to RATELIMIT"); */
/* 		    return; */
/* 		} */
/* 	    } */
/* 	    break; */
/* 	case AODV_RERR: */
/* 	    if (timeval_diff(&now, &time_last_rerr) > 1000) { */
/* 		num_rerr = 1; */
/* 		memcpy(&time_last_rerr, &now, sizeof(struct timeval)); */
/* 	    } else { */
/* 		num_rerr++; */
/* 		DEBUG(LOG_DEBUG, 0, "RATELIMIT RERR: time=%ld ms num=%d", */
/* 		      timeval_diff(&now, &time_last_rerr), num_rerr); */
/* 		if (num_rerr > RERR_RATELIMIT) { */
/* 		    num_rerr = 0; */
/* 		    DEBUG(LOG_DEBUG, 0, "Dropping RERR due to RATELIMIT"); */
/* 		    return; */
/* 		} */
/* 	    } */
/* 	    break; */
/* 	} */
/*      } */

    /* If we broadcast this message we update the time of last broadcast
       to prevent unnecessary broadcasts of HELLO msg's */
    if (dst == AODV_BROADCAST) {

	gettimeofday(&this_host.bcast_time, NULL);

#ifdef NS_PORT
	ch->addr_type() = NS_AF_NONE;

	sendPacket(p, 0, 0.0);
#else
	retval = sendto(dev->sock, send_buf, len, 0,
			(struct sockaddr *) &dst_addr, sizeof(dst_addr));

	if (retval < 0) {
	    log(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s",
		ip_to_str(dst));
	    return;
	}
#endif

    } else {

#ifdef NS_PORT
	ch->addr_type() = NS_AF_INET;
	/* We trust the decision of next hop for all AODV messages... */
	/* Add jitter, even for unicast control messages. */
	sendPacket(p, dst, 0.03 * Random::uniform());
#else
	retval = sendto(dev->sock, send_buf, len, 0,
			(struct sockaddr *) &dst_addr, sizeof(dst_addr));

	if (retval < 0) {
	    log(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s",
		ip_to_str(dst));
	    return;
	}
#endif
    }

    /* Do not print hello msgs... */
    if (!(aodv_msg->type == AODV_RREP && (dst == AODV_BROADCAST)))
	DEBUG(LOG_INFO, 0, "AODV msg to %s ttl=%d (%d bytes)",
	      ip_to_str(dst), ttl, retval);

    return;
}
Ejemplo n.º 3
0
void
	FastTcpAgent::output(int seqno, int reason)
{
	Packet* p = allocpkt();
	hdr_tcp *tcph = hdr_tcp::access(p);
	double now = Scheduler::instance().clock();
	hdr_flags* hf = hdr_flags::access(p);
	hdr_ip *iph = hdr_ip::access(p);
	int databytes = hdr_cmn::access(p)->size();
	tcph->seqno() = seqno;
	tcph->ts() = now;
	tcph->reason() = reason;
	/* if this is the 1st pkt, setup senttime[] and transmits[]
	* I alloc mem here, instrad of in the constructor, to cover
	* cases which windows get set by each different tcp flows */
	if (seqno==0) {
		maxwnd_ = int(wnd_);
		if (sendtime_)
			delete []sendtime_;
		if (transmits_)
			delete []transmits_;
		if (cwnd_array_)
			delete []cwnd_array_;
		sendtime_ = new double[maxwnd_];
		transmits_ = new int[maxwnd_];
		cwnd_array_= new double[maxwnd_];
		for(int i=0;i<maxwnd_;i++) {
			sendtime_[i] = -1.;
			transmits_[i] = 0;
			cwnd_array_[i]=-1;
		}
	}

	if (ecn_) {
		hf->ect() = 1; // ECN capable transport.
	}

	/* Check if this is the initial SYN packet. */
	if (seqno == 0) {
		if (syn_) {
			databytes= 0;
			curseq_ += 1;
			hdr_cmn::access(p)->size() = tcpip_base_hdr_size_;
		}
		if (ecn_) {
			hf->ecnecho() = 1;
			//			hf->cong_action() = 1;
			hf->ect() = 0;
		}
	}
	else if (useHeaders_ == true) {
		hdr_cmn::access(p)->size() += headersize();
	}

	// record a find grained send time and # of transmits 
	int index = seqno % maxwnd_;
	sendtime_[index] = fasttime(); 
	cwnd_array_[index]=avg_cwnd_last_RTT_; 
	++transmits_[index];
	/* support ndatabytes_ in output - Lloyd Wood 14 March 2000 */
	int bytes = hdr_cmn::access(p)->size(); 
	ndatabytes_ += bytes; 
	ndatapack_++; // Added this - Debojyoti 12th Oct 2000
	send(p, 0);

	if (seqno == curseq_ && seqno > maxseq_)
		idle();  // Tell application I have sent everything so far

	if (seqno > maxseq_) {
		maxseq_ = seqno;
		if (!rtt_active_) {
			rtt_active_ = 1;
			if (seqno > rtt_seq_) {
				rtt_seq_ = seqno;
				rtt_ts_ = now;
			}
		}
	} else {
		++nrexmitpack_;
		nrexmitbytes_ += bytes;
	}

	if (!(rtx_timer_.status() == TIMER_PENDING))
		/* No timer pending.  Schedule one. */
			set_rtx_timer();
}