mirror of
https://gitea.invidious.io/iv-org/lsquic.cr
synced 2024-08-15 00:43:31 +00:00
Compare commits
50 commits
Author | SHA1 | Date | |
---|---|---|---|
|
c273c83b98 | ||
|
a4ccf0dc6d | ||
|
26ccce9a29 | ||
|
0b9f16aa2f | ||
|
632d632bfa | ||
|
52bf01c559 | ||
|
cdec31a66e | ||
|
9eb767d668 | ||
|
4ba1a4a4dd | ||
|
c417433a47 | ||
|
53f31fd94c | ||
|
40b9ccc733 | ||
|
db4f73c25c | ||
|
3aab3dd7f1 | ||
|
cb01d0fbb8 | ||
|
a3d2458c28 | ||
|
c965e0a380 | ||
|
cd6ec66292 | ||
|
5ef544c1bd | ||
|
4855742c45 | ||
|
24dc58db99 | ||
|
2eceb3c279 | ||
|
195bb9e480 | ||
|
96a75aae05 | ||
|
5261034c0d | ||
|
392a57aa8f | ||
|
a6033ff7df | ||
|
e9db6c73b5 | ||
|
0d1ee4e712 | ||
|
bc101423fa | ||
|
fd48ef3471 | ||
|
023b4d9195 | ||
|
32aee44d8e | ||
|
31ad3664a5 | ||
|
1f7c9c652f | ||
|
50041fa046 | ||
|
31403055e7 | ||
|
016f733109 | ||
|
0c0d8748a7 | ||
|
aa94a6ea1b | ||
|
7f2ecbfcdc | ||
|
3c7d1aeeb3 | ||
|
d11cafa0ee | ||
|
7c0ade984c | ||
|
d85dd0b29b | ||
|
e5c49ba0c0 | ||
|
b84cc84aa1 | ||
|
820c169849 | ||
|
a50712f308 | ||
|
09b3f94426 |
13 changed files with 431 additions and 199 deletions
66
.github/workflows/ci.yml
vendored
Normal file
66
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
name: lsquic.cr CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *" # Every day at 00:00
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "master"
|
||||||
|
- "api-only"
|
||||||
|
pull_request:
|
||||||
|
branches: "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
name: "build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }}"
|
||||||
|
|
||||||
|
continue-on-error: ${{ !matrix.stable }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
stable: [true]
|
||||||
|
crystal:
|
||||||
|
- 1.0.0
|
||||||
|
- 1.1.1
|
||||||
|
- 1.2.0
|
||||||
|
include:
|
||||||
|
- crystal: nightly
|
||||||
|
stable: false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install Crystal
|
||||||
|
uses: crystal-lang/install-crystal@v1.5.3
|
||||||
|
with:
|
||||||
|
crystal: ${{ matrix.crystal }}
|
||||||
|
|
||||||
|
- name: Cache Shards
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ./lib
|
||||||
|
key: shards-${{ hashFiles('shard.lock') }}
|
||||||
|
|
||||||
|
- name: Install Shards
|
||||||
|
run: |
|
||||||
|
if ! shards check; then
|
||||||
|
shards install
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: crystal spec --warnings all --error-on-warnings --error-trace
|
||||||
|
|
||||||
|
- name: Run lint
|
||||||
|
run: |
|
||||||
|
if ! crystal tool format --check; then
|
||||||
|
crystal tool format
|
||||||
|
git diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: crystal build --warnings all --error-on-warnings --error-trace src/lsquic.cr
|
39
.github/workflows/container-release.yml
vendored
Normal file
39
.github/workflows/container-release.yml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
name: Build and release container
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "master"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
with:
|
||||||
|
platforms: arm64
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: quay.io
|
||||||
|
username: ${{ secrets.QUAY_USERNAME }}
|
||||||
|
password: ${{ secrets.QUAY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image for Push Event
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: docker/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64/v8
|
||||||
|
push: true
|
||||||
|
tags: quay.io/invidious/lsquic-compiled:${{ github.sha }},quay.io/invidious/lsquic-compiled:latest
|
12
README.md
12
README.md
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
Crystal bindings to the excellent [LSQUIC](https://github.com/litespeedtech/lsquic) library.
|
Crystal bindings to the excellent [LSQUIC](https://github.com/litespeedtech/lsquic) library.
|
||||||
|
|
||||||
`libssl.a`, `libcrypto.a` are both licensed under `LICENSE.boringssl`.
|
Releases track lsquic's versioning starting with `v2.18.1`.
|
||||||
|
|
||||||
`liblsquic.a` is licensed under `LICENSE.lsquic` and `LICENSE.chrome`.
|
`liblsquic.a` is licensed under `LICENSE.lsquic` and `LICENSE.chrome`.
|
||||||
|
|
||||||
|
Lsquic uses [boringssl](https://github.com/google/boringssl), which is licensed under `LICENSE.boringssl`.
|
||||||
|
|
||||||
This library is available under the MIT license.
|
This library is available under the MIT license.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
@ -15,7 +17,7 @@ This library is available under the MIT license.
|
||||||
```yaml
|
```yaml
|
||||||
dependencies:
|
dependencies:
|
||||||
lsquic:
|
lsquic:
|
||||||
github: omarroth/lsquic.cr
|
github: iv-org/lsquic.cr
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Run `shards install`
|
2. Run `shards install`
|
||||||
|
@ -37,7 +39,7 @@ client.get("/", headers: HTTP::Headers{
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
1. Fork it (<https://github.com/omarroth/lsquic.cr/fork>)
|
1. Fork it (<https://github.com/iv-org/lsquic.cr/fork>)
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||||
4. Push to the branch (`git push origin my-new-feature`)
|
4. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
@ -46,7 +48,3 @@ client.get("/", headers: HTTP::Headers{
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
- [Omar Roth](https://github.com/omarroth) - creator and maintainer
|
- [Omar Roth](https://github.com/omarroth) - creator and maintainer
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
46
docker/APKBUILD-boringssl
Normal file
46
docker/APKBUILD-boringssl
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Based on https://aur.archlinux.org/packages/boringssl-git/
|
||||||
|
# Maintainer: Omar Roth <omarroth@protonmail.com>
|
||||||
|
pkgname=boringssl
|
||||||
|
pkgver=1.1.0
|
||||||
|
pkgrel=0
|
||||||
|
pkgdesc="BoringSSL is a fork of OpenSSL that is designed to meet Google's needs"
|
||||||
|
url="https://boringssl.googlesource.com/boringssl"
|
||||||
|
arch="all"
|
||||||
|
license="MIT"
|
||||||
|
replaces="openssl libressl"
|
||||||
|
depends="!openssl-libs-static"
|
||||||
|
makedepends_host="linux-headers"
|
||||||
|
makedepends="cmake git go perl"
|
||||||
|
subpackages="$pkgname-static $pkgname-dev $pkgname-doc"
|
||||||
|
source="251b516.tar.gz::https://github.com/google/boringssl/tarball/251b516"
|
||||||
|
builddir="$srcdir/google-boringssl-251b516"
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Debug .
|
||||||
|
make ssl crypto
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
make all_tests
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
for i in *.md ; do
|
||||||
|
install -Dm644 $i "$pkgdir/usr/share/doc/$pkgname/$i"
|
||||||
|
done
|
||||||
|
install -d "$pkgdir/usr/lib"
|
||||||
|
install -d "$pkgdir/usr/include"
|
||||||
|
cp -R include/openssl "$pkgdir/usr/include"
|
||||||
|
|
||||||
|
install -Dm755 crypto/libcrypto.a "$pkgdir/usr/lib/libcrypto.a"
|
||||||
|
install -Dm755 ssl/libssl.a "$pkgdir/usr/lib/libssl.a"
|
||||||
|
# install -Dm755 decrepit/libdecrepit.a "$pkgdir/usr/lib/libdecrepit.a"
|
||||||
|
# install -Dm755 libboringssl_gtest.a "$pkgdir/usr/lib/libboringssl_gtest.a"
|
||||||
|
}
|
||||||
|
sha512sums="
|
||||||
|
b1d42ed188cf0cce89d40061fa05de85b387ee4244f1236ea488a431536a2c6b657b4f03daed0ac9328c7f5c4c9330499283b8a67f1444dcf9ba5e97e1199c4e 251b516.tar.gz
|
||||||
|
"
|
43
docker/APKBUILD-lsquic
Normal file
43
docker/APKBUILD-lsquic
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Maintainer: Omar Roth <omarroth@protonmail.com>
|
||||||
|
pkgname=lsquic
|
||||||
|
pkgver=2.18.1
|
||||||
|
pkgrel=0
|
||||||
|
pkgdesc="LiteSpeed QUIC and HTTP/3 Library"
|
||||||
|
url="https://github.com/litespeedtech/lsquic"
|
||||||
|
arch="all"
|
||||||
|
license="MIT"
|
||||||
|
depends="boringssl-dev boringssl-static zlib-static libevent-static"
|
||||||
|
makedepends="cmake git go perl bsd-compat-headers linux-headers"
|
||||||
|
subpackages="$pkgname-static"
|
||||||
|
source="v$pkgver.tar.gz::https://github.com/litespeedtech/lsquic/tarball/v2.18.1
|
||||||
|
ls-qpack-$pkgver.tar.gz::https://github.com/litespeedtech/ls-qpack/tarball/a8ae6ef
|
||||||
|
ls-hpack-$pkgver.tar.gz::https://github.com/litespeedtech/ls-hpack/tarball/bd5d589"
|
||||||
|
builddir="$srcdir/litespeedtech-$pkgname-692a910"
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
cp -r -T "$srcdir/litespeedtech-ls-qpack-a8ae6ef" "$builddir/src/liblsquic/ls-qpack"
|
||||||
|
cp -r -T "$srcdir/litespeedtech-ls-hpack-bd5d589" "$builddir/src/lshpack"
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
|
-DBORINGSSL_INCLUDE=/usr/include/openssl \
|
||||||
|
-DBORINGSSL_LIB_crypto=/usr/lib \
|
||||||
|
-DBORINGSSL_LIB_ssl=/usr/lib .
|
||||||
|
make lsquic
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
make tests
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
install -d "$pkgdir/usr/lib"
|
||||||
|
install -Dm755 src/liblsquic/liblsquic.a "$pkgdir/usr/lib/liblsquic.a"
|
||||||
|
}
|
||||||
|
sha512sums="
|
||||||
|
d015a72f1e88750ecb364768a40f532678f11ded09c6447a2e698b20f43fa499ef143a53f4c92a5938dfece0e39e687dc9df4aea97c618faee0c63da771561c3 v2.18.1.tar.gz
|
||||||
|
c5629085a3881815fb0b72a321eeba8de093eff9417b8ac7bde1ee1264971be0dca6d61d74799b02ae03a4c629b2a9cf21387deeb814935339a8a2503ea33fee ls-qpack-2.18.1.tar.gz
|
||||||
|
1b9f7ce4c82dadfca8154229a415b0335a61761eba698f814d4b94195c708003deb5cb89318a1ab78ac8fa88b141bc9df283fb1c6e40b3ba399660feaae353a0 ls-hpack-2.18.1.tar.gz
|
||||||
|
"
|
28
docker/Dockerfile
Normal file
28
docker/Dockerfile
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
FROM alpine:edge AS liblsquic-builder
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN apk add --no-cache build-base git apk-tools abuild cmake go perl linux-headers
|
||||||
|
|
||||||
|
RUN abuild-keygen -a -n && \
|
||||||
|
cp /root/.abuild/-*.rsa.pub /etc/apk/keys/
|
||||||
|
|
||||||
|
COPY docker/APKBUILD-boringssl boringssl/APKBUILD
|
||||||
|
RUN cd boringssl && abuild -F -r && cd ..
|
||||||
|
|
||||||
|
RUN apk add --repository /root/packages/src boringssl boringssl-dev boringssl-static
|
||||||
|
|
||||||
|
RUN apk add --no-cache zlib-dev zlib-static libevent-dev libevent-static
|
||||||
|
|
||||||
|
COPY docker/APKBUILD-lsquic lsquic/APKBUILD
|
||||||
|
RUN cd lsquic && abuild -F -r && cd ..
|
||||||
|
|
||||||
|
RUN apk add --repository /root/packages/src lsquic-static
|
||||||
|
|
||||||
|
RUN mkdir tmp && cd tmp && \
|
||||||
|
ar -x /usr/lib/libssl.a && \
|
||||||
|
ar -x /usr/lib/libcrypto.a && \
|
||||||
|
ar -x /usr/lib/liblsquic.a && \
|
||||||
|
ar rc liblsquic.a *.o && \
|
||||||
|
ranlib liblsquic.a && \
|
||||||
|
cp liblsquic.a /root/liblsquic.a && \
|
||||||
|
cd .. && rm -rf tmp
|
|
@ -1,9 +1,9 @@
|
||||||
name: lsquic
|
name: lsquic
|
||||||
version: 0.1.9
|
version: 2.18.1-2
|
||||||
|
|
||||||
authors:
|
authors:
|
||||||
- Omar Roth <omarroth@protonmail.com>
|
- Omar Roth <omarroth@protonmail.com>
|
||||||
|
|
||||||
crystal: 0.33.0
|
crystal: ">= 0.35.0, < 2.0.0"
|
||||||
|
|
||||||
license: MIT
|
license: MIT
|
||||||
|
|
|
@ -11,6 +11,8 @@ module QUIC
|
||||||
end
|
end
|
||||||
|
|
||||||
class Client
|
class Client
|
||||||
|
REQUIRED_HEADERS = {":method", ":scheme", ":path", ":authority"}
|
||||||
|
|
||||||
def self.stream_readf(stream_if_ctx : Void*, buf : UInt8*, buf_len : LibC::SizeT, fin : LibC::Int)
|
def self.stream_readf(stream_if_ctx : Void*, buf : UInt8*, buf_len : LibC::SizeT, fin : LibC::Int)
|
||||||
stream_ctx = Box(StreamCtx).unbox(stream_if_ctx)
|
stream_ctx = Box(StreamCtx).unbox(stream_if_ctx)
|
||||||
stream_ctx.io.write Slice.new(buf, buf_len)
|
stream_ctx.io.write Slice.new(buf, buf_len)
|
||||||
|
@ -30,9 +32,7 @@ module QUIC
|
||||||
.try { |c| LibLsquic.conn_get_ctx(c) }
|
.try { |c| LibLsquic.conn_get_ctx(c) }
|
||||||
.try { |c| Box(StreamCtx).unbox(c) }
|
.try { |c| Box(StreamCtx).unbox(c) }
|
||||||
|
|
||||||
if LibLsquic.stream_is_pushed(s) != 0
|
return Box.box(stream_ctx) if LibLsquic.stream_is_pushed(s) != 0
|
||||||
return Box.box(stream_ctx)
|
|
||||||
end
|
|
||||||
|
|
||||||
LibLsquic.stream_wantwrite(s, 1)
|
LibLsquic.stream_wantwrite(s, 1)
|
||||||
Box.box(stream_ctx)
|
Box.box(stream_ctx)
|
||||||
|
@ -40,32 +40,33 @@ module QUIC
|
||||||
|
|
||||||
def self.on_write(s : LibLsquic::StreamT, stream_if_ctx : Void*)
|
def self.on_write(s : LibLsquic::StreamT, stream_if_ctx : Void*)
|
||||||
stream_ctx = Box(StreamCtx).unbox(stream_if_ctx)
|
stream_ctx = Box(StreamCtx).unbox(stream_if_ctx)
|
||||||
|
request_headers = stream_ctx.request.headers
|
||||||
|
|
||||||
headers = [] of LibLsquic::HttpHeader
|
headers = [] of LibLsquic::LsxpackHeader
|
||||||
(stream_ctx.request.headers.to_a.sort_by { |k, v| {":authority", ":path", ":scheme", ":method"}.index(k) || -1 }).reverse.each do |tuple|
|
REQUIRED_HEADERS.each do |name|
|
||||||
name, values = tuple
|
value = stream_ctx.request.headers[name]
|
||||||
name = name.downcase
|
headers << LibLsquic::LsxpackHeader.new(
|
||||||
|
buf: "#{name}#{value}",
|
||||||
values.each do |value|
|
name_len: name.bytesize,
|
||||||
name_vec = LibLsquic::Iovec.new
|
name_offset: 0,
|
||||||
name_vec.iov_base = name.to_slice
|
val_len: value.bytesize,
|
||||||
name_vec.iov_len = name.bytesize
|
val_offset: name.bytesize
|
||||||
|
)
|
||||||
value_vec = LibLsquic::Iovec.new
|
|
||||||
value_vec.iov_base = value.to_slice
|
|
||||||
value_vec.iov_len = value.bytesize
|
|
||||||
|
|
||||||
header = LibLsquic::HttpHeader.new
|
|
||||||
header.name = name_vec
|
|
||||||
header.value = value_vec
|
|
||||||
|
|
||||||
headers << header
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
http_headers = LibLsquic::HttpHeaders.new
|
request_headers.each do |name, values|
|
||||||
http_headers.count = headers.size
|
name = name.downcase
|
||||||
http_headers.headers = headers.to_unsafe
|
next if REQUIRED_HEADERS.includes? name
|
||||||
|
headers << LibLsquic::LsxpackHeader.new(
|
||||||
|
buf: "#{name}#{values[0]}",
|
||||||
|
name_len: name.bytesize,
|
||||||
|
name_offset: 0,
|
||||||
|
val_len: values[0].bytesize,
|
||||||
|
val_offset: name.bytesize
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_headers = LibLsquic::HttpHeaders.new(count: headers.size, headers: headers.to_unsafe)
|
||||||
|
|
||||||
raise "Could not send headers" if LibLsquic.stream_send_headers(s, pointerof(http_headers), stream_ctx.request.body ? 0 : 1) != 0
|
raise "Could not send headers" if LibLsquic.stream_send_headers(s, pointerof(http_headers), stream_ctx.request.body ? 0 : 1) != 0
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ module QUIC
|
||||||
|
|
||||||
def run_engine
|
def run_engine
|
||||||
LibLsquic.engine_init_settings(out engine_settings, ENGINE_FLAGS)
|
LibLsquic.engine_init_settings(out engine_settings, ENGINE_FLAGS)
|
||||||
engine_settings.es_ua = "Chrome/78.0.3904.97 Linux x86_64"
|
engine_settings.es_ua = "Chrome/83.0.4103.61 Linux x86_64"
|
||||||
engine_settings.es_ecn = 0
|
engine_settings.es_ecn = 0
|
||||||
|
|
||||||
err_buf = Bytes.new(0x100)
|
err_buf = Bytes.new(0x100)
|
||||||
|
@ -194,7 +195,16 @@ module QUIC
|
||||||
hostname = host.starts_with?('[') && host.ends_with?(']') ? host[1..-2] : host
|
hostname = host.starts_with?('[') && host.ends_with?(']') ? host[1..-2] : host
|
||||||
@engine_open = true
|
@engine_open = true
|
||||||
|
|
||||||
conn = LibLsquic.engine_connect(engine, LibLsquic::Version::Lsqver046, socket.local_address, socket.remote_address, Box.box(socket), nil, hostname, 0, nil, 0, nil, 0)
|
conn = LibLsquic.engine_connect(
|
||||||
|
engine,
|
||||||
|
LibLsquic::Version::Lsqver050,
|
||||||
|
socket.local_address,
|
||||||
|
socket.remote_address,
|
||||||
|
Box.box(socket), nil,
|
||||||
|
hostname, 0,
|
||||||
|
nil, 0,
|
||||||
|
nil, 0
|
||||||
|
)
|
||||||
spawn do
|
spawn do
|
||||||
while stream_ctx = @stream_channel.receive
|
while stream_ctx = @stream_channel.receive
|
||||||
LibLsquic.conn_set_ctx(conn, Box.box(stream_ctx))
|
LibLsquic.conn_set_ctx(conn, Box.box(stream_ctx))
|
||||||
|
@ -203,25 +213,29 @@ module QUIC
|
||||||
end
|
end
|
||||||
@engine_open = false
|
@engine_open = false
|
||||||
LibLsquic.engine_destroy(engine)
|
LibLsquic.engine_destroy(engine)
|
||||||
|
@socket.try &.close
|
||||||
|
@socket = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
buffer = Bytes.new(0x600)
|
begin
|
||||||
loop do
|
buffer = Bytes.new(0x600)
|
||||||
begin
|
loop do
|
||||||
bytes_read = socket.read buffer
|
bytes_read = socket.read buffer
|
||||||
rescue ex
|
break if !@engine_open
|
||||||
break
|
LibLsquic.engine_packet_in(engine, buffer[0, bytes_read], bytes_read, socket.local_address, socket.remote_address, Box.box(socket), 0) if bytes_read != 0
|
||||||
|
LibLsquic.engine_process_conns(engine)
|
||||||
end
|
end
|
||||||
break if !@engine_open
|
rescue IO::Error
|
||||||
LibLsquic.engine_packet_in(engine, buffer[0, bytes_read], bytes_read, socket.local_address, socket.remote_address, Box.box(socket), 0) if bytes_read != 0
|
# may have already been closed
|
||||||
LibLsquic.engine_process_conns(engine)
|
ensure
|
||||||
|
@socket.try &.close
|
||||||
|
@socket = nil
|
||||||
end
|
end
|
||||||
@socket.try &.close
|
|
||||||
@socket = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def socket : UDPSocket
|
def socket : UDPSocket
|
||||||
return @socket.as(UDPSocket) if @socket
|
socket = @socket
|
||||||
|
return socket.not_nil! if @socket
|
||||||
|
|
||||||
socket = UDPSocket.new @family
|
socket = UDPSocket.new @family
|
||||||
case @family
|
case @family
|
||||||
|
@ -497,8 +511,6 @@ module QUIC
|
||||||
def close
|
def close
|
||||||
@stream_channel.send nil
|
@stream_channel.send nil
|
||||||
Fiber.yield
|
Fiber.yield
|
||||||
@socket.try &.close
|
|
||||||
@socket = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private def new_request(method, path, headers, body : BodyType)
|
private def new_request(method, path, headers, body : BodyType)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,74 +1,64 @@
|
||||||
@[Link(ldflags: "#{__DIR__}/ext/liblsquic.a -lz")]
|
@[Link(ldflags: "#{__DIR__}/ext/liblsquic.a")]
|
||||||
lib LibLsquic
|
lib LibLsquic
|
||||||
MAX_CID_LEN = 20
|
LSENG_SERVER = 1
|
||||||
QQUIC_CID_LEN = 8
|
LSENG_HTTP = 2
|
||||||
LSENG_SERVER = 1
|
|
||||||
LSENG_HTTP = 2
|
|
||||||
LSENG_HTTP_SERVER = LSENG_SERVER | LSENG_HTTP
|
LSENG_HTTP_SERVER = LSENG_SERVER | LSENG_HTTP
|
||||||
GLOBAL_CLIENT = 1
|
GLOBAL_CLIENT = 1
|
||||||
GLOBAL_SERVER = 2
|
GLOBAL_SERVER = 2
|
||||||
MAJOR_VERSION = 2
|
MAJOR_VERSION = 2
|
||||||
MINOR_VERSION = 6
|
MINOR_VERSION = 18
|
||||||
PATCH_VERSION = 1
|
PATCH_VERSION = 1
|
||||||
EXPERIMENTAL_Q098 = 0
|
EXPERIMENTAL_Q098 = 0
|
||||||
DEPRECATED_VERSIONS = 0
|
DEPRECATED_VERSIONS = 0
|
||||||
MIN_CFW = 16 * 1024
|
|
||||||
DF_CFCW_SERVER = 3 * 1024 * 1024 / 2
|
|
||||||
DF_CFCW_CLIENT = 15 * 1024 * 1024
|
|
||||||
DF_SFCW_SERVER = 1 * 1024 * 1024
|
|
||||||
DF_SFCW_CLIENT = 6 * 1024 * 1024
|
|
||||||
DF_MAX_STREAMS_IN = 100
|
DF_MAX_STREAMS_IN = 100
|
||||||
DF_INIT_MAX_STREAM_DATA_BIDI_LOCAL_SERVER = 0
|
DF_INIT_MAX_STREAM_DATA_BIDI_LOCAL_SERVER = 0
|
||||||
DF_INIT_MAX_STREAM_DATA_BIDI_REMOTE_CLIENT = 0
|
DF_INIT_MAX_STREAM_DATA_BIDI_REMOTE_CLIENT = 0
|
||||||
DF_INIT_MAX_STREAMS_UNI_CLIENT = 100
|
DF_INIT_MAX_STREAMS_UNI_CLIENT = 100
|
||||||
DF_INIT_MAX_STREAMS_UNI_SERVER = 3
|
DF_INIT_MAX_STREAMS_UNI_SERVER = 3
|
||||||
DF_INIT_MAX_STREAM_DATA_UNI_CLIENT = 32 * 1024
|
DF_IDLE_TIMEOUT = 30
|
||||||
DF_INIT_MAX_STREAM_DATA_UNI_SERVER = 12 * 1024
|
DF_PING_PERIOD = 15
|
||||||
DF_IDLE_TIMEOUT = 30
|
DF_SILENT_CLOSE = 1
|
||||||
DF_PING_PERIOD = 15
|
DF_MAX_HEADER_LIST_SIZE = 0
|
||||||
DF_HANDSHAKE_TO = 10 * 1000 * 1000
|
|
||||||
DF_IDLE_CONN_TO = DF_IDLE_TIMEOUT * 1000 * 1000
|
|
||||||
DF_SILENT_CLOSE = 1
|
|
||||||
DF_MAX_HEADER_LIST_SIZE = 0
|
|
||||||
DF_UA = "LSQUIC"
|
DF_UA = "LSQUIC"
|
||||||
DF_STTL = 86400
|
DF_STTL = 86400
|
||||||
DF_MAX_INCHOATE = 1 * 1000 * 1000
|
DF_SUPPORT_NSTP = 0
|
||||||
DF_SUPPORT_SREJ_SERVER = 1
|
DF_SUPPORT_PUSH = 1
|
||||||
DF_SUPPORT_SREJ_CLIENT = 0
|
DF_SUPPORT_TCID0 = 1
|
||||||
DF_SUPPORT_NSTP = 0
|
DF_HONOR_PRST = 0
|
||||||
DF_SUPPORT_PUSH = 1
|
DF_SEND_PRST = 0
|
||||||
DF_SUPPORT_TCID0 = 1
|
DF_PROGRESS_CHECK = 1000
|
||||||
DF_HONOR_PRST = 0
|
DF_RW_ONCE = 0
|
||||||
DF_SEND_PRST = 0
|
DF_PROC_TIME_THRESH = 0
|
||||||
DF_PROGRESS_CHECK = 1000
|
DF_PACE_PACKETS = 1
|
||||||
DF_RW_ONCE = 0
|
DF_CLOCK_GRANULARITY = 1000
|
||||||
DF_PROC_TIME_THRESH = 0
|
DF_SCID_LEN = 8
|
||||||
DF_PACE_PACKETS = 1
|
DF_SCID_ISS_RATE = 60
|
||||||
DF_CLOCK_GRANULARITY = 1000
|
DF_QPACK_DEC_MAX_BLOCKED = 100
|
||||||
DF_SCID_LEN = 8
|
DF_QPACK_DEC_MAX_SIZE = 4096
|
||||||
DF_SCID_ISS_RATE = 60
|
DF_QPACK_ENC_MAX_BLOCKED = 100
|
||||||
DF_QPACK_DEC_MAX_BLOCKED = 100
|
DF_QPACK_ENC_MAX_SIZE = 4096
|
||||||
DF_QPACK_DEC_MAX_SIZE = 4096
|
DF_ECN = 0
|
||||||
DF_QPACK_ENC_MAX_BLOCKED = 100
|
DF_ALLOW_MIGRATION = 1
|
||||||
DF_QPACK_ENC_MAX_SIZE = 4096
|
DF_QL_BITS = 2
|
||||||
DF_ECN = 0
|
DF_SPIN = 1
|
||||||
DF_ALLOW_MIGRATION = 1
|
DF_DELAYED_ACKS = 0
|
||||||
DF_CC_ALGO = 2
|
DF_TIMESTAMPS = 1
|
||||||
|
DF_CC_ALGO = 1
|
||||||
|
DF_MAX_UDP_PAYLOAD_SIZE_RX = 0
|
||||||
|
DF_GREASE_QUIC_BIT = 1
|
||||||
|
DF_NOPROGRESS_TIMEOUT_SERVER = 60
|
||||||
|
DF_NOPROGRESS_TIMEOUT_CLIENT = 0
|
||||||
|
|
||||||
struct Cid
|
struct Cid
|
||||||
len : UintFast8T
|
len : UInt8
|
||||||
u_cid : CidUCid
|
u_cid : CidUCid
|
||||||
end
|
end
|
||||||
|
|
||||||
alias UintFast8T = UInt8
|
|
||||||
|
|
||||||
union CidUCid
|
union CidUCid
|
||||||
buf : Uint8T[20]
|
buf : LibC::UInt8T[20]
|
||||||
id : Uint64T
|
id : LibC::UInt64T
|
||||||
end
|
end
|
||||||
|
|
||||||
alias Uint8T = UInt8
|
|
||||||
alias Uint64T = LibC::ULong
|
|
||||||
alias Engine = Void
|
alias Engine = Void
|
||||||
alias Conn = Void
|
alias Conn = Void
|
||||||
alias ConnCtx = Void
|
alias ConnCtx = Void
|
||||||
|
@ -77,16 +67,26 @@ lib LibLsquic
|
||||||
|
|
||||||
struct HttpHeaders
|
struct HttpHeaders
|
||||||
count : LibC::Int
|
count : LibC::Int
|
||||||
headers : HttpHeader*
|
headers : LsxpackHeader*
|
||||||
end
|
end
|
||||||
|
|
||||||
struct HttpHeader
|
struct LsxpackHeader
|
||||||
name : Iovec
|
buf : LibC::Char*
|
||||||
value : Iovec
|
name_hash : LibC::UInt32T
|
||||||
|
nameval_hash : LibC::UInt32T
|
||||||
|
name_offset : LibC::UInt16T
|
||||||
|
name_len : LibC::UInt16T
|
||||||
|
val_offset : LibC::UInt16T
|
||||||
|
val_len : LibC::UInt16T
|
||||||
|
chain_next_idx : LibC::UInt16T
|
||||||
|
hpack_index : LibC::UInt8T
|
||||||
|
qpack_index : LibC::UInt8T
|
||||||
|
app_index : LibC::UInt8T
|
||||||
|
flags : LibC::UInt8T
|
||||||
|
indexed_type : LibC::UInt8T
|
||||||
|
dec_overhead : LibC::UInt8T
|
||||||
end
|
end
|
||||||
|
|
||||||
type HttpHeaderT = HttpHeader
|
|
||||||
|
|
||||||
struct Iovec
|
struct Iovec
|
||||||
iov_base : UInt8*
|
iov_base : UInt8*
|
||||||
iov_len : LibC::SizeT
|
iov_len : LibC::SizeT
|
||||||
|
@ -126,12 +126,11 @@ lib LibLsquic
|
||||||
es_silent_close : LibC::Int
|
es_silent_close : LibC::Int
|
||||||
es_max_header_list_size : LibC::UInt
|
es_max_header_list_size : LibC::UInt
|
||||||
es_ua : LibC::Char*
|
es_ua : LibC::Char*
|
||||||
es_sttl : Uint64T
|
es_sttl : LibC::UInt64T
|
||||||
es_pdmd : Uint32T
|
es_pdmd : LibC::UInt32T
|
||||||
es_aead : Uint32T
|
es_aead : LibC::UInt32T
|
||||||
es_kexs : Uint32T
|
es_kexs : LibC::UInt32T
|
||||||
es_max_inchoate : LibC::UInt
|
es_max_inchoate : LibC::UInt
|
||||||
es_support_srej : LibC::Int
|
|
||||||
es_support_push : LibC::Int
|
es_support_push : LibC::Int
|
||||||
es_support_tcid0 : LibC::Int
|
es_support_tcid0 : LibC::Int
|
||||||
es_support_nstp : LibC::Int
|
es_support_nstp : LibC::Int
|
||||||
|
@ -159,9 +158,13 @@ lib LibLsquic
|
||||||
es_ecn : LibC::Int
|
es_ecn : LibC::Int
|
||||||
es_allow_migration : LibC::Int
|
es_allow_migration : LibC::Int
|
||||||
es_cc_algo : LibC::UInt
|
es_cc_algo : LibC::UInt
|
||||||
|
es_ql_bits : LibC::Int
|
||||||
|
es_spin : LibC::Int
|
||||||
|
es_delayed_acks : LibC::Int
|
||||||
|
es_timestamps : LibC::Int
|
||||||
|
es_max_packet_size_rx : LibC::UInt16T
|
||||||
end
|
end
|
||||||
|
|
||||||
alias Uint32T = LibC::UInt
|
|
||||||
fun engine_init_settings = lsquic_engine_init_settings(x0 : EngineSettings*, engine_flags : LibC::UInt)
|
fun engine_init_settings = lsquic_engine_init_settings(x0 : EngineSettings*, engine_flags : LibC::UInt)
|
||||||
fun engine_check_settings = lsquic_engine_check_settings(settings : EngineSettings*, engine_flags : LibC::UInt, err_buf : LibC::Char*, err_buf_sz : LibC::SizeT) : LibC::Int
|
fun engine_check_settings = lsquic_engine_check_settings(settings : EngineSettings*, engine_flags : LibC::UInt, err_buf : LibC::Char*, err_buf_sz : LibC::SizeT) : LibC::Int
|
||||||
|
|
||||||
|
@ -189,25 +192,17 @@ lib LibLsquic
|
||||||
end
|
end
|
||||||
|
|
||||||
struct HsetIf
|
struct HsetIf
|
||||||
hsi_create_header_set : (Void*, LibC::Int -> Void*)
|
hsi_create_header_set : (Void*, StreamT, LibC::Int -> Void*)
|
||||||
hsi_process_header : (Void*, LibC::UInt, LibC::Char*, LibC::UInt, LibC::Char*, LibC::UInt -> HeaderStatus)
|
hsi_prepare_decode : (Void*, LsxpackHeader*, LibC::SizeT -> LsxpackHeader*)
|
||||||
|
hsi_process_header : (Void*, LsxpackHeader* -> LibC::Int)
|
||||||
hsi_discard_header_set : (Void* -> Void)
|
hsi_discard_header_set : (Void* -> Void)
|
||||||
|
hsi_flags : HsiFlag
|
||||||
end
|
end
|
||||||
|
|
||||||
enum HeaderStatus
|
enum HsiFlag
|
||||||
HdrOk = 0
|
HsiHttp1X = 2
|
||||||
HdrErrDuplicatePsdoHdr = 1
|
HsiHashName = 4
|
||||||
HdrErrIncomplReqPsdoHdr = 2
|
HsiHashNameval = 8
|
||||||
HdrErrUnnecReqPsdoHdr = 3
|
|
||||||
HdrErrBadReqHeader = 4
|
|
||||||
HdrErrIncomplRespPsdoHdr = 5
|
|
||||||
HdrErrUnnecRespPsdoHdr = 6
|
|
||||||
HdrErrUnknownPsdoHdr = 7
|
|
||||||
HdrErrUppercaseHeader = 8
|
|
||||||
HdrErrMisplacedPsdoHdr = 9
|
|
||||||
HdrErrMissingPsdoHdr = 10
|
|
||||||
HdrErrHeadersTooLarge = 11
|
|
||||||
HdrErrNomem = 12
|
|
||||||
end
|
end
|
||||||
|
|
||||||
struct KeylogIf
|
struct KeylogIf
|
||||||
|
@ -239,27 +234,32 @@ lib LibLsquic
|
||||||
ea_hsi_ctx : Void*
|
ea_hsi_ctx : Void*
|
||||||
ea_keylog_if : KeylogIf*
|
ea_keylog_if : KeylogIf*
|
||||||
ea_keylog_ctx : Void*
|
ea_keylog_ctx : Void*
|
||||||
|
ea_alpn : LibC::Char*
|
||||||
end
|
end
|
||||||
|
|
||||||
alias PacketsOutF = (Void*, OutSpec*, LibC::UInt -> LibC::Int)
|
alias PacketsOutF = (Void*, OutSpec*, LibC::UInt -> LibC::Int)
|
||||||
alias SslCtxSt = Void
|
alias SslCtxSt = Void
|
||||||
alias LookupCertF = (Void*, LibC::Sockaddr*, LibC::Char* -> SslCtxSt*)
|
alias Sockaddr = LibC::Sockaddr
|
||||||
|
alias LookupCertF = (Void*, Sockaddr*, LibC::Char* -> SslCtxSt*)
|
||||||
type CidT = Cid
|
type CidT = Cid
|
||||||
alias CidsUpdateF = (Void*, Void**, CidT*, LibC::UInt -> Void)
|
alias CidsUpdateF = (Void*, Void**, CidT*, LibC::UInt -> Void)
|
||||||
alias StackStX509 = Void
|
alias StackStX509 = Void
|
||||||
fun engine_new = lsquic_engine_new(engine_flags : LibC::UInt, x1 : EngineApi*) : EngineT
|
fun engine_new = lsquic_engine_new(engine_flags : LibC::UInt, api : EngineApi*) : EngineT
|
||||||
type EngineT = Void*
|
type EngineT = Void*
|
||||||
fun engine_connect = lsquic_engine_connect(x0 : EngineT, x1 : Version, local_sa : LibC::Sockaddr*, peer_sa : LibC::Sockaddr*, peer_ctx : Void*, conn_ctx : Void*, hostname : LibC::Char*, max_packet_size : LibC::UShort, zero_rtt : UInt8*, zero_rtt_len : LibC::SizeT, token : UInt8*, token_sz : LibC::SizeT) : ConnT
|
fun engine_connect = lsquic_engine_connect(x0 : EngineT, x1 : Version, local_sa : Sockaddr*, peer_sa : Sockaddr*, peer_ctx : Void*, conn_ctx : Void*, hostname : LibC::Char*, max_packet_size : LibC::UShort, zero_rtt : UInt8*, zero_rtt_len : LibC::SizeT, token : UInt8*, token_sz : LibC::SizeT) : ConnT
|
||||||
|
|
||||||
enum Version
|
enum Version
|
||||||
Lsqver039 = 0
|
Lsqver043 = 0
|
||||||
Lsqver043 = 1
|
Lsqver046 = 1
|
||||||
Lsqver046 = 2
|
Lsqver050 = 2
|
||||||
LsqverId23 = 3
|
LsqverId27 = 3
|
||||||
LsqverId24 = 4
|
LsqverId28 = 4
|
||||||
LsqverVerneg = 5
|
LsqverId29 = 5
|
||||||
NLsqver = 6
|
LsqverVerneg = 6
|
||||||
|
NLsqver = 7
|
||||||
end
|
end
|
||||||
fun engine_packet_in = lsquic_engine_packet_in(x0 : EngineT, packet_in_data : UInt8*, packet_in_size : LibC::SizeT, sa_local : LibC::Sockaddr*, sa_peer : LibC::Sockaddr*, peer_ctx : Void*, ecn : LibC::Int) : LibC::Int
|
|
||||||
|
fun engine_packet_in = lsquic_engine_packet_in(x0 : EngineT, packet_in_data : UInt8*, packet_in_size : LibC::SizeT, sa_local : Sockaddr*, sa_peer : Sockaddr*, peer_ctx : Void*, ecn : LibC::Int) : LibC::Int
|
||||||
fun engine_process_conns = lsquic_engine_process_conns(engine : EngineT)
|
fun engine_process_conns = lsquic_engine_process_conns(engine : EngineT)
|
||||||
fun engine_has_unsent_packets = lsquic_engine_has_unsent_packets(engine : EngineT) : LibC::Int
|
fun engine_has_unsent_packets = lsquic_engine_has_unsent_packets(engine : EngineT) : LibC::Int
|
||||||
fun engine_send_unsent_packets = lsquic_engine_send_unsent_packets(engine : EngineT)
|
fun engine_send_unsent_packets = lsquic_engine_send_unsent_packets(engine : EngineT)
|
||||||
|
@ -271,13 +271,12 @@ lib LibLsquic
|
||||||
fun conn_going_away = lsquic_conn_going_away(x0 : ConnT)
|
fun conn_going_away = lsquic_conn_going_away(x0 : ConnT)
|
||||||
fun conn_close = lsquic_conn_close(x0 : ConnT)
|
fun conn_close = lsquic_conn_close(x0 : ConnT)
|
||||||
fun stream_wantread = lsquic_stream_wantread(s : StreamT, is_want : LibC::Int) : LibC::Int
|
fun stream_wantread = lsquic_stream_wantread(s : StreamT, is_want : LibC::Int) : LibC::Int
|
||||||
fun stream_read = lsquic_stream_read(s : StreamT, buf : Void*, len : LibC::SizeT) : SsizeT
|
fun stream_read = lsquic_stream_read(s : StreamT, buf : Void*, len : LibC::SizeT) : LibC::SizeT
|
||||||
alias SsizeT = LibC::Long
|
fun stream_readv = lsquic_stream_readv(s : StreamT, vec : Iovec*, iovcnt : LibC::Int) : LibC::SizeT
|
||||||
fun stream_readv = lsquic_stream_readv(s : StreamT, x1 : Iovec*, iovcnt : LibC::Int) : SsizeT
|
fun stream_readf = lsquic_stream_readf(s : StreamT, readf : (Void*, UInt8*, LibC::SizeT, LibC::Int -> LibC::SizeT), ctx : Void*) : LibC::SizeT
|
||||||
fun stream_readf = lsquic_stream_readf(s : StreamT, readf : (Void*, UInt8*, LibC::SizeT, LibC::Int -> LibC::SizeT), ctx : Void*) : SsizeT
|
|
||||||
fun stream_wantwrite = lsquic_stream_wantwrite(s : StreamT, is_want : LibC::Int) : LibC::Int
|
fun stream_wantwrite = lsquic_stream_wantwrite(s : StreamT, is_want : LibC::Int) : LibC::Int
|
||||||
fun stream_write = lsquic_stream_write(s : StreamT, buf : Void*, len : LibC::SizeT) : SsizeT
|
fun stream_write = lsquic_stream_write(s : StreamT, buf : Void*, len : LibC::SizeT) : LibC::SizeT
|
||||||
fun stream_writev = lsquic_stream_writev(s : StreamT, vec : Iovec*, count : LibC::Int) : SsizeT
|
fun stream_writev = lsquic_stream_writev(s : StreamT, vec : Iovec*, count : LibC::Int) : LibC::SizeT
|
||||||
|
|
||||||
struct Reader
|
struct Reader
|
||||||
lsqr_read : (Void*, Void*, LibC::SizeT -> LibC::SizeT)
|
lsqr_read : (Void*, Void*, LibC::SizeT -> LibC::SizeT)
|
||||||
|
@ -285,18 +284,17 @@ lib LibLsquic
|
||||||
lsqr_ctx : Void*
|
lsqr_ctx : Void*
|
||||||
end
|
end
|
||||||
|
|
||||||
fun stream_writef = lsquic_stream_writef(x0 : StreamT, x1 : Reader*) : SsizeT
|
fun stream_writef = lsquic_stream_writef(x0 : StreamT, x1 : Reader*) : LibC::SizeT
|
||||||
fun stream_flush = lsquic_stream_flush(s : StreamT) : LibC::Int
|
fun stream_flush = lsquic_stream_flush(s : StreamT) : LibC::Int
|
||||||
fun stream_send_headers = lsquic_stream_send_headers(s : StreamT, h : HttpHeaders*, eos : LibC::Int) : LibC::Int
|
fun stream_send_headers = lsquic_stream_send_headers(s : StreamT, headers : HttpHeaders*, eos : LibC::Int) : LibC::Int
|
||||||
type HttpHeadersT = HttpHeaders
|
|
||||||
fun stream_get_hset = lsquic_stream_get_hset(x0 : StreamT) : Void*
|
fun stream_get_hset = lsquic_stream_get_hset(x0 : StreamT) : Void*
|
||||||
fun conn_push_stream = lsquic_conn_push_stream(c : ConnT, hdr_set : Void*, s : StreamT, url : Iovec*, authority : Iovec*, headers : HttpHeaders*) : LibC::Int
|
fun conn_push_stream = lsquic_conn_push_stream(c : ConnT, hdr_set : Void*, s : StreamT, headers : HttpHeaders*) : LibC::Int
|
||||||
fun conn_is_push_enabled = lsquic_conn_is_push_enabled(x0 : ConnT) : LibC::Int
|
fun conn_is_push_enabled = lsquic_conn_is_push_enabled(x0 : ConnT) : LibC::Int
|
||||||
fun stream_shutdown = lsquic_stream_shutdown(s : StreamT, how : LibC::Int) : LibC::Int
|
fun stream_shutdown = lsquic_stream_shutdown(s : StreamT, how : LibC::Int) : LibC::Int
|
||||||
fun stream_close = lsquic_stream_close(s : StreamT) : LibC::Int
|
fun stream_close = lsquic_stream_close(s : StreamT) : LibC::Int
|
||||||
fun conn_get_server_cert_chain = lsquic_conn_get_server_cert_chain(x0 : ConnT) : StackStX509*
|
fun conn_get_server_cert_chain = lsquic_conn_get_server_cert_chain(x0 : ConnT) : StackStX509*
|
||||||
fun stream_id = lsquic_stream_id(s : StreamT) : StreamIdT
|
fun stream_id = lsquic_stream_id(s : StreamT) : StreamIdT
|
||||||
alias StreamIdT = Uint64T
|
alias StreamIdT = LibC::UInt64T
|
||||||
fun stream_get_ctx = lsquic_stream_get_ctx(s : StreamT) : Void*
|
fun stream_get_ctx = lsquic_stream_get_ctx(s : StreamT) : Void*
|
||||||
fun stream_is_pushed = lsquic_stream_is_pushed(s : StreamT) : LibC::Int
|
fun stream_is_pushed = lsquic_stream_is_pushed(s : StreamT) : LibC::Int
|
||||||
fun stream_is_rejected = lsquic_stream_is_rejected(s : StreamT) : LibC::Int
|
fun stream_is_rejected = lsquic_stream_is_rejected(s : StreamT) : LibC::Int
|
||||||
|
@ -305,16 +303,16 @@ lib LibLsquic
|
||||||
fun stream_priority = lsquic_stream_priority(s : StreamT) : LibC::UInt
|
fun stream_priority = lsquic_stream_priority(s : StreamT) : LibC::UInt
|
||||||
fun stream_set_priority = lsquic_stream_set_priority(s : StreamT, priority : LibC::UInt) : LibC::Int
|
fun stream_set_priority = lsquic_stream_set_priority(s : StreamT, priority : LibC::UInt) : LibC::Int
|
||||||
fun stream_conn = lsquic_stream_conn(s : StreamT) : ConnT
|
fun stream_conn = lsquic_stream_conn(s : StreamT) : ConnT
|
||||||
fun conn_get_stream_by_id = lsquic_conn_get_stream_by_id(c : ConnT, stream_id : StreamIdT) : StreamT
|
|
||||||
fun conn_id = lsquic_conn_id(c : ConnT) : CidT*
|
fun conn_id = lsquic_conn_id(c : ConnT) : CidT*
|
||||||
fun conn_get_engine = lsquic_conn_get_engine(c : ConnT) : EngineT
|
fun conn_get_engine = lsquic_conn_get_engine(c : ConnT) : EngineT
|
||||||
fun conn_get_sockaddr = lsquic_conn_get_sockaddr(c : ConnT, local : LibC::Sockaddr**, peer : LibC::Sockaddr**) : LibC::Int
|
fun conn_get_sockaddr = lsquic_conn_get_sockaddr(c : ConnT, local : Sockaddr**, peer : Sockaddr**) : LibC::Int
|
||||||
|
|
||||||
struct LoggerIf
|
struct LoggerIf
|
||||||
log_buf : (Void*, LibC::Char*, LibC::SizeT -> LibC::Int)
|
log_buf : (Void*, LibC::Char*, LibC::SizeT -> LibC::Int)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun logger_init = lsquic_logger_init(x0 : LoggerIf*, logger_ctx : Void*, x2 : LoggerTimestampStyle)
|
fun logger_init = lsquic_logger_init(x0 : LoggerIf*, logger_ctx : Void*, x2 : LoggerTimestampStyle)
|
||||||
|
|
||||||
enum LoggerTimestampStyle
|
enum LoggerTimestampStyle
|
||||||
LltsNone = 0
|
LltsNone = 0
|
||||||
LltsHhmmssms = 1
|
LltsHhmmssms = 1
|
||||||
|
@ -324,6 +322,7 @@ lib LibLsquic
|
||||||
LltsYyyymmddHhmmssus = 5
|
LltsYyyymmddHhmmssus = 5
|
||||||
NLlts = 6
|
NLlts = 6
|
||||||
end
|
end
|
||||||
|
|
||||||
fun set_log_level = lsquic_set_log_level(log_level : LibC::Char*) : LibC::Int
|
fun set_log_level = lsquic_set_log_level(log_level : LibC::Char*) : LibC::Int
|
||||||
fun logger_lopt = lsquic_logger_lopt(optarg : LibC::Char*) : LibC::Int
|
fun logger_lopt = lsquic_logger_lopt(optarg : LibC::Char*) : LibC::Int
|
||||||
fun engine_quic_versions = lsquic_engine_quic_versions(x0 : EngineT) : LibC::UInt
|
fun engine_quic_versions = lsquic_engine_quic_versions(x0 : EngineT) : LibC::UInt
|
||||||
|
@ -337,15 +336,14 @@ lib LibLsquic
|
||||||
LsqCryQuic = 0
|
LsqCryQuic = 0
|
||||||
LsqCryTlSv13 = 1
|
LsqCryTlSv13 = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
fun conn_crypto_cipher = lsquic_conn_crypto_cipher(c : ConnT) : LibC::Char*
|
fun conn_crypto_cipher = lsquic_conn_crypto_cipher(c : ConnT) : LibC::Char*
|
||||||
fun str2ver = lsquic_str2ver(str : LibC::Char*, len : LibC::SizeT) : Version
|
fun str2ver = lsquic_str2ver(str : LibC::Char*, len : LibC::SizeT) : Version
|
||||||
fun alpn2ver = lsquic_alpn2ver(alpn : LibC::Char*, len : LibC::SizeT) : Version
|
fun alpn2ver = lsquic_alpn2ver(alpn : LibC::Char*, len : LibC::SizeT) : Version
|
||||||
fun engine_cooldown = lsquic_engine_cooldown(x0 : EngineT)
|
fun engine_cooldown = lsquic_engine_cooldown(x0 : EngineT)
|
||||||
fun hsk_getssl = lsquic_hsk_getssl(conn : ConnT) : SslSt*
|
|
||||||
alias SslSt = Void
|
|
||||||
fun conn_get_ctx = lsquic_conn_get_ctx(x0 : ConnT) : Void*
|
fun conn_get_ctx = lsquic_conn_get_ctx(x0 : ConnT) : Void*
|
||||||
fun conn_set_ctx = lsquic_conn_set_ctx(x0 : ConnT, x1 : Void*)
|
fun conn_set_ctx = lsquic_conn_set_ctx(x0 : ConnT, x1 : Void*)
|
||||||
fun conn_get_peer_ctx = lsquic_conn_get_peer_ctx(x0 : ConnT, local_sa : LibC::Sockaddr*) : Void*
|
fun conn_get_peer_ctx = lsquic_conn_get_peer_ctx(x0 : ConnT, local_sa : Sockaddr*) : Void*
|
||||||
fun conn_abort = lsquic_conn_abort(x0 : ConnT)
|
fun conn_abort = lsquic_conn_abort(x0 : ConnT)
|
||||||
fun get_alt_svc_versions = lsquic_get_alt_svc_versions(versions : LibC::UInt) : LibC::Char*
|
fun get_alt_svc_versions = lsquic_get_alt_svc_versions(versions : LibC::UInt) : LibC::Char*
|
||||||
fun get_h3_alpns = lsquic_get_h3_alpns(versions : LibC::UInt) : LibC::Char**
|
fun get_h3_alpns = lsquic_get_h3_alpns(versions : LibC::UInt) : LibC::Char**
|
||||||
|
@ -354,6 +352,7 @@ lib LibLsquic
|
||||||
fun engine_earliest_adv_tick = lsquic_engine_earliest_adv_tick(engine : EngineT, diff : LibC::Int*) : LibC::Int
|
fun engine_earliest_adv_tick = lsquic_engine_earliest_adv_tick(engine : EngineT, diff : LibC::Int*) : LibC::Int
|
||||||
fun engine_count_attq = lsquic_engine_count_attq(engine : EngineT, from_now : LibC::Int) : LibC::UInt
|
fun engine_count_attq = lsquic_engine_count_attq(engine : EngineT, from_now : LibC::Int) : LibC::UInt
|
||||||
fun conn_status = lsquic_conn_status(x0 : ConnT, errbuf : LibC::Char*, bufsz : LibC::SizeT) : ConnStatus
|
fun conn_status = lsquic_conn_status(x0 : ConnT, errbuf : LibC::Char*, bufsz : LibC::SizeT) : ConnStatus
|
||||||
|
|
||||||
enum ConnStatus
|
enum ConnStatus
|
||||||
LsconnStHskInProgress = 0
|
LsconnStHskInProgress = 0
|
||||||
LsconnStConnected = 1
|
LsconnStConnected = 1
|
||||||
|
@ -366,5 +365,6 @@ lib LibLsquic
|
||||||
LsconnStClosed = 8
|
LsconnStClosed = 8
|
||||||
LsconnStPeerGoingAway = 9
|
LsconnStPeerGoingAway = 9
|
||||||
end
|
end
|
||||||
$ver2str : LibC::Char*[6]
|
|
||||||
|
$lsquic_ver2str : LibC::Char*[7]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
require "openssl"
|
require "openssl"
|
||||||
|
|
||||||
@[Link(ldflags: "#{__DIR__}/ext/liblsquic.a #{__DIR__}/ext/libcrypto.a")]
|
|
||||||
lib LibCrypto
|
lib LibCrypto
|
||||||
fun evp_ripemd160 = EVP_sha1 : EVP_MD
|
fun evp_ripemd160 = EVP_sha1 : EVP_MD
|
||||||
fun sk_free = sk_free(st : Void*)
|
fun sk_free = sk_free(st : Void*)
|
||||||
|
@ -12,8 +11,9 @@ lib LibCrypto
|
||||||
fun err_load_crypto_strings = rand : LibC::Int
|
fun err_load_crypto_strings = rand : LibC::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
@[Link(ldflags: "#{__DIR__}/ext/libssl.a")]
|
|
||||||
lib LibSSL
|
lib LibSSL
|
||||||
|
{% ssl_version = "1.1.0" %}
|
||||||
|
|
||||||
fun ssl_set_tlsext_host_name = SSL_set_tlsext_host_name(handle : SSL, name : Char*) : Long
|
fun ssl_set_tlsext_host_name = SSL_set_tlsext_host_name(handle : SSL, name : Char*) : Long
|
||||||
fun ssl_ctx_set_tmp_ecdh = SSL_CTX_set_tmp_ecdh(ctx : SSLContext, parg : Void*) : ULong
|
fun ssl_ctx_set_tmp_ecdh = SSL_CTX_set_tmp_ecdh(ctx : SSLContext, parg : Void*) : ULong
|
||||||
fun ssl_ctx_get_mode = SSL_CTX_get_mode(ctx : SSLContext) : ULong
|
fun ssl_ctx_get_mode = SSL_CTX_get_mode(ctx : SSLContext) : ULong
|
||||||
|
@ -27,43 +27,6 @@ lib LibSSL
|
||||||
fun ssl_load_error_strings = rand : LibC::Int
|
fun ssl_load_error_strings = rand : LibC::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
abstract class OpenSSL::SSL::Context
|
|
||||||
def set_tmp_ecdh_key(curve = LibCrypto::NID_X9_62_prime256v1)
|
|
||||||
key = LibCrypto.ec_key_new_by_curve_name(curve)
|
|
||||||
raise OpenSSL::Error.new("ec_key_new_by_curve_name") if key.null?
|
|
||||||
LibSSL.ssl_ctx_set_tmp_ecdh(@handle, key)
|
|
||||||
LibCrypto.ec_key_free(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the current modes set on the TLS context.
|
|
||||||
def modes
|
|
||||||
OpenSSL::SSL::Modes.new LibSSL.ssl_ctx_get_mode(@handle)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds modes to the TLS context.
|
|
||||||
def add_modes(mode : OpenSSL::SSL::Modes)
|
|
||||||
OpenSSL::SSL::Modes.new LibSSL.ssl_ctx_set_mode(@handle, mode)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Removes modes from the TLS context.
|
|
||||||
def remove_modes(mode : OpenSSL::SSL::Modes)
|
|
||||||
OpenSSL::SSL::Modes.new LibSSL.ssl_ctx_clear_mode(@handle, mode)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the current options set on the TLS context.
|
|
||||||
def options
|
|
||||||
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_get_options(@handle)
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_options(options : OpenSSL::SSL::Options)
|
|
||||||
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_set_options(@handle, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_options(options : OpenSSL::SSL::Options)
|
|
||||||
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_clear_options(@handle, options)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
struct OpenSSL::BIO
|
struct OpenSSL::BIO
|
||||||
CRYSTAL_BIO_BORING = begin
|
CRYSTAL_BIO_BORING = begin
|
||||||
bwrite = LibCrypto::BioMethodWriteOld.new do |bio, data, len|
|
bwrite = LibCrypto::BioMethodWriteOld.new do |bio, data, len|
|
||||||
|
@ -163,6 +126,43 @@ struct OpenSSL::BIO
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
abstract class OpenSSL::SSL::Context
|
||||||
|
def set_tmp_ecdh_key(curve = LibCrypto::NID_X9_62_prime256v1)
|
||||||
|
key = LibCrypto.ec_key_new_by_curve_name(curve)
|
||||||
|
raise OpenSSL::Error.new("ec_key_new_by_curve_name") if key.null?
|
||||||
|
LibSSL.ssl_ctx_set_tmp_ecdh(@handle, key)
|
||||||
|
LibCrypto.ec_key_free(key)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the current modes set on the TLS context.
|
||||||
|
def modes
|
||||||
|
OpenSSL::SSL::Modes.new LibSSL.ssl_ctx_get_mode(@handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds modes to the TLS context.
|
||||||
|
def add_modes(mode : OpenSSL::SSL::Modes)
|
||||||
|
OpenSSL::SSL::Modes.new LibSSL.ssl_ctx_set_mode(@handle, mode)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes modes from the TLS context.
|
||||||
|
def remove_modes(mode : OpenSSL::SSL::Modes)
|
||||||
|
OpenSSL::SSL::Modes.new LibSSL.ssl_ctx_clear_mode(@handle, mode)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the current options set on the TLS context.
|
||||||
|
def options
|
||||||
|
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_get_options(@handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_options(options : OpenSSL::SSL::Options)
|
||||||
|
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_set_options(@handle, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_options(options : OpenSSL::SSL::Options)
|
||||||
|
OpenSSL::SSL::Options.new LibSSL.ssl_ctx_clear_options(@handle, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
abstract class OpenSSL::SSL::Socket < IO
|
abstract class OpenSSL::SSL::Socket < IO
|
||||||
class Client < Socket
|
class Client < Socket
|
||||||
def initialize(io, context : Context::Client = Context::Client.new, sync_close : Bool = false, hostname : String? = nil)
|
def initialize(io, context : Context::Client = Context::Client.new, sync_close : Bool = false, hostname : String? = nil)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue