我們後面的系列文章會配合著 RFC 的規格書以及 ngtcp2 的實作來講解,那今天我們就先試著把 ngtcp2 編譯起來,跑跑看範例來嘗鮮一下,如果連編譯都編不起來,後續的實驗就只能紙上談兵了XD
編譯環境
由於使用 ubuntu 22.04 的關係,基本上很多工具類的軟體都已經有內建了,我們底下需要手動操作的是編譯一些 ngtcp2 的依賴,如果 os 版本跟我有點差異也可以在 ngtcp2 的文檔中查找一下基本的 requirements 看看是否符合,因為範例是用 c++ 寫的,也請注意一下自己電腦上編譯器是否能支援編譯 c++ 20。
$ mkdir quic_learn
$ cd quic_learn/
依照文檔的指示依序編譯 nghttp3 以及 openssl
$ git clone --depth 1 -b OpenSSL_1_1_1q+quic https://github.com/quictls/openssl
$ cd openssl
$ ./config enable-tls1_3 --prefix=$PWD/build
$ make -j$(nproc)
$ make install_sw
$ cd .. # 安裝好回到 quic_learn/
這邊可以發現到時候 quic 所依賴的 TLS 1.3 功能是安裝在 quic_learn/openssl/
底下,沒有安裝到系統內,這樣方便很多,避免跟內建的 openssl 有撞車的風險
$ git clone https://github.com/ngtcp2/nghttp3
$ cd nghttp3/
$ autoreconf -i
$ ./configure --prefix=$PWD/build --enable-lib-only
$ make -j${nproc} check
$ make install
$ git clone https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ autoreconf -i
$ ./configure PKG_CONFIG_PATH=$PWD/../openssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig LDFLAGS="-Wl,-rpath,$PWD/../openssl/build/lib"
$ make -j${nproc} check
上述的步驟都是照著 ngtcp2 的文檔,但我在最後編譯 ngtcp2 的時候都沒有報錯,但是 /example/
資料夾底下沒有出現預期的 client 跟 server 執行檔,所以重新檢查了 ./configure
的結果,發現是缺少了 libev
的依賴,但文檔默認你之前裝過了,所以請再安裝一下 libev
。
可以選擇用 apt 的方式安裝
$ apt install libev-dev
也可以選擇手動編譯
$ git clone https://github.com/enki/libev
$ cd libev
$ ./configure # 默認
$ make -j${nproc}
$ sudo make install
安裝好之後就可以在 /usr/local/lib/
底下找到
再繼續回去編譯 ngtcp2,編譯如果沒有報錯的話就可以在 example
底下看到 client 與 server 兩個待會要用的範例執行檔。
生成密鑰與憑證
$ cd examples
$ openssl genrsa -out server.key 2048
$ openssl req -new -x509 -key server.key -out server.crt -days 3650
一切準備就緒請開兩個 terminal,分別作為 client 與 server
$ ./server 127.0.0.1 4433 server.key server.crt
可能很多人跟我一樣會在這邊看到這個錯誤
先用 ldd
檢查一下動態庫依賴關係
這邊用個軟連結來處理,預設 libev
安裝在 /usr/local/lib
它沒辦法抓到
$ sudo ln -s /usr/local/lib/libev.so.4 /usr/lib/libev.so.4
$ sudo ldconfig
再次執行 ./server
發現可以正常啟動了
$ ./client 127.0.0.1 4433 -i
同時開啟兩個 terminal 就可以看到我們的第一個 quic 建立成功了,而且範例還很貼心的加了很多 log 來表示兩端都分別做了哪些事情。