﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-LIULIANG-随笔分类-网络协议</title><link>http://www.cppblog.com/LIULIANG/category/19031.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 06 Jan 2013 20:38:09 GMT</lastBuildDate><pubDate>Sun, 06 Jan 2013 20:38:09 GMT</pubDate><ttl>60</ttl><item><title>浅谈Radius协议 </title><link>http://www.cppblog.com/LIULIANG/archive/2013/01/06/197021.html</link><dc:creator>BIG森林</dc:creator><author>BIG森林</author><pubDate>Sun, 06 Jan 2013 08:52:00 GMT</pubDate><guid>http://www.cppblog.com/LIULIANG/archive/2013/01/06/197021.html</guid><wfw:comment>http://www.cppblog.com/LIULIANG/comments/197021.html</wfw:comment><comments>http://www.cppblog.com/LIULIANG/archive/2013/01/06/197021.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LIULIANG/comments/commentRss/197021.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LIULIANG/services/trackbacks/197021.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt"><strong><span style="font-family: 黑体; font-size: 12pt">一．RADIUS协议原理</span></strong></p>
<p style="text-indent: 21pt"><strong></strong>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 'Times New Roman'; font-size: 10.5pt">RADIUS</span><span style="font-family: 宋体; font-size: 10.5pt">（</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">Remote Authentication Dial In User Service</span><span style="font-family: 宋体; font-size: 10.5pt">）</span> <span style="font-family: 宋体; font-size: 10.5pt">用户远程拨入认证服务，<span style="font-family: 宋体">它主要针对的远程登录类型有：</span><span style="font-family: Times New Roman">SLIP</span><span style="font-family: 宋体">、<span style="font-family: Times New Roman">PPP</span></span><span style="font-family: 宋体">、<span style="font-family: Times New Roman">telnet</span></span><span style="font-family: 宋体">和<span style="font-family: Times New Roman">rlogin</span></span><span style="font-family: 宋体">等。</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">协议应用范围很广，包括普通电话、上网业务计费，对</span><span style="font-family: Times New Roman">VPN</span><span style="font-family: 宋体">的支持可以使不同的拨入服务器的用户具有不同权限。</span></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">典型应用环境如下：</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img alt="radius典型应用" src="http://p.blog.csdn.net/images/p_blog_csdn_net/cjx1986/EntryImages/20090831/clip_image002.jpg" width="465" height="230" /></span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 20.6pt"><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">数据包分为</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">5</span></span><span style="font-family: 宋体">个部分：</span></p>
<p style="text-align: left; text-indent: -36pt; margin: 0cm 0cm 0pt 57pt" align="left"><span style="font-family: Times New Roman"><span style="font-family: DY168+ZEFA21-171">（1）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: DY168+ZEFA21-171">Code:1</span></span><span style="font-family: 宋体">个字节，用于区分</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">RADIUS</span></span><span style="font-family: 宋体">包的类型：常用类型有：</span></p>
<p align="left"><span style="font-family: 宋体">接入请求（</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Access-Request</span></span><span style="font-family: 宋体">），</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Code=1</span></span><span style="font-family: 宋体">；接入允许（</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Access-Accept</span></span><span style="font-family: 宋体">），</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Code=2</span></span><span style="font-family: 宋体">；接入拒绝（</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Access-Reject</span></span><span style="font-family: 宋体">），</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Code=3</span></span><span style="font-family: 宋体">；计费请求（</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Accounting-Request</span></span><span style="font-family: 宋体">），</span><span style="font-family: DY168+ZEFA21-171"><span style="font-family: Times New Roman">Code=4</span></span><span style="font-family: 宋体">等。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">2</span><span style="font-family: 宋体">）</span><span style="font-family: Times New Roman">Identifier:</span><span style="font-family: 宋体">一个字节，用于请求和应答包的匹配。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">3</span><span style="font-family: 宋体">）</span><span style="font-family: Times New Roman">Length:</span><span style="font-family: 宋体">两个字节，表示</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">数据区（包括</span><span style="font-family: Times New Roman">Code, Identifier, Length, Authenticator, Attributes</span><span style="font-family: 宋体">）的长度，单位是字节，最小为</span><span style="font-family: Times New Roman">20</span><span style="font-family: 宋体">，最大为</span><span style="font-family: Times New Roman">4096</span><span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">4</span><span style="font-family: 宋体">）</span><span style="font-family: Times New Roman">Authenticator:16</span><span style="font-family: 宋体">个字节，用于验证服务器端的应答，另外还用于用户口令的加密。</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器和</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">的共享密钥(</span><span style="font-family: Times New Roman">Shared Secret)</span><span style="font-family: 宋体">与请求认证码(</span><span style="font-family: Times New Roman">Request Authenticator)</span><span style="font-family: 宋体">和应答认证码</span><span style="font-family: Times New Roman">(Response Authenticator)</span><span style="font-family: 宋体">，共同支持发、收报文的完整性和认证。另外，用户密码不能在</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">和</span><span style="font-family: Times New Roman">RADIUS </span><span style="font-family: 宋体">服务器之间用明文传输，而一般使用共享密钥(</span><span style="font-family: Times New Roman">Shared Secret)</span><span style="font-family: 宋体">和认证码(</span><span style="font-family: Times New Roman">Authenticator)</span><span style="font-family: 宋体">通过</span><span style="font-family: Times New Roman">MD5</span><span style="font-family: 宋体">加密算法进行加密隐藏。</span></p>
<p style="text-indent: 20.6pt"><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">5</span><span style="font-family: 宋体">）</span><span style="font-family: Times New Roman">Attributes:</span><span style="font-family: 宋体">不定长度，最小可为</span><span style="font-family: Times New Roman">0</span><span style="font-family: 宋体">个字节，描述</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">协议的属性，如用户名、口令、</span><span style="font-family: Times New Roman">IP</span><span style="font-family: 宋体">地址等信息都是存放在本数据段。</span></p>
<p style="text-indent: 20.6pt"><span style="font-family: 宋体">各个属性的详细编码信息，以及数据格式，限于篇幅，这里不作具体介绍，感兴趣的，可以参看</span><span style="font-family: Times New Roman">RFC</span><span style="font-family: 宋体">文档，或与我交流。</span></p>
<p style="text-indent: 20.6pt">&nbsp;</p>
<p style="text-indent: 20.6pt"><strong><span style="font-family: 黑体; font-size: 12pt">二．RADIUS协议实现</span></strong></p>
<p style="text-indent: 20.6pt"><strong></strong>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">目前，开源软件包</span><span style="font-family: Times New Roman">freeRadius , tinyRadius</span><span style="font-family: 宋体">，可以下载到其实现的源码。</span><span style="font-family: Times New Roman">freeRadius</span><span style="font-family: 宋体">是目前功能最强大的开源</span><span style="font-family: Times New Roman"> RADIUS </span><span style="font-family: 宋体">服务器软件，采用</span><span style="font-family: Times New Roman">C</span><span style="font-family: 宋体">语言实现，采用了多进程，进程池的处理方法，拥有很好的吞吐处理能力，同时，提供了连接各种数据库的应用接口，方便用户根据自己的需要进行适当的扩展。值得一提的是，它采用模块化处理，用户可以定做适合自己的认证计费处理模块。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">freeRadius</span><span style="font-family: 宋体">的功能强大，也造成了它模块的庞大，不易维护，对安装环境有一些要求。</span><span style="font-family: Times New Roman">tinyRadius</span><span style="font-family: 宋体">采用</span><span style="font-family: Times New Roman">Java</span><span style="font-family: 宋体">开发，短小精悍，能接收各种标准协议中的数据包，可以快速的完成对</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">数据包的封装与解包，我们可以自己的需要进行某些处理，具有很大的自由度，唯一的缺陷是单线程，没有数据库接口。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><strong><span style="font-family: 黑体; font-size: 12pt">三．RADIUS协议对安全的考虑</span></strong></p>
<p style="text-indent: 21pt"><strong></strong>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">采用</span><span style="font-family: Times New Roman">UDP</span><span style="font-family: 宋体">协议基于以下几点原因：</span></p>
<p style="text-indent: -18pt; margin: 0cm 0cm 0pt 39pt"><span style="font-family: Times New Roman"><span>1．&nbsp;</span>NAS</span><span style="font-family: 宋体">和</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器大多在同一个局域网中，使用</span><span style="font-family: Times New Roman">UDP</span><span style="font-family: 宋体">更加快捷方便。</span></p>
<p style="text-indent: -18pt; margin: 0cm 0cm 0pt 39pt"><span style="font-family: Times New Roman">2．&nbsp;</span><span style="font-family: 宋体">简化了服务端的实现。</span></p>
<p style="margin: 0cm 0cm 0pt 21pt"><span style="font-family: 宋体">事实证明，采用</span><span style="font-family: Times New Roman">UDP</span><span style="font-family: 宋体">协议可行，</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">有自己的机制，来解决</span><span style="font-family: Times New Roman">UDP</span><span style="font-family: 宋体">丢包特点。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如果</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">向某个</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器提交请求没有收到返回信息，那么可以要求备份</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器重传。由于有多个备份</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器，因此</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">进行重传的时候，可以采用轮询的方法。如果备份</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器的密钥和以前</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器的密钥不同，则需要重新进行认证。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">下面重点从</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">协议来谈下它在身份认证中如何确保安全认证的。</span></p>
<p style="text-indent: -18pt; margin: 0cm 0cm 0pt 39pt"><span style="font-family: Times New Roman"><span>1．&nbsp;</span><span>Authenticator</span></span><span style="font-family: 宋体">：鉴别码，分为请求鉴别码，回应鉴别码。</span><span style="font-family: Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在<span style="font-family: Times New Roman">&#8220;Access-Request&#8221;</span></span><span style="font-family: 宋体">数据包中，<span style="font-family: Times New Roman">Authenticator</span></span><span style="font-family: 宋体">是一个<span style="font-family: Times New Roman">16</span></span><span style="font-family: 宋体">字节的随机数，称为<span style="font-family: Times New Roman">&#8220;Request Authenticator&#8221;</span></span><span style="font-family: 宋体">。</span> <span style="font-family: 宋体">在机密的整个生存周期中（如</span><span style="font-family: Times New Roman">RADIUAS</span><span style="font-family: 宋体">服务器和客户端共享的机密），这个值应该是不可预测的，并且是唯一的，因为具有相同密码的重复请求值，使黑客有机会用已截取的响应回复用户</span><span style="font-family: 宋体">。</span><span style="font-family: 宋体">因为同一机密可以被用在不同地理区域中的服务器的验证中，所以请求认证域应该具有全球和临时唯一性。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为防止数据包中数据被截获被篡改，回应鉴别码采用如下方式生成：</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">ResponseAuth = MD5(Code+ID+Length+RequestAuth+ Attributes+Secret)</span><span style="font-family: 宋体">；</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">回应鉴别码是对整个数据包进行</span><span style="font-family: Times New Roman">MD5</span><span style="font-family: 宋体">演算产生的</span><span style="font-family: Times New Roman">16</span><span style="font-family: 宋体">字节索引，防止伪造服务器的回应。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">2</span><span style="font-family: 宋体">．加密方式。</span><span style="font-family: Times New Roman">PAP</span><span style="font-family: 宋体">，</span><span style="font-family: Times New Roman">CAHP</span><span style="font-family: 宋体">，</span><span style="font-family: Times New Roman">EAP</span><span style="font-family: 宋体">以及</span><span style="font-family: Times New Roman">Unix</span><span style="font-family: 宋体">登录认证三种加密认证方式。最常用的是前两种，下面介绍下：</span></p>
<p style="text-indent: 21pt"><strong><span style="font-family: Times New Roman">PAP</span></strong><strong><span style="font-family: 宋体">加密</span></strong><span style="font-family: 宋体">，采用此加密方法时，密码存放在</span><span style="font-family: Times New Roman">User-Password</span><span style="font-family: 宋体">属性中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">User-Password</span><span style="font-family: 宋体">加密方法：</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">1.</span><span style="font-family: 宋体">在密码的末尾用</span><span style="font-family: Times New Roman">nulls</span><span style="font-family: 宋体">代替填补形成多个十六个字节的二进制数</span><span style="font-family: Times New Roman">;</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">2.</span><span style="font-family: 宋体">把密码按</span><span style="font-family: Times New Roman">16</span><span style="font-family: 宋体">个字节为一组划分为</span><span style="font-family: Times New Roman">p1</span><span style="font-family: 宋体">、</span><span style="font-family: Times New Roman">p2</span><span style="font-family: 宋体">等等</span><span style="font-family: Times New Roman">; </span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">&nbsp;b1=MD5(Secret + Authenticator)&nbsp;c(1) = p1 </span><span style="font-family: 宋体">异或</span><span style="font-family: Times New Roman"> b1</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">&nbsp;b2 = MD5(S + c(1))<span>&nbsp;&nbsp;&nbsp;&nbsp; c(2) = p2 </span></span><span style="font-family: 宋体">异或</span><span style="font-family: Times New Roman">b2 </span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">&nbsp;bi = MD5(S + c(i-1))<span>&nbsp;&nbsp; c (i) = pi </span></span><span style="font-family: 宋体">异或</span><span style="font-family: Times New Roman"> bi</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">c(1)+c(2)+...+c (i) </span></p>
<p style="text-indent: 21pt"><span>&nbsp;</span><span style="font-family: 宋体">在接收时，这个过程被反过来，由于采用异或方式贯穿在每</span><span style="font-family: Times New Roman">16</span><span style="font-family: 宋体">个字节之间，同样的算法再异或一次，然后配合</span><span style="font-family: Times New Roman">MD5</span><span style="font-family: 宋体">演算，从而生成原始的密码，尽管这种加密方式是可逆的，黑客截获到密文后，能通过一定的手段来破解出密码，但如果共享密钥未知的情况下，很难破解，也就只能采用蛮力破解方法。使用共享密钥应采用合适的长度，来防止破解，不应过短。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="font-family: Times New Roman">PAP</span><span style="font-family: 宋体">加密方法使密码以密文的方式在网络中进行传输，使黑客仍有有机可乘的机会，但</span><span style="font-family: Times New Roman">CHAP</span><span style="font-family: 宋体">加密方法阻止了密码的传输。</span></p>
<p style="text-indent: 21pt"><strong><span style="font-family: Times New Roman">CHAP</span></strong><strong><span style="font-family: 宋体">加密</span></strong><span style="font-family: 宋体">，采用此加密方法时，密码存放在</span><span style="font-family: Times New Roman">Chap-Password</span><span style="font-family: 宋体">属性中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这种加密方法的原则是不是密码在网络中进行传输，而只是传输一个索引值，从而增加了安全性，但这样做的代价是，</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务端必须要知道用户的密码，从而再现密码索引值来和发来的认证请求中的密码索引值比对。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">Chap-Password</span><span style="font-family: 宋体">加密方法：</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">Md5(chapId+password+chapChallenge);</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">chapId :</span><span style="font-family: 宋体">可以是随机产生的一字节码；</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">chapChallenge&nbsp;:NAS</span><span style="font-family: 宋体">生成一个随机挑战字（</span><span style="font-family: Times New Roman">16</span><span style="font-family: 宋体">个字节比较合适）</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</span></span><span style="font-family: 宋体">该字段有时缺失，读取</span><span style="font-family: Times New Roman">Authenticator</span><span style="font-family: 宋体">域作为挑战字。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">3</span><span style="font-family: 宋体">．共享密钥（</span><span style="font-family: Times New Roman">Secret</span><span style="font-family: 宋体">）：共享密钥在密码加密以及数据包的鉴别码部分都参与了运算，即使</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">数据包被截获，但不知道共享密钥，很难破解用户的密码伪造数据。共享密钥应采用合适的长度，不应过短，</span><span style="font-family: 宋体">宽大密码范围能有效提供对穷举搜寻攻击的防卫，</span><span style="font-family: 宋体">随着密钥长度的增加，其破解花费的时间将大大增加。</span></p>
<p style="text-indent: 21pt">4．为防止非法用户的重放攻击，造成服务器瘫痪。如果在一个很短的时间片段里，一个请求有相同的客户源IP地址、源UDP端口号和标识符，RADIUS服务器会认为这是上一个重复的请求，将直接丢弃，不做任何处理。</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><strong><span style="font-family: 黑体; font-size: 12pt">四．总结</span></strong></p>
<p style="text-indent: 21pt"><strong></strong>&nbsp;</p>
<p style="text-indent: 21pt">Radius协议本身比较易掌握，在应用中，可以结合其自身的密码方式，实现满足企业需要的更高强度的强认证，比如结合各种令牌卡，手机短信等等。对协议进行开发，离不开各种抓包工具，像sniffer,tcpdump,ethereal等抓包工具的使用。</p>
<p>&nbsp;</p>
<p style="text-indent: 20.6pt"><span style="font-family: 宋体">外部用户要访问某局域网络中计算机设备，其访问方式有多种，比如采用</span><span style="font-family: Times New Roman">VPN</span><span style="font-family: 宋体">拨号，</span><span style="font-family: Times New Roman">Telnet</span><span style="font-family: 宋体">等等。如用户</span><span style="font-family: Times New Roman">Telnet</span><span style="font-family: 宋体">登陆时，产生用户名和密码信息，而</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">服务器</span><span style="font-family: Times New Roman">AAA</span><span style="font-family: 宋体">配置中指定了采用</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">作为认证服务器，则</span><span style="font-family: 宋体">将其封装成</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">请求数据包发送到</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器进行身份认证，</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器通过</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">和用户进行交流，以提示用户认证通过与否，以及是否需要</span><span style="font-family: Times New Roman">Challenge</span><span style="font-family: 宋体">身份认证。</span></p>
<p style="text-indent: 20.6pt">&nbsp;</p>
<p style="text-indent: 20.6pt"><span style="font-family: 宋体">其工作原理为：用户接入</span><span style="font-family: Times New Roman">NAS </span><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">Net Access Server</span><span style="font-family: 宋体">），</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">一般为路由器等设备，</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">向</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器使用</span><span style="font-family: Times New Roman">Access-Request</span><span style="font-family: 宋体">数据包提交用户信息，包括用户名、密码等相关信息，其中用户密码是经过</span><span style="font-family: Times New Roman">MD5</span><span style="font-family: 宋体">加密的，双方使用共享密钥，这个密钥不经过网络传播；</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器对用户名和密码的合法性进行检验，必要时可以提出一个</span><span style="font-family: Times New Roman">Challenge</span><span style="font-family: 宋体">，要求进一步对用户认证，也可以对</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">进行类似的认证；如果合法，给</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">返回</span><span style="font-family: Times New Roman">Access-Accept</span><span style="font-family: 宋体">数据包，允许用户进行下一步工作，否则返回</span><span style="font-family: Times New Roman">Access-Reject</span><span style="font-family: 宋体">数据包，拒绝用户访问；如果允许访问，</span><span style="font-family: Times New Roman">NAS</span><span style="font-family: 宋体">向</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器提出计费请求</span><span style="font-family: Times New Roman">Account-Require</span><span style="font-family: 宋体">，</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器响应</span><span style="font-family: Times New Roman">Account-Accept</span><span style="font-family: 宋体">，对用户的计费开始，同时用户可以进行自己的相关操作。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">还支持代理和漫游功能。简单地说，代理就是一台服务器，可以作为其他</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器的代理，负责转发</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">认证和计费数据包。所谓漫游功能，就是代理的一个具体实现，这样可以让用户通过本来和其无关的</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">服务器进行认证。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">能够实现其功能依赖于它自身的数据包结构。</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">采用的是</span><span style="font-family: Times New Roman">UDP</span><span style="font-family: 宋体">传输协议，认证和计费监听端口一般分别为：</span><span style="font-family: Times New Roman">1812</span><span style="font-family: 宋体">，</span><span style="font-family: Times New Roman">1813</span><span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">以太网上的</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">封装后的包结构如下：</span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"></p>
<table style="border-bottom: medium none; border-left: medium none; margin: auto auto auto 23.4pt; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 81pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="108">
<p style="text-indent: 10.5pt"><span style="font-size: small"><span style="font-family: 宋体">以太帧头</span></span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 63pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="84">
<p style="text-indent: 10.5pt"><span style="font-size: small"><span style="font-family: Times New Roman">IP</span><span style="font-family: 宋体">包头</span></span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 72pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="96">
<p><span style="font-size: small"><span style="font-family: Times New Roman">UDP</span><span style="font-family: 宋体">包头</span></span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 90pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="120">
<p><span style="font-size: small"><span style="color: red"><span style="font-family: Times New Roman">RADIUS</span></span><span style="font-family: 宋体; color: red">数据包</span></span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 72pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="96">
<p><span style="font-size: small"><span style="font-family: 宋体">以太网</span><span style="font-family: Times New Roman">FCS</span></span></p></td></tr></tbody></table>
<p>&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这里我们关心的是红色</span><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">数据包部分。</span></p>
<p style="text-indent: 21pt"><span style="font-family: Times New Roman">RADIUS</span><span style="font-family: 宋体">数据包的格式如下：</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><img alt="radius数据包格式" src="http://p.blog.csdn.net/images/p_blog_csdn_net/cjx1986/EntryImages/20090831/2.gif" width="512" height="172" /><br /><br /><br />转自：<a href="http://blog.csdn.net/cjx1986/article/details/4503524#comments">http://blog.csdn.net/cjx1986/article/details/4503524#comments</a></p><img src ="http://www.cppblog.com/LIULIANG/aggbug/197021.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LIULIANG/" target="_blank">BIG森林</a> 2013-01-06 16:52 <a href="http://www.cppblog.com/LIULIANG/archive/2013/01/06/197021.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网卡工作原理</title><link>http://www.cppblog.com/LIULIANG/archive/2012/11/22/195561.html</link><dc:creator>BIG森林</dc:creator><author>BIG森林</author><pubDate>Thu, 22 Nov 2012 10:01:00 GMT</pubDate><guid>http://www.cppblog.com/LIULIANG/archive/2012/11/22/195561.html</guid><wfw:comment>http://www.cppblog.com/LIULIANG/comments/195561.html</wfw:comment><comments>http://www.cppblog.com/LIULIANG/archive/2012/11/22/195561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LIULIANG/comments/commentRss/195561.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LIULIANG/services/trackbacks/195561.html</trackback:ping><description><![CDATA[<div style="layout-grid:  15.6pt none">
<p align="center"><strong><span style="font-family: 黑体; font-size: 15pt">网卡工作原理</span></strong></p>
<p style="text-indent: 21pt">Linux<span style="font-family: 宋体">操作系统的功能可以概括为进程管理、内存管理、文件系统管理、设备管理、网络等几部分。所有的系统操作最终都可以映射到对物理设备的操作。除去对</span>CPU<span style="font-family: 宋体">、内存以及其他少数几个物理实体的操作之外，系统对其他设备的所有操作都通过专门的称为驱动程序的代码完成。系统中存在的每种外设在内核中都必须有对应的设备驱动程序对其进行处理。所以分析网卡的工作原理即是分析网卡的驱动程序。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">网络是独立的一个模块。为了屏蔽网络环境中物理网络设备的多样性，</span>Linux<span style="font-family: 宋体">对所有的设备进行抽象并定义了一个统一的概念，称之为接口。所有对网络硬件的访问都是通过接口进行的，接口提供了一个对所有类型的硬件一致化的操作集合来处理基本数据发送和接收。一个网络接口被看作是一个发送和接收数据包的实体。对于每个网络接口，都用一个</span>net_device<span style="font-family: 宋体">的数据结构来表示。</span>net_device<span style="font-family: 宋体">中有很多提供系统访问和协议层调用的设备方法，包括提供设备初始化和往系统注册用的</span>init<span style="font-family: 宋体">函数，打开和关闭网络设备的</span>open<span style="font-family: 宋体">和</span>stop<span style="font-family: 宋体">函数，处理数据包发送的函数</span>hard_start_xmit<span style="font-family: 宋体">，以及中断处理函数。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">所有被发送和接收的包都用数据结构</span>sk_buff<span style="font-family: 宋体">表示。要发送数据时，网络系统将分局系统路由表选择相应的网络接口进行数据传输；当接收数据包时，通过驱动程序登记的中断服务程序进行数据的接口处理。</span></p>
<p style="text-indent: 21pt">Linux<span style="font-family: 宋体">网络驱动程序崇尚倒下分为四层：协议接口层、网络设备接口层、设备驱动功能层、网络设备和网络媒介层。如下图所示：</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><span style="font-size: 10.5pt" times="" new=""  ar-sa?="" 1.0pt;?? roman?;??><a href="http://blog.chinaunix.net/attachment/201102/27/23208702_1298783439GKfa.jpg" target="_blank"><img border="0" src="http://blog.chinaunix.net/attachment/201102/27/23208702_1298783439GKfa.jpg"  ;="" load="imgResize(this, 650);"  .  alt="" /></a> </span></span></p>
<p align="center"></p>
<p><strong><span style="font-family: 黑体; font-size: 14pt">网卡初始化</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">网络设备初始化主要工作时检测设备的存在、初始化描述设备的</span>net_device<span style="font-family: 宋体">结构及在系统中登记该设备。在系统初始化完成以后，系统检测到的网络设备将保存在链表</span>dev_base<span style="font-family: 宋体">中，其中每个链表单元</span>net_device<span style="font-family: 宋体">对应一个存在的物理网络设备。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">初始化过程首先检测网络物理设备是否存在，这是通过检测物理设备的硬件特征来完成；然后对设备进行资源配置，这些完成之后就要构造设备的</span>net_device<span style="font-family: 宋体">数据结构，用检测到值对</span>net_device<span style="font-family: 宋体">中的变量初始化；最后</span>Linux<span style="font-family: 宋体">内核中注册该设备并申请内存空间。</span></p>
<p style="text-indent: 21.1pt"><strong>&nbsp;</strong></p>
<p><strong><span style="font-family: 黑体; font-size: 14pt">网卡的打开与关闭</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了使用网络设备，需要打开网卡，打开和关闭的一个接口是由</span>shell<span style="font-family: 宋体">命令</span>ifconfig<span style="font-family: 宋体">调用的，而</span>ifconfig<span style="font-family: 宋体">则要调用一个通用的设备打开函数</span>dev_open<span style="font-family: 宋体">（</span>net/core/dev.c<span style="font-family: 宋体">），相应的还有一个</span>dev_close<span style="font-family: 宋体">函数，这两个函数提供独立于设备的操作接口的打开和关闭功能。一般打开函数执行的操作包括注册中断函数，分配并初始化网卡所需要的接收与发送缓冲区，启动硬件检查网络连接线状态等。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p><strong><span style="font-family: 黑体; font-size: 14pt">数据包的发送与接收</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">数据包的发送和接收是实现</span>Linux<span style="font-family: 宋体">网络驱动程序中两个最关键的过程。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当物理网络设备接收到数据是，系统通过两种途径解决这个问题。一种方法是轮询方式，另一种方式是中断法师。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在轮询方式中，系统每隔一定的时间间隔就去检查一次物理设备，若设备有数据到达，就调用读取数据的程序。</span>Linux<span style="font-family: 宋体">中通过定时器实现，但是此法有一个明显的缺点：不管设备是否有数据，系统总是要固定的消耗</span>CPU<span style="font-family: 宋体">资源去查看设备，并且可能对一些紧急数据处理予以延迟。从资源的利用率以及工作的效率上看都不是最优的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">中断方式利用硬件体系结构的中断机制实现设备和系统的应答对话，即当物理设备需要</span>CPU<span style="font-family: 宋体">处理数据时，就向</span>CPU<span style="font-family: 宋体">发送一个终端信号，系统则在收到信号后调用相应的中断服务程序响应对设备中断的处理。因此，基本在所有的网络设备驱动程序中都是用中断方式的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">每一个网卡上都有一块</span>FIFO<span style="font-family: 宋体">存储器，对于</span>NIC<span style="font-family: 宋体">（</span>Network Interface Controller<span style="font-family: 宋体">），</span>FIFO<span style="font-family: 宋体">存储器是用来通过系统总线传送数据到系统存储器之前，缓存从</span>LAN<span style="font-family: 宋体">上接收到的数据。对与快速以太网还有一个直接内存存取（</span>DMA<span style="font-family: 宋体">：</span>Directly Memory Access<span style="font-family: 宋体">）控制器，用于提供对系统存储器的可靠访问。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">驱动为网卡分配一个环形缓冲区，在一段连续的物理内存中实现。</span></p>
<p style="text-indent: -18pt; margin-left: 39pt"><span>1、&nbsp;</span><span style="font-family: 宋体">数据接收</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（1）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">接收来自</span>MAC<span style="font-family: 宋体">的数据包，先暂存于片内</span>FIFO<span style="font-family: 宋体">接收队列；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（2）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当接收器达到早期接收上线时就移至环形缓冲区；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（3）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">待整个数据包全部从</span>FIFO<span style="font-family: 宋体">移至缓存后，将接收状态寄存器和包长度写入接收的数据包头部，并更新</span>CBA<span style="font-family: 宋体">（</span>Current Buffer Address<span style="font-family: 宋体">）寄存器的值；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（4）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>CMD<span style="font-family: 宋体">（</span>Command<span style="font-family: 宋体">）寄存器中的</span>BufferEmpty<span style="font-family: 宋体">位和</span>ISR<span style="font-family: 宋体">（中断状态寄存器）寄存器的</span>ROK<span style="font-family: 宋体">位置</span>1<span style="font-family: 宋体">，并发出</span>ROK<span style="font-family: 宋体">的中断；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（5）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>ISR<span style="font-family: 宋体">中断调用完成后，清除</span>ISR<span style="font-family: 宋体">（</span>ROK<span style="font-family: 宋体">）并更新</span>CAPR<span style="font-family: 宋体">（</span>Current Address of Packet Read<span style="font-family: 宋体">，指向接收缓存的已读取包的地址），完成本次接收。</span></p>
<p style="text-indent: -18pt; margin-left: 39pt"><span>2、&nbsp;</span><span style="font-family: 宋体">数据发送</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（1）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">将待传送的数据写入主存中一段连续的缓存空间，由</span>OS<span style="font-family: 宋体">配合驱动程序完成；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（2）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">找到一个可用的描述器，并写入内容，包括该数据包的开始物理地址和传输状态字（包的大小、可传送下限、</span>OWN<span style="font-family: 宋体">位）；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（3）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>OWN<span style="font-family: 宋体">位有效，将数据从缓存移至片内</span>FIFO<span style="font-family: 宋体">队列；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（4）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当</span>FIFO<span style="font-family: 宋体">队列中的数据达到早期传送下限，</span>NIC<span style="font-family: 宋体">的传送单元就会启动，将数据顺序输出至线路；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（5）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当整个数据包都已经传至</span>FIFO<span style="font-family: 宋体">，</span>OWN<span style="font-family: 宋体">位置</span>1<span style="font-family: 宋体">；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（6）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当整个数据包都已经传至线路上，</span> TOK<span style="font-family: 宋体">寄存器置</span>1<span style="font-family: 宋体">；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（7）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当</span>TOK<span style="font-family: 宋体">（</span>IMR<span style="font-family: 宋体">）和</span>TOK<span style="font-family: 宋体">（</span>ISR<span style="font-family: 宋体">）多置</span>1<span style="font-family: 宋体">，就发出</span>TOK<span style="font-family: 宋体">中断；</span></p>
<p style="text-indent: -36pt; margin-left: 57pt"><span>（8）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>TOK<span style="font-family: 宋体">中断调用完成以后，清除</span>TSD<span style="font-family: 宋体">状态字，完成本次传送。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">可以看出，网卡需要发送</span>/<span style="font-family: 宋体">接收数据，都必须以中断的方式告诉系统，系统处理中断后做出相应操作。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">网卡存在一定大小的</span>FIFO<span style="font-family: 宋体">存储器，同时还有缓冲区，缓冲区是由系统以及驱动共同分配一段连续的物理内存，所有的发送</span>/<span style="font-family: 宋体">接收的数据，都必须通过</span>FIFO<span style="font-family: 宋体">已经缓冲区，只有一包数据都发送成功后，才能继续发送下一包数据。系统维护缓冲区，只有当缓冲区有空间时才会接受上层来的数据，而网卡处理数据的速率远高于接收数据的最大速率，因此在网卡上不会存在堵塞情况。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对编程而言，在应用层调用传输层函数</span>send/sendto<span style="font-family: 宋体">，使用套接字传送数据，屏蔽了底层的所有实现。此时，</span>send/sendto<span style="font-family: 宋体">函数是没有阻塞的，只要调用，必然有返回值，成功返回发送数据的长度，失败则返回负值（失败的主要原因是网络连接的问题），因此可能存在数据丢失的现象，需要写程序的时候保证数据的传输成功。但是只有</span>send/sendto<span style="font-family: 宋体">函数返回后，程序才会执行下一次发送，因此编程时没必要考虑数据会在传输层上出现阻塞。<br /><br /><font face="Verdana">转自：<a href="http://blog.chinaunix.net/uid-25839577-id-3035405.html">http://blog.chinaunix.net/uid-25839577-id-3035405.html</a></font></span></p></div><img src ="http://www.cppblog.com/LIULIANG/aggbug/195561.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LIULIANG/" target="_blank">BIG森林</a> 2012-11-22 18:01 <a href="http://www.cppblog.com/LIULIANG/archive/2012/11/22/195561.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POP3命令列表</title><link>http://www.cppblog.com/LIULIANG/archive/2012/04/08/170429.html</link><dc:creator>BIG森林</dc:creator><author>BIG森林</author><pubDate>Sun, 08 Apr 2012 03:03:00 GMT</pubDate><guid>http://www.cppblog.com/LIULIANG/archive/2012/04/08/170429.html</guid><wfw:comment>http://www.cppblog.com/LIULIANG/comments/170429.html</wfw:comment><comments>http://www.cppblog.com/LIULIANG/archive/2012/04/08/170429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LIULIANG/comments/commentRss/170429.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LIULIANG/services/trackbacks/170429.html</trackback:ping><description><![CDATA[<p>一般telnet pop3Server 110后就可以用这些命令了，大小写不敏感， <br />不包括口令本身，注意不要让口令回显，等验证通过后再允许回显好了。 <br /><br />user username 认可 <br />pass password 认可 执行成功则状态转换 <br />apop name,digest 认可 一种安全传输口令的办法，执行成功导 <br />致状态转换，请参见RFC 1321 <br />stat 处理 请求server回送邮箱统计资料，如邮件数、 <br />邮件总字节数 <br />uidl n 处理 server返回用于该指定邮件的唯一标识， <br />如果没有指定，返回所有的 <br />list n 处理 server返回指定邮件的大小等 <br />retr n 处理 server返回邮件的全部文本 <br />dele n 处理 server标记删除，quit命令执行时才真正删除 <br />rset 处理 撤消所有的dele命令 <br />top n,m 处理 返回n号邮件的前m行内容，m必须是自然数 <br />noop 处理 server返回一个肯定的响应 <br />quit client希望结束会话。如果server处于'处理' <br />状态，则现在进入'更新'状态，删除那些标记 <br />成删除的邮件。如果server处于'认可'状态， <br />则结束会话时server不进入'更新'状态 <br /><br />关于apop命令 <br /><br />如果client使用user命令，口令将是明文。使用apop命令时，client第一次 <br />与server连接时，server向client发送一个ascii码问候，该问候由一个字符 <br />串组成，它对于每个client的连接都是唯一的，client把它的纯文本口令附加 <br />到从server接收到的字符串之后，然后计算结果字符串的MD5摘要，client把 <br />username和MD5摘要作为apop命令的参数一起发送出去。 <br /><br />telnet pop3Server 110 <br />user username <br />pass **** <br />stat <br />list <br />retr 1 <br />retr 2 <br />... <br />dele 1 <br />dele 2 <br />... <br />quit <br /><br /></p>转自：<a href="http://www.douban.com/group/topic/3573819/">http://www.douban.com/group/topic/3573819/</a><img src ="http://www.cppblog.com/LIULIANG/aggbug/170429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LIULIANG/" target="_blank">BIG森林</a> 2012-04-08 11:03 <a href="http://www.cppblog.com/LIULIANG/archive/2012/04/08/170429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POP3邮局协议-版本3</title><link>http://www.cppblog.com/LIULIANG/archive/2012/04/08/170428.html</link><dc:creator>BIG森林</dc:creator><author>BIG森林</author><pubDate>Sun, 08 Apr 2012 03:02:00 GMT</pubDate><guid>http://www.cppblog.com/LIULIANG/archive/2012/04/08/170428.html</guid><wfw:comment>http://www.cppblog.com/LIULIANG/comments/170428.html</wfw:comment><comments>http://www.cppblog.com/LIULIANG/archive/2012/04/08/170428.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LIULIANG/comments/commentRss/170428.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LIULIANG/services/trackbacks/170428.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.&nbsp;&nbsp;&nbsp; 简介对于在网络上的比较小的结点，支持消息传输系统（MTS）是不实际的。例如，一台工作站可能不具有充足的资源允许SMTP服务器和相当的本地邮件传送系统保持序驻留，并持续运行。同样的，将一台个人计算机长时间连接在IP类型网络上的费用也是可观的（结点缺少的资源被称为&#8220;联络性&#8221;）。虽然如此，在这样的小结点上允许管理邮件是十分有用的，...&nbsp;&nbsp;<a href='http://www.cppblog.com/LIULIANG/archive/2012/04/08/170428.html'>阅读全文</a><img src ="http://www.cppblog.com/LIULIANG/aggbug/170428.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LIULIANG/" target="_blank">BIG森林</a> 2012-04-08 11:02 <a href="http://www.cppblog.com/LIULIANG/archive/2012/04/08/170428.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>