ONC+ 開発ガイド

rpcbind プロトコル

rpcbind は RPC のプログラム番号とバージョン番号を汎用アドレスにマップし、リモートプログラムの動的結合を可能にします。

rpcbind はそれをサポートしているトランスポートのよく知られたアドレスに結合しています。他のプログラムは、動的に割り当てられたアドレスを rpcbind で登録します。rpcbind は、それらのアドレスを一般に使用できるようにします。汎用アドレスとは、トランスポートに依存したアドレスで、文字列で表現されています。汎用アドレスは、各トランスポートのアドレス管理者が定義します。

rpcbind はブロードキャスト RPC にも利用できます。RPC プログラムでは、マシンが異なる場合、アドレスも異なるため、これらのプログラムすべてに直接ブロードキャスト通信を行うことは不可能です。ところが、rpcbind のアドレスはわかっています。 そのため、特定のプログラムへブロードキャスト通信を行うには、クライアントは送信先マシン上にある rpcbind プロセスへメッセージを送信します。 rpcbind はブロードキャストメッセージを取り出し、クライアントが指定したローカルサービスを呼び出します。rpcbind はローカルサービスからの応答を取り出すと、それをクライアントに送信します。

次のコーディング例は、RPC 言語の rpcbind プロトコル仕様を示します。


例 B–5 rpcbind プロトコル仕様 (RPC 言語で記述)

/*
 * rpcb_prot.x
 * rpc 言語で記述した RPCBIND プロトコル
 */
/*
 * (プログラム、バージョン、ネットワーク ID) の汎用アドレスへの割り当て
 */
struct rpcb {
	rpcproc_t r_prog;           /* プログラム番号 */
	rpcvers_t r_vers;           /* バージョン番号 */
	string r_netid<>;               /* ネットワーク ID */
	string r_addr<>;                /* 汎用アドレス */
	string r_owner<>;               /* このサービスの所有者 */ };
/* 割り当てのリスト */
struct rpcblist {
	rpcb rpcb_map;
	struct rpcblist *rpcb_next;
};
 
/* リモート呼び出しの引数 */
struct rpcb_rmtcallargs {
	rpcprog_t prog;             /* プログラム番号 */
	rpcvers_t vers;             /* バージョン番号 */
	rpcproc_t proc;             /* 手続き番号 */
	opaque args<>;                  /* 引数 */
};
 
/* リモート呼び出しの戻り値 */
struct rpcb_rmtcallres {
	string addr<>;                  /* リモート汎用アドレス */
	opaque results<>;               /* 戻り値 */
};
 
/*
 * rpcb_entry には、特定のトランスポート上のサービスの
 * マージされたアドレスと関連付けられた netconfig 情報を含みます。
 * RPCBPROC_GETADDRLIST は rpcb_entry のリストを返します。
 * r_nc_* フィールドで使用できる値については、netconfig.h を
 * 参照してください。
 */
struct rpcb_entry {
	string          r_maddr<>;      /* サービスのマージされたアドレス */
	string          r_nc_netid<>;   /* netid フィールド */
	unsigned int   r_nc_semantics; /* トランスポートのセマンティクス */
	string          r_nc_protofmly<>; /* プロトコルファミリ */
	string          r_nc_proto<>;   /* プロトコル名 */
};
 
/* サービスがサポートするアドレスのリスト */
struct rpcb_entry_list {
	rpcb_entry rpcb_entry_map;
	struct rpcb_entry_list *rpcb_entry_next;
};
 
typedef rpcb_entry_list *rpcb_entry_list_ptr;
 
/* rpcbind 統計情報 */
const rpcb_highproc_2 = RPCBPROC_CALLIT;
const rpcb_highproc_3 = RPCBPROC_TADDR2UADDR;
const rpcb_highproc_4 = RPCBPROC_GETSTAT;
const RPCBSTAT_HIGHPROC = 13;  /* rpcbind V4 内の手続きに 1 を足した数 */
const RPCBVERS_STAT = 3;  /* rpcbind V2、V3、V4 だけのために提供 */
const RPCBVERS_4_STAT = 2;
const RPCBVERS_3_STAT = 1;
const RPCBVERS_2_STAT = 0;
 
/* getport と getaddr に関するすべての状態のリンクリスト */
struct rpcbs_addrlist {
	rpcprog_t prog;
	rpcvers_t vers;
	int success;
	int failure;
	string netid<>;
	struct rpcbs_addrlist *next;
};
 
/* rmtcall に関するすべての状態のリンクリスト*/
struct rpcbs_rmtcalllist {
	rpcprog_t prog;
	rpcvers_t vers;
	rpcproc_t proc;
	int success;
	int failure;
	int indirect;   /* 直接的に呼び出すか、間接的に呼び出すか */
	string netid<>;
	struct rpcbs_rmtcalllist *next;
};
 
typedef int rpcbs_proc[RPCBSTAT_HIGHPROC];
typedef rpcbs_addrlist *rpcbs_addrlist_ptr;
typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr;
 
struct rpcb_stat {
	rpcbs_proc              info;
	int                     setinfo;
	int                     unsetinfo;
	rpcbs_addrlist_ptr      addrinfo;
	rpcbs_rmtcalllist_ptr   rmtinfo;
};
 
/*
 * 監視する rpcbind のバージョン 1 つに対して 
 * 1 つの rpcb_stat 構造体が返される。
 */
typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT];
/* rpcbind 手続き */
program RPCBPROG {
	version RPCBVERS {
		void
		RPCBPROC_NULL(void) = 0;
 
		/*
		 * [r_prog, r_vers, r_addr, r_owner,r_netid] の組み合わせを登録。
		 * セキュリティー上の理由から、rpcbind サーバーはこの手続きの要求を
		 * ループバックトランスポートのみで受け付ける。成功の場合は真を、
		 * 失敗の場合は偽を返す。
		 */
		bool
		RPCBPROC_SET(rpcb) = 1;
 
		/*
		 * [r_prog, r_vers, r_owner, r_netid] の組み合わせを登録解除。
		 * vers がゼロの場合、すべてのバージョンが登録解除される。
                 * セキュリティー上の理由から、rpcbind サーバーは
                 * この手続きの要求をループバックトランスポート
		 * のみで受け付ける。成功の場合は真を、失敗の場合は偽を返す。
		 */
		bool
		RPCBPROC_UNSET(rpcb) = 2;
 
		/*
		 * [r_prog, r_vers, r_netid] の組み合わせが登録されている
                 * 汎用アドレスを返す。r_addr を指定すると、
                 * r_addr へマージされた汎用アドレスを返す。
		 * r_owner は無視する。失敗の場合は偽を返す。
		 */
		string
		RPCBPROC_GETADDR(rpcb) = 3;
 
		/* すべての割り当てのリストを返す。 */
 
	rpcblist
		RPCBPROC_DUMP(void) = 4;
 
		/*
		 * リモートマシン上の手続きを呼び出す。
                 * 登録されていない場合はこの手続きは
		 * 何も出力しない。つまり、エラー情報を返さない。
		 */
		rpcb_rmtcallres
		RPCBPROC_CALLIT(rpcb_rmtcallargs) = 5;
 
		/*
		 * rpcbind サーバーシステム上の時刻を返す。 
		 */
		unsigned int
		RPCBPROC_GETTIME(void) = 6;
 
		struct netbuf
		RPCBPROC_UADDR2TADDR(string) = 7;
 

		string
		RPCBPROC_TADDR2UADDR(struct netbuf) = 8;
 
		} = 3;
		version RPCBVERS4 {
		bool
		RPCBPROC_SET(rpcb) = 1;
 
		bool
		RPCBPROC_UNSET(rpcb) = 2;
 
		string
		RPCBPROC_GETADDR(rpcb) = 3;
 
		rpcblist_ptr
		RPCBPROC_DUMP(void) = 4;
 
		/*
		 * 注: RPCBPROC_BCAST は CALLIT と同じ機能を持つ。 
	 * 新しい名前の目的は RPCBPROC_BCAST はブロードキャスト RPC に
		 * 使用し、RPCBPROC_INDIRECT は間接呼び出しに使用する
                 * ことを示すため。
		 */
		rpcb_rmtcallres
		RPCBPROC_BCAST(rpcb_rmtcallargs) = RPCBPROC_CALLIT;
 
		unsigned int
		RPCBPROC_GETTIME(void) = 6;
 
		struct netbuf
		RPCBPROC_UADDR2TADDR(string) = 7;
 

		string
		RPCBPROC_TADDR2UADDR(struct netbuf) = 8;
 

		/*
		 * RPCBPROC_GETADDR と同じ機能を持つが、
                 * バージョン番号がわからなければ、
		 * アドレスが返されない点が異なる。
		 */
		string
		RPCBPROC_GETVERSADDR(rpcb) = 9;
 

		/*
		 * リモートマシン上の手続きを呼び出す。登録されていない場合は、
		 * この手続きは出力を行う。つまり、エラー情報を返す。
		 */
		rpcb_rmtcallres
		RPCBPROC_INDIRECT(rpcb_rmtcallargs) = 10;
 
		/*
		 * RPCBPROC_GETADDR と同じ機能を持つが、
                 * この組み合わせ (prog, vers) へ
		 * 登録されたアドレスのリストを返す点が異なる。
		 */
		rpcb_entry_list_ptr
		RPCBPROC_GETADDRLIST(rpcb) = 11;
 
		/*
		 * rpcbind サーバーの動作に関する統計情報を返す。
		 */
		rpcb_stat_byvers
		RPCBPROC_GETSTAT(void) = 12;
	} = 4;
} = 100000;