⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet_queue.cc

📁 在ns2.28中实现的AODV的升级版本AODV-
💻 CC
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University & Ericsson AB. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Authors: Erik Nordstr鰉, <erik.nordstrom@it.uu.se> * *****************************************************************************/#include "aodv-uu.h"#define GARBAGE_COLLECTvoid NS_CLASS packet_queue_init(void){    INIT_LIST_HEAD(&PQ.head);    PQ.len = 0;#ifdef GARBAGE_COLLECT    /* Set up garbage collector */    timer_init(&PQ.garbage_collect_timer, &NS_CLASS packet_queue_timeout, &PQ);    timer_set_timeout(&PQ.garbage_collect_timer, GARBAGE_COLLECT_TIME);#endif}void NS_CLASS packet_queue_destroy(void){    int count = 0;    list_t *pos, *tmp;        list_foreach_safe(pos, tmp, &PQ.head) {	struct q_pkt *qp = (struct q_pkt *)pos;	list_detach(pos);	drop(qp->p, DROP_END_OF_SIMULATION);	free(qp);	count++;	PQ.len--;    }    DEBUG(LOG_INFO, 0, "Destroyed %d buffered packets!", count);}/* Garbage collect packets which have been queued for too long... */int NS_CLASS packet_queue_garbage_collect(void){    int count = 0;    list_t *pos, *tmp;    struct timeval now;        gettimeofday(&now, NULL);        list_foreach_safe(pos, tmp, &PQ.head) {	struct q_pkt *qp = (struct q_pkt *)pos;	if (timeval_diff(&now, &qp->q_time) > MAX_QUEUE_TIME) {	   	    list_detach(pos);	    drop(qp->p, DROP_RTR_QTIMEOUT); 	    	    free(qp);	    count++;	    PQ.len--;	}    }        if (count) {        DEBUG(LOG_DEBUG, 0, "Removed %d packet(s)!", count);    }        return count;}/* Buffer a packet in a FIFO queue. Implemented as a linked list,   where we add elements at the end and remove at the beginning.... */void NS_CLASS packet_queue_add(Packet * p, struct in_addr dest_addr){    struct q_pkt *qp;    struct hdr_ip *ih;    struct hdr_cmn *ch = HDR_CMN(p);        ih = HDR_IP(p);        assert(ih->daddr() == dest_addr.s_addr);    if (PQ.len >= MAX_QUEUE_LENGTH) {	DEBUG(LOG_DEBUG, 0, "MAX Queue length! Removing first packet.");	if (!list_empty(&PQ.head)) {	    qp = (struct q_pkt *)PQ.head.next;	    	    list_detach(PQ.head.next);	    drop(qp->p, DROP_RTR_QFULL);	    free(qp);	    PQ.len--;	}    }    qp = (struct q_pkt *) malloc(sizeof(struct q_pkt));        if (qp == NULL) {	fprintf(stderr, "Malloc failed!\n");	exit(-1);    }    qp->p = p;    qp->dest_addr = dest_addr;        gettimeofday(&qp->q_time, NULL);        list_add_tail(&PQ.head, &qp->l);    PQ.len++;    DEBUG(LOG_INFO, 0, "buffered pkt to %s uid=%d qlen=%u",	  ip_to_str(dest_addr), ch->uid(), PQ.len);}int NS_CLASS packet_queue_set_verdict(struct in_addr dest_addr, int verdict){    int count = 0;    rt_table_t *rt, *next_hop_rt, *inet_rt = NULL;    list_t *pos, *tmp;    double delay = 0;#define ARP_DELAY 0.005        if (verdict == PQ_ENC_SEND) {	inet_rt = rt_table_find(dest_addr);		if (!inet_rt)	    return -1;	rt = rt_table_find(inet_rt->next_hop);    } else {	rt = rt_table_find(dest_addr);    }        list_foreach_safe(pos, tmp, &PQ.head) {	 struct q_pkt *qp = (struct q_pkt *)pos;	if (qp->dest_addr.s_addr == dest_addr.s_addr) {	    	    list_detach(pos);	    	    switch (verdict) {	    case PQ_SEND:				if (!rt)		    return -1;		/* Apparently, the link layer implementation can't handle		 * a burst of packets. So to keep ARP happy, buffered		 * packets are sent with ARP_DELAY seconds between		 * sends. */		sendPacket(qp->p, rt->next_hop, delay);		delay += ARP_DELAY;		break;	    case PQ_DROP:		drop(qp->p, DROP_RTR_NO_ROUTE);		break;#ifdef CONFIG_GATEWAY	    case PQ_ENC_SEND:				if (!rt)		    return -1;		DEBUG(LOG_DEBUG, 0, "Encap. PQ_ENC_SEND");		qp->p = pkt_encapsulate(qp->p, inet_rt->next_hop);				if (!qp->p) {		    DEBUG(LOG_ERR, 0, "Encapsulation failed...");		}					sendPacket(qp->p, rt->next_hop, delay);		delay += ARP_DELAY;		break;#endif /* CONFIG_GATEWAY */	    }	    free(qp);	    count++;	    PQ.len--;	}    }    /* Update rt timeouts */    if (rt && rt->state == VALID && 	(verdict == PQ_SEND || verdict == PQ_ENC_SEND)) {	if (dest_addr.s_addr != DEV_IFINDEX(rt->ifindex).ipaddr.s_addr) {	    if (verdict == PQ_ENC_SEND && inet_rt)		rt_table_update_timeout(inet_rt, ACTIVE_ROUTE_TIMEOUT);	    	    rt_table_update_timeout(rt, ACTIVE_ROUTE_TIMEOUT);	    	    next_hop_rt = rt_table_find(rt->next_hop);	    	    if (next_hop_rt && next_hop_rt->state == VALID && 		next_hop_rt->dest_addr.s_addr != rt->dest_addr.s_addr)		rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);	}		DEBUG(LOG_INFO, 0, "SENT %d packets to %s qlen=%u",	      count, ip_to_str(dest_addr), PQ.len);    } else if (verdict == PQ_DROP) {	DEBUG(LOG_INFO, 0, "DROPPED %d packets for %s!",	      count, ip_to_str(dest_addr));    }    return count;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -