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

📄 transport.c

📁 在linux环境下的流控制传输协议(sctp)的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* SCTP kernel implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001-2003 International Business Machines Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 La Monte H.P. Yarroll * * This file is part of the SCTP kernel implementation * * This module provides the abstraction for an SCTP tranport representing * a remote transport address.  For local transport addresses, we just use * union sctp_addr. * * This SCTP implementation 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, or (at your option) * any later version. * * This SCTP implementation 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 GNU CC; see the file COPYING.  If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Please send any bug reports or fixes you make to the * email address(es): *    lksctp developers <lksctp-developers@lists.sourceforge.net> * * Or submit a bug report through the following website: *    http://www.sf.net/projects/lksctp * * Written or modified by: *    La Monte H.P. Yarroll <piggy@acm.org> *    Karl Knutson          <karl@athena.chicago.il.us> *    Jon Grimm             <jgrimm@us.ibm.com> *    Xingang Guo           <xingang.guo@intel.com> *    Hui Huang             <hui.huang@nokia.com> *    Sridhar Samudrala	    <sri@us.ibm.com> *    Ardelle Fan	    <ardelle.fan@intel.com> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. */#include <linux/types.h>#include <linux/random.h>#include <net/sctp/sctp.h>#include <net/sctp/sm.h>/* 1st Level Abstractions.  *//* Initialize a new transport from provided memory.  */static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,						  const union sctp_addr *addr,						  gfp_t gfp){	/* Copy in the address.  */	peer->ipaddr = *addr;	peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);	peer->asoc = NULL;	peer->dst = NULL;	memset(&peer->saddr, 0, sizeof(union sctp_addr));	/* From 6.3.1 RTO Calculation:	 *	 * C1) Until an RTT measurement has been made for a packet sent to the	 * given destination transport address, set RTO to the protocol	 * parameter 'RTO.Initial'.	 */	peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial);	peer->rtt = 0;	peer->rttvar = 0;	peer->srtt = 0;	peer->rto_pending = 0;	peer->last_time_heard = jiffies;	peer->last_time_used = jiffies;	peer->last_time_ecne_reduced = jiffies;	peer->init_sent_count = 0;	peer->param_flags = SPP_HB_DISABLE |			    SPP_PMTUD_ENABLE |			    SPP_SACKDELAY_ENABLE;	peer->hbinterval  = 0;	/* Initialize the default path max_retrans.  */	peer->pathmaxrxt  = sctp_max_retrans_path;	peer->error_count = 0;	INIT_LIST_HEAD(&peer->transmitted);	INIT_LIST_HEAD(&peer->send_ready);	INIT_LIST_HEAD(&peer->transports);	setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event,			(unsigned long)peer);	setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,			(unsigned long)peer);	/* Initialize the 64-bit random nonce sent with heartbeat. */	get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));	atomic_set(&peer->refcnt, 1);	peer->dead = 0;	peer->malloced = 0;	/* Initialize the state information for SFR-CACC */	peer->cacc.changeover_active = 0;	peer->cacc.cycling_changeover = 0;	peer->cacc.next_tsn_at_change = 0;	peer->cacc.cacc_saw_newack = 0;	return peer;}/* Allocate and initialize a new transport.  */struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,					  gfp_t gfp){	struct sctp_transport *transport;	transport = t_new(struct sctp_transport, gfp);	if (!transport)		goto fail;	if (!sctp_transport_init(transport, addr, gfp))		goto fail_init;	transport->malloced = 1;	SCTP_DBG_OBJCNT_INC(transport);	return transport;fail_init:	kfree(transport);fail:	return NULL;}/* This transport is no longer needed.  Free up if possible, or * delay until it last reference count. */void sctp_transport_free(struct sctp_transport *transport){	transport->dead = 1;	/* Try to delete the heartbeat timer.  */	if (del_timer(&transport->hb_timer))		sctp_transport_put(transport);	/* Delete the T3_rtx timer if it's active.	 * There is no point in not doing this now and letting	 * structure hang around in memory since we know	 * the tranport is going away.	 */	if (timer_pending(&transport->T3_rtx_timer) &&	    del_timer(&transport->T3_rtx_timer))		sctp_transport_put(transport);	sctp_transport_put(transport);}/* Destroy the transport data structure. * Assumes there are no more users of this structure. */static void sctp_transport_destroy(struct sctp_transport *transport){	SCTP_ASSERT(transport->dead, "Transport is not dead", return);	if (transport->asoc)		sctp_association_put(transport->asoc);	sctp_packet_free(&transport->packet);	dst_release(transport->dst);	kfree(transport);	SCTP_DBG_OBJCNT_DEC(transport);}/* Start T3_rtx timer if it is not already running and update the heartbeat * timer.  This routine is called every time a DATA chunk is sent. */void sctp_transport_reset_timers(struct sctp_transport *transport){	/* RFC 2960 6.3.2 Retransmission Timer Rules	 *	 * R1) Every time a DATA chunk is sent to any address(including a	 * retransmission), if the T3-rtx timer of that address is not running	 * start it running so that it will expire after the RTO of that	 * address.	 */	if (!timer_pending(&transport->T3_rtx_timer))		if (!mod_timer(&transport->T3_rtx_timer,			       jiffies + transport->rto))			sctp_transport_hold(transport);	/* When a data chunk is sent, reset the heartbeat interval.  */	if (!mod_timer(&transport->hb_timer,		       sctp_transport_timeout(transport)))	    sctp_transport_hold(transport);}/* This transport has been assigned to an association. * Initialize fields from the association or from the sock itself. * Register the reference count in the association. */void sctp_transport_set_owner(struct sctp_transport *transport,			      struct sctp_association *asoc){	transport->asoc = asoc;	sctp_association_hold(asoc);}/* Initialize the pmtu of a transport. */void sctp_transport_pmtu(struct sctp_transport *transport){	struct dst_entry *dst;	dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL);	if (dst) {		transport->pathmtu = dst_mtu(dst);		dst_release(dst);	} else		transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;}/* this is a complete rip-off from __sk_dst_check * the cookie is always 0 since this is how it's used in the * pmtu code */static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t){	struct dst_entry *dst = t->dst;	if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) {		dst_release(t->dst);		t->dst = NULL;		return NULL;	}	return dst;}void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu){	struct dst_entry *dst;	if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {		printk(KERN_WARNING "%s: Reported pmtu %d too low, "		       "using default minimum of %d\n",		       __FUNCTION__, pmtu,		       SCTP_DEFAULT_MINSEGMENT);		/* Use default minimum segment size and disable		 * pmtu discovery on this transport.		 */		t->pathmtu = SCTP_DEFAULT_MINSEGMENT;	} else {		t->pathmtu = pmtu;	}	dst = sctp_transport_dst_check(t);	if (dst)		dst->ops->update_pmtu(dst, pmtu);}/* Caches the dst entry and source address for a transport's destination * address. */void sctp_transport_route(struct sctp_transport *transport,			  union sctp_addr *saddr, struct sctp_sock *opt){	struct sctp_association *asoc = transport->asoc;	struct sctp_af *af = transport->af_specific;	union sctp_addr *daddr = &transport->ipaddr;	struct dst_entry *dst;	dst = af->get_dst(asoc, daddr, saddr);	if (saddr)		memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));	else		af->get_saddr(asoc, dst, daddr, &transport->saddr);	transport->dst = dst;	if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {		return;

⌨️ 快捷键说明

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