ソケットデバイスはソケットにアクセスして操作するために使用されます。SOCKETデバイスは無制限の個数の関連ソケットを持つことができます。デフォルトの制限は64個です。環境変数 gtm_max_sockets を、GT.Mプロセスに設定する最大の関連ソケットの数に設定します。$VIEW("MAX_SOCKETS") は、関連するソケットの最大数の現在の値を返します。
いつでも、コレクション(collection)から1つのソケットのみ、現在のソケットになります。もし、デバイスからの読み込みや書き込みを試みる現在のソケットがない場合は、エラーを生成します。
ソケットは、デバイスに関連付けられているソケットのコレクション(collection)に接続したり取り外すことができます。取り外されたソケットは、"SocketPoolの"と呼ばれる擬似デバイスに属しています。プロセスは、デバイスからソケットを取り外し、後で同じデバイスまたは別のデバイスに接続することができます。
注意 | |
---|---|
現在、異なるCHSETを持つデバイスにソケットが接続されている場合、GT.Mはエラーを生成しません。 |
注意 | |
---|---|
例外ハンドラ(EXCEPTION)はSOCKETデバイス・レベルで操作し、エラー・トラップ(IOERROR)はソケット・レベルを操作します。したがって、1つのEXCEPTION(例外) は、SOCKETデバイスのすべてのソケットで操作し、IOERORはソケットごとに個別にオンまたはオフにすることができます。 |
アプリケーションの観点から、ソケット・デバイスによって使用されるトランスポート層は、暗黙的なアプリケーション・メッセージにとっては規定がない、ストリーム指向です。したがって、以下は、セグメントのアプリケーション・ メッセージに使用される、2つの一般的なプロトコルです。
一つの方法は、次、可変長、メッセージの長さを含む、一般的に小さく、固定長メッセージを使用することです。GT.Mで単純化した出力は次のようになります。
Write $Justify($Length(x),4),x
Writeに対応する単純化した入力は次のようになります。
read len#4,x#len
このアプローチの利点は、メッセージの内容(上記のコードフラグメントにある x の値)が任意の文字を含むことができるということです。欠点は、プロトコルの同期ずれになったことを検出することが問題であるということです。
他の一般的な方法は、それぞれのアプリケーション メッセージ間に区切り文字を配置することです。メッセージがこれまにその内容の一部として区切り文字が含まれている場合は、プロトコルが壊れます。
SOCKETデバイスは、デリミタを認識してメッセージを解析する機能を提供します。
TCP/IPは、バイトが送信された順序で到着することを保証するストリームベースのプロトコルです。しかしながら、それらバイトが同じパケットでグループ化されることを保証するものではありません。
パケットが、まれに、あるいは時々遅い異なったレートで到着するならば、短いインターバルでは、ありそうもないイベントをチェックするためにCPUサイクルを浪費することがあります。一方、パケットの処理において時間が正確であるならば、長いインターバルは、望ましくない遅延を導きます。もしパケットが迅速で一定流量(異常事態)の状態で到着するならば、共に動作するREAD用のバッファが常にあるので、インターバルはたいした問題ではありません。MOREREADTIMEを指定しない場合、データを検出できなかった時、SOCKET READは、200msの長い最初のインターバルを使用してのダイナミックなアプローチを実装しているので、その後、データが到着し始めると、10msにインターバルを短くします。インターバルを指定する場合、SOCKETデバイスは常に、指定されたインターバルを使用し、そして、動的には調整されません。MOREREADTIMEの詳細については、 “MOREREADTIME” を参照してください。
最大の SOCKET READ の操作は、(a) 区切り文字の受取、(b)最大文字数の受取、または、(c) タイムアウトの有効期限を検出された最初の条件の結果として終了します。これらの条件はすべてオプションであり、特定のREADは0以上を指定することができます。このセクションでは、これらの3つの条件を「定義済みの終了条件」と言います。SOCKET READ が、定義された終了条件のうちのいずれかの対象ではない場合、新たなキャラクターのないインターバルにより続く少なくとも1つの文字を受信した後、それが終了します。エラーはまた、READを終了することができます。終了条件のいずれも満たされていない間は、READが続行されます。
次のフローチャートは、SOCKET READのロジックを表します。
次のいずれかの条件が満たされている場合に、SOCKET READの操作は終了します。
終了条件 |
含まれる引数 |
$Device |
$Key |
$Test |
---|---|---|---|---|
エラー |
空の文字列 |
エラー文字列 |
空の文字列 |
1 |
タイムアウト * |
データはタイムアウト前に受信 |
空の文字列 |
空の文字列 |
0 |
デリミタ(区切り文字) * |
データをアップ、区切り文字は含まない |
空の文字列 |
区切り文字列 |
1 |
固定長測定 * |
固定長の文字列 |
空の文字列 |
空の文字列 |
1 |
Width |
全幅の文字列 |
空の文字列 |
空の文字列 |
1 |
バッファーが空になった |
追加入力なしで MOREREADTIME で指定された間隔(ミリ秒単位)を待つ前に、トランスポート・インタフェースによって提供される多くの文字として 1 。MOREREADTIME が指定されていない場合、最初の入力で200ミリ秒ごとにバッファーが検査され、新しい入力がなくなり、他の終了条件が満たされなくなるまで10ミリ秒ごとに検査されます。 MOREREADTIMEが指定されている場合、READはその値をバッファチェック専用に使用します。 |
空の文字列 |
空の文字列 |
1 |
* 定義済みの終了条件を示します
タイムアウトもデリミタもない固定長でない(non-fixed-length)の読み込み(上記の表の6行目)では、予測可能な結果を保証するために、READのシーケンスを複雑に実装する必要があります。これは、リーダー(reader)に配信されるトランスポート層のストリームのフラグメントが、ライタ(writer)によって実行される操作で偶発的にのみ対応しているためです。たとえば、次のようになります:
Write "Message 1","Message 2" は、ストリーム "Message1Message2" としてリーダに提示されますが、それはストリーム全体を取得するために1個から18個のREADコマンドに取ることができます。
メッセージング・プロトコルは、次のいずれかの方法でREADを実装する必要があります:
区切り文字を使用してメッセージを区切ります(一般的なREAD、場合によってはMOREREADTIMEの大きな値)。
メッセージを<length, value>のペア(固定長READ(READ #)のペアと、おそらくMOREREADTIMEの大きな値のペア)として指定します。
バイトまたは文字が入ってくるのを解析します(MOREADTIMEの場合は小さい値かもしれません)
それぞれのデバイスは、それに関連付けられている0から64 の区切り文字を持つことができます。各区切り文字は、pne(1)から64の文字にすることができます。デバイスのために宣言されたすべての区切り文字は、いくつかの関連付けられたソケットからのREADのために有効で、それは、READを終了させことを定義された区切り文字のいずれかであること。実際の終端区切り文字は、$KEYで利用可能です。1個以上の区切り文字にデバイスに関連付けられているソケットへの1回のWRITEは、WRITE ! フォーマットで、区切り文字の最初に挿入します。format.
READコマンドは、ソケットからデータを取得するために使用できます。次のいずれかが検出されると、以下に指定された順序で、READ操作は終了します。
終了 |
含まれる引数 |
$Device |
$Key (継続) |
---|---|---|---|
エラー |
空の文字列 |
エラー文字列 |
空の文字列 |
タイムアウト |
データはタイムアウト前に受信 |
空の文字列 |
空の文字列 |
デリミタ(区切り文字) |
データをアップ、区切り文字は含まない |
空の文字列 |
区切り文字列 |
固定長測定 |
固定長の文字列 |
空の文字列 |
空の文字列 |
バッファーが空 |
トランスポートインタフェースによって提供されることが起こる限り多くの文字として1つ(1) |
空の文字列 |
空の文字列 |
タイムアウトなしでそして区切り文字(delimiter)なしでの非固定長(non-fixed-length)の読み込みは、予測可能な結果を保証するためにREADのシーケンスの複雑な実装を必要とします。これは、リーダー(reader)に配信されるトランスポート層のストリームのフラグメントが、ライタ(writer)によって実行される操作で偶発的にのみ対応しているためです。たとえば、次のようです
Write "Message 1","Message 2"
ストリーム "Message1Message2" としてリーダー(reader)に提示されますが、それはストリーム全体を取得するために1つから18のREADコマンドに取ることができます。
WRITEコマンドは、ソケットにデータを送信します。
WRITE ! は、送信バッファへの最初のI/O区切り文字(もしあれば)を挿入します。"ZFF=expr" が指定されている場合、WRITE # は expr の文字を挿入します。それ以外の場合、WRITE # は効果がありません。WRITE ! と WRITE # は、デバイスがUTF CHSETでOPENされている場合を除いて、常にターミナル・カーソル位置をエミュレートする方法で $X と $Y を維持します、それは、ターミナルの $X と $Y の単位は表示列にあり、ソケットの場合はコードポイントにあるためです。
SOCKETデバイスのWRITEコマンドは、次の制御ニーモニックを受け入れます:
/L[ISTEN][(numexpr)]
ここで、numexpr は 1〜5 の範囲であり、リスニング・ソケットのリッスン・キューの深さを指定します。デフォルトでは、LISTENを使用したOPENまたはUSEは、リスニング・キュー・サイズをただちに1に設定します。
/W[AIT][(timeout)]
ここで、timeout は、サーバが現在のソケットデバイス内のソケットの1つで接続またはデータを使用できるようになるまでの待機時間を秒単位で指定する表現式です。
注意 | |
---|---|
現在のソケットデバイスが $PRINCIPAL で、入出力が異なる場合、WRITE /WAITはデバイスの入力側に適用されます。 |
WRITE /PASS([targetpid],[timeout],handle[,handle]...)
WRITE /PASSは、GT.MプロセスがDETACHされたTCPまたはLOCALソケット(つまり、ソケットプール内のソケット)を別のGT.Mプロセスに送ることを可能にします。受信プロセスは、ソケットを受信するために WRITE /ACCEPT を実行する必要があります。
数値の targetpid が指定されている場合、GT.Mは値をソケットを受け取るプロセスのプロセスID($JOB)と照合します。GT.Mはシステム・サービスを使用して、現在サポートしているプラットフォーム(Linux、AIX、Solaris)でこのチェックを実行します。サービスを実装していないプラットフォーム(HP-UX)では、GT.Mは targetpid を無視します。pid が一致しない場合、GT.MはPEERPIDMISMATCHエラーを発行し、ソケットを転送しません。
数値のタイムアウトが指定されている場合、指定した時間内に転送が完了するとGT.Mは $TESTを1に設定し、そうでなければ $TESTを 0 に設定してソケットを転送しません。
各ハンドルは、ソケット・プール内のソケットを指定します。
転送が成功すると、GT.Mは指定され送信されたソケットへの送信プロセスによるアクセスを排除します。転送が完了しない場合、GT.Mは送信者のソケットプール内のすべてのソケットを保持します。
WRITE /ACCEPT(.lvar,[sourcepid],[timeout][,[handle]]...)
WRITE /ACCEPT を使用すると、GT.Mプロセスは別のGT.MプロセスからDETACHされたTCPソケットまたはローカルソケット(つまり、ソケット・プール内のソケット)を受け取ることができます。送信プロセスは、ソケットを送信するために WRITE /PASS を実行する必要があります。
lvar は、添字なしのローカル変数名(lvn)で、ピリオド( "." )接頭辞で示される参照によって渡されなければなりません。正常終了すると、指定された添字なしの lvn には、受信したソケットのハンドルが、送信された順番で垂直バー( " | ")で区切られて格納されます。GT.Mはソケットをソケットプールに配置するので、後で使用するためのSOCKETデバイスに結合(ATTACH)できます。
数値の sourcepid が指定されている場合、GT.Mはその値をソケットを送信するプロセスのプロセスID($JOB)と照合します。サービスを実装していないプラットフォーム(HP-UX)では、GT.Mは targetpid を無視します。pid が一致しない場合、GT.MはPEERPIDMISMATCHエラーを発行し、ソケットを転送しません。
数値のタイムアウトが指定されている場合、指定した時間内に転送が完了するとGT.Mは $TESTを1に設定し、そうでなければ $TESTを 0 に設定してソケットを転送しません。
ハンドルが指定されている場合、GT.Mは、送信プロセスのWRITE /PASSに表示される順序で、受信したソケットに提供されたハンドルを割り当てます; コンマで区切られたハンドルリスト内の空のアイテムは、順序を保持するように動作します。リストにハンドルがない場合、ソケットは送信側が提供するハンドルを保持します。どちらの場合でも、転送ハンドルを持つソケットがソケットプールにある場合、GT.Mは転送ソケット用の新しいハンドルを生成します。GT.Mは、着信ソケットの数を超えて指定された余分なハンドルを無視します。
WRITE /PASS と WRITE /ACCEPT の両方とも、現在の $IO はCONNECTED(LISTENではない)とLOCALドメイン(TCPでない)ソケットを持つSOCKETデバイスである必要があります。GT.Mは、これらの条件が満たされていない場合、それぞれ、CONNSOCKREQ または LOCALSOCKREQエラーを発行します。
SOCKETデバイスは、同じCONNECTED LOCALソケットでのソケットの受け渡しと他のREADおよびWRITEの混合をサポートせず、SOCKPASSDATAMIXエラーを生成します。アプリケーションは、CLOSEを発行する前に、複数の WRITE /PASS と WRITE /ACCEPT 操作をソケット上のいずれかの方向に実行することができます。
受信プロセスは、すべてのソケットの特性を提供するSOCKETデバイスにそれをATTACH(アタッチ)することによって、または、適切なデバイスパラメータを指定する後続のUSEによって、要求するデバイスパラメータ(例えば、DELIMITER)を確立しなければならないことに注意してください。GT.Mは、ソケット接続自体、ソケットハンドル、バッファされたソケットデータ(存在する場合)のみを転送します。
WRITE /TLS(option[,[timeout][,tlsid]])
SOCKETデバイスは、暗号化プラグインを使用してTLSで暗号化接続をサポートします。GT.Mには、OpenSSLを使用するプラグインのリファレンス実装が付属しています; リファレンス実装はGT.Mレプリケーション・ストリーム用のTLSもサポートしています。OpenSSLオプションは、設定ファイルによって制御されます。WRITE /TLSコマンドは、接続されたソケットに対してこの機能を有効にします。
オプションは "TLS" の役割を示す "サーバ"または "クライアント"です。サーバーの役割には、構成ファイルのセクションで指定された証明書と、tlsid に一致するラベルが必要です。クライアントの役割は、OpenSSLオプションに応じて証明書を要求することがあります。引数にタイムアウトが指定されている場合、GT.Mは、コマンドが正常に完了した場合は$TESTを 1 に、タイムアウトした場合は 0 に設定します。$DEVICE は、エラーが発生した場合のステータス情報を提供します。ZSHOW "D" には、暗号化されたソケットの出力の2行目に「TLS」が含まれています。
SOCKETデバイスのアクションによって、TLSDLLOPEN, TLSINIT, TLSCONVSOCK, TLSHANDSHAKE, TLSCONNINFO, TLSIOERROR, TLSRENEGOTIATE というエラーが生成されることに注意してください。
TLSプラグインは、すべてのTLS接続のデフォルトとして tls:label の下に指定された設定ファイル内のOpenSSLオプションを使用し、特定のラベルの下で対応する接続のデフォルトを上書きします。GT.Mは、両方のソケットで次のことを認識します:
cipher-list オプションは、使用する暗号アルゴリズムを指定します。このオプションの形式は、OpenSSL ciphers のmanページで説明されています。空の文字列は、レプリケーション接続の場合はデフォルト値 "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH" を使用し、ソケット接続の場合は OpenSSLのデフォルトの暗号リストを使用します。
SSL_set_options のマニュアルページに記載されている ssl_optionsは、OpenSSLのデフォルトの動作を変更します。複数のオプションを指定する場合は、コロン(:)デリミタで区切ります。ラベル付きセクションで指定された ssl-options は、 "tls" レベルで指定された ssl-optionsを追加または上書きします。ラベル付きセクションのオプションに先行する感嘆符 ("!") は、tls: level で指定されたオプションのデフォルトを無効にします。例えば:
tls: { ssl-options: "SSL_OP_CIPHER_SERVER_PREFERENCE"; mylabel: { ssl-options: "!SSL_OP_CIPHER_SERVER_PREFERENCE"; }; }
verify-mode オプションは、OpenSSLが証明書をどのように検証するかを指定します。verify-mode が指定されていない場合、ソケット接続のデフォルトはSSL_VERIFY_NONEになります。SSL_VERIFY_PEER とSSL_VERIFY_NONE でテストしました。詳細については、SSL_set_verify のマニュアルページを参照してください。 SSL_VERIFY_PEER には、サーバーの役割(role)の検証のみを変更する2つの追加フラグがあります; それらをオプション文字列に追加する場合は、コロン (:) デリミタを使用します。
ラベル付きセクションで指定された verify-depth オプションは、そのセクションに関連付けられた接続に適用されます。
証明書ファイルの先頭に証明書の秘密鍵を置くときは、構成ファイルから「key」アイテムを省略することができます。結合されたファイルの形式は次のとおりです:
-----BEGIN RSA PRIVATE KEY----- [encoded key] -----END RSA PRIVATE KEY----- [empty line] -----BEGIN CERTIFICATE----- [encoded certificate] -----END CERTIFICATE----- [empty line]
GT.Mは、次の USE :FLUSH, WRITE !, WRITE # 、または内部400ミリ秒タイマーが満了するまで、WRITEをTLS対応ソケットにバッファリングします。
注意 | |
---|---|
この機能には多種多様なユーザー・ストーリー(ユースケース)があり、複雑なコードを使用しているため、テストで十分な幅のユースケースを実行したとは確信していません。また、完全に下位互換性がない将来のリリースでも変更を加えることがあります。この機能を開発およびテストに使用し、フィードバックを提供することをお勧めします。FISのお客様でプロダクションでこれを使用したい場合は、事前にお問い合わせをしてユースケースについてご相談ください。 |
注意 | |
---|---|
すべてのプラットフォーム上で、特にLinux以外のUNIXプラットフォームで、GT.Mがサポートする幅広いプラットフォームおよびバージョンで使用されているOpenSSLバージョンの範囲のために、FLSは、TLSを使用するプロダクションまたはプロダクションステージング環境用に、ご使用のシステムにインストールされている特定のOpenSSLバージョンのGT.Mバイナリディストリビューションに含まれているソースからプラグインを再ビルドすることを推奨しています。参照実装の再コンパイルの詳細については、 GT.M管理および操作ガイド の「GT.Mのインストール」の章を参照してください。 |
各ソケットは、次の状態のいずれかになります($KEYを通して観測可能)。
Created (クリエイト) – ソケットが存在することを示します。
ESTABLISHED - CONNECTデバイスパラメータでOPENまたはUSEが成功した後、またはGT.Mがソケットを$PRINCIPALデバイスとして起動したとき。
LISTENING - LISTENデバイスパラメータでOPENまたはUSEが成功し、リッスン・キューが確立されたことを示します。
新しい接続を受け入れるために使用されるリスニング・ソケットは、1つのステップで3つの状態を1つのOPENまたはUSEで処理します。サーバーが WRITE /WAIT を実行すると、クライアントは新しいサーバー・ソケットを作成する接続を確立できます。$KEY には、この新しいソケットに関する情報が CONNECT|handle|<address> の形式で入ります。ここで、<address> はTCPソケットのIPアドレスおよびLOCALソケットのパスです。
各ソケットには、着信接続またはREAD可能なデータを待っているソケットが1つ以上あります($ZKEYを通して観測可能)。$ZKEY には、現在のSOCKETデバイスの待機ソケットを詳述するセミコロン( " ; ")で区切られたエントリのリストが含まれています。
$KEY と $ZKEYの詳細については、 第8章: “固有の特殊変数” を参照してください。
次の表は、ソケットデバイス用のデバイスパラメータの簡単な要約です。
デバイスパラメータのエラー処理 | ||
---|---|---|
デバイスパラメータ |
コマンド |
コメント |
EXCEPTION=expr |
O/U/C |
デバイス特性のエラーハンドリングを制御 |
IOERROR=strexpr |
O/U |
use [NO]TRAP 、strexpr として $LENGTH(strexpr)&("Tt"[$EXTRACT(strexpr)) の場合、エラー・トラッピングが有効になります; そうしないと、アプリケーションは $DEVICEでエラーをチェックする必要があります。 |
デバイスパラメータのフォーマット | ||
---|---|---|
デバイスパラメータ |
コマンド |
コメント |
[NO]DELIMITER[=strexpr] |
O/U |
strexpr はソケット・デリミタを指定します; コロン(:)を使用してリストを区切ります。 |
[NO]FILTER[=strexpr] |
U |
strexprは、ソケット出力の文字フィルタリングを指定します。 |
LENGTH=intexpr または ZLENGTH=intexpr |
U |
ソケットデバイスの仮想ページの長さをセット |
ICHSET=strexpr |
O/U/C |
strexpr は入力文字セットを指定します |
OCHSET=strexpr |
O/U/C |
strexpr は出力文字セットを指定します |
O/U |
デバイスの幅より長いレコードのハンドリングを制御 |
|
WIDTH=intexpr |
U |
出力メッセージの最大長を制御 |
Z[NO]FF[=strexpr] |
O/U |
WRITE # に応答して送信する文字かどうか、および、どのような文字か制御 |
sockexamplemulti31.m
ルーチンは、基本的なソケットI / O設定で $KEYと$ZKEY の使用を示します。多くの機能を実証するために、その機能は非典型的です。2つのジョブを起動: リッスン・ソケットを開くサーバー・プロセスとサーバーへの5つの接続を行うクライアントプロセスサーバーは各接続ソケットにメッセージを送信します。偶数番号のクライアント・ソケットは、メッセージを部分的に読み取りますが、応答をサーバーに返送しません。奇数番号のクライアント・ソケットは、完全なメッセージを受信し、メッセージ「OK」をサーバに応答します。サーバーは2文字を読み込みますが(クライアントは3文字を送信します)、$ZKEY はソケットに未読文字を表示します。ダウンロード sockexamplemulti31.mをクリック してsockexamplemulti31.m プログラムをダウンロードし、プログラム・ファイルの上部にあるコメントの指示に従ってください。http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/sockexamplemulti31.m から sockexamplemulti31.m をダウンロードすることもできます。
inetd / xinetdを使用して行われた接続要求に応答して、GT.Mプロセスを開始することができます。次の例では、inetd / xinetdを使用して、前の例と同様に接続とメッセージに応答するリスナーを実装しています。
xinetd の設定ファイルで、gtmserverという新しいサービスを定義します。socket_typeを「stream」に設定し、次のスニペットのように「no」を待ちます:
service gtmserver { disable = no type = UNLISTED port = 7777 socket_type = stream wait = no user = gtmuser server = /path/to/startgtm }
/etc/services にサーバーを定義すると、タイプとポートのオプションは必要ありません。詳細については、xinetd.confのマニュアルページを参照してください。
inetd を使用している場合、sockettype "stream"、プロトコル "tcp" を持つ /etc/inetd.conf に行を追加し、以下の例のように "nowait" フラグを指定します。これは /etc/services に gtmserver サービスが定義されていることを前提としています:
gtmserver stream tcp nowait gtmuser /path/to/startgtm
上記の両方の例では、 "gtmuser" は gtmserver サービスを所有して実行するユーザの名前で、 "/path/to/startgtm" はGT.Mを呼び出す前に必要ないくつかの環境変数を定義するスクリプトの名前です。ご使用のシステムのinetd.confのマニュアルページを確認してください。詳細は多少異なる場合があります。
最小の変数は、GT.M配布を含むディレクトリを指定する $gtm_dist、および、GT.Mルーチンを見つけるために使用されるパスを指定する $gtmroutines です。例として:
#!/bin/bash cd /path/to/workarea export gtm_dist=/usr/local/gtm export gtmroutines="/var/myApp/o(/var/myApp/r) $gtm_dist" export gtmgbldir=/var/myApp/g/mumps.dat $gtm_dist/mumps -r start^server
start^server が始まると、$PRINCIPALデバイスはソケットに接続された現在のデバイスで、$KEY には "ESTABLISHED | socket_handle | remote_ip_address" が含まれています。ほとんどの場合、ルーチンの始めの近くにあるUSEコマンドは、デリミタなどのさまざまなデバイスパラメータを設定します。
ZSHOW "D" コマンドは、ローカルおよびリモートアドレスとポートを含むTCPソケットのローカル側とリモート側の両方で利用可能な情報を報告します。
0 OPEN SOCKET TOTAL=1 CURRENT=0 SOCKET[0]=h11135182870 DESC=0 CONNECTED ACTIVE NOTRAP REMOTE=10.1.2.3@53731 LOCAL=10.2.3.4@7777 ZDELAY ZIBFSIZE=1024 ZIBFSIZE=0