分散アプリケーションを各種のプロトコルに移植可能にするには、分散アプリケーションでトランスポートサービスの標準インタフェースを使用する必要があります。トランスポート選択サービスが提供するインタフェースを使用すると、アプリケーションは、使用するプロトコルを選択できます。これによって、アプリケーションは、「プロトコル」と「媒体」に依存しなくなります。
トランスポート選択機能を使用すると、クライアントアプリケーションは、サーバーとの通信を確立するまでに、どのトランスポートが使用できるかを簡単に試すことができます。一方、サーバーアプリケーションは、複数のトランスポートに関する要求を受け入れ、複数のプロトコルを経由して通信を行うことができます。どのトランスポートが使用できるかは、ローカルなデフォルトシーケンスで指定された順序、またはユーザーが指定した順序で試すことができます。
使用可能なトランスポートのうち、どれを選択するかを決定するのは、アプリケーションの役割です。トランスポート選択機構を使用すると、選択が統一的な方法で簡単に行えます。
トランスポートの選択は、次に基づいて行われます。
環境変数 NETPATH は、ユーザーが設定します。この環境変数は、トランスポート識別子を順番に指定したリストと同じです。トランスポート識別子は、netconfig network ID フィールドに一致し、netconfig(4) ファイル内のレコードとリンクしています。netconfig(4) ファイルについては、「/etc/netconfig ファイル」を参照してください。ネットワーク選択インタフェースは、ネットワーク構成データベースへの一連のアクセスルーチンから構成されます。
ライブラリルーチン一式は、環境変数 NETPATH
で指定される /etc/netconfig のエントリにだけアクセスします。
setnetpath(3NSL) | NETPATH の検索を初期化する |
getnetpath(3NSL) | NETPATH の次の要素に対応する netconfig(4) エントリへのポインタを返す |
endnetpath(3NSL) | 処理の完了時に NETPATH の要素へのデータベースポインタを解放する |
これらのルーチンについては、「NETPATH を経由した netconfig(4) データへのアクセス」および getnetpath(3NSL) を参照してください。これらのルーチンを使用すると、アプリケーションが使用するトランスポート選択にユーザーが影響を与えることができます。
トランスポート選択へのユーザーの影響を避けるには、netconfig(4) データベースに直接アクセスするルーチンを使用します。これらのルーチンについては、「netconfig(4) へのアクセス」および getnetconfig(3NSL) を参照してください。
setnetconfig(3NSL) | データベースの最初のインデックスへのレコードポインタを初期化する |
getnetconfig(3NSL) | netconfig(4) データベース内の現在のレコードへのポインタを返し、次のレコードを指すようにポインタを 1 だけ増加する |
endnetconfig(3NSL) | 処理の完了時にデータベースポインタを解放する |
次の 2 つのルーチンは、netconfig(4) エントリおよびそれが表すデータ構造体を操作します。これらのルーチンについては、「netconfig(4) へのアクセス」を参照してください。
getnetconfigent(3NSL) | netid に対応する netconfig 構造体へのポインタを返す |
freenetconfigent(3NSL) | getnetconfigent(3NSL) で返される構造体を解放する |
netconfig(4) ファイルには、ホスト上のすべてのトランスポートプロトコルが記述されています。表 4-1 で、netconfig(4) ファイルのエントリについて簡単に説明しています。詳細については、netconfig(4) のマニュアルページを参照してください。
表 4-1 netconfig(4) ファイル
例 4-1 に、netconfig(4) ファイルのサンプルを示します。inet トランスポートについては、このサンプルファイルのコメント部分に示すように、netconfig(4) ファイルの使用方法が変更されました。この変更については、「名前からアドレスへのマッピング」も参照してください。
# The "Network Configuration" File. # # Each entry is of the form: # #<net <semantics> <flags> <proto <proto <device> <nametoaddr_libs> # id> family> name> # # The "-" in <nametoaddr_libs> for inet family transports indicates redirection # to the name service switch policies for "hosts" and "services. The "-" may be # replaced by nametoaddr libraries that comply with the SVR4 specs, in which # case the name service switch will be used for netdir_getbyname, netdir_ # getbyaddr, gethostbyname, gethostbyaddr, getservbyname, and getservbyport. # There are no nametoaddr_libs for the inet family in Solaris anymore. # udp tpi_clts v inet udp /dev/udp - # tcp tpi_cots_ord v inet tcp /dev/tcp - # icmp tpi_raw - inet icmp /dev/icmp - # rawip tpi_raw - inet - /dev/rawip - # ticlts tpi_clts v loopback - /dev/ticlts straddr.so # ticots tpi_cots v loopback - /dev/ticots straddr.so # ticotsord tpi_cots_ord v loopback - /dev/ticotsord straddr.so #
ネットワーク選択ライブラリルーチンは、netconfig エントリへのポインタを返します。例 4-2 に、netconfig 構造体を示します。
struct netconfig { char *nc_netid; /* ネットワーク識別子 */ unsigned int nc_semantics; /* プロトコルの意味 */ unsigned int nc_flag; /* プロトコルのフラグ */ char *nc_protofmly; /* ファミリ名 */ char *nc_proto; /* プロトコル固有 */ char *nc_device; /* ネットワーク ID に相当するデバイス名 */ unsigned int nc_nlookups; /* nc_lookups 内のエントリ数 */ char **nc_lookups; /* ルックアップライブラリのリスト */ unsigned int nc_unused[8]; };
有効なネットワーク ID は、システム管理者が定義します。システム管理者は、必ず、ネットワーク ID をローカルに一意にしなければなりません。一意でないと、一部のネットワーク選択ルーチンが正しく機能しません。たとえば、udp というネットワーク ID が指定された netconfig エントリが 2 つあると、getnetconfigent ("udp") がどちらのネットワークを使用するかがわかりません。
システム管理者は、netconfig(4) データベース内のエントリの順序も設定します。/etc/netconfig 内のエントリを見つけるルーチンは、ファイルの先頭から順番に走査し、エントリを返します。netconfig(4) ファイル内のトランスポートの記述順序は、ルーチンがトランスポートを検索する際のデフォルト順序になります。ループバックエントリは、ファイルの終わりに設定する必要があります。
netconfig(4) ファイルおよび netconfig 構造体については、netconfig(4) のマニュアルページでさらに詳細に説明しています。
NETPATH
アプリケーションは、通常、システム管理者が設定したデフォルトのトランスポート検索パスを使用して、使用可能なトランスポートを検索します。ただし、ユーザーがアプリケーションのトランスポート選択に関与したい場合は、環境変数 NETPATH
と、「NETPATH を経由した netconfig(4) データへのアクセス」で説明するルーチンとを使用することによって、アプリケーションがインタフェースを変更できます。これらのルーチンは、環境変数 NETPATH
に指定されているトランスポートにだけアクセスします。
NETPATH
は、PATH
変数と同様に、トランスポート ID をコロンで区切ったリストです。環境変数 NETPATH
内の各トランスポート ID は、netconfig(4) ファイル内のレコードのネットワーク ID フィールドに対応します。NETPATH
については、environ(4) のマニュアルページを参照してください。
デフォルトトランスポートセットは、環境変数 NETPATH (次の節で説明する) を経由して netconfig(4) にアクセスするルーチンと、netconfig(4) に直接アクセスするルーチンとで異なります。環境変数 NETPATH を介して netconfig(4) にアクセスするルーチンのデフォルトトランスポートセットは、netconfig(4) ファイルに定義された可視のトランスポートからなります。一方、netconfig(4) に直接アクセスするルーチンのデフォルトトランスポートセットは、netconfig(4) ファイル全体になります。トランスポートが可視になるのは、システム管理者がそのトランスポートの netconfig(4) エントリの flags フィールドに v フラグを設定した場合です。
環境変数 NETPATH を経由して間接的にネットワーク構成データベースにアクセスするルーチンは、3 つあります。この環境変数では、アプリケーションが使用するトランスポート (複数も可) と、使用できるトランスポートを試す順序とを指定します。NETPATH の構成要素は、左から右へと読み込まれます。これらの関数は、次のインタフェースを使用します。
#include <netconfig.h> void *setnetpath(void); struct netconfig *getnetpath(void *); int endnetpath(void *);
setnetpath(3NSL) の呼び出しは、NETPATH の検索を初期化します。また、環境変数 NETPATH で指定したエントリが含まれるデータベースへのポインタを返します。このポインタはハンドルと呼ばれ、getnetpath(3NSL) を使用してデータベース内を移動する際に使用します。setnetpath(3NSL) 関数は、getnetpath(3NSL) を最初に呼び出す前に呼び出しておく必要があります。
getnetpath(3NSL) は、最初に呼び出されると、環境変数 NETPATH の最初の構成要素に対応する netconfig(4) ファイル内のエントリへのポインタを返します。以降の getnetpath(3NSL) 呼び出しでは、環境変数 NETPATH
の次の構成要素に対応する netconfig(4) ファイル内のエントリへのポインタを返します。NETPATH に構成要素がなくなると、getnetpath(3NSL) は NULL を返します。setnetpath(3NSL) を最初に呼び出さずに getnetpath(3NSL) を呼び出すと、エラーが発生します。getnetpath(3NSL) には、setnetpath(3NSL) で返されたポインタを引数に指定する必要があります。
getnetpath(3NSL) は、無効な NETPATH 構成要素を無視するだけで、メッセージを出力しません。無効な NETPATH
構成要素とは、netconfig(4) データベースに対応するエントリがないものです。
環境変数 NETPATH が設定されていない場合、getnetpath(3NSL) は、netconfig(4) データベースのデフォルトトランスポートまたは可視トランスポートの順序が NETPATH に設定されているように振る舞います。
endnetpath(3NSL) は、処理の完了時に呼び出され、環境変数 NETPATH 内の要素へのデータベースポインタを解放します。setnetpath(3NSL) が事前に呼び出されていないと、endnetpath(3NSL) は失敗します。例 4-3 に、setnetpath(3NSL)、getnetpath(3NSL)、および endnetpath(3NSL) の各ルーチンを示します。
#include <netconfig.h> void *handlep; struct netconfig *nconf; if ((handlep = setnetpath()) == (void *)NULL) { nc_perror(argv[0]); exit(1); } while ((nconf = getnetpath(handlep)) != (struct netconfig *)NULL) { /* * nconf がトランスポートプロバイダ情報を示す */ } endnetpath(handlep);
getnetpath(3NSL) 経由で取得した netconfig(4) 構造体は、endnetpath(3NSL) の実行後無効になります。構造体内のデータを保持するには、getnetconfigent(nconf->nc_netid) を使用して、それらを新しいデータ構造体にコピーします。
/etc/netconfig にアクセスし、netconfig(4) 内のエントリを検索する関数は、3 つあります。これら 3 つのルーチンである setnetconfig(3NSL)、 getnetconfigent(3NSL) および endnetconfig(3NSL) は、次のインタフェースを使用します。
#include <netconfig.h> void *setnetconfig(void); struct netconfig *getnetconfig(void *); int endnetconfig(void *);
setnetconfig(3NSL) 呼び出しは、データベースの最初のインデックスへのレコードポインタを初期化します。setnetconfig(3NSL) は、最初に getnetconfig(3NSL) を使用する前に使用する必要があります。setnetconfig(3NSL) は、getnetconfig(3NSL) ルーチンが使用する一意のハンドル (データベースへのポインタ) を返します。getnetconfig(3NSL) の各呼び出しは、netconfig(4) データベース内の現在のレコードへのポインタを返し、次のレコードを指すようにポインタを 1 だけ増加させます。また、getnetconfig(3NSL) は netconfig(4) データベース全体の検索にも使用できます。getnetconfig(3NSL) は、ファイルの終わりに NULL を返します。
処理の完了時にデータベースポインタを解放するには、endnetconfig(3NSL) を使用する必要があります。endnetconfig(3NSL) は、setnetconfig(3NSL) の前に呼び出してはなりません。
void *handlep; struct netconfig *nconf; if ((handlep = setnetconfig()) == (void *)NULL){ nc_perror(argv[0]); exit(1); } /* * トランスポートプロバイダ情報は、nconf に記載されている。 * process_transport は、ユーザーが提供するルーチンであり、 * トランスポート nconf を経由してサーバーへの接続を試みる。 */ while ((nconf = getnetconfig(handlep)) != (struct netconfig *)NULL){ if (process_transport(nconf) == SUCCESS) break; } endnetconfig(handlep);
getnetconfigent(3NSL) および freenetconfigent(3NSL) の各関数は、次のインタフェースを使用します。
#include <netconfig.h> struct netconfig *getnetconfigent(char *); int freenetconfigent(struct netconfig *);
getnetconfigent(3NSL) は、netid に対応した netconfig 構造体へのポインタを返します。netid が無効の場合は、NULL を返します。freenetconfigent(3NSL) は、getnetconfigent(3NSL) の前に呼び出してはなりません。
freenetconfigent(3NSL) は、getnetconfigent(3NSL) で返された構造体を解放します。例 4-5 に、getnetconfigent(3NSL) と freenetconfigent(3NSL) の各ルーチンを示します。
/* udp がこのホストの netid と仮定する */ struct netconfig *nconf; if ((nconf = getnetconfigent("udp")) == (struct netconfig *)NULL){ nc_perror("no information about udp"); exit(1); } process_transport(nconf); freenetconfigent(nconf);
setnetconfig(3NSL) 呼び出しを使用して、netconfig(4) データベースで可視とマークされたすべてのトランスポート (flags フィールドに v フラグが設定されているもの) 間を移動します。トランスポート選択ルーチンは、netconfig(4) ポインタを返します。
環境変数 NETPATH にコロンで区切ったトランスポート名のリストを設定することによって、ループを制御できます。NETPATH は、次のように設定します。
NETPATH=tcp:udp |
ループは、最初に tcp エントリを返し、次に udp エントリを返します。NETPATH が定義されていないと、ループは、netconfig(4) ファイル内に存在するすべての可視エントリを格納順に返します。環境変数 NETPATH を使用すると、クライアント側アプリケーションがサービスに接続しようとする順番をユーザーが定義できるだけでなく、サービスが待機できるトランスポートの数をサーバーの管理者が制限できます。
getnetpath(3NSL) と setnetpath(3NSL) を使用して、ネットワークパス変数を取得したり、変更したりします。例 4-6 では、その形式と使用方法を示します。これは、getnetconfig(3NSL) と setnetconfig(3NSL) のルーチンに似ています。
void *handlep; struct netconfig *nconf; if ((handlep = setnetconfig() == (void *) NULL) { nc_perror("setnetconfig"); exit(1); } while (nconf = getnetconfig(handlep)) if (nconf->nc_flag & NC_VISIBLE) doit(nconf); (void) endnetconfig(handlep);