Open6

MiniSock: C APIの設計

okuokuokuoku

MiniSockのC APIを適当に用意する。 ... 一度適当に作ったあとPOSIXなりlwIPなりで実装してみて、合わなかったところを摺り合わせる作戦で行こうと思う。

後回し機能

  • no copyなsend/receive
  • scatter / gather
  • マルチキャストとブロードキャスト
okuokuokuoku

初期化・終了

全ての操作はコンテキスト msck_ctx_t* を通じて操作することになるため、コンテキストの確保、開放操作が必要になる。 コンテキストの作成数に上限があっても良い

create APIはバックエンドが独自拡張するケースが想定される。このため default を含んだAPIをとりあえず定義しておく。

コンテキストの解放操作である destroy は必ず成功する。失敗をハンドルする妥当な方法が存在しないため。

int msck_ctx_create_default(msck_ctx_t** out_ctx, void* cb, uintptr_t data);
void msck_ctx_destroy(msck_ctx_t* ctx);
void msck_ctx_step(msck_ctx_t* ctx, int waitok);
okuokuokuoku

セッションの作成・破棄

MiniSockは全ての通信を接続指向で行うものと見做す。UDPであっても、通常のシチュエーションでは対話を行うため、セッションの作成が必要になる。

destroy は明示的に行う必要がある。

int msck_session_create(msck_ctx_t* ctx, 
    msck_session_type_t st,
    msck_name_type_t nt, const char* name, size_t namelen,
    uintptr_t arg0, uintptr_t arg1,
    uintptr_t data,
    msck_session_t** out_session);

void msck_session_destroy(msck_ctx_t* ctx, msck_session_t* session);

セッションタイプ

セッションタイプは、 enum で表現される。

タイプ 内容
MSCK_SESSION_TYPE_STREAM TCP (バイトストリーム)
MSCK_SESSION_TYPE_STREAM_SERVER TCP (バイトストリーム、Listen)
MSCK_SESSION_TYPE_DATAGRAM UDP

名前空間タイプ

名前は const char* で表現されるが、その指す先のデータが何であるかを名前空間タイプで表現する。

タイプ 内容
MSCK_NAME_TYPE_VIRTUAL 管理用の仮想名
MSCK_NAME_TYPE_IPV4 IPv4 numeric
MSCK_NAME_TYPE_IPV6 IPv6 numeric
MSCK_NAME_TYPE_DNS DNS name
MSCK_NAME_TYPE_DNS_IPV4 DNS name (v4 only)
MSCK_NAME_TYPE_DNS_IPV6 DNS name (v6 only)
okuokuokuoku

送信

送信はブロッキングと非ブロッキングを選択できる。これは受信がイベント処理として行われる都合でイベントハンドラからブロッキング送信がブロックされるのを防ぐ必要があるため。

どちらのケースも、関数から戻ってきた後はバッファを解放して良い。no copy版はもし必要なら別途。

バッファの解放はコールバックが呼出されたタイミングで実施できる。つまり、ストリームするためにコールバックから次々とsendするということが可能である。送信処理自体はキャンセルできない。

int msck_session_send(msck_ctx_t* ctx, msck_session_t* session, const char* data, size_t datalen);
okuokuokuoku

イベントと受信

イベントは初期化時に与えたコールバック関数に通知される。受信データはコールバック関数から抜けるまでに消費する必要がある。

コールバック関数の基本

void callback(msck_ctx_t* ctx, msck_event_type_t type,
    msck_session_t* session, 
    const char* buf, int arg0,
    uintptr_t data_ctx, uintptr_t data_session); 

コールバック関数は コールバックタイプ、 (ctx, session)の組とそれぞれに対応した data 、1つのデータバッファを通知する。

処理のブロック

EDIT: ブロッキングは一旦仕様から外した。

msck_send 以外のAPIは、コールバック内で呼びだしても完了することが保証される(エラーになる可能性はある)。また、コールバック内で msck_send_nowait を呼出しても コールバックは再帰しないことが保証される

msck_send はコールバック内で呼出した場合の挙動は未定義となる。つまり、 msck_send はコールバックの完了を前提として動作しても構わない。

イベントタイプ

タイプ 概要
MSCK_EVENT_TYPE_SESSION_CREATE_RESULT create_session の成否(arg0: エラーコード)
MSCK_EVENT_TYPE_SESSION_DATA データの受信(arg0: バッファバイト長)
MSCK_EVENT_TYPE_SESSION_INCOMING サーバー接続の開始要求
MSCK_EVENT_TYPE_SESSION_TERMINATE セッションの終了(arg0: エラーコード)
okuokuokuoku

(やっぱし無理だった)

  • ブロッキングな send は一旦仕様から外した
  • session_receive API を追加。セッションの作成後、明示的にバッファを与えないと受信がkickされないようにした
  • MSCK_EVENT_TYPE_SESSION_INCOMING イベントと session_accept を追加 (忘れてた)

一旦ダブル(以上)バッファはやらない方向で。