文章目錄
- 前言
- 一、HTTP3測試 in Ubuntu
- 1.1. 基本軟件
- 1.2. gcc/g++
- 1.2.1. Ubuntu22
- 1.2.2. Ubuntu20
- 1.2.2.1. 必備庫
- 1.2.2.1.1. gmp
- 1.2.2.1.2. mpfr
- 1.2.2.1.3. mpc
- 1.2.2.2. 安裝
- 1.3. libev >= 4.11(備用)
- 1.3.1. 安裝
- 1.3.2. 測試
- 1.4. nghttp3
- 1.5. ngtcp2 build with wolfSSL
- 1.5.1. wolfSSL >= 5.7.0
- 1.5.2. ngtcp2
- 1.5.3. 使用
- 1.5.3.1. server
- 1.5.3.2. client
- 1.6. ngtcp2 build with LibreSSL(可選)
- 1.6.1. LibreSSL
- 1.6.2. ngtcp2
- 1.7. Wireshark
- 二、HTTP3測試 in CentOS8.5
前言
nghttp3是Github上的一個基于C語言的HTTP/3庫,它使用的QUIC協議則由ngtcp2庫實現,并且可以從該庫中編譯出若干二進制文件形式的樣例以供入門,本文參考項目說明,分享個人從軟件安裝到樣例使用的全過程。
如果后續計劃使用的Linux系統為Ubuntu,建議至少為Ubuntu 22。
一、HTTP3測試 in Ubuntu
1.1. 基本軟件
名稱 | 操作 |
---|---|
pkg-config >= 0.20 | sudo apt install pkg-config -y && pkg-config --version |
autoconf | sudo apt install autoconf -y |
automake | automake --version |
autotools-dev | apt search autotools-dev |
libev-dev | sudo apt install libev-dev |
libtool | sudo apt install libtool -y |
make | sudo apt install make |
1.2. gcc/g++
后續編譯ngtcp2的項目時,正常情況下會編譯出若干個可執行文件,但這要求g++能夠支持C++20的特性,否則在編譯時會提示如下信息:
因此,gcc/g++的版本至少為v11。
1.2.1. Ubuntu22
Ubuntu22.4默認使用的gcc和g++版本為v11,可以通過apt安裝的最高版本為v12,但是需要額外操作以指定版本。
首先通過apt安裝gcc-12和g+±12:
sudo apt install gcc-12 g++-12 -y
此時可以通過gcc-12命令來使用v12版本的gcc,但是使用gcc命令時仍會提示找不到該命令或者使用的舊版本。
將gcc-12添加到update-alternatives工具中,設置其為gcc的軟鏈接,同時設置從屬的g++:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 20 --slave /usr/bin/g++ g++ /usr/bin/g++-12
確認版本配置:
sudo update-alternatives --config gcc
此時即可通過gcc命令來使用gcc-12。
1.2.2. Ubuntu20
Ubuntu20.4通過apt可安裝的gcc版本最高為v10,因此只能使用源碼安裝gcc12。
1.2.2.1. 必備庫
1.2.2.1.1. gmp
從官網(https://gmplib.org/download/gmp/)下載最新的源碼包:
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
解壓:
tar -xvf gmp-6.3.0.tar.xz
進入解壓后的文件夾:
cd gmp-6.3.0
編譯:
./configure
make -j16
sudo make install
返回上一級目錄:
cd ..
1.2.2.1.2. mpfr
從官網(https://www.mpfr.org/)下載最新的源碼包:
wget https://www.mpfr.org/mpfr-4.2.1/mpfr-4.2.1.tar.xz
解壓:
tar -xvf mpfr-4.2.1.tar.xz
進入解壓后的文件夾:
cd mpfr-4.2.1
編譯:
./configure
make -j16
sudo make install
返回上一級目錄:
cd ..
1.2.2.1.3. mpc
從官網(https://ftp.gnu.org/gnu/mpc/)下載最新的源碼包:
wget https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz
解壓:
tar -zxvf mpc-1.3.1.tar.gz
進入解壓后的文件夾:
cd mpc-1.3.1
編譯:
./configure
make -j16
sudo make install
返回上一級目錄:
cd ..
1.2.2.2. 安裝
從官網鏡像(http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/)下載v12的源碼包:
wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-12.4.0/gcc-12.4.0.tar.gz
解壓:
tar -zxvf gcc-12.4.0.tar.gz
進入解壓后的文件夾:
cd gcc-12.4.0
編譯:
./configure --disable-multilib
make -j16
sudo make install
編譯完成后查看版本號:
gcc -v
返回上一級目錄:
cd ..
1.3. libev >= 4.11(備用)
如果不能apt安裝libev的版本不滿足要求,則可參考該方法。本節參考來源為Libev中文手冊。
1.3.1. 安裝
從官網下載源碼包:
wget https://libev.cn/downloads/libev-4.33.tar.gz
解壓:
tar -zxvf libev-4.33.tar.gz
進入解壓后的文件夾:
cd libev-4.33
編譯:
sh autogen.sh
./configure
make && sudo make install
1.3.2. 測試
返回上一級目錄:
cd ..
新建main.c文件:
vim main.c
內容如下:
#include <stdio.h>
#include <ev.h>static ev_idle idle;static void idle_cb(struct ev_loop* loop, ev_idle *idle, int revents) {puts("idle start.");ev_idle_stop(loop, idle);
}int main(int argc, char const *argv[])
{struct ev_loop* loop = EV_DEFAULT;// Register an idle event.ev_idle_init(&idle, idle_cb);ev_idle_start(loop, &idle);ev_run(loop, 0);return 0;
}
編譯main:
cc -o main main.c -L/usr/local/lib -I/usr/local/include/ -lev -Wl,-rpath,/usr/local/lib
運行main:
./main
輸出"idle start."證明安裝成功。
1.4. nghttp3
克隆源代碼倉庫:
git clone --recursive https://github.com/ngtcp2/nghttp3
進入源代碼目錄:
cd nghttp3
編譯:
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only
make -j$(nproc) check
make install
返回上一級目錄:
cd ..
1.5. ngtcp2 build with wolfSSL
1.5.1. wolfSSL >= 5.7.0
構建ngtcp2中的樣例文件需要至少一種TLS庫,這里使用的是wolfSSL。
克隆源代碼倉庫:
git clone --depth 1 -b v5.7.4-stable https://github.com/wolfSSL/wolfssl
進入源代碼目錄:
cd wolfssl
編譯:
autoreconf -i
./configure --prefix=$PWD/build --enable-all --enable-aesni --enable-harden --enable-keylog-export --disable-ech
make -j$(nproc)
make install
返回上一級目錄:
cd ..
1.5.2. ngtcp2
克隆源代碼倉庫(翻墻非必須):
git clone --recursive https://github.com/ngtcp2/ngtcp2
--recursive
參數用于下載項目中的子項目。
ngtcp2需要兩個子項目:munit和urlparse,將分別下載到tests/和third-party/下。
urlparse也需要兩個子項目:munit和http-parser,將分別下載到主目錄下。
正常情況下,所有子模塊都應檢出:
如果任何一個子模塊下載失敗,例如:
解決方法是刪除已下載的項目:
rm -r -f ngtcp2
重新克隆源代碼倉庫,直到一切正常。
進入源代碼目錄:
cd ngtcp2
編譯:
autoreconf -i
./configure PKG_CONFIG_PATH=$PWD/../wolfssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig --with-wolfssl
make -j$(nproc) check
編譯成功后在examples中會多出兩個二進制文件wsslclient和wsslserver,它們使用HTTP/3。此外,還有兩個二進制文件h09wsslclient和h09wsslserver,它們使用HTTP/0.9。
./examples/wsslclient -h
./examples/wsslserver -h
如果運行wsslclient和wsslserver時出現如下問題:
error while loading shared libraries: libev.so.4: cannot open shared object file: No such file or directory
原因是在安裝libev時,默認安裝在/usr/local/lib中,而二進制文件在/usr/lib中找不到該庫。解決方案是重新編譯libev,指定安裝路徑:
cd ~/libev-4.33
sh autogen.sh
./configure --prefix=/usr
sudo make && sudo make install
1.5.3. 使用
1.5.3.1. server
進入wsslserver所在目錄:
cd ~/ngtcp2/examples
為服務端生成私鑰和證書:
openssl genrsa -out server.key 2048
openssl req -new -x509 -key server.key -out server.crt -days 3650
啟動服務端:
./wsslserver 192.168.202.129 4433 server.key server.crt
之后服務端就會在對應端口監聽請求,注意輸出Using document root /home/csb2/ngtcp2/examples/
,說明服務端是以當前目錄為文件的根目錄。
1.5.3.2. client
進入wsslclient所在目錄:
cd ~/ngtcp2/examples
啟動客戶端,下載由URL指定的文件:
./wsslclient --download=./ 192.168.202.129 4433 https://192.168.202.129:4433/clash.tar.gz
這里URI中的路徑是服務端根目錄的相對路徑。
1.6. ngtcp2 build with LibreSSL(可選)
這里使用LibreSSL庫而非wolfSSL。
1.6.1. LibreSSL
克隆源代碼倉庫(翻墻非必須):
git clone --depth 1 -b v4.0.0 https://github.com/libressl/portable.git libressl
進入源代碼目錄:
cd libressl
編譯:
export LIBRESSL_GIT_OPTIONS="-b libressl-v4.0.0" #必須,不然下一步會報錯
./autogen.sh
./configure --prefix=$PWD/build
make -j$(nproc) install
返回上一級目錄:
cd ..
1.6.2. ngtcp2
進入源代碼目錄:
cd ngtcp2
編譯:
autoreconf -i
./configure PKG_CONFIG_PATH=$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../libressl/build/lib/pkgconfig
make -j$(nproc) check
編譯成功后在examples中會多出兩個二進制文件qtlsclient和qtlsserver。
1.7. Wireshark
使用apt命令安裝Wireshark:
sudo add-apt-repository universe
sudo apt install wireshark
安裝過程中會詢問是否允許非超級用戶捕獲數據包,選擇yes。
將當前用戶添加到 wireshark 組:
sudo usermod -aG wireshark $(whoami)
在服務端所在的虛機上打開Wireshark,點擊“編輯-首選項”。
設置QUIC UDP端口為服務端啟動時的端口:
設置TLS的(Pre)-Master-Secret log filename為examples中的sslkeylog.log:
選擇正確的網絡接口(即,服務端IP所在的網卡),設置過濾器:
udp.port==4433
點擊“開始捕獲分組”即可抓包。
二、HTTP3測試 in CentOS8.5
名稱 | 操作 |
---|---|
pkg-config >= 0.20 | yum install pkg-config && pkg-config --version |
autoconf | yum install autoconf |
automake | yum install automake |
libtool | yum install libtool |
make | yum install make |
gcc-11 / g+±11 | yum install -y gcc-toolset-11 && source /opt/rh/gcc-toolset-11/enable && gcc -v |
libev-dev | 詳見1.3節 |
nghttp3 | 詳見1.4節 |
wolfSSL | 詳見1.5.1節 |
ngtcp2 | 詳見1.5.2節 |