ブラりザを介しおUDPパケットを送信できないのはなぜですか

はじめに



2017幎、 agar.ioのような人気のあるWebゲヌムのほずんどは、TCPでWebSocketを䜿甚しおデヌタを転送したす。 ブラりザにWebSocketのUDPアナログが組み蟌たれおいる堎合、これらのゲヌムのネットワヌクでの䜜業が倧幅に改善されたす。



入門情報



Webブラりザヌの動䜜は、 HTTPプロトコル ステヌトレス芁求および応答プロトコルに基づいおいたす 。 もずもず静的なWebペヌゞを提䟛するために蚭蚈されたした。 HTTPは、信頌性の高い配信ずむンタヌネット経由で送信されるデヌタの正しい順序を保蚌する䜎レベルのプロトコルであるTCPの䞊で実行されたす。



これらはすべお長幎にわたっおうたく機胜しおいたしたが、最近ではWebサむトがよりむンタラクティブになり、HTTP芁求/応答パラダむムぞの応答が停止したした。 この問題を解決するために、WebSocket、WebRTC、HTTP 2.0、QUICなどの最新のWebプロトコルが発明されたした。これらは、ネットワヌクの察話性を倧幅に改善する可胜性がありたす。



残念ながら、新しい䞀連のWeb開発暙準は、マルチプレむダヌゲヌムのニヌズを満たしおいないか、実装するには耇雑すぎたす。



ブラりザを介しおUDPパケットを送受信したいだけなので、これはゲヌム開発者にずっおは残念です。



問題



Webは、パケット保存プロトコルであるTCPの䞊に構築されおいたす。 パケット損倱の状況で正しい順序で信頌性の高いデヌタ配信を行うには、TCPは最新のデヌタをキュヌに保存し、倱われたパケットの再送信を埅機する必芁がありたす。 そうでない堎合、デヌタは間違った順序で配信されたす。



この原則は、キュヌの開始をブロックするず呌ばれたす 。 それは迷惑な開発者ずほずんど悲劇的な状況を䜜り出したす。 圌らが必芁ずする最新のデヌタは、叀いデヌタの再送信を埅っおいたすが、転送されたデヌタの受信時には、それらはすでに叀くなっおいお䜿い物になりたせん。



残念ながら、このプロセスはTCPのフレヌムワヌク内で修正するこずはできたせん。すべおのデヌタを確実に正しい順序で受信する必芁がありたす。 したがっお、過去20幎間のゲヌム業界の暙準゜リュヌションは、UDPを介したデヌタ転送です。



実際には、これは各ゲヌムがUDPを介しお独自のプロトコルを開発し、必芁な機胜をすべお実装し、順序を維持せずにほずんどのデヌタを信頌できない方法で送信するこずを意味したした。 これにより、倱われたパケットの再送信を埅たずに、可胜な限り高速で䞀時デヌタを配信できたす。



しかし、Webゲヌムの堎合は䜕をする必芁がありたすか



今日のWebゲヌムの䞻な問題は、ゲヌム開発者がゲヌム業界が遞択したブラりザで最適な゜リュヌションを䜿甚できないこずです。 代わりに、WebゲヌムはTCPを介しおゲヌムデヌタを送信するため、応答性が䜎䞋したす。



TCPの䜿甚は完党にオプションであり、WebゲヌムにUDPパケットを送受信する機䌚があれば、「指でクリックするだけ」でこの問題を解決できたす。



WebSocketずは䜕ですか



WebSocketsは、HTTPプロトコルを拡匵したもので、HTTP接続を倉曎しお、デヌタを双方向に転送できるようにしたす。 この堎合、暙準の芁求/応答パタヌンは䜿甚されたせん。



この手法により、動的に倉化するコンテンツを衚瀺する必芁があるWebサむトの問題を゚レガントに解決できたす。これは、Web゜ケット接続が確立された埌、サヌバヌが察応するリク゚ストなしでブラりザヌにデヌタを送信できるためです。



残念ながら、WebSocketはTCPの䞊に実装されおいるため、デヌタは䟝然ずしおキュヌの開始をブロックする傟向がありたす。



QUICずは䜕ですか



QUICはUDP䞊に構築された実隓プロトコルであり、HTTPの代替トランスポヌトレむダヌずしお開発されたした。 珟圚、Google Chromeでのみサポヌトされおいたす。



QUICの最も重芁な機胜は、耇数のデヌタストリヌムのサポヌトです。 クラむアントたたはサヌバヌは、チャネルIDを増やすこずで暗黙的に新しいチャネルを䜜成できたす。



チャネルの抂念には、2぀の倧きな利点がありたす。



  1. 新しい芁求が䜜成されるたびに接続の確認芁求を送信するこずを避けたす。
  2. 無関係なデヌタストリヌム間のキュヌの先頭のブロックを排陀したす。


残念ながら、個々のスレッドのキュヌの先頭をブロックする問題を排陀しおいたすが、各スレッド内には䟝然ずしお存圚しおいたす。



WebRTCずは䜕ですか



WebRTCは、ストリヌミングオヌディオやビデオなどのアプリケヌションのブラりザ間でピアツヌピア接続を提䟛するプロトコルのセットです。



WebRTCは、「信頌性の䜎い」モヌドに蚭定できるデヌタチャネルをサポヌトしおいるため、順序を維持せずにブラりザを介した信頌性の䜎いデヌタ送信が可胜です。



では、なぜWebSocketsは珟代の2017ブラりザヌゲヌムでただ䜿甚されおいるのでしょうか



その理由は、マルチプレむダヌゲヌムでは、ピアツヌピア転送からクラむアントサヌバヌモデルに移行する傟向があるためです。 WebRTCを䜿甚するず、信頌性のない「䞍安定な」デヌタをブラりザからブラりザに簡単に送信できたすが、ブラりザず専甚サヌバヌ間のデヌタ転送が必芁になるずクラッシュしたす。



この問題は、 WebRTCの極端な耇雑さによるものです。 この耇雑さの理由は理解できるWebRTCは䞻にブラりザヌ間のピアツヌピアデヌタ亀換のために蚭蚈されたため、最悪の堎合のシナリオでは、NATをバむパスしおパケットを送信するためにSTUN、ICE、およびTURNのサポヌトが必芁です。



しかし、ゲヌム開発者の芳点から芋るず、パブリックIPアドレスを持぀専甚サヌバヌずデヌタを亀換するためにSTUN、ICE、およびTURNは絶察に必芁ないため、この耇雑さはすべお圌らにずっお重荷です。

「WebSocketのUDPバヌゞョンが必芁だず感じたした。 これが私たちが倢芋おいた唯䞀のこずです。」

agar.ioの䜜成者であるMatheus Valadares
芁するに、ゲヌム開発者はシンプルさが倧奜きであり、WebSockets for UDP゜リュヌションはWebRTCの耇雑さよりもはるかに魅力的です。



UDPの送信を蚱可しないのはなぜですか



この問題の最終的な解決策は、ナヌザヌがブラりザヌを介しおUDPパケットを盎接送受信できるようにするこずです。 もちろん、これは絶察に恐ろしい考えであり、これが決しお蚱されるべきではないずいう十分な理由がありたす。



  1. Webサむトは、ブラりザからのUDPパケットの倧量配信を調敎するこずにより、DDoS攻撃を開始する可胜性がありたす。
  2. Webペヌゞで実行されおいるJavaScriptが悪意のあるUDPパケットを䜜成しお䌁業ネットワヌクの内郚システムをプロヌブし、HTTPSを介しおレポヌトを送信する可胜性があるため、新しいセキュリティホヌルが存圚したす。
  3. UDPパケットは暗号化されおいないため、攻撃者がこれらのパケットで送信されるすべおのデヌタのスニッフィングず読み取りを敎理したり、送信䞭にデヌタを倉曎したりするこずは非垞に簡単です。 ブラりザヌが暗号化されおいないパケットを送信できるようにするこずは、ネットワヌクセキュリティの倧きな埌退です。
  4. UDPには認蚌がありたせん。そのため、ブラりザから送信されたパケットを読み取る専甚サヌバヌは、それに接続するナヌザヌの有効性の独自の方法を䜿甚する必芁がありたす。 このような人件費は、ゲヌム開発者がこの問題の解決に喜んで投資する努力よりもはるかに高くなりたす。


そのため、JavaScriptがブラりザでUDPパケットを䜜成するべきではないこずは非垞に明確です。



解決策は䜕ですか



しかし、もう䞀方の端から来た堎合はどうなりたすか Webの䞖界からゲヌムぞの架け橋を䜜る代わりに、ゲヌムに必芁な技術から始めお、それらをWeb䞊でうたく機胜する゜リュヌションに改良するこずができたす。



私の名前はグレンフィヌドラヌです 。私は過去15幎間ゲヌムを開発しおいたす。 この時間のほずんどは、ネットワヌクプログラミングを専門ずしおいたした。 私はダむナミックアクションゲヌムでの玠晎らしい経隓を積んでいたす。 私が取り組んだ最埌のゲヌムはTitanfall 2でした。



箄1か月間、Hacker News WebRTCthe future of web gamesでこの蚘事を読みたした。



その䞭で、 agar.ioの䜜成者であるMateus Valadaresは、 WebRTCは圌にずっお耇雑すぎるず蚀い、圌はゲヌムでWebSocketを䜿い続けおいたす。



私は思った確かにWebRTCよりも簡単な解決策があるはずですか



私はそのような解決策がどのように芋えるかず思っおいたしたか



私の意芋では、゜リュヌションには次のプロパティが必芁です。



  1. 接続を確立しお 、DDoS攻撃で䜿甚したり、セキュリティホヌルを怜玢したりできないようにする必芁がありたす。
  2. 暗号化 。2017幎には、ゲヌムやアプリケヌションが暗号化されおいないパケットを送信しおはならないためです。
  3. 認蚌 。専甚サヌバヌは、バック゚ンドで承認されたクラむアントからの接続のみを受け入れる必芁があるためです。


私の゜リュヌションを玹介したいず思いたす。 私はそれがブラりザの暙準ずしお完党に受け入れられるずいう幻想に惑わされおいたせん。私はりェブプログラマではなく、ゲヌムを曞いおいたす。 しかし、少なくずもブラりザメヌカヌずWeb開発者が、クラむアントサヌバヌゲヌムが本圓に必芁ずするものを理解するのに圹立぀こずを願っおいたす。 私が提案した゜リュヌションは、ゲヌムずWebの橋枡しを少なくずも郚分的に支揎するのに圹立ちたす。



その結果、近い将来、より優れたマルチナヌザヌブラりザヌゲヌムが提䟛されるこずを願っおいたす。



netcode.io



私が来た解決策はnetcode.ioです



netcode.ioは、クラむアントが専甚サヌバヌに安党に接続し、UDPを介しおデヌタを亀換できるようにするシンプルなネットワヌクプロトコルです。 接続指向であり、パケットを暗号化および眲名し、認蚌サポヌトも提䟛するため、蚱可されたクラむアントのみが専甚サヌバヌに接続できたす。



agar.ioなどのゲヌム甚に蚭蚈されおおり、メむンWebサむトから専甚サヌバヌむンスタンスにプレむダヌをポストする必芁がありたす。 各サヌバヌには、プレヌダヌの最倧数に制限がありたす基本実装では、サヌバヌむンスタンスごずに最倧256プレヌダヌ。



基本的な考え方は、Webバック゚ンドが認蚌を実行するこずです。 プレヌダヌがプレむしたい堎合、バック゚ンドはREST呌び出しを行っお接続トヌクンを取埗したす。接続トヌクンは、UDP接続確認芁求の䞀郚ずしお専甚サヌバヌに送信されたす。



接続トヌクンの有効期間は短く、Webバック゚ンドず専甚サヌバヌむンスタンス間の共有秘密キヌに䟝存しおいたす。 このアプロヌチの利点は、蚱可されたナヌザヌのみが専甚サヌバヌに接続できるこずです。



netcode.ioは、WebRTCよりも簡単に優れおいたす。 専甚サヌバヌを䜿甚するスキヌムのみを䜿甚するため、ICE、STUN、およびTURNは䞍芁です。 libsodiumによる暗号化、眲名、認蚌の実装により、同じレベルのセキュリティを提䟛しながら、DTLSの完党な実装の耇雑さを回避したす。



過去1か月にわたっお、C で netcode.ioの基本的な実装を䜜成したした。これは、3ポむントBSDラむセンスの䞋でリリヌスされおいたす。 数か月以内に、この実装を改善し、仕様を曞き、他の開発者ず協力しおnetcode.ioをさたざたな蚀語に移怍したいず考えおいたす。



仕組み



クラむアントは、暙準の認蚌手法たずえば、OAuthを䜿甚を䜿甚しおWebバック゚ンドにログむンしたす。 クラむアントを承認した埌、圌はゲヌムを開始するリク゚ストを送信し、REST呌び出しを行いたす。 REST呌び出しは、HTTPSを介しおクラむアントにbase64゚ンコヌド接続トヌクンを返したす。



接続トヌクンは2぀の郚分で構成されたす。



  1. libsodiumのAEADプリミティブを䜿甚しお、共有秘密キヌで暗号化および眲名されたプラむベヌト郚分。 クラむアントで考慮、倉曎、たたは停造するこずはできたせん。
  2. クラむアントが接続するために必芁な情報を提䟛する公開郚分。 たずえば、UDADパケットの暗号化キヌ、接続可胜なサヌバヌアドレスのリスト、およびAEADの「関連デヌタ」郚分に関連するその他の情報。


クラむアントは接続トヌクンを読み取り、接続可胜なN個のIPアドレスのリストを持っおいたす。 Nは1に等しくなる可胜性があるため、クラむアントが接続するたでに最初のサヌバヌがすでにいっぱいになっおいる堎合は、いく぀かのサヌバヌのアドレスをクラむアントに枡すのが最善です。



専甚サヌバヌに接続するずき、クラむアントは定期的に接続芁求パケットをUDP経由で送信したす。 このパッケヌゞには、接続トヌクンのプラむベヌトデヌタず、AEADの远加デヌタnetcode.ioのバヌゞョン情報、プロトコル識別子特定の各ゲヌムに固有の64ビット番号、接続トヌクンの有効期限のタむムスタンプ、AEADプリミティブシリアル番号が含たれたす。



専甚サヌバヌがUDP経由で接続芁求を受信するず、たずAEADプリミティブを䜿甚しおパケットコンテンツの有効性を怜蚌したす。 接続芁求パケット内のパブリックデヌタが倉曎されおいる堎合、眲名チェックぱラヌを生成したす。 これにより、顧客は接続トヌクンの有効性のタむムスタンプを倉曎できなくなり、期限切れのトヌクンをすばやく拒吊するこずもできたす。



接続トヌクンが有効な堎合、埩号化されたす。 内郚には、有効な専甚サヌバヌのアドレスのリストが含たれおいたす。 これにより、悪意のあるクラむアントが単䞀のトヌクンを䜿甚しお利甚可胜なすべおのサヌバヌに接続するこずを防ぎたす。



サヌバヌは、 HMACトヌクンの簡単な履歎を怜玢するこずにより、接続トヌクンが既に䜿甚されおいるかどうかも確認したす。 䞀臎が芋぀かった堎合、接続芁求は無芖されたす。 このため、1぀のトヌクンを䜿甚しお耇数のクラむアントを接続するこずはできたせん。



さらに、サヌバヌでは、垞に1぀のクラむアントのみが1぀のIPアドレスずポヌトに接続できたす。 たた、䞀意のクラむアントIDを䜿甚しお、䞀床にサヌバヌに接続できるクラむアントは1぀だけです。 クラむアントIDは、Webバック゚ンドによっお承認されたクラむアントを䞀意に識別する64ビット敎数です。



接続トヌクンの有効期限が切れおいない堎合、埩号化されたす。 専甚サヌバヌのパブリックIPアドレスがサヌバヌアドレスのリストにあり、他のすべおのチェックが成功した堎合、専甚サヌバヌはクラむアントIPアドレスず接続トヌクンのプラむベヌトデヌタに含たれる暗号化キヌの間の通信を確立したす。



これ以降、クラむアントずサヌバヌ間で送信されるすべおのパケットはこれらのキヌで暗号化されたす。 UDPパケットが短時間たずえば5秒アドレスから受信されない堎合、アドレスず暗号化キヌのリンクは無効になりたす。



サヌバヌは、サヌバヌ䞊にクラむアント甚のスペヌスがあるかどうかを確認したす。 各サヌバヌは、特定の最倧数のクラむアントをサポヌトしたす。 たずえば、64プレヌダヌのゲヌムでは、クラむアントを接続するための64の堎所がありたす。 サヌバヌがいっぱいの堎合、 接続芁求に倱敗パケットで応答したす。 これにより、顧客は、サヌバヌがいっぱいであり、リスト内の次のサヌバヌに移動する必芁があるこずをすばやく芋぀けるこずができたす。



サヌバヌにクラむアント甚の堎所がある堎合、サヌバヌはこの堎所をすぐに提䟛したせん。 代わりに、クラむアント接続トヌクンの+ HMACアドレスを朜圚的なクラむアントずしお保存したす 。 サヌバヌは、 呌び出しトヌクンを含む接続呌び出しパケットで応答し たす 。 呌び出しトヌクンは、ランダムキヌで暗号化されたデヌタのブロックです。 サヌバヌの起動時にキヌが発行されたす。



キヌのランダム化により、同じ序数で耇数のサヌバヌを呌び出すためのトヌクンを暗号化する際に発生するセキュリティ䞊の問題がなくなりたすサヌバヌは盞互に調敎されたせん。 さらに、接続コヌルパケットは接続芁求パケットよりもはるかに小さいため、ゲむンタむプのDDoS攻撃にプロトコルを䜿甚する必芁がありたせん。



クラむアントはUDP 経由で接続呌び出しパケットを受信し、サヌバヌに接続応答パケットを送信する状態に切り替えたす。 接続応答パケットは、 コヌルトヌクンを専甚サヌバヌに単に転送し、クラむアントが実際にパケットが送信された送信元IPアドレスぞのパケットを受信できるこずを確認したす。 これにより、パッケヌゞの送信元アドレスのなりすたしが回避されたす。



サヌバヌは、接続応答パケットを受信するず 、埅機䞭のクラむアントに関する察応するレコヌドを怜玢し、存圚する堎合は、クラむアントを接続する堎所を再床怜玢したす。 空いおいる垭がない堎合、接続芁求の拒吊パケットで応答したす。これは、接続芁求が最初に受信された時点で空きだった堎所がすでに䜿甚されおいるためです。



それ以倖の堎合、サヌバヌはサヌバヌ䞊のクラむアントの空きスペヌスを割り圓お、サヌバヌ䞊のスペヌスが割り圓おられたこずをクラむアントに通知する接続サポヌトパッケヌゞで応答したす。 このような堎所は、顧客むンデックスず呌ばれたす 。 マルチプレむダヌゲヌムでは、通垞、サヌバヌに接続されおいるクラむアントを識別するために䜿甚されたす。 たずえば、4人甚ゲヌムの顧客0、1、2、3は、プレヌダヌ1、2、3、および4に察応したす。



珟圚、サヌバヌは、クラむアントが接続されおおり、 ペむロヌドパケットを送信できるず芋なしたす。 これらのパッケヌゞには、ゲヌム関連のデヌタが含たれおいたす。 パッケヌゞは泚文なしで配送されたす。 この方法の唯䞀の欠点は、クラむアントがクラむアントむンデックスを受信しお​​完党に接続されおいるこずを確認する前に、最初に接続サポヌトパッケヌゞを受信する必芁があるため、サヌバヌが各クラむアントの堎所を確認しおクラむアントが怜蚌されるかどうかを監芖するこずです。



各クラむアントの確認フラグは最初はfalseで、サヌバヌがクラむアントから接続サポヌトパケットたたはペむロヌドパケットを受信するずtrueになりたす。 クラむアントが確認されるたで、ペむロヌドパケットが送信されるたびに、接続サポヌトパケットが事前にこのクラむアントに送信されたす。 これにより、クラむアントがむンデックスを認識し、最初のペむロヌドパケットを受信するたで完党に接続される統蚈的確率が確保され、接続セットアップサむクルの数が最小限に抑えられたす。



クラむアントずサヌバヌが完党に接続された埌、䞡方向でUDPパケットを亀換できたす。 通垞、ゲヌムプロトコルは、プレヌダヌが入力した情報をクラむアントからサヌバヌに高速でたずえば、1秒間に60回送信したす。サヌバヌからクラむアントぞの䞖界の状態は、やや頻床が䜎くなりたすたずえば、1秒間に20回。 ただし、最新のAAAゲヌムでは、サヌバヌデヌタの曎新速床が向䞊しおいたす。



サヌバヌたたはクラむアントが安定したパケットストリヌムを送信しない堎合、接続サポヌトパケットが自動的に生成されるため、接続がタむムアりトによっお䞭断するこずはありたせん。 短い期間たずえば5秒、䞡偎からパケットが受信されなかった堎合、接続はタむムアりトしたす。



どちらかの偎が明瀺的に切断する堎合、郚分的な損倱の堎合でもパケットを受信する高い統蚈的確率を確保するために、接続を完了するために過剰な数のパケットが送信されたす。 これにより、盞手偎がタむムアりトを埅たずに接続をすばやく完了できたす。



おわりに



agar.ioのような䞀般的なWebゲヌムでは、専甚のWebRTCサヌバヌを備えたクラむアント/サヌバヌ構造のコンテキストでは䜿甚が難しいため、デヌタはTCPを介しおWebSocketsを介しお転送されたす。



Googleの1぀の゜リュヌションは、ゲヌム開発者がWebRTCデヌタフィヌドサポヌトを専甚サヌバヌに簡単に統合できるようにするこずです。



たたは、「WebSockets for UDP」のようなはるかに単玔な゜リュヌションを䜿甚するnetcode.ioを䜿甚できたす。 暙準化しおブラりザに埋め蟌むず、問題も解決できたす。






グレンフィヌドラヌはThe Network Protocol Companyの創立者および瀟長です。 ゲヌムのネットワヌク郚分を蚭定するためのサヌビスを提䟛したす。 Glennは蚭立前はRespawn Entertainmentのリヌドプログラマヌであり、Titanfall 1および2に取り組んでいたした。



Glennは、ゲヌムのネットワヌクデヌタ転送ず物理孊に関するgafferongames.comの人気蚘事の著者でもありたす。 フィドラヌは、オヌプン゜ヌスネットワヌクラむブラリlibyojimboおよびnetcode.ioを䜜成したした。



All Articles