linuxkernel2.4.5ipv4socket层的一点解释
作者:mobiledu2502884357 | 来源:互联网 | 2017-10-07 07:59
文章标题:linuxkernel2.4.5ipv4socket层的一点解释。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类
1.新建socket 函数原形: static int inet_create(struct socket *sock, int protocol) 在net/ipv4/af_inet.c中 详细解释 static int inet_create(struct socket *sock, int protocol) { struct sock *sk; struct proto *prot; sock->state = SS_UNCONNECTED; /* 设置状态为未连接 */ sk = sk_alloc(PF_INET, GFP_KERNEL, 1); /* 申请sock所需的内存 */ /* net/core/sock.c */ if (sk == NULL) goto do_oom; switch (sock->type) { case SOCK_STREAM: /* TCP协议 */ if (protocol && protocol != IPPROTO_TCP) goto free_and_noproto; protocol = IPPROTO_TCP; prot = &tcp_prot; /* tcp_prot定义在net/ipv4/tcp_ipv4.c */ sock->ops = &inet_stream_ops; /* 针对STREAM的socket操作 */ break; case SOCK_SEQPACKET: /* 不支持 */ goto free_and_badtype; case SOCK_DGRAM: /* UDP协议 */ if (protocol && protocol != IPPROTO_UDP) goto free_and_noproto; protocol = IPPROTO_UDP; sk->no_check = UDP_CSUM_DEFAULT; prot=&udp_prot; /* udp_prot定义在net/ipv4/udp.c */ sock->ops = &inet_dgram_ops; /* 针对DGRAM的socket操作 */ break; case SOCK_RAW: /* RAW */ if (!capable(CAP_NET_RAW)) /* 判断是否有权利建立SOCK_RAW */ goto free_and_badperm; if (!protocol) /* protocol不能为0 */ goto free_and_noproto; prot = &raw_prot; /* raw_prot定义在net/ipv4/raw.c */ sk->reuse = 1; /* 允许地址重用 */ sk->num = protocol; sock->ops = &inet_dgram_ops; /* RAW的一些特性和DGRAM相同 */ if (protocol == IPPROTO_RAW) sk->protinfo.af_inet.hdrincl = 1; /* 允许自己定制ip头 */ break; default: goto free_and_badtype; } if (ipv4_config.no_pmtu_disc) sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; else sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT; sk->protinfo.af_inet.id = 0; sock_init_data(sock,sk); /* 初始化一些数据 */ /* net/core/sock.c */ sk->destruct = inet_sock_destruct; /* 当销毁socket时调用inet_sock_destruct */ sk->zapped = 0; sk->family = PF_INET; sk->protocol = protocol; sk->prot = prot; sk->backlog_rcv = prot->backlog_rcv; /* prot->backlog_rcv()见各个类型的定义 */ sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl; /* 设置默认ttl */ /* 修改/proc/sys/net/ipv4/ip_default_ttl */ sk->protinfo.af_inet.mc_loop = 1; sk->protinfo.af_inet.mc_ttl = 1; sk->protinfo.af_inet.mc_index = 0; sk->protinfo.af_inet.mc_list = NULL; #ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); #endif if (sk->num) { /* It assumes that any protocol which allows * the user to assign a number at socket * creation time automatically * shares. */ sk->sport = htons(sk->num); /* 设置本地端口 */ /* Add to protocol hash chains. */ sk->prot->hash(sk); } if (sk->prot->init) { int err = sk->prot->init(sk); /* 协议对socket的初始化 */ if (err != 0) { inet_sock_release(sk); return(err); } } return(0); free_and_badtype: sk_free(sk); /* 释放内存 */ return -ESOCKTNOSUPPORT; free_and_badperm: sk_free(sk); return -EPERM; free_and_noproto: sk_free(sk); return -EPROTONOSUPPORT; do_oom: return -ENOBUFS; } 在net/core/sock.c void sock_init_data(struct socket *sock, struct sock *sk) { skb_queue_head_init(&sk->receive_queue); /* 初始化3条队列 接受,发送,错误*/ skb_queue_head_init(&sk->write_queue); skb_queue_head_init(&sk->error_queue); init_timer(&sk->timer); /* 初始化timer */ sk->allocation = GFP_KERNEL; sk->rcvbuf = sysctl_rmem_default; sk->sndbuf = sysctl_wmem_default; sk->state = TCP_CLOSE; sk->zapped = 1; sk->socket = sock; if(sock) { sk->type = sock->type; sk->sleep = &sock->wait; sock->sk = sk; } else sk->sleep = NULL; sk->dst_lock = RW_LOCK_UNLOCKED; sk->callback_lock = RW_LOCK_UNLOCKED; /* sock_def_wakeup(),sock_def_readable(), sock_def_write_space(),sock_def_error_report(), sock_def_destruct() 在net/core/sock.c */ sk->state_change = sock_def_wakeup; sk->data_ready = sock_def_readable; sk->write_space = sock_def_write_space; sk->error_report = sock_def_error_report; sk->destruct = sock_def_destruct; sk->peercred.pid = 0; sk->peercred.uid = -1; sk->peercred.gid = -1; sk->rcvlowat = 1; sk->rcvtimeo = MAX_SCHEDULE_TIMEOUT; /* 设置接受,发送超时 */ sk->sndtimeo = MAX_SCHEDULE_TIMEOUT; atomic_set(&sk->refcnt, 1); } 1.1 SOCK_STREAM的初始化 在net/ipv4/tcp_ipv4.c static int tcp_v4_init_sock(struct sock *sk) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); skb_queue_head_init(&tp->out_of_order_queue); tcp_init_xmit_timers(sk); tcp_prequeue_init(tp); tp->rto = TCP_TIMEOUT_INIT; tp->mdev = TCP_TIMEOUT_INIT; /* So many TCP implementations out there (incorrectly) count the * initial SYN frame in their delayed-ACK and congestion control * algorithms that we must have the following bandaid to talk * efficiently to them. -DaveM */ tp->snd_cwnd = 2; /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ tp->snd_ssthresh = 0x7fffffff; /* Infinity */ tp->snd_cwnd_clamp = ~0; tp->mss_cache = 536; tp->reordering = sysctl_tcp_reordering; sk->state = TCP_CLOSE; sk->write_space = tcp_write_space; /* tcp_write_space() 在net/ipv4/tcp.c */ sk->use_write_queue = 1; sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific; /* ipv4_specific 在net/ipv4/tcp_ipv4.c */ sk->sndbuf = sysctl_tcp_wmem[1]; /* 设置发送和接收缓冲区大小 */ sk->rcvbuf = sysctl_tcp_rmem[1]; /* sysctl_tcp_* 在net/ipv4/tcp.c */ atomic_inc(&tcp_sockets_allocated); /* tcp_sockets_allocated是当前TCP socket的数量 */ return 0; } SOCK_DGRAM无初始化 1.2 SOCK_RAW初始化 在net/ipv4/raw.c static int raw_init(struct sock *sk) { struct raw_opt *tp = &(sk->tp_pinfo.tp_raw4); if (sk->num == IPPROTO_ICMP) memset(&tp->filter, 0, sizeof(tp->filter)); return 0; } 2.Server 2.1 bind static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in *addr=(struct sockaddr_in *)uaddr; struct sock *sk=sock->sk; unsigned short snum; int chk_addr_ret; int err; /* If the socket has its own bind function then use it. (RAW) */ if(sk->prot->bind) return sk->prot->bind(sk, uaddr, addr_len); /* 只有SOCK_RAW定义了自己的bind函数 */ if (addr_len return -EINVAL; chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); /* inet_addr_type返回地址的类型 */ /* 在net/ipv4/fib_frontend.c */ /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since * allowing applications to make a non-local bind solv
推荐阅读
本文介绍了一款好用的内网穿透工具FRP,它是一个使用Go语言开发的高性能的反向代理应用。FRP支持多种协议类型,并且可以根据域名进行路由转发。 ...
[详细]
蜡笔小新 2023-12-09 04:46:42
本文介绍了某点评网的搜索策略,包括名称和地址的匹配策略,模糊匹配的方法以及不同口音和拼音的近似发音。同时提供了一些例子来说明这些策略的应用。 ...
[详细]
蜡笔小新 2023-12-09 08:18:18
概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ...
[详细]
蜡笔小新 2023-10-17 19:16:37
Opencv提供了几种分类器,例程里通过字符识别来进行说明的1、支持向量机(SVM):给定训练样本,支持向量机建立一个超平面作为决策平面,使得正例和反例之间的隔离边缘被最大化。函数原型:训练原型cv ...
[详细]
蜡笔小新 2023-10-17 17:02:44
01—实验目的掌握单点登陆相关原理和深信服配置02—实验环境1.AC版本v12.0.42AC1地址:https:172.172.1.1AC2地址:htt ...
[详细]
蜡笔小新 2023-10-17 15:23:51
SQLServer2008到底需要使用哪些端口?-下面就来介绍下SQLServer2008中使用的端口有哪些: 首先,最常用最常见的就是1433端口。这个是数据库引擎的端口,如果 ...
[详细]
蜡笔小新 2023-10-17 14:12:12
Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ...
[详细]
蜡笔小新 2023-12-14 17:38:12
本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ...
[详细]
蜡笔小新 2023-12-14 14:44:00
本文介绍了Linux环境变量$PATH的作用及使用方法。$PATH是一个由多个目录组成的变量,用冒号分隔。当执行一个指令时,系统会按照$PATH定义的目录顺序搜索同名的可执行文件,如果有多个同名指令,则先找到的会被执行。通过设置$PATH变量,可以在任何地方执行指令,无需输入绝对路径。 ...
[详细]
蜡笔小新 2023-12-10 15:26:56
本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ...
[详细]
蜡笔小新 2023-12-10 14:45:37
先来简单回顾一下今年的显卡市场,nvidia自从发布了帕斯卡架构新品之后,可以说是一直都主宰着高端游戏显卡市场,虽说amd也憋了一个hbm2的vega64出来,然而即使是最高贵的水 ...
[详细]
蜡笔小新 2023-12-10 14:36:15
本文介绍了禅道作为一款国产开源免费的测试管理工具的特点和功能,并提供了禅道的搭建和调试方法。禅道是一款B/S结构的项目管理工具,可以实现组织管理、后台管理、产品管理、项目管理和测试管理等功能。同时,本文还介绍了其他软件测试相关工具,如功能自动化工具和性能自动化工具,以及白盒测试工具的使用。通过本文的阅读,读者可以了解禅道的基本使用方法和优势,从而更好地进行测试管理工作。 ...
[详细]
蜡笔小新 2023-12-09 19:03:20
本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ...
[详细]
蜡笔小新 2023-12-09 17:36:44
loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ...
[详细]
蜡笔小新 2023-10-17 21:26:42
本文目录一览:1、如何在IIS中执行Python脚本 ...
[详细]
蜡笔小新 2023-10-17 19:41:52
mobiledu2502884357
这个家伙很懒,什么也没留下!