※当サイトの記事には、広告・プロモーションが含まれます。

JavaでQUICが利用できるKwikとは。JettyやNettyもQUICに対応している模様

cloud.watch.impress.co.jp

⇧ 結構、話題になってますね。

xtech.nikkei.com

⇧ う~ん、機能・非機能の仕様を「要件定義」でザックリとでも良いから決めておかないと、複数人での開発において、仕様について認識齟齬が頻発して、システム開発が破綻すると思うんだけどな...

「データモデリング」も「要件定義」も、どちらも経験を積むことでしか良いものにすることができない気はするけど...

何と言うか、経験を積ませてもらう機会がほとんど無いのに、経験を積んできた人たちが、経験の乏しい人たちにとっての稀少な経験を積む機会を潰すような発言を敢えてするのはどうなのかと思うんだが...

稀に天才といえるような人が、経験を経ずに理論だけで完璧なものを作り上げるケースもあるとは思うけど、一般的なモデルケースに当てはめられないしな...

システム開発のプロジェクトが始まるとして、「要求定義」は「発注者」と「受注者」の両者が議論して認識合わせをすべきだと思う。

一方で、「要求」に対しての「要件定義」は「受注者」側で、する・しないを決めれば良いと思うから「要件定義」をしない、と決めるという方針を取ることもできると思う。

だとしても、開発者同士で認識齟齬の頻度を下げるためにも「要件定義」はする方が良い気はするけどな...

そもそも「データモデリング」についても、ある程度、どういう機能・非機能を実現するのかという仕様が分かっていないと頓珍漢なものが出来上がるような気がしてならない...

「要件定義」で仕様をドキュメント化しておけば、仕様についての共通認識をいつでも確認できる気はしますし。

仮に有識者の頭の中だけにある仕様だとしたら、有識者に対して認識合わせのコストが膨大になるし、属人化もしてる点から言っても悪手な気はするんだけど...

何が言いたいかと言うと、有識者の人は、もうちょっと、後進のことを考えて欲しいかな...

QUICとは?

冒頭、長々とボヤきから始まりましたが、悪しからず。

それでは気持ちを切り替えまして参りましょう、って、お笑い芸人のブラックマヨネーズみたいな入りになってしまいましたが、ご了承ください。

QUICについては、前に調べたことがあったのだけど、Kwikについて調べる前のお浚いとして改めて調べてみる。

Wikipediaさんによりますと、

QUIC (pronounced "quick") is a general-purpose transport layer network protocol initially designed by Jim Roskind at Google, implemented, and deployed in 2012, announced publicly in 2013 as experimentation broadened, and described at an IETF meeting.

https://en.wikipedia.org/wiki/QUIC

In June 2015, an Internet Draft of a specification for QUIC was submitted to the IETF for standardization. A QUIC working group was established in 2016. In October 2018, the IETF's HTTP and QUIC Working Groups jointly decided to call the HTTP mapping over QUIC "HTTP/3" in advance of making it a worldwide standard. In May 2021, the IETF standardized QUIC in RFC 9000, supported by RFC 8999RFC 9001 and RFC 9002. DNS-over-QUIC is another application.

https://en.wikipedia.org/wiki/QUIC

Googleによって開発された「transport layer network protocol」ということらしい。

当初は、

Although its name was initially proposed as the acronym for "Quick UDP Internet Connections", IETF's use of the word QUIC is not an acronym; it is simply the name of the protocol.

https://en.wikipedia.org/wiki/QUIC

⇧ 略称を提案していたらしいけど、採択されなかったってことなんかね?

transport layer network protocol」ということで、ネットワーク分野で名を馳せているCiscoCisco Systems)のコミュニティが公開しているOSI参照モデルで確認してみるが、

community.cisco.com

⇧ QUICは、OSI参照モデルでは7層の内の第4層に該当するTRANSPORT層のprotocolに該当しますと。

ザックリとしたQUICの立ち位置としては、

⇧ 上図のようになるらしい。

TCPではなくUDPを利用してるからHTTPの通信が高速になるってことなんかね?

HTTP/3については、

HTTP/3は、HTTP/2に続くハイパーテキスト転送プロトコルの3つ目のメジャーバージョンである。HTTP/2に引き続き、伝送はバイナリ形式で行われる。HTTP/3 は RFC ドラフト「Hypertext Transfer Protocol(HTTP) over QUIC」をベースとしている。

HTTP/3 - Wikipedia

QUIC は Google によって初めに開発された実験的なトランスポート層プロトコルである

HTTP/3 - Wikipedia

⇧ とある。

伝送がバイナリ形式ってのも高速化に寄与してるんかな。

blogs.itmedia.co.jp

その後、XMLをはじめとして、データを様々な環境で使うことを前提としたフォーマットはほとんどテキスト形式が採用され、バイナリ形式はサイズ、速度などが要求される限定的な用途で使われるようになってきています。

バイナリデータとテキストデータ:プログラマー社長のブログ:オルタナティブ・ブログ

⇧ とあるので、バイナリ形式の方が高速に処理できるって認識で良いみたい。

QUICでバイナリ形式のデータを受け取って処理する場合も、QUICが良しなに処理できるようなものを用意してくれているんだろうか。

By the way、QUICが対応してるか分からんのだけど、

Protocol Buffersの主な目的は「ネットワーク上の通信を高速化すること」ではあるが、その自己記述性の低さに起因するシンプルさおよび高速さによりC++クラスおよび構造体を用いたデータ格納からの有力な置き換え手段としても用いられている。

Protocol Buffers - Wikipedia

現在、Googleにより開発されている。オリジナルのGoogle実装はC++JavaPythonによるものであり、フリーソフトウェアとしてオープンソースライセンスで公開されている。また、ActionScriptC言語C#ClojureCommon LispD言語ErlangGoHaskellJavaScriptLuaMATLABMercuryObjective-COCamlPerlPHPR言語RubyScala.NET Frameworkなどの実装が利用可能である

Protocol Buffers - Wikipedia

⇧ Protocol Buffersも利用できたら、より高速になるんかね?

QUICにしろProtocol Buffersにしろ、どちらもGoogleが発祥の技術なんですな、ブラボー。

Protocol Buffersが出てきたついでに、

gRPC (gRPC Remote Procedure Calls) は、オープンソースリモートプロシージャコール (RPC) システムである。当初はGoogleによって、RPC基盤であるStubbyの次世代版として2015年に開発された。

gRPC - Wikipedia

gRPCは、HTTP/2をトランスポートとして利用し、Protocol Buffersインタフェース記述言語およびデータエンコーディングとして利用する。提供する機能としては、認証、双方向のストリーミングとフロー制御、同期および非同期のバインディング、キャンセルとタイムアウトの対応などがある。多くの言語において、クロスプラットフォームなクライアントおよびサーバーのバインディングを生成できる

gRPC - Wikipedia

⇧ gRPCも確認してみたけど、Googleが発祥ですと。

QUICから脱線してますが、もうちょっと脱線して、OSI参照モデルTCP/IPの関係性については、

zenn.dev

ところが次の一言で悩みが全てとけた

TCP/IPOSI参照モデルに則って作られていない

そのため、実務的には、TCP/IPの4層モデルを基準に考える方が良い。

OSI参照モデルの有害性

ただし、情報処理のテストではOSI参照モデルは出てくるので、試験対策には覚える必要がある

OSI参照モデルの有害性

⇧とのこと。

独立行政法人情報処理推進機構IPA:Information-technology Promotion Agency, Japan)」の資格試験に限らないと思うけど、実務に活かせる知識を習得できるようにして欲しいよね...

ただでさえ実業務に関する技術の学習や調査の方で忙しくて、資格試験の学習に費やせるような時間が無いんだからさ...実業務に直結しないよう知識の学習してる余裕は無いんだわ...

Wikipediaさんによりますと、

歴史

その後、当初の予定では、OSI参照モデルを基に、準拠した通信機器やソフトウェアが開発・製品化していくはずであった。TCP/IP1990年代中ごろから急速に普及したため、OSI準拠製品は普及しないまま、現在に至る。

OSI参照モデル - Wikipedia

⇧ 理想と現実のギャップ...

何て言うか、利益を優先せざるを得なかったが故に、標準の仕様に準拠しないという経緯があったようで、結局のところ、お金が全てを決するということですな、というか歴史に学ばないんではなくて、利益重視に舵を切るという意図的に標準の仕様を無視してるってわけですな...

その結果、独自の仕様で実装されたものは、その実装を理解するために余計な学習コストや認知負荷を増大させることになり易くもあり、保守・運用がし辛くレガシーな遺物となって後世の負担となる、俗に言う「技術的負債」になりやすい気がしている、個人の見解ですが...。

結局のところ、全部エンジニアにしわ寄せが来てるんよね...

例えるならば、解消できる当ての無いように見える国債みたいに負担を先送りしてその場凌ぎを続けてる状況に似ていて、未来のエンジニアに丸投げするという負のスパイラルが止められないように思える...

まぁ、限られた開発工数という制限もあったことだと思うし、致し方ないことなのかも知らんけど...

ちなみに、OSIって何の略なんだろうと思ってたのだけど、

国際標準化機構 (ISO) によって制定された、異機種間のデータ通信を実現するためのネットワーク構造の設計方針「開放型システム間相互接続 (Open Systems InterconnectionOSI)」に基づいて通信機能を以下の7階層(レイヤ)に分割する。

OSI参照モデル - Wikipedia

⇧ ということらしい。

話をQUICに戻すと、QUICの内部では、「TLS 1.3」を利用しているらしいのだけど、「TLS」はと言うと、

Transport Layer Security(トランスポート・レイヤー・セキュリティ、TLS)は、インターネットなどのコンピュータネットワークにおいてセキュリティを要求される通信を行うためのプロトコルである。主な機能として、通信相手の認証、通信内容の暗号化改竄の検出を提供する。TLSIETFによって策定された

Transport Layer Security - Wikipedia

プロトコルは(特に区別する場合を除いて)SSL (Secure Sockets Layer) と呼ばれることも多い。これは、TLSの元になったプロトコルSSLであり、そのSSLという名称が広く普及していることによる

Transport Layer Security - Wikipedia

概要

TLSは多くの場合、コネクション型のトランスポート層プロトコル(通常はTCP)とアプリケーション層の間で使われる。特にHTTPでの利用を意識して設計されているが、アプリケーション層の特定のプロトコルには依存せず、様々なアプリケーションにおいて使われている。TLS 1.1以降を元にしたプロトコルが、UDPDCCPといったデータグラムプロトコル上でも実装されており、こちらはDatagram Transport Layer Security (DTLS) として独立して標準化されている

Transport Layer Security - Wikipedia

⇧「Datagram Transport Layer Security (DTLS)」はと言うと、

Datagram Transport Layer Security (DTLS) は、データグラムプロトコルのための暗号化プロトコルである。DTLSはTransport Layer Security (TLS) に基づくプロトコルであり、TLSと同様に、データグラムを扱うプログラムがやり取りする情報の盗聴や改竄を防止する。

Datagram Transport Layer Security - Wikipedia

このほか、各種トランスポート層プロトコル上でのDTLSの使用に関して、以下のRFCが存在する。

Datagram Transport Layer Security - Wikipedia

⇧ とあり、ここで言っている「トランスポート層プロトコル」の参照先の説明を見ると、

トランスポート層(トランスポートそう、Transport layer)とは、コンピュータ電気通信では、TCP/IPモデルにおけるの4階層の内の第3層の事である。上位のアプリケーション層からのサービス要求に応じ、また下位のインターネット層に対してサービス要求を行う。

トランスポート層 - Wikipedia

トランスポート層OSI参照モデルにおける7階層の内の第4層の名前でもある。上位のセッション層からのサービス要求に応じ、また下位のネットワーク層に対してサービス要求を行う。

トランスポート層 - Wikipedia

トランスポート層の定義はそれら2モデルで僅かに異なる。この記事では主としてTCP/IPモデルについて言及する。OSI参照モデルでのトランスポート層の定義も参照の事。

トランスポート層 - Wikipedia

⇧「TLS」のバージョンによって実装は様々で、OSI参照モデルのレイヤー層も異なってくるらしいのと、単純に「トランスポート層」とだけ言われた場合、

のどちらに関しての話なのかを明確にしてくれていないとややこしい。

このことを知らずに、ネット上の情報で「TLS」の実装はOSI参照モデルの「【6層】プレゼンテーション層」であるという情報が圧倒的多数なのだが(旧い情報で更新されていないと思われる)、鵜呑みにしてると、痛い目に会うと...

脱線しましたが、Wikipediaの情報が正しいと仮定して矛盾が無いとすると、QUICの中で実装されてる「TLS」の実装は、

で行われてる、ということになるかと、ただ、OSI参照モデルが形骸化してるっていう話も出てきてるので、TCP/IPモデルで考えれば良いんかな?

何か、多重化という機能の説明で

Services

Transport layer services are conveyed to an application via a programming interface to the transport layer protocols. The services may include the following features:

  • MultiplexingPorts can provide multiple endpoints on a single node. For example, the name on a postal address is a kind of multiplexing and distinguishes between different recipients of the same location. Computer applications will each listen for information on their own ports, which enables the use of more than one network service at the same time. It is part of the transport layer in the TCP/IP model, but of the session layer in the OSI model.

https://en.wikipedia.org/wiki/Transport_layer

⇧ って話が出てきて、そもそもレイヤーが異なるって言ってるんだが...

TCP/IPモデルのレイヤーとOSI参照モデルのレイヤーの正確な対応表が存在してくれていないと認識を合わせることが不可能なんだが...

Wikipediaの情報がどこまで信用できるか分からんので何とも言えんのだけど、ネットの情報を見る限りだと、

www.ccnablog.com

⇧ って図解になっていて、上記サイト様が公式のものなのかは分からないのですが、「CCNACisco Certified Network Associate)」についての見解だとすると、「トランスポート層」については、TCP/IPモデルのレイヤーとOSI参照モデルのレイヤーで1:1の関係になっているように見えるんだが...

Cisco Certified Network Associate(CCNA)はベンダー資格のひとつで、ネットワーク機器ベンダーであるシスコシステムズ(Cisco Systems)が主催している認定資格である。 ネットワークエンジニアにとっては、登竜門的な資格に位置する。

Cisco Certified Network Associate - Wikipedia

⇧ 流石に、ネットワークエンジニアにおける登竜門的な資格で扱われてる情報だから信頼して良いと思うけど...

だとすると、Wikipediaの「Transport layer」における「Multiplexing」の説明の『It is part of the transport layer in the TCP/IP model, but of the session layer in the OSI model.』が誤っているってことになるんかね?

一応、CiscoCisco Systems)の公式のサイトで発信してるっぽい情報では、

www.ciscopress.com

⇧ 上図のような関係性になっている。

It is part of the transport layer in the TCP/IP model, but of the session layer in the OSI model.』について、自分と同じような疑問を抱えてた人がおられるようで、

learningnetwork.cisco.com

Here, it states that the session layer enables the use of more than one network service at the same time. Not multiplexing of ports.

Rephrasing this one too,

"enables the use of more than one network service at the same time which is part of the transport layer in the TCP/IP model, but of the session layer in the OSI model."

Content of the following link might be helpful.

http://www3.gdin.edu.cn/jpkc/dzxnw/jsjkj/chapter3/32.htm

https://learningnetwork.cisco.com/s/question/0D53i00000KsrOgCAJ/osi-question

⇧ ベストアンサーに選ばれてる回答を見てみたけど、参照先のリンクにアクセスできないこともあり、曖昧なんよな...

 『"enables the use of more than one network service at the same time which is part of the transport layer in the TCP/IP model, but of the session layer in the OSI model."』という説明と『Figure 2-13 OSI Model Compared to the Two TCP/IP Models』の図の整合性が取れていないような気がするんだが...

う~む、ネットワーク、何も分からん...

長らく脱線しましたが、「Johannes Zirngibl is a Research Associate at TU Munich.」の見解をAPNICが公開している情報では、

blog.apnic.net

The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.

https://blog.apnic.net/2022/01/27/2-6-million-addresses-support-quic/

⇧ QUICが属するレイヤーは、複数に跨るという認識らしい...

APNICの公式と思えるブログであるにも関わらず、「do not necessarily reflect the views of APNIC.」って添えるのは微妙な気もするのだけど...

ちなみに、APNICは、

Asia-Pacific Network Information Centre(略称: APNIC)は、東部・南部アジア太平洋エリアを管轄する地域インターネットレジストリ (RIR) である。日本のJPNICも加盟している。

Asia-Pacific Network Information Centre - Wikipedia

⇧ のような組織らしい。

Red Hatで公開されてる情報でも

www.redhat.com

⇧ QUICは複数のレイヤーに跨るという認識の模様。ただ、APNICの情報と微妙に異なるので余計によく分からん...

よく分からんのだけど、

datatracker.ietf.org

1. Overview

QUIC is a secure general-purpose transport protocol.

https://datatracker.ietf.org/doc/html/rfc9000#name-overview

RFCで、OSI参照モデル、またはTCP/IPモデルのどのレイヤーに属するのか一言言及してはいけないんかね?

Wikipediaの「トランスポート層」の説明によると、

トランスポート・プロトコル

トランスポート・プロトコルは、トランスポート層(第四層)の通信プロトコルである。インターネットにおける2大トランスポート・プロトコルとして、コネクション型の「TCP」(Transmission Control Protocol)と、コネクションレス型の「UDP」(User Datagram Protocol)がある。その他、Datagram Congestion Control Protocol(DCCP)やStream Control Transmission Protocol(SCTP)が有る。

トランスポート層 - Wikipedia

⇧ とのこと。

RFC 9000のoverviewで言っている「transport protocol」と、Wikipediaの「トランスポート層」の説明に出てくる「トランスポート・プロトコル」が同じものを指してるかが分からんのよな...

QUICの定義のルールが分からな過ぎる...

そんなQUICですが、いまのところ、

eh-career.com

⇧ 課題があり、まだ実運用は難しそうな感じですかね?

Kwikとは?

KwikのGitHubで公開されてる説明によると、

github.com

Kwik is an implementation of the QUIC protocol in (100%) Java. Kwik started as client (library) only, but since May 2021 it supports both client and server.

https://github.com/ptrd/kwik

JavaでQUICの実装を実現してるライブラリってことかと。

いまのところ、MavenやGradleといったビルドツールで依存関係を追加して利用する方法は用意されていないらしいのだけど、

github.com

⇧ 検討はしてくれているらしい。

実際に、Javaでクライアント側のQUICの通信の処理を実装するのは、

github.com

HTTP3 is a new standard that is being developed by the Internet Engineering Task Force (IETF) and that is still "work in progress", see https://tools.ietf.org/html/draft-ietf-quic-http-29.

https://github.com/StuffNoOneCaresAbout/flupke/blob/master/readme.md

HTTP3 uses QUIC as transport protocol. Flupke builds on Kwik, a Java implementation of QUIC. Currently, Flupke supports the HTTP3 draft-29 version and uses QPACK version draft-16 and QUIC version draft-29.

https://github.com/StuffNoOneCaresAbout/flupke/blob/master/readme.md

Flupke is created and maintained by Peter Doornbosch. The latest greatest can always be found on BitBucket.

https://github.com/StuffNoOneCaresAbout/flupke/blob/master/readme.md

⇧ Flupkeってライブラリを利用する感じになるらしい。

で、ややこしいのが、

bitbucket.org

HTTP3 Java

Flupke is a Java HTTP3 implementation that runs on top of Kwik.

https://bitbucket.org/pjtr/flupke/src/master/

Initially, Flupke was only a HTTP3 Client, but since June 2021 it also provides a plugin that, when used with Kwik, acts as a (simple) HTTP3 webserver server.

https://bitbucket.org/pjtr/flupke/src/master/

⇧ という説明で、

  • Flupke
    • ClientとしてQUICを利用する処理
  • Flupke + Kwik
    • ServerとしてQUICを利用する処理

ってことらしい。

ただ、ServerとしてQUICを利用する実装例が無いのよな...

QUIC自体が、まだまだ課題があるようですし、MavenやGradleといったビルドツールで依存関係を追加して利用する方法で実装できるように対応してもらえたら、Kwikを利用してみますかね。

JettyもQUICに対応している模様

ちなみに、

eclipse.dev

HTTP/3 is a multiplexed protocol because it relies on the multiplexing capabilities of QUIC, the protocol based on UDP that transports HTTP/3 frames. Thanks to multiplexing, multiple HTTP/3 requests are sent on the same QUIC connection, or session. Each request/response cycle is represented by a stream. Therefore, a single session manages multiple concurrent streams. A stream has typically a very short life compared to the session: a stream only exists for the duration of the request/response cycle and then disappears.

https://eclipse.dev/jetty/documentation/jetty-12/programming-guide/index.html#pg-server-http3-intro

⇧ Jettyは、HTTP/3がQUICに依存しているという見解で、QUICを実現していると言えそうです。

Jettyはと言うと、

Eclipse Jetty is a Java web server and Java Servlet container. While web servers are usually associated with serving documents to people, Jetty is now often used for machine to machine communications, usually within larger software frameworks. Jetty is developed as a free and open source project as part of the Eclipse Foundation

https://en.wikipedia.org/wiki/Jetty_(web_server)

The web server is used in products such as Apache ActiveMQ, Alfresco, ScalatraApache Geronimo, Apache MavenApache SparkGoogle App Engine, Eclipse, FUSE, iDempiere, Twitter's Streaming API and Zimbra. Jetty is also the server in open source projects such as LiftEucalyptusOpenNMSRed5Hadoop and I2P. Jetty supports the latest Java Servlet API (with JSP support) as well as protocols HTTP/2 and WebSocket.

https://en.wikipedia.org/wiki/Jetty_(web_server)

Overview

Jetty started as an independent open source project in 1995. In 2009 Jetty moved to Eclipse. Jetty provides Web services in an embedded Java application and it is already a component of the Eclipse IDE. It supports AJP, JASPI, JMXJNDIOSGiWebSocket and other Java technologies.

https://en.wikipedia.org/wiki/Jetty_(web_server)

⇧ いまは、Eclipse Foundationという団体で管理されてると。

日本語版のWikipediaの説明だと、

Jetty は、100%Javaで開発されたJava ServletコンテナWebサーバである。WebSocketなどの通信プロトコルもサポートする。Jetty はオープンソースプロジェクトとして開発され、Apache 2.0 License でリリースされている。JBossApache Geronimoといった他のプロジェクトでも利用されている。

Jetty - Wikipedia

単純で効率的な組み込みやすいWebサーバとなるよう意図して開発されている。サイズが小さいので、組み込み型 Java アプリケーションにWebサービスを提供するのに適している。

Jetty - Wikipedia

その一方で、Apache HadoopGoogle App Engineといった大規模でスケーラビリティが重視されるサービスにおいても採用されている

Jetty - Wikipedia

2009年1月、WebtideはJettyのコアコンポーネントcodehausからEclipse Foundationに移管することを発表した。

Jetty - Wikipedia

⇧ 結構、説明の内容に温度差があるような...

Web Serverとあるけど、Javaのアプリケーションを動作させることができるっぽいので、Javaアプリケーションを動作させる用途で利用する場合はApplication Serverと見なせるのではないかと。

NettyもQUICに対応している模様

ちなみに、ノンブロッキングでリアクティブ通信を実現できるNettyはと言うと、

Netty is a non-blocking I/O client-server framework for the development of Java network applications such as protocol servers and clients. The asynchronous event-driven network application framework and tools are used to simplify network programming such as TCP and UDP socket servers. Netty includes an implementation of the reactor pattern of programming. Originally developed by JBoss, Netty is now developed and maintained by the Netty Project Community.

https://en.wikipedia.org/wiki/Netty_(software)

Besides being an asynchronous network application framework, Netty also includes built-in implementations of SSL/TLSHTTPHTTP/2HTTP/3WebSocketsDNSProtocol BuffersSPDY and other protocols. Netty is not a Java web container, but is able to run inside one, and supports message compression. Netty has been actively developed since 2004.

https://en.wikipedia.org/wiki/Netty_(software)

⇧ HTTP/3には対応しているらしい。

QUICへの対応はと言うと、

netty.io

How would I setup a QUIC server / client ?

Bootstrapping a QUIC server that speaks HTTP/0.9 would look like that:

// We just want to support HTTP 0.9 as application protocol
byte[] proto = new byte[] {
        0x08, 'h', 't', 't', 'p', '/', '0', '.', '9'
};

NioEventLoopGroup group = new NioEventLoopGroup(1);
ChannelHandler codec = new QuicServerCodecBuilder()
        .certificateChain("./src/test/resources/cert.crt")
        .privateKey("./src/test/resources/cert.key")
        .applicationProtocols(proto)
        .maxIdleTimeout(5000, TimeUnit.MILLISECONDS)
        // Configure some limits for the maximal number of streams (and the data) that we want to handle.
        .initialMaxData(10000000)
        .initialMaxStreamDataBidirectionalLocal(1000000)
        .initialMaxStreamDataBidirectionalRemote(1000000)
        .initialMaxStreamsBidirectional(100)
        .initialMaxStreamsUnidirectional(100)

        // Setup a token handler. In a production system you would want to implement and provide your
        // custom one.
        .tokenHandler(InsecureQuicTokenHandler.INSTANCE)
        // ChannelHandler that is added into QuicChannel pipeline.
        .handler(new ChannelInboundHandlerAdapter() {
            @Override
            public void channelActive(ChannelHandlerContext ctx) {
                QuicChannel channel = (QuicChannel) ctx.channel();
                // Create streams etc..
            }

            public void channelInactive(ChannelHandlerContext ctx) {
                ((QuicChannel) ctx.channel()).collectStats().addListener(f -> {
                    if (f.isSuccess()) {
                        LOGGER.info("Connection closed: {}", f.getNow());
                    }
                });
            }

            @Override
            public boolean isSharable() {
                return true;
            }
        })
        .streamHandler(new ChannelInitializer<QuicStreamChannel>() {
            @Override
            protected void initChannel(QuicStreamChannel ch)  {
                // Add a LineBasedFrameDecoder here as we just want to do some simple HTTP 0.9 handling.
                ch.pipeline().addLast(new LineBasedFrameDecoder(1024))
                        .addLast(new ChannelInboundHandlerAdapter() {
                    @Override
                    public void channelRead(ChannelHandlerContext ctx, Object msg) {
                        ByteBuf byteBuf = (ByteBuf) msg;
                        try {
                            if (byteBuf.toString(CharsetUtil.US_ASCII).trim().equals("GET /")) {
                                ByteBuf buffer = ctx.alloc().directBuffer();
                                buffer.writeCharSequence("Hello World!\r\n", CharsetUtil.US_ASCII);
                                // Write the buffer and shutdown the output by writing a FIN.
                                ctx.writeAndFlush(buffer).addListener(QuicStreamChannel.SHUTDOWN_OUTPUT);
                            }
                        } finally {
                            byteBuf.release();
                        }
                    }
                });
            }
        }).build();
try {
    Bootstrap bs = new Bootstrap();
    Channel channel = bs.group(group)
            .channel(NioDatagramChannel.class)
            .handler(codec)
            .bind(new InetSocketAddress(9999)).sync().channel();
    channel.closeFuture().sync();
} finally {
    group.shutdownGracefully();
}

https://netty.io/news/2020/12/09/quic-0-0-1-Final.html

Clientの実装。

And the corresponding QUIC client like that:

// We just want to support HTTP 0.9 as application protocol
byte[] proto = new byte[] {
        0x08, 'h', 't', 't', 'p', '/', '0', '.', '9'
};

NioEventLoopGroup group = new NioEventLoopGroup(1);
try {
    ChannelHandler codec = new QuicClientCodecBuilder()
            .applicationProtocols(proto)
            .maxIdleTimeout(5000, TimeUnit.MILLISECONDS)
            .initialMaxData(10000000)
            // As we don't want to support remote initiated streams just setup the limit for
            // local initiated streams in this example.
            .initialMaxStreamDataBidirectionalLocal(1000000)
            .build();

    Bootstrap bs = new Bootstrap();
    Channel channel = bs.group(group)
            .channel(NioDatagramChannel.class)
            .handler(codec)
            .bind(0).sync().channel();

    QuicChannel quicChannel = QuicChannel.newBootstrap(channel)
            .streamHandler(new ChannelInboundHandlerAdapter() {
                @Override
                public void channelActive(ChannelHandlerContext ctx) {
                    // As we did not allow any remote initiated streams we will never see
                    // this method called. That said just let us keep it here to demonstrate
                    // that this handle would be called for each remote initiated stream.
                    ctx.close();
                }
            })
            .remoteAddress(new InetSocketAddress(NetUtil.LOCALHOST4, 9999))
            .connect()
            .get();

    QuicStreamChannel streamChannel = quicChannel.createStream(QuicStreamType.BIDIRECTIONAL,
            new ChannelInboundHandlerAdapter() {
                @Override
                public void channelRead(ChannelHandlerContext ctx, Object msg) {
                    ByteBuf byteBuf = (ByteBuf) msg;
                    System.err.println(byteBuf.toString(CharsetUtil.US_ASCII));
                    byteBuf.release();
                }

                @Override
                public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                    if (evt == ChannelInputShutdownReadComplete.INSTANCE) {
                        // Close the connection once the remote peer did send the FIN
                        // for this stream.
                        ((QuicChannel) ctx.channel().parent()).close(true, 0,
                                ctx.alloc().directBuffer(16)
                                        .writeBytes(new byte[]{'k', 't', 'h', 'x', 'b', 'y', 'e'}));
                    }
                }
            }).sync().getNow();
    // Write the data and send the FIN. After this its not possible anymore to write any more data.
    streamChannel.writeAndFlush(Unpooled.copiedBuffer("GET /\r\n", CharsetUtil.US_ASCII))
            .addListener(QuicStreamChannel.SHUTDOWN_OUTPUT);

    // Wait for the stream channel and quic channel to be closed (this will happen after we
    // received the FIN).  After this is done we will close the underlying datagram channel.
    streamChannel.closeFuture().sync();
    quicChannel.closeFuture().sync();
    channel.close().sync();
} finally {
    group.shutdownGracefully();
}  

https://netty.io/news/2020/12/09/quic-0-0-1-Final.html

⇧ どうも、HTTP/0.9と出て来てる時点で、QUICの意味合いが異なっているような気がする...

と思ったのだけど、

github.com

This is a new experimental QUIC codec for netty which makes use of quiche.

https://github.com/netty/netty-incubator-codec-quic

⇧ とあり、

github.com

quiche is an implementation of the QUIC transport protocol and HTTP/3 as specified by the IETF. It provides a low level API for processing QUIC packets and handling connection state. The application is responsible for providing I/O (e.g. sockets handling) as well as an event loop with support for timers.

https://github.com/netty/netty-incubator-codec-quic

⇧ とあるので、QUIC protocolのことを言っているという認識で良いみたい。

と言うか、

For some examples please check our example package. This contains a server and a client that can speak some limited HTTP/0.9 with each other.

https://github.com/netty/netty-incubator-codec-quic

For more "advanced" use cases, consider checking our netty-incubator-codec-http3 project.

https://github.com/netty/netty-incubator-codec-quic

⇧ QUICって、HTTP/3じゃなくても機能するんか。

と言うか、Wikipediaをしっかり読んだら、

Google QUIC (gQUIC)

The protocol that was created by Google and taken to the IETF under the name QUIC (already in 2012 around QUIC version 20) is quite different from the QUIC that has continued to evolve and be refined within the IETF. The original Google QUIC was designed to be a general purpose protocol, though it was initially deployed as a protocol to support HTTP(S) in Chromium. The current evolution of the IETF QUIC protocol is a general purpose transport protocol. Chromium developers continued to track the evolution of IETF QUIC's standardization efforts to adopt and fully comply with the most recent internet standards for QUIC in Chromium.

https://github.com/netty/netty-incubator-codec-quic

⇧ ってあるんだけど...

でも、流石に、「Google QUIC」のことを言っているなら「gQUIC」と書くと思うし「QUIC」とは書かないですよね?

そんな鬼畜の所業を、ネットワークに繋がってさえいれば世界中の人が目を通すことができるドキュメントでやらかすとは思えんしな...

HTTP/3

詳細は「HTTP/3」を参照

HTTP-over-QUIC(hq)としてIETFが開発していた新たな通信プロトコルが、HTTP/3へと改名される。

Hypertext Transfer Protocol - Wikipedia

⇧ とあり、

github.com

github.com

⇧ のような情報があることから、HTTP/0.9 over QUICというものが存在していたのだと思われる、と言うか、驚くほどの情報の見つからなさなんだが...黒歴史とかみたいな扱いなの?

まぁ、HTTP/0.9 over QUICとかの存在は無かったことにしたいのか分からんけども、HTTP/3でのQUICの実装は、

github.com

Experimental HTTP3 codec on top of our own QUIC codec.

https://github.com/netty/netty-incubator-codec-http3

⇧ HTTP/3用のライブラリが用意されているみたいで、

github.com

github.com

⇧ サンプルが公開されていたので、おそらく、QUICに対応してると思われる。

JettyとNetty

JettyとNettyについて、

www.infoq.com

⇧ 上記サイト様の比較がイメージしやすいかと。

というか、Jettyはリアクティブでも動作するみたいですね、Servletがリアクティブに対応したっていうことなんかな。

とりあえず、本番環境でQUICを利用するような処理の実装は、まだ時期尚早って感じなんかね?

そして、JettyやNettyでQUICが使えるんなら、Kwikを使わなくても良い気がしてきたんだけど、そのあたりってどうなんでしょうね?

github.com

github.com

⇧ JettyとNettyのリポジトリを見た感じ、Kwikは『Kwik is an implementation of the QUIC protocol in (100%) Java. 』ってあるから、純度100%のJavaライブラリという点がJettyとNettyとは異なると言えるけど...

ただ、そんなことが知りたいのではなくて、機能とか性能の違いが知りたいんよね...

そもそもJavaでQUIC使ってみました的な情報が無いので、まだ暫く様子見って感じで良さそうということにしておこう。

ちなみに、

medium.com

⇧ Rustで実装してらっしゃる方はおられました。

まぁ、正直、JavaでQUICを使うような機会が訪れるか分からんのと、

stackoverflow.com

⇧ 他のライブラリが、QUICに対応して無さそうということもあるようなので...

まぁ、大容量のデータをプログラム上のネットワーク通信処理で高速にサーバーに送る方法が無いか調べてたら、何となくQUICに辿り着いたということなんだが...

大容量のデータでも高速に動作するのか分からんですが、

gigazine.net

github.com

Born from the ashes of Stadia, this repository contains tools for syncing and streaming files from Windows to Windows or Linux. The tools are based on Content Defined Chunking (CDC), in particular FastCDC, to split up files into chunks.

https://github.com/google/cdc-file-transfer

Googleさんが高速ファイル転送ツールを公開してるそうな。

Content Defined Chunking (CDC)」がそもそも、何なのか分からんのだけど、「Chunking」については、Wikipediaに情報があって、

Typical modern software systems allocate memory dynamically from structures known as heaps. Calls are made to heap-management routines to allocate and free memory. Heap management involves some computation time and can be a performance issue. Chunking refers to strategies for improving performance by using special knowledge of a situation to aggregate related memory-allocation requests. For example, if it is known that a certain kind of object will typically be required in groups of eight, instead of allocating and freeing each object individually, making sixteen calls to the heap manager, one could allocate and free an array of eight of the objects, reducing the number of calls to two.

https://en.wikipedia.org/wiki/Chunking_(computing)

In HTTP message transmission

Main article: Chunked transfer encoding

Chunking is a specific feature of the HTTP 1.1 protocol. Here, the meaning is the opposite of that used in memory management. It refers to a facility that allows inconveniently large messages to be broken into conveniently-sized smaller "chunks".

https://en.wikipedia.org/wiki/Chunking_(computing)

⇧ HTTP 1.1 protocolの固有の機能と言っているのだけど、「Content Defined Chunking (CDC)」は内部的にHTTP 1.1 protocolを使っているってことなんだろうか?

う~む、分からん...

疲れたので、就寝することにします...

毎度モヤモヤ感が半端ない...

今回はこのへんで。