これはscheme1のValidationが有効になるようにRTMPClientがHandshakeしないためです。
Red5のサーバー動作側がscheme1でValidationの確認してるんだから、Red5チームがメンテしわすれたんでしょうね。
さて、この問題をなんとかしてみます。
ちなみに、現状のバージョンのRed5では別にValidation通さなくてもなんの問題もありません。判定だけしてそのまま処理続行してますから。ただの自己満足の色合いが強いです。
ソースコードの全体図はgithubにあげたred5_phpのリポジトリを確認してください。
ここのcom.ttProject.TestClassを実行するとlocalhostの1935ポートのRtmpサーバーのliveアプリケーションに接続しにいくようにしてあります。
まずは変更点の解説
■RtmpClientEx.javaの中
1:コンストラクタ上でioHandlerの初期化を実行
2:startConnectorのメソッドをRTMPClientよりオーバーライド
元ネタのRTMPClientではioHandlerをRTMPMinaIoHandlerとして初期化しています。
このHandlerの内部でつかっているOutboundHandshakeというクラスの中身を必要に応じて変更したいので、Handlerに細工する→Sessionに独自handshakeクラスを注入するという手を使います。
2の方のstartConnectorのメソッドのオーバーライドはioHandlerがprivateではなくprotectedだったら必要なかったのですが、まぁしかたないです。
■RTMPMinaIoHandlerEx
1:sessionCreatedをオーバーライド
このイベントの時に、オリジナルのRTMPMinaIoHandlerの処理を実施したあとに、sessionの設定属性を独自のものに書き換え。
テスト等でオリジナルのRTMPClientのHandshakeを実行したい場合は設定しているOutboundHandshakeExの部分をコメントアウトすれば大丈夫です。
■OutboundHandshakeEx
1:generateClientRequest1をオーバーライド
2:addBytesメソッド
3:calculateOffsetメソッド
2と3は内部で使う補助メソッドです。OutboundHandshakeの中でも定義されているんですが、privateになっているため、コピーしました。
問題は1の部分
大本のOutboundHandshakeクラスの中では次のようにHandshakeが進行します。
はじめにcreateHandshakeBytesメソッドで、timestamp(4バイト) + プレーヤーバージョン指定(4バイト*1) + 1528バイトのランダムバイトをひな形として作成します。
続いてgenerateClientRequest1メソッドで、送信バイトデータとして、Encrypted識別子(0x03)と先ほどつくったひな形をHandshakeのエントリーとして送信しています。(*2)
*1:ここでいうプレーヤーのバージョンは、adobeのFlashプレーヤーのバージョン確認ででるバージョンとは別のデータになります。内部管理用のバージョン番号が別にあるのでしょう。
*2:adobeのサイトのrtmpの仕様書によるとHandshakeの冒頭でc0 c1 c2 s0 s1 s2とクライアントが3回、サーバーが3回データを送信するように設計されていると記述されています。このc0c1に相当するデータが一度に送信されています。(ってか分けてる必要あんのこれ?)
OutboundHandshakeExではひな形はcreateHandshakeBytesでつくってもらってからgenerateClientRequest1上で次のようなことを行っています。
まず、ひな形をローカル変数に保持。
続いて772から4バイトがvalidation用のキーの埋め込み場所を指定するデータとなるため、その4バイトを取得する。
776から728バイトのデータがどうなっているかをキーにSHA256で暗号化するのでその計算を実行。
できたキーを先ほど計算した埋め込み場所に上書き。
でHandshakeのひな形できあがりとなります。
では最後に、conf/logback.xmlでorg.red5.server.net.rtmpをDEBUGにした状態でRed5 1.0.0 RC2 Rev 4222に接続させてみます。
まずは、エラーにRTMPClientでつないだ場合
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Player encryption byte: 3
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Detecting flash player version 9,0,124,2
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Player version byte: 9
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Scheme: 0 client digest offset: 342
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Temp: 1f52f06ea4da019863e8d35badd242cb29be6224613996df3bf3becd2da28676
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Scheme: 1 client digest offset: 1284
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Temp: 32ba98dd706a7c8ecb089ea49c44c31aafe2bbcc5ad0b44e489bbf13e1d0761b
[ERROR] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Unable to validate client
[INFO] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Invalid RTMP connection data detected, you may experience errors
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Using new style handshake
ちゃんと無効なクライアントと判定されてしまいました。Scheme 0もScheme 1も認証がとおっていません。
続いて修正版で接続した場合
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Player encryption byte: 3
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Detecting flash player version 9,0,124,2
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Player version byte: 9
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Scheme: 0 client digest offset: 691
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Temp: 4f19642c794f70f130ac7b159cda40f71a754abbcea4fa40d8bc328923bf0504
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Scheme: 1 client digest offset: 1217
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Temp: 55671918c7a41de1e20d29b1f9b11e3c70951ce34e13f5c4b32b51054bbef963
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Selected scheme: 1
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Valid RTMP client detected
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Using new style handshake
きちんとScheme1を検出して有効と判定してくれました。
まぁやってることは同じですけどw
最後にFlashPlayerでつないだ場合
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Player encryption byte: 3
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Detecting flash player version 128,0,7,2
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Player version byte: 128
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Scheme: 0 client digest offset: 374
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Temp: e038bc995719caece95d042eb4e71a1ffbfb140d4a6ac3aa52e296c742d3082b
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Scheme: 1 client digest offset: 1310
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Temp: 8753c820eb1225042a7c13ce15bc5f99af692caa07986d0125b9567eec7f4bc4
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Selected scheme: 1
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Valid RTMP client detected
[DEBUG] [NioProcessor-1] org.red5.server.net.rtmp.RTMPHandshake - Using new style handshake
これで似た感じの動作になってきました。
0 件のコメント:
コメントを投稿