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

📄 rcp协议2.htm

📁 internet协议集
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0052)http://www.longen.org/L-R/detaill~r/RPCProtocol2.htm -->
<HTML><HEAD><TITLE>新建网页 0</TITLE>
<META http-equiv=Content-Language content=zh-cn>
<META content="MSHTML 6.00.2800.1400" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId>
<META http-equiv=Content-Type content="text/html; charset=gb2312"></HEAD>
<BODY>
<TABLE id=AutoNumber1 cellSpacing=0 cellPadding=0 width="100%" border=0>
  <TBODY>
  <TR>
    <TD width="100%">
      <H4>RCP协议2</H4>
      <P>本文介绍用于ONC RPC协议规范。此协议使用XDR语言进行描述,并文不打算描述具体的使用细节而只介绍RPC协议本身。</P>
      <P>ONC 
      RPC是基于RPC调用模型,此模型和本地过程调用(LPC)类似。对于LPC而言,调用方只需要将参加放入一些固定的地址,如寄存器,然后将程序的控制权转交给另一个程序,最后再由那个程序返回即可。RCP与之类似,RCP在调用一个远程过程后,自己进行等待状态,传往远程过程的参数包括过程参数,返回参数包括执行结果。当收到包括执行结果的消息后,本地进程从消息中取得结果,调用进程重新开始执行。在服务器一方,有一个程序在等待调用,当有一个调用到达时,服务器进程取得进程参数,计算结果,然后返回结果。</P>
      <P>在上面的模型中,在某一个时刻只有一个进程是活动的。ONC 
      RCP没有规定如何处理并发。调用可以同步的也可以是异步的。服务器可以创建一个线程来接收用户请求,也可以自己来接收用户请求。下面是RCP不同于LPC的几点:</P>
      <P>1. 错误处理:对于远程服务器和网络失败必须进行处理;<BR>2. 
      全局变量:因为远程服务不可能访问本地的变量,因此不能传送全局变量;<BR>3. 性能:RPC通常比LPC要慢许多;<BR>4. 
      认证:因为RPC通常要经过网络,因此必须进行认证。</P>
      <P>虽然有现成的工具可以自动生成相关的服务器和客户方,但是协议本身仍然需要仔细设计。</P>
      <P>RPC可由不同的传输协议实现,但RPC依然需要获得传输层的信息(这一过程本文不涉及)。这是因为有时候,传输层会限制信息的长度,同时通信双方必须遵守同一个通信协议。RPC不会试图实现任何可靠性,应用程序应该注意相关的可靠性问题。如果RPC在TCP上运行,一切好说。TCP代替应用程序做一些工作,但如果RPC运行在UDP上,应用程序必须注意超时,重传,多次请求检查等工作。因为传输是独立的,因此RPC必须从相关的传输层上获得是否正确执行的信息。对于UDP来讲,如果应用程序没有得到响应,它必须重新请求;重新请求后得到响应,应用程序只能推断出服务器至少执行了一次请求。通过对请求加上编号,可以使得服务器不对重复的请求加以响应。因此我们可以确定在收到确定后,服务器至多执行了一次请求。这里需要注意的一点是:客户的请求的ID号只能用于和服务器内的ID号进行相等比较,不能进行其它操作。 
      <BR>即使使用了TCP,在没有得到响应时,我们也不能确定服务器是不是一定执行了相关的操作。我们还需要使用超时机制以保证服务器没有失败。RPC可以使用其它的协议,如VMTP。但本文中我们以TCP作为例子。RPC协议本身不包括绑定,这是由高层协议来完成的。RPC必须提供:</P>
      <P>1. 被调用过程必须是唯一的;<BR>2. 必须提供调用消息和响应消息的配对机制;<BR>3. 必须提供认证机制;</P>
      <P>除上面的要求外还必须提供对下面问题的检测机制:</P>
      <P>1. RPC不匹配;<BR>2. 版本号不匹配;<BR>3. 协议错误,如参数错误;<BR>4. 必须提供认证错误的原因;<BR>5. 
      提供其它错误信息。</P>
      <P>RCP调用有三个无符号整数域:远程程序号,程序版本号和远程过程号。程序号必须统一管理 (<A 
      href="mailto:(rpc@sun.com">mailto:(rpc@sun.com</A>) 
      。在拥有一个程序号后,我们就可以实现自己的远程程序了。第一个实现通常以版本1来标记,这个版本号用于标记我们应该使用何种版本的程序。过程号用于标记被调用的程序。RCP本身可以变化,RCP消息协议也可以变化。因此消息本身也有RPC版本号,它通常和这里描述的两个版本号之一一致。返回消息必须提供信息以足以确定下面错误:</P>
      <P>1. 远程实现不支持版本2,返回可以支持的最高和最低版本号;<BR>2. 远程程序在远程机上不可用;<BR>3. 
      远程程序不支持请求的版本号,返回支持的最高和最低版本号;<BR>4. 请求的过程不存在;<BR>5. 参数错误</P>
      <P>认证机制要求请求消息有两个认证域:证书和确认。响应消息有一个域:响应确认。RPC对这三个域统一定义如下:</P>
      <P>enum auth_flavor {<BR>AUTH_NONE = 0,<BR>AUTH_SYS = 1,<BR>AUTH_SHORT = 
      2<BR>/* and more to be defined */<BR>};</P>
      <P>struct opaque_auth {<BR>auth_flavor flavor;<BR>opaque 
      body&lt;400&gt;;<BR>};</P>
      <P>对于认证结构语义的解释不在本协议规定之列。如果认证失败,必须提供失败原因。程序号成组给出,下面是一些规定:</P>
      <P>0 - 1fffffff 由rpc@sun.com定义<BR>20000000 - 3fffffff 用户定义<BR>40000000 - 
      5fffffff 临时<BR>60000000 - 7fffffff reserved<BR>80000000 - 9fffffff 
      reserved<BR>a0000000 - bfffffff reserved<BR>c0000000 - dfffffff 
      reserved<BR>e0000000 - ffffffff reserved</P>
      <P>其中第一组中要求的号码要求所有的RPC过程必须遵守,即同一个号必须提供相同的功能。第二组主要用于调试。第三组是由程序临时产生的号码。其它号码保留,不得使用。用户可以向服务器发送一组请求,称为批处理。批处理时用户不用等待服务器返回,而是使用一个特定的请求获得这一组请求的响应。批处理时通常使用TCP。而UDP多使用于广播式RPC,对于支持广播的服务器,它们在成功时返回确定,在失败时什么也不返回(此规定可根据实现不同而不用加以遵守)。下面我们来定义RPC消息:</P>
      <P>enum msg_type {<BR>CALL = 0,<BR>REPLY = 1<BR>};</P>
      <P>当一个消息接收到时,下面是调用远程过程调用的状态:</P>
      <P>enum accept_stat {<BR>SUCCESS = 0, /* RPC executed successfully 
      */<BR>PROG_UNAVAIL = 1, /* remote hasn't exported program 
      */<BR>PROG_MISMATCH = 2, /* remote can't support version # 
      */<BR>PROC_UNAVAIL = 3, /* program can't support procedure 
      */<BR>GARBAGE_ARGS = 4, /* procedure can't decode params */<BR>SYSTEM_ERR 
      = 5 /* errors like memory allocation failure */<BR>};</P>
      <P>调用消息被拒绝的原因如下:</P>
      <P>enum reject_stat {<BR>RPC_MISMATCH = 0, /* RPC version number != 2 
      */<BR>AUTH_ERROR = 1 /* remote can't authenticate caller */<BR>};</P>
      <P>认证失败的原因如下:</P>
      <P>enum auth_stat {<BR>AUTH_OK = 0, /* success */<BR>/*<BR>* failed at 
      remote end<BR>*/<BR>AUTH_BADCRED = 1, /* bad credential (seal broken) 
      */<BR>AUTH_REJECTEDCRED = 2, /* client must begin new session 
      */<BR>AUTH_BADVERF = 3, /* bad verifier (seal broken) 
      */<BR>AUTH_REJECTEDVERF = 4, /* verifier expired or replayed 
      */<BR>AUTH_TOOWEAK = 5, /* rejected for security reasons */<BR>/*<BR>* 
      failed locally<BR>*/<BR>AUTH_INVALIDRESP = 6, /* bogus response verifier 
      */<BR>AUTH_FAILED = 7 /* reason unknown */<BR>};</P>
      <P>消息体格式如下,其中XID是消息号,请求消息和返回消息的消息号必须一致。</P>
      <P>struct rpc_msg {<BR>unsigned int xid;<BR>union switch (msg_type mtype) 
      {<BR>case CALL:<BR>call_body cbody;<BR>case REPLY:<BR>reply_body 
      rbody;<BR>} body;<BR>};</P>
      <P>RPC的消息体,版本号为2:</P>
      <P>struct call_body {<BR>unsigned int rpcvers; /* must be equal to two (2) 
      */<BR>unsigned int prog;<BR>unsigned int vers;<BR>unsigned int 
      proc;<BR>opaque_auth cred;<BR>opaque_auth verf;<BR>/* procedure specific 
      parameters start here */<BR>};</P>
      <P>虽然cred和verf是两个数据域,但我们通常将它们做一个处理。而响应消息格式如下:</P>
      <P>union reply_body switch (reply_stat stat) {<BR>case 
      MSG_ACCEPTED:<BR>accepted_reply areply;<BR>case 
      MSG_DENIED:<BR>rejected_reply rreply;<BR>} reply;</P>
      <P>如果服务器接收这个请求,必须返回一个认证域以使自己为客户认证:</P>
      <P>struct accepted_reply {<BR>opaque_auth verf;<BR>union switch 
      (accept_stat stat) {<BR>case SUCCESS:<BR>opaque results[0];<BR>/*<BR>* 
      procedure-specific results start here<BR>*/<BR>case 
      PROG_MISMATCH:<BR>struct {<BR>unsigned int low;<BR>unsigned int high;<BR>} 
      mismatch_info;<BR>default:<BR>/*<BR>* Void. Cases include PROG_UNAVAIL, 
      PROC_UNAVAIL,<BR>* GARBAGE_ARGS, and SYSTEM_ERR.<BR>*/<BR>void;<BR>} 
      reply_data;<BR>};</P>
      <P>服务器可以因为版本原因或认证原因拒绝请求,下面是拒绝消息的格式:</P>
      <P>union rejected_reply switch (reject_stat stat) {<BR>case 
      RPC_MISMATCH:<BR>struct {<BR>unsigned int low;<BR>unsigned int high;<BR>} 
      mismatch_info;<BR>case AUTH_ERROR:<BR>auth_stat stat;<BR>};</P>
      <P>认证虽然对于RPC是透明的,可是RPC必须有两种认证必须实现。任何一种新的认证机制必须有一种独立的认证号,这个号是统一管理的,用户可以通过 
      <A href="mailto:rcp@sun.com">rcp@sun.com</A> 
      获得。其中NULL认证必须实现,我们推荐实现系统认证。NULL认证其实就是不认证,这里推荐相关的数据域长度为0。</P>
      <P>RPC在其它通信协议之上,为了保证一个消息和另一消息分离并能够从错误中进行恢复,我们规定了一个消息片断称为RM,一个消息在一个RM中。一个RM中可以有多个记录片断,每个片断除四个字节的头外,还有一个0到2的31次方减1的数据域。<BR>下面我们来描述一下RPC语言,这是对XDR的一个扩展。下面是一个PING的例子:</P>
      <P>program PING_PROG {<BR>/*<BR>* Latest and greatest 
      version<BR>*/<BR>version PING_VERS_PINGBACK 
      {<BR>void<BR>PINGPROC_NULL(void) = 0;<BR>/*<BR>* Ping the client, return 
      the round-trip time<BR>* (in microseconds). Returns -1 if the 
      operation<BR>* timed out.<BR>*/<BR>int<BR>PINGPROC_PINGBACK(void) = 
      1;<BR>} = 2;<BR><BR>/*<BR>* Original version<BR>*/<BR>version 
      PING_VERS_ORIG {<BR>void<BR>PINGPROC_NULL(void) = 0;<BR>} = 1;<BR>} = 
      1;<BR><BR>const PING_VERS = 2; /* latest version */</P>
      <P>上程序中包括了三个小程序。通过上面的例子,我们可以看出RPC语言和XDR语言很象,不过就加了一个program-def而已。</P>
      <P>program-def: <BR>"program" identifier "{" <BR>version-def 
      <BR>version-def * <BR>"}" "=" constant ";" <BR>version-def: <BR>"version" 
      identifier "{" <BR>procedure-def <BR>procedure-def * <BR>"}" "=" constant 
      ";" <BR>procedure-def: <BR>type-specifier identifier "(" type-specifier 
      <BR>("," type-specifier )* ")" "=" constant ";" </P>
      <P>下面是一些基本的规定:</P>
      <P>不使用program和version作为变量名;在一个域中版本名,过程名,版本号,过程号不能出现两次;程序标记在一个域中是常量,只能使用未使用的常量可被指定到程序,版本和过程。最后我们来看看系统认证。如果要使用系统认证,它的标识为AUTH_SYS。证书由下面的结构表示:</P>
      <P>struct authsys_parms {<BR>unsigned int stamp;<BR>string 
      machinename&lt;255&gt;;<BR>unsigned int uid;<BR>unsigned int 
      gid;<BR>unsigned int gids&lt;16&gt;;<BR>};</P>
      <P>stamp是一个ID号由调用机产生。machinename是调用机的机器名,uid和gid是用户ID和组ID,gids是包括此用户的组的集合。一般verf指定为AUTH_NONE。这个证书只在一个特定的域内有效(此域是由机器名,用户ID和组ID组成的)。</P>
      <P>从服务器接收到的Verf的认证号可以是AUTH_NONE或AUTH_SHORT。在接收到后者时,返回的是一个新的认证结构。这个新的结构可以取代原来的AUTH_SYS结构而被传送到服务器。这样客户可以传送比较少的数据而获得认证。服务器保留结构和旧结构的一个映射。当然,服务器可以随时取消这种映射,此时客户的请求会被拒绝。此时用户可以必须使用原有的结构进行认证。这种认证本身并不能保证安全,真正的网络安全必须通过别的方式进行保证。</P></TD></TR></TBODY></TABLE></BODY></HTML>

⌨️ 快捷键说明

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