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

📄 protocol.c

📁 在linux环境下的流控制传输协议(sctp)的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	.get_saddr	   = sctp_v4_get_saddr,	.copy_addrlist	   = sctp_v4_copy_addrlist,	.from_skb	   = sctp_v4_from_skb,	.from_sk	   = sctp_v4_from_sk,	.to_sk_saddr	   = sctp_v4_to_sk_saddr,	.to_sk_daddr	   = sctp_v4_to_sk_daddr,	.from_addr_param   = sctp_v4_from_addr_param,	.to_addr_param	   = sctp_v4_to_addr_param,	.dst_saddr	   = sctp_v4_dst_saddr,	.cmp_addr	   = sctp_v4_cmp_addr,	.addr_valid	   = sctp_v4_addr_valid,	.inaddr_any	   = sctp_v4_inaddr_any,	.is_any		   = sctp_v4_is_any,	.available	   = sctp_v4_available,	.scope		   = sctp_v4_scope,	.skb_iif	   = sctp_v4_skb_iif,	.is_ce		   = sctp_v4_is_ce,	.seq_dump_addr	   = sctp_v4_seq_dump_addr,	.net_header_len	   = sizeof(struct iphdr),	.sockaddr_len	   = sizeof(struct sockaddr_in),#ifdef CONFIG_COMPAT	.compat_setsockopt = compat_ip_setsockopt,	.compat_getsockopt = compat_ip_getsockopt,#endif};struct sctp_pf *sctp_get_pf_specific(sa_family_t family) {	switch (family) {	case PF_INET:		return sctp_pf_inet_specific;	case PF_INET6:		return sctp_pf_inet6_specific;	default:		return NULL;	}}/* Register the PF specific function table.  */int sctp_register_pf(struct sctp_pf *pf, sa_family_t family){	switch (family) {	case PF_INET:		if (sctp_pf_inet_specific)			return 0;		sctp_pf_inet_specific = pf;		break;	case PF_INET6:		if (sctp_pf_inet6_specific)			return 0;		sctp_pf_inet6_specific = pf;		break;	default:		return 0;	}	return 1;}static int __init init_sctp_mibs(void){	sctp_statistics[0] = alloc_percpu(struct sctp_mib);	if (!sctp_statistics[0])		return -ENOMEM;	sctp_statistics[1] = alloc_percpu(struct sctp_mib);	if (!sctp_statistics[1]) {		free_percpu(sctp_statistics[0]);		return -ENOMEM;	}	return 0;}static void cleanup_sctp_mibs(void){	free_percpu(sctp_statistics[0]);	free_percpu(sctp_statistics[1]);}static void sctp_v4_pf_init(void){	/* Initialize the SCTP specific PF functions. */	sctp_register_pf(&sctp_pf_inet, PF_INET);	sctp_register_af(&sctp_af_inet);}static void sctp_v4_pf_exit(void){	list_del(&sctp_af_inet.list);}static int sctp_v4_protosw_init(void){	int rc;	rc = proto_register(&sctp_prot, 1);	if (rc)		return rc;	/* Register SCTP(UDP and TCP style) with socket layer.  */	inet_register_protosw(&sctp_seqpacket_protosw);	inet_register_protosw(&sctp_stream_protosw);	return 0;}static void sctp_v4_protosw_exit(void){	inet_unregister_protosw(&sctp_stream_protosw);	inet_unregister_protosw(&sctp_seqpacket_protosw);	proto_unregister(&sctp_prot);}static int sctp_v4_add_protocol(void){	/* Register notifier for inet address additions/deletions. */	register_inetaddr_notifier(&sctp_inetaddr_notifier);	/* Register SCTP with inet layer.  */	if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0)		return -EAGAIN;	return 0;}static void sctp_v4_del_protocol(void){	inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);	unregister_inetaddr_notifier(&sctp_inetaddr_notifier);}/* Initialize the universe into something sensible.  */SCTP_STATIC __init int sctp_init(void){	int i;	int status = -EINVAL;	unsigned long goal;	unsigned long limit;	int max_share;	int order;	/* SCTP_DEBUG sanity check. */	if (!sctp_sanity_check())		goto out;	/* Allocate bind_bucket and chunk caches. */	status = -ENOBUFS;	sctp_bucket_cachep = kmem_cache_create("sctp_bind_bucket",					       sizeof(struct sctp_bind_bucket),					       0, SLAB_HWCACHE_ALIGN,					       NULL);	if (!sctp_bucket_cachep)		goto out;	sctp_chunk_cachep = kmem_cache_create("sctp_chunk",					       sizeof(struct sctp_chunk),					       0, SLAB_HWCACHE_ALIGN,					       NULL);	if (!sctp_chunk_cachep)		goto err_chunk_cachep;	/* Allocate and initialise sctp mibs.  */	status = init_sctp_mibs();	if (status)		goto err_init_mibs;	/* Initialize proc fs directory.  */	status = sctp_proc_init();	if (status)		goto err_init_proc;	/* Initialize object count debugging.  */	sctp_dbg_objcnt_init();	/*	 * 14. Suggested SCTP Protocol Parameter Values	 */	/* The following protocol parameters are RECOMMENDED:  */	/* RTO.Initial              - 3  seconds */	sctp_rto_initial		= SCTP_RTO_INITIAL;	/* RTO.Min                  - 1  second */	sctp_rto_min	 		= SCTP_RTO_MIN;	/* RTO.Max                 -  60 seconds */	sctp_rto_max 			= SCTP_RTO_MAX;	/* RTO.Alpha                - 1/8 */	sctp_rto_alpha	        	= SCTP_RTO_ALPHA;	/* RTO.Beta                 - 1/4 */	sctp_rto_beta			= SCTP_RTO_BETA;	/* Valid.Cookie.Life        - 60  seconds */	sctp_valid_cookie_life		= SCTP_DEFAULT_COOKIE_LIFE;	/* Whether Cookie Preservative is enabled(1) or not(0) */	sctp_cookie_preserve_enable 	= 1;	/* Max.Burst		    - 4 */	sctp_max_burst 			= SCTP_DEFAULT_MAX_BURST;	/* Association.Max.Retrans  - 10 attempts	 * Path.Max.Retrans         - 5  attempts (per destination address)	 * Max.Init.Retransmits     - 8  attempts	 */	sctp_max_retrans_association 	= 10;	sctp_max_retrans_path		= 5;	sctp_max_retrans_init		= 8;	/* Sendbuffer growth	    - do per-socket accounting */	sctp_sndbuf_policy		= 0;	/* Rcvbuffer growth	    - do per-socket accounting */	sctp_rcvbuf_policy		= 0;	/* HB.interval              - 30 seconds */	sctp_hb_interval		= SCTP_DEFAULT_TIMEOUT_HEARTBEAT;	/* delayed SACK timeout */	sctp_sack_timeout		= SCTP_DEFAULT_TIMEOUT_SACK;	/* Implementation specific variables. */	/* Initialize default stream count setup information. */	sctp_max_instreams    		= SCTP_DEFAULT_INSTREAMS;	sctp_max_outstreams   		= SCTP_DEFAULT_OUTSTREAMS;	/* Initialize handle used for association ids. */	idr_init(&sctp_assocs_id);	/* Set the pressure threshold to be a fraction of global memory that	 * is up to 1/2 at 256 MB, decreasing toward zero with the amount of	 * memory, with a floor of 128 pages.	 * Note this initalizes the data in sctpv6_prot too	 * Unabashedly stolen from tcp_init	 */	limit = min(num_physpages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);	limit = (limit * (num_physpages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);	limit = max(limit, 128UL);	sysctl_sctp_mem[0] = limit / 4 * 3;	sysctl_sctp_mem[1] = limit;	sysctl_sctp_mem[2] = sysctl_sctp_mem[0] * 2;	/* Set per-socket limits to no more than 1/128 the pressure threshold*/	limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7);	max_share = min(4UL*1024*1024, limit);	sysctl_sctp_rmem[0] = PAGE_SIZE; /* give each asoc 1 page min */	sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1));	sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share);	sysctl_sctp_wmem[0] = SK_MEM_QUANTUM;	sysctl_sctp_wmem[1] = 16*1024;	sysctl_sctp_wmem[2] = max(64*1024, max_share);	/* Size and allocate the association hash table.	 * The methodology is similar to that of the tcp hash tables.	 */	if (num_physpages >= (128 * 1024))		goal = num_physpages >> (22 - PAGE_SHIFT);	else		goal = num_physpages >> (24 - PAGE_SHIFT);	for (order = 0; (1UL << order) < goal; order++)		;	do {		sctp_assoc_hashsize = (1UL << order) * PAGE_SIZE /					sizeof(struct sctp_hashbucket);		if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)			continue;		sctp_assoc_hashtable = (struct sctp_hashbucket *)					__get_free_pages(GFP_ATOMIC, order);	} while (!sctp_assoc_hashtable && --order > 0);	if (!sctp_assoc_hashtable) {		printk(KERN_ERR "SCTP: Failed association hash alloc.\n");		status = -ENOMEM;		goto err_ahash_alloc;	}	for (i = 0; i < sctp_assoc_hashsize; i++) {		rwlock_init(&sctp_assoc_hashtable[i].lock);		INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);	}	/* Allocate and initialize the endpoint hash table.  */	sctp_ep_hashsize = 64;	sctp_ep_hashtable = (struct sctp_hashbucket *)		kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL);	if (!sctp_ep_hashtable) {		printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n");		status = -ENOMEM;		goto err_ehash_alloc;	}	for (i = 0; i < sctp_ep_hashsize; i++) {		rwlock_init(&sctp_ep_hashtable[i].lock);		INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);	}	/* Allocate and initialize the SCTP port hash table.  */	do {		sctp_port_hashsize = (1UL << order) * PAGE_SIZE /					sizeof(struct sctp_bind_hashbucket);		if ((sctp_port_hashsize > (64 * 1024)) && order > 0)			continue;		sctp_port_hashtable = (struct sctp_bind_hashbucket *)					__get_free_pages(GFP_ATOMIC, order);	} while (!sctp_port_hashtable && --order > 0);	if (!sctp_port_hashtable) {		printk(KERN_ERR "SCTP: Failed bind hash alloc.");		status = -ENOMEM;		goto err_bhash_alloc;	}	for (i = 0; i < sctp_port_hashsize; i++) {		spin_lock_init(&sctp_port_hashtable[i].lock);		INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);	}	printk(KERN_INFO "SCTP: Hash tables configured "			 "(established %d bind %d)\n",		sctp_assoc_hashsize, sctp_port_hashsize);	/* Disable ADDIP by default. */	sctp_addip_enable = 0;	sctp_addip_noauth = 0;	/* Enable PR-SCTP by default. */	sctp_prsctp_enable = 1;	/* Disable AUTH by default. */	sctp_auth_enable = 0;	sctp_sysctl_register();	INIT_LIST_HEAD(&sctp_address_families);	sctp_v4_pf_init();	sctp_v6_pf_init();	/* Initialize the local address list. */	INIT_LIST_HEAD(&sctp_local_addr_list);	spin_lock_init(&sctp_local_addr_lock);	sctp_get_local_addr_list();	status = sctp_v4_protosw_init();	if (status)		goto err_protosw_init;	status = sctp_v6_protosw_init();	if (status)		goto err_v6_protosw_init;	/* Initialize the control inode/socket for handling OOTB packets.  */	if ((status = sctp_ctl_sock_init())) {		printk (KERN_ERR			"SCTP: Failed to initialize the SCTP control sock.\n");		goto err_ctl_sock_init;	}	status = sctp_v4_add_protocol();	if (status)		goto err_add_protocol;	/* Register SCTP with inet6 layer.  */	status = sctp_v6_add_protocol();	if (status)		goto err_v6_add_protocol;	status = 0;out:	return status;err_v6_add_protocol:	sctp_v6_del_protocol();err_add_protocol:	sctp_v4_del_protocol();	sock_release(sctp_ctl_socket);err_ctl_sock_init:	sctp_v6_protosw_exit();err_v6_protosw_init:	sctp_v4_protosw_exit();err_protosw_init:	sctp_free_local_addr_list();	sctp_v4_pf_exit();	sctp_v6_pf_exit();	sctp_sysctl_unregister();	list_del(&sctp_af_inet.list);	free_pages((unsigned long)sctp_port_hashtable,		   get_order(sctp_port_hashsize *			     sizeof(struct sctp_bind_hashbucket)));err_bhash_alloc:	kfree(sctp_ep_hashtable);err_ehash_alloc:	free_pages((unsigned long)sctp_assoc_hashtable,		   get_order(sctp_assoc_hashsize *			     sizeof(struct sctp_hashbucket)));err_ahash_alloc:	sctp_dbg_objcnt_exit();	sctp_proc_exit();err_init_proc:	cleanup_sctp_mibs();err_init_mibs:	kmem_cache_destroy(sctp_chunk_cachep);err_chunk_cachep:	kmem_cache_destroy(sctp_bucket_cachep);	goto out;}/* Exit handler for the SCTP protocol.  */SCTP_STATIC __exit void sctp_exit(void){	/* BUG.  This should probably do something useful like clean	 * up all the remaining associations and all that memory.	 */	/* Unregister with inet6/inet layers. */	sctp_v6_del_protocol();	sctp_v4_del_protocol();	/* Free the control endpoint.  */	sock_release(sctp_ctl_socket);	/* Free protosw registrations */	sctp_v6_protosw_exit();	sctp_v4_protosw_exit();	/* Free the local address list.  */	sctp_free_local_addr_list();	/* Unregister with socket layer. */	sctp_v6_pf_exit();	sctp_v4_pf_exit();	sctp_sysctl_unregister();	list_del(&sctp_af_inet.list);	free_pages((unsigned long)sctp_assoc_hashtable,		   get_order(sctp_assoc_hashsize *			     sizeof(struct sctp_hashbucket)));	kfree(sctp_ep_hashtable);	free_pages((unsigned long)sctp_port_hashtable,		   get_order(sctp_port_hashsize *			     sizeof(struct sctp_bind_hashbucket)));	sctp_dbg_objcnt_exit();	sctp_proc_exit();	cleanup_sctp_mibs();	kmem_cache_destroy(sctp_chunk_cachep);	kmem_cache_destroy(sctp_bucket_cachep);}module_init(sctp_init);module_exit(sctp_exit);/* * __stringify doesn't likes enums, so use IPPROTO_SCTP value (132) directly. */MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132");MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-132");MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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