2009年10月12日月曜日

翻訳している文書

勉強のために翻訳したものを公開しています。訳の内容については保証できませんので、参考にする場合はご注意ください。

RFC 3588 Diameter Base Protocol
2009/05/09 1章だけ完了
RFC 4320 Session Initiation Protocol(SIP)の非INVITEトランザクションについて認識された問題を解決するアクション
2009/05/24 本文は完了
RFC 4321 Session Initiation Protocol(SIP)の非INVITEトランザクションに関連付けられて認識されている問題
2009/05/24 本文は完了
ETSI TS 183 017 AF-SPDF間におけるポリシー情報交換のためのDIAMETERプロトコル仕様
2009/05/19 5章の途中まで完了。ETSIの文書は公開していいのかどうか不明。。。
TR-069: Wikipedia
2009/07/06 Wikipediaの記事を翻訳。実際の技術仕様は量が多いのでおいおい
MS-CFB: Compound File Binary File Format NEW!
2009/10/12 2章まで完了。

2009年7月30日木曜日

parityfec(parity FEC)

具体的な機能については不明ですが、エラー訂正(パリティ)用のMIMEタイプのようです。FECとはForward Error Correctionの略です。parityfecについてはRFC2733で定義されていて、RFC3009でMIMEタイプとしてaudio/parityfecvideo/parityfectext/parityfecapplication/parityfecが定義されています。

なおparityfecというMIMEタイプは、RFC5109で廃止されています。なぜ今さら投稿したかというと、T.38の勧告の中で出てきたからです。T.38自体RFC2327ベースで書かれているため、こうした古い記事も残っていたのでしょう。

ですので、今さら覚える必要はありません。RFC5109を読んでください。

使い方

fmtpに下記のようなフォーマットの文字列を設定します。

a=fmtp:<number> <port> <network type> <address type> <connection address>

使用例

v=0
o=hamming 2890844526 2890842807 IN IP4 126.16.64.4
s=FEC Seminar
c=IN IP4 224.2.17.12/127
t=0 0
m=audio 49170 RTP/AVP 0 78
a=rtpmap:78 parityfec/8000
a=fmtp:78 49172 IN IP4 224.2.17.12/127
m=video 51372 RTP/AVP 31 79
a=rtpmap:79 parityfec/8000
a=fmtp:79 51372 IN IP4 224.2.17.13/127

2009年7月3日金曜日

PCMU(G.711 mu-law) / PCMA(G.711 A-law)

PCMU/PCMAは言わずと知れた一般的なIP電話のコーデックです。G.711 u-lawとも呼ばれます。RFC4856のSection 2.1.18にSDPでの指定方法が登録されています。一方PCMAはPCMUよりダイナミックレンジが若干狭いようです。Wikipediaによれば規定により、1カ国でもA-lawを使う国があれば、国際接続ではA-lawが使われるそうです。PCMAはRFC4856のSection 2.1.17にSDPについて記述があります。

概要

G.711の仕様書は以下にあります。

G.711のサンプリングは8000Hzで1サンプル1バイトですので、64kbpsになることが一般的です。

PCMUもPCMAもG.711の1つですが、PCMUはmu-lawアルゴリズムを、PCMAはA-lawアルゴリズムを使用する、という違いがあります。

(RFC3551) 4.5.14 PCMA and PCMU (拙訳)

PCMAとPCMUはITU-Tの勧告でG.711と規定されている。オーディオデータは対数スケーリング(logarithmic scaling)後にサンプル毎に8bitでエンコードされる。PCMUはmu-lawスケーリングを、PCMAはA-lawスケーリングを意味している。詳細な記述はJayantとNollによって提供されている。[15] 各G.711オクテットはRTPパケット内に整列(octet-aligned)されるべきである(SHALL)。各G.711オクテットの符号ビットはRTPパケット内のオクテットの最上位ビットに一致するべきである(SHALL)(つまり、G.711のサンプル数の推測はホストマシン上でオクテットとして扱われ、符号ビットはホストマシンのフォーマットによって定義される、オクテットの最上位ビットとすべきである)。G.711の56kb/sと48kb/sモードはRTPへは適用されない。PCMAとPCMUは常に8ビットでサンプリングされ、転送されなければならないからである(MUST)。

使い方

PCMU/PCMAのパラメータ
パラメータ名説明
メディアタイプ audio
メディアサブタイプ PCMU PCMA
必須パラメータ
rateRTPタイムスタンプのクロックレートで、これはサンプリングレートに一致します。一般的には8000ですが他のレートが指定されることもあります。仕様上も「名目上1秒間に8000サンプル。誤差は±50ppmまで」と言っているだけで、制限については書かれていません。チャンネル数を2ch(=ステレオ)にする場合は、サンプリングレートを2倍(16000)にします。こうすることで、左右交互にデータがインタリーブされ、8000Hzの音が左右から出るのと同じ効果が得られます。
オプションパラメータ
channels 何本のオーディオストリームが使用されるかを示します。デフォルトは1、ステレオは2です。それ以外も指定可能です。インタリーブは1バイトサンプルされる毎に実施されます。チャンネル順序はRFC3551で規定されています。「チャンネル数毎のチャンネル順序」にRFC3551からの抜粋を示します。
ptime RFC4566参照
maxptime RFC4566参照
チャンネル数毎のチャンネル順序
チャンネル数記述チャンネル
2stereol r
3 l r c
4 l c r S
5 FlFrFcSlSr
6 l lcc r rcS
凡例
l left
r right
c center
S surround
F front
R rear

使用例

サンプリング周波数8000のPCMUとPCMAでコーデックネゴシエーションするオファーをする場合。
v=0
o=john 51050101 51050101 IN IP4 offhost.example.com
s=-
c=IN IP4 offhost.example.com
t=0 0
m=audio 5004 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
サンプリング周波数16000でPCMUのステレオ(2チャンネル)をオファーをする場合。アンサーでこのオファーに同意した場合、左右から8000Hzでサンプリングされた音声が流れます。
v=0
o=john 51050101 51050101 IN IP4 offhost.example.com
s=-
c=IN IP4 offhost.example.com
t=0 0
m=audio 5004 RTP/AVP 0
a=rtpmap:0 PCMU/16000/2

2009年5月23日土曜日

RFC3261を読み解こう: 再送のまとめ

Timerについて前回まとめたので、今回は再送のロジックについてまとめます。再送の動作もRFC3261読んだだけでは全くイメージできませんからね。状態機械だけ見てイメージできる人がいるんでしょうか。うらやましい。

INVITEの再送動作(300~699応答の場合)

  • INVITEの再送はUDPでのみ行います。
  • INVITEを受信したUAは200ms以内に最終応答が返却できる保証がなければ100を返送しなければなりません(MUST)。普通そんな保証はないのでよほどの理由がない限り100を返送します。
  • INVITEを受信したUAはINVITEの再送を受信する度に直前の暫定応答を再送します。が、100は再送されません。なぜなら100はサーバトランザクションがProceeding状態のときに扱う暫定応答に含まれていないからです(RFC3261 17.2.1 Figure.2参照)。
  • INVITEを受信したUAはProceedingにいる間なら任意のタイミングで何度でも暫定応答を送信できます。
  • 暫定応答を受信したUAはINVITEEの再送を停止し、最終応答を待ちます。
  • 300~699の最終応答の再送はUDPでのみ行います。
  • 300~699の最終応答に対するACKは1つのINVITEトランザクションの中のものとして扱われます。
  • 300~699の最終応答を受信したUAはその度にACKを再送します。
  • ACKを受信したUAはConfirmedになり、再送されてくるACKを待ち受けて破棄します。
  • どのUAもTerminatedになったらトランザクションを直ちに解放します。
  • Terminatedになった後に受信した信号は全て新規のものとして扱います。

INVITEの再送動作(200応答の場合)

  • INVTEの最終応答が200の場合、UASは最終応答送信時に、UACは最終応答受信時にTerminatedに移行します。ただし、これだとINVITEがフォークされていた場合に後から来た応答に対応できないため、Timer LとTimer Mが新しく定義されています。がまだ正式な仕様になっていないため説明は割愛します。
  • 200は300~699と違い、UAS→UACのエンドエンドで流通するため、UASのみが生成できます(プロキシは200を生成してはいけません)。
  • 200は300~699と違い、トランザクションの外で再送されます。その再送のタイミングはTimer Gと同じなのですが、なぜか再送用のタイマや再送T.Oのタイマは定義されていません(RFC3261 13.3.1.4参照)。
  • UACのみがACKを生成でき、200を受信する度にACKを再送します。

非INVITEの動作

  • 非INVITEのサーバトランザクションもINVITEサーバトランザクションと同じような動作をしますが、非INVITEサーバトランザクションにはなぜかTryingステートがあります
  • 非INVITEサーバトランザクションはRFC3261上、暫定応答を送信してもいいことになっていますが、RFC4320(和訳)で色々な条件付きで禁止されています。この記事はRFC3261に関する説明と言うことで割愛します。
  • 非INVITEトランザクションでは200とそれ以外の応答とで動作の違いはありません。
  • 非INVITEクライアントトランザクションでは、暫定応答や最終応答を受信しても、リクエストの再送を継続します(UDPに限り)。
  • 最終応答の再送はリクエストの再送契機で行われます。だから暫定応答を受信してもリクエストの再送を止めないのです。

ゼロから学ぶSIP: 第04回 SIPメッセージの中身と通信方式

SIPはSIPメッセージと言うテキスト形式のデータをやりとりすることで、セッションを確立します。具体的に言うと、TCPやUDPの様なトランスポートプロトコルのデータ部(=ペイロード)にSIPメッセージを載せ、これを通信者同士で送受信し合うことで、必要な情報を共有していきます。

SIPメッセージはその内容によってリクエスト(要求)とレスポンス(応答)の2種類があります。リクエストはセッションを開始/変更/終了しようするときにUACから送出されるSIPメッセージです。レスポンスはUASからリクエストの成功または失敗を返却するためのSIPメッセージです。

SIPメッセージは大きく分けて以下の3つの部分で構成されています。

スタートライン
リクエストの場合はリクエストの種類(メソッド)、レスポンスの場合は成功または失敗を表すコード(ステータスコード)を記述。
ヘッダ部
SIP自身のプロトコルで必要となる情報(=発着の論理アドレス、ルーチングの為の情報等)を記述。
ボディ部
セッションを確立させる為の情報(=発着のIPアドレス/ポート番号、メディア情報等)を記述

スタートラインはリクエスト、レスポンスでそれぞれ以下の様な形式で記述します。

リクエスト
INVITE sip:bob@biloxi.com SIP/2.0
レスポンス
SIP/2.0 200 OK

ヘッダやSDPの詳細の説明はここでは割愛します(基本的すぎるので)。RFC3261に記述されているSIPメッセージの例を参考までに示しておきます。

リクエストの例(INVITE)

INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com>
Content-Type: application/sdp
Content-Length: 142

レスポンスの例

SIP/2.0 200 OK
Via: SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bKnashds8;received=192.0.2.3
Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds ;received=192.0.2.1
To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:bob@192.0.2.4>
Content-Type: application/sdp
Content-Length: 131

セッションを確立させるための情報はSession Description Protocol: SDPというプロトコルに従って記述するのが一般的です。SDPは現在はRFC4566で定義されています。

SIPでセッションを確立させるには、まず発信者がSIPメッセージにメディア情報を記述したリクエストを出し、着信者がその中から対応可能なメディアを選択したレスポンスを返却することで、通信に使用するメディア情報を共有します。このようにセッションを開始するためにSIPメッセージにメディア情報を載せることをオファーといい、それに対して対応可能なメディア情報を返却することをアンサーといいます。このオファーアンサーモデルについてはRFC3264で定義されています。

ボディ部にはSDPを記述しますが、SDPはオファーもしくはアンサーのときのみ必要なので、それ以外の場合はボディ部は空になります。

ここではリクエストでオファーし、レスポンスでアンサーする例をあげましたが、場合によってはレスポンスでオファーし別の何らかの方法を使ってアンサーを返却することもできます。詳しくはRFC3264を参照してください。

ボディ部にはセッションで利用されるメディア情報をSDPで記述しオファーアンサーで共有する、ということは上述しましたが、ヘッダ部に記述される情報はどのように利用されるのでしょうか。実はここからがSIPの真髄です。ルーティングやらダイアログやらターゲットやら、複雑な話がたくさん出てきます。それらについては次回以降で説明していきます。

2009年5月17日日曜日

RFC3261を読み解こう: Timerのまとめ

SIPのRFC3261にはたくさんのタイマ(Timer)が定義されていますが、本文内のあちこちに書かれていて、結局どのタイミングでどのタイマがいくつに設定されるのか、いまいちよくわかりません。本稿ではRFC3261に散りばめられたタイマについてまとめ、上記の問題を払拭します。

まずは「付録A タイマ値表(英語)」にちょっと補足したものを以下に示します。なお、これ以降RFC3261内の「信頼性のないトランスポート」を意味する箇所をUDP、「信頼性のあるトランスポート」を意味する箇所をTCPと表記することにします。また各タイマのn回目に更新された値を「An」のように表現していますが、これは本稿で便宜上定義するもので、RFC3261内に同様な記述はありません。

タイマ値表
タイマ設定値説明
T1 500ms RTTの推定値です。限定的なネットワークでない限り500ms以下は推奨されません(NOT RECOMMENDED)。一方、応答に時間がかかることが分かっている場合は500msより大きくすることが推奨されています(RECOMMENDED)。UACとUASそれぞれのT1値が異なる場合がありえますが、UAC、UAS共に相手のT1値を知ることはできません(≒知る仕組みがありません)。
T24sINVITEリクエスト以外の全ての再送処理における、最大再送間隔を表します。初期値は4sと規定されていますが、他の値にしていいのかどうかはRFC3261には規定されていません。
T4 5s 既に処理が終わったメッセージの再送を受け取るための時間です。このタイマが有効な間は該当の再送メッセージを再送として受け取り、タイマが満了すると新規レスポンスとして処理します。初期値は5sと規定されていますが、他の値にしていいのかどうかはRFC3261には規定されていません。
Timer A A0 = T1
An = An-1×2
INVITEの再送の為のタイマ。このタイマが満了するたびにINVITEを再送し、値を更新します。UDPでのみ左記の設定値が適用され、TCPでは常に0(=再送しない)となります。理屈上無限に大きくなりそうですが、Timer B(=64s×T1)が満了するとその時点でトランザクション終了となるため、実際はA5までしかないのが普通です。
Timer B 64s×T1 (UDP/TCP) INVITEクライアントトランザクションがCalling状態でいられる最大時間。満了するとトランザクション状態がTerminatedへ遷移します。いかなるトランスポートでも64s×T1となります。
Timer C Timer C > 180s プロキシがINVITEを転送するときにクライアントトランザクションに設定するタイマ。180s(3分)より大きい値でなければならず(MUST)、暫定応答を受信するたびに180sより大きい値で更新されます。満了した場合は、暫定応答をもらっていればCANCEL送出、暫定応答がなければ408応答を受信したかのように動作しなければなりません(MUST)。なお、プロキシのみに設定される値で、UACには設定しません。これは、UACは任意にCANCELでINVITEトランザクションを終了できますが、プロキシは(Timer Cがなければ)自発的にCANCELを送出する契機を持っていないからです。
Timer D > 32s (UDP)
= 0s (TCP)
INVITEトランザクションで300~699を受信したときに、ACKを返却する期間。
Timer E E0 = T1
En = min(En-1×2, T2)
非INVITEトランザクションにおいて、UACがリクエストを再送するためのタイマです。最大でT2にしかならない、という点を除いて、Timer Aと同じです。
Timer F 64s×T1 (UDP/TCP) 非INVITEトランザクションにおいて、UACが暫定応答をもらうまでのタイマです。Timer Bと同じです。
Timer G G0 = T1
Gn = min(Gn-1×2, T2)
INVITEサーバトランザクションにおいて、UASが300~699までの最終応答を再送するためのタイマです。Timer Eと同じ更新の仕方をします。
Timer H 64s×T1 (UDP/TCP) INVITEサーバトランザクションにおいて、UASが300~699までの最終応答に対するACKを受信するまでの時間です。UDP、TCPともに左記の値にします。満了した場合はTerminatedに遷移してトランザクションを破棄します。
Timer I = T4 (UDP)
= 0s (TCP)
INVITEサーバトランザクションにおいて、UASがACKの再送に備える時間です。満了する以外に消滅契機はありません。満了した場合はTerminatedに遷移してトランザクションを破棄します。
Timer J = 64s×T1 (UDP)
= 0s (TCP)
非INVITEサーバトランザクションがCompleted状態にいられる時間。Timer Hと同じ役割。
Timer K = T4 (UDP)
= 0s (TCP)
非INVITEクライアントトランザクションがCompleted状態にいられる時間。Timer Dと同じ役割。
Timer L 64s×T1 RFC3261非掲載。トランザクション状態がAcceptedのときに受理済みのINVITEの再送を受け付けるタイマ。詳しくはdraft-sparks-sip-invfixを参照。
Timer M 64s×T1 RFC3261非掲載。200の再送またはフォークされた先からの200の再送を受け付けるタイマ。詳しくはdraft-sparks-sip-invfixを参照。

2009年5月7日木曜日

ゼロから学ぶSIP: 第03回 SIPの登場人物、UAとSIPサーバ

SIPを使った通信をするときに登場する登場人物(装置)は以下の通りです。

  • 通信者(UA: User Agent)
    • 通信元(UAC: User Agent Client)
    • 通信先(UAS: User Agent Server)
  • SIPサーバ(またはプロキシサーバ)

通信をするユーザのことをUAと呼びます。電話の場合は加入者(の端末)のことです。チャットの場合はサービスに入っているメンバのことです。

UAが通信を開始しようとするとき、そのUAをUACと呼び、通信に招待されるUAをUASと呼びます。つまりUACとUASの間のセッションを成立させることがSIPの目的であると言えます。UACとUASがお互いのIPアドレス/ポート番号とメディアの情報をSIPメッセージをやり取りすることで共有できれば、目的達成ができるというわけです。なお、UACとUASは論理的な立場のようなもので、1回のトランザクション(リクエストとレスポンスのセット)が終了するとなくなります。そして次にリクエストを出すときに改めてUAC、UASが定義されます。そのため、リクエストを出す方向が逆になればUAC、UASも逆転します

しかしSIPメッセージをやり取りするためには、SIPメッセージをやり取りするためのIPアドレス/ポート番号が必要になります(ややこしい。。)。例えば電話の場合、通信先(着信先)の電話番号は知っているかもしれませんが、IPアドレスなんて知らないことが多いです。つまり、UACがUASのIPアドレスを知らなくても、電話番号やメールアドレス(チャットの場合)さえあれば相手にSIPメッセージが届く仕組みが必要になります。そこで登場するのがSIPサーバ(プロキシサーバ)と呼ばれるSIPメッセージを中継するサーバです。

SIPサーバは、UACからのSIPメッセージ(正確にはリクエスト)に記述されている電話番号やメールアドレスのような論理的なアドレスを基に、適切なUASや別のSIPサーバへとSIPメッセージを中継します。具体的にはリクエストのSIPメッセージ内に記述されているRequest-URIToヘッダを見て経路選択を行います。この経路選択のことをルーティングと言います。SIPサーバはリクエストだけでなく、レスポンスも中継します。

SIPサーバは、どんなリクエストをどこにルーティングすればいいかを知っています(そう設定されています)。電話の場合、それは電話番号と接続先(UAS or 他のSIPサーバ)を関連付けた単純なリスト(あるいはデータベース)のようなものですが、どんなリクエストをどこにルーティングするのかはSIPでは規定されていない為、どこへどうつなぐかはSIPサーバの胸三寸です。また時と場合によって接続する先を変えてもかまいません。これは例えば、同じ電話番号へかけても、接続先が輻輳している場合にガイダンスサーバへつないだり、着信先が収容変え(番号ポータビリティ)で他の事業会社に収容されているかもしれないからです。いづれにしても、(リクエストがエラーにならない限り、)SIPサーバが中継動作を繰り返すことで、必ずどこかのUASへと辿りつくことができます

上記のSIPサーバの動作によって、UACは通信先の論理的なアドレスをSIPメッセージに記述し、それをSIPサーバに渡すだけで、ルーティングをSIPサーバに任せることができます。UACはリクエストを書くことだけに専念すればいいわけです。

SIPサーバの動作はとてもたくさんあり、全てを説明することはできませんが、基本的には上述の通り、受信したリクエストの論理的なアドレスを見て適切にルーティングすることです。

まとめると、SIPを使って通信をするときには、発信者(UAC)、着信者(UAS)という2つのUA以外に、SIPサーバ(プロキシサーバ)という中継サーバがあり、これがルーティング機能を全て賄ってくれるので、UAはSIPサーバからのリクエスト、レスポンスだけを処理すればいいことになります。