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

📄 packet_history.c

📁 linux 内核源代码
💻 C
字号:
/* *  net/dccp/packet_history.c * *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. * *  An implementation of the DCCP protocol * *  This code has been developed by the University of Waikato WAND *  research group. For further information please see http://www.wand.net.nz/ *  or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz * *  This code also uses code from Lulea University, rereleased as GPL by its *  authors: *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon * *  Changes to meet Linux coding standards, to make it meet latest ccid3 draft *  and to make it work as a loadable module in the DCCP stack written by *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>. * *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> * *  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., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/module.h>#include <linux/string.h>#include "packet_history.h"/* * 	Transmitter History Routines */struct dccp_tx_hist *dccp_tx_hist_new(const char *name){	struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);	static const char dccp_tx_hist_mask[] = "tx_hist_%s";	char *slab_name;	if (hist == NULL)		goto out;	slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,			    GFP_ATOMIC);	if (slab_name == NULL)		goto out_free_hist;	sprintf(slab_name, dccp_tx_hist_mask, name);	hist->dccptxh_slab = kmem_cache_create(slab_name,					     sizeof(struct dccp_tx_hist_entry),					       0, SLAB_HWCACHE_ALIGN,					       NULL);	if (hist->dccptxh_slab == NULL)		goto out_free_slab_name;out:	return hist;out_free_slab_name:	kfree(slab_name);out_free_hist:	kfree(hist);	hist = NULL;	goto out;}EXPORT_SYMBOL_GPL(dccp_tx_hist_new);void dccp_tx_hist_delete(struct dccp_tx_hist *hist){	const char* name = kmem_cache_name(hist->dccptxh_slab);	kmem_cache_destroy(hist->dccptxh_slab);	kfree(name);	kfree(hist);}EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);struct dccp_tx_hist_entry *	dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq){	struct dccp_tx_hist_entry *packet = NULL, *entry;	list_for_each_entry(entry, list, dccphtx_node)		if (entry->dccphtx_seqno == seq) {			packet = entry;			break;		}	return packet;}EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list){	struct dccp_tx_hist_entry *entry, *next;	list_for_each_entry_safe(entry, next, list, dccphtx_node) {		list_del_init(&entry->dccphtx_node);		dccp_tx_hist_entry_delete(hist, entry);	}}EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,			      struct list_head *list,			      struct dccp_tx_hist_entry *packet){	struct dccp_tx_hist_entry *next;	list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) {		list_del_init(&packet->dccphtx_node);		dccp_tx_hist_entry_delete(hist, packet);	}}EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older);/* * 	Receiver History Routines */struct dccp_rx_hist *dccp_rx_hist_new(const char *name){	struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);	static const char dccp_rx_hist_mask[] = "rx_hist_%s";	char *slab_name;	if (hist == NULL)		goto out;	slab_name = kmalloc(strlen(name) + sizeof(dccp_rx_hist_mask) - 1,			    GFP_ATOMIC);	if (slab_name == NULL)		goto out_free_hist;	sprintf(slab_name, dccp_rx_hist_mask, name);	hist->dccprxh_slab = kmem_cache_create(slab_name,					     sizeof(struct dccp_rx_hist_entry),					       0, SLAB_HWCACHE_ALIGN,					       NULL);	if (hist->dccprxh_slab == NULL)		goto out_free_slab_name;out:	return hist;out_free_slab_name:	kfree(slab_name);out_free_hist:	kfree(hist);	hist = NULL;	goto out;}EXPORT_SYMBOL_GPL(dccp_rx_hist_new);void dccp_rx_hist_delete(struct dccp_rx_hist *hist){	const char* name = kmem_cache_name(hist->dccprxh_slab);	kmem_cache_destroy(hist->dccprxh_slab);	kfree(name);	kfree(hist);}EXPORT_SYMBOL_GPL(dccp_rx_hist_delete);int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,			    u8 *ccval){	struct dccp_rx_hist_entry *packet = NULL, *entry;	list_for_each_entry(entry, list, dccphrx_node)		if (entry->dccphrx_seqno == seq) {			packet = entry;			break;		}	if (packet)		*ccval = packet->dccphrx_ccval;	return packet != NULL;}EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry);struct dccp_rx_hist_entry *		dccp_rx_hist_find_data_packet(const struct list_head *list){	struct dccp_rx_hist_entry *entry, *packet = NULL;	list_for_each_entry(entry, list, dccphrx_node)		if (entry->dccphrx_type == DCCP_PKT_DATA ||		    entry->dccphrx_type == DCCP_PKT_DATAACK) {			packet = entry;			break;		}	return packet;}EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet);void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,			    struct list_head *rx_list,			    struct list_head *li_list,			    struct dccp_rx_hist_entry *packet,			    u64 nonloss_seqno){	struct dccp_rx_hist_entry *entry, *next;	u8 num_later = 0;	list_add(&packet->dccphrx_node, rx_list);	num_later = TFRC_RECV_NUM_LATE_LOSS + 1;	if (!list_empty(li_list)) {		list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {			if (num_later == 0) {				if (after48(nonloss_seqno,				   entry->dccphrx_seqno)) {					list_del_init(&entry->dccphrx_node);					dccp_rx_hist_entry_delete(hist, entry);				}			} else if (dccp_rx_hist_entry_data_packet(entry))				--num_later;		}	} else {		int step = 0;		u8 win_count = 0; /* Not needed, but lets shut up gcc */		int tmp;		/*		 * We have no loss interval history so we need at least one		 * rtt:s of data packets to approximate rtt.		 */		list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {			if (num_later == 0) {				switch (step) {				case 0:					step = 1;					/* OK, find next data packet */					num_later = 1;					break;				case 1:					step = 2;					/* OK, find next data packet */					num_later = 1;					win_count = entry->dccphrx_ccval;					break;				case 2:					tmp = win_count - entry->dccphrx_ccval;					if (tmp < 0)						tmp += TFRC_WIN_COUNT_LIMIT;					if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {						/*						 * We have found a packet older						 * than one rtt remove the rest						 */						step = 3;					} else /* OK, find next data packet */						num_later = 1;					break;				case 3:					list_del_init(&entry->dccphrx_node);					dccp_rx_hist_entry_delete(hist, entry);					break;				}			} else if (dccp_rx_hist_entry_data_packet(entry))				--num_later;		}	}}EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list){	struct dccp_rx_hist_entry *entry, *next;	list_for_each_entry_safe(entry, next, list, dccphrx_node) {		list_del_init(&entry->dccphrx_node);		kmem_cache_free(hist->dccprxh_slab, entry);	}}EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");MODULE_DESCRIPTION("DCCP TFRC library");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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