加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

Linux内核--网络栈实现分析(二)--数据包的传递过程--转

发布时间:2020-12-13 14:05:37 所属栏目:Linux 来源:网络整理
导读:转载地址 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析、”(下)“表示分析是从上向下分析。 ?上篇: 上一篇博文中我们从宏观上分析了Linux内核

转载地址

作者:闫明

本文分析基于Linux Kernel 1.2.13

注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析、”(下)“表示分析是从上向下分析。

?上篇:

上一篇博文中我们从宏观上分析了Linux内核中网络栈的初始化过程,这里我们再从宏观上分析一下一个数据包在各网络层的传递的过程。

我们知道网络的OSI模型和TCP/IP模型层次结构如下:

上文中我们看到了网络栈的层次结构:

我们就从最底层开始追溯一个数据包的传递流程。

1、网络接口层

* 硬件监听物理介质,进行数据的接收,当接收的数据填满了缓冲区,硬件就会产生中断,中断产生后,系统会转向中断服务子程序。

* 在中断服务子程序中,数据会从硬件的缓冲区复制到内核的空间缓冲区,并包装成一个数据结构(sk_buff),然后调用对驱动层的接口函数netif_rx()将数据包发送给链路层。该函数的实现在net/inet/dev.c中,(在整个网络栈实现中dev.c文件的作用重大,它衔接了其下的驱动层和其上的网络层,可以称它为链路层模块的实现)

该函数的实现如下:

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
    ?
  1. ?
  2. ?
  3. ?
  4. ?
  5. ?
  6. ??
  7. ??
  8. ?netif_rx(?sk_buff?*skb)??
  9. {??
  10. ??????dropping?=?0;??
  11. ??
  12. ?????
  13. ?
  14. ?
  15. ?
  16. ??
  17. ????skb->sk?=?NULL;??
  18. ????skb->free?=?1;??
  19. ????(skb->stamp.tv_sec==0)??
  20. ????????skb->stamp?=?xtime;??
  21. ??
  22. ?????
  23. ?
  24. ??
  25. ??
  26. ?????(!backlog_size)??
  27. ????????dropping?=?0;??
  28. ??????(backlog_size?>?300)??
  29. ????????dropping?=?1;??
  30. ??
  31. ?????(dropping)???
  32. ????{??
  33. ????????kfree_skb(skb,?FREE_READ);??
  34. ????????;??
  35. ????}??
  36. ??
  37. ?????
  38. ?
  39. ??
  40. ??
  41. ????IS_SKB(skb);??
  42. ??
  43. ????skb_queue_tail(&backlog,skb);??
  44. ????backlog_size++;??
  45. ????
  46. ?????
  47. ?
  48. ?
  49. ??
  50. ??
  51. ????mark_bh(NET_BH);??
  52. ????;??
  53. }??

该函数中用到了bootom half技术,该技术的原理是将中断处理程序人为的分为两部分,上半部分是实时性要求较高的任务,后半部分可以稍后完成,这样就可以节省中断程序的处理时间。可整体的提高系统的性能。该技术将会在后续的博文中详细分析。

我们从上一篇分析中知道,在网络栈初始化的时候,已经将NET的下半部分执行函数定义成了net_bh(在socket.c文件中1375行左右)

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
    bh_base[NET_BH].routine=?net_bh;??

* 函数net_bh的实现在net/inet/dev.c中

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
    ?
  1. ?
  2. ?
  3. ?
  4. ?
  5. ?
  6. ??
  7. ???
  8. ?net_bh(?*tmp)??
  9. {??
  10. ?????sk_buff?*skb;??
  11. ?????packet_type?*ptype;??
  12. ?????packet_type?*pt_prev;??
  13. ????unsigned??type;??
  14. ??
  15. ?????
  16. ?
  17. ??
  18. ??
  19. ?????(set_bit(1,?(*)&in_bh))??
  20. ????????;??
  21. ??
  22. ?????
  23. ?
  24. ?
  25. ?
  26. ??
  27. ??
  28. ????dev_transmit();??
  29. ????
  30. ?????
  31. ?
  32. ?
  33. ?
  34. ??
  35. ??
  36. ????cli();??
  37. ??????
  38. ?????
  39. ?
  40. ??
  41. ???????
  42. ????((skb=skb_dequeue(&backlog))!=NULL)??
  43. ????{??
  44. ?????????
  45. ?
  46. ??
  47. ????????backlog_size--;??
  48. ??
  49. ????????sti();??
  50. ??????????
  51. ????????????
  52. ?
  53. ?
  54. ?
  55. ?
  56. ??
  57. ??
  58. ????????skb->h.raw?=?skb->data?+?skb->dev->hard_header_len;??
  59. ????????skb->len?-=?skb->dev->hard_header_len;??
  60. ??
  61. ????????????
  62. ?
  63. ?
  64. ?
  65. ?
  66. ?
  67. ?
  68. ?
  69. ?
  70. ??
  71. ??????????
  72. ????????type?=?skb->dev->type_trans(skb,?skb->dev);??
  73. ??
  74. ?????????
  75. ?
  76. ?
  77. ?
  78. ?
  79. ?
  80. ?
  81. ?
  82. ?
  83. ?
  84. ??
  85. ????????pt_prev?=?NULL;??
  86. ?????????(ptype?=?ptype_base;?ptype?!=?NULL;?ptype?=?ptype->next)???
  87. ????????{??
  88. ??????????????
  89. ?????????????((ptype->type?==?type?||?ptype->type?==?htons(ETH_P_ALL))?&&?(!ptype->dev?||?ptype->dev==skb->dev))??
  90. ????????????{??
  91. ?????????????????
  92. ?
  93. ?
  94. ??
  95. ????????????????(pt_prev)??
  96. ????????????????{??
  97. ?????????????????????sk_buff?*skb2;??
  98. ??
  99. ????????????????????skb2=skb_clone(skb,?GFP_ATOMIC);??
  100. ??
  101. ?????????????????????
  102. ?
  103. ?
  104. ??
  105. ??
  106. ????????????????????(skb2)??
  107. ????????????????????????pt_prev->func(skb2,?skb->dev,?pt_prev);??
  108. ??????????????????????????????????????????????
  109. ??????????????????????????????????????????????
  110. ????????????????}??
  111. ??????????????????
  112. ????????????????pt_prev=ptype;??
  113. ????????????}??
  114. ????????}???
  115. ??????????
  116. ?????????
  117. ?
  118. ??
  119. ??
  120. ????????(pt_prev)??
  121. ????????????pt_prev->func(skb,?pt_prev);??
  122. ?????????
  123. ?
  124. ??
  125. ???????
  126. ??????????
  127. ????????????kfree_skb(skb,?FREE_WRITE);??
  128. ??
  129. ?????????
  130. ?
  131. ?
  132. ?
  133. ??
  134. ??
  135. ????????dev_transmit();??
  136. ????????cli();??
  137. ????}?????
  138. ??????
  139. ?????
  140. ?
  141. ??
  142. ???????
  143. ????in_bh?=?0;??
  144. ????sti();??
  145. ??????
  146. ?????
  147. ?
  148. ??
  149. ???????
  150. ????dev_transmit();??
  151. }??

2、网络层* 就以IP数据包为例来说明,那么从链路层向网络层传递时将调用ip_rcv函数。该函数完成本层的处理后会根据IP首部中使用的传输层协议来调用相应协议的处理函数。

UDP对应udp_rcv、TCP对应tcp_rcv、ICMP对应icmp_rcv、IGMP对应igmp_rcv(虽然这里的ICMP,IGMP一般成为网络层协议,但是实际上他们都封装在IP协议里面,作为传输层对待)

这个函数比较复杂,后续会详细分析。这里粘贴一下,让我们对整体了解更清楚

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
    ?
  1. ?
  2. ??
  3. ??
  4. ?ip_rcv(?sk_buff?*skb,??device?*dev,??packet_type?*pt)??
  5. {??
  6. ?????iphdr?*iph?=?skb->h.iph;??
  7. ?????sock?*raw_sk=NULL;??
  8. ????unsigned??hash;??
  9. ????unsigned??flag?=?0;??
  10. ????unsigned??opts_p?=?0;?????
  11. ?????inet_protocol?*ipprot;??
  12. ??????options?opt;??
  13. ??
  14. ?????brd=IS_MYADDR;??
  15. ?????is_frag=0;??
  16. ??
  17. ?????err;??
  18. ??
  19. ??
  20. ????ip_statistics.IpInReceives++;??
  21. ??
  22. ?????
  23. ?
  24. ??
  25. ??
  26. ????skb->ip_hdr?=?iph;??
  27. ??
  28. ?????
  29. ?
  30. ?
  31. ?
  32. ?
  33. ?
  34. ?
  35. ??
  36. ??
  37. ?????(skb->len<(?iphdr)?||?iph->ihl<5?||?iph->version?!=?4?||??
  38. ????????skb->lentot_len)?||?ip_fast_csum((unsigned??*)iph,?iph->ihl)?!=0)??
  39. ????{??
  40. ????????ip_statistics.IpInHdrErrors++;??
  41. ????????kfree_skb(skb,?FREE_WRITE);??
  42. ????????(0);??
  43. ????}??
  44. ??????
  45. ?????
  46. ?
  47. ??
  48. ??
  49. ??
  50. ??????
  51. ?????((err=ip_fw_chk(iph,dev,ip_fw_blk_chain,ip_fw_blk_policy,?0))!=1)??
  52. ????{??
  53. ????????(err==-1)??
  54. ????????????icmp_send(skb,?ICMP_DEST_UNREACH,?ICMP_PORT_UNREACH,?0,?dev);??
  55. ????????kfree_skb(skb,?FREE_WRITE);??
  56. ?????????0;?????
  57. ????}??
  58. ??
  59. ??
  60. ??????
  61. ?????
  62. ?
  63. ?
  64. ??
  65. ??
  66. ????skb->len=ntohs(iph->tot_len);??
  67. ??
  68. ?????
  69. ?
  70. ?
  71. ??
  72. ??
  73. ?????(iph->ihl?!=?5)??
  74. ????{?????
  75. ????????memset((?*)?&opt,?(opt));??
  76. ?????????(do_options(iph,?&opt)?!=?0)??
  77. ?????????????0;??
  78. ????????opts_p?=?1;??
  79. ????}??
  80. ??
  81. ?????
  82. ?
  83. ??
  84. ???????
  85. ????(iph->frag_off)??
  86. ????{??
  87. ?????????(iph->frag_off?&?0x0020)??
  88. ????????????is_frag|=1;??
  89. ?????????
  90. ?
  91. ??
  92. ??????
  93. ?????????(ntohs(iph->frag_off)?&?0x1fff)??
  94. ????????????is_frag|=2;??
  95. ????}??
  96. ??????
  97. ?????
  98. ?
  99. ?
  100. ?
  101. ?
  102. ?
  103. ?
  104. ?
  105. ?
  106. ?
  107. ??
  108. ??
  109. ?????(?iph->daddr?!=?skb->dev->pa_addr?&&?(brd?=?ip_chk_addr(iph->daddr))?==?0)??
  110. ????{??
  111. ?????????
  112. ?
  113. ??
  114. ??
  115. ????????(skb->pkt_type!=PACKET_HOST?||?brd==IS_BROADCAST)??
  116. ????????{??
  117. ????????????kfree_skb(skb,FREE_WRITE);??
  118. ?????????????0;??
  119. ????????}??
  120. ??
  121. ?????????
  122. ?
  123. ??
  124. ??
  125. ??
  126. ????????ip_forward(skb,?dev,?is_frag);??
  127. ??
  128. ?
  129. saddr,iph->daddr);*/??
  130. ????????ip_statistics.IpInAddrErrors++;??
  131. ??
  132. ?????????
  133. ?
  134. ?
  135. ??
  136. ??
  137. ????????kfree_skb(skb,?FREE_WRITE);??
  138. ????????(0);??
  139. ????}??
  140. ??????
  141. ??
  142. ??
  143. ????(brd==IS_MULTICAST?&&?iph->daddr!=IGMP_ALL_HOSTS?&&?!(dev->flags&IFF_LOOPBACK))??
  144. ????{??
  145. ?????????
  146. ?
  147. ??
  148. ?????????ip_mc_list?*ip_mc=dev->ip_mc_list;??
  149. ??????????
  150. ????????{??
  151. ????????????(ip_mc==NULL)??
  152. ????????????{?????
  153. ????????????????kfree_skb(skb,?FREE_WRITE);??
  154. ?????????????????0;??
  155. ????????????}??
  156. ????????????(ip_mc->multiaddr==iph->daddr)??
  157. ????????????????;??
  158. ????????????ip_mc=ip_mc->next;??
  159. ????????}??
  160. ????????(1);??
  161. ????}??
  162. ??
  163. ?????
  164. ?
  165. ??
  166. ???????
  167. ??
  168. ????ip_acct_cnt(iph,?ip_acct_chain);??
  169. ??
  170. ??
  171. ?????
  172. ?
  173. ??
  174. ??
  175. ????(is_frag)??
  176. ????{??
  177. ??????????
  178. ????????skb=ip_defrag(iph,skb,dev);??
  179. ????????(skb==NULL)??
  180. ?????????????0;??
  181. ????????skb->dev?=?dev;??
  182. ????????iph=skb->h.iph;??
  183. ????}??
  184. ??????
  185. ???????????
  186. ??
  187. ?????
  188. ?
  189. ??
  190. ??
  191. ????skb->ip_hdr?=?iph;??
  192. ????skb->h.raw?+=?iph->ihl*4;??
  193. ??????
  194. ?????
  195. ?
  196. ??
  197. ???????
  198. ????hash?=?iph->protocol?&?(SOCK_ARRAY_SIZE-1);??
  199. ??????
  200. ??????
  201. ????((raw_sk=raw_prot.sock_array[hash])!=NULL)??
  202. ????{??
  203. ?????????sock?*sknext=NULL;??
  204. ?????????sk_buff?*skb1;??
  205. ????????raw_sk=get_sock_raw(raw_sk,?hash,??iph->saddr,?iph->daddr);??
  206. ????????(raw_sk)????
  207. ????????{??
  208. ??????????????
  209. ????????????{??
  210. ??????????????????
  211. ????????????????sknext=get_sock_raw(raw_sk->next,?iph->saddr,?iph->daddr);??
  212. ????????????????(sknext)??
  213. ????????????????????skb1=skb_clone(skb,?GFP_ATOMIC);??
  214. ??????????????????
  215. ????????????????????;????
  216. ????????????????(skb1)??
  217. ????????????????????raw_rcv(raw_sk,?skb1,iph->daddr);??
  218. ????????????????raw_sk=sknext;??
  219. ????????????}??
  220. ????????????(raw_sk!=NULL);??
  221. ??????????????
  222. ??????????????
  223. ????????}??
  224. ????}??
  225. ??????
  226. ?????
  227. h.raw?now?points?at?the?protocol?beyond?the?IP?header.?
  228. ??
  229. ??
  230. ????hash?=?iph->protocol?&?(MAX_INET_PROTOS?-1);??
  231. ?????(ipprot?=?(?inet_protocol?*)inet_protos[hash];ipprot?!=?NULL;ipprot=(?inet_protocol?*)ipprot->next)??
  232. ????{??
  233. ?????????sk_buff?*skb2;??
  234. ??
  235. ?????????(ipprot->protocol?!=?iph->protocol)??
  236. ????????????;??
  237. ????????
  238. ?
  239. ?
  240. ?
  241. ?
  242. ??
  243. ?????????(ipprot->copy?||?raw_sk)??
  244. ????????{??
  245. ????????????skb2?=?skb_clone(skb,?GFP_ATOMIC);??
  246. ????????????(skb2==NULL)??
  247. ????????????????;??
  248. ????????}??
  249. ??????????
  250. ????????{??
  251. ????????????skb2?=?skb;??
  252. ????????}??
  253. ????????flag?=?1;??
  254. ??
  255. ????????????
  256. ?
  257. ?
  258. ?
  259. ??
  260. ????????ipprot->handler(skb2,?opts_p???&opt?:?0,?iph->daddr,??
  261. ????????????????(ntohs(iph->tot_len)?-?(iph->ihl?*?4)),??
  262. ????????????????iph->saddr,?ipprot);??
  263. ??
  264. ????}??
  265. ??
  266. ?????
  267. ?
  268. ?
  269. ?
  270. ?
  271. ??
  272. ??
  273. ????(raw_sk!=NULL)??????
  274. ????????raw_rcv(raw_sk,?skb,?iph->daddr);??
  275. ??????(!flag)???????
  276. ????{??
  277. ?????????(brd?!=?IS_BROADCAST?&&?brd!=IS_MULTICAST)??
  278. ????????????icmp_send(skb,?ICMP_PROT_UNREACH,?FREE_WRITE);??
  279. ????}??
  280. ??
  281. ????(0);??
  282. }??

3、传输层

如果在IP数据报的首部标明的是使用TCP传输数据,则在上述函数中会调用tcp_rcv函数。该函数的大体处理流程为:

“所有使用TCP 协议的套接字对应sock 结构都被挂入tcp_prot 全局变量表示的proto 结构之sock_array 数组中,采用以本地端口号为索引的插入方式,所以当tcp_rcv 函数接收到一个数据包,在完成必要的检查和处理后,其将以TCP 协议首部中目的端口号(对于一个接收的数据包而言,其目的端口号就是本地所使用的端口号)为索引,在tcp_prot 对应sock 结构之sock_array 数组中得到正确的sock 结构队列,在辅之以其他条件遍历该队列进行对应sock 结构的查询,在得到匹配的sock 结构后,将数据包挂入该sock 结构中的缓存队列中(由sock 结构中receive_queue 字段指向),从而完成数据包的最终接收。”

该函数的实现也会比较复杂,这是由TCP协议的复杂功能决定的。附代码如下:

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
    ?
  1. ?
  2. ??
  3. ???
  4. ?tcp_rcv(?sk_buff?*skb,??options?*opt,??
  5. ????unsigned??daddr,?unsigned??len,??
  6. ????unsigned??saddr,??redo,??inet_protocol?*?protocol)??
  7. {??
  8. ?????tcphdr?*th;??
  9. ?????sock?*sk;??
  10. ?????syn_ok=0;??
  11. ??????
  12. ?????(!skb)???
  13. ????{??
  14. ????????printk();??
  15. ????????(0);??
  16. ????}??
  17. ??
  18. ?????(!dev)???
  19. ????{??
  20. ????????printk();??
  21. ????????(0);??
  22. ????}??
  23. ????
  24. ????tcp_statistics.TcpInSegs++;??
  25. ????
  26. ????(skb->pkt_type!=PACKET_HOST)??
  27. ????{??
  28. ????????kfree_skb(skb,FREE_READ);??
  29. ????????(0);??
  30. ????}??
  31. ????
  32. ????th?=?skb->h.th;??
  33. ??
  34. ?????
  35. ?
  36. ??
  37. ??
  38. ????sk?=?get_sock(&tcp_prot,?th->dest,?saddr,?th->source,?daddr);??
  39. ??
  40. ?????
  41. ?
  42. ?
  43. ?
  44. ?
  45. ?
  46. ?
  47. ??
  48. ???????
  49. ?????(sk!=NULL?&&?(sk->zapped?||?sk->state==TCP_CLOSE))??
  50. ????????sk=NULL;??
  51. ??
  52. ?????(!redo)???
  53. ????{??
  54. ?????????(tcp_check(th,?len,?daddr?))???
  55. ????????{??
  56. ????????????skb->sk?=?NULL;??
  57. ????????????kfree_skb(skb,FREE_READ);??
  58. ?????????????
  59. ?
  60. ?
  61. ??
  62. ????????????(0);??
  63. ????????}??
  64. ????????th->seq?=?ntohl(th->seq);??
  65. ??
  66. ??????????
  67. ?????????(sk?==?NULL)???
  68. ????????{??
  69. ?????????????
  70. rst?is?0?send?a?reset?(checked?in?tcp_reset)?
  71. ??
  72. ????????????tcp_reset(daddr,?th,?&tcp_prot,?opt,skb->ip_hdr->tos,255);??
  73. ????????????skb->sk?=?NULL;??
  74. ?????????????
  75. ?
  76. ??
  77. ????????????kfree_skb(skb,?FREE_READ);??
  78. ????????????(0);??
  79. ????????}??
  80. ??
  81. ????????skb->len?=?len;??
  82. ????????skb->acked?=?0;??
  83. ????????skb->used?=?0;??
  84. ????????skb->free?=?0;??
  85. ????????skb->saddr?=?daddr;??
  86. ????????skb->daddr?=?saddr;??
  87. ??????
  88. ??????????
  89. ????????cli();??
  90. ?????????(sk->inuse)???
  91. ????????{??
  92. ????????????skb_queue_tail(&sk->back_log,?skb);??
  93. ????????????sti();??
  94. ????????????(0);??
  95. ????????}??
  96. ????????sk->inuse?=?1;??
  97. ????????sti();??
  98. ????}??
  99. ??????
  100. ????{??
  101. ?????????(sk==NULL)???
  102. ????????{??
  103. ????????????tcp_reset(daddr,255);??
  104. ????????????skb->sk?=?NULL;??
  105. ????????????kfree_skb(skb,?FREE_READ);??
  106. ????????????(0);??
  107. ????????}??
  108. ????}??
  109. ??
  110. ??
  111. ?????(!sk->prot)???
  112. ????{??
  113. ????????printk();??
  114. ????????(0);??
  115. ????}??
  116. ??
  117. ??
  118. ?????
  119. ?
  120. ??
  121. ???????
  122. ?????(sk->rmem_alloc?+?skb->mem_len?>=?sk->rcvbuf)???
  123. ????{??
  124. ????????kfree_skb(skb,?FREE_READ);??
  125. ????????release_sock(sk);??
  126. ????????(0);??
  127. ????}??
  128. ??
  129. ????skb->sk=sk;??
  130. ????sk->rmem_alloc?+=?skb->mem_len;??
  131. ??
  132. ?????
  133. ?
  134. ?
  135. ?
  136. ?
  137. ??
  138. ??
  139. ????(sk->state!=TCP_ESTABLISHED)?????????
  140. ????{??
  141. ??????
  142. ?????????
  143. ?
  144. ??
  145. ???????
  146. ????????(sk->state==TCP_LISTEN)??
  147. ????????{??
  148. ????????????(th->ack)????
  149. ????????????????tcp_reset(daddr,saddr,th,sk->prot,opt,sk->ip_tos,?sk->ip_ttl);??
  150. ??
  151. ?????????????
  152. ?
  153. ?
  154. ?
  155. ?
  156. ??
  157. ?????????????????
  158. ????????????(th->rst?||?!th->syn?||?th->ack?||?ip_chk_addr(daddr)!=IS_MYADDR)??
  159. ????????????{??
  160. ????????????????kfree_skb(skb,?FREE_READ);??
  161. ????????????????release_sock(sk);??
  162. ?????????????????0;??
  163. ????????????}??
  164. ??????????
  165. ?????????????
  166. ?
  167. ??
  168. ??????????
  169. ????????????tcp_conn_request(sk,?daddr,?tcp_init_seq());??
  170. ??????????
  171. ?????????????
  172. ?
  173. ?
  174. ?
  175. ?
  176. ?
  177. ?
  178. ??
  179. ???????????????
  180. ????????????release_sock(sk);??
  181. ?????????????0;??
  182. ????????}??
  183. ??????
  184. ??????????
  185. ?????????(sk->state?==?TCP_SYN_RECV?&&?th->syn?&&?th->seq+1?==?sk->acked_seq)??
  186. ????????{??
  187. ????????????kfree_skb(skb,?FREE_READ);??
  188. ????????????release_sock(sk);??
  189. ?????????????0;??
  190. ????????}??
  191. ??????????
  192. ?????????
  193. ?
  194. ?
  195. ??
  196. ?????????
  197. ????????(sk->state==TCP_SYN_SENT)??
  198. ????????{??
  199. ??????????????
  200. ????????????(th->ack)??
  201. ????????????{??
  202. ??????????????????
  203. ????????????????(!tcp_ack(sk,len))??
  204. ????????????????{??
  205. ?????????????????????
  206. rst?is?checked?in?tcp_reset()]?*/??
  207. ????????????????????tcp_statistics.TcpAttemptFails++;??
  208. ????????????????????tcp_reset(daddr,??
  209. ????????????????????????sk->prot,sk->ip_ttl);??
  210. ????????????????????kfree_skb(skb,?FREE_READ);??
  211. ????????????????????release_sock(sk);??
  212. ????????????????????(0);??
  213. ????????????????}??
  214. ????????????????(th->rst)??
  215. ?????????????????????tcp_std_reset(sk,skb);??
  216. ????????????????(!th->syn)??
  217. ????????????????{??
  218. ?????????????????????
  219. ??
  220. ????????????????????kfree_skb(skb,?FREE_READ);??
  221. ????????????????????release_sock(sk);??
  222. ?????????????????????0;??
  223. ????????????????}??
  224. ?????????????????
  225. ?
  226. ?
  227. ??
  228. ????????????????syn_ok=1;?????
  229. ????????????????sk->acked_seq=th->seq+1;??
  230. ????????????????sk->fin_seq=th->seq;??
  231. ????????????????tcp_send_ack(sk->sent_seq,sk->acked_seq,sk,sk->daddr);??
  232. ????????????????tcp_set_state(sk,?TCP_ESTABLISHED);??
  233. ????????????????tcp_options(sk,th);??
  234. ????????????????sk->dummy_th.dest=th->source;??
  235. ????????????????sk->copied_seq?=?sk->acked_seq;??
  236. ????????????????(!sk->dead)??
  237. ????????????????{??
  238. ????????????????????sk->state_change(sk);??
  239. ????????????????????sock_wake_async(sk->socket,?0);??
  240. ????????????????}??
  241. ????????????????(sk->max_window==0)??
  242. ????????????????{??
  243. ????????????????????sk->max_window?=?32;??
  244. ????????????????????sk->mss?=?min(sk->max_window,?sk->mtu);??
  245. ????????????????}??
  246. ????????????}??
  247. ??????????????
  248. ????????????{??
  249. ??????????????????
  250. ????????????????(th->syn?&&?!th->rst)??
  251. ????????????????{??
  252. ?????????????????????
  253. ??
  254. ????????????????????(sk->saddr==saddr?&&?sk->daddr==daddr?&&??
  255. ????????????????????????sk->dummy_th.source==th->source?&&??
  256. ????????????????????????sk->dummy_th.dest==th->dest)??
  257. ????????????????????{??
  258. ????????????????????????tcp_statistics.TcpAttemptFails++;??
  259. ?????????????????????????tcp_std_reset(sk,skb);??
  260. ????????????????????}??
  261. ????????????????????tcp_set_state(sk,TCP_SYN_RECV);??
  262. ??????????????????????
  263. ?????????????????????
  264. ?
  265. ?
  266. ??
  267. ????????????????}?????????
  268. ??????????????????
  269. ????????????????kfree_skb(skb,?FREE_READ);??
  270. ????????????????release_sock(sk);??
  271. ?????????????????0;??
  272. ????????????}??
  273. ?????????????
  274. ?
  275. ??
  276. ?????????????rfc_step6;??
  277. ????????}??
  278. ??
  279. ?????
  280. ?
  281. ?
  282. ?
  283. ??
  284. ??????
  285. ??
  286. ??
  287. ?????????(sk->state?==?TCP_TIME_WAIT?&&?th->syn?&&?sk->dead?&&???
  288. ????????????after(th->seq,?sk->acked_seq)?&&?!th->rst)??
  289. ????????{??
  290. ?????????????seq=sk->write_seq;??
  291. ????????????(sk->debug)??
  292. ????????????????printk();??
  293. ????????????tcp_statistics.TcpEstabResets++;?????????
  294. ????????????sk->rmem_alloc?-=?skb->mem_len;??
  295. ????????????skb->sk?=?NULL;??
  296. ????????????sk->err=ECONNRESET;??
  297. ????????????tcp_set_state(sk,?TCP_CLOSE);??
  298. ????????????sk->shutdown?=?SHUTDOWN_MASK;??
  299. ????????????release_sock(sk);??
  300. ????????????sk=get_sock(&tcp_prot,?daddr);??
  301. ?????????????(sk?&&?sk->state==TCP_LISTEN)??
  302. ????????????{??
  303. ????????????????sk->inuse=1;??
  304. ????????????????skb->sk?=?sk;??
  305. ????????????????sk->rmem_alloc?+=?skb->mem_len;??
  306. ????????????????tcp_conn_request(sk,seq+128000);??
  307. ????????????????release_sock(sk);??
  308. ?????????????????0;??
  309. ????????????}??
  310. ????????????kfree_skb(skb,?FREE_READ);??
  311. ?????????????0;??
  312. ????????}??
  313. ??
  314. ????}??
  315. ??
  316. ?????
  317. ?
  318. ?
  319. ?
  320. ??
  321. ??????
  322. ????(!tcp_sequence(sk,len,dev))??
  323. ????{??
  324. ????????kfree_skb(skb,?FREE_READ);??
  325. ????????release_sock(sk);??
  326. ?????????0;??
  327. ????}??
  328. ??
  329. ????(th->rst)??
  330. ?????????tcp_std_reset(sk,skb);??
  331. ??????
  332. ?????
  333. ?
  334. ??
  335. ???????
  336. ????(th->syn?&&?!syn_ok)??
  337. ????{??
  338. ????????tcp_reset(daddr,?skb->ip_hdr->tos,?255);??
  339. ?????????tcp_std_reset(sk,skb);?????
  340. ????}??
  341. ??
  342. ?????
  343. ?
  344. ??
  345. ???????
  346. ??
  347. ????(th->ack?&&?!tcp_ack(sk,len))??
  348. ????{??
  349. ?????????
  350. ?
  351. ??
  352. ???????????
  353. ????????(sk->state==TCP_SYN_RECV)??
  354. ????????{??
  355. ????????????tcp_reset(daddr,sk->ip_ttl);??
  356. ????????}??
  357. ????????kfree_skb(skb,?FREE_READ);??
  358. ????????release_sock(sk);??
  359. ?????????0;??
  360. ????}??
  361. ??????
  362. rfc_step6:????????
  363. ??
  364. ?????
  365. ?
  366. ??
  367. ??????????
  368. ????(tcp_urg(sk,?len))??
  369. ????{??
  370. ????????kfree_skb(skb,?FREE_READ);??
  371. ????????release_sock(sk);??
  372. ?????????0;??
  373. ????}??
  374. ??????
  375. ??????
  376. ?????
  377. ?
  378. ??
  379. ??????
  380. ????(tcp_data(skb,?FREE_READ);??
  381. ????????release_sock(sk);??
  382. ?????????0;??
  383. ????}??
  384. ??
  385. ?????
  386. ?
  387. ???
  388. ??????
  389. ????release_sock(sk);??
  390. ?????0;??
  391. }??

4、应用层

当用户需要接收数据时,首先根据文件描述符inode得到socket结构和sock结构,然后从sock结构中指向的队列recieve_queue中读取数据包,将数据包COPY到用户空间缓冲区。数据就完整的从硬件中传输到用户空间。这样也完成了一次完整的从下到上的传输。

下篇:

在博文中分析了数据包从网卡设备经过驱动链路层,网络层,传输层到应用层的过程。

本文就分析一下本机产生数据是如何通过传输层,网络层到达物理层的。

综述来说,数据流程图如下:

一、应用层

应用层可以通过系统调用或文件操作来调用内核函数,BSD层的sock_write()函数会调用INET层的inet_wirte()函数。

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ?
  1. ?
  2. ?
  3. ??
  4. ??
  5. ??sock_write(?inode?*inode,??file?*file,??*ubuf,??size)??
  6. {??
  7. ?????socket?*sock;??
  8. ?????err;??
  9. ??????
  10. ?????(!(sock?=?socki_lookup(inode)))???
  11. ????{??
  12. ????????printk();??
  13. ????????(-EBADF);??
  14. ????}??
  15. ??
  16. ?????(sock->flags?&?SO_ACCEPTCON)???
  17. ????????(-EINVAL);??
  18. ??????
  19. ????(size<0)??
  20. ?????????-EINVAL;??
  21. ????(size==0)??
  22. ?????????0;??
  23. ??????????
  24. ?????((err=verify_area(VERIFY_READ,ubuf,size))<0)??
  25. ?????????err;??
  26. ????(sock->ops->write(sock,?ubuf,?size,(file->f_flags?&?O_NONBLOCK)));??
  27. }??

INET层会调用具体传输层协议的write函数,该函数是通过调用本层的inet_send()函数实现功能的,inet_send()函数的UDP协议对应的函数为udp_write()

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ??inet_send(?socket?*sock,??*ubuf,??size,??noblock,???
  1. ???????????unsigned?flags)??
  2. {??
  3. ?????sock?*sk?=?(?sock?*)?sock->data;??
  4. ?????(sk->shutdown?&?SEND_SHUTDOWN)???
  5. ????{??
  6. ????????send_sig(SIGPIPE,?current,?1);??
  7. ????????(-EPIPE);??
  8. ????}??
  9. ????(sk->err)??
  10. ?????????inet_error(sk);??
  11. ??????
  12. ????(inet_autobind(sk)!=0)??
  13. ????????(-EAGAIN);??
  14. ????(sk->prot->write(sk,?(unsigned??*)?ubuf,?noblock,?flags));??
  15. }??
  16. ??
  17. ??inet_write(?socket?*sock,??noblock)??
  18. {??
  19. ?????inet_send(sock,size,noblock,0);??
  20. }??

二、传输层

在传输层udp_write()函数调用本层的udp_sendto()函数完成功能。

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ?
  1. ?
  2. ??
  3. ??
  4. ??udp_write(?sock?*sk,?unsigned??*buff,??len,??
  5. ??????unsigned?flags)??
  6. {??
  7. ????(udp_sendto(sk,?buff,?flags,?NULL,?0));??
  8. }??

udp_send()函数完成sk_buff结构相应的设置和报头的填写后会调用udp_send()来发送数据。具体的实现过程后面会详细分析。

而在udp_send()函数中,最后会调用ip_queue_xmit()函数,将数据包下放的网络层。

下面是udp_prot定义:

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ?proto?udp_prot?=?{??
  1. ????sock_wmalloc,??
  2. ????sock_rmalloc,??
  3. ????sock_wfree,??
  4. ????sock_rfree,??
  5. ????sock_rspace,??
  6. ????sock_wspace,??
  7. ????udp_close,??
  8. ????udp_read,??
  9. ????udp_write,??
  10. ????udp_sendto,??
  11. ????udp_recvfrom,??
  12. ????ip_build_header,??
  13. ????udp_connect,??
  14. ????NULL,??
  15. ????ip_queue_xmit,??
  16. ????NULL,??
  17. ????udp_rcv,??
  18. ????datagram_select,??
  19. ????udp_ioctl,??
  20. ????ip_setsockopt,??
  21. ????ip_getsockopt,??
  22. ????128,??
  23. ????0,??
  24. ????{NULL,},??
  25. ????,??
  26. ????0,?0??
  27. };??

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ??udp_send(?sock?*sk,??sockaddr_in?*sin,??
  1. ?????unsigned??*from,??rt)??
  2. {??
  3. ?????sk_buff?*skb;??
  4. ?????device?*dev;??
  5. ?????udphdr?*uh;??
  6. ????unsigned??*buff;??
  7. ????unsigned??saddr;??
  8. ?????size,?tmp;??
  9. ?????ttl;??
  10. ????
  11. ?????
  12. ?
  13. ??
  14. ???????
  15. ????........................??
  16. ??
  17. ?????
  18. ?
  19. ??
  20. ???????
  21. ????..........................??
  22. ?????
  23. ?
  24. ??
  25. ???????
  26. ????..............................??
  27. ??
  28. ?????
  29. ?
  30. ??
  31. ???????
  32. ????memcpy_fromfs(buff,?from,?len);??
  33. ??
  34. ?????
  35. ?
  36. ??
  37. ???????
  38. ????udp_send_check(uh,?sin->sin_addr.s_addr,?skb->len?-?tmp,?sk);??
  39. ??
  40. ?????
  41. ?
  42. ??
  43. ???????
  44. ????udp_statistics.UdpOutDatagrams++;??
  45. ???????
  46. ????sk->prot->queue_xmit(sk,?1);??
  47. ????(len);??
  48. }??

三、网络层

?在网络层,函数ip_queue_xmit()的功能是将数据包进行一系列复杂的操作,比如是检查数据包是否需要分片,是否是多播等一系列检查,最后调用dev_queue_xmit()函数发送数据。

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ?
  1. ?
  2. ?
  3. ?
  4. ?
  5. ?
  6. ?
  7. ??
  8. ??
  9. ?ip_queue_xmit(?sock?*sk,??
  10. ???????????sk_buff?*skb,??free)??
  11. {??
  12. ?????iphdr?*iph;??
  13. ????unsigned??*ptr;??
  14. ??
  15. ??????
  16. ????............??
  17. ?????
  18. ?
  19. ??
  20. ??
  21. ??
  22. ????...........??
  23. ??
  24. ?????
  25. ?
  26. ?
  27. ?
  28. ip_hdr?to?avoid?this?mess?and?the?fixed?
  29. ?
  30. ??
  31. ??
  32. ????..............??
  33. ?????
  34. ?
  35. ??
  36. ??
  37. ????(free!=2)??
  38. ????????iph->id??????=?htons(ip_id_count++);??
  39. ??????
  40. ????????free=1;??
  41. ??
  42. ??????
  43. ?????(sk?==?NULL)??
  44. ????????free?=?1;??
  45. ??
  46. ????skb->free?=?free;??
  47. ??
  48. ?????
  49. ?
  50. ?
  51. ?
  52. ??
  53. ??
  54. ????................??
  55. ??
  56. ?????
  57. ?
  58. ??
  59. ??
  60. ????ip_send_check(iph);??
  61. ??
  62. ?????
  63. ?
  64. ??
  65. ??
  66. ?????
  67. ?
  68. ?
  69. ??
  70. ????.......................??
  71. ??
  72. ?????
  73. ?
  74. ?
  75. ?
  76. ?
  77. ??
  78. ??
  79. ????......................??
  80. ?????
  81. ?
  82. ??
  83. ???????
  84. ????ip_statistics.IpOutRequests++;??
  85. ????????.............................??
  86. ????.............................??
  87. ????????((dev->flags&IFF_BROADCAST)?&&?iph->daddr==dev->pa_brdaddr?&&?!(dev->flags&IFF_LOOPBACK))??
  88. ????????ip_loopback(dev,skb);??
  89. ??????????
  90. ?????(dev->flags?&?IFF_UP)??
  91. ????{??
  92. ?????????
  93. ?
  94. ?
  95. ??
  96. ??
  97. ?????????(sk?!=?NULL)??
  98. ????????{??
  99. ????????????dev_queue_xmit(skb,?sk->priority);??
  100. ????????}??
  101. ??????????
  102. ????????{??
  103. ????????????dev_queue_xmit(skb,?SOPRI_NORMAL);??
  104. ????????}??
  105. ????}??
  106. ??????
  107. ????{??
  108. ????????ip_statistics.IpOutDiscards++;??
  109. ?????????(free)??
  110. ????????????kfree_skb(skb,?FREE_WRITE);??
  111. ????}??
  112. }??

四、驱动层(链路层)

在函数中,函数调用会调用具体设备的发送函数来发送数据包

dev->hard_start_xmit(skb,dev);

具体设备的发送函数在网络初始化的时候已经设置了。

这里以8390网卡为例来说明驱动层的工作原理,在net/drivers/8390.c中函数ethdev_init()函数中设置如下:

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7545855"&gt;copy

?
    ??
  1. ?ethdev_init(?device?*dev)??
  2. {??
  3. ?????(ei_debug?>?1)??
  4. ????????printk(version);??
  5. ??????
  6. ?????(dev->priv?==?NULL)?{??
  7. ?????????ei_device?*ei_local;??
  8. ??????????
  9. ????????dev->priv?=?kmalloc((?ei_device),?GFP_KERNEL);??
  10. ????????memset(dev->priv,?(?ei_device));??
  11. ????????ei_local?=?(?ei_device?*)dev->priv;??
  12. ??
  13. ????????ei_local->pingpong?=?1;??
  14. ??
  15. ????}??
  16. ??????
  17. ??????
  18. ?????(dev->open?==?NULL)??
  19. ????????dev->open?=?&ei_open;??
  20. ????stop?entry?also.?*/??
  21. ????dev->hard_start_xmit?=?&ei_start_xmit;??
  22. ????dev->get_stats???=?get_stats;??
  23. ??
  24. ????dev->set_multicast_list?=?&set_multicast_list;??
  25. ??
  26. ??
  27. ????ether_setup(dev);??
  28. ??????????
  29. ?????0;??
  30. }??

驱动中的发送函数比较复杂,和硬件关系紧密,这里不再详细分析。

这样就大体分析了下网络数据从应用层到物理层的数据通路,后面会详细分析。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读