diff options
| author | 李佳 <[email protected]> | 2024-07-10 06:58:33 +0000 |
|---|---|---|
| committer | lijia <[email protected]> | 2024-07-17 16:29:42 +0800 |
| commit | 60b96b10eb985d13ef6df0f4fc525074e7128325 (patch) | |
| tree | 5b5b833295c37ae52c02eb9ccccc4dfa5598a377 | |
Initial commitv1.0.2
198 files changed, 6068 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63b3612 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +Debug +*.o +*.d +*.so +.cproject +.project +.settings/ +SI +build*/ +src/inc +src/lib64 +cmake-build-*/ +.vscode/ +.cache/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..902d17a --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,173 @@ +variables: + GIT_STRATEGY: "clone" + BUILD_IMAGE_CENTOS8: "git.mesalab.cn:7443/mesa_platform/build-env:rockylinux" + BUILD_PADDING_PREFIX: /tmp/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX_PREFIX_PREFIX_PREFIX_PREFIX_PREFIX/ + INSTALL_DEPENDENCY_PLATFORM: sapp-devel libasan systemd-devel systemd libnsl glib2-devel libMESA_htable libMESA_jump_layer libbreakpad_mini libuuid libMESA_field_stat2 libfieldstat3 libfieldstat4 libfieldstat4-devel + INSTALL_DEPENDENCY_FRAMEWORK: libMESA_handle_logger-devel libcjson-devel libcjson framework_env + libMESA_prof_load-devel libMESA_handle_logger + stellar-on-sapp-devel stellar-on-sapp + + INSTALL_PREFIX: "/opt/tsg/" + RPM_REPO_PREFIX: stellar + +stages: +- build +- test +- package + +.build_before_script: + before_script: + - mkdir -p $BUILD_PADDING_PREFIX/$CI_PROJECT_NAMESPACE/ + - ln -s $CI_PROJECT_DIR $BUILD_PADDING_PREFIX/$CI_PROJECT_PATH + - cd $BUILD_PADDING_PREFIX/$CI_PROJECT_PATH + - chmod +x ./ci/travis.sh + - yum makecache + - yum install -y elfutils-libelf-devel + +.build_by_travis_for_centos8: + stage: build + image: $BUILD_IMAGE_CENTOS8 + extends: .build_before_script + script: + - dnf --enablerepo=powertools install -y libmnl-devel + - dnf --enablerepo=powertools install -y libnfnetlink-devel + - ./ci/travis.sh + tags: + - share + +branch_build_debug_for_centos8: + stage: build + extends: .build_by_travis_for_centos8 + variables: + BUILD_TYPE: Debug + except: + - /^develop.*$/i + - /^master.*$/i + - tags + +branch_build_release_for_centos8: + stage: build + variables: + BUILD_TYPE: RelWithDebInfo + extends: .build_by_travis_for_centos8 + except: + - /^develop.*$/i + - /^master.*$/i + - tags + +develop_build_debug_for_centos8: + stage: build + extends: .build_by_travis_for_centos8 + variables: + BUILD_TYPE: Debug + PACKAGE: 1 + UPLOAD_RPM: 1 + ASAN_OPTION: ADDRESS + TESTING_VERSION_BUILD: 1 + PULP3_REPO_NAME: $RPM_REPO_PREFIX-testing-x86_64.el8 + PULP3_DIST_NAME: $RPM_REPO_PREFIX-testing-x86_64.el8 + artifacts: + name: "quic_decoder-$CI_COMMIT_REF_NAME-debug" + paths: + - build/*.rpm + only: + - /^develop.*$/i + - /^master.*$/i + +develop_build_release_for_centos8: + stage: build + extends: .build_by_travis_for_centos8 + variables: + BUILD_TYPE: RelWithDebInfo + PACKAGE: 1 + UPLOAD_RPM: 1 + TESTING_VERSION_BUILD: 1 + PULP3_REPO_NAME: $RPM_REPO_PREFIX-testing-x86_64.el8 + PULP3_DIST_NAME: $RPM_REPO_PREFIX-testing-x86_64.el8 + artifacts: + name: "quic_decoder-$CI_COMMIT_REF_NAME-release" + paths: + - build/*.rpm + only: + - /^develop.*$/i + - /^master.*$/i + +release_build_debug_for_centos8: + stage: package + variables: + BUILD_TYPE: Debug + PACKAGE: 1 + UPLOAD_RPM: 1 + ASAN_OPTION: ADDRESS + PULP3_REPO_NAME: $RPM_REPO_PREFIX-stable-x86_64.el8 + PULP3_DIST_NAME: $RPM_REPO_PREFIX-stable-x86_64.el8 + extends: .build_by_travis_for_centos8 + artifacts: + name: "quic_decoder-$CI_COMMIT_REF_NAME-debug" + paths: + - build/*.rpm + only: + - tags + +release_build_release_for_centos8: + stage: package + variables: + BUILD_TYPE: RelWithDebInfo + PACKAGE: 1 + UPLOAD_RPM: 1 + UPLOAD_SYMBOL_FILES: 1 + SYMBOL_TARGET: quic_decoder + PULP3_REPO_NAME: $RPM_REPO_PREFIX-stable-x86_64.el8 + PULP3_DIST_NAME: $RPM_REPO_PREFIX-stable-x86_64.el8 + extends: .build_by_travis_for_centos8 + artifacts: + name: "quic_decoder-$CI_COMMIT_REF_NAME-release" + paths: + - build/*.rpm + only: + - tags + +############################################################################### +# test +############################################################################### + +.install_rpm_package: &install_rpm_package + - rpm -e sapp || true + - rpm -e sapp-devel || true + - rpm -e stellar-on-sapp || true + - rpm -e stellar-on-sapp-devel || true + - rpm -ivh /tmp/sapp.x86_64.rpm --prefix=${INSTALL_PREFIX}/sapp --force --nodeps + - rpm -ivh /tmp/sapp-devel.x86_64.rpm --prefix=${INSTALL_PREFIX}/sapp --force --nodeps + - rpm -ivh /tmp/stellar-on-sapp.x86_64.rpm --prefix=${INSTALL_PREFIX} --force --nodeps + - rpm -qa | grep sapp + - rpm -qa | grep stellar-on-sapp + - ls -l /opt/MESA/lib && echo "/opt/MESA/lib" >> /etc/ld.so.conf + + +history_version_test: + stage: test + extends: .build_by_travis_for_centos8 + script: + - yum makecache + - ./ci/travis.sh + - cp -f ./support/stellar-on-sapp*.rpm /tmp/stellar-on-sapp.x86_64.rpm + - cp -f ./support/sapp-devel*.rpm /tmp/sapp-devel.x86_64.rpm + - cp -f ./support/sapp-4*.rpm /tmp/sapp.x86_64.rpm + - *install_rpm_package + - cd build + - ctest3 --verbose + +latest_version_test: + stage: test + extends: .build_by_travis_for_centos8 + script: + - yum makecache + - ./ci/travis.sh + - rm -f stellar-on-sapp*.rpm sapp*.rpm + - yumdownloader stellar-on-sapp sapp-devel sapp + - cp -f stellar-on-sapp*.rpm /tmp/stellar-on-sapp.x86_64.rpm + - cp -f sapp-devel*.rpm /tmp/sapp-devel.x86_64.rpm + - cp -f sapp-4*.rpm /tmp/sapp.x86_64.rpm + - *install_rpm_package + - cd build + - ctest3 --verbose
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e6ee32f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required (VERSION 2.8...3.10) + +set(lib_name quic_decoder) + +project (${lib_name}) + +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) +include(Version) + +set(CMAKE_MACOSX_RPATH 0) +set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -Wall) + +#for ASAN +set(ASAN_OPTION "OFF" CACHE STRING " set asan type chosen by the user, using OFF as default") +set_property(CACHE ASAN_OPTION PROPERTY STRINGS OFF ADDRESS THREAD) +message(STATUS "ASAN_OPTION='${ASAN_OPTION}'") + +if(ASAN_OPTION MATCHES "ADDRESS") + set(CMAKE_C_FLAGS "${CMAKADDRESS} -g -DCMAKE_BUILD_TYPE=Debug -fsanitize=address -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -DCMAKE_BUILD_TYPE=Debug -fsanitize=address -fno-omit-frame-pointer") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan") +elseif(ASAN_OPTION MATCHES "THREAD") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -DCMAKE_BUILD_TYPE=Debug -fsanitize=thread -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -DCMAKE_BUILD_TYPE=Debug -fsanitize=thread -fno-omit-frame-pointer") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan") +endif() +# end of for ASAN + +set(CMAKE_INSTALL_PREFIX /opt/tsg) + +include_directories(include) +include_directories(/opt/MESA/include/MESA/) + +add_subdirectory(support) +add_subdirectory(src) + +enable_testing() +add_subdirectory(test) + +set(CPACK_RPM_USER_FILELIST "%config(noreplace) ${CMAKE_INSTALL_PREFIX}/sapp/conf/quic_decoder/quic.conf" + "%config(noreplace) ${CMAKE_INSTALL_PREFIX}/sapp/conf/quic_decoder/main.conf") + +install(FILES bin/quic.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/sapp/conf/quic_decoder COMPONENT PROFILE) +install(FILES bin/main.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/sapp/conf/quic_decoder COMPONENT PROFILE) +install(FILES include/quic_decoder.h DESTINATION ${CMAKE_INSTALL_PREFIX}/framework/include/quic_decoder COMPONENT HEADER) + +include(Package) diff --git a/README.md b/README.md new file mode 100644 index 0000000..b55e799 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# quic_decoder + + + +## Getting started + +To make it easy for you to get started with GitLab, here's a list of recommended next steps. + +Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! + +## Add your files + +- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files +- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: + +``` +cd existing_repo +git remote add origin https://git.mesalab.cn/stellar/quic_decoder.git +git branch -M main +git push -uf origin main +``` + +## Integrate with your tools + +- [ ] [Set up project integrations](https://git.mesalab.cn/stellar/quic_decoder/-/settings/integrations) + +## Collaborate with your team + +- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) +- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) +- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) +- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) +- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) + +## Test and Deploy + +Use the built-in continuous integration in GitLab. + +- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) +- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) +- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) +- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) +- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) + +*** + +# Editing this README + +When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. + +## Suggestions for a good README + +Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. + +## Name +Choose a self-explaining name for your project. + +## Description +Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. + +## Badges +On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. + +## Visuals +Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. + +## Installation +Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. + +## Usage +Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. + +## Support +Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. + +## Roadmap +If you have ideas for releases in the future, it is a good idea to list them in the README. + +## Contributing +State if you are open to contributions and what your requirements are for accepting them. + +For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. + +You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. + +## Authors and acknowledgment +Show your appreciation to those who have contributed to the project. + +## License +For open source projects, say how it is licensed. + +## Project status +If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/autorevision.sh b/autorevision.sh new file mode 100644 index 0000000..3baa179 --- /dev/null +++ b/autorevision.sh @@ -0,0 +1,1268 @@ +#!/bin/sh + +# Copyright (c) 2012 - 2016 dak180 and contributors. See +# https://opensource.org/licenses/mit-license.php or the included +# COPYING.md for licence terms. +# +# autorevision - extracts metadata about the head version from your +# repository. + +# Usage message. +arUsage() { + cat > "/dev/stderr" << EOF +usage: autorevision {-t output-type | -s symbol} [-o cache-file [-f] ] [-V] + Options include: + -t output-type = specify output type + -s symbol = specify symbol output + -o cache-file = specify cache file location + -f = force the use of cache data + -U = check for untracked files in svn + -V = emit version and exit + -? = help message + +The following are valid output types: + clojure = clojure file + c = C/C++ file + h = Header for use with c/c++ + hpp = Alternate C++ header strings with namespace + ini = INI file + java = Java file + javaprop = Java properties file + js = javascript file + json = JSON file + lua = Lua file + m4 = m4 file + matlab = matlab file + octave = octave file + php = PHP file + pl = Perl file + py = Python file + rpm = rpm file + scheme = scheme file + sh = Bash sytax + swift = Swift file + tex = (La)TeX file + xcode = Header useful for populating info.plist files + cmake = CMake file + + +The following are valid symbols: + VCS_TYPE + VCS_BASENAME + VCS_UUID + VCS_NUM + VCS_DATE + VCS_BRANCH + VCS_TAG + VCS_TICK + VCS_EXTRA + VCS_FULL_HASH + VCS_SHORT_HASH + VCS_WC_MODIFIED + VCS_ACTION_STAMP +EOF + exit 1 +} + +# Config +ARVERSION="&&ARVERSION&&" +TARGETFILE="/dev/stdout" +while getopts ":t:o:s:VfU" OPTION; do + case "${OPTION}" in + t) + AFILETYPE="${OPTARG}" + ;; + o) + CACHEFILE="${OPTARG}" + ;; + f) + CACHEFORCE="1" + ;; + s) + VAROUT="${OPTARG}" + ;; + U) + UNTRACKEDFILES="1" + ;; + V) + echo "autorevision ${ARVERSION}" + exit 0 + ;; + ?) + # If an unknown flag is used (or -?): + arUsage + ;; + esac +done + +if [ ! -z "${VAROUT}" ] && [ ! -z "${AFILETYPE}" ]; then + # If both -s and -t are specified: + echo "error: Improper argument combination." 1>&2 + exit 1 +elif [ -z "${VAROUT}" ] && [ -z "${AFILETYPE}" ]; then + # If neither -s or -t are specified: + arUsage +elif [ -z "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then + # If -f is specified without -o: + arUsage +elif [ ! -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then + # If we are forced to use the cache but it does not exist. + echo "error: Cache forced but no cache found." 1>&2 + exit 1 +fi + +# Make sure that the path we are given is one we can source +# (dash, we are looking at you). +if [ ! -z "${CACHEFILE}" ] && ! echo "${CACHEFILE}" | grep -q '^\.*/'; then + CACHEFILE="./${CACHEFILE}" +fi + +GENERATED_HEADER="Generated by autorevision - do not hand-hack!" + +# Functions to extract data from different repo types. +# For git repos +# shellcheck disable=SC2039,SC2164,SC2155 +gitRepo() { + local oldPath="${PWD}" + + cd "$(git rev-parse --show-toplevel)" + + VCS_TYPE="git" + + VCS_BASENAME="$(basename "${PWD}")" + + VCS_UUID="$(git rev-list --max-parents=0 --date-order --reverse HEAD 2>/dev/null | sed -n 1p)" + if [ -z "${VCS_UUID}" ]; then + VCS_UUID="$(git rev-list --topo-order HEAD | tail -n 1)" + fi + + # Is the working copy clean? + test -z "$(git status --untracked-files=normal --porcelain)" + VCS_WC_MODIFIED="${?}" + + # Enumeration of changesets + VCS_NUM="$(git rev-list --count HEAD 2>/dev/null)" + if [ -z "${VCS_NUM}" ]; then + echo "warning: Counting the number of revisions may be slower due to an outdated git version less than 1.7.2.3. If something breaks, please update it." 1>&2 + VCS_NUM="$(git rev-list HEAD | wc -l)" + fi + + # This may be a git-svn remote. If so, report the Subversion revision. + if [ -z "$(git config svn-remote.svn.url 2>/dev/null)" ]; then + # The full revision hash + VCS_FULL_HASH="$(git rev-parse HEAD)" + + # The short hash + VCS_SHORT_HASH="$(echo "${VCS_FULL_HASH}" | cut -b 1-7)" + else + # The git-svn revision number + VCS_FULL_HASH="$(git svn find-rev HEAD)" + VCS_SHORT_HASH="${VCS_FULL_HASH}" + fi + + # Current branch + VCS_BRANCH="$(git rev-parse --symbolic-full-name --verify "$(git name-rev --name-only --no-undefined HEAD 2>/dev/null)" 2>/dev/null | sed -e 's:refs/heads/::' | sed -e 's:refs/::')" + + # Cache the description + local DESCRIPTION="$(git describe --long --tags 2>/dev/null)" + + # Current or last tag ancestor (empty if no tags) + VCS_TAG="$(echo "${DESCRIPTION}" | sed -e "s:-g${VCS_SHORT_HASH}\$::" -e 's:-[0-9]*$::')" + + # Distance to last tag or an alias of VCS_NUM if there is no tag + if [ ! -z "${DESCRIPTION}" ]; then + VCS_TICK="$(echo "${DESCRIPTION}" | sed -e "s:${VCS_TAG}-::" -e "s:-g${VCS_SHORT_HASH}::")" + else + VCS_TICK="${VCS_NUM}" + fi + + # Date of the current commit + VCS_DATE="$(TZ=UTC git show -s --date=iso-strict-local --pretty=format:%ad | sed -e 's|+00:00|Z|')" + if [ -z "${VCS_DATE}" ]; then + echo "warning: Action stamps require git version 2.7+." 1>&2 + VCS_DATE="$(git log -1 --pretty=format:%ci | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')" + local ASdis="1" + fi + + # Action Stamp + if [ -z "${ASdis}" ]; then + VCS_ACTION_STAMP="${VCS_DATE}!$(git show -s --pretty=format:%cE)" + else + VCS_ACTION_STAMP="" + fi + + cd "${oldPath}" +} + +# For hg repos +# shellcheck disable=SC2039,SC2164 +hgRepo() { + local oldPath="${PWD}" + + cd "$(hg root)" + + VCS_TYPE="hg" + + VCS_BASENAME="$(basename "${PWD}")" + + VCS_UUID="$(hg log -r "0" -l 1 --template '{node}\n')" + + # Is the working copy clean? + test -z "$(hg status -duram)" + VCS_WC_MODIFIED="${?}" + + # Enumeration of changesets + VCS_NUM="$(hg id -n | tr -d '+')" + + # The full revision hash + VCS_FULL_HASH="$(hg log -r "${VCS_NUM}" -l 1 --template '{node}\n')" + + # The short hash + VCS_SHORT_HASH="$(hg id -i | tr -d '+')" + + # Current bookmark (bookmarks are roughly equivalent to git's branches) + # or branch if no bookmark + VCS_BRANCH="$(hg id -B | cut -d ' ' -f 1)" + # Fall back to the branch if there are no bookmarks + if [ -z "${VCS_BRANCH}" ]; then + VCS_BRANCH="$(hg id -b)" + fi + + # Current or last tag ancestor (excluding auto tags, empty if no tags) + VCS_TAG="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttag}\n' 2>/dev/null | sed -e 's:qtip::' -e 's:tip::' -e 's:qbase::' -e 's:qparent::' -e "s:$(hg --config 'extensions.color=' --config 'extensions.mq=' --color never qtop 2>/dev/null)::" | cut -d ' ' -f 1)" + + # Distance to last tag or an alias of VCS_NUM if there is no tag + if [ ! -z "${VCS_TAG}" ]; then + VCS_TICK="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttagdistance}\n' 2>/dev/null)" + else + VCS_TICK="${VCS_NUM}" + fi + + # Date of the current commit + VCS_DATE="$(hg log -r "${VCS_NUM}" -l 1 --template '{date|isodatesec}\n' 2>/dev/null | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')" + + # Action Stamp + VCS_ACTION_STAMP="$(TZ=UTC hg log -r "${VCS_NUM}" -l 1 --template '{date|localdate|rfc3339date}\n' 2>/dev/null | sed -e 's|+00:00|Z|')!$(hg log -r "${VCS_NUM}" -l 1 --template '{author|email}\n' 2>/dev/null)" + + cd "${oldPath}" +} + +# For bzr repos +# shellcheck disable=SC2039,SC2164 +bzrRepo() { + local oldPath="${PWD}" + + cd "$(bzr root)" + + VCS_TYPE="bzr" + + VCS_BASENAME="$(basename "${PWD}")" + + # Currently unimplemented because more investigation is needed. + VCS_UUID="" + + # Is the working copy clean? + bzr version-info --custom --template='{clean}\n' | grep -q '1' + VCS_WC_MODIFIED="${?}" + + # Enumeration of changesets + VCS_NUM="$(bzr revno)" + + # The full revision hash + VCS_FULL_HASH="$(bzr version-info --custom --template='{revision_id}\n')" + + # The short hash + VCS_SHORT_HASH="${VCS_NUM}" + + # Nick of the current branch + VCS_BRANCH="$(bzr nick)" + + # Current or last tag ancestor (excluding auto tags, empty if no tags) + VCS_TAG="$(bzr tags --sort=time | sed '/?$/d' | tail -n1 | cut -d ' ' -f1)" + + # Distance to last tag or an alias of VCS_NUM if there is no tag + if [ ! -z "${VCS_TAG}" ]; then + VCS_TICK="$(bzr log --line -r "tag:${VCS_TAG}.." | tail -n +2 | wc -l | sed -e 's:^ *::')" + else + VCS_TICK="${VCS_NUM}" + fi + + # Date of the current commit + VCS_DATE="$(bzr version-info --custom --template='{date}\n' | sed -e 's: :T:' -e 's: ::')" + + # Action Stamp + # Currently unimplemented because more investigation is needed. + VCS_ACTION_STAMP="" + + cd "${oldPath}" +} + +# For svn repos +# shellcheck disable=SC2039,SC2164,SC2155 +svnRepo() { + local oldPath="${PWD}" + + VCS_TYPE="svn" + + case "${PWD}" in + /*trunk*|/*branches*|/*tags*) + local fn="${PWD}" + while [ "$(basename "${fn}")" != 'trunk' ] && [ "$(basename "${fn}")" != 'branches' ] && [ "$(basename "${fn}")" != 'tags' ] && [ "$(basename "${fn}")" != '/' ]; do + local fn="$(dirname "${fn}")" + done + local fn="$(dirname "${fn}")" + if [ "${fn}" = '/' ]; then + VCS_BASENAME="$(basename "${PWD}")" + else + VCS_BASENAME="$(basename "${fn}")" + fi + ;; + *) VCS_BASENAME="$(basename "${PWD}")" ;; + esac + + VCS_UUID="$(svn info --xml | sed -n -e 's:<uuid>::' -e 's:</uuid>::p')" + + # Cache svnversion output + local SVNVERSION="$(svnversion)" + + # Is the working copy clean? + echo "${SVNVERSION}" | grep -q "M" + case "${?}" in + 0) + VCS_WC_MODIFIED="1" + ;; + 1) + if [ ! -z "${UNTRACKEDFILES}" ]; then + # `svnversion` does not detect untracked files and `svn status` is really slow, so only run it if we really have to. + if [ -z "$(svn status)" ]; then + VCS_WC_MODIFIED="0" + else + VCS_WC_MODIFIED="1" + fi + else + VCS_WC_MODIFIED="0" + fi + ;; + esac + + # Enumeration of changesets + VCS_NUM="$(echo "${SVNVERSION}" | cut -d : -f 1 | sed -e 's:M::' -e 's:S::' -e 's:P::')" + + # The full revision hash + VCS_FULL_HASH="${SVNVERSION}" + + # The short hash + VCS_SHORT_HASH="${VCS_NUM}" + + # Current branch + case "${PWD}" in + /*trunk*|/*branches*|/*tags*) + local lastbase="" + local fn="${PWD}" + while : + do + base="$(basename "${fn}")" + if [ "${base}" = 'trunk' ]; then + VCS_BRANCH='trunk' + break + elif [ "${base}" = 'branches' ] || [ "${base}" = 'tags' ]; then + VCS_BRANCH="${lastbase}" + break + elif [ "${base}" = '/' ]; then + VCS_BRANCH="" + break + fi + local lastbase="${base}" + local fn="$(dirname "${fn}")" + done + ;; + *) VCS_BRANCH="" ;; + esac + + # Current or last tag ancestor (empty if no tags). But "current + # tag" can't be extracted reliably because Subversion doesn't + # have tags the way other VCSes do. + VCS_TAG="" + VCS_TICK="" + + # Date of the current commit + VCS_DATE="$(svn info --xml | sed -n -e 's:<date>::' -e 's:</date>::p')" + + # Action Stamp + VCS_ACTION_STAMP="${VCS_DATE}!$(svn log --xml -l 1 -r "${VCS_SHORT_HASH}" | sed -n -e 's:<author>::' -e 's:</author>::p')" + + cd "${oldPath}" +} + + +# Functions to output data in different formats. +# For bash output +shOutput() { + cat > "${TARGETFILE}" << EOF +# ${GENERATED_HEADER} + +VCS_TYPE="${VCS_TYPE}" +VCS_BASENAME="${VCS_BASENAME}" +VCS_UUID="${VCS_UUID}" +VCS_NUM="${VCS_NUM}" +VCS_DATE="${VCS_DATE}" +VCS_BRANCH="${VCS_BRANCH}" +VCS_TAG="${VCS_TAG}" +VCS_TICK="${VCS_TICK}" +VCS_EXTRA="${VCS_EXTRA}" + +VCS_ACTION_STAMP="${VCS_ACTION_STAMP}" +VCS_FULL_HASH="${VCS_FULL_HASH}" +VCS_SHORT_HASH="${VCS_SHORT_HASH}" + +VCS_WC_MODIFIED="${VCS_WC_MODIFIED}" + +# end +EOF +} + +# For source C output +cOutput() { + cat > "${TARGETFILE}" << EOF +/* ${GENERATED_HEADER} */ + +const char *VCS_TYPE = "${VCS_TYPE}"; +const char *VCS_BASENAME = "${VCS_BASENAME}"; +const char *VCS_UUID = "${VCS_UUID}"; +const int VCS_NUM = ${VCS_NUM}; +const char *VCS_DATE = "${VCS_DATE}"; +const char *VCS_BRANCH = "${VCS_BRANCH}"; +const char *VCS_TAG = "${VCS_TAG}"; +const int VCS_TICK = ${VCS_TICK}; +const char *VCS_EXTRA = "${VCS_EXTRA}"; + +const char *VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"; +const char *VCS_FULL_HASH = "${VCS_FULL_HASH}"; +const char *VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; + +const int VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +/* end */ +EOF +} + +# For header output +hOutput() { + cat > "${TARGETFILE}" << EOF +/* ${GENERATED_HEADER} */ +#ifndef AUTOREVISION_H +#define AUTOREVISION_H + +#define VCS_TYPE "${VCS_TYPE}" +#define VCS_BASENAME "${VCS_BASENAME}" +#define VCS_UUID "${VCS_UUID}" +#define VCS_NUM ${VCS_NUM} +#define VCS_DATE "${VCS_DATE}" +#define VCS_BRANCH "${VCS_BRANCH}" +#define VCS_TAG "${VCS_TAG}" +#define VCS_TICK ${VCS_TICK} +#define VCS_EXTRA "${VCS_EXTRA}" + +#define VCS_ACTION_STAMP "${VCS_ACTION_STAMP}" +#define VCS_FULL_HASH "${VCS_FULL_HASH}" +#define VCS_SHORT_HASH "${VCS_SHORT_HASH}" + +#define VCS_WC_MODIFIED ${VCS_WC_MODIFIED} + +#endif + +/* end */ +EOF +} + +# A header output for use with xcode to populate info.plist strings +xcodeOutput() { + cat > "${TARGETFILE}" << EOF +/* ${GENERATED_HEADER} */ +#ifndef AUTOREVISION_H +#define AUTOREVISION_H + +#define VCS_TYPE ${VCS_TYPE} +#define VCS_BASENAME ${VCS_BASENAME} +#define VCS_UUID ${VCS_UUID} +#define VCS_NUM ${VCS_NUM} +#define VCS_DATE ${VCS_DATE} +#define VCS_BRANCH ${VCS_BRANCH} +#define VCS_TAG ${VCS_TAG} +#define VCS_TICK ${VCS_TICK} +#define VCS_EXTRA ${VCS_EXTRA} + +#define VCS_ACTION_STAMP ${VCS_ACTION_STAMP} +#define VCS_FULL_HASH ${VCS_FULL_HASH} +#define VCS_SHORT_HASH ${VCS_SHORT_HASH} + +#define VCS_WC_MODIFIED ${VCS_WC_MODIFIED} + +#endif + +/* end */ +EOF +} + +# For Swift output +swiftOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + # For values that may not exist depending on the type of repo we + # have read from, set them to `nil` when they are empty. + if [ -z "${VCS_UUID}" ]; then + VCS_UUID="nil" + else + VCS_UUID="\"${VCS_UUID}\"" + fi + if [ -z "${VCS_TAG}" ]; then + VCS_TAG="nil" + else + VCS_TAG="\"${VCS_TAG}\"" + fi + : "${VCS_TICK:="nil"}" + if [ -z "${VCS_EXTRA}" ]; then + VCS_EXTRA="nil" + else + VCS_EXTRA="\"${VCS_EXTRA}\"" + fi + if [ -z "${VCS_ACTION_STAMP}" ]; then + VCS_ACTION_STAMP="nil" + else + VCS_ACTION_STAMP="\"${VCS_ACTION_STAMP}\"" + fi + cat > "${TARGETFILE}" << EOF +/* ${GENERATED_HEADER} */ + +let VCS_TYPE = "${VCS_TYPE}" +let VCS_BASENAME = "${VCS_BASENAME}" +let VCS_UUID: String? = ${VCS_UUID} +let VCS_NUM: Int = ${VCS_NUM} +let VCS_DATE = "${VCS_DATE}" +let VCS_BRANCH: String = "${VCS_BRANCH}" +let VCS_TAG: String? = ${VCS_TAG} +let VCS_TICK: Int? = ${VCS_TICK} +let VCS_EXTRA: String? = ${VCS_EXTRA} + +let VCS_ACTION_STAMP: String? = ${VCS_ACTION_STAMP} +let VCS_FULL_HASH: String = "${VCS_FULL_HASH}" +let VCS_SHORT_HASH: String = "${VCS_SHORT_HASH}" + +let VCS_WC_MODIFIED: Bool = ${VCS_WC_MODIFIED} + +/* end */ +EOF +} + +# For Python output +pyOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="False" ;; + 1) VCS_WC_MODIFIED="True" ;; + esac + cat > "${TARGETFILE}" << EOF +# ${GENERATED_HEADER} + +VCS_TYPE = "${VCS_TYPE}" +VCS_BASENAME = "${VCS_BASENAME}" +VCS_UUID = "${VCS_UUID}" +VCS_NUM = ${VCS_NUM} +VCS_DATE = "${VCS_DATE}" +VCS_BRANCH = "${VCS_BRANCH}" +VCS_TAG = "${VCS_TAG}" +VCS_TICK = ${VCS_TICK} +VCS_EXTRA = "${VCS_EXTRA}" + +VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}" +VCS_FULL_HASH = "${VCS_FULL_HASH}" +VCS_SHORT_HASH = "${VCS_SHORT_HASH}" + +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED} + +# end +EOF +} + +# For Perl output +plOutput() { + cat << EOF +# ${GENERATED_HEADER} + +\$VCS_TYPE = '${VCS_TYPE}'; +\$VCS_BASENAME = '${VCS_BASENAME}'; +\$VCS_UUID = '${VCS_UUID}'; +\$VCS_NUM = ${VCS_NUM}; +\$VCS_DATE = '${VCS_DATE}'; +\$VCS_BRANCH = '${VCS_BRANCH}'; +\$VCS_TAG = '${VCS_TAG}'; +\$VCS_TICK = ${VCS_TICK}; +\$VCS_EXTRA = '${VCS_EXTRA}'; + +\$VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}'; +\$VCS_FULL_HASH = '${VCS_FULL_HASH}'; +\$VCS_SHORT_HASH = '${VCS_SHORT_HASH}'; + +\$VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +# end +1; +EOF +} + +# For lua output +luaOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + cat > "${TARGETFILE}" << EOF +-- ${GENERATED_HEADER} + +VCS_TYPE = "${VCS_TYPE}" +VCS_BASENAME = "${VCS_BASENAME}" +VCS_UUID = "${VCS_UUID}" +VCS_NUM = ${VCS_NUM} +VCS_DATE = "${VCS_DATE}" +VCS_BRANCH = "${VCS_BRANCH}" +VCS_TAG = "${VCS_TAG}" +VCS_TICK = ${VCS_TICK} +VCS_EXTRA = "${VCS_EXTRA}" + +VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}" +VCS_FULL_HASH = "${VCS_FULL_HASH}" +VCS_SHORT_HASH = "${VCS_SHORT_HASH}" + +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED} + +-- end +EOF +} + +# For php output +phpOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + cat > "${TARGETFILE}" << EOF +<?php +# ${GENERATED_HEADER} + +return array( + "VCS_TYPE" => "${VCS_TYPE}", + "VCS_BASENAME" => "${VCS_BASENAME}", + "VCS_UUID" => "${VCS_UUID}", + "VCS_NUM" => ${VCS_NUM}, + "VCS_DATE" => "${VCS_DATE}", + "VCS_BRANCH" => "${VCS_BRANCH}", + "VCS_TAG" => "${VCS_TAG}", + "VCS_TICK" => ${VCS_TICK}, + "VCS_EXTRA" => "${VCS_EXTRA}", + "VCS_ACTION_STAMP" => "${VCS_ACTION_STAMP}", + "VCS_FULL_HASH" => "${VCS_FULL_HASH}", + "VCS_SHORT_HASH" => "${VCS_SHORT_HASH}", + "VCS_WC_MODIFIED" => ${VCS_WC_MODIFIED} +); + +# end +?> +EOF +} + +# For ini output +iniOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + cat > "${TARGETFILE}" << EOF +; ${GENERATED_HEADER} +[VCS] +VCS_TYPE = "${VCS_TYPE}" +VCS_BASENAME = "${VCS_BASENAME}" +VCS_UUID = "${VCS_UUID}" +VCS_NUM = ${VCS_NUM} +VCS_DATE = "${VCS_DATE}" +VCS_BRANCH = "${VCS_BRANCH}" +VCS_TAG = "${VCS_TAG}" +VCS_TICK = ${VCS_TICK} +VCS_EXTRA = "${VCS_EXTRA}" +VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}" +VCS_FULL_HASH = "${VCS_FULL_HASH}" +VCS_SHORT_HASH = "${VCS_SHORT_HASH}" +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED} +; end +EOF +} + +# For javascript output +jsOutput() { + case "${VCS_WC_MODIFIED}" in + 1) VCS_WC_MODIFIED="true" ;; + 0) VCS_WC_MODIFIED="false" ;; + esac + cat > "${TARGETFILE}" << EOF +/** ${GENERATED_HEADER} */ + +var autorevision = { + VCS_TYPE: "${VCS_TYPE}", + VCS_BASENAME: "${VCS_BASENAME}", + VCS_UUID: "${VCS_UUID}", + VCS_NUM: ${VCS_NUM}, + VCS_DATE: "${VCS_DATE}", + VCS_BRANCH: "${VCS_BRANCH}", + VCS_TAG: "${VCS_TAG}", + VCS_TICK: ${VCS_TICK}, + VCS_EXTRA: "${VCS_EXTRA}", + + VCS_ACTION_STAMP: "${VCS_ACTION_STAMP}", + VCS_FULL_HASH: "${VCS_FULL_HASH}", + VCS_SHORT_HASH: "${VCS_SHORT_HASH}", + + VCS_WC_MODIFIED: ${VCS_WC_MODIFIED} +}; + +/** Node.js compatibility */ +if (typeof module !== 'undefined') { + module.exports = autorevision; +} + +/** end */ +EOF +} + +# For JSON output +jsonOutput() { + case "${VCS_WC_MODIFIED}" in + 1) VCS_WC_MODIFIED="true" ;; + 0) VCS_WC_MODIFIED="false" ;; + esac + cat > "${TARGETFILE}" << EOF +{ + "_comment": "${GENERATED_HEADER}", + "VCS_TYPE": "${VCS_TYPE}", + "VCS_BASENAME": "${VCS_BASENAME}", + "VCS_UUID": "${VCS_UUID}", + "VCS_NUM": ${VCS_NUM}, + "VCS_DATE": "${VCS_DATE}", + "VCS_BRANCH":"${VCS_BRANCH}", + "VCS_TAG": "${VCS_TAG}", + "VCS_TICK": ${VCS_TICK}, + "VCS_EXTRA": "${VCS_EXTRA}", + + "VCS_ACTION_STAMP": "${VCS_ACTION_STAMP}", + "VCS_FULL_HASH": "${VCS_FULL_HASH}", + "VCS_SHORT_HASH": "${VCS_SHORT_HASH}", + + "VCS_WC_MODIFIED": ${VCS_WC_MODIFIED} +} +EOF +} + +# For Java output +javaOutput() { + case "${VCS_WC_MODIFIED}" in + 1) VCS_WC_MODIFIED="true" ;; + 0) VCS_WC_MODIFIED="false" ;; + esac + cat > "${TARGETFILE}" << EOF +/* ${GENERATED_HEADER} */ + +public class autorevision { + public static final String VCS_TYPE = "${VCS_TYPE}"; + public static final String VCS_BASENAME = "${VCS_BASENAME}"; + public static final String VCS_UUID = "${VCS_UUID}"; + public static final long VCS_NUM = ${VCS_NUM}; + public static final String VCS_DATE = "${VCS_DATE}"; + public static final String VCS_BRANCH = "${VCS_BRANCH}"; + public static final String VCS_TAG = "${VCS_TAG}"; + public static final long VCS_TICK = ${VCS_TICK}; + public static final String VCS_EXTRA = "${VCS_EXTRA}"; + + public static final String VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"; + public static final String VCS_FULL_HASH = "${VCS_FULL_HASH}"; + public static final String VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; + + public static final boolean VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; +} +EOF +} + +# For Java properties output +javapropOutput() { + case "${VCS_WC_MODIFIED}" in + 1) VCS_WC_MODIFIED="true" ;; + 0) VCS_WC_MODIFIED="false" ;; + esac + cat > "${TARGETFILE}" << EOF +# ${GENERATED_HEADER} + +VCS_TYPE=${VCS_TYPE} +VCS_BASENAME=${VCS_BASENAME} +VCS_UUID=${VCS_UUID} +VCS_NUM=${VCS_NUM} +VCS_DATE=${VCS_DATE} +VCS_BRANCH=${VCS_BRANCH} +VCS_TAG=${VCS_TAG} +VCS_TICK=${VCS_TICK} +VCS_EXTRA=${VCS_EXTRA} + +VCS_ACTION_STAMP=${VCS_ACTION_STAMP} +VCS_FULL_HASH=${VCS_FULL_HASH} +VCS_SHORT_HASH=${VCS_SHORT_HASH} + +VCS_WC_MODIFIED=${VCS_WC_MODIFIED} +EOF +} + +# For m4 output +m4Output() { + cat > "${TARGETFILE}" << EOF +dnl ${GENERATED_HEADER} +define(\`VCS_TYPE', \`${VCS_TYPE}')dnl +define(\`VCS_BASENAME', \`${VCS_BASENAME}')dnl +define(\`VCS_UUID', \`${VCS_UUID}')dnl +define(\`VCS_NUM', \`${VCS_NUM}')dnl +define(\`VCS_DATE', \`${VCS_DATE}')dnl +define(\`VCS_BRANCH', \`${VCS_BRANCH}')dnl +define(\`VCS_TAG', \`${VCS_TAG}')dnl +define(\`VCS_TICK', \`${VCS_TICK}')dnl +define(\`VCS_EXTRA', \`${VCS_EXTRA}')dnl +define(\`VCS_ACTIONSTAMP', \`${VCS_ACTION_STAMP}')dnl +define(\`VCS_FULLHASH', \`${VCS_FULL_HASH}')dnl +define(\`VCS_SHORTHASH', \`${VCS_SHORT_HASH}')dnl +define(\`VCS_WC_MODIFIED', \`${VCS_WC_MODIFIED}')dnl +EOF +} + +# For (La)TeX output +texOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + cat > "${TARGETFILE}" << EOF +% ${GENERATED_HEADER} +\def \vcsType {${VCS_TYPE}} +\def \vcsBasename {${VCS_BASENAME}} +\def \vcsUUID {${VCS_UUID}} +\def \vcsNum {${VCS_NUM}} +\def \vcsDate {${VCS_DATE}} +\def \vcsBranch {${VCS_BRANCH}} +\def \vcsTag {${VCS_TAG}} +\def \vcsTick {${VCS_TICK}} +\def \vcsExtra {${VCS_EXTRA}} +\def \vcsACTIONSTAMP {${VCS_ACTION_STAMP}} +\def \vcsFullHash {${VCS_FULL_HASH}} +\def \vcsShortHash {${VCS_SHORT_HASH}} +\def \vcsWCModified {${VCS_WC_MODIFIED}} +\endinput +EOF +} + +# For scheme output +schemeOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="#f" ;; + 1) VCS_WC_MODIFIED="#t" ;; + esac + cat > "${TARGETFILE}" << EOF +;; ${GENERATED_HEADER} +(define VCS_TYPE "${VCS_TYPE}") +(define VCS_BASENAME "${VCS_BASENAME}") +(define VCS_UUID "${VCS_UUID}") +(define VCS_NUM ${VCS_NUM}) +(define VCS_DATE "${VCS_DATE}") +(define VCS_BRANCH "${VCS_BRANCH}") +(define VCS_TAG "${VCS_TAG}") +(define VCS_TICK ${VCS_TICK}) +(define VCS_EXTRA "${VCS_EXTRA}") + +(define VCS_ACTION_STAMP "${VCS_ACTION_STAMP}") +(define VCS_FULL_HASH "${VCS_FULL_HASH}") +(define VCS_SHORT_HASH "${VCS_SHORT_HASH}") + +(define VCS_WC_MODIFIED ${VCS_WC_MODIFIED}) +;; end +EOF +} + +# For clojure output +clojureOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + cat > "${TARGETFILE}" << EOF +;; ${GENERATED_HEADER} +(def VCS_TYPE "${VCS_TYPE}") +(def VCS_BASENAME "${VCS_BASENAME}") +(def VCS_UUID "${VCS_UUID}") +(def VCS_NUM ${VCS_NUM}) +(def VCS_DATE "${VCS_DATE}") +(def VCS_BRANCH "${VCS_BRANCH}") +(def VCS_TAG "${VCS_TAG}") +(def VCS_TICK ${VCS_TICK}) +(def VCS_EXTRA "${VCS_EXTRA}") + +(def VCS_ACTION_STAMP "${VCS_ACTION_STAMP}") +(def VCS_FULL_HASH "${VCS_FULL_HASH}") +(def VCS_SHORT_HASH "${VCS_SHORT_HASH}") + +(def VCS_WC_MODIFIED ${VCS_WC_MODIFIED}) +;; end +EOF +} + +# For rpm spec file output +rpmOutput() { + cat > "${TARGETFILE}" << EOF +# ${GENERATED_HEADER} +$([ "${VCS_TYPE}" ] && echo "%define vcs_type ${VCS_TYPE}") +$([ "${VCS_BASENAME}" ] && echo "%define vcs_basename ${VCS_BASENAME}") +$([ "${VCS_UUID}" ] && echo "%define vcs_uuid ${VCS_UUID}") +$([ "${VCS_NUM}" ] && echo "%define vcs_num ${VCS_NUM}") +$([ "${VCS_DATE}" ] && echo "%define vcs_date ${VCS_DATE}") +$([ "${VCS_BRANCH}" ] && echo "%define vcs_branch ${VCS_BRANCH}") +$([ "${VCS_TAG}" ] && echo "%define vcs_tag ${VCS_TAG}") +$([ "${VCS_TICK}" ] && echo "%define vcs_tick ${VCS_TICK}") +$([ "${VCS_EXTRA}" ] && echo "%define vcs_extra ${VCS_EXTRA}") + +$([ "${VCS_ACTION_STAMP}" ] && echo "%define vcs_action_stamp ${VCS_ACTION_STAMP}") +$([ "${VCS_FULL_HASH}" ] && echo "%define vcs_full_hash ${VCS_FULL_HASH}") +$([ "${VCS_SHORT_HASH}" ] && echo "%define vcs_short_hash ${VCS_SHORT_HASH}") + +$([ "${VCS_WC_MODIFIED}" ] && echo "%define vcs_wc_modified ${VCS_WC_MODIFIED}") +# end +EOF +} + +# shellcheck disable=SC2155,SC2039 +hppOutput() { + local NAMESPACE="$(echo "${VCS_BASENAME}" | sed -e 's:_::g' | tr '[:lower:]' '[:upper:]')" + cat > "${TARGETFILE}" << EOF +/* ${GENERATED_HEADER} */ + +#ifndef ${NAMESPACE}_AUTOREVISION_H +#define ${NAMESPACE}_AUTOREVISION_H + +#include <string> + +namespace $(echo "${NAMESPACE}" | tr '[:upper:]' '[:lower:]') +{ + const std::string VCS_TYPE = "${VCS_TYPE}"; + const std::string VCS_BASENAME = "${VCS_BASENAME}"; + const std::string VCS_UUID = "${VCS_UUID}"; + const int VCS_NUM = ${VCS_NUM}; + const std::string VCS_DATE = "${VCS_DATE}"; + const std::string VCS_BRANCH = "${VCS_BRANCH}"; + const std::string VCS_TAG = "${VCS_TAG}"; + const int VCS_TICK = ${VCS_TICK}; + const std::string VCS_EXTRA = "${VCS_EXTRA}"; + + const std::string VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"; + const std::string VCS_FULL_HASH = "${VCS_FULL_HASH}"; + const std::string VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; + + const int VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; +} + +#endif + +/* end */ +EOF +} + +matlabOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="FALSE" ;; + 1) VCS_WC_MODIFIED="TRUE" ;; + esac + cat > "${TARGETFILE}" << EOF +% ${GENERATED_HEADER} + +VCS_TYPE = '${VCS_TYPE}'; +VCS_BASENAME = '${VCS_BASENAME}'; +VCS_UUID = '${VCS_UUID}'; +VCS_NUM = ${VCS_NUM}; +VCS_DATE = '${VCS_DATE}'; +VCS_BRANCH = '${VCS_BRANCH}'; +VCS_TAG = '${VCS_TAG}'; +VCS_TICK = ${VCS_TICK}; +VCS_EXTRA = '${VCS_EXTRA}'; + +VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}'; +VCS_FULL_HASH = '${VCS_FULL_HASH}'; +VCS_SHORT_HASH = '${VCS_SHORT_HASH}'; + +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +% end +EOF +} + +octaveOutput() { + cat > "${TARGETFILE}" << EOF +% ${GENERATED_HEADER} + +VCS_TYPE = '${VCS_TYPE}'; +VCS_BASENAME = '${VCS_BASENAME}'; +VCS_UUID = '${VCS_UUID}'; +VCS_NUM = ${VCS_NUM}; +VCS_DATE = '${VCS_DATE}'; +VCS_BRANCH = '${VCS_BRANCH}'; +VCS_TAG = '${VCS_TAG}'; +VCS_TICK = ${VCS_TICK}; +VCS_EXTRA = '${VCS_EXTRA}'; + +VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}'; +VCS_FULL_HASH = '${VCS_FULL_HASH}'; +VCS_SHORT_HASH = '${VCS_SHORT_HASH}'; + +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +% end +EOF +} + +cmakeOutput() { + cat > "${TARGETFILE}" << EOF +# ${GENERATED_HEADER} + +set(VCS_TYPE ${VCS_TYPE}) +set(VCS_BASENAME ${VCS_BASENAME}) +set(VCS_UUID ${VCS_UUID}) +set(VCS_NUM ${VCS_NUM}) +set(VCS_DATE ${VCS_DATE}) +set(VCS_BRANCH ${VCS_BRANCH}) +set(VCS_TAG ${VCS_TAG}) +set(VCS_TICK ${VCS_TICK}) +set(VCS_EXTRA ${VCS_EXTRA}) + +set(VCS_ACTION_STAMP ${VCS_ACTION_STAMP}) +set(VCS_FULL_HASH ${VCS_FULL_HASH}) +set(VCS_SHORT_HASH ${VCS_SHORT_HASH}) + +set(VCS_WC_MODIFIED ${VCS_WC_MODIFIED}) + +# end +EOF +} + + +# Helper functions +# Count path segments +# shellcheck disable=SC2039 +pathSegment() { + local pathz="${1}" + local depth="0" + + if [ ! -z "${pathz}" ]; then + # Continue until we are at / or there are no path separators left. + while [ ! "${pathz}" = "/" ] && [ ! "${pathz}" = "$(echo "${pathz}" | sed -e 's:/::')" ]; do + pathz="$(dirname "${pathz}")" + depth="$((depth+1))" + done + fi + echo "${depth}" +} + +# Largest of four numbers +# shellcheck disable=SC2039 +multiCompare() { + local larger="${1}" + local numA="${2}" + local numB="${3}" + local numC="${4}" + + [ "${numA}" -gt "${larger}" ] && larger="${numA}" + [ "${numB}" -gt "${larger}" ] && larger="${numB}" + [ "${numC}" -gt "${larger}" ] && larger="${numC}" + echo "${larger}" +} + +# Test for repositories +# shellcheck disable=SC2155,SC2039 +repoTest() { + REPONUM="0" + if [ ! -z "$(git rev-parse HEAD 2>/dev/null)" ]; then + local gitPath="$(git rev-parse --show-toplevel)" + local gitDepth="$(pathSegment "${gitPath}")" + REPONUM="$((REPONUM+1))" + else + local gitDepth="0" + fi + if [ ! -z "$(hg root 2>/dev/null)" ]; then + local hgPath="$(hg root 2>/dev/null)" + local hgDepth="$(pathSegment "${hgPath}")" + REPONUM="$((REPONUM+1))" + else + local hgDepth="0" + fi + if [ ! -z "$(bzr root 2>/dev/null)" ]; then + local bzrPath="$(bzr root 2>/dev/null)" + local bzrDepth="$(pathSegment "${bzrPath}")" + REPONUM="$((REPONUM+1))" + else + local bzrDepth="0" + fi + if [ ! -z "$(svn info 2>/dev/null)" ]; then + local stringz="<wcroot-abspath>" + local stringx="</wcroot-abspath>" + local svnPath="$(svn info --xml | sed -n -e "s:${stringz}::" -e "s:${stringx}::p")" + # An old enough svn will not be able give us a path; default + # to 1 for that case. + if [ -z "${svnPath}" ]; then + local svnDepth="1" + else + local svnDepth="$(pathSegment "${svnPath}")" + fi + REPONUM="$((REPONUM+1))" + else + local svnDepth="0" + fi + + # Do not do more work then we have to. + if [ "${REPONUM}" = "0" ]; then + return + fi + + # Figure out which repo is the deepest and use it. + local wonRepo="$(multiCompare "${gitDepth}" "${hgDepth}" "${bzrDepth}" "${svnDepth}")" + if [ "${wonRepo}" = "${gitDepth}" ]; then + gitRepo + elif [ "${wonRepo}" = "${hgDepth}" ]; then + hgRepo + elif [ "${wonRepo}" = "${bzrDepth}" ]; then + bzrRepo + elif [ "${wonRepo}" = "${svnDepth}" ]; then + svnRepo + fi +} + + + +# Detect which repos we are in and gather data. +# shellcheck source=/dev/null +if [ -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then + # When requested only read from the cache to populate our symbols. + . "${CACHEFILE}" +else + # If a value is not set through the environment set VCS_EXTRA to nothing. + : "${VCS_EXTRA:=""}" + repoTest + + if [ -f "${CACHEFILE}" ] && [ "${REPONUM}" = "0" ]; then + # We are not in a repo; try to use a previously generated cache to populate our symbols. + . "${CACHEFILE}" + # Do not overwrite the cache if we know we are not going to write anything new. + CACHEFORCE="1" + elif [ "${REPONUM}" = "0" ]; then + echo "error: No repo or cache detected." 1>&2 + exit 1 + fi +fi + + +# -s output is handled here. +if [ ! -z "${VAROUT}" ]; then + if [ "${VAROUT}" = "VCS_TYPE" ]; then + echo "${VCS_TYPE}" + elif [ "${VAROUT}" = "VCS_BASENAME" ]; then + echo "${VCS_BASENAME}" + elif [ "${VAROUT}" = "VCS_NUM" ]; then + echo "${VCS_NUM}" + elif [ "${VAROUT}" = "VCS_DATE" ]; then + echo "${VCS_DATE}" + elif [ "${VAROUT}" = "VCS_BRANCH" ]; then + echo "${VCS_BRANCH}" + elif [ "${VAROUT}" = "VCS_TAG" ]; then + echo "${VCS_TAG}" + elif [ "${VAROUT}" = "VCS_TICK" ]; then + echo "${VCS_TICK}" + elif [ "${VAROUT}" = "VCS_FULL_HASH" ]; then + echo "${VCS_FULL_HASH}" + elif [ "${VAROUT}" = "VCS_SHORT_HASH" ]; then + echo "${VCS_SHORT_HASH}" + elif [ "${VAROUT}" = "VCS_WC_MODIFIED" ]; then + echo "${VCS_WC_MODIFIED}" + elif [ "${VAROUT}" = "VCS_ACTION_STAMP" ]; then + echo "${VCS_ACTION_STAMP}" + else + echo "error: Not a valid output symbol." 1>&2 + exit 1 + fi +fi + + +# Detect requested output type and use it. +if [ ! -z "${AFILETYPE}" ]; then + if [ "${AFILETYPE}" = "c" ]; then + cOutput + elif [ "${AFILETYPE}" = "h" ]; then + hOutput + elif [ "${AFILETYPE}" = "xcode" ]; then + xcodeOutput + elif [ "${AFILETYPE}" = "swift" ]; then + swiftOutput + elif [ "${AFILETYPE}" = "sh" ]; then + shOutput + elif [ "${AFILETYPE}" = "py" ] || [ "${AFILETYPE}" = "python" ]; then + pyOutput + elif [ "${AFILETYPE}" = "pl" ] || [ "${AFILETYPE}" = "perl" ]; then + plOutput + elif [ "${AFILETYPE}" = "lua" ]; then + luaOutput + elif [ "${AFILETYPE}" = "php" ]; then + phpOutput + elif [ "${AFILETYPE}" = "ini" ]; then + iniOutput + elif [ "${AFILETYPE}" = "js" ]; then + jsOutput + elif [ "${AFILETYPE}" = "json" ]; then + jsonOutput + elif [ "${AFILETYPE}" = "java" ]; then + javaOutput + elif [ "${AFILETYPE}" = "javaprop" ]; then + javapropOutput + elif [ "${AFILETYPE}" = "tex" ]; then + texOutput + elif [ "${AFILETYPE}" = "m4" ]; then + m4Output + elif [ "${AFILETYPE}" = "scheme" ]; then + schemeOutput + elif [ "${AFILETYPE}" = "clojure" ]; then + clojureOutput + elif [ "${AFILETYPE}" = "rpm" ]; then + rpmOutput + elif [ "${AFILETYPE}" = "hpp" ]; then + hppOutput + elif [ "${AFILETYPE}" = "matlab" ]; then + matlabOutput + elif [ "${AFILETYPE}" = "octave" ]; then + octaveOutput + elif [ "${AFILETYPE}" = "cmake" ]; then + cmakeOutput + else + echo "error: Not a valid output type." 1>&2 + exit 1 + fi +fi + + +# If requested, make a cache file. +if [ ! -z "${CACHEFILE}" ] && [ ! "${CACHEFORCE}" = "1" ]; then + TARGETFILE="${CACHEFILE}.tmp" + shOutput + + # Check to see if there have been any actual changes. + if [ ! -f "${CACHEFILE}" ]; then + mv -f "${CACHEFILE}.tmp" "${CACHEFILE}" + elif cmp -s "${CACHEFILE}.tmp" "${CACHEFILE}"; then + rm -f "${CACHEFILE}.tmp" + else + mv -f "${CACHEFILE}.tmp" "${CACHEFILE}" + fi +fi diff --git a/bin/main.conf b/bin/main.conf new file mode 100644 index 0000000..d35a5ab --- /dev/null +++ b/bin/main.conf @@ -0,0 +1,7 @@ +[QUIC] +QUIC_PORT_LIST=443;8443;4433; +LOG_LEVEL=30 +LOG_PATH="./log/quic_decoder/quic_decoder" +DECRYPTED_SWITCH=2 +#MAX_PARSE_PKT_NUM=3 +MAX_CHLO_SIZE=4096 diff --git a/bin/quic.conf b/bin/quic.conf new file mode 100755 index 0000000..d93181b --- /dev/null +++ b/bin/quic.conf @@ -0,0 +1,8 @@ +0 QUIC_INTEREST_KEY +1 QUIC_CLIENT_HELLO +2 QUIC_SERVER_HELLO +3 QUIC_CACHED_CERT +4 QUIC_COMM_CERT +5 QUIC_CERT_CHAIN +6 QUIC_APPLICATION_DATA +7 QUIC_VERSION
\ No newline at end of file diff --git a/bin/quic.inf b/bin/quic.inf new file mode 100755 index 0000000..2e73f7d --- /dev/null +++ b/bin/quic.inf @@ -0,0 +1,9 @@ +[[plugin]] +path = "./stellar_plugin/quic_decoder/quic_decoder.so" +init = "QUIC_ONLOAD" +exit = "QUIC_UNLOAD" + +[[plugin]] +path = "./stellar_plugin/quic_decoder/quic_decoder_test_plug.so" +init = "QUIC_TEST_PLUG_INIT" +exit = "QUIC_TEST_PLUG_DESTROY" diff --git a/ci/get-nprocessors.sh b/ci/get-nprocessors.sh new file mode 100644 index 0000000..43635e7 --- /dev/null +++ b/ci/get-nprocessors.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This file is typically sourced by another script. +# if possible, ask for the precise number of processors, +# otherwise take 2 processors as reasonable default; see +# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization +if [ -x /usr/bin/getconf ]; then + NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN) +else + NPROCESSORS=2 +fi + +# as of 2017-09-04 Travis CI reports 32 processors, but GCC build +# crashes if parallelized too much (maybe memory consumption problem), +# so limit to 4 processors for the time being. +if [ $NPROCESSORS -gt 4 ] ; then + echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4." + NPROCESSORS=4 +fi diff --git a/ci/perpare_pulp3_netrc.sh b/ci/perpare_pulp3_netrc.sh new file mode 100644 index 0000000..8414bbb --- /dev/null +++ b/ci/perpare_pulp3_netrc.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh +set -evx +echo "machine ${PULP3_SERVER_URL}\nlogin ${PULP3_SERVER_LOGIN}\npassword ${PULP3_SERVER_PASSWORD}\n" > ~/.netrc diff --git a/ci/travis.sh b/ci/travis.sh new file mode 100644 index 0000000..7a4cdc1 --- /dev/null +++ b/ci/travis.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env sh +set -evx + +chmod +x ci/get-nprocessors.sh +. ci/get-nprocessors.sh + +# if possible, ask for the precise number of processors, +# otherwise take 2 processors as reasonable default; see +# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization +if [ -x /usr/bin/getconf ]; then + NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN) +else + NPROCESSORS=2 +fi + +# as of 2017-09-04 Travis CI reports 32 processors, but GCC build +# crashes if parallelized too much (maybe memory consumption problem), +# so limit to 4 processors for the time being. +if [ $NPROCESSORS -gt 4 ] ; then + echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4." + NPROCESSORS=4 +fi + +# Tell make to use the processors. No preceding '-' required. +MAKEFLAGS="j${NPROCESSORS}" +export MAKEFLAGS + +env | sort + +# Set default values to OFF for these variables if not specified. +: "${NO_EXCEPTION:=OFF}" +: "${NO_RTTI:=OFF}" +: "${COMPILER_IS_GNUCXX:=OFF}" + +# Install dependency from YUM +if [ -n "${INSTALL_DEPENDENCY_FRAMEWORK}" ]; then + yum install -y $INSTALL_DEPENDENCY_FRAMEWORK + source /etc/profile.d/framework.sh +fi + +if [ -n "${INSTALL_DEPENDENCY_PLATFORM}" ]; then + yum install -y $INSTALL_DEPENDENCY_PLATFORM +fi + +if [ $ASAN_OPTION ] && [ -f "/opt/rh/devtoolset-7/enable" ] ;then + source /opt/rh/devtoolset-7/enable +fi + +mkdir build || true +cd build + +cmake3 -DCMAKE_CXX_FLAGS=$CXX_FLAGS \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ + -DASAN_OPTION=$ASAN_OPTION \ + -DVERSION_DAILY_BUILD=$TESTING_VERSION_BUILD \ + .. + +make + +if [ -n "${PACKAGE}" ]; then + make package +fi + +if [ -n "${UPLOAD_RPM}" ]; then + cp ~/rpm_upload_tools.py ./ + python3 rpm_upload_tools.py ${PULP3_REPO_NAME} ${PULP3_DIST_NAME} *.rpm +fi + diff --git a/cmake/Package.cmake b/cmake/Package.cmake new file mode 100644 index 0000000..d7c7dd3 --- /dev/null +++ b/cmake/Package.cmake @@ -0,0 +1,56 @@ +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(MY_RPM_NAME_PREFIX "${lib_name}-debug") +else() + set(MY_RPM_NAME_PREFIX "${lib_name}") +endif() + +message(STATUS "Package: ${MY_RPM_NAME_PREFIX}") + +set(CPACK_PACKAGE_VECDOR "MESA") +set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}") +set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}.${VERSION_BUILD}") +set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) +set(CPACK_PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILD}") + +execute_process(COMMAND sh changelog.sh ${CMAKE_BINARY_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/cmake) +SET(CPACK_RPM_CHANGELOG_FILE ${CMAKE_BINARY_DIR}/changelog.txt) + +# RPM Build +set(CPACK_GENERATOR "RPM") +set(CPACK_RPM_AUTO_GENERATED_FILE_NAME ON) +set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") +set(CPACK_RPM_PACKAGE_VENDOR "MESA") +set(CPACK_RPM_PACKAGE_AUTOREQPROV "yes") +set(CPACK_RPM_PACKAGE_RELEASE_DIST "on") +set(CPACK_RPM_DEBUGINFO_PACKAGE "on") + +set(CPACK_RPM_COMPONENT_INSTALL ON) +set(CPACK_COMPONENTS_IGNORE_GROUPS 1) +set(CPACK_COMPONENTS_GROUPING ONE_PER_GROUP) +set(CPACK_COMPONENT_HEADER_DISPLAY_NAME "develop") + +set(CPACK_COMPONENT_LIBRARIES_REQUIRED TRUE) +set(CPACK_RPM_LIBRARIES_PACKAGE_NAME ${MY_RPM_NAME_PREFIX}) +set(CPACK_COMPONENT_LIBRARIES_GROUP "LIBRARIES") +set(CPACK_COMPONENT_PROFILE_GROUP "LIBRARIES") + +set(CPACK_COMPONENT_HEADER_REQUIRED TRUE) +set(CPACK_RPM_HEADER_PACKAGE_NAME "${MY_RPM_NAME_PREFIX}-devel") +set(CPACK_COMPONENT_HEADER_GROUP "HEADER") + +set(CPACK_RPM_HEADER_PACKAGE_REQUIRES_PRE ${CPACK_RPM_LIBRARIES_PACKAGE_NAME}) +set(CPACK_RPM_HEADER_PACKAGE_CONFLICTS ${CPACK_RPM_HEADER_PACKAGE_NAME}) + +set(CPACK_COMPONENTS_ALL LIBRARIES HEADER PROFILE) + +SET(CPACK_RPM_LIBRARIES_PRE_INSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/cmake/preInstall.sh") +SET(CPACK_RPM_LIBRARIES_PRE_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/cmake/preUninstall.sh") + +set(CPACK_BUILD_SOURCE_DIRS "${CMAKE_SOURCE_DIR}") + +# Must uninstall the debug package before install release package +set(CPACK_RPM_PACKAGE_CONFLICTS ${MY_RPM_NAME_PREFIX}) + +# set(CPACK_STRIP_FILES TRUE) +include(CPack) diff --git a/cmake/Version.cmake b/cmake/Version.cmake new file mode 100644 index 0000000..a47944c --- /dev/null +++ b/cmake/Version.cmake @@ -0,0 +1,54 @@ + +# Using autorevision.sh to generate version information + +set(__SOURCE_AUTORESIVISION ${CMAKE_SOURCE_DIR}/autorevision.sh) +set(__AUTORESIVISION ${CMAKE_BINARY_DIR}/autorevision.sh) +set(__VERSION_CACHE ${CMAKE_BINARY_DIR}/version.txt) +set(__VERSION_CONFIG ${CMAKE_BINARY_DIR}/version.cmake) + +file(COPY ${__SOURCE_AUTORESIVISION} DESTINATION ${CMAKE_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + +# execute autorevision.sh to generate version information +execute_process(COMMAND ${__AUTORESIVISION} -t cmake -o ${__VERSION_CACHE} + OUTPUT_FILE ${__VERSION_CONFIG} ERROR_QUIET) +include(${__VERSION_CONFIG}) + +# extract major, minor, patch version from git tag +string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VCS_TAG}") +string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VCS_TAG}") +string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VCS_TAG}") +string(REGEX REPLACE "[T\\:\\+\\-]" "" VERSION_DATE "${VCS_DATE}") + +if(VERSION_DAILY_BUILD) + set(VERSION_PATCH ${VERSION_PATCH}.${VERSION_DATE}) +endif() + +if(NOT VERSION_MAJOR) + set(VERSION_MAJOR 1) +endif() + +if(NOT VERSION_MINOR) + set(VERSION_MINOR 0) +endif() + +if(NOT VERSION_PATCH) + set(VERSION_PATCH 0) +endif() + +set(VERSION "${VERSION_MAJOR}_${VERSION_MINOR}_${VERSION_PATCH}") +set(VERSION_BUILD "${VCS_SHORT_HASH}") + +# print information +message(STATUS "Version: ${VERSION}-${VERSION_BUILD}") + +option(DEFINE_GIT_VERSION "Set DEFINE_GIT_VERSION to TRUE or FALSE" TRUE) + +if(DEFINE_GIT_VERSION) + set(GIT_VERSION + "${VERSION}-${CMAKE_BUILD_TYPE}-${VERSION_BUILD}-${VCS_BRANCH}-${VCS_TAG}-${VCS_DATE}") + string(REGEX REPLACE "[-:+/\\.]" "_" GIT_VERSION ${GIT_VERSION}) + + add_definitions(-DGIT_VERSION=${GIT_VERSION}) +endif() diff --git a/cmake/changelog.sh b/cmake/changelog.sh new file mode 100644 index 0000000..087129d --- /dev/null +++ b/cmake/changelog.sh @@ -0,0 +1,4 @@ +#!/bin/sh +work_path=$1 +branch=`git status | grep 'On branch' | awk '{print $NF}'` +git log --branches=$branch --no-merges --date=local --show-signature --pretty="* %ad %an %ae %nhash: %H%ncommit:%n%B" | awk -F"-" '{print "- "$0}' | sed 's/- \*/\*/g' | sed 's/- $//g' | sed 's/-/ -/g' | sed 's/[0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}//g' > $work_path/changelog.txt diff --git a/cmake/preInstall.sh b/cmake/preInstall.sh new file mode 100644 index 0000000..1c763db --- /dev/null +++ b/cmake/preInstall.sh @@ -0,0 +1,14 @@ +#!/bin/sh +DST=${RPM_INSTALL_PREFIX}/sapp/ + +mkdir -p ${DST}/stellar_plugin +touch ${DST}/stellar_plugin/spec.toml + +if ! grep -q '^\./plug/stellar_plugin/quic_decoder/quic_decoder.so' "${DST}/stellar_plugin/spec.toml"; then + echo -e "\n" >> "${DST}/stellar_plugin/spec.toml" + echo -e "[[plugin]]" >> "${DST}/stellar_plugin/spec.toml" + echo -e "path = \"./stellar_plugin/quic_decoder/quic_decoder.so\"" >> "${DST}/stellar_plugin/spec.toml" + echo -e "init = \"QUIC_ONLOAD\"" >> "${DST}/stellar_plugin/spec.toml" + echo -e "exit = \"QUIC_UNLOAD\"" >> "${DST}/stellar_plugin/spec.toml" + echo -e "\n" >> "${DST}/stellar_plugin/spec.toml" +fi diff --git a/cmake/preUninstall.sh b/cmake/preUninstall.sh new file mode 100644 index 0000000..bda4668 --- /dev/null +++ b/cmake/preUninstall.sh @@ -0,0 +1,6 @@ +if [ $1 == 0 ]; then + DST=${RPM_INSTALL_PREFIX}/sapp/stellar_plugin + sed -i -n '$!N;/quic_decoder.so/!P;D' ${DST}/spec.toml + sed -i '/QUIC_ONLOAD/d' ${DST}/spec.toml + sed -i '/QUIC_UNLOAD/d' ${DST}/spec.toml +fi diff --git a/demo/correct.txt b/demo/correct.txt Binary files differnew file mode 100644 index 0000000..9579c66 --- /dev/null +++ b/demo/correct.txt diff --git a/demo/error.txt b/demo/error.txt Binary files differnew file mode 100644 index 0000000..42e9bd9 --- /dev/null +++ b/demo/error.txt diff --git a/demo/parse_quic_transport_parameter.cpp b/demo/parse_quic_transport_parameter.cpp new file mode 100644 index 0000000..3f896a7 --- /dev/null +++ b/demo/parse_quic_transport_parameter.cpp @@ -0,0 +1,70 @@ +//https://jira.geedge.net/browse/OMPUB-527 + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +static int msb2_varint_decode(const unsigned char *buf, long *out) +{ + unsigned long val = buf[0] & 0x3f; + unsigned int nfollow = 1<<(buf[0]>>6); + switch (nfollow-1) + { + case 7: val = (val << 8) | buf[nfollow - 7]; /*fail through*/ + case 6: val = (val << 8) | buf[nfollow - 6]; /*fail through*/ + case 5: val = (val << 8) | buf[nfollow - 5]; /*fail through*/ + case 4: val = (val << 8) | buf[nfollow - 4]; /*fail through*/ + case 3: val = (val << 8) | buf[nfollow - 3]; /*fail through*/ + case 2: val = (val << 8) | buf[nfollow - 2]; /*fail through*/ + case 1: val = (val << 8) | buf[nfollow-1]; + case 0: break; + } + *out=val; + + return nfollow; +} + +int parse_quic_transport_parameter(const char *quic_para, int quic_para_len, int thread_seq) +{ + int one_para_length=0; + int para_offset=0; + long one_para_type=0; + + while(quic_para_len > para_offset) + { + para_offset+=msb2_varint_decode((const unsigned char *)(quic_para+para_offset), &one_para_type); + switch(one_para_type) + { + //case EXT_QUIC_PARAM_USER_AGENT: // 2021-10-20 deprecated + case 0x3129: + one_para_length=quic_para[para_offset++]; // length=1 + if(one_para_length+para_offset>quic_para_len) + { + return 0; + } + //para_offset+=copy_extension_tag(quic_para+para_offset, one_para_length, &client_hello->user_agent, thread_seq); + return 1; + default: + one_para_length=(int)(quic_para[para_offset++]); // length=1 + if(one_para_length<0 || one_para_length>quic_para_len) + { + break; + } + para_offset+=one_para_length; + break; + } + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + char buff1[106]={0x80, 0x0, 0x47, 0x52, 0x4, 0x0, 0x0, 0x0, 0x1, 0x20, 0x4, 0x80, 0x1, 0x0, 0x0, 0xf, 0x0, 0x4, 0x4, 0x80, 0xf0, 0x0, 0x0, 0x8, 0x2, 0x40, 0x64, 0x7, 0x4, 0x80, 0x60, 0x0, 0x0, 0x9, 0x2, 0x40, 0x67, 0x6, 0x4, 0x80, 0x60, 0x0, 0x0, 0x80, 0xff, 0x73, 0xdb, 0xc, 0x0, 0x0, 0x0, 0x1, 0x3a, 0x6a, 0x9b, 0xaa, 0x4f, 0x2f, 0xbd, 0xc, 0xd5, 0xe2, 0xae, 0x32, 0x45, 0x6, 0x2e, 0xf, 0xc5, 0x82, 0x94, 0x3d, 0x5d, 0xb2, 0x69, 0x2c, 0x25, 0xbd, 0xd5, 0x85, 0x99, 0x72, 0xeb, 0x3, 0x2, 0x45, 0xc0, 0x1, 0x4, 0x80, 0x0, 0x75, 0x30, 0x71, 0x28, 0x4, 0x52, 0x56, 0x43, 0x4d, 0x5, 0x4, 0x80, 0x60, 0x0, 0x0}; + char buff2[99]={0x71, 0x27, 0x4, 0x80, 0x2, 0xa5, 0xb2, 0xe4, 0xcf, 0x74, 0x5b, 0xf5, 0x6, 0x41, 0x20, 0x0, 0x8, 0x2, 0x40, 0x64, 0x4, 0x4, 0x80, 0xd4, 0x9f, 0xb7, 0x6f, 0xdf, 0xed, 0x48, 0x94, 0x18, 0xd7, 0x53, 0xf7, 0x92, 0x6, 0x94, 0xa0, 0x0, 0x0, 0x1, 0x4, 0x80, 0x0, 0x75, 0x30, 0xf, 0x0, 0x80, 0xff, 0x73, 0xdb, 0xc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x8a, 0x7a, 0x8a, 0x3a, 0x9, 0x2, 0x40, 0x67, 0x3, 0x2, 0x45, 0xc0, 0x5, 0x4, 0x80, 0x60, 0x0, 0x0, 0x71, 0x28, 0x4, 0x52, 0x56, 0x43, 0x4d, 0x20, 0x4, 0x80, 0x1, 0x0, 0x0, 0x7, 0x4, 0x80, 0x60, 0x0, 0x0}; + + parse_quic_transport_parameter(buff1, 106, 0); + parse_quic_transport_parameter(buff2, 99, 0); + + return 0; +} diff --git a/include/quic_decoder.h b/include/quic_decoder.h new file mode 100644 index 0000000..a4a909b --- /dev/null +++ b/include/quic_decoder.h @@ -0,0 +1,33 @@ +#pragma once +#ifdef __cplusplus +extern "C" +{ +#endif +#include <stddef.h> + +enum quic_message_type +{ + QUIC_CLIENT_HELLO, + QUIC_SERVER_HELLO, + QUIC_PROTECTED_PAYLOAD, + QUIC_MSG_MAX, +}; + +#define QUIC_DECODER_TOPIC "QUIC_DECODER_MESSAGE" +struct quic_message; +enum quic_message_type quic_message_type_get(const struct quic_message *msg); + +/* + * 0 is reserved for version negotiation, will never represent a real protocol. + * https://www.rfc-editor.org/rfc/rfc9000.html#name-versions +*/ +unsigned int quic_message_version_get(const struct quic_message *msg); +const char *quic_message_readable_version_get0(const struct quic_message *msg); +const char *quic_message_readable_ja3hash_get0(const struct quic_message *msg); +void quic_message_sni_get0(const struct quic_message *msg, char **result, size_t *len); +void quic_message_user_agent_get0(const struct quic_message *msg, char **result, size_t *len); +void quic_message_protected_payload_get0(const struct quic_message *msg, char **result, size_t *len); + +#ifdef __cplusplus +} +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..db4cca3 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required (VERSION 2.8...3.10) + +file(GLOB SRC "*.cpp") +set(DEPEND_DYN_LIB MESA_handle_logger) + +include_directories(/opt/tsg/framework/include/) + +# Shared Library Output +add_library(${lib_name} SHARED ${SRC}) +set_target_properties(${lib_name} PROPERTIES LINK_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/src/version.map") +set_target_properties(${lib_name} PROPERTIES PREFIX "") +target_link_libraries(${lib_name} ${DNS_DEPEND_DYN_LIB} pthread -Wl,--no-whole-archive openssl-crypto-static -Wl,--no-whole-archive openssl-ssl-static) +set_target_properties(${lib_name} PROPERTIES OUTPUT_NAME ${lib_name}) + +install(TARGETS ${lib_name} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/sapp/stellar_plugin/quic_decoder COMPONENT LIBRARIES) diff --git a/src/quic_deprotection.cpp b/src/quic_deprotection.cpp new file mode 100644 index 0000000..923a395 --- /dev/null +++ b/src/quic_deprotection.cpp @@ -0,0 +1,1129 @@ +#include "quic_deprotection.h" + +#include <inttypes.h> +#include <openssl/evp.h> +#include <openssl/kdf.h> +#include <openssl/sha.h> + +#define QUIC_IV_LEN 12 /* RFC 5116, 5.1 and RFC 8439, 2.3 for all supported ciphers */ +#define QUIC_HP_LEN 5 /* RFC 9001, 5.4.1. Header Protection Application: 5-byte mask */ + +#define QUIC_MAX_CID_LEN 20 +#define QUIC_AES_128_KEY_LEN 16 +#define QUIC_MIN_INITIAL_SIZE 1200 +#define QUIC_UNSET_PN (uint64_t) - 1 + +/* + * RFC 9000, 17.2. Long Header Packets + * 17.3. Short Header Packets + * QUIC flags in first byte + */ +#define QUIC_PKT_LONG 0x80 /* header form */ +#define QUIC_PKT_FIXED_BIT 0x40 +#define QUIC_PKT_TYPE 0x30 /* in long packet */ +#define QUIC_PKT_KPHASE 0x04 /* in short packet */ + +#define quic_pkt_header_is_long(flags) ((flags)&QUIC_PKT_LONG) +#define quic_pkt_header_is_short(flags) (((flags)&QUIC_PKT_LONG) == 0) +#define quic_pkt_hp_mask(flags) (quic_pkt_header_is_long(flags) ? 0x0F : 0x1F) +#define quic_pkt_rb_mask(flags) (quic_pkt_header_is_long(flags) ? 0x0C : 0x18) + +/* Long packet types */ +#define quic_pkt_level_is_initial(flags) (((flags)&QUIC_PKT_TYPE) == 0x00) +#define quic_pkt_level_is_zrtt(flags) (((flags)&QUIC_PKT_TYPE) == 0x10) +#define quic_pkt_level_is_handshake(flags) (((flags)&QUIC_PKT_TYPE) == 0x20) + +/* MAX MIN */ +#define MAX(val1, val2) ((val1 < val2) ? (val2) : (val1)) +#define MIN(val1, val2) ((val1 > val2) ? (val2) : (val1)) + +#define quic_pkt_level_to_name(lvl) \ + (lvl == ssl_encryption_application) ? "application" \ + : (lvl == ssl_encryption_initial) ? "initial" \ + : (lvl == ssl_encryption_handshake) ? "handshake" \ + : "early" + +typedef struct +{ + const EVP_CIPHER *c; + const EVP_CIPHER *hp; + const EVP_MD *d; +} quic_ciphers_t; + +/////////////////////////////////////////////////////////////////////////////// +// QUIC version +/////////////////////////////////////////////////////////////////////////////// + +#define QUIC_NVERSIONS (sizeof(quic_version_vals) / sizeof(quic_version_vals[0])) + +const quic_str_t quic_version_vals[] = { + {0x00000000, (u_char *)"Version Negotiation"}, + {0x00000001, (u_char *)"1"}, + /* Versions QXXX < Q050 are dissected by Wireshark as GQUIC and not as QUIC. + Nonetheless, some implementations report these values in "Version Negotiation" + packets, so decode these fields */ + {0x51303433, (u_char *)"Google Q043"}, + {0x51303434, (u_char *)"Google Q044"}, + {0x51303436, (u_char *)"Google Q046"}, + {0x51303530, (u_char *)"Google Q050"}, + {0x54303530, (u_char *)"Google T050"}, + {0x54303531, (u_char *)"Google T051"}, + {0xfaceb001, (u_char *)"Facebook mvfst (draft-22)"}, + {0xfaceb002, (u_char *)"Facebook mvfst (draft-27)"}, + {0xfaceb00e, (u_char *)"Facebook mvfst (Experimental)"}, + {0xff000004, (u_char *)"draft-04"}, + {0xff000005, (u_char *)"draft-05"}, + {0xff000006, (u_char *)"draft-06"}, + {0xff000007, (u_char *)"draft-07"}, + {0xff000008, (u_char *)"draft-08"}, + {0xff000009, (u_char *)"draft-09"}, + {0xff00000a, (u_char *)"draft-10"}, + {0xff00000b, (u_char *)"draft-11"}, + {0xff00000c, (u_char *)"draft-12"}, + {0xff00000d, (u_char *)"draft-13"}, + {0xff00000e, (u_char *)"draft-14"}, + {0xff00000f, (u_char *)"draft-15"}, + {0xff000010, (u_char *)"draft-16"}, + {0xff000011, (u_char *)"draft-17"}, + {0xff000012, (u_char *)"draft-18"}, + {0xff000013, (u_char *)"draft-19"}, + {0xff000014, (u_char *)"draft-20"}, + {0xff000015, (u_char *)"draft-21"}, + {0xff000016, (u_char *)"draft-22"}, + {0xff000017, (u_char *)"draft-23"}, + {0xff000018, (u_char *)"draft-24"}, + {0xff000019, (u_char *)"draft-25"}, + {0xff00001a, (u_char *)"draft-26"}, + {0xff00001b, (u_char *)"draft-27"}, + {0xff00001c, (u_char *)"draft-28"}, + {0xff00001d, (u_char *)"draft-29"}, + {0xff00001e, (u_char *)"draft-30"}, + {0xff00001f, (u_char *)"draft-31"}, + {0xff000020, (u_char *)"draft-32"}, + {0, NULL}}; + +static int quic_version_is_supported(uint32_t version) +{ + unsigned int i = 0; + for (i = 0; i < QUIC_NVERSIONS; i++) + { + if (quic_version_vals[i].len == version) + { + return 1; + } + } + + return 0; +} + +// Returns the QUIC draft version or 0 if not applicable. +static inline uint8_t quic_draft_version(uint32_t version) +{ + if ((version >> 8) == 0xff0000) + return (uint8_t)version; + + // Facebook mvfst, based on draft -22. + if (version == 0xfaceb001) + return 22; + + // Facebook mvfst, based on draft -27. + if (version == 0xfaceb002 || version == 0xfaceb00e) + return 27; + + // GQUIC Q050, T050 and T051: they are not really based on any drafts, + // but we must return a sensible value + if (version == 0x51303530 || version == 0x54303530 || version == 0x54303531) + return 27; + + /* + * https://tools.ietf.org/html/draft-ietf-quic-transport-32#section-15 + * "Versions that follow the pattern 0x?a?a?a?a are reserved for use in + * forcing version negotiation to be exercised" + * It is tricky to return a correct draft version: such number is primarly + * used to select a proper salt (which depends on the version itself), but + * we don't have a real version here! Let's hope that we need to handle + * only latest drafts... + */ + if ((version & 0x0F0F0F0F) == 0x0a0a0a0a) + return 29; + + return 0; +} + +static inline uint8_t quic_draft_is_max(uint32_t version, uint8_t max_version) +{ + uint8_t draft_version = quic_draft_version(version); + return draft_version && draft_version <= max_version; +} + +/////////////////////////////////////////////////////////////////////////////// +// quic_parse_packet_header() +/////////////////////////////////////////////////////////////////////////////// + +static inline u_char *quic_parse_uint8(const u_char *pos, const u_char *end, uint8_t *out) +{ + if ((size_t)(end - pos) < 1) + { + return NULL; + } + + *out = *pos; + return (u_char *)pos + 1; +} + +static inline u_char *quic_parse_int(const u_char *pos, const u_char *end, uint64_t *out) +{ + u_char *p; + uint64_t value; + int len; + + if (pos >= end) + { + return NULL; + } + + p = (u_char *)pos; + len = 1 << (*p >> 6); + + value = *p++ & 0x3f; + + if ((size_t)(end - p) < (size_t)(len - 1)) + { + return NULL; + } + + while (--len) + { + value = (value << 8) + *p++; + } + + *out = value; + return p; +} + +static inline u_char *quic_parse_uint32(const u_char *pos, const u_char *end, uint32_t *out) +{ + if ((size_t)(end - pos) < sizeof(uint32_t)) + { + return NULL; + } + + *out = ((uint32_t)(pos)[0] << 24 | (pos)[1] << 16 | (pos)[2] << 8 | (pos)[3]); + return (u_char *)pos + sizeof(uint32_t); +} + +static inline u_char *quic_parse_nbytes(const u_char *pos, const u_char *end, size_t len, u_char **out) +{ + if ((size_t)(end - pos) < len) + { + return NULL; + } + + *out = (u_char *)pos; + return (u_char *)pos + len; +} + +static int quic_parse_short_header(quic_dpt_t *dpt, size_t dcid_len) +{ + u_char *p = dpt->pos; + u_char *end = dpt->data + dpt->len; + + if (!(dpt->flags & QUIC_PKT_FIXED_BIT)) + { + LOG_WARN("QUIC fixed bit is not set"); + return -1; + } + + p = quic_parse_nbytes(p, end, dcid_len, &dpt->dcid.data); + if (p == NULL) + { + LOG_WARN("QUIC packet is too small to read dcid"); + return -1; + } + dpt->dcid.len = dcid_len; + + dpt->pos = p; + return 0; +} + +static int quic_parse_long_header(quic_dpt_t *dpt) +{ + uint8_t idlen; + + u_char *p = dpt->pos; + u_char *end = dpt->data + dpt->len; + + // Parser Version + p = quic_parse_uint32(p, end, &dpt->version); + if (p == NULL) + { + LOG_WARN("QUIC packet is too small to read version"); + return -1; + } + + if (!(dpt->flags & QUIC_PKT_FIXED_BIT)) + { + LOG_WARN("QUIC fixed bit is not set"); + return -1; + } + + // Parser DCID + p = quic_parse_uint8(p, end, &idlen); + if (p == NULL) + { + LOG_WARN("QUIC packet is too small to read dcid len"); + return -1; + } + if (idlen > QUIC_MAX_CID_LEN) + { + LOG_WARN("QUIC packet dcid is too long"); + return -1; + } + dpt->dcid.len = idlen; + + p = quic_parse_nbytes(p, end, idlen, &dpt->dcid.data); + if (p == NULL) + { + LOG_WARN("QUIC packet is too small to read dcid"); + return -1; + } + + // Parser SCID + p = quic_parse_uint8(p, end, &idlen); + if (p == NULL) + { + LOG_WARN("QUIC packet is too small to read scid len"); + return -1; + } + if (idlen > QUIC_MAX_CID_LEN) + { + LOG_WARN("QUIC packet scid is too long"); + return -1; + } + + dpt->scid.len = idlen; + + p = quic_parse_nbytes(p, end, idlen, &dpt->scid.data); + if (p == NULL) + { + LOG_WARN("QUIC packet is too small to read scid"); + return -1; + } + + dpt->pos = p; + return 0; +} + +static int quic_parse_long_header_v1(quic_dpt_t *dpt) +{ + uint64_t varint; + + u_char *p = dpt->pos; + u_char *end = (u_char *)dpt->data + dpt->len; + + // ssl_encryption_initial + if (quic_pkt_level_is_initial(dpt->flags)) + { + dpt->level = ssl_encryption_initial; + if (dpt->len < QUIC_MIN_INITIAL_SIZE) + { + LOG_WARN("QUIC UDP datagram is too small for initial packet"); + return -1; + } + + // Parse Token + p = quic_parse_int(p, end, &varint); + if (p == NULL) + { + LOG_WARN("QUIC failed to parse token length"); + return -1; + } + dpt->token.len = varint; + + p = quic_parse_nbytes(p, end, dpt->token.len, &dpt->token.data); + if (p == NULL) + { + LOG_WARN("QUIC packet too small to read token data"); + return -1; + } + } + // ssl_encryption_early_data + else if (quic_pkt_level_is_zrtt(dpt->flags)) + { + dpt->level = ssl_encryption_early_data; + } + // ssl_encryption_handshake + else if (quic_pkt_level_is_handshake(dpt->flags)) + { + dpt->level = ssl_encryption_handshake; + } + else + { + LOG_WARN("QUIC bad packet type"); + return -1; + } + + // Parse Packet Length + p = quic_parse_int(p, end, &varint); + if (p == NULL) + { + LOG_WARN("QUIC bad packet length"); + return -1; + } + dpt->pkt_len = varint; + + if (varint > (uint64_t)((dpt->data + dpt->len) - p)) + { + LOG_WARN("QUIC truncated packet with level %s", quic_pkt_level_to_name(dpt->level)); + return -1; + } + + dpt->pos = p; + dpt->len = p + varint - dpt->data; + + return 0; +} + +static int quic_parse_packet_header(quic_dpt_t *dpt) +{ + if (quic_pkt_header_is_short(dpt->flags)) + { + dpt->header_type = SHORT; + dpt->level = ssl_encryption_application; + + // Parser DCID + if (quic_parse_short_header(dpt, QUIC_MAX_CID_LEN) != 0) + { + return -1; + } + + return 0; + } + + dpt->header_type = LONG; + + // Parser Version, DCID, SCID + if (quic_parse_long_header(dpt) != 0) + { + return -1; + } + + // Check QUIC Version + if (!quic_version_is_supported(dpt->version)) + { + LOG_WARN("QUIC version %08" PRIx32 "unsupport", dpt->version); + return -1; + } + + // Parser Level, Token, Packet Length + if (quic_parse_long_header_v1(dpt) != 0) + { + return -1; + } + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// quic_keys_set_initial_secret() +/////////////////////////////////////////////////////////////////////////////// + +static int hkdf_expand(quic_str_t *out, const EVP_MD *digest, const quic_str_t *prk, const quic_str_t *info) +{ + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + if (pctx == NULL) + { + LOG_ERROR("EVP_PKEY_CTX_new_id() failed"); + return -1; + } + + if (EVP_PKEY_derive_init(pctx) <= 0) + { + LOG_ERROR("EVP_PKEY_derive_init() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_hkdf_mode() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_set_hkdf_md() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_set1_hkdf_key(pctx, prk->data, prk->len) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_set1_hkdf_key() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info->data, info->len) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_add1_hkdf_info() failed"); + goto failed; + } + + if (EVP_PKEY_derive(pctx, out->data, &(out->len)) <= 0) + { + LOG_ERROR("EVP_PKEY_derive() failed"); + goto failed; + } + + EVP_PKEY_CTX_free(pctx); + return 0; + +failed: + + EVP_PKEY_CTX_free(pctx); + return -1; +} + +static int quic_hkdf_expand(const EVP_MD *digest, quic_str_t *out, const quic_str_t *label, const quic_str_t *prk) +{ + uint8_t info_buf[20]; + info_buf[0] = 0; + info_buf[1] = out->len; + info_buf[2] = label->len; + + uint8_t *p = (u_char *)memcpy(&info_buf[3], label->data, label->len) + label->len; + *p = '\0'; + + quic_str_t info; + info.len = 2 + 1 + label->len + 1; + info.data = info_buf; + + if (hkdf_expand(out, digest, prk, &info) != 0) + { + return -1; + } + + return 0; +} + +static int hkdf_extract(quic_str_t *out, const EVP_MD *digest, const quic_str_t *secret, const quic_str_t *initial_salt) +{ + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + if (pctx == NULL) + { + LOG_ERROR("EVP_PKEY_CTX_new_id() failed"); + return -1; + } + + if (EVP_PKEY_derive_init(pctx) <= 0) + { + LOG_ERROR("EVP_PKEY_derive_init() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_hkdf_mode() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_set_hkdf_md() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret->data, secret->len) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_set1_hkdf_key() failed"); + goto failed; + } + + if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, initial_salt->data, initial_salt->len) <= 0) + { + LOG_ERROR("EVP_PKEY_CTX_set1_hkdf_salt() failed"); + goto failed; + } + + if (EVP_PKEY_derive(pctx, out->data, &(out->len)) <= 0) + { + LOG_ERROR("EVP_PKEY_derive() failed"); + goto failed; + } + + EVP_PKEY_CTX_free(pctx); + return 0; + +failed: + + EVP_PKEY_CTX_free(pctx); + return -1; +} + +static int quic_keys_set_initial_secret(quic_secret_t *client_secret, const quic_str_t *dcid, uint32_t version) +{ + unsigned int i; + const quic_str_t initial_salt_v1 = quic_string( + "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a"); + const quic_str_t initial_salt_draft_22 = quic_string( + "\x7f\xbc\xdb\x0e\x7c\x66\xbb\xe9\x19\x3a\x96\xcd\x21\x51\x9e\xbd\x7a\x02\x64\x4a"); + const quic_str_t initial_salt_draft_23 = quic_string( + "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02"); + const quic_str_t initial_salt_draft_29 = quic_string( + "\xaf\xbf\xec\x28\x99\x93\xd2\x4c\x9e\x97\x86\xf1\x9c\x61\x11\xe0\x43\x90\xa8\x99"); + const quic_str_t initial_salt_draft_q50 = quic_string( + "\x50\x45\x74\xEF\xD0\x66\xFE\x2F\x9D\x94\x5C\xFC\xDB\xD3\xA7\xF0\xD3\xB5\x6B\x45"); + const quic_str_t initial_salt_draft_t50 = quic_string( + "\x7f\xf5\x79\xe5\xac\xd0\x72\x91\x55\x80\x30\x4c\x43\xa2\x36\x7c\x60\x48\x83\x10"); + const quic_str_t initial_salt_draft_t51 = quic_string( + "\x7a\x4e\xde\xf4\xe7\xcc\xee\x5f\xa4\x50\x6c\x19\x12\x4f\xc8\xcc\xda\x6e\x03\x3d"); + + const quic_str_t *initial_salt; + if (version == 0x51303530) + { + initial_salt = &initial_salt_draft_q50; + } + else if (version == 0x54303530) + { + initial_salt = &initial_salt_draft_t50; + } + else if (version == 0x54303531) + { + initial_salt = &initial_salt_draft_t51; + } + else if (quic_draft_is_max(version, 22)) + { + initial_salt = &initial_salt_draft_22; + } + else if (quic_draft_is_max(version, 28)) + { + initial_salt = &initial_salt_draft_23; + } + else if (quic_draft_is_max(version, 32)) + { + initial_salt = &initial_salt_draft_29; + } + else + { + initial_salt = &initial_salt_v1; + } + + /* + * RFC 9001, section 5. Packet Protection + * + * Initial packets use AEAD_AES_128_GCM. The hash function + * for HKDF when deriving initial secrets and keys is SHA-256. + */ + const EVP_MD *digest = EVP_sha256(); + + uint8_t is[SHA256_DIGEST_LENGTH] = {0}; + quic_str_t initial_secret; + initial_secret.data = is; + initial_secret.len = SHA256_DIGEST_LENGTH; + + // Use dcid and initial_salt get initial_secret + if (hkdf_extract(&initial_secret, digest, dcid, initial_salt) != 0) + { + return -1; + } + + struct + { + quic_str_t label; + quic_str_t *key; + quic_str_t *prk; + } seq[] = { + /* labels per RFC 9001, 5.1. Packet Protection Keys */ + {quic_string("tls13 client in"), &client_secret->secret, &initial_secret}, + {quic_string("tls13 quic key"), &client_secret->key, &client_secret->secret}, + {quic_string("tls13 quic iv"), &client_secret->iv, &client_secret->secret}, + {quic_string("tls13 quic hp"), &client_secret->hp, &client_secret->secret}, + }; + + for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) + { + if (quic_hkdf_expand(digest, seq[i].key, &seq[i].label, seq[i].prk) != 0) + { + return -1; + } + } + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// quic_deprotection_packet() +/////////////////////////////////////////////////////////////////////////////// + +static int quic_deprotection_header(const EVP_CIPHER *cipher, const quic_secret_t *secret, u_char *out, const u_char *in) +{ + int outlen; + u_char zero[QUIC_HP_LEN] = {0}; + + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + { + return -1; + } + + if (EVP_EncryptInit_ex(ctx, cipher, NULL, secret->hp.data, in) != 1) + { + LOG_ERROR("EVP_EncryptInit_ex() failed"); + goto failed; + } + + if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, QUIC_HP_LEN)) + { + LOG_ERROR("EVP_EncryptUpdate() failed"); + goto failed; + } + + if (!EVP_EncryptFinal_ex(ctx, out + QUIC_HP_LEN, &outlen)) + { + LOG_ERROR("EVP_EncryptFinal_ex() failed"); + goto failed; + } + + EVP_CIPHER_CTX_free(ctx); + return 0; + +failed: + + EVP_CIPHER_CTX_free(ctx); + return -1; +} + +static uint64_t quic_deprotection_pktnum(u_char **pos, int len, const u_char *mask, uint64_t *largest_pkt_num) +{ + u_char *p; + uint64_t truncated_pn, expected_pn, candidate_pn; + uint64_t pn_nbits, pn_win, pn_hwin, pn_mask; + + pn_nbits = MIN(len * 8, 62); + + p = *pos; + truncated_pn = *p++ ^ *mask++; + + while (--len) + { + truncated_pn = (truncated_pn << 8) + (*p++ ^ *mask++); + } + + *pos = p; + + expected_pn = *largest_pkt_num + 1; + pn_win = 1ULL << pn_nbits; + pn_hwin = pn_win / 2; + pn_mask = pn_win - 1; + + candidate_pn = (expected_pn & ~pn_mask) | truncated_pn; + + if ((int64_t)candidate_pn <= (int64_t)(expected_pn - pn_hwin) && candidate_pn < (1ULL << 62) - pn_win) + { + candidate_pn += pn_win; + } + else if (candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win) + { + candidate_pn -= pn_win; + } + + *largest_pkt_num = MAX((int64_t)*largest_pkt_num, (int64_t)candidate_pn); + + return candidate_pn; +} + +static void quic_deprotection_nonce(u_char *nonce, size_t len, uint64_t pkt_num) +{ + nonce[len - 4] ^= (pkt_num & 0xff000000) >> 24; + nonce[len - 3] ^= (pkt_num & 0x00ff0000) >> 16; + nonce[len - 2] ^= (pkt_num & 0x0000ff00) >> 8; + nonce[len - 1] ^= (pkt_num & 0x000000ff); +} + +static int quic_deprotection_payload(const EVP_CIPHER *cipher, const quic_secret_t *secret, quic_str_t *out, const u_char *nonce, const quic_str_t *in, const quic_str_t *ad) +{ + int len; + u_char *tag; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + { + LOG_ERROR("EVP_CIPHER_CTX_new() failed"); + return -1; + } + + if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_DecryptInit_ex() failed"); + return -1; + } + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, secret->iv.len, NULL) == 0) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed"); + return -1; + } + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, secret->key.data, nonce) != 1) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_DecryptInit_ex() failed"); + return -1; + } + + if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_DecryptUpdate() failed"); + return -1; + } + + if (EVP_DecryptUpdate(ctx, out->data, &len, in->data, in->len - EVP_GCM_TLS_TAG_LEN) != 1) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_DecryptUpdate() failed"); + return -1; + } + + out->len = len; + tag = in->data + in->len - EVP_GCM_TLS_TAG_LEN; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag) == 0) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_TAG) failed"); + return -1; + } + + if (EVP_DecryptFinal_ex(ctx, out->data + len, &len) <= 0) + { + EVP_CIPHER_CTX_free(ctx); + LOG_ERROR("EVP_DecryptFinal_ex failed"); + return -1; + } + + out->len += len; + EVP_CIPHER_CTX_free(ctx); + + return 0; +} + +static int quic_deprotection_packet(quic_dpt_t *dpt) +{ + u_char *p, *sample; + size_t len; + uint64_t pkt_num, lpn; + int pnl, rc, key_phase; + quic_str_t in, ad; + uint8_t nonce[QUIC_IV_LEN] = {0}, mask[QUIC_HP_LEN] = {0}; + + // Init ciphers, only process the quic package whose level is init, so only use AES_128_GCM_SHA256 + quic_ciphers_t ciphers; + ciphers.c = EVP_aes_128_gcm(); + ciphers.hp = EVP_aes_128_ctr(); + ciphers.d = EVP_sha256(); + + // 使用 client_secret secrets + quic_secret_t *secret = &dpt->client_secret; + + p = dpt->pos; + len = dpt->data + dpt->len - p; + + /* + * RFC 9001, 5.4.2. Header Protection Sample + * 5.4.3. AES-Based Header Protection + * 5.4.4. ChaCha20-Based Header Protection + * + * the Packet Number field is assumed to be 4 bytes long + * AES and ChaCha20 algorithms sample 16 bytes + */ + + if (len < EVP_GCM_TLS_TAG_LEN + 4) + { + LOG_WARN("QUIC payload length %zu too small", len); + return -1; + } + + sample = p + 4; + + /****************************************************** + * header protection + ******************************************************/ + + // Use the ciphers.hp algorithm and the secret.HP to encrypt the data in the sample and store it in the mask + if (quic_deprotection_header(ciphers.hp, secret, mask, sample) != 0) + { + return -1; + } + + // Parse Flags After Decode + dpt->flags ^= mask[0] & quic_pkt_hp_mask(dpt->flags); + + if (quic_pkt_header_is_short(dpt->flags)) + { + key_phase = (dpt->flags & QUIC_PKT_KPHASE) != 0; + + if (key_phase != dpt->key_phase) + { + // TODO + LOG_WARN("key need update !!!!"); + } + } + + lpn = dpt->largest_pkt_num; + + // RFC pn_length = (packet[0] & 0x03) + 1 + // Parser Packet Number length + pnl = (dpt->flags & 0x03) + 1; + + // Parser Packet number + pkt_num = quic_deprotection_pktnum(&p, pnl, &mask[1], &lpn); + dpt->pkt_num = pkt_num; + + /****************************************************** + * packet protection + ******************************************************/ + + in.data = p; + in.len = len - pnl; + + ad.len = p - dpt->data; + ad.data = dpt->plaintext; + + memcpy(ad.data, dpt->data, ad.len); + ad.data[0] = dpt->flags; + + do + { + ad.data[ad.len - pnl] = pkt_num >> (8 * (pnl - 1)) % 256; + } while (--pnl); + + memcpy(nonce, secret->iv.data, secret->iv.len); + quic_deprotection_nonce(nonce, sizeof(nonce), pkt_num); + + dpt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN; + dpt->payload.data = dpt->plaintext + ad.len; + + // Parser payload + rc = quic_deprotection_payload(ciphers.c, secret, &dpt->payload, nonce, &in, &ad); + if (rc != 0) + { + return -1; + } + + if (dpt->payload.len == 0) + { + /* + * RFC 9000, 12.4. Frames and Frame Types + * + * An endpoint MUST treat receipt of a packet containing no + * frames as a connection error of type PROTOCOL_VIOLATION. + */ + LOG_WARN("QUIC zero-length packet"); + return -1; + } + + if (dpt->flags & quic_pkt_rb_mask(dpt->flags)) + { + /* + * RFC 9000, Reserved Bits + * + * An endpoint MUST treat receipt of a packet that has + * a non-zero value for these bits, after removing both + * packet and header protection, as a connection error + * of type PROTOCOL_VIOLATION. + */ + LOG_WARN("QUIC reserved bit set in packet"); + return -1; + } + + // Set Largest Packet Number + dpt->largest_pkt_num = lpn; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// debug +/////////////////////////////////////////////////////////////////////////////// + +static void quic_str_to_hex(u_char *data, size_t len) +{ + for (unsigned int i = 0; i < len; i++) + { + printf("%02x", data[i]); + } + printf("\n"); +} + +static u_char *quic_version_to_str(uint32_t version) +{ + unsigned int i = 0; + for (i = 0; i < QUIC_NVERSIONS; i++) + { + if (quic_version_vals[i].len == version) + { + return quic_version_vals[i].data; + } + } + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +// PUB API +/////////////////////////////////////////////////////////////////////////////// + +quic_dpt_t *quic_deprotection_new(void) +{ + quic_dpt_t *dpt = (quic_dpt_t *)calloc(1, sizeof(quic_dpt_t)); + + // Allocate the space of length len + 1, instead of allocating the space of length len, mainly for the convenience of debugging printf + dpt->client_secret.secret.len = SHA256_DIGEST_LENGTH; + dpt->client_secret.secret.data = (u_char *)calloc(SHA256_DIGEST_LENGTH + 1, sizeof(u_char)); + + dpt->client_secret.key.len = QUIC_AES_128_KEY_LEN; + dpt->client_secret.key.data = (u_char *)calloc(QUIC_AES_128_KEY_LEN + 1, sizeof(u_char)); + + dpt->client_secret.hp.len = QUIC_AES_128_KEY_LEN; + dpt->client_secret.hp.data = (u_char *)calloc(QUIC_AES_128_KEY_LEN + 1, sizeof(u_char)); + + dpt->client_secret.iv.len = QUIC_IV_LEN; + dpt->client_secret.iv.data = (u_char *)calloc(QUIC_IV_LEN + 1, sizeof(u_char)); + + // NOTE: QUIC_MAX_UDP_PAYLOAD_SIZE is 65527(form Nginx-quice offical) + dpt->plaintext = (u_char *)calloc(QUIC_MAX_UDP_PAYLOAD_SIZE + 1, sizeof(u_char)); + + return dpt; +} + +void quic_deprotection_free(quic_dpt_t *dpt) +{ + if (dpt == NULL) + { + return; + } + + if (dpt->client_secret.secret.data) + { + free(dpt->client_secret.secret.data); + dpt->client_secret.secret.data = NULL; + dpt->client_secret.secret.len = 0; + } + + if (dpt->client_secret.key.data) + { + free(dpt->client_secret.key.data); + dpt->client_secret.key.data = NULL; + dpt->client_secret.key.len = 0; + } + + if (dpt->client_secret.hp.data) + { + free(dpt->client_secret.hp.data); + dpt->client_secret.hp.data = NULL; + dpt->client_secret.hp.len = 0; + } + + if (dpt->client_secret.iv.data) + { + free(dpt->client_secret.iv.data); + dpt->client_secret.iv.data = NULL; + dpt->client_secret.iv.len = 0; + } + + if (dpt->plaintext) + { + free(dpt->plaintext); + dpt->plaintext = NULL; + } + + free(dpt); + dpt = NULL; +} + +void quic_deprotection_dump(quic_dpt_t *dpt) +{ + printf("QUIC version : %08" PRIx32 " %s\n", dpt->version, quic_version_to_str(dpt->version)); + printf("QUIC type : %s\n", dpt->header_type == LONG ? "long" : "short"); + printf("QUIC level : %s\n", quic_pkt_level_to_name(dpt->level)); + printf("QUIC flags : %x\n", dpt->flags); + printf("QUIC num : %" PRIu64 "\n", dpt->pkt_num); + printf("QUIC len : %" PRIu64 "\n", dpt->pkt_len); + printf("QUIC larg_num : %" PRIu64 "\n", dpt->largest_pkt_num); + + printf("QUIC dcid : %zu, ", dpt->dcid.len); + quic_str_to_hex(dpt->dcid.data, dpt->dcid.len); + + printf("QUIC scid : %zu, ", dpt->scid.len); + quic_str_to_hex(dpt->scid.data, dpt->scid.len); + + printf("QUIC token : %zu, ", dpt->token.len); + quic_str_to_hex(dpt->token.data, dpt->token.len); + + printf("QUIC hp : %zu, ", dpt->client_secret.hp.len); + quic_str_to_hex(dpt->client_secret.hp.data, dpt->client_secret.hp.len); + + printf("QUIC iv : %zu, ", dpt->client_secret.iv.len); + quic_str_to_hex(dpt->client_secret.iv.data, dpt->client_secret.iv.len); + + printf("QUIC key : %zu, ", dpt->client_secret.key.len); + quic_str_to_hex(dpt->client_secret.key.data, dpt->client_secret.key.len); + + printf("QUIC secretn : %zu, ", dpt->client_secret.secret.len); + quic_str_to_hex(dpt->client_secret.secret.data, dpt->client_secret.secret.len); + + printf("QUIC plaintex : %zu, ", strlen((char *)dpt->plaintext)); + quic_str_to_hex(dpt->plaintext, strlen((char *)dpt->plaintext)); + + printf("QUIC payload : %zu, ", dpt->payload.len); + quic_str_to_hex(dpt->payload.data, dpt->payload.len); +} + +int quic_deprotection(quic_dpt_t *dpt, const u_char *payload, size_t payload_len) +{ + dpt->data = (u_char *)payload; + dpt->len = payload_len; + dpt->pos = (u_char *)dpt->data; + dpt->flags = payload[0]; + dpt->pos++; + dpt->largest_pkt_num = QUIC_UNSET_PN; + + // Parser Level, Version, DCID, SCID, Token, Packet Length + if (quic_parse_packet_header(dpt) == -1) + { + return -1; + } + + if (dpt->level != ssl_encryption_initial) + { + LOG_WARN("QUIC level %s ignoring", quic_pkt_level_to_name(dpt->level)) + return -1; + } + + /* + * 1.Get the initial_salt to be used through pkt_version + * 2.DCID and initial_salt generate initial_secret through SHA-256 + * 3.IN/Key/IV/HP lable of initial_secret and client_secret generates HP/Key/IV key of client_secret + */ + if (quic_keys_set_initial_secret(&dpt->client_secret, &dpt->dcid, dpt->version) == -1) + { + goto failed; + } + + if (dpt->client_secret.key.len == 0) + { + LOG_WARN("QUIC packet no client_secret, ignoring"); + goto failed; + } + + if (quic_deprotection_packet(dpt) == -1) + { + goto failed; + } + + // deprotection data: dpt->payload.data + + return 0; + +failed: + + return -1; +}
\ No newline at end of file diff --git a/src/quic_deprotection.h b/src/quic_deprotection.h new file mode 100644 index 0000000..11c0d03 --- /dev/null +++ b/src/quic_deprotection.h @@ -0,0 +1,116 @@ +#ifndef _QUIC_DEPROTECTION_H +#define _QUIC_DEPROTECTION_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/stat.h> +#include <arpa/inet.h> + +#ifdef DEBUG_SWITCH + +#define LOG_DEBUG(format, ...) \ + { \ + fprintf(stdout, format "\n", ##__VA_ARGS__); \ + fflush(stdout); \ + } + +#define LOG_WARN(format, ...) \ + { \ + fprintf(stderr, format "\n", ##__VA_ARGS__); \ + fflush(stderr); \ + } + +#define LOG_ERROR(format, ...) \ + { \ + fprintf(stderr, format "\n", ##__VA_ARGS__); \ + fflush(stderr); \ + } + +#else + +#define LOG_DEBUG(format, ...) +#define LOG_WARN(format, ...) +#define LOG_ERROR(format, ...) + +#endif + +#define QUIC_MAX_UDP_PAYLOAD_SIZE 1460 + +#define quic_string(str) \ + { \ + sizeof(str) - 1, (u_char *)str \ + } + +typedef struct +{ + size_t len; + u_char *data; +} quic_str_t; + +typedef struct quic_secret_s +{ + quic_str_t secret; + quic_str_t key; + quic_str_t iv; + quic_str_t hp; +} quic_secret_t; + +typedef enum +{ + ssl_encryption_initial = 0, + ssl_encryption_early_data = 1, + ssl_encryption_handshake = 2, + ssl_encryption_application = 3, +} ssl_encryption_level_t; + +typedef enum +{ + LONG = 0, + SHORT = 1, +} quic_header_type; + +typedef struct +{ + quic_secret_t client_secret; + ssl_encryption_level_t level; // QUIC Packet Process Level + quic_header_type header_type; // QUIC Packet Header Type + + uint32_t version; // QUIC Version + uint8_t flags; // QUIC Flags + u_char *data; // QUIC Packet Data + size_t len; // QUIC Packet Length + u_char *pos; // Process Ptr + uint64_t largest_pkt_num; + + quic_str_t dcid; // QUIC DCID + quic_str_t scid; // QUIC SCID + quic_str_t token; // QUIC TOKEN + + size_t pkt_len; + uint64_t pkt_num; // QUIC Packet Number + u_char *plaintext; + quic_str_t payload; // Decrypted data + + unsigned key_phase : 1; +} quic_dpt_t; + +quic_dpt_t *quic_deprotection_new(void); +void quic_deprotection_free(quic_dpt_t *dpt); +void quic_deprotection_dump(quic_dpt_t *dpt); +int quic_deprotection(quic_dpt_t *dpt, const u_char *payload, size_t payload_len); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/src/quic_entry.cpp b/src/quic_entry.cpp new file mode 100644 index 0000000..d8cae1b --- /dev/null +++ b/src/quic_entry.cpp @@ -0,0 +1,233 @@ +#include <stdio.h> +#include <assert.h> +#include <MESA/MESA_prof_load.h> +#include <MESA/MESA_handle_logger.h> + +#include "quic_decoder.h" +#include "quic_entry.h" +#include "quic_process.h" +#include "quic_deprotection.h" +#include "quic_util.h" + +static const char *g_quic_proto_conffile="./conf/quic_decoder/main.conf"; +// static const char *g_quic_regionname_conffile="./conf/quic/quic.conf"; +static const char *g_quic_log_path = "./log/quic_decoder/quic_decoder"; +#ifdef __cplusplus +extern "C" +{ +#endif +#include <stellar/stellar.h> +#include <stellar/session.h> +#include <stellar/session_mq.h> +#include <stellar/session_exdata.h> + +#define GIT_VERSION_CATTER(v) __attribute__((__used__)) const char * GIT_VERSION_##v = NULL +#define GIT_VERSION_EXPEND(v) GIT_VERSION_CATTER(v) + +/* VERSION TAG */ +#ifdef GIT_VERSION +GIT_VERSION_EXPEND(GIT_VERSION); +#else +static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL; +#endif +#undef GIT_VERSION_CATTER +#undef GIT_VERSION_EXPEND + +#ifdef __cplusplus +} +#endif + +static int parse_quic_port(char *port_list, unsigned short *quic_port, int quic_port_num) +{ + int i=0,ret=0; + int port_num=0; + int range_len=0,used_len=0; + char buf[256]={0}; + unsigned short s_port=0,e_port=0; + char *begin=NULL,*end=NULL,*pchr=NULL; + + if(port_list==NULL) + { + return 0; + } + + begin=port_list; + end=NULL; + range_len=strlen(port_list); + + while(range_len>used_len) + { + end=index(begin, ';'); + if(end==NULL) + { + end=begin+range_len-used_len; + } + + if(end==begin) + { + break; + } + + memset(buf, 0, sizeof(buf)); + strncpy(buf, begin, end-begin); + used_len+=end-begin+1; + if(range_len>used_len) + { + begin=end+1; + } + + pchr=strchr(buf, '-'); + if(pchr == NULL) + { + s_port=(unsigned short)atoi(buf); + e_port=s_port; + + } + else + { + ret=sscanf(buf, "%hu-%hu", &s_port, &e_port); + if(ret!=2) + { + continue; + } + } + + for(i=s_port; i<=e_port && port_num<quic_port_num; i++) + { + quic_port[port_num++]= htons((unsigned short)i); + } + } + + return port_num; +} + +static void free_quicinfo(struct quic_info *quic_info) +{ + if(quic_info->sni.iov_base) + FREE(quic_info->sni.iov_base); + + if(quic_info->user_agent.iov_base) + FREE(quic_info->user_agent.iov_base); + return ; +} + +extern "C" void quic_on_session_msg_cb(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env) +{ + struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env; + struct quic_context *context = (struct quic_context *)per_session_ctx; + + int thread_seq = session_get_current_thread_id(sess); + const char *payload = NULL; + size_t payload_len = -1; + + enum session_state sstate = session_get_current_state(sess); + if(sstate == SESSION_STATE_CLOSING) + { + return; + } + + payload = session_get0_current_payload(sess, &payload_len); + if(NULL == payload || payload_len <= 0) + { + return; + } + quic_analyze_entry(sess, quic_plugin_env, context, thread_seq, payload, payload_len); + + return; +} + +void *quic_session_ctx_new_cb(struct session *sess, void *plugin_env) +{ + struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env; + if(0 == quic_protocol_identify(sess, quic_plugin_env)) + { + stellar_session_plugin_dettach_current_session(sess); + return NULL; + } + size_t payload_len = 0; + const char * payload = session_get0_current_payload(sess, &payload_len); + if(NULL == payload || payload_len <= 0) + { + stellar_session_plugin_dettach_current_session(sess); + return NULL; + } + int payload_offset = 0; + enum QUIC_VERSION_T quic_ver = is_quic_protocol(payload, payload_len, &payload_offset); + if(QUIC_VERSION_UNKNOWN == quic_ver || (size_t)payload_offset > payload_len) + { + stellar_session_plugin_dettach_current_session(sess); + return NULL; + } + struct quic_context *qcontext = (struct quic_context *)CALLOC(1, sizeof(struct quic_context)); + qcontext->quic_info.quic_version = (unsigned int )quic_ver; + return (void *)qcontext; +} + +void quic_session_ctx_free_cb(struct session *sess, void *session_ctx, void *plugin_env) +{ + if(session_ctx){ + struct quic_context *qcontext = (struct quic_context *)session_ctx; + free_quicinfo(&qcontext->quic_info); + if(qcontext->quic_buf.buffer){ + free(qcontext->quic_buf.buffer); + } + FREE(session_ctx); + } + return; +} + +void quic_session_exdata_free_cb(struct session *sess, int idx, void *ex_ptr, void *arg) +{ + return; +} + +void quic_msg_free_cb(struct session *sess, void *msg, void *msg_free_arg) +{ + FREE(msg); +} + +extern "C" void *QUIC_ONLOAD(struct stellar *st) +{ + char buff[2048]={0}; + + struct quic_param *quic_plugin_env = (struct quic_param *)CALLOC(1, sizeof(struct quic_param)); + quic_plugin_env->st = st; + + MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "LOG_LEVEL", &quic_plugin_env->level, RLOG_LV_FATAL); + MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "LOG_PATH", quic_plugin_env->log_path, sizeof(quic_plugin_env->log_path), g_quic_log_path); + + MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "DECRYPTED_SWITCH", &quic_plugin_env->decrypted_switch, 2); + // MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "MAX_PARSE_PKT_NUM", &quic_plugin_env->max_parse_pkt_num, 3); + MESA_load_profile_int_def(g_quic_proto_conffile, "QUIC", "MAX_CHLO_SIZE", &quic_plugin_env->max_chlo_size, 4096); + + MESA_load_profile_string_def(g_quic_proto_conffile, "QUIC", "QUIC_PORT_LIST", buff, sizeof(buff), "443;8443;"); + quic_plugin_env->quic_port_num=parse_quic_port(buff, quic_plugin_env->quic_port_list, SUPPORT_QUIC_PORT_NUM); + + quic_plugin_env->logger=MESA_create_runtime_log_handle(quic_plugin_env->log_path, quic_plugin_env->level); + if(quic_plugin_env->logger==NULL) + { + fprintf(stderr, "MESA_create_runtime_log_handle failed, level: %d log_path: %s", quic_plugin_env->level, quic_plugin_env->log_path); + return NULL; + } + + quic_plugin_env->quic_plugid = stellar_session_plugin_register(st, quic_session_ctx_new_cb, quic_session_ctx_free_cb, quic_plugin_env); + assert(quic_plugin_env->quic_plugid >= 0); + + quic_plugin_env->exdata_id=stellar_session_exdata_new_index(st, "QUIC_EXDATA", quic_session_exdata_free_cb, quic_plugin_env); + assert(quic_plugin_env->exdata_id >= 0); + quic_plugin_env->udp_topic_id=stellar_session_mq_get_topic_id(st, TOPIC_UDP); + assert(quic_plugin_env->udp_topic_id >= 0); + stellar_session_mq_subscribe(st, quic_plugin_env->udp_topic_id, quic_on_session_msg_cb, quic_plugin_env->quic_plugid); + + quic_plugin_env->quic_topic_id=stellar_session_mq_create_topic(st, QUIC_DECODER_TOPIC, quic_msg_free_cb, quic_plugin_env); + assert(quic_plugin_env->quic_topic_id >= 0); + return (void *)quic_plugin_env; +} + +extern "C" void QUIC_UNLOAD(void *plugin_env) +{ + struct quic_param *quic_plugin_env = (struct quic_param *)plugin_env; + MESA_destroy_runtime_log_handle(quic_plugin_env->logger); + FREE(plugin_env); + return; +}
\ No newline at end of file diff --git a/src/quic_entry.h b/src/quic_entry.h new file mode 100644 index 0000000..478b2d9 --- /dev/null +++ b/src/quic_entry.h @@ -0,0 +1,58 @@ +#pragma once + +#include "quic_decoder.h" +#include <bits/types/struct_iovec.h> +typedef struct iovec qstring; + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#define FALSE 0x00 +#define TRUE 0x01 +#define MAYBE 0x02 + +#define QUIC_VERSION_STRING_MAX_SIZE (32) + +#define SUPPORT_QUIC_PORT_NUM 128 + +#define QUIC_HALF_CLOSE 0x01 +#define QUIC_WHOLE_CLOSE 0x02 +#define QUIC_DATA 0x03 +#define QUIC_KEY 1 +#define QUIC_RETURN_NORM 0x60 +#define QUIC_RETURN_UNNORM 0x61 +#define QUIC_RETURN_RESET_BUFFER 0x62 +#define QUIC_RETURN_DROPME 0x63 +#define MAX_REGION_NUM 15 +#define REGION_NAME_LEN 32 + +struct quic_param +{ + struct stellar *st; + int quic_plugid; + int level; + int quic_port_num; + int decrypted_switch; + // int max_parse_pkt_num; + int max_chlo_size; + // int context_bridge_id; + int exdata_id; + int udp_topic_id; //as subscriber + int quic_topic_id; //as publisher + unsigned short quic_port_list[SUPPORT_QUIC_PORT_NUM]; //network order + char quic_conf_regionname[MAX_REGION_NUM][REGION_NAME_LEN]; + char log_path[128]; + void *logger; +}; + +enum quic_mes_type{ + VER_NEGO = 0, //vertion negotiation packet + PUB_RST, //public reset packet + FRAME, //frame packet + FEC, //FEC packet + Initial, //iquic + Retey, //iquic + Handshake, //iquic + MSG_UNKNOWN = 255 +}; diff --git a/src/quic_header.h b/src/quic_header.h new file mode 100644 index 0000000..34a7cd1 --- /dev/null +++ b/src/quic_header.h @@ -0,0 +1,35 @@ +#pragma once + +#define QUIC_IS_LONG_HEADER(c) (c & 0x80) +#define QUIC_IS_FIXED_BIT(c) (c & 0x40) + +#define QUIC_PKT_TYPE_INITIAL 0x00 +#define QUIC_PKT_TYPE_0RTT 0x01 +#define QUIC_PKT_TYPE_HANDSHAKE 0x02 +#define QUIC_PKT_TYPE_RETRY 0x03 + +// https://www.rfc-editor.org/rfc/rfc9000.html#name-long-header-packets +struct quic_long_header{ + unsigned char type_specific_bit:4; + unsigned char packet_type:2; + unsigned char fixed_bit:1; + unsigned char header_form:1; + unsigned int version; +}__attribute__((packed)); + +// https://www.rfc-editor.org/rfc/rfc9000.html#name-initial-packet +struct quic_initial_pkt_header{ + unsigned char packet_number_length:2; + unsigned char reserved_bits:2; + unsigned char packet_type:2; + unsigned char fixed_bit:1; + unsigned char header_form:1; + unsigned int version; +}__attribute__((packed)); + +struct quic_short_header{ + unsigned char toto:5; + unsigned char spin_bit:1; + unsigned char fixed_bit:1; + unsigned char header_form:1; +}__attribute__((packed));
\ No newline at end of file diff --git a/src/quic_process.cpp b/src/quic_process.cpp new file mode 100644 index 0000000..3f94ad7 --- /dev/null +++ b/src/quic_process.cpp @@ -0,0 +1,1010 @@ +#include <stdio.h> +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <sys/time.h> +#include <arpa/inet.h> +#include <MESA/MESA_handle_logger.h> +#include "quic_entry.h" +#include "quic_process.h" +#include "quic_deprotection.h" +#include "quic_header.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "quic_util.h" +#include <stellar/stellar.h> +#include <stellar/session.h> +#include <stellar/session_mq.h> +#include <stellar/session_exdata.h> +#ifdef __cplusplus +} +#endif + +struct quic_client_hello_msg_hdr +{ + uint8_t handshake_type; + uint8_t client_hello_len[3]; + uint16_t tls_version; + uint8_t random[32]; +}; + +static int check_port(const struct quic_param *quic_plugin_env, unsigned short port) +{ + for (int i = 0; i < quic_plugin_env->quic_port_num; i++) + { + if (quic_plugin_env->quic_port_list[i] == port) + { + return 1; + } + } + return 0; +} + +int quic_protocol_identify(struct session *sess, struct quic_param *quic_plugin_env) +{ + enum session_addr_type addr_type; + struct session_addr *saddr = session_get0_addr(sess, &addr_type); + unsigned short sport, dport; + if (addr_type == SESSION_ADDR_TYPE_IPV4_UDP) + { + sport = saddr->ipv4.sport; + dport = saddr->ipv4.dport; + } + else if (addr_type == SESSION_ADDR_TYPE_IPV6_UDP) + { + sport = saddr->ipv6.sport; + dport = saddr->ipv6.dport; + } + else + { + return 0; + } + if (0 == (check_port(quic_plugin_env, sport) || check_port(quic_plugin_env, dport))) + { + return 0; + } + return 1; +} + +static int gquic_pkn_bit2length(unsigned char bit_value) +{ + switch(bit_value) + { + case 0x30: return 6; + case 0x20: return 4; + case 0x10: return 2; + default: + return 1; + } + + return 1; +} + +/* + for quic , the decrypted payload store in quic_dpt_t, will be freed after quic_decrypting_payload(), + so we need to malloc memory and copy them to quic_info. +*/ +#if 1 +static int copy_extension_tag(const unsigned char *tag_start_pos, int tag_len, qstring *out) +{ + if(tag_start_pos!=NULL && tag_len>0) + { + if(out->iov_base!=NULL) + { + FREE(out->iov_base); + } + + out->iov_base=CALLOC(1, tag_len+1); + memcpy((void *)out->iov_base, tag_start_pos, tag_len); + out->iov_len = tag_len; + + return tag_len; + } + + return 0; +} +#else +static int quic_extension_tag_get0(const unsigned char *tag_start_pos, int tag_len, qstring *out) +{ + if(tag_start_pos!=NULL && tag_len>0) + { + out->iov_len = tag_len; + out->iov_base = (void *)tag_start_pos; + return tag_len; + } + return 0; +} +#endif + +//Source: https://wise2.ipac.caltech.edu/staff/slw/docs/html/varint_8h_source.html +static int msb2_varint_decode(const unsigned char *buf, long *out) +{ + unsigned long val = buf[0] & 0x3f; + unsigned int nfollow = 1<<(buf[0]>>6); + switch (nfollow-1) + { + case 7: val = (val << 8) | buf[nfollow - 7]; /*fail through*/ + case 6: val = (val << 8) | buf[nfollow - 6]; /*fail through*/ + case 5: val = (val << 8) | buf[nfollow - 5]; /*fail through*/ + case 4: val = (val << 8) | buf[nfollow - 4]; /*fail through*/ + case 3: val = (val << 8) | buf[nfollow - 3]; /*fail through*/ + case 2: val = (val << 8) | buf[nfollow - 2]; /*fail through*/ + case 1: val = (val << 8) | buf[nfollow-1]; + case 0: break; + } + *out=val; + + return nfollow; +} + +/* + +//https://docs.google.com/document/d/1FcpCJGTDEMblAs-Bm5TYuqhHyUqeWpqrItw2vkMFsdY/edit + +Long Header (used for packets that are sent prior to the completion of version negotiation and establishment of 1-RTT keys): ++-+-+-+-+-+-+-+-+ +|1|1|T|T|R|R|P|P| ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Version (32) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|DCIL(4)|SCIL(4)| ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Destination Connection ID (0/64) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Source Connection ID (0/64) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Packet Number (8/16/24/32) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +*/ + + +static int join_client_hello_frames(const unsigned char *payload, int payload_len, unsigned char *join_payload, int *join_payload_len) +{ + int joined_length=0; + int payload_offset=0; + long frame_type=0, frame_offset=0, frame_length=0; + + for(; payload_offset<payload_len; ) + { + frame_type=payload[payload_offset++]; // Frame Type=1 + if(frame_type==IQUIC_FRAME_PADDING || frame_type==IQUIC_FRAME_PING) + { + continue; + } + + payload_offset+=msb2_varint_decode((const unsigned char *)(payload+payload_offset), &frame_offset); + payload_offset+=msb2_varint_decode((const unsigned char *)(payload+payload_offset), &frame_length); + + if(joined_length+frame_length>(*join_payload_len) || frame_offset<0 || frame_offset+frame_length>payload_len) + { + return -1; + } + memcpy(join_payload+frame_offset, payload+payload_offset, frame_length); + joined_length+=frame_length; + payload_offset+=frame_length; + } + + (*join_payload_len)=joined_length; + + return joined_length; +} + +static int parse_gquic_version_44to48_header(const char *payload, int payload_len, int *payload_offset) +{ + unsigned pkn_length=0; + unsigned char client_CID_len=0; + unsigned char server_CID_len=0; + unsigned char public_flags=payload[*payload_offset]; + *payload_offset+=1; //skip public flags + + *payload_offset+=sizeof(int); // skip version + + if((payload[*payload_offset])&GQUIC_VERSION_44to48_CID_MASK) + { + client_CID_len=(payload[*payload_offset]&GQUIC_VERSION_44to48_CID_MASK) + 3; + } + + if((payload[*payload_offset]>>4)&GQUIC_VERSION_44to48_CID_MASK) + { + server_CID_len=((payload[*payload_offset]>>4)&GQUIC_VERSION_44to48_CID_MASK) + 3; + } + + *payload_offset+=1; // both connection_id length + *payload_offset+=server_CID_len; // Destination connection id length + *payload_offset+=client_CID_len; // source connection id length + + pkn_length=(public_flags&GQUIC_VERSION_44to48_PKN_LEN_MASK)+1; + *payload_offset+=pkn_length; + + *payload_offset+=12; //message authentication hash + + return 1; +} + +int parse_special_frame_stream(struct quic_info* quic_info, const unsigned char *payload, int payload_len) +{ + int tag_num = 0; + int payload_offset=0; + unsigned int message_tag; + int pass_tag_num=0; + int ext_tag_type=0; + int tag_value_start_offset=0; + int total_tag_len=0,one_tag_len=0; + int parse_result=PARSE_RESULT_VERSION; + int one_tag_offset_end=0,pre_one_tag_offset_end=0; + + if(payload_len-payload_offset<=8) + { + return PARSE_RESULT_VERSION; + } + + switch(quic_info->quic_version) + { + case GQUIC_VERSION_Q041: + payload_offset+=1; // unknown + case GQUIC_VERSION_Q044: + message_tag=(unsigned int)ntohl(*(unsigned int *)(payload+payload_offset)); + payload_offset+=4; + + tag_num=*(int *)(payload+payload_offset); + payload_offset+=4; //tag_num + break; + default: + message_tag=(unsigned int)ntohl(*(unsigned int *)(payload+payload_offset)); + payload_offset+=4; + + tag_num=*(unsigned short *)(payload+payload_offset); + payload_offset+=2; //tag_num + payload_offset+=2; //padding + break; + } + + if(message_tag!=CHLO || tag_num>64 || tag_num<=0) + { + return PARSE_RESULT_VERSION; + } + + // if(quic_info->client_hello==NULL) + // { + // quic_info->client_hello=(struct quic_client_hello *)CALLOC(1, sizeof(struct quic_client_hello)); + // memset(quic_info->client_hello, 0, sizeof(struct quic_client_hello)); + // } + + tag_value_start_offset=payload_offset+tag_num*4*2; // skip length of type and offset, type(offset)=szieof(int) + + while(tag_num>pass_tag_num) + { + ext_tag_type=ntohl(*(unsigned int *)(payload+payload_offset)); + payload_offset+=sizeof(int); + + one_tag_offset_end=*(unsigned int *)(payload+payload_offset); + payload_offset+=sizeof(int); + + one_tag_len=one_tag_offset_end-pre_one_tag_offset_end; + if(one_tag_len<=0 || (one_tag_offset_end>=payload_len) || (one_tag_len+tag_value_start_offset)>payload_len) + { + break; + } + + switch(ext_tag_type) + { + case TAG_UAID: + copy_extension_tag(payload+tag_value_start_offset, one_tag_len, &quic_info->user_agent); + parse_result=PARSE_RESULT_CLIENT_HELLO; + break; + case TAG_SNI: + copy_extension_tag(payload+tag_value_start_offset, one_tag_len, &quic_info->sni); + parse_result=PARSE_RESULT_CLIENT_HELLO; + break; + default: + break; + } + + pass_tag_num++; + tag_value_start_offset+=one_tag_len; + total_tag_len+=one_tag_len; + pre_one_tag_offset_end=one_tag_offset_end; + } + + return parse_result; +} + +int parse_quic_transport_parameter(struct quic_info *quic_info, const unsigned char *quic_para, int quic_para_len) +{ + int one_para_length=0; + int para_offset=0; + long one_para_type=0; + + while(quic_para_len > para_offset) + { + para_offset+=msb2_varint_decode((const unsigned char *)(quic_para+para_offset), &one_para_type); + switch(one_para_type) + { + case EXT_QUIC_PARAM_USER_AGENT: // 2021-10-20 deprecated + one_para_length=quic_para[para_offset++]; // length=1 + if(one_para_length+para_offset>quic_para_len) + { + return 0; + } + para_offset+=copy_extension_tag(quic_para+para_offset, one_para_length, &quic_info->user_agent); + return 1; + default: + one_para_length=(int)(quic_para[para_offset++]); // length=1 + if(one_para_length<0 || one_para_length>quic_para_len) + { + break; + } + para_offset+=one_para_length; + break; + } + } + + return 0; +} + +int parse_extension_server_name(struct quic_info *quic_info, const unsigned char *ext_server_name, int ext_server_name_length) +{ + unsigned short sni_type=0; + unsigned short sni_length=0; + unsigned short extension_offset=0; + unsigned short server_name_list_len=0; + + server_name_list_len=ntohs(*(unsigned short *)(ext_server_name+extension_offset)); //Server Name List length + if(server_name_list_len<=0 || server_name_list_len>ext_server_name_length) + { + return 0; + } + extension_offset+=2; //Server Name List length + + sni_type=ext_server_name[extension_offset++]; //Server Name type + if(sni_type!=EXTENSION_SERVER_NAME) + { + return 0; + } + + sni_length=ntohs(*(unsigned short*)(ext_server_name+extension_offset)); //Server Name length + if(sni_length<=0 || sni_length>ext_server_name_length) + { + return 0; + } + extension_offset+=2; + + copy_extension_tag(ext_server_name+extension_offset, sni_length, &quic_info->sni); + + return 1; +} + +int parse_tls_client_hello(struct quic_info *quic_info, const unsigned char *payload, int payload_len) +{ + int ret=0,skip_len=0; + int payload_offset=0; + int extension_offset=0; + const unsigned char *extension_start_pos=NULL; + int parse_result=PARSE_RESULT_VERSION; + unsigned short one_ext_type=0, one_ext_len=0, extension_total_len=0; + + if(payload_len-payload_offset<=(int)sizeof(struct quic_client_hello_msg_hdr)) + { + return PARSE_RESULT_VERSION; + } + + // handshake type(1), client hello length(3), ssl_version(2), Random(32) + payload_offset+=sizeof(struct quic_client_hello_msg_hdr); + + skip_len=payload[payload_offset++]; //Session ID length + if(payload_len-payload_offset<=skip_len) + { + return PARSE_RESULT_VERSION; + } + payload_offset+=skip_len; + + skip_len=ntohs(*(unsigned short *)(payload+payload_offset)); //Ciper Suites length + if(payload_len-payload_offset<=skip_len+2) + { + return PARSE_RESULT_VERSION; + } + payload_offset+=skip_len+2; + + skip_len=payload[payload_offset++]; //Compression Methods + if(payload_len-payload_offset<skip_len) + { + return PARSE_RESULT_VERSION; + } + payload_offset+=skip_len; + + extension_total_len=ntohs(*(unsigned short *)(payload+payload_offset)); //Extension length + if(payload_len-payload_offset<extension_total_len) + { + return PARSE_RESULT_VERSION; + } + + payload_offset+=2; + + // if(*client_hello==NULL) + // { + // *client_hello=(struct quic_client_hello *)CALLOC(1, sizeof(struct quic_client_hello)); + // // memset(*client_hello, 0, sizeof(struct quic_client_hello)); + // } + + extension_start_pos=payload+payload_offset; + + while(extension_total_len > extension_offset) + { + one_ext_type=ntohs(*(unsigned short *)(extension_start_pos+extension_offset)); //Extension type + extension_offset+=2; + + one_ext_len=ntohs(*(unsigned short *)(extension_start_pos+extension_offset)); //length + extension_offset+=2; + + if(extension_total_len-extension_offset<one_ext_len) + { + break; + } + + switch(one_ext_type) + { + case EXTENSION_SERVER_NAME: + ret=parse_extension_server_name(quic_info, extension_start_pos+extension_offset, one_ext_len); + break; + case EXTENSION_QUIC_PARAM_TLS_13: + case EXTENSION_QUIC_PARAM_TLS_33: + ret=parse_quic_transport_parameter(quic_info, extension_start_pos+extension_offset, one_ext_len); + break; + default: + break; + } + + if(ret==1) + { + ret=0; + parse_result=PARSE_RESULT_CLIENT_HELLO; + } + + extension_offset+=one_ext_len; + } + + return parse_result; +} + +int get_chlo_total_length(const unsigned char *payload, int payload_len) +{ + const struct quic_client_hello_msg_hdr *chlo_hdr=(const struct quic_client_hello_msg_hdr *)payload; + int chlo_len=0; + uint8_t *p = (uint8_t *)&chlo_len; + p[2] = chlo_hdr->client_hello_len[0]; + p[1] = chlo_hdr->client_hello_len[1]; + p[0] = chlo_hdr->client_hello_len[2]; + return chlo_len; +} + +int parse_quic_decrypted_payload(struct quic_info *quic_info, const unsigned char * payload, int payload_len) +{ + unsigned char join_payload[MAX_CLIENT_HELLO_CHUNK_SIZE]={0}; + int join_payload_len=sizeof(join_payload); + unsigned int quic_version=quic_info->quic_version; + + if( (quic_version>=MVFST_VERSION_00 && quic_version<=MVFST_VERSION_0F) || + (quic_version>=GQUIC_VERSION_T050 && quic_version<=GQUIC_VERSION_T059) || + (quic_version>=IQUIC_VERSION_I022 && quic_version<=IQUIC_VERSION_I029) || + (quic_version==IQUIC_VERSION_RFC9000) + ) + { + join_payload_len=join_client_hello_frames(payload, payload_len, join_payload, &join_payload_len); + if(join_payload_len<=0) + { + return PARSE_RESULT_VERSION; + } + + if(join_payload[0] == QUIC_HANDSHAKE_TYPE_CLIENTHELLO) + { + return parse_tls_client_hello(quic_info, join_payload, join_payload_len); + } + } + else //if(quic_version>=GQUIC_VERSION_Q047 && quic_version<=GQUIC_VERSION_Q059) + { + return parse_special_frame_stream(quic_info, payload+4, payload_len-4); // Frame type=1,offset=1,length=2 + } + + return PARSE_RESULT_VERSION; +} + +int parse_quic_uncryption_payload(struct quic_info *quic_info, const unsigned char * payload, int payload_len) +{ + int stream_id_len=0; + int offset_len=0; + unsigned char frame_type; + int payload_offset=0; + + frame_type=payload[payload_offset]; + payload_offset+=1; //skip frame_type + + //https://docs.google.com/document/d/1WJvyZflAO2pq77yOLbp9NsGjC1CHetAXV8I0fQe-B_U/edit# + //Frame Type: The Frame Type byte is an 8-bit value containing various flags (1fdooossB): + if(frame_type&GQUIC_SPECIAL_FRAME_STREAM || (frame_type&0xC0)==GQUIC_SPECIAL_FRAME_ACK) + { + stream_id_len=(frame_type&GQUIC_SPECIAL_FRAME_STREAM_ID)+1; + if(payload_len-payload_offset<=stream_id_len) + { + return PARSE_RESULT_VERSION; + } + + payload_offset+=stream_id_len; // stream ID length + + if(frame_type&GQUIC_SPECIAL_FRAME_STREAM_DLEN) + { + if(payload_len-payload_offset<2) + { + return PARSE_RESULT_VERSION; + } + payload_offset+=2; //data length + } + + if(frame_type&GQUIC_SPECIAL_FRAME_STREAM_OFFSET) + {//The next three 'ooo' bits encode the length of the Offset header field as 0, 16, 24, 32, 40, 48, 56, or 64 bits long. + offset_len= (((frame_type&GQUIC_SPECIAL_FRAME_STREAM_OFFSET))>>2)+1; + if(payload_len-payload_offset<=offset_len) + { + return PARSE_RESULT_VERSION; + } + payload_offset+=offset_len; //data length + } + + return parse_special_frame_stream(quic_info, payload+payload_offset, payload_len-payload_offset); + } + + return PARSE_RESULT_VERSION; +} + +/* +//https://docs.google.com/document/d/1WJvyZflAO2pq77yOLbp9NsGjC1CHetAXV8I0fQe-B_U/edit + +--- src + 0 1 2 3 4 8 ++--------+--------+--------+--------+--------+--- ---+ +| Public | Connection ID (64) ... | -> +|Flags(8)| (optional) | ++--------+--------+--------+--------+--------+--- ---+ + + 9 10 11 12 ++--------+--------+--------+--------+ +| QUIC Version (32) | -> +| (optional) | ++--------+--------+--------+--------+ + + + 13 14 15 16 17 18 19 20 ++--------+--------+--------+--------+--------+--------+--------+--------+ +| Diversification Nonce | -> +| (optional) | ++--------+--------+--------+--------+--------+--------+--------+--------+ + + 21 22 23 24 25 26 27 28 ++--------+--------+--------+--------+--------+--------+--------+--------+ +| Diversification Nonce Continued | -> +| (optional) | ++--------+--------+--------+--------+--------+--------+--------+--------+ + + 29 30 31 32 33 34 35 36 ++--------+--------+--------+--------+--------+--------+--------+--------+ +| Diversification Nonce Continued | -> +| (optional) | ++--------+--------+--------+--------+--------+--------+--------+--------+ + + 37 38 39 40 41 42 43 44 ++--------+--------+--------+--------+--------+--------+--------+--------+ +| Diversification Nonce Continued | -> +| (optional) | ++--------+--------+--------+--------+--------+--------+--------+--------+ + + + 45 46 47 48 49 50 ++--------+--------+--------+--------+--------+--------+ +| Packet Number (8, 16, 32, or 48) | +| (variable length) | ++--------+--------+--------+--------+--------+--------+ + +*/ +enum QUIC_VERSION_T identify_gquic_version0to43(const char *payload, int payload_len, int *payload_offset) +{ + unsigned char pkn_length=0; + unsigned char public_flags=0; + enum QUIC_VERSION_T quic_version=QUIC_VERSION_UNKNOWN; + + public_flags=payload[*payload_offset]; + *payload_offset+=1; + + if(!(public_flags&GQUIC_PUBLIC_FLAG_VERSION)) + { + return QUIC_VERSION_UNKNOWN; + } + + /* + 0x08 = Indicates the full 8 byte Connection ID is present in the packet. + This must be set in all packets until negotiated to a different value for a given direction + (e.g., client may request fewer bytes of the Connection ID be presented) + */ + if(public_flags&GQUIC_PUBLIC_FLAG_CID) + { + *payload_offset+=8; // CID length + } + + if(public_flags&GQUIC_PUBLIC_FLAG_VERSION && (*(unsigned char *)(payload+*payload_offset)==0x51)) + { + quic_version=(enum QUIC_VERSION_T)ntohl(*(unsigned int *)(payload+*payload_offset)); + *payload_offset+=sizeof(int); // skip version + } + + if(quic_version<GQUIC_VERSION_Q001 || quic_version>GQUIC_VERSION_Q043) + { + return QUIC_VERSION_UNKNOWN; + } + + pkn_length=gquic_pkn_bit2length(public_flags&GQUIC_VERSION_0to43_PKN_LEN_MASK); + *payload_offset+=pkn_length; // packet number length + + if(public_flags==GQUIC_PUBLIC_FLAG_NONCE) + { + *payload_offset+=32; //diversification nonce + } + + // Version 11 reduced the length of null encryption authentication tag from 16 to 12 bytes + if(quic_version > GQUIC_VERSION_Q010) + { + *payload_offset+=12; + } + else + { + *payload_offset+=16; + } + + // Version 34 removed entropy bits from packets and ACK frames, + // removed private flag from packet header and changed the ACK format to specify ranges of packets acknowledged rather than missing ranges. + if(quic_version < GQUIC_VERSION_Q034) + { + *payload_offset+=1; //private flags + } + + return quic_version; +} + +enum QUIC_VERSION_T identify_quic_version(const char *payload, int payload_len, int *payload_offset) +{ + enum QUIC_VERSION_T quic_version=(enum QUIC_VERSION_T)ntohl(*(unsigned int *)(payload+(*payload_offset+1))); + if(quic_version>=GQUIC_VERSION_Q044 && quic_version<=GQUIC_VERSION_Q048) + { + parse_gquic_version_44to48_header(payload, payload_len, payload_offset); + return quic_version; + } + else if( + (quic_version==GQUIC_VERSION_Q099) || + (quic_version==PICOQUIC_VERSION_30) || + (quic_version==PQUIC_VERSION_PROX) || + (quic_version==GQUIC_VERSION_T099) || + (quic_version>=GQUIC_VERSION_Q049 && quic_version<=GQUIC_VERSION_Q050) || + (quic_version>=GQUIC_VERSION_Q051 && quic_version<=GQUIC_VERSION_Q059) || + (quic_version>=GQUIC_VERSION_T048 && quic_version<=GQUIC_VERSION_T049) || + (quic_version>=GQUIC_VERSION_T050 && quic_version<=GQUIC_VERSION_T059) || + (quic_version>=QUANT_VERSION_00 && quic_version<=QUANT_VERSION_FF) || + (quic_version>=QUIC_GO_VERSION_00 && quic_version<=QUIC_GO_VERSION_FF) || + (quic_version>=QUICLY_VERSION_00 && quic_version<=QUICLY_VERSION_FF) || + (quic_version>=MSQUIC_VERSION_00 && quic_version<=MSQUIC_VERSION_0F) || + (quic_version>=MOZQUIC_VERSION_00 && quic_version<=MOZQUIC_VERSION_0F) || + (quic_version>=MVFST_VERSION_00 && quic_version<=MVFST_VERSION_0F) || + (quic_version>=IQUIC_VERSION_I001 && quic_version<=IQUIC_VERSION_I032) || + (quic_version==IQUIC_VERSION_RFC9000) + ) + { + return quic_version; + } + + return QUIC_VERSION_UNKNOWN; +} + +enum QUIC_VERSION_T is_quic_protocol(const char *payload, int payload_len, int *payload_offset) +{ + enum QUIC_VERSION_T quic_version=QUIC_VERSION_UNKNOWN; + unsigned char frame_type=(unsigned char)(payload[0]); + + if(payload_len<=4) + { + return QUIC_VERSION_UNKNOWN; + } + + if(frame_type&QUIC_LONG_HEADER_MASK) + { + quic_version=identify_quic_version(payload, payload_len, payload_offset); + } + else if(frame_type<QUIC_LONG_HEADER_MASK) + { + quic_version=identify_gquic_version0to43(payload, payload_len, payload_offset); + } + else + { + return QUIC_VERSION_UNKNOWN; + } + + return quic_version; +} + +// +static void quic_chlo_chunk_assemble(struct quic_buffer *qbuf, unsigned char *new_payload, int new_len) +{ + if(NULL == new_payload || new_len <= 0){ + return; + } + if(NULL == qbuf->buffer){ + qbuf->buffer = (unsigned char *)calloc(1, MAX_CLIENT_HELLO_CHUNK_SIZE); + qbuf->max_size = MAX_CLIENT_HELLO_CHUNK_SIZE; + } + int max_copy_len = MIN((int)(qbuf->max_size - qbuf->datalen), new_len); + memcpy(qbuf->buffer + qbuf->datalen, new_payload, max_copy_len); + qbuf->datalen += max_copy_len; +} + +/* + 1: is chlo, is complete. + 0: is chlo, is fragment; + -1: not support +*/ +static int quic_chlo_is_complete(enum QUIC_VERSION_T quic_version, const unsigned char *payload, int payload_len) +{ + if(!( (quic_version>=MVFST_VERSION_00 && quic_version<=MVFST_VERSION_0F) || + (quic_version>=GQUIC_VERSION_T050 && quic_version<=GQUIC_VERSION_T059) || + (quic_version>=IQUIC_VERSION_I022 && quic_version<=IQUIC_VERSION_I029) || + (quic_version==IQUIC_VERSION_RFC9000))) + { + return -1; + } + + if((payload[0] != IQUIC_FRAME_CRYPTO) && (payload[0] != 0x08)) + { + return -1; + } + int payload_offset = 0; + long frame_offset, frame_length; + payload_offset = 1; //skip frame type + payload_offset+=msb2_varint_decode(payload+payload_offset, &frame_offset); + payload_offset+=msb2_varint_decode(payload+payload_offset, &frame_length); + + if(payload[payload_offset] != QUIC_HANDSHAKE_TYPE_CLIENTHELLO) + { + return -1; + } + int expect_len = get_chlo_total_length(payload + payload_offset, payload_len-payload_offset); + if(payload_len-payload_offset >= expect_len){ + return 1; + } + return 0; +} + +static enum PARSE_RESULT quic_decrypting_payload(struct quic_context *qcontext, unsigned char *udp_payload, int udp_payload_len) +{ + struct quic_buffer *qbuf = &qcontext->quic_buf; + unsigned char *quic_decrypted_payload; + int ret, quic_decrypted_payload_len; + quic_dpt_t *dpt = quic_deprotection_new(); + + if(quic_deprotection(dpt, (const u_char *)udp_payload, udp_payload_len) < 0){ + goto err_exit; + } + + if(qbuf->datalen > 0){ //some fragment exist + quic_chlo_chunk_assemble(qbuf, dpt->payload.data, dpt->payload.len); + quic_decrypted_payload = qbuf->buffer; + quic_decrypted_payload_len = qbuf->datalen; + }else{ + quic_decrypted_payload = dpt->payload.data; + quic_decrypted_payload_len = dpt->payload.len; + } + + ret = quic_chlo_is_complete((enum QUIC_VERSION_T)qcontext->quic_info.quic_version, quic_decrypted_payload, quic_decrypted_payload_len); + if(0 == ret){ + if(NULL == qbuf->buffer || 0 == qbuf->datalen){ + quic_chlo_chunk_assemble(qbuf, dpt->payload.data, dpt->payload.len); + } + goto fun_exit; + }else{ + qbuf->is_completed = 1; + } + parse_quic_decrypted_payload(&qcontext->quic_info, quic_decrypted_payload, quic_decrypted_payload_len); + +fun_exit: + quic_deprotection_free(dpt); + return PARSE_RESULT_VERSION; + +err_exit: + quic_deprotection_free(dpt); + return PARSE_RESULT_VERSION; +} + +enum PARSE_RESULT parse_quic_all_version(const struct quic_param *g_quic_plugin_env, struct quic_context *qcontext, const char *payload, int payload_len) +{ + struct quic_info *quic_info = &qcontext->quic_info; + int payload_offset = 0; + enum QUIC_VERSION_T quic_version = QUIC_VERSION_UNKNOWN; + + if (payload == NULL || payload_len <= 0) + { + return PARSE_RESULT_UNKNOWN; + } + quic_version = is_quic_protocol(payload, payload_len, &payload_offset); + if (quic_version == QUIC_VERSION_UNKNOWN) + { + if(QUIC_IS_LONG_HEADER(payload[0]) == 0){ + return PARSE_RESULT_PAYLOAD; + } + return PARSE_RESULT_UNKNOWN; + } + + if (quic_version >= GQUIC_VERSION_Q001 && quic_version <= GQUIC_VERSION_Q048) + { + if (payload_len > payload_offset) + { + return (enum PARSE_RESULT)parse_quic_uncryption_payload(quic_info, (const unsigned char *)payload + payload_offset, payload_len - payload_offset); + } + return PARSE_RESULT_VERSION; + } + else if (((quic_version >= MVFST_VERSION_00 && quic_version <= MVFST_VERSION_0F) || + (quic_version >= GQUIC_VERSION_Q049 && quic_version <= GQUIC_VERSION_Q059) || + (quic_version >= GQUIC_VERSION_T050 && quic_version <= GQUIC_VERSION_T059) || + (quic_version >= GQUIC_VERSION_T050 && quic_version <= GQUIC_VERSION_T059) || + (quic_version >= IQUIC_VERSION_I022 && quic_version <= IQUIC_VERSION_I029) || + (quic_version == IQUIC_VERSION_RFC9000)) && + g_quic_plugin_env->decrypted_switch > 0) + { + return quic_decrypting_payload(qcontext, (unsigned char *)payload, payload_len); + } + else + { + return PARSE_RESULT_VERSION; + } + + return PARSE_RESULT_VERSION; +} + +static void quic_info_clear(struct quic_info *qinfo) +{ + if(qinfo->sni.iov_base){ + free(qinfo->sni.iov_base); + qinfo->sni.iov_base = NULL; + qinfo->sni.iov_len = 0; + } + if(qinfo->user_agent.iov_base){ + free(qinfo->user_agent.iov_base); + qinfo->user_agent.iov_base = NULL; + qinfo->user_agent.iov_len = 0; + } + if(qinfo->payload.iov_base){ + free(qinfo->payload.iov_base); + qinfo->payload.iov_base = NULL; + qinfo->payload.iov_len = 0; + } +} + +static void quic_buffer_clear(struct quic_buffer *qbuf) +{ + if(qbuf->buffer != NULL && qbuf->is_completed == 1){ + free(qbuf->buffer); + qbuf->buffer = NULL; + qbuf->datalen = 0; + qbuf->max_size = 0; + qbuf->is_completed = 0; + } +} + +void quic_analyze_entry(struct session *sess, const struct quic_param *quic_plugin_env, struct quic_context *qcontext, int thread_seq, const char *payload, size_t payload_len) +{ + struct quic_message *qmsg; + enum PARSE_RESULT res; + + quic_info_clear(&qcontext->quic_info); + quic_buffer_clear(&qcontext->quic_buf); + + res = parse_quic_all_version(quic_plugin_env, qcontext, payload, payload_len); + if (res == PARSE_RESULT_UNKNOWN){ + stellar_session_plugin_dettach_current_session(sess); + return; + } + + if(res == PARSE_RESULT_PAYLOAD){ + qmsg = quic_create_message(QUIC_PROTECTED_PAYLOAD, qcontext); + quic_session_mq_publish_message_safe(sess, quic_plugin_env->quic_topic_id, qmsg); + return; + } + + if(qcontext->quic_info.sni.iov_base || qcontext->quic_info.user_agent.iov_base){ + qmsg = quic_create_message(QUIC_CLIENT_HELLO, qcontext); + quic_session_mq_publish_message_safe(sess, quic_plugin_env->quic_topic_id, qmsg); + } + return; +} + +void quic_session_mq_publish_message_safe(struct session *sess, int topic_id, void *msg) +{ + int ret = session_mq_publish_message(sess, topic_id, msg); + if(ret < 0){ + FREE(msg); + } + return; +} +struct quic_message *quic_create_message(enum quic_message_type mtype, struct quic_context *context) +{ + struct quic_message *msg = (struct quic_message *)CALLOC(1, sizeof(struct quic_message)); + msg->magic = QUIC_MSG_HDR_MAGIC; + msg->type = mtype; + msg->qctx = context; + return msg; +} + +#ifdef __cplusplus +extern "C" +{ +#endif +enum quic_message_type quic_message_type_get(const struct quic_message *msg) +{ + assert(QUIC_MSG_HDR_MAGIC == msg->magic); + if(QUIC_MSG_HDR_MAGIC != msg->magic){ + return QUIC_MSG_MAX; + } + return msg->type; +} + +unsigned int quic_message_version_get(const struct quic_message *msg) +{ + assert(QUIC_MSG_HDR_MAGIC == msg->magic); + return msg->qctx->quic_info.quic_version; +} + +const char *quic_message_readable_version_get0(const struct quic_message *msg) +{ + assert(QUIC_MSG_HDR_MAGIC == msg->magic); + quic_version_int2string(msg->qctx->quic_info.quic_version, msg->qctx->quic_info.quic_version_str, QUIC_VERSION_STRING_MAX_SIZE); + return msg->qctx->quic_info.quic_version_str; +} + +const char *quic_message_readable_ja3hash_get0(const struct quic_message *msg) +{ + //todo + return NULL; +} + +void quic_message_sni_get0(const struct quic_message *msg, char **result, size_t *len) +{ + assert(QUIC_MSG_HDR_MAGIC == msg->magic); + if(result){ + *result = (char *)msg->qctx->quic_info.sni.iov_base; + } + if(len){ + *len = msg->qctx->quic_info.sni.iov_len; + } +} +void quic_message_user_agent_get0(const struct quic_message *msg, char **result, size_t *len) +{ + assert(QUIC_MSG_HDR_MAGIC == msg->magic); + if(result){ + *result = (char *)msg->qctx->quic_info.user_agent.iov_base; + } + if(len){ + *len = msg->qctx->quic_info.user_agent.iov_len; + } +} + +void quic_message_protected_payload_get0(const struct quic_message *msg, char **result, size_t *len) +{ + assert(QUIC_MSG_HDR_MAGIC == msg->magic); + if(result){ + *result = (char *)msg->qctx->quic_info.payload.iov_base; + } + if(len){ + *len = msg->qctx->quic_info.payload.iov_len; + } + +} + +#ifdef __cplusplus +} +#endif diff --git a/src/quic_process.h b/src/quic_process.h new file mode 100644 index 0000000..4bb66c8 --- /dev/null +++ b/src/quic_process.h @@ -0,0 +1,346 @@ +#pragma once + +#include <stddef.h> +#include <stdbool.h> + +#include "quic_decoder.h" +#include "quic_entry.h" + +#define QUIC_LONG_HEADER_MASK 0x80 + +#define GQUIC_VERSION_44to48_CID_MASK 0x0F +#define GQUIC_VERSION_44to48_PKN_LEN_MASK 0x03 +#define GQUIC_VERSION_0to43_PKN_LEN_MASK 0x30 + +#define GQUIC_PUBLIC_FLAG_VERSION 0x01 +#define GQUIC_PUBLIC_FLAG_RST 0x02 +#define GQUIC_PUBLIC_FLAG_NONCE 0x04 +#define GQUIC_PUBLIC_FLAG_CID 0x08 +#define GQUIC_PUBLIC_FLAG_PKT_NUM 0x30 + +//GQIIC Frame type +#define GQUIC_SPECIAL_FRAME_FLAG 0xE0 // Special Frame Types +#define GQUIC_SPECIAL_FRAME_STREAM 0x80 +#define GQUIC_SPECIAL_FRAME_ACK 0x40 +#define GQUIC_SPECIAL_FRAME_CONGEST_FB 0x20 + +#define GQUIC_SPECIAL_FRAME_STREAM_FIN 0x40 // FIN +#define GQUIC_SPECIAL_FRAME_STREAM_DLEN 0x20 //stream length +#define GQUIC_SPECIAL_FRAME_STREAM_OFFSET 0x1C //offset header field +#define GQUIC_SPECIAL_FRAME_STREAM_ID 0x03 //offset header field + +#define GQUIC_REGULAR_FRAME_PADDING 0x00 +#define GQUIC_REGULAR_FRAME_RST_STREAM 0x01 +#define GQUIC_REGULAR_FRAME_CONNECTION_CLOSE 0x02 +#define GQUIC_REGULAR_FRAME_GOAWAY 0x03 +#define GQUIC_REGULAR_FRAME_WINDOW_UPDATE 0x04 +#define GQUIC_REGULAR_FRAME_BLOCKED 0x05 +#define GQUIC_REGULAR_FRAME_STOP_WAITING 0x06 +#define GQUIC_REGULAR_FRAME_PING 0x07 + +// https://www.rfc-editor.org/rfc/rfc9000.html#name-frames-and-frame-types +#define IQUIC_FRAME_PADDING 0x00 +#define IQUIC_FRAME_PING 0x01 +#define IQUIC_FRAME_ACK 0x02 +#define IQUIC_FRAME_RST_STREAM 0x03 +#define IQUIC_FRAME_STOP_WAITING 0x04 +#define IQUIC_FRAME_CRYPTO 0x06 +#define IQUIC_FRAME_NEW_TOKEN 0x07 +#define IQUIC_FRAME_STREAM 0x08 +#define IQUIC_FRAME_MAX_DATA 0x10 +#define IQUIC_FRAME_MAX_STREAM_DATA 0x11 +#define IQUIC_FRAME_MAX_STREAMS 0x12 +#define IQUIC_FRAME_DATA_BLOCKED 0x13 +#define IQUIC_FRAME_STREAM_DATA_BLOCKED 0x14 +#define IQUIC_FRAME_STREAMS_BLOCKED 0x15 +#define IQUIC_FRAME_NEW_CONNECTION_ID 0x18 +#define IQUIC_FRAME_RETIRE_CONNECTION_ID 0x19 +#define IQUIC_FRAME_PATH_CHALLENGE 0x1A +#define IQUIC_FRAME_PATH_RESPONSE 0x1B +#define IQUIC_FRAME_CONNECTION_CLOSE 0x1C +#define IQUIC_FRAME_APPLICATION_CLOSE 0x1D +#define IQUIC_FRAME_HANDSHAKE_DONE 0x1E + +#define QUIC_HANDSHAKE_TYPE_CLIENTHELLO 0x01 + +//https://datatracker.ietf.org/doc/html/draft-ietf-quic-transport-27#section-12.4 +//IQIIC Frame type (GQUIC_Q046 is iQUIC 17) + + +/**************************************************************************/ +/* Message tag */ +/**************************************************************************/ +#define CHLO 0x43484C4F +#define SHLO 0x53484C4F +#define REJ 0x52454A00 +#define PRST 0x50525354 + + +/**************************************************************************/ +/* Tag */ +/**************************************************************************/ +#define TAG_SNI 0x534E4900 +#define TAG_VER 0x56455200 +#define TAG_UAID 0x55414944 + + +#define EXTENSION_SERVER_NAME 0x0000 +#define EXTENSION_SUPPORT_GROUP 0x000A +#define EXTENSION_APP_PROT_NEGO 0x0010 //application layer protocol negotiation +#define EXTENSION_SIG_ALGORITHM 0x000D +#define EXTENSION_KEY_SHARE 0x0033 +#define EXTENSION_PSK_EXCHANGE 0x002D +#define EXTENSION_SUPP_SSL_VER 0x002B +#define EXTENSION_QUIC_PARAM_TLS_33 0x0039 /* draft-ietf-quic-tls-33 */ +#define EXTENSION_QUIC_PARAM_TLS_13 0xFFA5 /* 0xffa5 draft-ietf-quic-tls-13 */ +#define EXTENSION_COMPRESS_CERT 0x001B +#define EXTENTION_UNKNOWN 0x4469 + +// https://www.iana.org/assignments/quic/quic.xhtml +#define EXT_QUIC_PARAM_ORIGINAL_DST_CONN_ID 0x00 +#define EXT_QUIC_PARAM_MAX_IDLE_TIMEOUT 0x01 +#define EXT_QUIC_PARAM_STATELESS_RST_TOKEN 0x02 +#define EXT_QUIC_PARAM_MAX_UDP_PAYLOAD 0x03 +#define EXT_QUIC_PARAM_MAX_INIT_DATA 0x04 +#define EXT_QUIC_PARAM_MAX_STREAM_BIDI_LOCAL 0x05 +#define EXT_QUIC_PARAM_MAX_STREAM_BIDI_REMOTE 0x06 +#define EXT_QUIC_PARAM_MAX_STREAM_UNI 0x07 +#define EXT_QUIC_PARAM_MAX_STREAMS_BIDI 0x08 +#define EXT_QUIC_PARAM_MAX_STREAMS_UNI 0x09 +#define EXT_QUIC_PARAM_ACK_DELAY_EXPONENT 0x0A +#define EXT_QUIC_PARAM_MAX_ACK_DELAY 0x0B +#define EXT_QUIC_PARAM_DISABLE_ACTIVE_MIGRATION 0x0C +#define EXT_QUIC_PARAM_PREFERRED_ADDRESS 0x0D +#define EXT_QUIC_PARAM_ACTIVE_CONN_ID_LINIT 0x0E +#define EXT_QUIC_PARAM_INIT_SRC_CONN_ID 0x0F +#define EXT_QUIC_PARAM_RETRY_SRC_CONN_ID 0x10 +#define EXT_QUIC_PARAM_MAX_DATAGRAM_FRAME_SIZE 0x20 +#define EXT_QUIC_PARAM_INIT_RTT 0x3127 +#define EXT_QUIC_PARAM_GOOGLE_CONN_OPTIONS 0x3128 +#define EXT_QUIC_PARAM_USER_AGENT 0x3129 // 2021-10-20 deprecated +#define EXT_QUIC_PARAM_QUIC_VERSION 0x4752 + +//https://github.com/quicwg/base-drafts/wiki/QUIC-Versions +/* + https://www.chromium.org/quic/quic-faq/ + In June of 2021, Chromium defaults to supporting IETF QUIC draft29 and gQUIC Q050. +*/ +enum QUIC_VERSION_T +{ + QUIC_VERSION_UNKNOWN=0, + //NetApp + QUANT_VERSION_00=0x45474700, + QUANT_VERSION_FF=0x454747FF, + + //Private Octopus + PICOQUIC_VERSION_30=0x50435130, + + //google + GQUIC_VERSION_Q001=0x51303031, + GQUIC_VERSION_Q002=0x51303032, + GQUIC_VERSION_Q003=0x51303033, + GQUIC_VERSION_Q004=0x51303034, + GQUIC_VERSION_Q005=0x51303035, + GQUIC_VERSION_Q006=0x51303036, + GQUIC_VERSION_Q007=0x51303037, + GQUIC_VERSION_Q008=0x51303038, + GQUIC_VERSION_Q009=0x51303039, + + GQUIC_VERSION_Q010=0x51303130, + GQUIC_VERSION_Q011=0x51303131, + GQUIC_VERSION_Q012=0x51303132, + GQUIC_VERSION_Q013=0x51303133, + GQUIC_VERSION_Q014=0x51303134, + GQUIC_VERSION_Q015=0x51303135, + GQUIC_VERSION_Q016=0x51303136, + GQUIC_VERSION_Q017=0x51303137, + GQUIC_VERSION_Q018=0x51303138, + GQUIC_VERSION_Q019=0x51303139, + + GQUIC_VERSION_Q020=0x51303230, + GQUIC_VERSION_Q021=0x51303231, + GQUIC_VERSION_Q022=0x51303232, + GQUIC_VERSION_Q023=0x51303233, + GQUIC_VERSION_Q024=0x51303234, + GQUIC_VERSION_Q025=0x51303235, + GQUIC_VERSION_Q026=0x51303236, + GQUIC_VERSION_Q027=0x51303237, + GQUIC_VERSION_Q028=0x51303238, + GQUIC_VERSION_Q029=0x51303239, + + GQUIC_VERSION_Q030=0x51303330, + GQUIC_VERSION_Q031=0x51303331, + GQUIC_VERSION_Q032=0x51303332, + GQUIC_VERSION_Q033=0x51303333, + GQUIC_VERSION_Q034=0x51303334, + GQUIC_VERSION_Q035=0x51303335, + GQUIC_VERSION_Q036=0x51303336, + GQUIC_VERSION_Q037=0x51303337, + GQUIC_VERSION_Q038=0x51303338, + GQUIC_VERSION_Q039=0x51303339, + + GQUIC_VERSION_Q040=0x51303430, + GQUIC_VERSION_Q041=0x51303431, + GQUIC_VERSION_Q042=0x51303432, + GQUIC_VERSION_Q043=0x51303433, + GQUIC_VERSION_Q044=0x51303434, + GQUIC_VERSION_Q045=0x51303435, + GQUIC_VERSION_Q046=0x51303436, + GQUIC_VERSION_Q047=0x51303437, + GQUIC_VERSION_Q048=0x51303438, + GQUIC_VERSION_Q049=0x51303439, + + GQUIC_VERSION_Q050=0x51303530, + GQUIC_VERSION_Q051=0x51303531, + GQUIC_VERSION_Q052=0x51303532, + GQUIC_VERSION_Q053=0x51303533, + GQUIC_VERSION_Q054=0x51303534, + GQUIC_VERSION_Q055=0x51303535, + GQUIC_VERSION_Q056=0x51303536, + GQUIC_VERSION_Q057=0x51303537, + GQUIC_VERSION_Q058=0x51303538, + GQUIC_VERSION_Q059=0x51303539, + + GQUIC_VERSION_Q099=0x51303939, + + //Google QUIC with TLS 48 - 49 (T048 - T049) + GQUIC_VERSION_T048=0x54303438, + GQUIC_VERSION_T049=0x54303439, + + //Google QUIC with TLS 50 - 59 (T050 - T059) + GQUIC_VERSION_T050=0x54303530, + GQUIC_VERSION_T051=0x54303531, + GQUIC_VERSION_T052=0x54303532, + GQUIC_VERSION_T053=0x54303533, + GQUIC_VERSION_T054=0x54303534, + GQUIC_VERSION_T055=0x54303535, + GQUIC_VERSION_T056=0x54303536, + GQUIC_VERSION_T057=0x54303537, + GQUIC_VERSION_T058=0x54303538, + GQUIC_VERSION_T059=0x54303539, + + //Google QUIC with TLS 99 (T099) + GQUIC_VERSION_T099=0x54303939, + + //Google Proxied QUIC + PQUIC_VERSION_PROX=0x50524f58, + + //quic-go + QUIC_GO_VERSION_00=0x51474F00, + QUIC_GO_VERSION_FF=0x51474FFF, + + //quicly + QUICLY_VERSION_00=0x91c17000, + QUICLY_VERSION_FF=0x91c170FF, + + //Microsoft + MSQUIC_VERSION_00=0xabcd0000, + MSQUIC_VERSION_0F=0xabcd000F, + + //Mozilla + MOZQUIC_VERSION_00=0xf123f0c0, + MOZQUIC_VERSION_0F=0xf123f0cF, + + //Facebook + MVFST_VERSION_00=0xfaceb000, + MVFST_VERSION_01=0xfaceb001, + MVFST_VERSION_02=0xfaceb002, + MVFST_VERSION_03=0xfaceb003, + MVFST_VERSION_04=0xfaceb004, + MVFST_VERSION_05=0xfaceb005, + MVFST_VERSION_06=0xfaceb006, + MVFST_VERSION_07=0xfaceb007, + MVFST_VERSION_08=0xfaceb008, + MVFST_VERSION_09=0xfaceb009, + MVFST_VERSION_0A=0xfaceb00A, + MVFST_VERSION_0B=0xfaceb00B, + MVFST_VERSION_0C=0xfaceb00C, + MVFST_VERSION_0D=0xfaceb00D, + MVFST_VERSION_0E=0xfaceb00E, + MVFST_VERSION_0F=0xfaceb00F, + + //IETF + IQUIC_VERSION_RFC9000=0x00000001, + IQUIC_VERSION_I001=0xFF000001, + IQUIC_VERSION_I002=0xFF000002, + IQUIC_VERSION_I003=0xFF000003, + IQUIC_VERSION_I004=0xFF000004, + IQUIC_VERSION_I005=0xFF000005, + IQUIC_VERSION_I006=0xFF000006, + IQUIC_VERSION_I007=0xFF000007, + IQUIC_VERSION_I008=0xFF000008, + IQUIC_VERSION_I009=0xFF000009, + IQUIC_VERSION_I010=0xFF00000A, + IQUIC_VERSION_I011=0xFF00000B, + IQUIC_VERSION_I012=0xFF00000C, + IQUIC_VERSION_I013=0xFF00000D, + IQUIC_VERSION_I014=0xFF00000E, + IQUIC_VERSION_I015=0xFF00000F, + IQUIC_VERSION_I016=0xFF000010, + IQUIC_VERSION_I017=0xFF000011, + IQUIC_VERSION_I018=0xFF000012, + IQUIC_VERSION_I019=0xFF000013, + IQUIC_VERSION_I020=0xFF000014, + IQUIC_VERSION_I021=0xFF000015, + IQUIC_VERSION_I022=0xFF000016, + IQUIC_VERSION_I023=0xFF000017, + IQUIC_VERSION_I024=0xFF000018, + IQUIC_VERSION_I025=0xFF000019, + IQUIC_VERSION_I026=0xFF00001A, + IQUIC_VERSION_I027=0xFF00001B, + IQUIC_VERSION_I028=0xFF00001C, + IQUIC_VERSION_I029=0xFF00001D, + IQUIC_VERSION_I030=0xFF00001E, + IQUIC_VERSION_I031=0xFF00001F, + IQUIC_VERSION_I032=0xFF000020 +}; + +struct quic_info +{ + unsigned int quic_version; + char quic_version_str[QUIC_VERSION_STRING_MAX_SIZE]; + qstring sni; + qstring user_agent; + qstring payload; +}; + +#define MAX_CLIENT_HELLO_CHUNK_SIZE (4096) +struct quic_buffer{ + int is_completed; + unsigned char *buffer; + size_t max_size; + size_t datalen; +}; + +struct quic_context +{ + unsigned int parse_payload_size; + struct quic_info quic_info; + struct quic_buffer quic_buf; //for client hello fragment +}; + +#define QUIC_MSG_HDR_MAGIC 0x51554943 // ASCII: "QUIC" +struct quic_message +{ + unsigned int magic; + enum quic_message_type type; + struct quic_context *qctx; +}; + +enum PARSE_RESULT +{ + PARSE_RESULT_UNKNOWN, + PARSE_RESULT_VERSION, + PARSE_RESULT_CLIENT_HELLO, + PARSE_RESULT_PAYLOAD, + PARSE_RESULT_MAX +}; + +enum PARSE_RESULT parse_quic_all_version(const struct quic_param *g_quic_plugin_env, struct quic_info *quic_info, const char *payload, int payload_len, int thread_seq); +void quic_analyze_entry(struct session *sess, const struct quic_param *g_quic_plug_env, struct quic_context* context, int thread_seq, const char *payload, size_t payload_len); +// unsigned char quic_call_business_plug(const struct streaminfo *pstream, struct quic_context *context, void *buff, int buff_len, enum quic_interested_region region_mask, const void *a_packet); +int quic_protocol_identify(struct session *sess, struct quic_param *g_quic_plug_env); +struct quic_message *quic_create_message(enum quic_message_type mtype, struct quic_context *context); +void quic_session_mq_publish_message_safe(struct session *sess, int topic_id, void *msg); +enum QUIC_VERSION_T is_quic_protocol(const char *payload, int payload_len, int *payload_offset); +int quic_version_int2string(unsigned int version, char *buff, int buff_len);
\ No newline at end of file diff --git a/src/quic_util.h b/src/quic_util.h new file mode 100644 index 0000000..e147e23 --- /dev/null +++ b/src/quic_util.h @@ -0,0 +1,5 @@ +#pragma once + +#define CALLOC(nmemb, size) calloc(nmemb, size) +#define REALLOC(ptr, newsize) realloc(ptr, newsize) +#define FREE(p) {free((void *)p); p = NULL;}
\ No newline at end of file diff --git a/src/quic_version.cpp b/src/quic_version.cpp new file mode 100644 index 0000000..1bec0bb --- /dev/null +++ b/src/quic_version.cpp @@ -0,0 +1,81 @@ +#include <stdio.h> +#include "quic_process.h" + +int quic_version_int2string(unsigned int version, char *buff, int buff_len) +{ + if(version>=GQUIC_VERSION_Q001 && version<=GQUIC_VERSION_Q099) + { + snprintf(buff, buff_len, "Google QUIC %02d", (((version>>8)&0x0000000F)*10) + (version&0x0000000F)); + return 1; + } + + if(version>=GQUIC_VERSION_T048 && version<=GQUIC_VERSION_T099) + { + snprintf(buff, buff_len, "Google QUIC with TLS %02d", (((version>>8)&0x0000000F)*10) + (version&0x0000000F)); + return 1; + } + + + if(version==IQUIC_VERSION_RFC9000) + { + snprintf(buff, buff_len, "IETF QUIC RFC9000"); + return 1; + } + + if(version>=IQUIC_VERSION_I001 && version<=IQUIC_VERSION_I032) + { + snprintf(buff, buff_len, "IETF QUIC %02d", (((version>>16)&0x000000FF)*10) + (((version>>8)&0x000000FF)*10) + (version&0x000000FF)); + return 1; + } + + if(version>=QUANT_VERSION_00 && version<=QUANT_VERSION_FF) + { + snprintf(buff, buff_len, "NetApp QUANT %02d", (version&0x000000FF)); + return 1; + } + + if(version==PICOQUIC_VERSION_30) + { + snprintf(buff, buff_len, "Private Octopus"); + return 1; + } + + if(version==PQUIC_VERSION_PROX) + { + snprintf(buff, buff_len, "Proxied QUIC"); + return 1; + } + + if(version>=QUIC_GO_VERSION_00 && version<=QUIC_GO_VERSION_FF) + { + snprintf(buff, buff_len, "quic-go QGO %02d", (version&0x000000FF)); + return 1; + } + + if(version>=QUIC_GO_VERSION_00 && version<=QUIC_GO_VERSION_FF) + { + snprintf(buff, buff_len, "quicly qicly0 %02d", (version&0x000000FF)); + return 1; + } + + if(version>=MSQUIC_VERSION_00 && version<=MSQUIC_VERSION_0F) + { + snprintf(buff, buff_len, "Microsoft MsQuic %02d", (version&0x0000000F)); + return 1; + } + + if(version>=MOZQUIC_VERSION_00 && version<=MOZQUIC_VERSION_0F) + { + snprintf(buff, buff_len, "Mozilla MozQuic %02d", (version&0x0000000F)); + return 1; + } + + if(version>=MVFST_VERSION_00&& version<=MVFST_VERSION_0F) + { + snprintf(buff, buff_len, "Facebook mvfst %02d", (version&0x0000000F)); + return 1; + } + + return 0; +} +
\ No newline at end of file diff --git a/src/version.map b/src/version.map new file mode 100644 index 0000000..db590f0 --- /dev/null +++ b/src/version.map @@ -0,0 +1,10 @@ +VERS_3.0{ +global: + extern "C" { + QUIC_ONLOAD; + QUIC_UNLOAD; + quic_version_int2string; + quic_message_*; + }; + local: *; +}; diff --git a/support/CMakeLists.txt b/support/CMakeLists.txt new file mode 100644 index 0000000..6c08350 --- /dev/null +++ b/support/CMakeLists.txt @@ -0,0 +1,28 @@ +# CMakeFiles for 3rd vendor library + +include(ExternalProject) + +### OpenSSL 1.1.1 +ExternalProject_Add(OpenSSL PREFIX openssl + URL ${CMAKE_CURRENT_SOURCE_DIR}/openssl-1.1.1l.tar.gz + URL_MD5 ac0d4387f3ba0ad741b0580dd45f6ff3 + CONFIGURE_COMMAND ./Configure linux-x86_64 --prefix=<INSTALL_DIR> --openssldir=<INSTALL_DIR>/lib/ssl enable-ec_nistp_64_gcc_128 no-shared + BUILD_COMMAND ${MAKE_COMMAND} + INSTALL_COMMAND make install_sw + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(OpenSSL INSTALL_DIR) +set(OPENSSL_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +set(OPENSSL_LINK_DIRECTORIES ${INSTALL_DIR}/lib) +set(OPENSSL_PKGCONFIG_PATH ${INSTALL_DIR}/lib/pkgconfig/) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) + +add_library(openssl-crypto-static STATIC IMPORTED GLOBAL) +add_dependencies(openssl-crypto-static OpenSSL) +set_property(TARGET openssl-crypto-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libcrypto.a) +set_property(TARGET openssl-crypto-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + +add_library(openssl-ssl-static STATIC IMPORTED GLOBAL) +add_dependencies(openssl-ssl-static OpenSSL) +set_property(TARGET openssl-ssl-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libssl.a) +set_property(TARGET openssl-ssl-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include)
\ No newline at end of file diff --git a/support/openssl-1.1.1l.tar.gz b/support/openssl-1.1.1l.tar.gz Binary files differnew file mode 100644 index 0000000..81be7f9 --- /dev/null +++ b/support/openssl-1.1.1l.tar.gz diff --git a/support/sapp-4.3.56.a47b3b5-1.el8.x86_64.rpm b/support/sapp-4.3.56.a47b3b5-1.el8.x86_64.rpm Binary files differnew file mode 100644 index 0000000..58e3f92 --- /dev/null +++ b/support/sapp-4.3.56.a47b3b5-1.el8.x86_64.rpm diff --git a/support/sapp-devel-4.3.56.a47b3b5-1.el8.x86_64.rpm b/support/sapp-devel-4.3.56.a47b3b5-1.el8.x86_64.rpm Binary files differnew file mode 100644 index 0000000..9affbf6 --- /dev/null +++ b/support/sapp-devel-4.3.56.a47b3b5-1.el8.x86_64.rpm diff --git a/support/stellar-on-sapp-2.1.1.7875675-1.el8.x86_64.rpm b/support/stellar-on-sapp-2.1.1.7875675-1.el8.x86_64.rpm Binary files differnew file mode 100644 index 0000000..695d6bc --- /dev/null +++ b/support/stellar-on-sapp-2.1.1.7875675-1.el8.x86_64.rpm diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..4ca4288 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required (VERSION 2.8...3.10) + +project(${lib_name}_test) + +set(proto_test_main plugin_test_main) +set(PROTO_TEST_RUN_DIR ${CMAKE_INSTALL_PREFIX}/sapp) + +add_library(${lib_name}_test_plug SHARED ${lib_name}_test_plug.cpp) +target_link_libraries(${lib_name}_test_plug MESA_prof_load cjson) +set_target_properties(${lib_name}_test_plug PROPERTIES PREFIX "") + +add_test(NAME COPY_QUIC_SO COMMAND sh -c "mkdir -p ${PROTO_TEST_RUN_DIR}/stellar_plugin/${lib_name} && cp ${CMAKE_BINARY_DIR}/src/${lib_name}.so ${PROTO_TEST_RUN_DIR}/stellar_plugin/${lib_name}/${lib_name}.so") +add_test(NAME COPY_TEST_SO COMMAND sh -c "mkdir -p ${PROTO_TEST_RUN_DIR}/stellar_plugin/${lib_name} && cp ${CMAKE_CURRENT_BINARY_DIR}/${lib_name}_test_plug.so ${PROTO_TEST_RUN_DIR}/stellar_plugin/${lib_name}/${lib_name}_test_plug.so") +add_test(NAME COPY_TEST_SPEC COMMAND sh -c "cp ${CMAKE_SOURCE_DIR}/bin/quic.inf ${PROTO_TEST_RUN_DIR}/stellar_plugin/spec.toml") +add_test(NAME COPY_PLUGIN_TEST_MAIN COMMAND sh -c "rpm -ql sapp | grep plugin_test_main | xargs -i cp -f {} ${PROTO_TEST_RUN_DIR}/") +add_test(NAME COPY_MAIN_CFG COMMAND sh -c "mkdir -p ${PROTO_TEST_RUN_DIR}/conf/quic_decoder && cp ${CMAKE_SOURCE_DIR}/bin/main.conf ${PROTO_TEST_RUN_DIR}/conf/quic_decoder/") +add_test(NAME COPY_QUIC_CFG COMMAND sh -c "mkdir -p ${PROTO_TEST_RUN_DIR}/conf/quic_decoder && cp ${CMAKE_SOURCE_DIR}/bin/quic.conf ${PROTO_TEST_RUN_DIR}/conf/quic_decoder/") +add_test(NAME UPDATE_SAPP_LOG_LEVEL COMMAND bash -c "sed -i 's/sapp_log.fatal/sapp_log.info/' ${PROTO_TEST_RUN_DIR}/etc/sapp_log.conf") + +set_tests_properties(COPY_QUIC_SO COPY_TEST_SO COPY_TEST_SPEC COPY_PLUGIN_TEST_MAIN COPY_MAIN_CFG COPY_QUIC_CFG UPDATE_SAPP_LOG_LEVEL + PROPERTIES FIXTURES_SETUP TestFixture) + +add_test(NAME IQUIC_29_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/iquic/29/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/iquic/29/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_23_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/23/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/23/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_25_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/25/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/25/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_33_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/33/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/33/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_34_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/34/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/34/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_35_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/35/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/35/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_37_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/37/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/37/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_39_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/39/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/39/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_41_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/41/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/41/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_43_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/43/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/43/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_44_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/44/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/44/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_46_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/46/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/46/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME GQUIC_50_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/50/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/gquic/50/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME MVFST_01_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/mvfst/01/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/mvfst/01/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME MVFST_02_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/mvfst/02/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/mvfst/02/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME TQUIC_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/tquic/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/tquic/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME IQUIC_PORT_8443_TEST COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/port-8443/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/port-8443/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME QUIC_RFC9000 COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME QUIC_RFC9000_FRAGMENT COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000-fragment/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000-fragment/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME QUIC_RFC9000_SPECIAL COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000-special/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000-special/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME QUIC_AIRPORT COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/airport/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/airport -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME QUIC_SPECIAL COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/special/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/special/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) +add_test(NAME QUIC_RFC9000_CHLO_FRAGMENT COMMAND ./${proto_test_main} ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000-chlo-fragment/quic_result.json -f "find ${CMAKE_CURRENT_SOURCE_DIR}/pcap/rfc9000-chlo-fragment/ -name *.pcap|sort -V" WORKING_DIRECTORY ${PROTO_TEST_RUN_DIR}) + +set_tests_properties(IQUIC_29_TEST + GQUIC_23_TEST + GQUIC_25_TEST + GQUIC_33_TEST + GQUIC_34_TEST + GQUIC_35_TEST + GQUIC_37_TEST + GQUIC_39_TEST + GQUIC_41_TEST + GQUIC_43_TEST + GQUIC_44_TEST + GQUIC_46_TEST + GQUIC_50_TEST + MVFST_01_TEST + MVFST_01_TEST + MVFST_02_TEST + TQUIC_TEST + IQUIC_PORT_8443_TEST + QUIC_RFC9000 + QUIC_RFC9000_FRAGMENT + QUIC_RFC9000_SPECIAL + QUIC_AIRPORT + QUIC_SPECIAL + QUIC_RFC9000_CHLO_FRAGMENT + PROPERTIES FIXTURES_REQUIRED TestFixture) +
\ No newline at end of file diff --git a/test/empty_array.json b/test/empty_array.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/test/empty_array.json @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/test/pcap/airport/Old-Airport-quic.pcap b/test/pcap/airport/Old-Airport-quic.pcap Binary files differnew file mode 100644 index 0000000..d6dc469 --- /dev/null +++ b/test/pcap/airport/Old-Airport-quic.pcap diff --git a/test/pcap/airport/quic_result.json b/test/pcap/airport/quic_result.json new file mode 100644 index 0000000..94b48cc --- /dev/null +++ b/test/pcap/airport/quic_result.json @@ -0,0 +1,94 @@ +[{ + "Tuple4": "10.56.160.76.44417>216.58.209.132.443", + "SNI": "www.google.com", + "UA": "com.google.android.googlequicksearchbox Cronet/96.0.4664.17", + "VERSION": "IETF QUIC RFC9000", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "10.56.160.76.47427>213.55.110.12.443", + "SNI": "r1---sn-xuj-5qqz.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "10.56.160.76.39996>142.250.185.33.443", + "SNI": "yt3.ggpht.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "IETF QUIC RFC9000", + "name": "QUIC_RESULT_3" + }, { + "Tuple4": "10.56.160.76.48527>216.58.209.130.443", + "SNI": "www.googleadservices.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "IETF QUIC RFC9000", + "name": "QUIC_RESULT_4" + }, { + "Tuple4": "10.56.160.76.43569>197.156.74.146.443", + "SNI": "r7---sn-xuj-5qqs.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_5" + }, { + "Tuple4": "10.56.160.76.52114>197.156.74.147.443", + "SNI": "r8---sn-xuj-5qqs.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_6" + }, { + "Tuple4": "10.56.160.76.59023>213.55.110.13.443", + "SNI": "r2---sn-xuj-5qqz.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_7" + }, { + "Tuple4": "10.56.160.76.46224>197.156.74.140.443", + "SNI": "r1---sn-xuj-5qqs.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_8" + }, { + "Tuple4": "10.56.160.76.54334>197.156.74.145.443", + "SNI": "r6---sn-xuj-5qqs.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_9" + }, { + "Tuple4": "10.56.160.76.41069>142.250.180.42.443", + "SNI": "youtubei.googleapis.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "IETF QUIC RFC9000", + "name": "QUIC_RESULT_10" + }, { + "Tuple4": "10.56.160.76.48756>213.55.110.14.443", + "SNI": "r3---sn-xuj-5qqz.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_11" + }, { + "Tuple4": "10.56.160.76.51113>142.250.180.54.443", + "SNI": "i.ytimg.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "IETF QUIC RFC9000", + "name": "QUIC_RESULT_12" + }, { + "Tuple4": "10.56.160.76.38866>197.156.74.141.443", + "SNI": "r2---sn-xuj-5qqs.googlevideo.com", + "UA": "com.google.android.youtube Cronet/96.0.4655.4", + "VERSION": "Google QUIC 43", + "name": "QUIC_RESULT_13" + }, { + "Tuple4": "10.56.160.76.46131>196.188.31.18.443", + "SNI": "video.fadd1-1.fna.fbcdn.net", + "VERSION": "Facebook mvfst 02", + "name": "QUIC_RESULT_14" + }, { + "Tuple4": "10.56.160.76.40267>102.132.96.18.443", + "SNI": "graph.facebook.com", + "VERSION": "Facebook mvfst 02", + "name": "QUIC_RESULT_15" + }, { + "Tuple4": "10.56.160.76.46761>196.188.31.17.443", + "SNI": "scontent.fadd1-1.fna.fbcdn.net", + "VERSION": "Facebook mvfst 02", + "name": "QUIC_RESULT_16" +}] diff --git a/test/pcap/gquic/23/1-gquic-023-85.117.117.169.47762-173.194.73.95.443.pcap b/test/pcap/gquic/23/1-gquic-023-85.117.117.169.47762-173.194.73.95.443.pcap Binary files differnew file mode 100644 index 0000000..db29a3b --- /dev/null +++ b/test/pcap/gquic/23/1-gquic-023-85.117.117.169.47762-173.194.73.95.443.pcap diff --git a/test/pcap/gquic/23/2-gquic-023-85.117.123.193.19270-64.233.165.95.443.pcap b/test/pcap/gquic/23/2-gquic-023-85.117.123.193.19270-64.233.165.95.443.pcap Binary files differnew file mode 100644 index 0000000..110620d --- /dev/null +++ b/test/pcap/gquic/23/2-gquic-023-85.117.123.193.19270-64.233.165.95.443.pcap diff --git a/test/pcap/gquic/23/quic_result.json b/test/pcap/gquic/23/quic_result.json new file mode 100644 index 0000000..27944d0 --- /dev/null +++ b/test/pcap/gquic/23/quic_result.json @@ -0,0 +1,12 @@ +[{ + "Tuple4": "85.117.117.169.47762>173.194.73.95.443", + "VERSION": "Google QUIC 23", + "SNI": "www.googleapis.com", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "85.117.123.193.19270>64.233.165.95.443", + "VERSION": "Google QUIC 23", + "SNI": "www.googleapis.com", + "SNI": "www.googleapis.com", + "name": "QUIC_RESULT_2" +}] diff --git a/test/pcap/gquic/25/1-gquic-025-85.117.113.98.4340-74.125.131.95.443.pcap b/test/pcap/gquic/25/1-gquic-025-85.117.113.98.4340-74.125.131.95.443.pcap Binary files differnew file mode 100644 index 0000000..299e573 --- /dev/null +++ b/test/pcap/gquic/25/1-gquic-025-85.117.113.98.4340-74.125.131.95.443.pcap diff --git a/test/pcap/gquic/25/2-gquic-025-90.143.184.225.63062-173.194.222.95.443.pcap b/test/pcap/gquic/25/2-gquic-025-90.143.184.225.63062-173.194.222.95.443.pcap Binary files differnew file mode 100644 index 0000000..ad5a080 --- /dev/null +++ b/test/pcap/gquic/25/2-gquic-025-90.143.184.225.63062-173.194.222.95.443.pcap diff --git a/test/pcap/gquic/25/quic_result.json b/test/pcap/gquic/25/quic_result.json new file mode 100644 index 0000000..3de6308 --- /dev/null +++ b/test/pcap/gquic/25/quic_result.json @@ -0,0 +1,12 @@ +[{ + "Tuple4": "85.117.113.98.4340>74.125.131.95.443", + "VERSION": "Google QUIC 25", + "SNI": "www.googleapis.com", + "SNI": "www.googleapis.com", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "90.143.184.225.63062>173.194.222.95.443", + "VERSION": "Google QUIC 25", + "SNI": "www.googleapis.com", + "name": "QUIC_RESULT_2" +}] diff --git a/test/pcap/gquic/33/1-gquic-033-90.143.189.5.8026-173.194.188.40.443.pcap b/test/pcap/gquic/33/1-gquic-033-90.143.189.5.8026-173.194.188.40.443.pcap Binary files differnew file mode 100644 index 0000000..b0e4c5b --- /dev/null +++ b/test/pcap/gquic/33/1-gquic-033-90.143.189.5.8026-173.194.188.40.443.pcap diff --git a/test/pcap/gquic/33/quic_result.json b/test/pcap/gquic/33/quic_result.json new file mode 100644 index 0000000..7df585e --- /dev/null +++ b/test/pcap/gquic/33/quic_result.json @@ -0,0 +1,9 @@ +[{ + "Tuple4": "90.143.189.5.8026>173.194.188.40.443", + "VERSION": "Google QUIC 33", + "SNI": "r3---sn-4g5ednse.googlevideo.com", + "UA": "com.google.android.youtube Cronet/53.0.2768.0", + "SNI": "r3---sn-4g5ednse.googlevideo.com", + "UA": "com.google.android.youtube Cronet/53.0.2768.0", + "name": "QUIC_RESULT_1" +}] diff --git a/test/pcap/gquic/34/1-gquic-034-85.117.125.8.21243-173.194.73.102.443.pcap b/test/pcap/gquic/34/1-gquic-034-85.117.125.8.21243-173.194.73.102.443.pcap Binary files differnew file mode 100644 index 0000000..eee3c8e --- /dev/null +++ b/test/pcap/gquic/34/1-gquic-034-85.117.125.8.21243-173.194.73.102.443.pcap diff --git a/test/pcap/gquic/34/quic_result.json b/test/pcap/gquic/34/quic_result.json new file mode 100644 index 0000000..cf4a4fc --- /dev/null +++ b/test/pcap/gquic/34/quic_result.json @@ -0,0 +1,9 @@ +[{ + "Tuple4": "85.117.125.8.21243>173.194.73.102.443", + "VERSION": "Google QUIC 34", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/54.0.2823.2", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/54.0.2823.2", + "name": "QUIC_RESULT_1" +}] diff --git a/test/pcap/gquic/35/1-gquic-035-redirector.googlevideo.com-85.117.122.194.32370-173.194.220.138.443.pcap b/test/pcap/gquic/35/1-gquic-035-redirector.googlevideo.com-85.117.122.194.32370-173.194.220.138.443.pcap Binary files differnew file mode 100644 index 0000000..5dc1f81 --- /dev/null +++ b/test/pcap/gquic/35/1-gquic-035-redirector.googlevideo.com-85.117.122.194.32370-173.194.220.138.443.pcap diff --git a/test/pcap/gquic/35/2-gquic-035-redirector.googlevideo.com-85.117.122.21.21396-173.194.220.138.443.pcap b/test/pcap/gquic/35/2-gquic-035-redirector.googlevideo.com-85.117.122.21.21396-173.194.220.138.443.pcap Binary files differnew file mode 100644 index 0000000..075c665 --- /dev/null +++ b/test/pcap/gquic/35/2-gquic-035-redirector.googlevideo.com-85.117.122.21.21396-173.194.220.138.443.pcap diff --git a/test/pcap/gquic/35/quic_result.json b/test/pcap/gquic/35/quic_result.json new file mode 100644 index 0000000..b2683ed --- /dev/null +++ b/test/pcap/gquic/35/quic_result.json @@ -0,0 +1,18 @@ +[{ + "Tuple4": "85.117.122.194.32370>173.194.220.138.443", + "VERSION": "Google QUIC 35", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/56.0.2900.3", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/56.0.2900.3", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/56.0.2900.3", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "85.117.122.21.21396>173.194.220.138.443", + "VERSION": "Google QUIC 35", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/59.0.3068.4", + "name": "QUIC_RESULT_2" +}] + diff --git a/test/pcap/gquic/37/1-gquic-037-10.32.121.249.33765-64.233.161.95.443.pcap b/test/pcap/gquic/37/1-gquic-037-10.32.121.249.33765-64.233.161.95.443.pcap Binary files differnew file mode 100644 index 0000000..ca6388d --- /dev/null +++ b/test/pcap/gquic/37/1-gquic-037-10.32.121.249.33765-64.233.161.95.443.pcap diff --git a/test/pcap/gquic/37/10-gquic-037-85.117.116.195.38495-173.194.222.132.443.pcap b/test/pcap/gquic/37/10-gquic-037-85.117.116.195.38495-173.194.222.132.443.pcap Binary files differnew file mode 100644 index 0000000..b7cc80a --- /dev/null +++ b/test/pcap/gquic/37/10-gquic-037-85.117.116.195.38495-173.194.222.132.443.pcap diff --git a/test/pcap/gquic/37/11-gquic-037-85.117.123.242.33040-64.233.162.95.443.pcap b/test/pcap/gquic/37/11-gquic-037-85.117.123.242.33040-64.233.162.95.443.pcap Binary files differnew file mode 100644 index 0000000..56a8add --- /dev/null +++ b/test/pcap/gquic/37/11-gquic-037-85.117.123.242.33040-64.233.162.95.443.pcap diff --git a/test/pcap/gquic/37/12-gquic-037-85.117.126.141.34209-64.233.164.132.443.pcap b/test/pcap/gquic/37/12-gquic-037-85.117.126.141.34209-64.233.164.132.443.pcap Binary files differnew file mode 100644 index 0000000..1e4bd53 --- /dev/null +++ b/test/pcap/gquic/37/12-gquic-037-85.117.126.141.34209-64.233.164.132.443.pcap diff --git a/test/pcap/gquic/37/13-gquic-037-85.117.126.166.46412-173.194.44.4.443.pcap b/test/pcap/gquic/37/13-gquic-037-85.117.126.166.46412-173.194.44.4.443.pcap Binary files differnew file mode 100644 index 0000000..e6a6b86 --- /dev/null +++ b/test/pcap/gquic/37/13-gquic-037-85.117.126.166.46412-173.194.44.4.443.pcap diff --git a/test/pcap/gquic/37/14-gquic-037-85.117.126.63.9977-64.233.165.113.443.pcap b/test/pcap/gquic/37/14-gquic-037-85.117.126.63.9977-64.233.165.113.443.pcap Binary files differnew file mode 100644 index 0000000..47024f1 --- /dev/null +++ b/test/pcap/gquic/37/14-gquic-037-85.117.126.63.9977-64.233.165.113.443.pcap diff --git a/test/pcap/gquic/37/15-gquic-037-85.117.126.68.44666-173.194.44.41.443.pcap b/test/pcap/gquic/37/15-gquic-037-85.117.126.68.44666-173.194.44.41.443.pcap Binary files differnew file mode 100644 index 0000000..0a7ebb8 --- /dev/null +++ b/test/pcap/gquic/37/15-gquic-037-85.117.126.68.44666-173.194.44.41.443.pcap diff --git a/test/pcap/gquic/37/16-gquic-037-90.143.176.79.38351-108.177.14.119.443.pcap b/test/pcap/gquic/37/16-gquic-037-90.143.176.79.38351-108.177.14.119.443.pcap Binary files differnew file mode 100644 index 0000000..b4624ff --- /dev/null +++ b/test/pcap/gquic/37/16-gquic-037-90.143.176.79.38351-108.177.14.119.443.pcap diff --git a/test/pcap/gquic/37/17-gquic-037-90.143.176.91.52171-173.194.222.101.443.pcap b/test/pcap/gquic/37/17-gquic-037-90.143.176.91.52171-173.194.222.101.443.pcap Binary files differnew file mode 100644 index 0000000..9ba5c8e --- /dev/null +++ b/test/pcap/gquic/37/17-gquic-037-90.143.176.91.52171-173.194.222.101.443.pcap diff --git a/test/pcap/gquic/37/18-gquic-037-90.143.178.25.15835-173.194.73.119.443.pcap b/test/pcap/gquic/37/18-gquic-037-90.143.178.25.15835-173.194.73.119.443.pcap Binary files differnew file mode 100644 index 0000000..6bd5b74 --- /dev/null +++ b/test/pcap/gquic/37/18-gquic-037-90.143.178.25.15835-173.194.73.119.443.pcap diff --git a/test/pcap/gquic/37/19-gquic-037-90.143.179.24.35032-173.194.32.196.443.pcap b/test/pcap/gquic/37/19-gquic-037-90.143.179.24.35032-173.194.32.196.443.pcap Binary files differnew file mode 100644 index 0000000..cc4016b --- /dev/null +++ b/test/pcap/gquic/37/19-gquic-037-90.143.179.24.35032-173.194.32.196.443.pcap diff --git a/test/pcap/gquic/37/2-gquic-037-10.35.127.134.42356-64.233.165.139.443.pcap b/test/pcap/gquic/37/2-gquic-037-10.35.127.134.42356-64.233.165.139.443.pcap Binary files differnew file mode 100644 index 0000000..86d19de --- /dev/null +++ b/test/pcap/gquic/37/2-gquic-037-10.35.127.134.42356-64.233.165.139.443.pcap diff --git a/test/pcap/gquic/37/20-gquic-037-90.143.180.185.57766-173.194.32.196.443.pcap b/test/pcap/gquic/37/20-gquic-037-90.143.180.185.57766-173.194.32.196.443.pcap Binary files differnew file mode 100644 index 0000000..efef52d --- /dev/null +++ b/test/pcap/gquic/37/20-gquic-037-90.143.180.185.57766-173.194.32.196.443.pcap diff --git a/test/pcap/gquic/37/21-gquic-037-90.143.183.75.19770-74.125.232.167.443.pcap b/test/pcap/gquic/37/21-gquic-037-90.143.183.75.19770-74.125.232.167.443.pcap Binary files differnew file mode 100644 index 0000000..9f5694a --- /dev/null +++ b/test/pcap/gquic/37/21-gquic-037-90.143.183.75.19770-74.125.232.167.443.pcap diff --git a/test/pcap/gquic/37/22-gquic-037-90.143.184.225.24092-173.194.222.95.443.pcap b/test/pcap/gquic/37/22-gquic-037-90.143.184.225.24092-173.194.222.95.443.pcap Binary files differnew file mode 100644 index 0000000..aeb088b --- /dev/null +++ b/test/pcap/gquic/37/22-gquic-037-90.143.184.225.24092-173.194.222.95.443.pcap diff --git a/test/pcap/gquic/37/23-gquic-037-90.143.185.235.17239-173.194.44.6.443.pcap b/test/pcap/gquic/37/23-gquic-037-90.143.185.235.17239-173.194.44.6.443.pcap Binary files differnew file mode 100644 index 0000000..02ea34e --- /dev/null +++ b/test/pcap/gquic/37/23-gquic-037-90.143.185.235.17239-173.194.44.6.443.pcap diff --git a/test/pcap/gquic/37/24-gquic-037-90.143.186.194.32570-173.194.44.1.443.pcap b/test/pcap/gquic/37/24-gquic-037-90.143.186.194.32570-173.194.44.1.443.pcap Binary files differnew file mode 100644 index 0000000..dfcff8b --- /dev/null +++ b/test/pcap/gquic/37/24-gquic-037-90.143.186.194.32570-173.194.44.1.443.pcap diff --git a/test/pcap/gquic/37/25-gquic-037-90.143.188.47.22565-64.233.162.95.443.pcap b/test/pcap/gquic/37/25-gquic-037-90.143.188.47.22565-64.233.162.95.443.pcap Binary files differnew file mode 100644 index 0000000..6bb7f96 --- /dev/null +++ b/test/pcap/gquic/37/25-gquic-037-90.143.188.47.22565-64.233.162.95.443.pcap diff --git a/test/pcap/gquic/37/26-gquic-037-90.143.190.56.19723-108.177.14.102.443.pcap b/test/pcap/gquic/37/26-gquic-037-90.143.190.56.19723-108.177.14.102.443.pcap Binary files differnew file mode 100644 index 0000000..40492fd --- /dev/null +++ b/test/pcap/gquic/37/26-gquic-037-90.143.190.56.19723-108.177.14.102.443.pcap diff --git a/test/pcap/gquic/37/3-gquic-037-185.57.74.232.43276-173.194.44.78.443.pcap b/test/pcap/gquic/37/3-gquic-037-185.57.74.232.43276-173.194.44.78.443.pcap Binary files differnew file mode 100644 index 0000000..4b3660b --- /dev/null +++ b/test/pcap/gquic/37/3-gquic-037-185.57.74.232.43276-173.194.44.78.443.pcap diff --git a/test/pcap/gquic/37/4-gquic-037-185.57.74.32.52134-74.125.232.249.443.pcap b/test/pcap/gquic/37/4-gquic-037-185.57.74.32.52134-74.125.232.249.443.pcap Binary files differnew file mode 100644 index 0000000..d075163 --- /dev/null +++ b/test/pcap/gquic/37/4-gquic-037-185.57.74.32.52134-74.125.232.249.443.pcap diff --git a/test/pcap/gquic/37/5-gquic-037-195.162.27.132.31404-217.76.77.81.443.pcap b/test/pcap/gquic/37/5-gquic-037-195.162.27.132.31404-217.76.77.81.443.pcap Binary files differnew file mode 100644 index 0000000..73eec87 --- /dev/null +++ b/test/pcap/gquic/37/5-gquic-037-195.162.27.132.31404-217.76.77.81.443.pcap diff --git a/test/pcap/gquic/37/6-gquic-037-195.162.27.132.31405-217.76.77.81.443.pcap b/test/pcap/gquic/37/6-gquic-037-195.162.27.132.31405-217.76.77.81.443.pcap Binary files differnew file mode 100644 index 0000000..b78a422 --- /dev/null +++ b/test/pcap/gquic/37/6-gquic-037-195.162.27.132.31405-217.76.77.81.443.pcap diff --git a/test/pcap/gquic/37/7-gquic-037-85.117.112.160.21969-64.233.165.95.443.pcap b/test/pcap/gquic/37/7-gquic-037-85.117.112.160.21969-64.233.165.95.443.pcap Binary files differnew file mode 100644 index 0000000..8b53513 --- /dev/null +++ b/test/pcap/gquic/37/7-gquic-037-85.117.112.160.21969-64.233.165.95.443.pcap diff --git a/test/pcap/gquic/37/8-gquic-037-85.117.113.62.29644-173.194.73.95.443.pcap b/test/pcap/gquic/37/8-gquic-037-85.117.113.62.29644-173.194.73.95.443.pcap Binary files differnew file mode 100644 index 0000000..370b9fc --- /dev/null +++ b/test/pcap/gquic/37/8-gquic-037-85.117.113.62.29644-173.194.73.95.443.pcap diff --git a/test/pcap/gquic/37/9-gquic-037-85.117.116.192.18140-173.194.44.1.443.pcap b/test/pcap/gquic/37/9-gquic-037-85.117.116.192.18140-173.194.44.1.443.pcap Binary files differnew file mode 100644 index 0000000..234e1c8 --- /dev/null +++ b/test/pcap/gquic/37/9-gquic-037-85.117.116.192.18140-173.194.44.1.443.pcap diff --git a/test/pcap/gquic/37/quic_result.json b/test/pcap/gquic/37/quic_result.json new file mode 100644 index 0000000..9b31ec5 --- /dev/null +++ b/test/pcap/gquic/37/quic_result.json @@ -0,0 +1,175 @@ +[{ + "Tuple4": "90.143.185.235.17239>173.194.44.6.443", + "VERSION": "Google QUIC 37", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "10.32.121.249.33765>64.233.161.95.443", + "VERSION": "Google QUIC 37", + "SNI": "instantmessaging-pa.googleapis.com", + "UA": "com.google.android.apps.tachyon Cronet/61.0.3142.0", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "10.35.127.134.42356>64.233.165.139.443", + "VERSION": "Google QUIC 37", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/60.0.3108.3", + "name": "QUIC_RESULT_3" + }, { + "Tuple4": "185.57.74.232.43276>173.194.44.78.443", + "VERSION": "Google QUIC 37", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_4" + }, { + "Tuple4": "185.57.74.32.52134>74.125.232.249.443", + "VERSION": "Google QUIC 37", + "SNI": "googleads.g.doubleclick.net", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_5" + }, { + "Tuple4": "195.162.27.132.31404>217.76.77.81.443", + "VERSION": "Google QUIC 37", + "SNI": "r6---sn-5auxa-unxe.googlevideo.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_6" + }, { + "Tuple4": "195.162.27.132.31405>217.76.77.81.443", + "VERSION": "Google QUIC 37", + "SNI": "r6---sn-5auxa-unxe.googlevideo.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_7" + }, { + "Tuple4": "85.117.112.160.21969>64.233.165.95.443", + "VERSION": "Google QUIC 37", + "SNI": "www.googleapis.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "name": "QUIC_RESULT_8" + }, { + "Tuple4": "85.117.113.62.29644>173.194.73.95.443", + "VERSION": "Google QUIC 37", + "SNI": "youtubei.googleapis.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_9" + }, { + "Tuple4": "85.117.116.192.18140>173.194.44.1.443", + "VERSION": "Google QUIC 37", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_10" + }, { + "Tuple4": "85.117.116.195.38495>173.194.222.132.443", + "VERSION": "Google QUIC 37", + "SNI": "yt3.ggpht.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_11" + }, { + "Tuple4": "85.117.123.242.33040>64.233.162.95.443", + "VERSION": "Google QUIC 37", + "SNI": "www.googleapis.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_12" + }, { + "Tuple4": "85.117.126.141.34209>64.233.164.132.443", + "VERSION": "Google QUIC 37", + "SNI": "yt3.ggpht.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "SNI": "yt3.ggpht.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "SNI": "yt3.ggpht.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "name": "QUIC_RESULT_13" + }, { + "Tuple4": "85.117.126.166.46412>173.194.44.4.443", + "VERSION": "Google QUIC 37", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_14" + }, { + "Tuple4": "85.117.126.63.9977>64.233.165.113.443", + "VERSION": "Google QUIC 37", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3136.4", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3136.4", + "name": "QUIC_RESULT_15" + }, { + "Tuple4": "85.117.126.68.44666>173.194.44.41.443", + "VERSION": "Google QUIC 37", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3124.3", + "name": "QUIC_RESULT_16" + }, { + "Tuple4": "90.143.176.79.38351>108.177.14.119.443", + "VERSION": "Google QUIC 37", + "SNI": "i.ytimg.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_17" + }, { + "Tuple4": "90.143.176.91.52171>173.194.222.101.443", + "VERSION": "Google QUIC 37", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3142.0", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3142.0", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3142.0", + "name": "QUIC_RESULT_18" + }, { + "Tuple4": "90.143.178.25.15835>173.194.73.119.443", + "VERSION": "Google QUIC 37", + "SNI": "i.ytimg.com", + "UA": "com.google.android.youtube Cronet/61.0.3129.3", + "name": "QUIC_RESULT_19" + }, { + "Tuple4": "90.143.179.24.35032>173.194.32.196.443", + "VERSION": "Google QUIC 37", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3124.3", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3124.3", + "name": "QUIC_RESULT_20" + }, { + "Tuple4": "90.143.180.185.57766>173.194.32.196.443", + "VERSION": "Google QUIC 37", + "SNI": "clients4.google.com", + "UA": "com.google.android.apps.maps Cronet/61.0.3142.0", + "name": "QUIC_RESULT_21" + }, { + "Tuple4": "90.143.183.75.19770>74.125.232.167.443", + "VERSION": "Google QUIC 37", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_22" + }, { + "Tuple4": "90.143.184.225.24092>173.194.222.95.443", + "VERSION": "Google QUIC 37", + "SNI": "youtubei.googleapis.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "name": "QUIC_RESULT_23" + }, { + "Tuple4": "90.143.186.194.32570>173.194.44.1.443", + "VERSION": "Google QUIC 37", + "SNI": "www.youtube.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_24" + }, { + "Tuple4": "90.143.188.47.22565>64.233.162.95.443", + "VERSION": "Google QUIC 37", + "SNI": "youtubei.googleapis.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "SNI": "youtubei.googleapis.com", + "UA": "com.google.android.youtube Cronet/61.0.3142.0", + "name": "QUIC_RESULT_25" + }, { + "Tuple4": "90.143.190.56.19723>108.177.14.102.443", + "VERSION": "Google QUIC 37", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/60.0.3112.12", + "name": "QUIC_RESULT_26" +}] diff --git a/test/pcap/gquic/39/1-gquic-039-redirector.googlevideo.com-85.117.119.45.22495-173.194.73.101.443.pcap b/test/pcap/gquic/39/1-gquic-039-redirector.googlevideo.com-85.117.119.45.22495-173.194.73.101.443.pcap Binary files differnew file mode 100644 index 0000000..bd088b0 --- /dev/null +++ b/test/pcap/gquic/39/1-gquic-039-redirector.googlevideo.com-85.117.119.45.22495-173.194.73.101.443.pcap diff --git a/test/pcap/gquic/39/quic_result.json b/test/pcap/gquic/39/quic_result.json new file mode 100644 index 0000000..6528c33 --- /dev/null +++ b/test/pcap/gquic/39/quic_result.json @@ -0,0 +1,13 @@ +[{ + "Tuple4": "85.117.119.45.22495>173.194.73.101.443", + "VERSION": "Google QUIC 39", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/65.0.3322.0", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/65.0.3322.0", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/65.0.3322.0", + "SNI": "redirector.googlevideo.com", + "UA": "com.google.android.youtube Cronet/65.0.3322.0", + "name": "QUIC_RESULT_1" +}] diff --git a/test/pcap/gquic/41/1-gquic-041-90.143.180.56.28496-64.233.165.113.443.pcap b/test/pcap/gquic/41/1-gquic-041-90.143.180.56.28496-64.233.165.113.443.pcap Binary files differnew file mode 100644 index 0000000..0a6e5ff --- /dev/null +++ b/test/pcap/gquic/41/1-gquic-041-90.143.180.56.28496-64.233.165.113.443.pcap diff --git a/test/pcap/gquic/41/2-gquic-041-90.143.189.30.53357-64.233.165.95.443.pcap b/test/pcap/gquic/41/2-gquic-041-90.143.189.30.53357-64.233.165.95.443.pcap Binary files differnew file mode 100644 index 0000000..171c264 --- /dev/null +++ b/test/pcap/gquic/41/2-gquic-041-90.143.189.30.53357-64.233.165.95.443.pcap diff --git a/test/pcap/gquic/41/quic_result.json b/test/pcap/gquic/41/quic_result.json new file mode 100644 index 0000000..30d0cc2 --- /dev/null +++ b/test/pcap/gquic/41/quic_result.json @@ -0,0 +1,15 @@ +[{ + "Tuple4": "90.143.180.56.28496>64.233.165.113.443", + "VERSION": "Google QUIC 41", + "SNI": "s.youtube.com", + "UA": "com.google.android.youtube Cronet/66.0.3335.4", + "SNI": "s.youtube.com", + "UA": "com.google.android.youtube Cronet/66.0.3335.4", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "90.143.189.30.53357>64.233.165.95.443", + "VERSION": "Google QUIC 41", + "SNI": "youtubei.googleapis.com", + "UA": "com.google.android.youtube Cronet/66.0.3335.4", + "name": "QUIC_RESULT_2" +}] diff --git a/test/pcap/gquic/43/1-gquic-043-client.weixin.qq.com-112.43.145.231.18699-112.46.25.216.443.pcap b/test/pcap/gquic/43/1-gquic-043-client.weixin.qq.com-112.43.145.231.18699-112.46.25.216.443.pcap Binary files differnew file mode 100644 index 0000000..0abc861 --- /dev/null +++ b/test/pcap/gquic/43/1-gquic-043-client.weixin.qq.com-112.43.145.231.18699-112.46.25.216.443.pcap diff --git a/test/pcap/gquic/43/2-gquic-043-without-sni-192.168.50.26.55209-34.102.215.99.443.pcap b/test/pcap/gquic/43/2-gquic-043-without-sni-192.168.50.26.55209-34.102.215.99.443.pcap Binary files differnew file mode 100644 index 0000000..ae75b00 --- /dev/null +++ b/test/pcap/gquic/43/2-gquic-043-without-sni-192.168.50.26.55209-34.102.215.99.443.pcap diff --git a/test/pcap/gquic/43/3-gquic-043-without-sni-192.168.50.26.60851-34.102.215.99.443.pcap b/test/pcap/gquic/43/3-gquic-043-without-sni-192.168.50.26.60851-34.102.215.99.443.pcap Binary files differnew file mode 100644 index 0000000..3bad2e1 --- /dev/null +++ b/test/pcap/gquic/43/3-gquic-043-without-sni-192.168.50.26.60851-34.102.215.99.443.pcap diff --git a/test/pcap/gquic/43/quic_result.json b/test/pcap/gquic/43/quic_result.json new file mode 100644 index 0000000..44eb443 --- /dev/null +++ b/test/pcap/gquic/43/quic_result.json @@ -0,0 +1,8 @@ +[ + { + "Tuple4": "112.43.145.231.18699>112.46.25.216.443", + "VERSION": "Google QUIC 43", + "SNI": "client.weixin.qq.com", + "name": "QUIC_RESULT_1" + } +]
\ No newline at end of file diff --git a/test/pcap/gquic/44/1-gquic-044-146.158.67.194.1044-108.177.14.138.443.pcap b/test/pcap/gquic/44/1-gquic-044-146.158.67.194.1044-108.177.14.138.443.pcap Binary files differnew file mode 100644 index 0000000..204f860 --- /dev/null +++ b/test/pcap/gquic/44/1-gquic-044-146.158.67.194.1044-108.177.14.138.443.pcap diff --git a/test/pcap/gquic/44/10-gquic-044-85.117.117.190.48098-173.194.221.95.443.pcap b/test/pcap/gquic/44/10-gquic-044-85.117.117.190.48098-173.194.221.95.443.pcap Binary files differnew file mode 100644 index 0000000..7090d7d --- /dev/null +++ b/test/pcap/gquic/44/10-gquic-044-85.117.117.190.48098-173.194.221.95.443.pcap diff --git a/test/pcap/gquic/44/11-gquic-044-85.117.119.57.4009-64.233.162.155.443.pcap b/test/pcap/gquic/44/11-gquic-044-85.117.119.57.4009-64.233.162.155.443.pcap Binary files differnew file mode 100644 index 0000000..480a855 --- /dev/null +++ b/test/pcap/gquic/44/11-gquic-044-85.117.119.57.4009-64.233.162.155.443.pcap diff --git a/test/pcap/gquic/44/12-gquic-044-85.117.126.11.11719-64.233.165.138.443.pcap b/test/pcap/gquic/44/12-gquic-044-85.117.126.11.11719-64.233.165.138.443.pcap Binary files differnew file mode 100644 index 0000000..e55a95c --- /dev/null +++ b/test/pcap/gquic/44/12-gquic-044-85.117.126.11.11719-64.233.165.138.443.pcap diff --git a/test/pcap/gquic/44/13-gquic-044-85.117.126.11.29355-173.194.220.94.443.pcap b/test/pcap/gquic/44/13-gquic-044-85.117.126.11.29355-173.194.220.94.443.pcap Binary files differnew file mode 100644 index 0000000..ad1eee6 --- /dev/null +++ b/test/pcap/gquic/44/13-gquic-044-85.117.126.11.29355-173.194.220.94.443.pcap diff --git a/test/pcap/gquic/44/14-gquic-044-85.117.126.11.45264-74.125.205.102.443.pcap b/test/pcap/gquic/44/14-gquic-044-85.117.126.11.45264-74.125.205.102.443.pcap Binary files differnew file mode 100644 index 0000000..5e88d98 --- /dev/null +++ b/test/pcap/gquic/44/14-gquic-044-85.117.126.11.45264-74.125.205.102.443.pcap diff --git a/test/pcap/gquic/44/15-gquic-044-89.218.169.150.55676-173.194.32.238.443.pcap b/test/pcap/gquic/44/15-gquic-044-89.218.169.150.55676-173.194.32.238.443.pcap Binary files differnew file mode 100644 index 0000000..7b6ccf8 --- /dev/null +++ b/test/pcap/gquic/44/15-gquic-044-89.218.169.150.55676-173.194.32.238.443.pcap diff --git a/test/pcap/gquic/44/16-gquic-044-89.218.79.162.64017-173.194.73.95.443.pcap b/test/pcap/gquic/44/16-gquic-044-89.218.79.162.64017-173.194.73.95.443.pcap Binary files differnew file mode 100644 index 0000000..54eeee5 --- /dev/null +++ b/test/pcap/gquic/44/16-gquic-044-89.218.79.162.64017-173.194.73.95.443.pcap diff --git a/test/pcap/gquic/44/17-gquic-044-90.143.176.186.54278-173.194.32.194.443.pcap b/test/pcap/gquic/44/17-gquic-044-90.143.176.186.54278-173.194.32.194.443.pcap Binary files differnew file mode 100644 index 0000000..9910d74 --- /dev/null +++ b/test/pcap/gquic/44/17-gquic-044-90.143.176.186.54278-173.194.32.194.443.pcap diff --git a/test/pcap/gquic/44/18-gquic-044-90.143.177.184.59077-74.125.232.247.443.pcap b/test/pcap/gquic/44/18-gquic-044-90.143.177.184.59077-74.125.232.247.443.pcap Binary files differnew file mode 100644 index 0000000..8385e43 --- /dev/null +++ b/test/pcap/gquic/44/18-gquic-044-90.143.177.184.59077-74.125.232.247.443.pcap diff --git a/test/pcap/gquic/44/19-gquic-044-90.143.177.184.5951-173.194.44.26.443.pcap b/test/pcap/gquic/44/19-gquic-044-90.143.177.184.5951-173.194.44.26.443.pcap Binary files differnew file mode 100644 index 0000000..89c797d --- /dev/null +++ b/test/pcap/gquic/44/19-gquic-044-90.143.177.184.5951-173.194.44.26.443.pcap diff --git a/test/pcap/gquic/44/2-gquic-044-185.57.75.21.44739-173.194.73.132.443.pcap b/test/pcap/gquic/44/2-gquic-044-185.57.75.21.44739-173.194.73.132.443.pcap Binary files differnew file mode 100644 index 0000000..200d565 --- /dev/null +++ b/test/pcap/gquic/44/2-gquic-044-185.57.75.21.44739-173.194.73.132.443.pcap diff --git a/test/pcap/gquic/44/20-gquic-044-90.143.178.243.51779-64.233.164.94.443.pcap b/test/pcap/gquic/44/20-gquic-044-90.143.178.243.51779-64.233.164.94.443.pcap Binary files differnew file mode 100644 index 0000000..d6e0a88 --- /dev/null +++ b/test/pcap/gquic/44/20-gquic-044-90.143.178.243.51779-64.233.164.94.443.pcap diff --git a/test/pcap/gquic/44/21-gquic-044-90.143.181.226.34777-74.125.232.237.443.pcap b/test/pcap/gquic/44/21-gquic-044-90.143.181.226.34777-74.125.232.237.443.pcap Binary files differnew file mode 100644 index 0000000..d9b386f --- /dev/null +++ b/test/pcap/gquic/44/21-gquic-044-90.143.181.226.34777-74.125.232.237.443.pcap diff --git a/test/pcap/gquic/44/22-gquic-044-90.143.181.245.31397-74.125.232.191.443.pcap b/test/pcap/gquic/44/22-gquic-044-90.143.181.245.31397-74.125.232.191.443.pcap Binary files differnew file mode 100644 index 0000000..d7509ec --- /dev/null +++ b/test/pcap/gquic/44/22-gquic-044-90.143.181.245.31397-74.125.232.191.443.pcap diff --git a/test/pcap/gquic/44/23-gquic-044-90.143.187.227.10862-64.233.165.139.443.pcap b/test/pcap/gquic/44/23-gquic-044-90.143.187.227.10862-64.233.165.139.443.pcap Binary files differnew file mode 100644 index 0000000..554174e --- /dev/null +++ b/test/pcap/gquic/44/23-gquic-044-90.143.187.227.10862-64.233.165.139.443.pcap diff --git a/test/pcap/gquic/44/24-gquic-044-90.143.187.227.10863-64.233.165.139.443.pcap b/test/pcap/gquic/44/24-gquic-044-90.143.187.227.10863-64.233.165.139.443.pcap Binary files differnew file mode 100644 index 0000000..b46e376 --- /dev/null +++ b/test/pcap/gquic/44/24-gquic-044-90.143.187.227.10863-64.233.165.139.443.pcap diff --git a/test/pcap/gquic/44/25-gquic-044-90.143.187.227.4586-173.194.44.58.443.pcap b/test/pcap/gquic/44/25-gquic-044-90.143.187.227.4586-173.194.44.58.443.pcap Binary files differnew file mode 100644 index 0000000..73d1ca6 --- /dev/null +++ b/test/pcap/gquic/44/25-gquic-044-90.143.187.227.4586-173.194.44.58.443.pcap diff --git a/test/pcap/gquic/44/26-gquic-044-90.143.188.64.2542-64.233.165.94.443.pcap b/test/pcap/gquic/44/26-gquic-044-90.143.188.64.2542-64.233.165.94.443.pcap Binary files differnew file mode 100644 index 0000000..5e733b0 --- /dev/null +++ b/test/pcap/gquic/44/26-gquic-044-90.143.188.64.2542-64.233.165.94.443.pcap diff --git a/test/pcap/gquic/44/27-gquic-044-90.143.191.8.24288-173.194.113.183.443.pcap b/test/pcap/gquic/44/27-gquic-044-90.143.191.8.24288-173.194.113.183.443.pcap Binary files differnew file mode 100644 index 0000000..f896d56 --- /dev/null +++ b/test/pcap/gquic/44/27-gquic-044-90.143.191.8.24288-173.194.113.183.443.pcap diff --git a/test/pcap/gquic/44/3-gquic-044-212.154.234.46.62716-74.125.131.156.443.pcap b/test/pcap/gquic/44/3-gquic-044-212.154.234.46.62716-74.125.131.156.443.pcap Binary files differnew file mode 100644 index 0000000..963dc30 --- /dev/null +++ b/test/pcap/gquic/44/3-gquic-044-212.154.234.46.62716-74.125.131.156.443.pcap diff --git a/test/pcap/gquic/44/4-gquic-044-2.135.246.186.56653-173.194.113.166.443.pcap b/test/pcap/gquic/44/4-gquic-044-2.135.246.186.56653-173.194.113.166.443.pcap Binary files differnew file mode 100644 index 0000000..677f71b --- /dev/null +++ b/test/pcap/gquic/44/4-gquic-044-2.135.246.186.56653-173.194.113.166.443.pcap diff --git a/test/pcap/gquic/44/5-gquic-044-85.117.110.235.48996-74.125.131.211.443.pcap b/test/pcap/gquic/44/5-gquic-044-85.117.110.235.48996-74.125.131.211.443.pcap Binary files differnew file mode 100644 index 0000000..a794995 --- /dev/null +++ b/test/pcap/gquic/44/5-gquic-044-85.117.110.235.48996-74.125.131.211.443.pcap diff --git a/test/pcap/gquic/44/6-gquic-044-85.117.112.180.21665-173.194.113.153.443.pcap b/test/pcap/gquic/44/6-gquic-044-85.117.112.180.21665-173.194.113.153.443.pcap Binary files differnew file mode 100644 index 0000000..bc0302d --- /dev/null +++ b/test/pcap/gquic/44/6-gquic-044-85.117.112.180.21665-173.194.113.153.443.pcap diff --git a/test/pcap/gquic/44/7-gquic-044-85.117.112.180.61808-64.233.165.132.443.pcap b/test/pcap/gquic/44/7-gquic-044-85.117.112.180.61808-64.233.165.132.443.pcap Binary files differnew file mode 100644 index 0000000..de7e692 --- /dev/null +++ b/test/pcap/gquic/44/7-gquic-044-85.117.112.180.61808-64.233.165.132.443.pcap diff --git a/test/pcap/gquic/44/8-gquic-044-85.117.114.90.16060-64.233.165.94.443.pcap b/test/pcap/gquic/44/8-gquic-044-85.117.114.90.16060-64.233.165.94.443.pcap Binary files differnew file mode 100644 index 0000000..4f2dcaf --- /dev/null +++ b/test/pcap/gquic/44/8-gquic-044-85.117.114.90.16060-64.233.165.94.443.pcap diff --git a/test/pcap/gquic/44/9-gquic-044-85.117.117.190.11567-64.233.165.94.443.pcap b/test/pcap/gquic/44/9-gquic-044-85.117.117.190.11567-64.233.165.94.443.pcap Binary files differnew file mode 100644 index 0000000..fcb85c1 --- /dev/null +++ b/test/pcap/gquic/44/9-gquic-044-85.117.117.190.11567-64.233.165.94.443.pcap diff --git a/test/pcap/gquic/44/quic_result.json b/test/pcap/gquic/44/quic_result.json new file mode 100644 index 0000000..4f4e400 --- /dev/null +++ b/test/pcap/gquic/44/quic_result.json @@ -0,0 +1,187 @@ +[ + { + "Tuple4": "185.57.75.21.44739>173.194.73.132.443", + "VERSION": "Google QUIC 44", + "SNI": "yt3.ggpht.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_1" + }, + { + "Tuple4": "212.154.234.46.62716>74.125.131.156.443", + "VERSION": "Google QUIC 44", + "SNI": "stats.g.doubleclick.net", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_2" + }, + { + "Tuple4": "2.135.246.186.56653>173.194.113.166.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google-analytics.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1", + "name": "QUIC_RESULT_3" + }, + { + "Tuple4": "85.117.110.235.48996>74.125.131.211.443", + "VERSION": "Google QUIC 44", + "SNI": "proxy.googlezip.net", + "UA": "dev Chrome/73.0.3667.2 Android 4.4.2; SM-G900F", + "name": "QUIC_RESULT_4" + }, + { + "Tuple4": "85.117.112.180.21665>173.194.113.153.443", + "VERSION": "Google QUIC 44", + "SNI": "adservice.google.kz", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.2; WOW64", + "name": "QUIC_RESULT_5" + }, + { + "Tuple4": "85.117.112.180.61808>64.233.165.132.443", + "VERSION": "Google QUIC 44", + "SNI": "yt3.ggpht.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.2; WOW64", + "name": "QUIC_RESULT_6" + }, + { + "Tuple4": "85.117.114.90.16060>64.233.165.94.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google.kz", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "SNI": "www.google.kz", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_7" + }, + { + "Tuple4": "85.117.117.190.11567>64.233.165.94.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google.kz", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.3; Win64; x64", + "name": "QUIC_RESULT_8" + }, + { + "Tuple4": "85.117.117.190.48098>173.194.221.95.443", + "VERSION": "Google QUIC 44", + "SNI": "safebrowsing.googleapis.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.3; Win64; x64", + "name": "QUIC_RESULT_9" + }, + { + "Tuple4": "85.117.119.57.4009>64.233.162.155.443", + "VERSION": "Google QUIC 44", + "SNI": "stats.g.doubleclick.net", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_10" + }, + { + "Tuple4": "85.117.126.11.11719>64.233.165.138.443", + "VERSION": "Google QUIC 44", + "SNI": "play.google.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_11" + }, + { + "Tuple4": "85.117.126.11.29355>173.194.220.94.443", + "VERSION": "Google QUIC 44", + "SNI": "beacons3.gvt2.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_12" + }, + { + "Tuple4": "85.117.126.11.45264>74.125.205.102.443", + "VERSION": "Google QUIC 44", + "SNI": "clients2.google.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_13" + }, + { + "Tuple4": "89.218.169.150.55676>173.194.32.238.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google-analytics.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_14" + }, + { + "Tuple4": "89.218.79.162.64017>173.194.73.95.443", + "VERSION": "Google QUIC 44", + "SNI": "ajax.googleapis.com", + "UA": "canary Chrome/73.0.3671.3 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_15" + }, + { + "Tuple4": "90.143.176.186.54278>173.194.32.194.443", + "VERSION": "Google QUIC 44", + "SNI": "clients4.google.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_16" + }, + { + "Tuple4": "90.143.177.184.59077>74.125.232.247.443", + "VERSION": "Google QUIC 44", + "SNI": "www.gstatic.com", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; WOW64", + "name": "QUIC_RESULT_17" + }, + { + "Tuple4": "90.143.177.184.5951>173.194.44.26.443", + "VERSION": "Google QUIC 44", + "SNI": "googleads.g.doubleclick.net", + "UA": "dev Chrome/73.0.3664.3 Windows NT 6.1; WOW64", + "name": "QUIC_RESULT_18" + }, + { + "Tuple4": "90.143.178.243.51779>64.233.164.94.443", + "VERSION": "Google QUIC 44", + "SNI": "update.googleapis.com", + "UA": "canary Chrome/73.0.3672.0 Windows NT 10.0; Win64; x64", + "SNI": "update.googleapis.com", + "UA": "canary Chrome/73.0.3672.0 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_19" + }, + { + "Tuple4": "90.143.181.226.34777>74.125.232.237.443", + "VERSION": "Google QUIC 44", + "SNI": "googleads.g.doubleclick.net", + "UA": "dev Chrome/73.0.3664.3 Windows NT 10.0; Win64; x64", + "SNI": "googleads.g.doubleclick.net", + "UA": "dev Chrome/73.0.3664.3 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_20" + }, + { + "Tuple4": "90.143.181.245.31397>74.125.232.191.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google.kz", + "UA": "dev Chrome/73.0.3664.3 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_21" + }, + { + "Tuple4": "90.143.187.227.10862>64.233.165.139.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google-analytics.com", + "UA": "canary Chrome/73.0.3672.0 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_22" + }, + { + "Tuple4": "90.143.187.227.10863>64.233.165.139.443", + "VERSION": "Google QUIC 44", + "SNI": "www.google-analytics.com", + "UA": "canary Chrome/73.0.3672.0 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_23" + }, + { + "Tuple4": "90.143.187.227.4586>173.194.44.58.443", + "VERSION": "Google QUIC 44", + "SNI": "googleads.g.doubleclick.net", + "UA": "canary Chrome/73.0.3672.0 Windows NT 10.0; Win64; x64", + "SNI": "googleads.g.doubleclick.net", + "UA": "canary Chrome/73.0.3672.0 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_24" + }, + { + "Tuple4": "90.143.188.64.2542>64.233.165.94.443", + "VERSION": "Google QUIC 44", + "SNI": "beacons5.gvt2.com", + "UA": "dev Chrome/73.0.3667.2 Android 6.0.1; SM-A700FD", + "SNI": "beacons5.gvt2.com", + "UA": "dev Chrome/73.0.3667.2 Android 6.0.1; SM-A700FD", + "name": "QUIC_RESULT_25" + } +]
\ No newline at end of file diff --git a/test/pcap/gquic/46/1-gquic-046-36.142.158.169.16385-36.189.11.71.443.pcap b/test/pcap/gquic/46/1-gquic-046-36.142.158.169.16385-36.189.11.71.443.pcap Binary files differnew file mode 100644 index 0000000..0b77c4d --- /dev/null +++ b/test/pcap/gquic/46/1-gquic-046-36.142.158.169.16385-36.189.11.71.443.pcap diff --git a/test/pcap/gquic/46/2-gquic-046-pagead2.googlesyndication.com-172.16.30.79.65003-203.208.50.45.443.pcap b/test/pcap/gquic/46/2-gquic-046-pagead2.googlesyndication.com-172.16.30.79.65003-203.208.50.45.443.pcap Binary files differnew file mode 100644 index 0000000..7c2a2a4 --- /dev/null +++ b/test/pcap/gquic/46/2-gquic-046-pagead2.googlesyndication.com-172.16.30.79.65003-203.208.50.45.443.pcap diff --git a/test/pcap/gquic/46/quic_result.json b/test/pcap/gquic/46/quic_result.json new file mode 100644 index 0000000..77d369d --- /dev/null +++ b/test/pcap/gquic/46/quic_result.json @@ -0,0 +1,11 @@ +[ + { + "Tuple4": "172.16.30.79.65003>203.208.50.45.443", + "VERSION": "Google QUIC 46", + "SNI": "pagead2.googlesyndication.com", + "UA": "Chrome/79.0.3945.79 Windows NT 6.1; Win64; x64", + "SNI": "pagead2.googlesyndication.com", + "UA": "Chrome/79.0.3945.79 Windows NT 6.1; Win64; x64", + "name": "QUIC_RESULT_1" + } +]
\ No newline at end of file diff --git a/test/pcap/gquic/48/gquic-048-103.3.138.59.12521-123.125.116.52.443.pcap b/test/pcap/gquic/48/gquic-048-103.3.138.59.12521-123.125.116.52.443.pcap Binary files differnew file mode 100644 index 0000000..5c9fcd6 --- /dev/null +++ b/test/pcap/gquic/48/gquic-048-103.3.138.59.12521-123.125.116.52.443.pcap diff --git a/test/pcap/gquic/48/gquic-048-116.178.222.19.11011-123.125.116.52.443.pcap b/test/pcap/gquic/48/gquic-048-116.178.222.19.11011-123.125.116.52.443.pcap Binary files differnew file mode 100644 index 0000000..c1e3f61 --- /dev/null +++ b/test/pcap/gquic/48/gquic-048-116.178.222.19.11011-123.125.116.52.443.pcap diff --git a/test/pcap/gquic/48/gquic-048-123.125.116.52.443-103.3.138.59.12519.pcap b/test/pcap/gquic/48/gquic-048-123.125.116.52.443-103.3.138.59.12519.pcap Binary files differnew file mode 100644 index 0000000..5fec439 --- /dev/null +++ b/test/pcap/gquic/48/gquic-048-123.125.116.52.443-103.3.138.59.12519.pcap diff --git a/test/pcap/gquic/48/gquic-048-123.125.116.52.443-116.178.235.37.25510.pcap b/test/pcap/gquic/48/gquic-048-123.125.116.52.443-116.178.235.37.25510.pcap Binary files differnew file mode 100644 index 0000000..d3740d8 --- /dev/null +++ b/test/pcap/gquic/48/gquic-048-123.125.116.52.443-116.178.235.37.25510.pcap diff --git a/test/pcap/gquic/50/1-gquic-050-i.ytimg.com-172.20.9.135.65045-64.233.162.119.443.pcap b/test/pcap/gquic/50/1-gquic-050-i.ytimg.com-172.20.9.135.65045-64.233.162.119.443.pcap Binary files differnew file mode 100644 index 0000000..1d5c46a --- /dev/null +++ b/test/pcap/gquic/50/1-gquic-050-i.ytimg.com-172.20.9.135.65045-64.233.162.119.443.pcap diff --git a/test/pcap/gquic/50/2-gquic-050-www.google.com-172.20.9.135.61564-173.194.221.103.443.pcap b/test/pcap/gquic/50/2-gquic-050-www.google.com-172.20.9.135.61564-173.194.221.103.443.pcap Binary files differnew file mode 100644 index 0000000..4a58ff7 --- /dev/null +++ b/test/pcap/gquic/50/2-gquic-050-www.google.com-172.20.9.135.61564-173.194.221.103.443.pcap diff --git a/test/pcap/gquic/50/3-gquic-050-www.youtube.com-172.20.9.135.49347-64.233.165.93.443.pcap b/test/pcap/gquic/50/3-gquic-050-www.youtube.com-172.20.9.135.49347-64.233.165.93.443.pcap Binary files differnew file mode 100644 index 0000000..81cad56 --- /dev/null +++ b/test/pcap/gquic/50/3-gquic-050-www.youtube.com-172.20.9.135.49347-64.233.165.93.443.pcap diff --git a/test/pcap/gquic/50/quic_result.json b/test/pcap/gquic/50/quic_result.json new file mode 100644 index 0000000..c1f0faa --- /dev/null +++ b/test/pcap/gquic/50/quic_result.json @@ -0,0 +1,19 @@ +[{ + "Tuple4": "172.20.9.135.65045>64.233.162.119.443", + "VERSION": "Google QUIC 50", + "SNI": "i.ytimg.com", + "UA": "Chrome/86.0.4240.75 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "172.20.9.135.61564>173.194.221.103.443", + "VERSION": "Google QUIC 50", + "SNI": "www.google.com", + "UA": "Chrome/86.0.4240.75 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "172.20.9.135.49347>64.233.165.93.443", + "VERSION": "Google QUIC 50", + "SNI": "www.youtube.com", + "UA": "Chrome/86.0.4240.75 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_3" +}] diff --git a/test/pcap/iquic/29/1-iquic-29-192.168.50.29.61891-31.13.77.35.443.pcap b/test/pcap/iquic/29/1-iquic-29-192.168.50.29.61891-31.13.77.35.443.pcap Binary files differnew file mode 100644 index 0000000..dcd22db --- /dev/null +++ b/test/pcap/iquic/29/1-iquic-29-192.168.50.29.61891-31.13.77.35.443.pcap diff --git a/test/pcap/iquic/29/2-iquic-29-223.104.233.102.13650-203.208.40.98.443.pcap b/test/pcap/iquic/29/2-iquic-29-223.104.233.102.13650-203.208.40.98.443.pcap Binary files differnew file mode 100644 index 0000000..3f2a3dc --- /dev/null +++ b/test/pcap/iquic/29/2-iquic-29-223.104.233.102.13650-203.208.40.98.443.pcap diff --git a/test/pcap/iquic/29/3-iquic-29-192.168.50.33.57220-114.250.70.38.443.pcap b/test/pcap/iquic/29/3-iquic-29-192.168.50.33.57220-114.250.70.38.443.pcap Binary files differnew file mode 100644 index 0000000..f6a188c --- /dev/null +++ b/test/pcap/iquic/29/3-iquic-29-192.168.50.33.57220-114.250.70.38.443.pcap diff --git a/test/pcap/iquic/29/quic_result.json b/test/pcap/iquic/29/quic_result.json new file mode 100644 index 0000000..ce7748b --- /dev/null +++ b/test/pcap/iquic/29/quic_result.json @@ -0,0 +1,16 @@ +[ + { + "Tuple4": "192.168.50.29.61891>31.13.77.35.443", + "VERSION": "IETF QUIC 29", + "SNI": "www.facebook.com", + "UA": "Chrome/86.0.4240.183 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_1" + }, + { + "Tuple4": "192.168.50.33.57220>114.250.70.38.443", + "VERSION": "IETF QUIC 29", + "SNI": "securepubads.g.doubleclick.net", + "UA": "Chrome/90.0.4430.72 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_2" + } +]
\ No newline at end of file diff --git a/test/pcap/mvfst/01/1-mvfst-01-i.instagram.com-192.168.60.9.55659-69.171.250.63.443.pcap b/test/pcap/mvfst/01/1-mvfst-01-i.instagram.com-192.168.60.9.55659-69.171.250.63.443.pcap Binary files differnew file mode 100644 index 0000000..be91a45 --- /dev/null +++ b/test/pcap/mvfst/01/1-mvfst-01-i.instagram.com-192.168.60.9.55659-69.171.250.63.443.pcap diff --git a/test/pcap/mvfst/01/quic_result.json b/test/pcap/mvfst/01/quic_result.json new file mode 100644 index 0000000..2997aea --- /dev/null +++ b/test/pcap/mvfst/01/quic_result.json @@ -0,0 +1,6 @@ +[{ + "Tuple4": "192.168.60.9.55659>69.171.250.63.443", + "VERSION": "Facebook mvfst 01", + "SNI": "i.instagram.com", + "name": "QUIC_RESULT_1" +}] diff --git a/test/pcap/mvfst/02/1-mvfst-02-192.168.137.141.50006-31.13.77.17.443.pcap b/test/pcap/mvfst/02/1-mvfst-02-192.168.137.141.50006-31.13.77.17.443.pcap Binary files differnew file mode 100644 index 0000000..9b88cc0 --- /dev/null +++ b/test/pcap/mvfst/02/1-mvfst-02-192.168.137.141.50006-31.13.77.17.443.pcap diff --git a/test/pcap/mvfst/02/10-mvfst-02-192.168.137.141.55335-157.240.13.15.443.pcap b/test/pcap/mvfst/02/10-mvfst-02-192.168.137.141.55335-157.240.13.15.443.pcap Binary files differnew file mode 100644 index 0000000..e732df2 --- /dev/null +++ b/test/pcap/mvfst/02/10-mvfst-02-192.168.137.141.55335-157.240.13.15.443.pcap diff --git a/test/pcap/mvfst/02/2-mvfst-02-192.168.137.141.63314-31.13.77.10.443.pcap b/test/pcap/mvfst/02/2-mvfst-02-192.168.137.141.63314-31.13.77.10.443.pcap Binary files differnew file mode 100644 index 0000000..27f209d --- /dev/null +++ b/test/pcap/mvfst/02/2-mvfst-02-192.168.137.141.63314-31.13.77.10.443.pcap diff --git a/test/pcap/mvfst/02/3-mvfst-02-192.168.137.141.60630-157.240.7.26.443.pcap b/test/pcap/mvfst/02/3-mvfst-02-192.168.137.141.60630-157.240.7.26.443.pcap Binary files differnew file mode 100644 index 0000000..4a6fa6c --- /dev/null +++ b/test/pcap/mvfst/02/3-mvfst-02-192.168.137.141.60630-157.240.7.26.443.pcap diff --git a/test/pcap/mvfst/02/4-mvfst-02-192.168.137.141.50293-157.240.15.13.443.pcap b/test/pcap/mvfst/02/4-mvfst-02-192.168.137.141.50293-157.240.15.13.443.pcap Binary files differnew file mode 100644 index 0000000..016d260 --- /dev/null +++ b/test/pcap/mvfst/02/4-mvfst-02-192.168.137.141.50293-157.240.15.13.443.pcap diff --git a/test/pcap/mvfst/02/5-mvfst-02-192.168.137.141.63677-157.240.13.19.443.pcap b/test/pcap/mvfst/02/5-mvfst-02-192.168.137.141.63677-157.240.13.19.443.pcap Binary files differnew file mode 100644 index 0000000..4bcc53f --- /dev/null +++ b/test/pcap/mvfst/02/5-mvfst-02-192.168.137.141.63677-157.240.13.19.443.pcap diff --git a/test/pcap/mvfst/02/6-mvfst-02-192.168.137.141.52300-157.240.235.1.443.pcap b/test/pcap/mvfst/02/6-mvfst-02-192.168.137.141.52300-157.240.235.1.443.pcap Binary files differnew file mode 100644 index 0000000..b8415a6 --- /dev/null +++ b/test/pcap/mvfst/02/6-mvfst-02-192.168.137.141.52300-157.240.235.1.443.pcap diff --git a/test/pcap/mvfst/02/7-mvfst-02-192.168.137.141.63951-157.240.7.21.443.pcap b/test/pcap/mvfst/02/7-mvfst-02-192.168.137.141.63951-157.240.7.21.443.pcap Binary files differnew file mode 100644 index 0000000..49cafd6 --- /dev/null +++ b/test/pcap/mvfst/02/7-mvfst-02-192.168.137.141.63951-157.240.7.21.443.pcap diff --git a/test/pcap/mvfst/02/8-mvfst-02-192.168.137.141.52981-157.240.235.2.443.pcap b/test/pcap/mvfst/02/8-mvfst-02-192.168.137.141.52981-157.240.235.2.443.pcap Binary files differnew file mode 100644 index 0000000..7b61929 --- /dev/null +++ b/test/pcap/mvfst/02/8-mvfst-02-192.168.137.141.52981-157.240.235.2.443.pcap diff --git a/test/pcap/mvfst/02/9-mvfst-02-192.168.137.141.53686-157.240.15.20.443.pcap b/test/pcap/mvfst/02/9-mvfst-02-192.168.137.141.53686-157.240.15.20.443.pcap Binary files differnew file mode 100644 index 0000000..4f3245b --- /dev/null +++ b/test/pcap/mvfst/02/9-mvfst-02-192.168.137.141.53686-157.240.15.20.443.pcap diff --git a/test/pcap/mvfst/02/quic_result.json b/test/pcap/mvfst/02/quic_result.json new file mode 100644 index 0000000..591e1de --- /dev/null +++ b/test/pcap/mvfst/02/quic_result.json @@ -0,0 +1,51 @@ +[{ + "Tuple4": "192.168.137.141.50006>31.13.77.17.443", + "VERSION": "Facebook mvfst 02", + "SNI": "graph.facebook.com", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "192.168.137.141.63314>31.13.77.10.443", + "VERSION": "Facebook mvfst 02", + "SNI": "gateway.facebook.com", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "192.168.137.141.60630>157.240.7.26.443", + "VERSION": "Facebook mvfst 02", + "SNI": "scontent-sin6-1.xx.fbcdn.net", + "name": "QUIC_RESULT_3" + }, { + "Tuple4": "192.168.137.141.50293>157.240.15.13.443", + "VERSION": "Facebook mvfst 02", + "SNI": "scontent-sin6-3.xx.fbcdn.net", + "name": "QUIC_RESULT_4" + }, { + "Tuple4": "192.168.137.141.63677>157.240.13.19.443", + "VERSION": "Facebook mvfst 02", + "SNI": "scontent-sin6-2.xx.fbcdn.net", + "name": "QUIC_RESULT_5" + }, { + "Tuple4": "192.168.137.141.52300>157.240.235.1.443", + "VERSION": "Facebook mvfst 02", + "SNI": "scontent-sin6-4.xx.fbcdn.net", + "name": "QUIC_RESULT_6" + }, { + "Tuple4": "192.168.137.141.63951>157.240.7.21.443", + "VERSION": "Facebook mvfst 02", + "SNI": "video-sin6-1.xx.fbcdn.net", + "name": "QUIC_RESULT_7" + }, { + "Tuple4": "192.168.137.141.52981>157.240.235.2.443", + "VERSION": "Facebook mvfst 02", + "SNI": "video-sin6-4.xx.fbcdn.net", + "name": "QUIC_RESULT_8" + }, { + "Tuple4": "192.168.137.141.53686>157.240.15.20.443", + "VERSION": "Facebook mvfst 02", + "SNI": "video-sin6-3.xx.fbcdn.net", + "name": "QUIC_RESULT_9" + }, { + "Tuple4": "192.168.137.141.55335>157.240.13.15.443", + "VERSION": "Facebook mvfst 02", + "SNI": "video-sin6-2.xx.fbcdn.net", + "name": "QUIC_RESULT_10" +}] diff --git a/test/pcap/port-8443/1-iquic-29-192.168.50.49.58445-45.77.96.66.8443.pcap b/test/pcap/port-8443/1-iquic-29-192.168.50.49.58445-45.77.96.66.8443.pcap Binary files differnew file mode 100644 index 0000000..dd8e74a --- /dev/null +++ b/test/pcap/port-8443/1-iquic-29-192.168.50.49.58445-45.77.96.66.8443.pcap diff --git a/test/pcap/port-8443/quic_result.json b/test/pcap/port-8443/quic_result.json new file mode 100644 index 0000000..cf5e36b --- /dev/null +++ b/test/pcap/port-8443/quic_result.json @@ -0,0 +1,7 @@ +[{ + "Tuple4": "192.168.50.49.58445>45.77.96.66.8443", + "VERSION": "IETF QUIC 29", + "SNI": "quic.tech", + "UA": "Chrome/92.0.4515.159 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_1" +}] diff --git a/test/pcap/prox/prox-quic-217.76.77.70.33232-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.33232-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..a2efae4 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.33232-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.39896-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.39896-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..5e20732 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.39896-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.43145-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.43145-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..9be1464 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.43145-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.49914-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.49914-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..1929ace --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.49914-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.54549-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.54549-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..019bc20 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.54549-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.57394-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.57394-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..2dd3dca --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.57394-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.62303-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.62303-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..9b2cdf6 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.62303-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.70.63484-173.194.220.105.443.pcap b/test/pcap/prox/prox-quic-217.76.77.70.63484-173.194.220.105.443.pcap Binary files differnew file mode 100644 index 0000000..7cbfba3 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.70.63484-173.194.220.105.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.34722-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.34722-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..841f59a --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.34722-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.43786-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.43786-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..d6f9917 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.43786-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.44344-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.44344-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..e95bf1a --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.44344-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.44360-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.44360-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..fa1f129 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.44360-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.45109-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.45109-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..efd735f --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.45109-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.45314-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.45314-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..9ab26f1 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.45314-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.47041-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.47041-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..fe56a34 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.47041-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.47174-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.47174-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..928fe88 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.47174-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.50829-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.50829-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..a3951a5 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.50829-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.61598-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.61598-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..89bbf37 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.61598-74.125.131.106.443.pcap diff --git a/test/pcap/prox/prox-quic-217.76.77.73.62585-74.125.131.106.443.pcap b/test/pcap/prox/prox-quic-217.76.77.73.62585-74.125.131.106.443.pcap Binary files differnew file mode 100644 index 0000000..5d00506 --- /dev/null +++ b/test/pcap/prox/prox-quic-217.76.77.73.62585-74.125.131.106.443.pcap diff --git a/test/pcap/quic_len_-2.pcapng b/test/pcap/quic_len_-2.pcapng Binary files differnew file mode 100644 index 0000000..44f3965 --- /dev/null +++ b/test/pcap/quic_len_-2.pcapng diff --git a/test/pcap/rfc9000-chlo-fragment/1-google-chlo-fragment-2.pcap b/test/pcap/rfc9000-chlo-fragment/1-google-chlo-fragment-2.pcap Binary files differnew file mode 100644 index 0000000..c9115fe --- /dev/null +++ b/test/pcap/rfc9000-chlo-fragment/1-google-chlo-fragment-2.pcap diff --git a/test/pcap/rfc9000-chlo-fragment/2-google-chlo-fragment-3.pcap b/test/pcap/rfc9000-chlo-fragment/2-google-chlo-fragment-3.pcap Binary files differnew file mode 100644 index 0000000..80ea303 --- /dev/null +++ b/test/pcap/rfc9000-chlo-fragment/2-google-chlo-fragment-3.pcap diff --git a/test/pcap/rfc9000-chlo-fragment/3-facebook-chlo-fragment-2.pcap b/test/pcap/rfc9000-chlo-fragment/3-facebook-chlo-fragment-2.pcap Binary files differnew file mode 100644 index 0000000..afde2ee --- /dev/null +++ b/test/pcap/rfc9000-chlo-fragment/3-facebook-chlo-fragment-2.pcap diff --git a/test/pcap/rfc9000-chlo-fragment/4-googleapis.com-chlo-fragment-3.pcap b/test/pcap/rfc9000-chlo-fragment/4-googleapis.com-chlo-fragment-3.pcap Binary files differnew file mode 100644 index 0000000..1dd5354 --- /dev/null +++ b/test/pcap/rfc9000-chlo-fragment/4-googleapis.com-chlo-fragment-3.pcap diff --git a/test/pcap/rfc9000-chlo-fragment/quic_result.json b/test/pcap/rfc9000-chlo-fragment/quic_result.json new file mode 100644 index 0000000..47931bc --- /dev/null +++ b/test/pcap/rfc9000-chlo-fragment/quic_result.json @@ -0,0 +1,26 @@ +[ + { + "Tuple4": "2607:5d00:2:2::38:2.53977>2404:6800:4005:807::2004.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "name": "QUIC_RESULT_1" + }, + { + "Tuple4": "2607:5d00:2:2::38:2.50835>2404:6800:4005:80d::2003.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com.hk", + "name": "QUIC_RESULT_2" + }, + { + "Tuple4": "192.168.64.25.61166>157.240.245.35.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.facebook.com", + "name": "QUIC_RESULT_3" + }, + { + "Tuple4": "2607:5d00:2:2::38:2.54817>2404:6800:4005:80c::200a.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "optimizationguide-pa.googleapis.com", + "name": "QUIC_RESULT_4" + } +]
\ No newline at end of file diff --git a/test/pcap/rfc9000-fragment/1-addis-quic-sni-not-parsed-filtered.pcap b/test/pcap/rfc9000-fragment/1-addis-quic-sni-not-parsed-filtered.pcap Binary files differnew file mode 100644 index 0000000..34b5c2d --- /dev/null +++ b/test/pcap/rfc9000-fragment/1-addis-quic-sni-not-parsed-filtered.pcap diff --git a/test/pcap/rfc9000-fragment/2-quic-no-parse-sni-RFC9000-192.168.8.106.53736-142.250.185.36.443-6.pcap b/test/pcap/rfc9000-fragment/2-quic-no-parse-sni-RFC9000-192.168.8.106.53736-142.250.185.36.443-6.pcap Binary files differnew file mode 100644 index 0000000..eb8d602 --- /dev/null +++ b/test/pcap/rfc9000-fragment/2-quic-no-parse-sni-RFC9000-192.168.8.106.53736-142.250.185.36.443-6.pcap diff --git a/test/pcap/rfc9000-fragment/3-quic-no-parse-sni-RFC9000-63821-443-192.168.8.106-142.250.185.36.pcap b/test/pcap/rfc9000-fragment/3-quic-no-parse-sni-RFC9000-63821-443-192.168.8.106-142.250.185.36.pcap Binary files differnew file mode 100644 index 0000000..c86c379 --- /dev/null +++ b/test/pcap/rfc9000-fragment/3-quic-no-parse-sni-RFC9000-63821-443-192.168.8.106-142.250.185.36.pcap diff --git a/test/pcap/rfc9000-fragment/quic_result.json b/test/pcap/rfc9000-fragment/quic_result.json new file mode 100644 index 0000000..65dbdd3 --- /dev/null +++ b/test/pcap/rfc9000-fragment/quic_result.json @@ -0,0 +1,31 @@ +[{ + "Tuple4": "192.168.8.106.57644>142.250.185.36.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "192.168.8.106.60687>142.250.185.36.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "192.168.8.106.53622>142.250.185.36.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_3" + }, { + "Tuple4": "192.168.8.106.53736>142.250.185.36.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_4" + }, { + "Tuple4": "192.168.8.106.63821>142.250.185.36.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_5" +}] diff --git a/test/pcap/rfc9000-special/1-quic-rc9000-no-parse-UA-192.168.8.110.49832-172.217.18.150.443.pcap b/test/pcap/rfc9000-special/1-quic-rc9000-no-parse-UA-192.168.8.110.49832-172.217.18.150.443.pcap Binary files differnew file mode 100644 index 0000000..f79f09d --- /dev/null +++ b/test/pcap/rfc9000-special/1-quic-rc9000-no-parse-UA-192.168.8.110.49832-172.217.18.150.443.pcap diff --git a/test/pcap/rfc9000-special/2-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.50339-172.217.169.227.443.pcap b/test/pcap/rfc9000-special/2-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.50339-172.217.169.227.443.pcap Binary files differnew file mode 100644 index 0000000..c53cbee --- /dev/null +++ b/test/pcap/rfc9000-special/2-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.50339-172.217.169.227.443.pcap diff --git a/test/pcap/rfc9000-special/3-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.52455-213.55.110.12.443.pcap b/test/pcap/rfc9000-special/3-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.52455-213.55.110.12.443.pcap Binary files differnew file mode 100644 index 0000000..3a1736c --- /dev/null +++ b/test/pcap/rfc9000-special/3-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.52455-213.55.110.12.443.pcap diff --git a/test/pcap/rfc9000-special/4-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.64550-142.250.185.36.443.pcap b/test/pcap/rfc9000-special/4-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.64550-142.250.185.36.443.pcap Binary files differnew file mode 100644 index 0000000..09e3dc2 --- /dev/null +++ b/test/pcap/rfc9000-special/4-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.64550-142.250.185.36.443.pcap diff --git a/test/pcap/rfc9000-special/5-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.65140-213.55.110.13.443.pcap b/test/pcap/rfc9000-special/5-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.65140-213.55.110.13.443.pcap Binary files differnew file mode 100644 index 0000000..7e484b7 --- /dev/null +++ b/test/pcap/rfc9000-special/5-quic-rfc9000-no-parse-SNI-UA-192.168.8.110.65140-213.55.110.13.443.pcap diff --git a/test/pcap/rfc9000-special/quic_result.json b/test/pcap/rfc9000-special/quic_result.json new file mode 100644 index 0000000..da2b724 --- /dev/null +++ b/test/pcap/rfc9000-special/quic_result.json @@ -0,0 +1,31 @@ +[{ + "Tuple4": "192.168.8.110.49832>172.217.18.150.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "i.ytimg.com", + "UA": "Chrome/95.0.4638.54 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "192.168.8.110.50339>172.217.169.227.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com.et", + "UA": "Chrome/95.0.4638.54 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "192.168.8.110.52455>213.55.110.12.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "r1---sn-xuj-5qqz.googlevideo.com", + "UA": "Chrome/95.0.4638.54 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_3" + }, { + "Tuple4": "192.168.8.110.64550>142.250.185.36.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "www.google.com", + "UA": "Chrome/95.0.4638.54 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_4" + }, { + "Tuple4": "192.168.8.110.65140>213.55.110.13.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "r2---sn-xuj-5qqz.googlevideo.com", + "UA": "Chrome/95.0.4638.54 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_5" +}] diff --git a/test/pcap/rfc9000/1-ietf-rfc9000-192.168.60.32.59699-64.233.164.84.443.pcap b/test/pcap/rfc9000/1-ietf-rfc9000-192.168.60.32.59699-64.233.164.84.443.pcap Binary files differnew file mode 100644 index 0000000..84097c8 --- /dev/null +++ b/test/pcap/rfc9000/1-ietf-rfc9000-192.168.60.32.59699-64.233.164.84.443.pcap diff --git a/test/pcap/rfc9000/2-ietf-rfc9000-124.88.191.113.39716-114.250.66.33-443.pcap b/test/pcap/rfc9000/2-ietf-rfc9000-124.88.191.113.39716-114.250.66.33-443.pcap Binary files differnew file mode 100644 index 0000000..ee760fb --- /dev/null +++ b/test/pcap/rfc9000/2-ietf-rfc9000-124.88.191.113.39716-114.250.66.33-443.pcap diff --git a/test/pcap/rfc9000/quic_result.json b/test/pcap/rfc9000/quic_result.json new file mode 100644 index 0000000..8a68816 --- /dev/null +++ b/test/pcap/rfc9000/quic_result.json @@ -0,0 +1,12 @@ +[{ + "Tuple4": "192.168.60.32.59699>64.233.164.84.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "accounts.google.com", + "UA": "Chrome/92.0.4515.159 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "124.88.191.113.39716>114.250.66.33.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "safebrowsing.googleapis.com", + "name": "QUIC_RESULT_2" +}] diff --git a/test/pcap/special/1-no-parse-sni-draft-29-10.83.31.23.37645-142.250.180.42.443.pcap b/test/pcap/special/1-no-parse-sni-draft-29-10.83.31.23.37645-142.250.180.42.443.pcap Binary files differnew file mode 100644 index 0000000..ad40e1d --- /dev/null +++ b/test/pcap/special/1-no-parse-sni-draft-29-10.83.31.23.37645-142.250.180.42.443.pcap diff --git a/test/pcap/special/1-no-parse-sni-draft-29.37645.pcap b/test/pcap/special/1-no-parse-sni-draft-29.37645.pcap Binary files differnew file mode 100644 index 0000000..ad40e1d --- /dev/null +++ b/test/pcap/special/1-no-parse-sni-draft-29.37645.pcap diff --git a/test/pcap/special/2-no-parse-sni-rfc9000-192.168.1.6.61269-142.250.180.42.443.pcap b/test/pcap/special/2-no-parse-sni-rfc9000-192.168.1.6.61269-142.250.180.42.443.pcap Binary files differnew file mode 100644 index 0000000..ad965e8 --- /dev/null +++ b/test/pcap/special/2-no-parse-sni-rfc9000-192.168.1.6.61269-142.250.180.42.443.pcap diff --git a/test/pcap/special/2-no-parse-sni-rfc9000.61269.pcap b/test/pcap/special/2-no-parse-sni-rfc9000.61269.pcap Binary files differnew file mode 100644 index 0000000..ad965e8 --- /dev/null +++ b/test/pcap/special/2-no-parse-sni-rfc9000.61269.pcap diff --git a/test/pcap/special/3-no-parse-sni-gquic-43-10.129.24.130.52558-213.55.110.12.443.pcap b/test/pcap/special/3-no-parse-sni-gquic-43-10.129.24.130.52558-213.55.110.12.443.pcap Binary files differnew file mode 100644 index 0000000..9ea020b --- /dev/null +++ b/test/pcap/special/3-no-parse-sni-gquic-43-10.129.24.130.52558-213.55.110.12.443.pcap diff --git a/test/pcap/special/4-no-sni-rfc9000-197.156.101.97.12388-142.250.185.46.443.pcap b/test/pcap/special/4-no-sni-rfc9000-197.156.101.97.12388-142.250.185.46.443.pcap Binary files differnew file mode 100644 index 0000000..36d7457 --- /dev/null +++ b/test/pcap/special/4-no-sni-rfc9000-197.156.101.97.12388-142.250.185.46.443.pcap diff --git a/test/pcap/special/quic_result.json b/test/pcap/special/quic_result.json new file mode 100644 index 0000000..9d8b38a --- /dev/null +++ b/test/pcap/special/quic_result.json @@ -0,0 +1,33 @@ +[ + { + "Tuple4": "10.83.31.23.37645>142.250.180.42.443", + "VERSION": "IETF QUIC 29", + "SNI": "play.googleapis.com", + "UA": "com.google.android.gms Cronet/92.0.4515.131", + "SNI": "play.googleapis.com", + "UA": "com.google.android.gms Cronet/92.0.4515.131", + "SNI": "play.googleapis.com", + "UA": "com.google.android.gms Cronet/92.0.4515.131", + "SNI": "play.googleapis.com", + "UA": "com.google.android.gms Cronet/92.0.4515.131", + "name": "QUIC_RESULT_1" + }, + { + "Tuple4": "192.168.1.6.61269>142.250.180.42.443", + "VERSION": "IETF QUIC RFC9000", + "SNI": "content-autofill.googleapis.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "SNI": "content-autofill.googleapis.com", + "UA": "Chrome/94.0.4606.81 Windows NT 10.0; Win64; x64", + "name": "QUIC_RESULT_2" + }, + { + "Tuple4": "10.129.24.130.52558>213.55.110.12.443", + "VERSION": "Google QUIC 43", + "SNI": "r1---sn-xuj-5qqz.googlevideo.com", + "UA": "com.google.android.youtube Cronet/80.0.3970.3", + "SNI": "r1---sn-xuj-5qqz.googlevideo.com", + "UA": "com.google.android.youtube Cronet/80.0.3970.3", + "name": "QUIC_RESULT_3" + } +]
\ No newline at end of file diff --git a/test/pcap/tquic/1-tquic-51-195.12.120.14.41803-173.194.222.101.443.pcap b/test/pcap/tquic/1-tquic-51-195.12.120.14.41803-173.194.222.101.443.pcap Binary files differnew file mode 100644 index 0000000..357777c --- /dev/null +++ b/test/pcap/tquic/1-tquic-51-195.12.120.14.41803-173.194.222.101.443.pcap diff --git a/test/pcap/tquic/2-tquic-51-195.12.120.14.39526-64.233.165.113.443.pcap b/test/pcap/tquic/2-tquic-51-195.12.120.14.39526-64.233.165.113.443.pcap Binary files differnew file mode 100644 index 0000000..f64152a --- /dev/null +++ b/test/pcap/tquic/2-tquic-51-195.12.120.14.39526-64.233.165.113.443.pcap diff --git a/test/pcap/tquic/3-tquic-51-195.12.120.14.41747-173.194.222.138.443.pcap b/test/pcap/tquic/3-tquic-51-195.12.120.14.41747-173.194.222.138.443.pcap Binary files differnew file mode 100644 index 0000000..8d87b8d --- /dev/null +++ b/test/pcap/tquic/3-tquic-51-195.12.120.14.41747-173.194.222.138.443.pcap diff --git a/test/pcap/tquic/4-tquic-51-195.12.120.14.59012-173.194.222.138.443.pcap b/test/pcap/tquic/4-tquic-51-195.12.120.14.59012-173.194.222.138.443.pcap Binary files differnew file mode 100644 index 0000000..bb67486 --- /dev/null +++ b/test/pcap/tquic/4-tquic-51-195.12.120.14.59012-173.194.222.138.443.pcap diff --git a/test/pcap/tquic/quic_result.json b/test/pcap/tquic/quic_result.json new file mode 100644 index 0000000..3d2d43e --- /dev/null +++ b/test/pcap/tquic/quic_result.json @@ -0,0 +1,25 @@ +[{ + "Tuple4": "195.12.120.14.41803>173.194.222.101.443", + "SNI": "clients4.google.com", + "UA": "Chrome/87.0.4280.101 Android 9; ANE-LX1", + "VERSION": "Google QUIC with TLS 51", + "name": "QUIC_RESULT_1" + }, { + "Tuple4": "195.12.120.14.39526>64.233.165.113.443", + "SNI": "m.youtube.com", + "UA": "Chrome/87.0.4280.101 Android 9; ANE-LX1", + "VERSION": "Google QUIC with TLS 51", + "name": "QUIC_RESULT_2" + }, { + "Tuple4": "195.12.120.14.41747>173.194.222.138.443", + "SNI": "clients4.google.com", + "UA": "Chrome/87.0.4280.101 Android 9; ANE-LX1", + "VERSION": "Google QUIC with TLS 51", + "name": "QUIC_RESULT_3" + }, { + "Tuple4": "195.12.120.14.59012>173.194.222.138.443", + "SNI": "clients4.google.com", + "UA": "Chrome/87.0.4280.101 Android 9; ANE-LX1", + "VERSION": "Google QUIC with TLS 51", + "name": "QUIC_RESULT_4" +}] diff --git a/test/quic_decoder_test_plug.cpp b/test/quic_decoder_test_plug.cpp new file mode 100644 index 0000000..39363e0 --- /dev/null +++ b/test/quic_decoder_test_plug.cpp @@ -0,0 +1,131 @@ +/* + * author:yangwei + * create time:2021-8-21 + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> +#include "cJSON.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "quic_decoder.h" +#include <stellar/stellar.h> +#include <stellar/session.h> +#include <stellar/session_mq.h> +#include <stellar/session_exdata.h> + +extern "C" int commit_test_result_json(cJSON *node, const char *name); +extern int quic_version_int2string(unsigned int version, char *buff, int buff_len); + +static int g_result_count = 1; + +#if 0 +#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ##args) +#else +#define DEBUG_PRINT(fmt, args...) +#endif + +struct quic_gtest_context +{ + cJSON *json_root; + int version_get; + int tuple4_get; +}; + +static void cJSON_Add_QStringToObject(cJSON * object, const char *name, const char* qstring, size_t len) +{ + char *tmp = (char *)calloc(1, len + 1); + memcpy(tmp, qstring, len); + cJSON_AddStringToObject(object, name, tmp); +} + +extern "C" void QUIC_TEST_PLUG_ENTRY(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env) +{ + struct quic_gtest_context *qctx = (struct quic_gtest_context *)per_session_ctx; + struct quic_message *qmsg = (struct quic_message *)msg; + enum quic_message_type mtype = quic_message_type_get(qmsg); + char *result = NULL; + size_t res_len = 0; + enum session_state sstate = session_get_current_state(sess); + + DEBUG_PRINT("### QUIC_TEST_PLUG_ENTRY: msg type=%d\n", (int)mtype); + + if(QUIC_CLIENT_HELLO == mtype){ + if(qctx->tuple4_get == 0){ + cJSON_AddStringToObject(qctx->json_root, "Tuple4", session_get0_readable_addr(sess)); + qctx->tuple4_get = 1; + } + + if(qctx->version_get == 0){ + const char *version_str = quic_message_readable_version_get0(qmsg); + if(version_str){ + cJSON_AddStringToObject(qctx->json_root, "VERSION", version_str); + qctx->version_get = 1; + } + } + + quic_message_sni_get0(qmsg, &result, &res_len); + if(result){ + cJSON_Add_QStringToObject(qctx->json_root, "SNI", result, res_len); + } + + quic_message_user_agent_get0(qmsg, &result, &res_len); + if(result){ + cJSON_Add_QStringToObject(qctx->json_root, "UA", result, res_len); + } + } + + if(sstate == SESSION_STATE_CLOSING){ + //some sapp version not support SESSION_STATE_CLOSING, do this in free_cb() + } + + return ; +} + +extern "C" void *quic_gtest_plug_session_ctx_new_cb(struct session *sess, void *plugin_env) +{ + struct quic_gtest_context *ctx = (struct quic_gtest_context *)calloc(1, sizeof(struct quic_gtest_context)); + ctx->json_root = cJSON_CreateObject(); + return ctx; +} + +extern "C" void quic_gtest_session_ctx_free_cb(struct session *sess, void *session_ctx, void *plugin_env) +{ + struct quic_gtest_context *qctx = (struct quic_gtest_context *)session_ctx; + if(qctx->tuple4_get || qctx->version_get){ + char result_name[16]=""; + sprintf(result_name,"QUIC_RESULT_%d", g_result_count); + commit_test_result_json(qctx->json_root, result_name); + g_result_count+=1; + } + free(session_ctx); +} + +extern "C" void *QUIC_TEST_PLUG_INIT(struct stellar *st) +{ + void *fake_quic_gtest_plugin_env = (void *)"_fake_plugin_env_"; + int quic_gtest_plug_id = stellar_session_plugin_register(st, quic_gtest_plug_session_ctx_new_cb, quic_gtest_session_ctx_free_cb, fake_quic_gtest_plugin_env); + int quic_topic_id = stellar_session_mq_get_topic_id(st, QUIC_DECODER_TOPIC); + assert(quic_topic_id >= 0); + stellar_session_mq_subscribe(st, quic_topic_id, QUIC_TEST_PLUG_ENTRY, quic_gtest_plug_id); + + return fake_quic_gtest_plugin_env; +} + +extern "C" void QUIC_TEST_PLUG_DESTROY(void *plugin_env) +{ + return ; +} + +#ifdef __cplusplus +} +#endif + + + |
