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; }
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; }
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(); }