ONC+ 開発ガイド

rpcbind プロトコル

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

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

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


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

/*
 * rpcb_prot.x
 * RPCBIND プロトコルを RPC 言語で記述 
 */
/*
 * (プログラム、バージョン、ネットワーク 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;   /* callit か 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 の各バージョンに対して rpcb_stat 構造体が
 * 1 つずつ返されます。
 */
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 サーバーは、セキュリティ上の理由
		 * から、この手続きへの要求をループバックトランスポートだけで受け入れ
 	 * ます。 正常終了では TRUE、異常終了では FALSE が返されます。
		 */
 	bool
		RPCBPROC_SET(rpcb) = 1;
 
	 /*
		 *この手続きは、[r_prog, r_vers, r_owner, r_netid] の
 
		 * 組み合わせの登録を解除します。
		 * vers がゼロの場合は、全バージョンを登録解除します。
 	 * この手続きへの要求は、ループバックトランスポートだけで受け入れます。
		 * 正常終了では TRUE、異常終了では FALSE が返されます。
		 */
		bool
	 RPCBPROC_UNSET(rpcb) = 2;
 
		/*
 	 * この手続きは、[r_prog, r_vers, r_netid] の組み合わせが登録さ
		 * れている汎用アドレスを返します。r_addr が指定されていれば、
		 * 汎用アドレスが r_addr にマージされて返されます。r_owner は無視
		 * します。 異常終了の場合は、FALSE が返されます。
 	 */
		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;
 
		/*
		 * 注: RPCBROC_BCAST と CALLIT の機能は同じです。
		 * 新たな名前を付けた目的は、ブロードキャスト 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;