mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
Compare commits
536 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e32b5df06 | |||
| 02881c4409 | |||
| 298e1e2e72 | |||
| fe7c66cf1d | |||
| b5aa940701 | |||
| 38f2f1a3e4 | |||
| b98c6ca5c5 | |||
| 5641874811 | |||
| 1dd34035c9 | |||
| 084ac9b916 | |||
| 9962bac50b | |||
| f0c3f1b9ba | |||
| ec8eeef428 | |||
| 7eb1a4b489 | |||
| 23b23f0e38 | |||
| cba78190a8 | |||
| e097a49186 | |||
| e895c784c7 | |||
| 7e1bcf84f0 | |||
| a92f1b82d0 | |||
| 433e6901c6 | |||
| e16d835727 | |||
| a5cf2d37d4 | |||
| 4bd6fbd445 | |||
| 8f18933713 | |||
| caad670dbf | |||
| 1dd79d9e31 | |||
| f2e9631af4 | |||
| c756ab70ae | |||
| 2e57fe0dfd | |||
| be39d28be7 | |||
| 23a292b8ff | |||
| cdbb247780 | |||
| 69d4f0ce10 | |||
| 2580475f67 | |||
| 1be66659d3 | |||
| 6d3ba0ae72 | |||
| 0096e65fe6 | |||
| b870306c5d | |||
| 480b2181f0 | |||
| ddc3fe7807 | |||
| a86e8659f7 | |||
| a0141624b9 | |||
| dc137620eb | |||
| e9b92b216a | |||
| 34a268624b | |||
| 1f048a6d04 | |||
| 58cf10ffb2 | |||
| 1ef14e129f | |||
| 268bd8f1a6 | |||
| 1d9ff17380 | |||
| 0fa0d72300 | |||
| 677d166b1e | |||
| b5778a9cb5 | |||
| b2fd94d20e | |||
| 16969bc39b | |||
| f7ee532add | |||
| 2fdab4c196 | |||
| 92907bced3 | |||
| ca4d6e0b2f | |||
| c3fc3a3132 | |||
| 78b8a1c36f | |||
| 638c3492d6 | |||
| 4c1699935c | |||
| 542039df01 | |||
| d652ecff21 | |||
| 00c4cf300a | |||
| da47054497 | |||
| 051a2a3ef2 | |||
| ee609f3e8f | |||
| eb66354c76 | |||
| c7fb7e58cf | |||
| c2b02a45a2 | |||
| e7ed532545 | |||
| 2a031320c2 | |||
| d0379fdede | |||
| ee8cd8ef26 | |||
| 18d89e9cad | |||
| 623c8ca6b0 | |||
| 39736e865e | |||
| 92374966fb | |||
| 6bebfb861c | |||
| 30ae13b245 | |||
| 2118327ae0 | |||
| 6aed2902a7 | |||
| e149e32ce1 | |||
| 41f2af8c4e | |||
| 016f808345 | |||
| bc69524654 | |||
| 3c6280c419 | |||
| 9d01a52a4a | |||
| a8273a8fdc | |||
| b9717e9894 | |||
| 6b3209e6ee | |||
| 0a6da5ead1 | |||
| 53441148b8 | |||
| 732d018819 | |||
| e261a8ba21 | |||
| c3c87bff74 | |||
| c3f423aad5 | |||
| 580975fda1 | |||
| 9f114a1dad | |||
| 0ae93d0657 | |||
| 44d2627e2a | |||
| 6e882760f1 | |||
| ff79ffd1c8 | |||
| 3175b0c4ff | |||
| 21779395ef | |||
| 32cbb698ee | |||
| 19a41b2792 | |||
| 221ea5ebb0 | |||
| e8242aec85 | |||
| 6ed9dcbe93 | |||
| 58371e6e43 | |||
| 2d8957489e | |||
| 1fd0794bfb | |||
| 58da60985f | |||
| 6b6a3cd38e | |||
| 4b1df16ecf | |||
| 20e44aa891 | |||
| 118bb53c03 | |||
| 7c3be9f0b0 | |||
| d1990a4263 | |||
| 396422ee3a | |||
| f735b401df | |||
| 85020270d5 | |||
| b1b9044021 | |||
| 8da30b216f | |||
| 167d3caa5d | |||
| 3259e6f0e8 | |||
| 64526c5232 | |||
| d9630afafd | |||
| c8c6e62aa0 | |||
| 7f561c30b3 | |||
| 1d8f342417 | |||
| 6ec090ea0d | |||
| 08a8eadb49 | |||
| 3e2835bef6 | |||
| 686fc754b2 | |||
| ea17124d6d | |||
| 4000041308 | |||
| 1a50ed0316 | |||
| 42038cd6e7 | |||
| 44c5b41cc7 | |||
| da7bd91514 | |||
| 0206623c6f | |||
| 3b2948d4dd | |||
| 918aeb670e | |||
| fd9fec48a2 | |||
| 77e51b40b8 | |||
| 195663c6e3 | |||
| ce4ca5c4d5 | |||
| 3e276c4111 | |||
| 41a4dc2fa2 | |||
| 7851047421 | |||
| a30e478cbd | |||
| ad4b3dfad1 | |||
| ad7fc937a9 | |||
| fd905ef308 | |||
| 3f257af7a9 | |||
| 030bb8fe76 | |||
| 131601d9d2 | |||
| 82165eaf37 | |||
| 804a790392 | |||
| 6c614a4b3c | |||
| 8191c25dd7 | |||
| dc4b2bd52e | |||
| ca60afbcee | |||
| 374b74b710 | |||
| ae0d3d78cd | |||
| f9f197afd0 | |||
| 93c43ecbc3 | |||
| 1fd1b0388b | |||
| 833364a94e | |||
| 893c105bf2 | |||
| c6bb33fa84 | |||
| 22939a6707 | |||
| 9222877306 | |||
| 5d8264e854 | |||
| 77124e098c | |||
| bd0a70d024 | |||
| 80d792915a | |||
| 54dc363231 | |||
| 36c436af50 | |||
| 73eb9259e2 | |||
| 14c25480ce | |||
| 77d87f8c50 | |||
| ab389d4817 | |||
| 58b9e0cd7c | |||
| ed2f5af204 | |||
| 5b2f1f8969 | |||
| a2122cb7d7 | |||
| d680702b15 | |||
| d15de499dc | |||
| bd382e3cc7 | |||
| d417fa58ab | |||
| ca9cb997b5 | |||
| ebd920f3b2 | |||
| 9c188e0acd | |||
| 1de143362c | |||
| 7345f464a5 | |||
| 3c45f2abe2 | |||
| 9c5e1faf46 | |||
| ce02d3a829 | |||
| 1b80c59e65 | |||
| f20f528a11 | |||
| 814b66c04a | |||
| 4df918d6a5 | |||
| d3cbd8cdae | |||
| 0fa5dc225c | |||
| b14f14c45a | |||
| 0851f4fdd4 | |||
| 807b3370e7 | |||
| a0f114e15c | |||
| f98792714e | |||
| 5649f85b58 | |||
| ab9c11e038 | |||
| 4d621dcbfe | |||
| a45537cbf3 | |||
| 9294324732 | |||
| b92422594b | |||
| ea2637b1b4 | |||
| c97b4859c1 | |||
| 7a2f42de30 | |||
| 99f5f78fc7 | |||
| 668f0ca675 | |||
| 6a89a51ea6 | |||
| df6b0f3945 | |||
| 65cf243373 | |||
| 2ef7813219 | |||
| 216efd74bf | |||
| b9d027a44a | |||
| 9097dd9645 | |||
| d784e26913 | |||
| 005008814a | |||
| ad3bbaedb3 | |||
| cad0dabe42 | |||
| 48fa3c8aec | |||
| fb585cbac0 | |||
| dd1adda1a6 | |||
| 3c6cd623af | |||
| 70c6e69b36 | |||
| 943e58d32a | |||
| 5237058016 | |||
| b87c5f8a51 | |||
| 43e7a03af4 | |||
| 19fce4975d | |||
| a9217810e7 | |||
| 9b1678a06c | |||
| 0da63062d7 | |||
| c8dd12eb20 | |||
| 008592f13b | |||
| 56b9972053 | |||
| 1335c94bbc | |||
| 21a6ab369e | |||
| 2a80117d42 | |||
| e65d312503 | |||
| 5fc34e643c | |||
| 3463a84903 | |||
| 48dc532de6 | |||
| 20cb62483f | |||
| dcb5828313 | |||
| 74860256b9 | |||
| 97457f17c1 | |||
| de9167cae6 | |||
| 2e5171c205 | |||
| a0b5491178 | |||
| fc8ef8678b | |||
| 2dc1f2ea5b | |||
| 7999527582 | |||
| 14be6506ee | |||
| c85ad470ba | |||
| 8b6afcc5ec | |||
| 813dced6df | |||
| 0a39866045 | |||
| 48734689d8 | |||
| dfe927dcbd | |||
| ca158def31 | |||
| 409386336d | |||
| eeed6c3474 | |||
| 3296cd6c39 | |||
| 60e25d9c67 | |||
| ec65e2025e | |||
| f09020c3bc | |||
| 91baaed96d | |||
| 64de64ce33 | |||
| b685e7008e | |||
| 375b3d776c | |||
| c1fddd7164 | |||
| 3af9bf9e12 | |||
| 9ef5d0c144 | |||
| 3d1b37dc85 | |||
| 80ce8347f6 | |||
| 3eb7e1392d | |||
| ac78a44d74 | |||
| 87fed9fde3 | |||
| 2564430046 | |||
| 663861dc09 | |||
| 2d6a12101e | |||
| e40110fa4c | |||
| 6ac162f3cd | |||
| aea1d16e31 | |||
| 16e26ef215 | |||
| 7270e701d4 | |||
| c8010d4d52 | |||
| 6941b7463e | |||
| 99a6cd82b2 | |||
| 1a44307664 | |||
| 53d7a92a0d | |||
| 4ba1f47423 | |||
| c38e47b726 | |||
| e6a4d79b86 | |||
| b62d0697be | |||
| f90ebbbb4e | |||
| ab39802512 | |||
| 84da67adda | |||
| cfff3c6d97 | |||
| cc3d9e0d2d | |||
| 442e7eb015 | |||
| 59248b7c2e | |||
| f2d7a45b74 | |||
| c79b6147ea | |||
| d93be76505 | |||
| 5fff65db5a | |||
| 53e240add7 | |||
| 9cfc65eeda | |||
| 47c305d557 | |||
| c5ba89b054 | |||
| de8977723a | |||
| 8cea93de94 | |||
| e25cbe54d9 | |||
| b356522f94 | |||
| 7a6c1de5d5 | |||
| fb07adf7c1 | |||
| 9ceadd44c9 | |||
| e1c529ab91 | |||
| ce27af6083 | |||
| ac7d224645 | |||
| df26f492a7 | |||
| 448c01ca99 | |||
| bd7a9e5444 | |||
| 1e717710b6 | |||
| 3cb14ad3bc | |||
| 4769a67936 | |||
| 279f866bf5 | |||
| 5cbe7600a6 | |||
| cdb1a4c288 | |||
| 340bbd8727 | |||
| 53c916ea4f | |||
| 6451337274 | |||
| 294b75ce2d | |||
| 0ca4f3b104 | |||
| ac74510d47 | |||
| 33ec69d33a | |||
| f6d329ac48 | |||
| a56fbeb611 | |||
| 8c20a67cfa | |||
| fffa4fc031 | |||
| 3316b73ab6 | |||
| 211f7b7965 | |||
| 3a5a7bf674 | |||
| 7c749a964c | |||
| 997c8c87d0 | |||
| ed6a417d7e | |||
| 4a54f545a4 | |||
| 789902b79a | |||
| 266859af19 | |||
| 9cca1a4819 | |||
| aae1da3aa8 | |||
| aed688224b | |||
| 3ce1ec708d | |||
| 510a564797 | |||
| b36517babb | |||
| 415d18338e | |||
| 14384131f4 | |||
| b3d54ce57e | |||
| b5890340e3 | |||
| 050d987d3b | |||
| c4651cd915 | |||
| b5f97c0d94 | |||
| 35165ba2b8 | |||
| aeb1dcdf15 | |||
| 37730744e7 | |||
| f821fe0356 | |||
| ba16fdb548 | |||
| 144e6f59c8 | |||
| 2e42c5e875 | |||
| eec8743e2f | |||
| e5e5684e2e | |||
| efddc6ccec | |||
| 5aef46733b | |||
| 201782184c | |||
| 5f2ef046e1 | |||
| 42398950e4 | |||
| 506c8af1ea | |||
| 70d9c516af | |||
| 11ad86b9db | |||
| 2e9cfa6973 | |||
| 13e2c325e1 | |||
| 7e428a273f | |||
| aa4bd516a9 | |||
| 82f8675b68 | |||
| fdcb994e7a | |||
| e89fa23533 | |||
| 21d4f0f569 | |||
| 625201e559 | |||
| d36378fcbf | |||
| 929ecfd42b | |||
| 44496e424a | |||
| 1eb789e847 | |||
| 1ab76617df | |||
| 3bff653bbb | |||
| 4b7a8c6d6e | |||
| 9236be7fbd | |||
| fd9b922b21 | |||
| eea88f6e11 | |||
| eb47c968ae | |||
| 560019b26c | |||
| 589e07f869 | |||
| 585de53148 | |||
| 1e85b25438 | |||
| 71b57bfed1 | |||
| 870cb26e01 | |||
| 9a180b098f | |||
| 06682c333f | |||
| 18c0aa5c81 | |||
| e49b468fd5 | |||
| 7e5748b3a6 | |||
| e99aa86863 | |||
| bc6ae1d1b5 | |||
| df94a87a51 | |||
| 9f7b2de311 | |||
| dab6e10881 | |||
| 3b78c3a929 | |||
| 7029968c47 | |||
| a8fe4e6aab | |||
| b93dd8cb9b | |||
| 0ba614961d | |||
| 79c56d440c | |||
| 9601506270 | |||
| 9ed16b81e8 | |||
| 1800c1ff12 | |||
| a8067bee36 | |||
| f879663033 | |||
| d618af19d6 | |||
| 8aa61bf5bc | |||
| cd70f4b1c9 | |||
| 240e55029b | |||
| 9aabe7c72e | |||
| 6744dce57e | |||
| d38e40d53f | |||
| aa1b561bc0 | |||
| 6674b7890c | |||
| a3a62165e9 | |||
| 8eb5a62737 | |||
| c5ef462937 | |||
| eca397b45f | |||
| 9f7a583c92 | |||
| a59077b94f | |||
| d61bfaa993 | |||
| a17690f88b | |||
| 271e948c1f | |||
| ac7de6213a | |||
| 7ff6b64742 | |||
| 531e0ad19d | |||
| cc7112fb66 | |||
| cf08af31ac | |||
| 1fdcf3877e | |||
| 0fadf035db | |||
| 58b1c4b511 | |||
| 0cc8feac57 | |||
| ba1efd57a5 | |||
| 29656fb9a6 | |||
| 92d79ebeea | |||
| 3a69107eac | |||
| 4bfb528526 | |||
| fe9dd1d014 | |||
| 4829c8b314 | |||
| 59b4bf5267 | |||
| c19f34570d | |||
| 94d29796b8 | |||
| e9f44ffcc6 | |||
| a261ab4f0c | |||
| 929bcf03a0 | |||
| a6a69ab1b6 | |||
| 39de79d3cd | |||
| 40ab540179 | |||
| 7d7b6f4475 | |||
| ccdd433e35 | |||
| 4a6ea38ef8 | |||
| b20e25f052 | |||
| 8591d4e96c | |||
| 912051637a | |||
| c233f767f4 | |||
| e1293c2c74 | |||
| b63bf2465f | |||
| 505c9c6218 | |||
| 14350240eb | |||
| cb21991efa | |||
| 49e58c25f2 | |||
| ac6000a2ae | |||
| 6d1c9edc24 | |||
| 1a7fa3746d | |||
| f7a57ffeb4 | |||
| ad9d45a154 | |||
| 5fffb2afe3 | |||
| 1269114074 | |||
| d24f6ae064 | |||
| 95fe09489c | |||
| 1a144da36d | |||
| 8e26da1759 | |||
| daf53226c3 | |||
| 2b9e615e51 | |||
| 02acbecef5 | |||
| 8f28964ce2 | |||
| 495e74e2f0 | |||
| 543bd1a777 | |||
| 8f23970ccc | |||
| 9ec39658fe | |||
| 7c0518843f | |||
| 7131257354 | |||
| db527be97c | |||
| 7c46e42820 | |||
| 9943e081d9 | |||
| 68a51c9c63 | |||
| 6a98cdf974 | |||
| 9ca8c66c47 | |||
| 56754d616b | |||
| e7dd964825 | |||
| 39e348948c | |||
| 6583090d4f | |||
| f20134415e | |||
| 40996888c9 | |||
| 1ce26b3ada | |||
| e7092ae769 | |||
| b8b0ffb626 |
@@ -0,0 +1,4 @@
|
|||||||
|
deploy/data/windows/x64/tap/windows_7/OemVista.inf eol=crlf
|
||||||
|
deploy/data/windows/x64/tap/windows_10/OemVista.inf eol=crlf
|
||||||
|
deploy/data/windows/x32/tap/windows_7/OemVista.inf eol=crlf
|
||||||
|
deploy/data/windows/x32/tap/windows_10/OemVista.inf eol=crlf
|
||||||
@@ -0,0 +1,326 @@
|
|||||||
|
name: 'Deploy workflow'
|
||||||
|
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build-Linux-Ubuntu:
|
||||||
|
name: 'Build-Linux-Ubuntu'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.4.1
|
||||||
|
QIF_VERSION: 4.5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Install Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'desktop'
|
||||||
|
arch: 'gcc_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
tools: 'tools_ifw'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Get sources'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 10
|
||||||
|
|
||||||
|
- name: 'Setup ccache'
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
|
- name: 'Build project'
|
||||||
|
run: |
|
||||||
|
sudo apt-get install libxkbcommon-x11-0
|
||||||
|
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64/bin
|
||||||
|
export QIF_BIN_DIR=${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin
|
||||||
|
bash deploy/build_linux.sh
|
||||||
|
|
||||||
|
- name: 'Upload installer artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: AmneziaVPN_Linux_installer
|
||||||
|
path: deploy/AmneziaVPN_Linux_Installer
|
||||||
|
retention-days: 7
|
||||||
|
- name: 'Upload unpacked artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: AmneziaVPN_Linux_unpacked
|
||||||
|
path: deploy/AppDir
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
|
||||||
|
Build-Windows:
|
||||||
|
name: Build-Windows
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.4.1
|
||||||
|
QIF_VERSION: 4.5
|
||||||
|
BUILD_ARCH: 64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Get sources'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 10
|
||||||
|
|
||||||
|
- name: 'Setup ccache'
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
|
- name: 'Install Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'windows'
|
||||||
|
target: 'desktop'
|
||||||
|
arch: 'win64_msvc2019_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
tools: 'tools_ifw'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Setup mvsc'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: 'x64'
|
||||||
|
|
||||||
|
- name: 'Build project'
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
set BUILD_ARCH=${{ env.BUILD_ARCH }}
|
||||||
|
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2019_64\\bin"
|
||||||
|
set QIF_BIN_DIR="${{ runner.temp }}\\Qt\\Tools\\QtInstallerFramework\\${{ env.QIF_VERSION }}\\bin"
|
||||||
|
call deploy\\build_windows.bat
|
||||||
|
|
||||||
|
- name: 'Upload installer artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: AmneziaVPN_Windows_installer
|
||||||
|
path: AmneziaVPN_x${{ env.BUILD_ARCH }}.exe
|
||||||
|
retention-days: 7
|
||||||
|
- name: 'Upload unpacked artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: AmneziaVPN_Windows_unpacked
|
||||||
|
path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
|
||||||
|
Build-IOS:
|
||||||
|
name: 'Build-IOS'
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.4.1
|
||||||
|
QIF_VERSION: 4.4
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Setup xcode'
|
||||||
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
with:
|
||||||
|
xcode-version: '13.4'
|
||||||
|
|
||||||
|
- name: 'Install desktop Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'mac'
|
||||||
|
target: 'desktop'
|
||||||
|
arch: 'clang_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
set-env: 'true'
|
||||||
|
|
||||||
|
- name: 'Install ios Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'mac'
|
||||||
|
target: 'ios'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Install go'
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
|
||||||
|
- name: 'Setup gomobile'
|
||||||
|
run: |
|
||||||
|
export PATH=$PATH:~/go/bin
|
||||||
|
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||||
|
gomobile init
|
||||||
|
|
||||||
|
- name: 'Get sources'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 10
|
||||||
|
|
||||||
|
- name: 'Setup ccache'
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
|
- name: 'Build project'
|
||||||
|
run: |
|
||||||
|
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/ios/bin"
|
||||||
|
export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
|
||||||
|
export QT_IOS_BIN=$QT_BIN_DIR
|
||||||
|
export PATH=$PATH:~/go/bin
|
||||||
|
mkdir build-ios
|
||||||
|
$QT_IOS_BIN/qt-cmake . -B build-ios -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR
|
||||||
|
|
||||||
|
# - name: iOS Build/Release With Multiple Targets Action
|
||||||
|
# uses: kumarsunil0007/build-ios-action@latest
|
||||||
|
# with:
|
||||||
|
# project-path: build-ios/AmneziaVPN.xcodeproj
|
||||||
|
# p12-base64: ~/amnezia-vpn/amnezia-ios-certificates/certs/distribution/443886Q5PL.p12
|
||||||
|
# mobileprovision-base64: ~/amnezia-vpn/amnezia-ios-certificates/testprofilez.mobileprovision
|
||||||
|
# code-signing-identity: 'iOS Distribution'
|
||||||
|
# team-id: 'X7UJ388FXK'
|
||||||
|
# configuration: Release
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
|
||||||
|
Build-MacOS:
|
||||||
|
name: 'Build-MacOS'
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.4.1
|
||||||
|
QIF_VERSION: 4.5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Setup xcode'
|
||||||
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
with:
|
||||||
|
xcode-version: '13.4'
|
||||||
|
|
||||||
|
- name: 'Install Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'mac'
|
||||||
|
target: 'desktop'
|
||||||
|
arch: 'clang_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
tools: 'tools_ifw'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Get sources'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 10
|
||||||
|
|
||||||
|
- name: 'Setup ccache'
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
|
- name: 'Build project'
|
||||||
|
run: |
|
||||||
|
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
||||||
|
export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin"
|
||||||
|
bash deploy/build_macos.sh
|
||||||
|
|
||||||
|
- name: 'Upload installer artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: AmneziaVPN_MacOS_installer
|
||||||
|
path: AmneziaVPN.dmg
|
||||||
|
retention-days: 7
|
||||||
|
- name: 'Upload unpacked artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: AmneziaVPN_MacOS_unpacked
|
||||||
|
path: deploy/build/client/AmneziaVPN.app
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
|
||||||
|
Build-Android:
|
||||||
|
name: 'Build-Android'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: ['android_x86_64', 'android_x86'] #, 'android_armv7', 'android_arm64_v8a']
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.4.1
|
||||||
|
QIF_VERSION: 4.5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Install desktop Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'desktop'
|
||||||
|
arch: 'gcc_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Install android Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'android'
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Get sources'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 10
|
||||||
|
|
||||||
|
- name: 'Setup ccache'
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
|
- name: 'Setup Java'
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '11'
|
||||||
|
|
||||||
|
- name: 'Build project'
|
||||||
|
run: |
|
||||||
|
export QT_HOST_PATH="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64"
|
||||||
|
export NDK_VERSION=23c
|
||||||
|
export ANDROID_NDK_PLATFORM=android-23
|
||||||
|
export ANDROID_NDK_HOME=${{ runner.temp }}/android-ndk-r${NDK_VERSION}
|
||||||
|
export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
|
||||||
|
export ANDROID_CURRENT_ARCH=${{ matrix.arch }}
|
||||||
|
|
||||||
|
if [ ! -f $ANDROID_NDK_ROOT/ndk-build ]; then
|
||||||
|
wget https://dl.google.com/android/repository/android-ndk-r${NDK_VERSION}-linux.zip -qO ${{ runner.temp }}/ndk.zip &&
|
||||||
|
unzip -q -d ${{ runner.temp }} ${{ runner.temp }}/ndk.zip ;
|
||||||
|
fi
|
||||||
|
|
||||||
|
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/${{ matrix.arch }}/bin
|
||||||
|
bash deploy/build_android.sh
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
name: 'Release deploy workflow'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
# push:
|
||||||
|
# tags:
|
||||||
|
# - **
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
Build-Android-Release:
|
||||||
|
name: 'Build-Android-Release'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: 6.4.1
|
||||||
|
QIF_VERSION: 4.5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Install desktop Qt'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'desktop'
|
||||||
|
arch: 'gcc_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Install android Qt x86_64'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'android'
|
||||||
|
arch: 'android_x86_64'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Install android Qt x86'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'android'
|
||||||
|
arch: 'android_x86'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Install android Qt arm_v7'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'android'
|
||||||
|
arch: 'android_armv7'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Install android Qt arm_v8'
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
host: 'linux'
|
||||||
|
target: 'android'
|
||||||
|
arch: 'android_arm64_v8a'
|
||||||
|
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||||
|
dir: ${{ runner.temp }}
|
||||||
|
setup-python: 'true'
|
||||||
|
set-env: 'true'
|
||||||
|
extra: '--external 7z'
|
||||||
|
|
||||||
|
- name: 'Get sources'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: main
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 10
|
||||||
|
|
||||||
|
- name: 'Preparations before keystore fetching'
|
||||||
|
run: |
|
||||||
|
mkdir keystore
|
||||||
|
|
||||||
|
- name: 'Getting keystore'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: amnezia-vpn/amnezia-android-certificates
|
||||||
|
ssh-key: ${{ secrets.ANDROID_CERTS_SSH_PRIVATE_KEY }}
|
||||||
|
path: keystore
|
||||||
|
|
||||||
|
- name: 'Setup ccache'
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
|
- name: 'Setup Java'
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '11'
|
||||||
|
|
||||||
|
- name: 'Build project'
|
||||||
|
run: |
|
||||||
|
export QT_HOST_PATH="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64"
|
||||||
|
export NDK_VERSION=23c
|
||||||
|
export ANDROID_NDK_PLATFORM=android-23
|
||||||
|
export ANDROID_NDK_HOME=${{ runner.temp }}/android-ndk-r${NDK_VERSION}
|
||||||
|
export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
|
||||||
|
|
||||||
|
if [ ! -f $ANDROID_NDK_ROOT/ndk-build ]; then
|
||||||
|
wget https://dl.google.com/android/repository/android-ndk-r${NDK_VERSION}-linux.zip -qO ${{ runner.temp }}/ndk.zip &&
|
||||||
|
unzip -q -d ${{ runner.temp }} ${{ runner.temp }}/ndk.zip ;
|
||||||
|
fi
|
||||||
|
|
||||||
|
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/android_arm64_v8a/bin
|
||||||
|
cd main
|
||||||
|
bash deploy/build_android.sh
|
||||||
|
|
||||||
|
- name: 'Signing APK'
|
||||||
|
run: |
|
||||||
|
pwd
|
||||||
|
|
||||||
|
ANDROID_BUILD_TOOLS_VERSION=30.0.3
|
||||||
|
|
||||||
|
${ANDROID_HOME}/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/zipalign -f -v 4 AmneziaVPN-release-unsigned.apk AmneziaVPN-release-aligned.apk
|
||||||
|
${ANDROID_HOME}/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/apksigner sign --out AmneziaVPN-release-signed.apk --ks keystore/debug.keystore --ks-key-alias ${{ secrets.DEBUG_ANDROID_KEYSTORE_KEY_ALIAS }} --ks-pass pass:${{secrets.DEBUG_ANDROID_KEYSTOTE_KEY_PASS }} AmneziaVPN-release-aligned.apk
|
||||||
|
|
||||||
|
- name: 'Upload'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Release APK
|
||||||
|
path: ${{ runner.temp }}/main/AmneziaVPN-release-signed.apk
|
||||||
+18
-1
@@ -23,8 +23,14 @@ qrc_*.cpp
|
|||||||
ui_*.h
|
ui_*.h
|
||||||
Makefile*
|
Makefile*
|
||||||
*build-*
|
*build-*
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
|
# fastlane
|
||||||
|
client/fastlane/report.xml
|
||||||
|
client/fastlane/build/*
|
||||||
|
|
||||||
# Qt-es
|
# Qt-es
|
||||||
|
client/Release-iphoneos/
|
||||||
client/Debug-iphoneos/
|
client/Debug-iphoneos/
|
||||||
client/.xcode/
|
client/.xcode/
|
||||||
client/.qmake.cache
|
client/.qmake.cache
|
||||||
@@ -39,6 +45,7 @@ client/qrc_*.cpp
|
|||||||
client/ui_*.h
|
client/ui_*.h
|
||||||
client/ui_*.cpp
|
client/ui_*.cpp
|
||||||
client/Makefile*
|
client/Makefile*
|
||||||
|
client/fastlane/build/
|
||||||
client/*build-*
|
client/*build-*
|
||||||
client/AmneziaVPN.xcodeproj
|
client/AmneziaVPN.xcodeproj
|
||||||
client/Debug-iphonesimulator/
|
client/Debug-iphonesimulator/
|
||||||
@@ -48,7 +55,7 @@ client/qmlcache_loader.cpp
|
|||||||
client/rep_ipc_interface_replica.h
|
client/rep_ipc_interface_replica.h
|
||||||
client/resources_qmlcache.qrc
|
client/resources_qmlcache.qrc
|
||||||
client/3rd/OpenVPNAdpter/build/
|
client/3rd/OpenVPNAdpter/build/
|
||||||
|
client/3rd/ShadowSocks/build/
|
||||||
# QtCreator
|
# QtCreator
|
||||||
|
|
||||||
*.autosave
|
*.autosave
|
||||||
@@ -60,6 +67,12 @@ client/3rd/OpenVPNAdpter/build/
|
|||||||
# QtCtreator CMake
|
# QtCtreator CMake
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
|
|
||||||
|
# Linux files
|
||||||
|
*.7z
|
||||||
|
deploy/AppDir
|
||||||
|
deploy/Tools
|
||||||
|
deploy/AmneziaVPN*Installer*
|
||||||
|
|
||||||
# MACOS files
|
# MACOS files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
client/.DS_Store
|
client/.DS_Store
|
||||||
@@ -113,3 +126,7 @@ captures/
|
|||||||
|
|
||||||
# Android Profiling
|
# Android Profiling
|
||||||
*.hprof
|
*.hprof
|
||||||
|
client/3rd/ShadowSocks/ss_ios.xcconfig
|
||||||
|
|
||||||
|
# UML generated pics
|
||||||
|
out/
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
variables:
|
|
||||||
GIT_STRATEGY: clone
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- build
|
|
||||||
|
|
||||||
build-windows:
|
|
||||||
stage: build
|
|
||||||
tags:
|
|
||||||
- windows
|
|
||||||
script:
|
|
||||||
- cmd.exe /k "deploy\windows-env.bat && cd deploy && windows.bat"
|
|
||||||
artifacts:
|
|
||||||
name: artifacts-windows
|
|
||||||
paths:
|
|
||||||
- AmneziaVPN.exe
|
|
||||||
|
|
||||||
build-macos:
|
|
||||||
stage: build
|
|
||||||
tags:
|
|
||||||
- macos
|
|
||||||
script:
|
|
||||||
- cd deploy && ./macos.sh
|
|
||||||
artifacts:
|
|
||||||
name: artifacts-macos
|
|
||||||
paths:
|
|
||||||
- AmneziaVPN.dmg
|
|
||||||
+21
-3
@@ -10,6 +10,24 @@
|
|||||||
[submodule "client/3rd/OpenVPNAdapter"]
|
[submodule "client/3rd/OpenVPNAdapter"]
|
||||||
path = client/3rd/OpenVPNAdapter
|
path = client/3rd/OpenVPNAdapter
|
||||||
url = https://github.com/ss-abramchuk/OpenVPNAdapter.git
|
url = https://github.com/ss-abramchuk/OpenVPNAdapter.git
|
||||||
[submodule "client/3rd/qzxing"]
|
[submodule "client/3rd/ShadowPath"]
|
||||||
path = client/3rd/qzxing
|
path = client/3rd/ShadowPath
|
||||||
url = https://github.com/ftylitak/qzxing.git
|
url = https://github.com/qman9501/ShadowPath
|
||||||
|
[submodule "client/3rd/outline-go-tun2socks"]
|
||||||
|
path = client/3rd/outline-go-tun2socks
|
||||||
|
url = https://github.com/Jigsaw-Code/outline-go-tun2socks.git
|
||||||
|
[submodule "client/3rd/CocoaAsyncSocket"]
|
||||||
|
path = client/3rd/CocoaAsyncSocket
|
||||||
|
url = https://github.com/robbiehanson/CocoaAsyncSocket.git
|
||||||
|
[submodule "client/3rd/CocoaLumberjack"]
|
||||||
|
path = client/3rd/CocoaLumberjack
|
||||||
|
url = https://github.com/CocoaLumberjack/CocoaLumberjack.git
|
||||||
|
[submodule "client/3rd/qtkeychain"]
|
||||||
|
path = client/3rd/qtkeychain
|
||||||
|
url = https://github.com/frankosterfeld/qtkeychain.git
|
||||||
|
[submodule "deploy/amnezia-ios-certificates"]
|
||||||
|
path = deploy/amnezia-ios-certificates
|
||||||
|
url = https://github.com/amnezia-vpn/amnezia-ios-certificates.git
|
||||||
|
[submodule "client/3rd/SortFilterProxyModel"]
|
||||||
|
path = client/3rd/SortFilterProxyModel
|
||||||
|
url = https://github.com/mitchcurtis/SortFilterProxyModel.git
|
||||||
|
|||||||
-144
@@ -1,144 +0,0 @@
|
|||||||
language: cpp
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- dev
|
|
||||||
- /\d+\.\d+/
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- name: MacOS
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode12.5
|
|
||||||
|
|
||||||
env:
|
|
||||||
- QT_VERSION=5.15.2
|
|
||||||
- QIF_VERSION=4.1
|
|
||||||
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin
|
|
||||||
- QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
|
|
||||||
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
if [ ! -f $HOME/Qt/$QT_VERSION/clang_64/bin/qmake ]; then \
|
|
||||||
brew install p7zip && \
|
|
||||||
python3 -m pip install --upgrade pip && \
|
|
||||||
pip install -U aqtinstall requests py7zr && \
|
|
||||||
pip show aqtinstall && \
|
|
||||||
python3 -m aqt install --outputdir $HOME/Qt $QT_VERSION mac desktop clang_64 -m qtbase && \
|
|
||||||
python3 -m aqt tool --outputdir $HOME/Qt mac tools_ifw $QIF_VERSION qt.tools.ifw.${QIF_VERSION/./};
|
|
||||||
fi
|
|
||||||
- bash deploy/build_macos.sh
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
token: $GH_TOKEN
|
|
||||||
skip_cleanup: true
|
|
||||||
file:
|
|
||||||
- "AmneziaVPN_unsigned.dmg"
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
branch: master
|
|
||||||
|
|
||||||
- name: Windows_x64
|
|
||||||
os: windows
|
|
||||||
|
|
||||||
env:
|
|
||||||
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
|
|
||||||
- QT_VERSION=5.14.2
|
|
||||||
- QIF_VERSION=4.1
|
|
||||||
- QT_BIN_DIR="c:\\Qt\\$QT_VERSION\\msvc2017_64\\bin"
|
|
||||||
- QIF_BIN_DIR="c:\\Qt\\Tools\\QtInstallerFramework\\${QIF_VERSION}\\bin"
|
|
||||||
- BUILD_ARCH=64
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- if [ ! -f /C/Qt/$QT_VERSION/msvc2017_64/bin/qmake ]; then choco install python --version 3.9.1; fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build"
|
|
||||||
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools"
|
|
||||||
- |
|
|
||||||
if [ ! -f /C/Qt/$QT_VERSION/msvc2017_64/bin/qmake ]; then \
|
|
||||||
python -m pip install --upgrade pip && \
|
|
||||||
pip3 install -U aqtinstall requests py7zr && \
|
|
||||||
pip3 show aqtinstall && \
|
|
||||||
python -m aqt install --outputdir /C/Qt $QT_VERSION windows desktop win64_msvc2017_64 -m qtbase && \
|
|
||||||
python -m aqt tool --outputdir /C/Qt windows tools_ifw $QIF_VERSION qt.tools.ifw.${QIF_VERSION/./}; \
|
|
||||||
fi
|
|
||||||
- echo set BUILD_ARCH=$BUILD_ARCH > winbuild.bat
|
|
||||||
- echo set QT_BIN_DIR="$QT_BIN_DIR" >> winbuild.bat
|
|
||||||
- echo set QIF_BIN_DIR="$QIF_BIN_DIR" >> winbuild.bat
|
|
||||||
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Auxiliary\\Build\\vcvars${BUILD_ARCH}.bat\"" >> winbuild.bat
|
|
||||||
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\Common7\\Tools\\VsDevCmd.bat\" -arch=amd64" >> winbuild.bat
|
|
||||||
- echo set WIN_CERT_PW=$WIN_CERT_PW >> winbuild.bat
|
|
||||||
- echo call deploy\\build_windows.bat >> winbuild.bat
|
|
||||||
- cmd //c winbuild.bat
|
|
||||||
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
token: $GH_TOKEN
|
|
||||||
skip_cleanup: true
|
|
||||||
file:
|
|
||||||
- "AmneziaVPN_x64.exe"
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
branch: master
|
|
||||||
|
|
||||||
- name: Windows_x32
|
|
||||||
os: windows
|
|
||||||
|
|
||||||
env:
|
|
||||||
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
|
|
||||||
- QT_VERSION=5.14.2
|
|
||||||
- QIF_VERSION=4.1
|
|
||||||
- QT_BIN_DIR="c:\\Qt\\${QT_VERSION}\\msvc2017\\bin"
|
|
||||||
- QIF_BIN_DIR="c:\\Qt\\Tools\\QtInstallerFramework\\${QIF_VERSION}\\bin"
|
|
||||||
- BUILD_ARCH=32
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- if [ ! -f /C/Qt/$QT_VERSION/msvc2017/bin/qmake ]; then choco install python --version 3.9.1; fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build"
|
|
||||||
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools"
|
|
||||||
- |
|
|
||||||
if [ ! -f /C/Qt/$QT_VERSION/msvc2017/bin/qmake ]; then \
|
|
||||||
python -m pip install --upgrade pip && \
|
|
||||||
pip3 install -U aqtinstall requests py7zr && \
|
|
||||||
pip3 show aqtinstall && \
|
|
||||||
python -m aqt install --outputdir /C/Qt $QT_VERSION windows desktop win32_msvc2017 -m qtbase && \
|
|
||||||
python -m aqt tool --outputdir /C/Qt windows tools_ifw $QIF_VERSION qt.tools.ifw.${QIF_VERSION/./}; \
|
|
||||||
fi
|
|
||||||
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\Common7\\Tools\\VsDevCmd.bat\"" > winbuild.bat
|
|
||||||
- echo set BUILD_ARCH=$BUILD_ARCH >> winbuild.bat
|
|
||||||
- echo set QT_BIN_DIR="$QT_BIN_DIR" >> winbuild.bat
|
|
||||||
- echo set QIF_BIN_DIR="$QIF_BIN_DIR" >> winbuild.bat
|
|
||||||
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Auxiliary\\Build\\vcvars${BUILD_ARCH}.bat\"" >> winbuild.bat
|
|
||||||
- echo set WIN_CERT_PW=$WIN_CERT_PW >> winbuild.bat
|
|
||||||
- echo call deploy\\build_windows.bat >> winbuild.bat
|
|
||||||
- cmd //c winbuild.bat
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
token: $GH_TOKEN
|
|
||||||
skip_cleanup: true
|
|
||||||
file:
|
|
||||||
- "AmneziaVPN_x32.exe"
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
branch: master
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
skip_cleanup: true
|
|
||||||
|
|
||||||
before_cache:
|
|
||||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
|
|
||||||
# Cache only .git files under "/usr/local/Homebrew" so "brew update" does not take 5min every build
|
|
||||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; fi
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- $HOME/Qt
|
|
||||||
- /C/Qt
|
|
||||||
- $HOME/Library/Caches/Homebrew
|
|
||||||
+1
-1
@@ -2,5 +2,5 @@ TEMPLATE = subdirs
|
|||||||
SUBDIRS = client
|
SUBDIRS = client
|
||||||
|
|
||||||
!ios:!android {
|
!ios:!android {
|
||||||
SUBDIRS += service platform
|
SUBDIRS += service
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||||
|
|
||||||
|
set(PROJECT AmneziaVPN)
|
||||||
|
project(${PROJECT})
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
set(QT_ANDROID_BUILD_ALL_ABIS ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(client)
|
||||||
|
|
||||||
|
if(NOT IOS AND NOT ANDROID)
|
||||||
|
add_subdirectory(service)
|
||||||
|
endif()
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Amnezia VPN
|
# Amnezia VPN
|
||||||
## _The best client for self-hosted VPN_
|
## _The best client for self-hosted VPN_
|
||||||
|
|
||||||
[](https://travis-ci.com/amnezia-vpn/desktop-client)
|
[]
|
||||||
|
|
||||||
Amnezia is a VPN client with the key feature of deploying your own VPN server on you virtual server.
|
Amnezia is a VPN client with the key feature of deploying your own VPN server on you virtual server.
|
||||||
|
|
||||||
@@ -20,11 +20,17 @@ AmneziaVPN uses a number of open source projects to work:
|
|||||||
- [OpenVPN](https://openvpn.net/)
|
- [OpenVPN](https://openvpn.net/)
|
||||||
- [ShadowSocks](https://shadowsocks.org/)
|
- [ShadowSocks](https://shadowsocks.org/)
|
||||||
- [Qt](https://www.qt.io/)
|
- [Qt](https://www.qt.io/)
|
||||||
- [EasyRSA](https://github.com/OpenVPN/easy-rsa) - part of OpenVPN
|
|
||||||
- [CygWin](https://www.cygwin.com/) - only for Windiws, used for launching EasyRSA scripts
|
|
||||||
- [QtSsh](https://github.com/jaredtao/QtSsh) - forked form Qt Creator
|
- [QtSsh](https://github.com/jaredtao/QtSsh) - forked form Qt Creator
|
||||||
- and more...
|
- and more...
|
||||||
|
|
||||||
|
## Checking out the source code
|
||||||
|
|
||||||
|
Make sure to pull all submodules after checking out the repo.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git submodule update --init
|
||||||
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Want to contribute? Welcome!
|
Want to contribute? Welcome!
|
||||||
@@ -34,6 +40,63 @@ Easiest way to build your own executables - is to fork project and configure [Tr
|
|||||||
Or you can build sources manually using Qt Creator. Qt >= 14.2 supported.
|
Or you can build sources manually using Qt Creator. Qt >= 14.2 supported.
|
||||||
Look to the `build_macos.sh` and `build_windows.bat` scripts in `deploy` folder for details.
|
Look to the `build_macos.sh` and `build_windows.bat` scripts in `deploy` folder for details.
|
||||||
|
|
||||||
|
### How to build iOS app from source code on MacOS
|
||||||
|
|
||||||
|
1. First, make sure you have [XCode](https://developer.apple.com/xcode/) installed,
|
||||||
|
at least version 12 or higher.
|
||||||
|
|
||||||
|
2. We use `qmake` to generate the XCode project and then we "patch" it to add
|
||||||
|
extra components such as the wireguard, the browser bridge and so on. We patch
|
||||||
|
the XCode project using [xcodeproj](https://github.com/CocoaPods/Xcodeproj). To
|
||||||
|
install it:
|
||||||
|
```bash
|
||||||
|
gem install xcodeproj # probably you want to run this command with `sudo`
|
||||||
|
```
|
||||||
|
3. You also need to install go >= v1.16. If you don't have it done already,
|
||||||
|
download go from the [official website](https://golang.org/dl/) or use Homebrew.
|
||||||
|
Latest version is recommended.
|
||||||
|
|
||||||
|
4. Navigate inside client folder and generate the XCode project using our script:
|
||||||
|
```bash
|
||||||
|
cd client
|
||||||
|
./scripts/apple_compile.sh ios
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have more than one version of Qt installed, you'll most likely get
|
||||||
|
a "`qmake` cannot be found in your `$PATH`" error. In this case run this script
|
||||||
|
using QT\IOS\_BIN env to set the path for the Qt5 macos build bin folder.
|
||||||
|
For example, the path could look like this:
|
||||||
|
```bash
|
||||||
|
QT_IOS_BIN="/Users/username/Qt/6.4.1/ios/bin" ./scripts/apple_compile.sh ios
|
||||||
|
```
|
||||||
|
|
||||||
|
If you get `gomobile: command not found` make sure to set PATH to the location
|
||||||
|
of the bin folder where gomobile was installed. Usually, it's in `GOPATH`.
|
||||||
|
```bash
|
||||||
|
export PATH=$(PATH):/path/to/GOPATH/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Xcode should automatically open. You can then run/test/archive/ship the app.
|
||||||
|
|
||||||
|
If build fails with the following error
|
||||||
|
```
|
||||||
|
make: ***
|
||||||
|
[$(PROJECTDIR)/client/build/AmneziaVPN.build/Debug-iphoneos/wireguard-go-bridge/goroot/.prepared]
|
||||||
|
Error 1
|
||||||
|
```
|
||||||
|
Add a user defined variable to both AmneziaVPN and WireGuardNetworkExtension targets' build settings with
|
||||||
|
key `PATH` and value `${PATH}/path/to/bin/folder/with/go/executable`, e.g. `${PATH}:/usr/local/go/bin`.
|
||||||
|
|
||||||
|
if above error still persists on you M1 Mac, then most proably you need to install arch based cmake
|
||||||
|
```
|
||||||
|
arch -arm64 brew install cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
Build might fail with "source files not found" error the first time you try it, because modern XCode build system compiles
|
||||||
|
dependencies in parallel, and some dependencies end up being built after the ones that
|
||||||
|
require them. In this case simply restart the build.
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
GPL v.3
|
GPL v.3
|
||||||
|
|
||||||
|
|||||||
Submodule
+1
Submodule client/3rd/CocoaAsyncSocket added at 5ddba5e72f
Submodule
+1
Submodule client/3rd/CocoaLumberjack added at 70f04b1dc5
File diff suppressed because it is too large
Load Diff
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
BIN
Binary file not shown.
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>PacketProcessor.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
BIN
Binary file not shown.
+18
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// CocoaAsyncSocket.h
|
||||||
|
// CocoaAsyncSocket
|
||||||
|
//
|
||||||
|
// Created by Derek Clarkson on 10/08/2015.
|
||||||
|
// CocoaAsyncSocket project is in the public domain.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
//! Project version number for CocoaAsyncSocket.
|
||||||
|
FOUNDATION_EXPORT double cocoaAsyncSocketVersionNumber;
|
||||||
|
|
||||||
|
//! Project version string for CocoaAsyncSocket.
|
||||||
|
FOUNDATION_EXPORT const unsigned char cocoaAsyncSocketVersionString[];
|
||||||
|
|
||||||
|
#import <CocoaAsyncSocket/GCDAsyncSocket.h>
|
||||||
|
#import <CocoaAsyncSocket/GCDAsyncUdpSocket.h>
|
||||||
+1226
File diff suppressed because it is too large
Load Diff
+1036
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+6
@@ -0,0 +1,6 @@
|
|||||||
|
framework module CocoaAsyncSocket {
|
||||||
|
umbrella header "CocoaAsyncSocket.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>files</key>
|
||||||
|
<dict>
|
||||||
|
<key>Headers/CocoaAsyncSocket.h</key>
|
||||||
|
<data>
|
||||||
|
19xueMkhcDCf6A2ihyiTCDjWjd4=
|
||||||
|
</data>
|
||||||
|
<key>Headers/GCDAsyncSocket.h</key>
|
||||||
|
<data>
|
||||||
|
JwDJxahaKup9fnB5MJuoxDHbdDs=
|
||||||
|
</data>
|
||||||
|
<key>Headers/GCDAsyncUdpSocket.h</key>
|
||||||
|
<data>
|
||||||
|
9hL7D86xSUKQ1TBRDa+fDNkDlqI=
|
||||||
|
</data>
|
||||||
|
<key>Info.plist</key>
|
||||||
|
<data>
|
||||||
|
eCKEB+C8HfC7DIu6eNc6P3wxyLo=
|
||||||
|
</data>
|
||||||
|
<key>Modules/module.modulemap</key>
|
||||||
|
<data>
|
||||||
|
+n94rYTWDjekX3imyh+PSyA9vgA=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>files2</key>
|
||||||
|
<dict>
|
||||||
|
<key>Headers/CocoaAsyncSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
19xueMkhcDCf6A2ihyiTCDjWjd4=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
VpE7gL1U1p/0urO77FEjPNjY06qrttQJnalOd+6VYDQ=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Headers/GCDAsyncSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
JwDJxahaKup9fnB5MJuoxDHbdDs=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
JL0b2lWPgVphz/ekZLsGMKrShDXTK2YY53aKtusc9hk=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Headers/GCDAsyncUdpSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
9hL7D86xSUKQ1TBRDa+fDNkDlqI=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
uNVm5yZ0jBhGDXZuAynPXvem1qcBvAVdWXAewQdJbh8=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Modules/module.modulemap</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
+n94rYTWDjekX3imyh+PSyA9vgA=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
RoVn8xMeEnU3Izg0DtYjYL/krI8V7qw0sa7Ggf+08Rs=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>rules</key>
|
||||||
|
<dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version.plist$</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>rules2</key>
|
||||||
|
<dict>
|
||||||
|
<key>.*\.dSYM($|/)</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>11</real>
|
||||||
|
</dict>
|
||||||
|
<key>^(.*/)?\.DS_Store$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>2000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Info\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^PkgInfo$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^embedded\.provisionprofile$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// PacketProcessor.h
|
||||||
|
// PacketProcessor
|
||||||
|
//
|
||||||
|
// Created by sanchez on 20.12.2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
//! Project version number for PacketProcessor.
|
||||||
|
FOUNDATION_EXPORT double PacketProcessorVersionNumber;
|
||||||
|
|
||||||
|
//! Project version string for PacketProcessor.
|
||||||
|
FOUNDATION_EXPORT const unsigned char PacketProcessorVersionString[];
|
||||||
|
|
||||||
|
// In this header, you should import all the public headers of your framework using statements like #import <PacketProcessor/PublicHeader.h>
|
||||||
|
|
||||||
|
|
||||||
|
#import "TunnelInterface.h"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// TunnelInterface.h
|
||||||
|
// Potatso
|
||||||
|
//
|
||||||
|
// Created by LEI on 12/23/15.
|
||||||
|
// Copyright © 2015 TouchingApp. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@import NetworkExtension;
|
||||||
|
|
||||||
|
#define TunnelMTU 1600
|
||||||
|
#define kTun2SocksStoppedNotification @"kTun2SocksStoppedNotification"
|
||||||
|
|
||||||
|
@interface TunnelInterface : NSObject
|
||||||
|
+ (TunnelInterface *)sharedInterface;
|
||||||
|
+ (NSError *)setupWithPacketTunnelFlow:(NEPacketTunnelFlow *)packetFlow;
|
||||||
|
+ (void)processPackets;
|
||||||
|
+ (void)writePacket: (NSData *)packet;
|
||||||
|
+ (void)startTun2Socks: (int)socksServerPort;
|
||||||
|
+ (void)stop;
|
||||||
|
@end
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
//
|
||||||
|
// TunnelInterface.m
|
||||||
|
// Potatso
|
||||||
|
//
|
||||||
|
// Created by LEI on 12/23/15.
|
||||||
|
// Copyright © 2015 TouchingApp. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "TunnelInterface.h"
|
||||||
|
#import <netinet/ip.h>
|
||||||
|
#import "ipv4/lwip/ip4.h"
|
||||||
|
#import "lwip/udp.h"
|
||||||
|
#import "lwip/ip.h"
|
||||||
|
#import <arpa/inet.h>
|
||||||
|
#import "inet_chksum.h"
|
||||||
|
#import "tun2socks/tun2socks.h"
|
||||||
|
@import CocoaAsyncSocket;
|
||||||
|
|
||||||
|
#define kTunnelInterfaceErrorDomain [NSString stringWithFormat:@"%@.TunnelInterface", [[NSBundle mainBundle] bundleIdentifier]]
|
||||||
|
|
||||||
|
@interface TunnelInterface () <GCDAsyncUdpSocketDelegate>
|
||||||
|
@property (nonatomic) NEPacketTunnelFlow *tunnelPacketFlow;
|
||||||
|
@property (nonatomic) NSMutableDictionary *udpSession;
|
||||||
|
@property (nonatomic) GCDAsyncUdpSocket *udpSocket;
|
||||||
|
@property (nonatomic) int readFd;
|
||||||
|
@property (nonatomic) int writeFd;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation TunnelInterface
|
||||||
|
|
||||||
|
+ (TunnelInterface *)sharedInterface {
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
static TunnelInterface *interface;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
interface = [TunnelInterface new];
|
||||||
|
});
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_udpSession = [NSMutableDictionary dictionaryWithCapacity:5];
|
||||||
|
_udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_queue_create("udp", NULL)];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSError *)setupWithPacketTunnelFlow:(NEPacketTunnelFlow *)packetFlow {
|
||||||
|
if (packetFlow == nil) {
|
||||||
|
return [NSError errorWithDomain:kTunnelInterfaceErrorDomain code:1 userInfo:@{NSLocalizedDescriptionKey: @"PacketTunnelFlow can't be nil."}];
|
||||||
|
}
|
||||||
|
[TunnelInterface sharedInterface].tunnelPacketFlow = packetFlow;
|
||||||
|
|
||||||
|
NSError *error;
|
||||||
|
GCDAsyncUdpSocket *udpSocket = [TunnelInterface sharedInterface].udpSocket;
|
||||||
|
[udpSocket bindToPort:0 error:&error];
|
||||||
|
if (error) {
|
||||||
|
return [NSError errorWithDomain:kTunnelInterfaceErrorDomain code:1 userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"UDP bind fail(%@).", [error localizedDescription]]}];
|
||||||
|
}
|
||||||
|
[udpSocket beginReceiving:&error];
|
||||||
|
if (error) {
|
||||||
|
return [NSError errorWithDomain:kTunnelInterfaceErrorDomain code:1 userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"UDP bind fail(%@).", [error localizedDescription]]}];
|
||||||
|
}
|
||||||
|
|
||||||
|
int fds[2];
|
||||||
|
if (pipe(fds) < 0) {
|
||||||
|
return [NSError errorWithDomain:kTunnelInterfaceErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Unable to pipe."}];
|
||||||
|
}
|
||||||
|
[TunnelInterface sharedInterface].readFd = fds[0];
|
||||||
|
[TunnelInterface sharedInterface].writeFd = fds[1];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)startTun2Socks: (int)socksServerPort {
|
||||||
|
[NSThread detachNewThreadSelector:@selector(_startTun2Socks:) toTarget:[TunnelInterface sharedInterface] withObject:@(socksServerPort)];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)stop {
|
||||||
|
stop_tun2socks();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)writePacket:(NSData *)packet {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[[TunnelInterface sharedInterface].tunnelPacketFlow writePackets:@[packet] withProtocols:@[@(AF_INET)]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)processPackets {
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
|
[[TunnelInterface sharedInterface].tunnelPacketFlow readPacketsWithCompletionHandler:^(NSArray<NSData *> * _Nonnull packets, NSArray<NSNumber *> * _Nonnull protocols) {
|
||||||
|
for (NSData *packet in packets) {
|
||||||
|
uint8_t *data = (uint8_t *)packet.bytes;
|
||||||
|
struct ip_hdr *iphdr = (struct ip_hdr *)data;
|
||||||
|
uint8_t proto = IPH_PROTO(iphdr);
|
||||||
|
if (proto == IP_PROTO_UDP) {
|
||||||
|
[[TunnelInterface sharedInterface] handleUDPPacket:packet];
|
||||||
|
}else if (proto == IP_PROTO_TCP) {
|
||||||
|
[[TunnelInterface sharedInterface] handleTCPPPacket:packet];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[weakSelf processPackets];
|
||||||
|
}];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_startTun2Socks: (NSNumber *)socksServerPort {
|
||||||
|
char socks_server[50];
|
||||||
|
sprintf(socks_server, "127.0.0.1:%d", (int)([socksServerPort integerValue]));
|
||||||
|
#if TCP_DATA_LOG_ENABLE
|
||||||
|
char *log_lvel = "debug";
|
||||||
|
#else
|
||||||
|
char *log_lvel = "none";
|
||||||
|
#endif
|
||||||
|
char *argv[] = {
|
||||||
|
"tun2socks",
|
||||||
|
"--netif-ipaddr",
|
||||||
|
"192.0.2.4",
|
||||||
|
"--netif-netmask",
|
||||||
|
"255.255.255.0",
|
||||||
|
"--loglevel",
|
||||||
|
log_lvel,
|
||||||
|
"--socks-server-addr",
|
||||||
|
socks_server
|
||||||
|
};
|
||||||
|
tun2socks_main(sizeof(argv)/sizeof(argv[0]), argv, self.readFd, TunnelMTU);
|
||||||
|
close(self.readFd);
|
||||||
|
close(self.writeFd);
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:kTun2SocksStoppedNotification object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleTCPPPacket: (NSData *)packet {
|
||||||
|
uint8_t message[TunnelMTU+2];
|
||||||
|
memcpy(message + 2, packet.bytes, packet.length);
|
||||||
|
message[0] = packet.length / 256;
|
||||||
|
message[1] = packet.length % 256;
|
||||||
|
write(self.writeFd , message , packet.length + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleUDPPacket: (NSData *)packet {
|
||||||
|
uint8_t *data = (uint8_t *)packet.bytes;
|
||||||
|
int data_len = (int)packet.length;
|
||||||
|
struct ip_hdr *iphdr = (struct ip_hdr *)data;
|
||||||
|
uint8_t version = IPH_V(iphdr);
|
||||||
|
|
||||||
|
switch (version) {
|
||||||
|
case 4: {
|
||||||
|
uint16_t iphdr_hlen = IPH_HL(iphdr) * 4;
|
||||||
|
data = data + iphdr_hlen;
|
||||||
|
data_len -= iphdr_hlen;
|
||||||
|
struct udp_hdr *udphdr = (struct udp_hdr *)data;
|
||||||
|
|
||||||
|
data = data + sizeof(struct udp_hdr *);
|
||||||
|
data_len -= sizeof(struct udp_hdr *);
|
||||||
|
|
||||||
|
NSData *outData = [[NSData alloc] initWithBytes:data length:data_len];
|
||||||
|
struct in_addr dest = { iphdr->dest.addr };
|
||||||
|
NSString *destHost = [NSString stringWithUTF8String:inet_ntoa(dest)];
|
||||||
|
NSString *key = [self strForHost:iphdr->dest.addr port:udphdr->dest];
|
||||||
|
NSString *value = [self strForHost:iphdr->src.addr port:udphdr->src];;
|
||||||
|
self.udpSession[key] = value;
|
||||||
|
[self.udpSocket sendData:outData toHost:destHost port:ntohs(udphdr->dest) withTimeout:30 tag:0];
|
||||||
|
} break;
|
||||||
|
case 6: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
|
||||||
|
const struct sockaddr_in *addr = (const struct sockaddr_in *)[address bytes];
|
||||||
|
ip_addr_p_t dest ={ addr->sin_addr.s_addr };
|
||||||
|
in_port_t dest_port = addr->sin_port;
|
||||||
|
NSString *strHostPort = self.udpSession[[self strForHost:dest.addr port:dest_port]];
|
||||||
|
NSArray *hostPortArray = [strHostPort componentsSeparatedByString:@":"];
|
||||||
|
int src_ip = [hostPortArray[0] intValue];
|
||||||
|
int src_port = [hostPortArray[1] intValue];
|
||||||
|
uint8_t *bytes = (uint8_t *)[data bytes];
|
||||||
|
int bytes_len = (int)data.length;
|
||||||
|
int udp_length = sizeof(struct udp_hdr) + bytes_len;
|
||||||
|
int total_len = IP_HLEN + udp_length;
|
||||||
|
|
||||||
|
ip_addr_p_t src = {src_ip};
|
||||||
|
struct ip_hdr *iphdr = generateNewIPHeader(IP_PROTO_UDP, dest, src, total_len);
|
||||||
|
|
||||||
|
struct udp_hdr udphdr;
|
||||||
|
udphdr.src = dest_port;
|
||||||
|
udphdr.dest = src_port;
|
||||||
|
udphdr.len = hton16(udp_length);
|
||||||
|
udphdr.chksum = hton16(0);
|
||||||
|
|
||||||
|
uint8_t *udpdata = malloc(sizeof(uint8_t) * udp_length);
|
||||||
|
memcpy(udpdata, &udphdr, sizeof(struct udp_hdr));
|
||||||
|
memcpy(udpdata + sizeof(struct udp_hdr), bytes, bytes_len);
|
||||||
|
|
||||||
|
ip_addr_t odest = { dest.addr };
|
||||||
|
ip_addr_t osrc = { src_ip };
|
||||||
|
|
||||||
|
struct pbuf *p_udp = pbuf_alloc(PBUF_TRANSPORT, udp_length, PBUF_RAM);
|
||||||
|
pbuf_take(p_udp, udpdata, udp_length);
|
||||||
|
|
||||||
|
struct udp_hdr *new_udphdr = (struct udp_hdr *) p_udp->payload;
|
||||||
|
new_udphdr->chksum = inet_chksum_pseudo(p_udp, IP_PROTO_UDP, p_udp->len, &odest, &osrc);
|
||||||
|
|
||||||
|
uint8_t *ipdata = malloc(sizeof(uint8_t) * total_len);
|
||||||
|
memcpy(ipdata, iphdr, IP_HLEN);
|
||||||
|
memcpy(ipdata + sizeof(struct ip_hdr), p_udp->payload, udp_length);
|
||||||
|
|
||||||
|
NSData *outData = [[NSData alloc] initWithBytes:ipdata length:total_len];
|
||||||
|
free(ipdata);
|
||||||
|
free(iphdr);
|
||||||
|
free(udpdata);
|
||||||
|
pbuf_free(p_udp);
|
||||||
|
[TunnelInterface writePacket:outData];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ip_hdr *generateNewIPHeader(u8_t proto, ip_addr_p_t src, ip_addr_p_t dest, uint16_t total_len) {
|
||||||
|
struct ip_hdr *iphdr = malloc(sizeof(struct ip_hdr));
|
||||||
|
IPH_VHL_SET(iphdr, 4, IP_HLEN / 4);
|
||||||
|
IPH_TOS_SET(iphdr, 0);
|
||||||
|
IPH_LEN_SET(iphdr, htons(total_len));
|
||||||
|
IPH_ID_SET(iphdr, 0);
|
||||||
|
IPH_OFFSET_SET(iphdr, 0);
|
||||||
|
IPH_TTL_SET(iphdr, 64);
|
||||||
|
IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
|
||||||
|
iphdr->src = src;
|
||||||
|
iphdr->dest = dest;
|
||||||
|
IPH_CHKSUM_SET(iphdr, 0);
|
||||||
|
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
|
||||||
|
return iphdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)strForHost: (int)host port: (int)port {
|
||||||
|
return [NSString stringWithFormat:@"%d:%d",host, port];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,400 @@
|
|||||||
|
/**
|
||||||
|
* @file BLog.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* A global object for logging.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_BLOG_H
|
||||||
|
#define BADVPN_BLOG_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/memref.h"
|
||||||
|
#include "base/BMutex.h"
|
||||||
|
|
||||||
|
// auto-generated channel numbers and number of channels
|
||||||
|
#include "generated/blog_channels_defines.h"
|
||||||
|
|
||||||
|
// keep in sync with level names in BLog.c!
|
||||||
|
#define BLOG_ERROR 1
|
||||||
|
#define BLOG_WARNING 2
|
||||||
|
#define BLOG_NOTICE 3
|
||||||
|
#define BLOG_INFO 4
|
||||||
|
#define BLOG_DEBUG 5
|
||||||
|
|
||||||
|
#define BLog(...) BLog_LogToChannel(BLOG_CURRENT_CHANNEL, __VA_ARGS__)
|
||||||
|
#define BContextLog(context, ...) BLog_ContextLog((context), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
|
||||||
|
#define BLOG_CCCC(context) BLog_MakeChannelContext((context), BLOG_CURRENT_CHANNEL)
|
||||||
|
|
||||||
|
typedef void (*_BLog_log_func) (int channel, int level, const char *msg);
|
||||||
|
typedef void (*_BLog_free_func) (void);
|
||||||
|
|
||||||
|
struct _BLog_channel {
|
||||||
|
const char *name;
|
||||||
|
int loglevel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _BLog_global {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
int initialized; // initialized statically
|
||||||
|
#endif
|
||||||
|
struct _BLog_channel channels[BLOG_NUM_CHANNELS];
|
||||||
|
_BLog_log_func log_func;
|
||||||
|
_BLog_free_func free_func;
|
||||||
|
BMutex mutex;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
int logging;
|
||||||
|
#endif
|
||||||
|
char logbuf[2048];
|
||||||
|
int logbuf_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _BLog_channel blog_channel_list[];
|
||||||
|
extern struct _BLog_global blog_global;
|
||||||
|
|
||||||
|
typedef void (*BLog_logfunc) (void *);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BLog_logfunc logfunc;
|
||||||
|
void *logfunc_user;
|
||||||
|
} BLogContext;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BLogContext context;
|
||||||
|
int channel;
|
||||||
|
} BLogChannelContext;
|
||||||
|
|
||||||
|
static int BLogGlobal_GetChannelByName (const char *channel_name);
|
||||||
|
|
||||||
|
static void BLog_Init (_BLog_log_func log_func, _BLog_free_func free_func);
|
||||||
|
static void BLog_Free (void);
|
||||||
|
static void BLog_SetChannelLoglevel (int channel, int loglevel);
|
||||||
|
static int BLog_WouldLog (int channel, int level);
|
||||||
|
static void BLog_Begin (void);
|
||||||
|
static void BLog_AppendVarArg (const char *fmt, va_list vl);
|
||||||
|
static void BLog_Append (const char *fmt, ...);
|
||||||
|
static void BLog_AppendBytes (MemRef data);
|
||||||
|
static void BLog_Finish (int channel, int level);
|
||||||
|
static void BLog_LogToChannelVarArg (int channel, int level, const char *fmt, va_list vl);
|
||||||
|
static void BLog_LogToChannel (int channel, int level, const char *fmt, ...);
|
||||||
|
static void BLog_LogViaFuncVarArg (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, va_list vl);
|
||||||
|
static void BLog_LogViaFunc (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, ...);
|
||||||
|
static BLogContext BLog_RootContext (void);
|
||||||
|
static BLogContext BLog_MakeContext (BLog_logfunc logfunc, void *logfunc_user);
|
||||||
|
static void BLog_ContextLogVarArg (BLogContext context, int channel, int level, const char *fmt, va_list vl);
|
||||||
|
static void BLog_ContextLog (BLogContext context, int channel, int level, const char *fmt, ...);
|
||||||
|
static BLogChannelContext BLog_MakeChannelContext (BLogContext context, int channel);
|
||||||
|
static void BLog_ChannelContextLogVarArg (BLogChannelContext ccontext, int level, const char *fmt, va_list vl);
|
||||||
|
static void BLog_ChannelContextLog (BLogChannelContext ccontext, int level, const char *fmt, ...);
|
||||||
|
|
||||||
|
void BLog_InitStdout (void);
|
||||||
|
void BLog_InitStderr (void);
|
||||||
|
|
||||||
|
int BLogGlobal_GetChannelByName (const char *channel_name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < BLOG_NUM_CHANNELS; i++) {
|
||||||
|
if (!strcmp(blog_channel_list[i].name, channel_name)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_Init (_BLog_log_func log_func, _BLog_free_func free_func)
|
||||||
|
{
|
||||||
|
ASSERT(!blog_global.initialized)
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
blog_global.initialized = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// initialize channels
|
||||||
|
memcpy(blog_global.channels, blog_channel_list, BLOG_NUM_CHANNELS * sizeof(struct _BLog_channel));
|
||||||
|
|
||||||
|
blog_global.log_func = log_func;
|
||||||
|
blog_global.free_func = free_func;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
blog_global.logging = 0;
|
||||||
|
#endif
|
||||||
|
blog_global.logbuf_pos = 0;
|
||||||
|
blog_global.logbuf[0] = '\0';
|
||||||
|
|
||||||
|
ASSERT_FORCE(BMutex_Init(&blog_global.mutex))
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_Free (void)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ASSERT(!blog_global.logging)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BMutex_Free(&blog_global.mutex);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
blog_global.initialized = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blog_global.free_func();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_SetChannelLoglevel (int channel, int loglevel)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(loglevel >= 0 && loglevel <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
blog_global.channels[channel].loglevel = loglevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BLog_WouldLog (int channel, int level)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
return (level <= blog_global.channels[channel].loglevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_Begin (void)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
|
||||||
|
BMutex_Lock(&blog_global.mutex);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ASSERT(!blog_global.logging)
|
||||||
|
blog_global.logging = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_AppendVarArg (const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ASSERT(blog_global.logging)
|
||||||
|
#endif
|
||||||
|
ASSERT(blog_global.logbuf_pos >= 0)
|
||||||
|
ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf))
|
||||||
|
|
||||||
|
int w = vsnprintf(blog_global.logbuf + blog_global.logbuf_pos, sizeof(blog_global.logbuf) - blog_global.logbuf_pos, fmt, vl);
|
||||||
|
|
||||||
|
if (w >= sizeof(blog_global.logbuf) - blog_global.logbuf_pos) {
|
||||||
|
blog_global.logbuf_pos = sizeof(blog_global.logbuf) - 1;
|
||||||
|
} else {
|
||||||
|
blog_global.logbuf_pos += w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_Append (const char *fmt, ...)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ASSERT(blog_global.logging)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
BLog_AppendVarArg(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_AppendBytes (MemRef data)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ASSERT(blog_global.logging)
|
||||||
|
#endif
|
||||||
|
ASSERT(blog_global.logbuf_pos >= 0)
|
||||||
|
ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf))
|
||||||
|
|
||||||
|
size_t avail = (sizeof(blog_global.logbuf) - 1) - blog_global.logbuf_pos;
|
||||||
|
data.len = (data.len > avail ? avail : data.len);
|
||||||
|
|
||||||
|
memcpy(blog_global.logbuf + blog_global.logbuf_pos, data.ptr, data.len);
|
||||||
|
blog_global.logbuf_pos += data.len;
|
||||||
|
blog_global.logbuf[blog_global.logbuf_pos] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_Finish (int channel, int level)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ASSERT(blog_global.logging)
|
||||||
|
#endif
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
ASSERT(BLog_WouldLog(channel, level))
|
||||||
|
|
||||||
|
ASSERT(blog_global.logbuf_pos >= 0)
|
||||||
|
ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf))
|
||||||
|
ASSERT(blog_global.logbuf[blog_global.logbuf_pos] == '\0')
|
||||||
|
|
||||||
|
blog_global.log_func(channel, level, blog_global.logbuf);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
blog_global.logging = 0;
|
||||||
|
#endif
|
||||||
|
blog_global.logbuf_pos = 0;
|
||||||
|
blog_global.logbuf[0] = '\0';
|
||||||
|
|
||||||
|
BMutex_Unlock(&blog_global.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_LogToChannelVarArg (int channel, int level, const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
if (!BLog_WouldLog(channel, level)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLog_Begin();
|
||||||
|
BLog_AppendVarArg(fmt, vl);
|
||||||
|
BLog_Finish(channel, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_LogToChannel (int channel, int level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
if (!BLog_WouldLog(channel, level)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
|
||||||
|
BLog_Begin();
|
||||||
|
BLog_AppendVarArg(fmt, vl);
|
||||||
|
BLog_Finish(channel, level);
|
||||||
|
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_LogViaFuncVarArg (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
if (!BLog_WouldLog(channel, level)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLog_Begin();
|
||||||
|
func(arg);
|
||||||
|
BLog_AppendVarArg(fmt, vl);
|
||||||
|
BLog_Finish(channel, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_LogViaFunc (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
ASSERT(blog_global.initialized)
|
||||||
|
ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS)
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
if (!BLog_WouldLog(channel, level)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
|
||||||
|
BLog_Begin();
|
||||||
|
func(arg);
|
||||||
|
BLog_AppendVarArg(fmt, vl);
|
||||||
|
BLog_Finish(channel, level);
|
||||||
|
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BLog__root_logfunc (void *unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLogContext BLog_RootContext (void)
|
||||||
|
{
|
||||||
|
return BLog_MakeContext(BLog__root_logfunc, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLogContext BLog_MakeContext (BLog_logfunc logfunc, void *logfunc_user)
|
||||||
|
{
|
||||||
|
ASSERT(logfunc)
|
||||||
|
|
||||||
|
BLogContext context;
|
||||||
|
context.logfunc = logfunc;
|
||||||
|
context.logfunc_user = logfunc_user;
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BLog_ContextLogVarArg (BLogContext context, int channel, int level, const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
BLog_LogViaFuncVarArg(context.logfunc, context.logfunc_user, channel, level, fmt, vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BLog_ContextLog (BLogContext context, int channel, int level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
BLog_ContextLogVarArg(context, channel, level, fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLogChannelContext BLog_MakeChannelContext (BLogContext context, int channel)
|
||||||
|
{
|
||||||
|
BLogChannelContext ccontext;
|
||||||
|
ccontext.context = context;
|
||||||
|
ccontext.channel = channel;
|
||||||
|
return ccontext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BLog_ChannelContextLogVarArg (BLogChannelContext ccontext, int level, const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
BLog_ContextLogVarArg(ccontext.context, ccontext.channel, level, fmt, vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BLog_ChannelContextLog (BLogChannelContext ccontext, int level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
BLog_ChannelContextLogVarArg(ccontext, level, fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* @file BLog.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include "BLog.h"
|
||||||
|
|
||||||
|
#ifndef BADVPN_PLUGIN
|
||||||
|
|
||||||
|
struct _BLog_channel blog_channel_list[] = {
|
||||||
|
#include "generated/blog_channels_list.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _BLog_global blog_global = {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
0
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// keep in sync with level numbers in BLog.h!
|
||||||
|
static char *level_names[] = { NULL, "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG" };
|
||||||
|
|
||||||
|
static void stdout_log (int channel, int level, const char *msg)
|
||||||
|
{
|
||||||
|
NSLog(@"%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stderr_log (int channel, int level, const char *msg)
|
||||||
|
{
|
||||||
|
NSLog(@"%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stdout_stderr_free (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_InitStdout (void)
|
||||||
|
{
|
||||||
|
BLog_Init(stdout_log, stdout_stderr_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLog_InitStderr (void)
|
||||||
|
{
|
||||||
|
BLog_Init(stderr_log, stdout_stderr_free);
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
/**
|
||||||
|
* @file BLog_syslog.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
|
||||||
|
#include "BLog_syslog.h"
|
||||||
|
|
||||||
|
static int resolve_facility (char *str, int *out)
|
||||||
|
{
|
||||||
|
if (!strcmp(str, "authpriv")) {
|
||||||
|
*out = LOG_AUTHPRIV;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "cron")) {
|
||||||
|
*out = LOG_CRON;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "daemon")) {
|
||||||
|
*out = LOG_DAEMON;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "ftp")) {
|
||||||
|
*out = LOG_FTP;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local0")) {
|
||||||
|
*out = LOG_LOCAL0;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local1")) {
|
||||||
|
*out = LOG_LOCAL1;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local2")) {
|
||||||
|
*out = LOG_LOCAL2;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local3")) {
|
||||||
|
*out = LOG_LOCAL3;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local4")) {
|
||||||
|
*out = LOG_LOCAL4;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local5")) {
|
||||||
|
*out = LOG_LOCAL5;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local6")) {
|
||||||
|
*out = LOG_LOCAL6;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "local7")) {
|
||||||
|
*out = LOG_LOCAL7;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "lpr")) {
|
||||||
|
*out = LOG_LPR;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "mail")) {
|
||||||
|
*out = LOG_MAIL;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "news")) {
|
||||||
|
*out = LOG_NEWS;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "syslog")) {
|
||||||
|
*out = LOG_SYSLOG;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "user")) {
|
||||||
|
*out = LOG_USER;
|
||||||
|
}
|
||||||
|
else if (!strcmp(str, "uucp")) {
|
||||||
|
*out = LOG_UUCP;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int convert_level (int level)
|
||||||
|
{
|
||||||
|
ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG)
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case BLOG_ERROR:
|
||||||
|
return LOG_ERR;
|
||||||
|
case BLOG_WARNING:
|
||||||
|
return LOG_WARNING;
|
||||||
|
case BLOG_NOTICE:
|
||||||
|
return LOG_NOTICE;
|
||||||
|
case BLOG_INFO:
|
||||||
|
return LOG_INFO;
|
||||||
|
case BLOG_DEBUG:
|
||||||
|
return LOG_DEBUG;
|
||||||
|
default:
|
||||||
|
ASSERT(0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char ident[200];
|
||||||
|
} syslog_global;
|
||||||
|
|
||||||
|
static void syslog_log (int channel, int level, const char *msg)
|
||||||
|
{
|
||||||
|
syslog(convert_level(level), "%s: %s", blog_global.channels[channel].name, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void syslog_free (void)
|
||||||
|
{
|
||||||
|
closelog();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BLog_InitSyslog (char *ident, char *facility_str)
|
||||||
|
{
|
||||||
|
int facility;
|
||||||
|
if (!resolve_facility(facility_str, &facility)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(syslog_global.ident, sizeof(syslog_global.ident), "%s", ident);
|
||||||
|
|
||||||
|
openlog(syslog_global.ident, 0, facility);
|
||||||
|
|
||||||
|
BLog_Init(syslog_log, syslog_free);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* @file BLog_syslog.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* BLog syslog backend.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_BLOG_SYSLOG_H
|
||||||
|
#define BADVPN_BLOG_SYSLOG_H
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/BLog.h"
|
||||||
|
|
||||||
|
int BLog_InitSyslog (char *ident, char *facility) WARN_UNUSED;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* @file BMutex.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_BMUTEX_H
|
||||||
|
#define BADVPN_BMUTEX_H
|
||||||
|
|
||||||
|
#if !defined(BADVPN_THREAD_SAFE) || (BADVPN_THREAD_SAFE != 0 && BADVPN_THREAD_SAFE != 1)
|
||||||
|
#error BADVPN_THREAD_SAFE is not defined or incorrect
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
pthread_mutex_t pthread_mutex;
|
||||||
|
#endif
|
||||||
|
DebugObject d_obj;
|
||||||
|
} BMutex;
|
||||||
|
|
||||||
|
static int BMutex_Init (BMutex *o) WARN_UNUSED;
|
||||||
|
static void BMutex_Free (BMutex *o);
|
||||||
|
static void BMutex_Lock (BMutex *o);
|
||||||
|
static void BMutex_Unlock (BMutex *o);
|
||||||
|
|
||||||
|
static int BMutex_Init (BMutex *o)
|
||||||
|
{
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
if (pthread_mutex_init(&o->pthread_mutex, NULL) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMutex_Free (BMutex *o)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
int res = pthread_mutex_destroy(&o->pthread_mutex);
|
||||||
|
B_USE(res)
|
||||||
|
ASSERT(res == 0)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMutex_Lock (BMutex *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
int res = pthread_mutex_lock(&o->pthread_mutex);
|
||||||
|
B_USE(res)
|
||||||
|
ASSERT(res == 0)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMutex_Unlock (BMutex *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
int res = pthread_mutex_unlock(&o->pthread_mutex);
|
||||||
|
B_USE(res)
|
||||||
|
ASSERT(res == 0)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
/**
|
||||||
|
* @file BPending.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/offset.h"
|
||||||
|
|
||||||
|
#include "BPending.h"
|
||||||
|
|
||||||
|
#include "BPending_list.h"
|
||||||
|
#include "structure/SLinkedList_impl.h"
|
||||||
|
|
||||||
|
void BPendingGroup_Init (BPendingGroup *g)
|
||||||
|
{
|
||||||
|
// init jobs list
|
||||||
|
BPending__List_Init(&g->jobs);
|
||||||
|
|
||||||
|
// init pending counter
|
||||||
|
DebugCounter_Init(&g->pending_ctr);
|
||||||
|
|
||||||
|
// init debug object
|
||||||
|
DebugObject_Init(&g->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPendingGroup_Free (BPendingGroup *g)
|
||||||
|
{
|
||||||
|
DebugCounter_Free(&g->pending_ctr);
|
||||||
|
ASSERT(BPending__List_IsEmpty(&g->jobs))
|
||||||
|
DebugObject_Free(&g->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BPendingGroup_HasJobs (BPendingGroup *g)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&g->d_obj);
|
||||||
|
|
||||||
|
return !BPending__List_IsEmpty(&g->jobs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPendingGroup_ExecuteJob (BPendingGroup *g)
|
||||||
|
{
|
||||||
|
ASSERT(!BPending__List_IsEmpty(&g->jobs))
|
||||||
|
DebugObject_Access(&g->d_obj);
|
||||||
|
|
||||||
|
// get a job
|
||||||
|
BSmallPending *p = BPending__List_First(&g->jobs);
|
||||||
|
ASSERT(!BPending__ListIsRemoved(p))
|
||||||
|
ASSERT(p->pending)
|
||||||
|
|
||||||
|
// remove from jobs list
|
||||||
|
BPending__List_RemoveFirst(&g->jobs);
|
||||||
|
|
||||||
|
// set not pending
|
||||||
|
BPending__ListMarkRemoved(p);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
p->pending = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// execute job
|
||||||
|
p->handler(p->user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&g->d_obj);
|
||||||
|
|
||||||
|
return BPending__List_First(&g->jobs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user)
|
||||||
|
{
|
||||||
|
// init arguments
|
||||||
|
o->handler = handler;
|
||||||
|
o->user = user;
|
||||||
|
|
||||||
|
// set not pending
|
||||||
|
BPending__ListMarkRemoved(o);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
o->pending = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// increment pending counter
|
||||||
|
DebugCounter_Increment(&g->pending_ctr);
|
||||||
|
|
||||||
|
// init debug object
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSmallPending_Free (BSmallPending *o, BPendingGroup *g)
|
||||||
|
{
|
||||||
|
DebugCounter_Decrement(&g->pending_ctr);
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
ASSERT(o->pending == !BPending__ListIsRemoved(o))
|
||||||
|
|
||||||
|
// remove from jobs list
|
||||||
|
if (!BPending__ListIsRemoved(o)) {
|
||||||
|
BPending__List_Remove(&g->jobs, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSmallPending_SetHandler (BSmallPending *o, BSmallPending_handler handler, void *user)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// set handler
|
||||||
|
o->handler = handler;
|
||||||
|
o->user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSmallPending_Set (BSmallPending *o, BPendingGroup *g)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
ASSERT(o->pending == !BPending__ListIsRemoved(o))
|
||||||
|
|
||||||
|
// remove from jobs list
|
||||||
|
if (!BPending__ListIsRemoved(o)) {
|
||||||
|
BPending__List_Remove(&g->jobs, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert to jobs list
|
||||||
|
BPending__List_Prepend(&g->jobs, o);
|
||||||
|
|
||||||
|
// set pending
|
||||||
|
#ifndef NDEBUG
|
||||||
|
o->pending = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
ASSERT(o->pending == !BPending__ListIsRemoved(o))
|
||||||
|
|
||||||
|
if (!BPending__ListIsRemoved(o)) {
|
||||||
|
// remove from jobs list
|
||||||
|
BPending__List_Remove(&g->jobs, o);
|
||||||
|
|
||||||
|
// set not pending
|
||||||
|
BPending__ListMarkRemoved(o);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
o->pending = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int BSmallPending_IsSet (BSmallPending *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
ASSERT(o->pending == !BPending__ListIsRemoved(o))
|
||||||
|
|
||||||
|
return !BPending__ListIsRemoved(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user)
|
||||||
|
{
|
||||||
|
BSmallPending_Init(&o->base, g, handler, user);
|
||||||
|
o->g = g;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPending_Free (BPending *o)
|
||||||
|
{
|
||||||
|
BSmallPending_Free(&o->base, o->g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPending_Set (BPending *o)
|
||||||
|
{
|
||||||
|
BSmallPending_Set(&o->base, o->g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPending_Unset (BPending *o)
|
||||||
|
{
|
||||||
|
BSmallPending_Unset(&o->base, o->g);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BPending_IsSet (BPending *o)
|
||||||
|
{
|
||||||
|
return BSmallPending_IsSet(&o->base);
|
||||||
|
}
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
/**
|
||||||
|
* @file BPending.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Module for managing a queue of jobs pending execution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_BPENDING_H
|
||||||
|
#define BADVPN_BPENDING_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "misc/debugcounter.h"
|
||||||
|
#include "structure/SLinkedList.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
|
||||||
|
struct BSmallPending_s;
|
||||||
|
|
||||||
|
#include "BPending_list.h"
|
||||||
|
#include "structure/SLinkedList_decl.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Job execution handler.
|
||||||
|
* It is guaranteed that the associated {@link BSmallPending} object was
|
||||||
|
* in set state.
|
||||||
|
* The {@link BSmallPending} object enters not set state before the handler
|
||||||
|
* is called.
|
||||||
|
*
|
||||||
|
* @param user as in {@link BSmallPending_Init}
|
||||||
|
*/
|
||||||
|
typedef void (*BSmallPending_handler) (void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Job execution handler.
|
||||||
|
* It is guaranteed that the associated {@link BPending} object was
|
||||||
|
* in set state.
|
||||||
|
* The {@link BPending} object enters not set state before the handler
|
||||||
|
* is called.
|
||||||
|
*
|
||||||
|
* @param user as in {@link BPending_Init}
|
||||||
|
*/
|
||||||
|
typedef void (*BPending_handler) (void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object that contains a list of jobs pending execution.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
BPending__List jobs;
|
||||||
|
DebugCounter pending_ctr;
|
||||||
|
DebugObject d_obj;
|
||||||
|
} BPendingGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object for queuing a job for execution.
|
||||||
|
*/
|
||||||
|
typedef struct BSmallPending_s {
|
||||||
|
BPending_handler handler;
|
||||||
|
void *user;
|
||||||
|
BPending__ListNode pending_node; // optimization: if not pending, .next is this
|
||||||
|
#ifndef NDEBUG
|
||||||
|
uint8_t pending;
|
||||||
|
#endif
|
||||||
|
DebugObject d_obj;
|
||||||
|
} BSmallPending;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object for queuing a job for execution. This is a convenience wrapper
|
||||||
|
* around {@link BSmallPending} with an extra field to remember the
|
||||||
|
* {@link BPendingGroup} being used.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
BSmallPending base;
|
||||||
|
BPendingGroup *g;
|
||||||
|
} BPending;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*
|
||||||
|
* @param g the object
|
||||||
|
*/
|
||||||
|
void BPendingGroup_Init (BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
* There must be no {@link BPending} or {@link BSmallPending} objects using
|
||||||
|
* this group.
|
||||||
|
*
|
||||||
|
* @param g the object
|
||||||
|
*/
|
||||||
|
void BPendingGroup_Free (BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there is at least one job in the queue.
|
||||||
|
*
|
||||||
|
* @param g the object
|
||||||
|
* @return 1 if there is at least one job, 0 if not
|
||||||
|
*/
|
||||||
|
int BPendingGroup_HasJobs (BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the top job on the job list.
|
||||||
|
* The job is removed from the list and enters
|
||||||
|
* not set state before being executed.
|
||||||
|
* There must be at least one job in job list.
|
||||||
|
*
|
||||||
|
* @param g the object
|
||||||
|
*/
|
||||||
|
void BPendingGroup_ExecuteJob (BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the top job on the job list, or NULL if there are none.
|
||||||
|
*
|
||||||
|
* @param g the object
|
||||||
|
* @return the top job if there is at least one job, NULL if not
|
||||||
|
*/
|
||||||
|
BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
* The object is initialized in not set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param g pending group to use
|
||||||
|
* @param handler job execution handler
|
||||||
|
* @param user value to pass to handler
|
||||||
|
*/
|
||||||
|
void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
* The execution handler will not be called after the object
|
||||||
|
* is freed.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param g pending group. Must be the same as was used in {@link BSmallPending_Init}.
|
||||||
|
*/
|
||||||
|
void BSmallPending_Free (BSmallPending *o, BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the job execution handler.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param handler job execution handler
|
||||||
|
* @param user value to pass to handler
|
||||||
|
*/
|
||||||
|
void BSmallPending_SetHandler (BSmallPending *o, BSmallPending_handler handler, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the job, pushing it to the top of the job list.
|
||||||
|
* If the object was already in set state, the job is removed from its
|
||||||
|
* current position in the list before being pushed.
|
||||||
|
* The object enters set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param g pending group. Must be the same as was used in {@link BSmallPending_Init}.
|
||||||
|
*/
|
||||||
|
void BSmallPending_Set (BSmallPending *o, BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the job, removing it from the job list.
|
||||||
|
* If the object was not in set state, nothing is done.
|
||||||
|
* The object enters not set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param g pending group. Must be the same as was used in {@link BSmallPending_Init}.
|
||||||
|
*/
|
||||||
|
void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the job is in set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @return 1 if in set state, 0 if not
|
||||||
|
*/
|
||||||
|
int BSmallPending_IsSet (BSmallPending *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
* The object is initialized in not set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param g pending group to use
|
||||||
|
* @param handler job execution handler
|
||||||
|
* @param user value to pass to handler
|
||||||
|
*/
|
||||||
|
void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
* The execution handler will not be called after the object
|
||||||
|
* is freed.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void BPending_Free (BPending *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the job, pushing it to the top of the job list.
|
||||||
|
* If the object was already in set state, the job is removed from its
|
||||||
|
* current position in the list before being pushed.
|
||||||
|
* The object enters set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void BPending_Set (BPending *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the job, removing it from the job list.
|
||||||
|
* If the object was not in set state, nothing is done.
|
||||||
|
* The object enters not set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void BPending_Unset (BPending *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the job is in set state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @return 1 if in set state, 0 if not
|
||||||
|
*/
|
||||||
|
int BPending_IsSet (BPending *o);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#define SLINKEDLIST_PARAM_NAME BPending__List
|
||||||
|
#define SLINKEDLIST_PARAM_FEATURE_LAST 0
|
||||||
|
#define SLINKEDLIST_PARAM_TYPE_ENTRY struct BSmallPending_s
|
||||||
|
#define SLINKEDLIST_PARAM_MEMBER_NODE pending_node
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* @file DebugObject.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DebugObject.h"
|
||||||
|
|
||||||
|
#ifndef BADVPN_PLUGIN
|
||||||
|
#ifndef NDEBUG
|
||||||
|
DebugCounter debugobject_counter = DEBUGCOUNTER_STATIC;
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
pthread_mutex_t debugobject_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* @file DebugObject.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Object used for detecting leaks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_DEBUGOBJECT_H
|
||||||
|
#define BADVPN_DEBUGOBJECT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if !defined(BADVPN_THREAD_SAFE) || (BADVPN_THREAD_SAFE != 0 && BADVPN_THREAD_SAFE != 1)
|
||||||
|
#error BADVPN_THREAD_SAFE is not defined or incorrect
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/debugcounter.h"
|
||||||
|
|
||||||
|
#define DEBUGOBJECT_VALID UINT32_C(0x31415926)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object used for detecting leaks.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
uint32_t c;
|
||||||
|
#endif
|
||||||
|
} DebugObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*
|
||||||
|
* @param obj the object
|
||||||
|
*/
|
||||||
|
static void DebugObject_Init (DebugObject *obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param obj the object
|
||||||
|
*/
|
||||||
|
static void DebugObject_Free (DebugObject *obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does nothing.
|
||||||
|
*
|
||||||
|
* @param obj the object
|
||||||
|
*/
|
||||||
|
static void DebugObject_Access (const DebugObject *obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does nothing.
|
||||||
|
* There must be no {@link DebugObject}'s initialized.
|
||||||
|
*/
|
||||||
|
static void DebugObjectGlobal_Finish (void);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
extern DebugCounter debugobject_counter;
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
extern pthread_mutex_t debugobject_mutex;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void DebugObject_Init (DebugObject *obj)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
|
||||||
|
obj->c = DEBUGOBJECT_VALID;
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
ASSERT_FORCE(pthread_mutex_lock(&debugobject_mutex) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DebugCounter_Increment(&debugobject_counter);
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
ASSERT_FORCE(pthread_mutex_unlock(&debugobject_mutex) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugObject_Free (DebugObject *obj)
|
||||||
|
{
|
||||||
|
ASSERT(obj->c == DEBUGOBJECT_VALID)
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
|
||||||
|
obj->c = 0;
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
ASSERT_FORCE(pthread_mutex_lock(&debugobject_mutex) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DebugCounter_Decrement(&debugobject_counter);
|
||||||
|
|
||||||
|
#if BADVPN_THREAD_SAFE
|
||||||
|
ASSERT_FORCE(pthread_mutex_unlock(&debugobject_mutex) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugObject_Access (const DebugObject *obj)
|
||||||
|
{
|
||||||
|
ASSERT(obj->c == DEBUGOBJECT_VALID)
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugObjectGlobal_Finish (void)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
DebugCounter_Free(&debugobject_counter);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* @file BufferWriter.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
|
||||||
|
#include "flow/BufferWriter.h"
|
||||||
|
|
||||||
|
static void output_handler_recv (BufferWriter *o, uint8_t *data)
|
||||||
|
{
|
||||||
|
ASSERT(!o->out_have)
|
||||||
|
|
||||||
|
// set output packet
|
||||||
|
o->out_have = 1;
|
||||||
|
o->out = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferWriter_Init (BufferWriter *o, int mtu, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(mtu >= 0)
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketRecvInterface_Init(&o->recv_interface, mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg);
|
||||||
|
|
||||||
|
// set no output packet
|
||||||
|
o->out_have = 0;
|
||||||
|
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
o->d_mtu = mtu;
|
||||||
|
o->d_writing = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferWriter_Free (BufferWriter *o)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
|
||||||
|
// free output
|
||||||
|
PacketRecvInterface_Free(&o->recv_interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
return &o->recv_interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf)
|
||||||
|
{
|
||||||
|
ASSERT(!o->d_writing)
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
if (!o->out_have) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
*buf = o->out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
o->d_writing = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferWriter_EndPacket (BufferWriter *o, int len)
|
||||||
|
{
|
||||||
|
ASSERT(len >= 0)
|
||||||
|
ASSERT(len <= o->d_mtu)
|
||||||
|
ASSERT(o->out_have)
|
||||||
|
ASSERT(o->d_writing)
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// set no output packet
|
||||||
|
o->out_have = 0;
|
||||||
|
|
||||||
|
// finish packet
|
||||||
|
PacketRecvInterface_Done(&o->recv_interface, len);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
o->d_writing = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* @file BufferWriter.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Object for writing packets to a {@link PacketRecvInterface} client
|
||||||
|
* in a best-effort fashion.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_BUFFERWRITER_H
|
||||||
|
#define BADVPN_FLOW_BUFFERWRITER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/PacketRecvInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object for writing packets to a {@link PacketRecvInterface} client
|
||||||
|
* in a best-effort fashion.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
PacketRecvInterface recv_interface;
|
||||||
|
int out_have;
|
||||||
|
uint8_t *out;
|
||||||
|
DebugObject d_obj;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
int d_mtu;
|
||||||
|
int d_writing;
|
||||||
|
#endif
|
||||||
|
} BufferWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
* The object is initialized in not writing state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param mtu maximum input packet length
|
||||||
|
* @param pg pending group
|
||||||
|
*/
|
||||||
|
void BufferWriter_Init (BufferWriter *o, int mtu, BPendingGroup *pg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void BufferWriter_Free (BufferWriter *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the output interface.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @return output interface
|
||||||
|
*/
|
||||||
|
PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to provide a memory location for writing a packet.
|
||||||
|
* The object must be in not writing state.
|
||||||
|
* On success, the object enters writing state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param buf if not NULL, on success, the memory location will be stored here.
|
||||||
|
* It will have space for MTU bytes.
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf) WARN_UNUSED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits a packet written to the buffer.
|
||||||
|
* The object must be in writing state.
|
||||||
|
* Yhe object enters not writing state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param len length of the packet that was written. Must be >=0 and
|
||||||
|
* <=MTU.
|
||||||
|
*/
|
||||||
|
void BufferWriter_EndPacket (BufferWriter *o, int len);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketBuffer.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/balloc.h"
|
||||||
|
|
||||||
|
#include "flow/PacketBuffer.h"
|
||||||
|
|
||||||
|
static void input_handler_done (PacketBuffer *buf, int in_len);
|
||||||
|
static void output_handler_done (PacketBuffer *buf);
|
||||||
|
|
||||||
|
void input_handler_done (PacketBuffer *buf, int in_len)
|
||||||
|
{
|
||||||
|
ASSERT(in_len >= 0)
|
||||||
|
ASSERT(in_len <= buf->input_mtu)
|
||||||
|
DebugObject_Access(&buf->d_obj);
|
||||||
|
|
||||||
|
// remember if buffer is empty
|
||||||
|
int was_empty = (buf->buf.output_avail < 0);
|
||||||
|
|
||||||
|
// submit packet to buffer
|
||||||
|
ChunkBuffer2_SubmitPacket(&buf->buf, in_len);
|
||||||
|
|
||||||
|
// if there is space, schedule receive
|
||||||
|
if (buf->buf.input_avail >= buf->input_mtu) {
|
||||||
|
PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if buffer was empty, schedule send
|
||||||
|
if (was_empty) {
|
||||||
|
PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void output_handler_done (PacketBuffer *buf)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&buf->d_obj);
|
||||||
|
|
||||||
|
// remember if buffer is full
|
||||||
|
int was_full = (buf->buf.input_avail < buf->input_mtu);
|
||||||
|
|
||||||
|
// remove packet from buffer
|
||||||
|
ChunkBuffer2_ConsumePacket(&buf->buf);
|
||||||
|
|
||||||
|
// if buffer was full and there is space, schedule receive
|
||||||
|
if (was_full && buf->buf.input_avail >= buf->input_mtu) {
|
||||||
|
PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is more data, schedule send
|
||||||
|
if (buf->buf.output_avail >= 0) {
|
||||||
|
PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketBuffer_Init (PacketBuffer *buf, PacketRecvInterface *input, PacketPassInterface *output, int num_packets, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(PacketPassInterface_GetMTU(output) >= PacketRecvInterface_GetMTU(input))
|
||||||
|
ASSERT(num_packets > 0)
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
buf->input = input;
|
||||||
|
buf->output = output;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketRecvInterface_Receiver_Init(buf->input, (PacketRecvInterface_handler_done)input_handler_done, buf);
|
||||||
|
|
||||||
|
// set input MTU
|
||||||
|
buf->input_mtu = PacketRecvInterface_GetMTU(buf->input);
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketPassInterface_Sender_Init(buf->output, (PacketPassInterface_handler_done)output_handler_done, buf);
|
||||||
|
|
||||||
|
// allocate buffer
|
||||||
|
int num_blocks = ChunkBuffer2_calc_blocks(buf->input_mtu, num_packets);
|
||||||
|
if (num_blocks < 0) {
|
||||||
|
goto fail0;
|
||||||
|
}
|
||||||
|
if (!(buf->buf_data = (struct ChunkBuffer2_block *)BAllocArray(num_blocks, sizeof(buf->buf_data[0])))) {
|
||||||
|
goto fail0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init buffer
|
||||||
|
ChunkBuffer2_Init(&buf->buf, buf->buf_data, num_blocks, buf->input_mtu);
|
||||||
|
|
||||||
|
// schedule receive
|
||||||
|
PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest);
|
||||||
|
|
||||||
|
DebugObject_Init(&buf->d_obj);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail0:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketBuffer_Free (PacketBuffer *buf)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&buf->d_obj);
|
||||||
|
|
||||||
|
// free buffer
|
||||||
|
BFree(buf->buf_data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketBuffer.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETBUFFER_H
|
||||||
|
#define BADVPN_FLOW_PACKETBUFFER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "structure/ChunkBuffer2.h"
|
||||||
|
#include "flow/PacketRecvInterface.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
DebugObject d_obj;
|
||||||
|
PacketRecvInterface *input;
|
||||||
|
int input_mtu;
|
||||||
|
PacketPassInterface *output;
|
||||||
|
struct ChunkBuffer2_block *buf_data;
|
||||||
|
ChunkBuffer2 buf;
|
||||||
|
} PacketBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the buffer.
|
||||||
|
* Output MTU must be >= input MTU.
|
||||||
|
*
|
||||||
|
* @param buf the object
|
||||||
|
* @param input input interface
|
||||||
|
* @param output output interface
|
||||||
|
* @param num_packets minimum number of packets the buffer must hold. Must be >0.
|
||||||
|
* @param pg pending group
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int PacketBuffer_Init (PacketBuffer *buf, PacketRecvInterface *input, PacketPassInterface *output, int num_packets, BPendingGroup *pg) WARN_UNUSED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the buffer.
|
||||||
|
*
|
||||||
|
* @param buf the object
|
||||||
|
*/
|
||||||
|
void PacketBuffer_Free (PacketBuffer *buf);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassConnector.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
|
||||||
|
#include "flow/PacketPassConnector.h"
|
||||||
|
|
||||||
|
static void input_handler_send (PacketPassConnector *o, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(data_len >= 0)
|
||||||
|
ASSERT(data_len <= o->input_mtu)
|
||||||
|
ASSERT(o->in_len == -1)
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// remember input packet
|
||||||
|
o->in_len = data_len;
|
||||||
|
o->in = data;
|
||||||
|
|
||||||
|
if (o->output) {
|
||||||
|
// schedule send
|
||||||
|
PacketPassInterface_Sender_Send(o->output, o->in, o->in_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_handler_done (PacketPassConnector *o)
|
||||||
|
{
|
||||||
|
ASSERT(o->in_len >= 0)
|
||||||
|
ASSERT(o->output)
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// have no input packet
|
||||||
|
o->in_len = -1;
|
||||||
|
|
||||||
|
// allow input to send more packets
|
||||||
|
PacketPassInterface_Done(&o->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassConnector_Init (PacketPassConnector *o, int mtu, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(mtu >= 0)
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
o->input_mtu = mtu;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketPassInterface_Init(&o->input, o->input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg);
|
||||||
|
|
||||||
|
// have no input packet
|
||||||
|
o->in_len = -1;
|
||||||
|
|
||||||
|
// have no output
|
||||||
|
o->output = NULL;
|
||||||
|
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassConnector_Free (PacketPassConnector *o)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
|
||||||
|
// free input
|
||||||
|
PacketPassInterface_Free(&o->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPassInterface * PacketPassConnector_GetInput (PacketPassConnector *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
return &o->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassConnector_ConnectOutput (PacketPassConnector *o, PacketPassInterface *output)
|
||||||
|
{
|
||||||
|
ASSERT(!o->output)
|
||||||
|
ASSERT(PacketPassInterface_GetMTU(output) >= o->input_mtu)
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// set output
|
||||||
|
o->output = output;
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o);
|
||||||
|
|
||||||
|
// if we have an input packet, schedule send
|
||||||
|
if (o->in_len >= 0) {
|
||||||
|
PacketPassInterface_Sender_Send(o->output, o->in, o->in_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassConnector_DisconnectOutput (PacketPassConnector *o)
|
||||||
|
{
|
||||||
|
ASSERT(o->output)
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// set no output
|
||||||
|
o->output = NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassConnector.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* A {@link PacketPassInterface} layer which allows the output to be
|
||||||
|
* connected and disconnected on the fly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETPASSCONNECTOR_H
|
||||||
|
#define BADVPN_FLOW_PACKETPASSCONNECTOR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link PacketPassInterface} layer which allows the output to be
|
||||||
|
* connected and disconnected on the fly.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
PacketPassInterface input;
|
||||||
|
int input_mtu;
|
||||||
|
int in_len;
|
||||||
|
uint8_t *in;
|
||||||
|
PacketPassInterface *output;
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketPassConnector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
* The object is initialized in not connected state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param mtu maximum input packet size. Must be >=0.
|
||||||
|
* @param pg pending group
|
||||||
|
*/
|
||||||
|
void PacketPassConnector_Init (PacketPassConnector *o, int mtu, BPendingGroup *pg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void PacketPassConnector_Free (PacketPassConnector *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input interface.
|
||||||
|
* The MTU of the interface will be as in {@link PacketPassConnector_Init}.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @return input interface
|
||||||
|
*/
|
||||||
|
PacketPassInterface * PacketPassConnector_GetInput (PacketPassConnector *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects output.
|
||||||
|
* The object must be in not connected state.
|
||||||
|
* The object enters connected state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param output output to connect. Its MTU must be >= MTU specified in
|
||||||
|
* {@link PacketPassConnector_Init}.
|
||||||
|
*/
|
||||||
|
void PacketPassConnector_ConnectOutput (PacketPassConnector *o, PacketPassInterface *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects output.
|
||||||
|
* The object must be in connected state.
|
||||||
|
* The object enters not connected state.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void PacketPassConnector_DisconnectOutput (PacketPassConnector *o);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,405 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassFairQueue.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/offset.h"
|
||||||
|
#include "misc/minmax.h"
|
||||||
|
#include "misc/compare.h"
|
||||||
|
|
||||||
|
#include "flow/PacketPassFairQueue.h"
|
||||||
|
|
||||||
|
static int compare_flows (PacketPassFairQueueFlow *f1, PacketPassFairQueueFlow *f2)
|
||||||
|
{
|
||||||
|
int cmp = B_COMPARE(f1->time, f2->time);
|
||||||
|
if (cmp) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_COMPARE((uintptr_t)f1, (uintptr_t)f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "PacketPassFairQueue_tree.h"
|
||||||
|
#include "structure/SAvl_impl.h"
|
||||||
|
|
||||||
|
static uint64_t get_current_time (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
if (m->sending_flow) {
|
||||||
|
return m->sending_flow->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t time = 0; // to remove warning
|
||||||
|
int have = 0;
|
||||||
|
|
||||||
|
PacketPassFairQueueFlow *first_flow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0);
|
||||||
|
if (first_flow) {
|
||||||
|
ASSERT(first_flow->is_queued)
|
||||||
|
|
||||||
|
time = first_flow->time;
|
||||||
|
have = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->previous_flow) {
|
||||||
|
if (!have || m->previous_flow->time < time) {
|
||||||
|
time = m->previous_flow->time;
|
||||||
|
have = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (have ? time : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void increment_sent_flow (PacketPassFairQueueFlow *flow, uint64_t amount)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
|
||||||
|
ASSERT(amount <= FAIRQUEUE_MAX_TIME)
|
||||||
|
ASSERT(!flow->is_queued)
|
||||||
|
ASSERT(!m->sending_flow)
|
||||||
|
|
||||||
|
// does time overflow?
|
||||||
|
if (amount > FAIRQUEUE_MAX_TIME - flow->time) {
|
||||||
|
// get time to subtract
|
||||||
|
uint64_t subtract;
|
||||||
|
PacketPassFairQueueFlow *first_flow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0);
|
||||||
|
if (!first_flow) {
|
||||||
|
subtract = flow->time;
|
||||||
|
} else {
|
||||||
|
ASSERT(first_flow->is_queued)
|
||||||
|
subtract = first_flow->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// subtract time from all flows
|
||||||
|
for (LinkedList1Node *list_node = LinkedList1_GetFirst(&m->flows_list); list_node; list_node = LinkedList1Node_Next(list_node)) {
|
||||||
|
PacketPassFairQueueFlow *someflow = UPPER_OBJECT(list_node, PacketPassFairQueueFlow, list_node);
|
||||||
|
|
||||||
|
// don't subtract more time than there is, except for the just finished flow,
|
||||||
|
// where we allow time to underflow and then overflow to the correct value after adding to it
|
||||||
|
if (subtract > someflow->time && someflow != flow) {
|
||||||
|
ASSERT(!someflow->is_queued)
|
||||||
|
someflow->time = 0;
|
||||||
|
} else {
|
||||||
|
someflow->time -= subtract;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add time to flow
|
||||||
|
flow->time += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void schedule (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
ASSERT(!m->sending_flow)
|
||||||
|
ASSERT(!m->previous_flow)
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
ASSERT(!PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree))
|
||||||
|
|
||||||
|
// get first queued flow
|
||||||
|
PacketPassFairQueueFlow *qflow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0);
|
||||||
|
ASSERT(qflow->is_queued)
|
||||||
|
|
||||||
|
// remove flow from queue
|
||||||
|
PacketPassFairQueue__Tree_Remove(&m->queued_tree, 0, qflow);
|
||||||
|
qflow->is_queued = 0;
|
||||||
|
|
||||||
|
// schedule send
|
||||||
|
PacketPassInterface_Sender_Send(m->output, qflow->queued.data, qflow->queued.data_len);
|
||||||
|
m->sending_flow = qflow;
|
||||||
|
m->sending_len = qflow->queued.data_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void schedule_job_handler (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
ASSERT(!m->sending_flow)
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
DebugObject_Access(&m->d_obj);
|
||||||
|
|
||||||
|
// remove previous flow
|
||||||
|
m->previous_flow = NULL;
|
||||||
|
|
||||||
|
if (!PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) {
|
||||||
|
schedule(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_handler_send (PacketPassFairQueueFlow *flow, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
|
||||||
|
ASSERT(flow != m->sending_flow)
|
||||||
|
ASSERT(!flow->is_queued)
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
DebugObject_Access(&flow->d_obj);
|
||||||
|
|
||||||
|
if (flow == m->previous_flow) {
|
||||||
|
// remove from previous flow
|
||||||
|
m->previous_flow = NULL;
|
||||||
|
} else {
|
||||||
|
// raise time
|
||||||
|
flow->time = bmax_uint64(flow->time, get_current_time(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
// queue flow
|
||||||
|
flow->queued.data = data;
|
||||||
|
flow->queued.data_len = data_len;
|
||||||
|
int res = PacketPassFairQueue__Tree_Insert(&m->queued_tree, 0, flow, NULL);
|
||||||
|
ASSERT_EXECUTE(res)
|
||||||
|
flow->is_queued = 1;
|
||||||
|
|
||||||
|
if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) {
|
||||||
|
schedule(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_handler_done (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
ASSERT(m->sending_flow)
|
||||||
|
ASSERT(!m->previous_flow)
|
||||||
|
ASSERT(!BPending_IsSet(&m->schedule_job))
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
ASSERT(!m->sending_flow->is_queued)
|
||||||
|
|
||||||
|
PacketPassFairQueueFlow *flow = m->sending_flow;
|
||||||
|
|
||||||
|
// sending finished
|
||||||
|
m->sending_flow = NULL;
|
||||||
|
|
||||||
|
// remember this flow so the schedule job can remove its time if it didn's send
|
||||||
|
m->previous_flow = flow;
|
||||||
|
|
||||||
|
// update flow time by packet size
|
||||||
|
increment_sent_flow(flow, (uint64_t)m->packet_weight + m->sending_len);
|
||||||
|
|
||||||
|
// schedule schedule
|
||||||
|
BPending_Set(&m->schedule_job);
|
||||||
|
|
||||||
|
// finish flow packet
|
||||||
|
PacketPassInterface_Done(&flow->input);
|
||||||
|
|
||||||
|
// call busy handler if set
|
||||||
|
if (flow->handler_busy) {
|
||||||
|
// handler is one-shot, unset it before calling
|
||||||
|
PacketPassFairQueue_handler_busy handler = flow->handler_busy;
|
||||||
|
flow->handler_busy = NULL;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
handler(flow->user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight)
|
||||||
|
{
|
||||||
|
ASSERT(packet_weight > 0)
|
||||||
|
ASSERT(use_cancel == 0 || use_cancel == 1)
|
||||||
|
ASSERT(!use_cancel || PacketPassInterface_HasCancel(output))
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
m->output = output;
|
||||||
|
m->pg = pg;
|
||||||
|
m->use_cancel = use_cancel;
|
||||||
|
m->packet_weight = packet_weight;
|
||||||
|
|
||||||
|
// make sure that (output MTU + packet_weight <= FAIRQUEUE_MAX_TIME)
|
||||||
|
if (!(
|
||||||
|
(PacketPassInterface_GetMTU(output) <= FAIRQUEUE_MAX_TIME) &&
|
||||||
|
(packet_weight <= FAIRQUEUE_MAX_TIME - PacketPassInterface_GetMTU(output))
|
||||||
|
)) {
|
||||||
|
goto fail0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketPassInterface_Sender_Init(m->output, (PacketPassInterface_handler_done)output_handler_done, m);
|
||||||
|
|
||||||
|
// not sending
|
||||||
|
m->sending_flow = NULL;
|
||||||
|
|
||||||
|
// no previous flow
|
||||||
|
m->previous_flow = NULL;
|
||||||
|
|
||||||
|
// init queued tree
|
||||||
|
PacketPassFairQueue__Tree_Init(&m->queued_tree);
|
||||||
|
|
||||||
|
// init flows list
|
||||||
|
LinkedList1_Init(&m->flows_list);
|
||||||
|
|
||||||
|
// not freeing
|
||||||
|
m->freeing = 0;
|
||||||
|
|
||||||
|
// init schedule job
|
||||||
|
BPending_Init(&m->schedule_job, m->pg, (BPending_handler)schedule_job_handler, m);
|
||||||
|
|
||||||
|
DebugObject_Init(&m->d_obj);
|
||||||
|
DebugCounter_Init(&m->d_ctr);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail0:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueue_Free (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
ASSERT(LinkedList1_IsEmpty(&m->flows_list))
|
||||||
|
ASSERT(PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree))
|
||||||
|
ASSERT(!m->previous_flow)
|
||||||
|
ASSERT(!m->sending_flow)
|
||||||
|
DebugCounter_Free(&m->d_ctr);
|
||||||
|
DebugObject_Free(&m->d_obj);
|
||||||
|
|
||||||
|
// free schedule job
|
||||||
|
BPending_Free(&m->schedule_job);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueue_PrepareFree (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&m->d_obj);
|
||||||
|
|
||||||
|
// set freeing
|
||||||
|
m->freeing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketPassFairQueue_GetMTU (PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&m->d_obj);
|
||||||
|
|
||||||
|
return PacketPassInterface_GetMTU(m->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueueFlow_Init (PacketPassFairQueueFlow *flow, PacketPassFairQueue *m)
|
||||||
|
{
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
DebugObject_Access(&m->d_obj);
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
flow->m = m;
|
||||||
|
|
||||||
|
// have no canfree handler
|
||||||
|
flow->handler_busy = NULL;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketPassInterface_Init(&flow->input, PacketPassInterface_GetMTU(flow->m->output), (PacketPassInterface_handler_send)input_handler_send, flow, m->pg);
|
||||||
|
|
||||||
|
// set time
|
||||||
|
flow->time = 0;
|
||||||
|
|
||||||
|
// add to flows list
|
||||||
|
LinkedList1_Append(&m->flows_list, &flow->list_node);
|
||||||
|
|
||||||
|
// is not queued
|
||||||
|
flow->is_queued = 0;
|
||||||
|
|
||||||
|
DebugObject_Init(&flow->d_obj);
|
||||||
|
DebugCounter_Increment(&m->d_ctr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
|
||||||
|
ASSERT(m->freeing || flow != m->sending_flow)
|
||||||
|
DebugCounter_Decrement(&m->d_ctr);
|
||||||
|
DebugObject_Free(&flow->d_obj);
|
||||||
|
|
||||||
|
// remove from current flow
|
||||||
|
if (flow == m->sending_flow) {
|
||||||
|
m->sending_flow = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from previous flow
|
||||||
|
if (flow == m->previous_flow) {
|
||||||
|
m->previous_flow = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from queue
|
||||||
|
if (flow->is_queued) {
|
||||||
|
PacketPassFairQueue__Tree_Remove(&m->queued_tree, 0, flow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from flows list
|
||||||
|
LinkedList1_Remove(&m->flows_list, &flow->list_node);
|
||||||
|
|
||||||
|
// free input
|
||||||
|
PacketPassInterface_Free(&flow->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueueFlow_AssertFree (PacketPassFairQueueFlow *flow)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
B_USE(m)
|
||||||
|
|
||||||
|
ASSERT(m->freeing || flow != m->sending_flow)
|
||||||
|
DebugObject_Access(&flow->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketPassFairQueueFlow_IsBusy (PacketPassFairQueueFlow *flow)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
DebugObject_Access(&flow->d_obj);
|
||||||
|
|
||||||
|
return (flow == m->sending_flow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueueFlow_RequestCancel (PacketPassFairQueueFlow *flow)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
|
||||||
|
ASSERT(flow == m->sending_flow)
|
||||||
|
ASSERT(m->use_cancel)
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
ASSERT(!BPending_IsSet(&m->schedule_job))
|
||||||
|
DebugObject_Access(&flow->d_obj);
|
||||||
|
|
||||||
|
// request cancel
|
||||||
|
PacketPassInterface_Sender_RequestCancel(m->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassFairQueueFlow_SetBusyHandler (PacketPassFairQueueFlow *flow, PacketPassFairQueue_handler_busy handler, void *user)
|
||||||
|
{
|
||||||
|
PacketPassFairQueue *m = flow->m;
|
||||||
|
B_USE(m)
|
||||||
|
|
||||||
|
ASSERT(flow == m->sending_flow)
|
||||||
|
ASSERT(!m->freeing)
|
||||||
|
DebugObject_Access(&flow->d_obj);
|
||||||
|
|
||||||
|
// set handler
|
||||||
|
flow->handler_busy = handler;
|
||||||
|
flow->user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPassInterface * PacketPassFairQueueFlow_GetInput (PacketPassFairQueueFlow *flow)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&flow->d_obj);
|
||||||
|
|
||||||
|
return &flow->input;
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassFairQueue.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Fair queue using {@link PacketPassInterface}.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETPASSFAIRQUEUE_H
|
||||||
|
#define BADVPN_FLOW_PACKETPASSFAIRQUEUE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/debugcounter.h"
|
||||||
|
#include "structure/SAvl.h"
|
||||||
|
#include "structure/LinkedList1.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "base/BPending.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
// reduce this to test time overflow handling
|
||||||
|
#define FAIRQUEUE_MAX_TIME UINT64_MAX
|
||||||
|
|
||||||
|
typedef void (*PacketPassFairQueue_handler_busy) (void *user);
|
||||||
|
|
||||||
|
struct PacketPassFairQueueFlow_s;
|
||||||
|
|
||||||
|
#include "PacketPassFairQueue_tree.h"
|
||||||
|
#include "structure/SAvl_decl.h"
|
||||||
|
|
||||||
|
typedef struct PacketPassFairQueueFlow_s {
|
||||||
|
struct PacketPassFairQueue_s *m;
|
||||||
|
PacketPassFairQueue_handler_busy handler_busy;
|
||||||
|
void *user;
|
||||||
|
PacketPassInterface input;
|
||||||
|
uint64_t time;
|
||||||
|
LinkedList1Node list_node;
|
||||||
|
int is_queued;
|
||||||
|
struct {
|
||||||
|
PacketPassFairQueue__TreeNode tree_node;
|
||||||
|
uint8_t *data;
|
||||||
|
int data_len;
|
||||||
|
} queued;
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketPassFairQueueFlow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fair queue using {@link PacketPassInterface}.
|
||||||
|
*/
|
||||||
|
typedef struct PacketPassFairQueue_s {
|
||||||
|
PacketPassInterface *output;
|
||||||
|
BPendingGroup *pg;
|
||||||
|
int use_cancel;
|
||||||
|
int packet_weight;
|
||||||
|
struct PacketPassFairQueueFlow_s *sending_flow;
|
||||||
|
int sending_len;
|
||||||
|
struct PacketPassFairQueueFlow_s *previous_flow;
|
||||||
|
PacketPassFairQueue__Tree queued_tree;
|
||||||
|
LinkedList1 flows_list;
|
||||||
|
int freeing;
|
||||||
|
BPending schedule_job;
|
||||||
|
DebugObject d_obj;
|
||||||
|
DebugCounter d_ctr;
|
||||||
|
} PacketPassFairQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the queue.
|
||||||
|
*
|
||||||
|
* @param m the object
|
||||||
|
* @param output output interface
|
||||||
|
* @param pg pending group
|
||||||
|
* @param use_cancel whether cancel functionality is required. Must be 0 or 1.
|
||||||
|
* If 1, output must support cancel functionality.
|
||||||
|
* @param packet_weight additional weight a packet bears. Must be >0, to keep
|
||||||
|
* the queue fair for zero size packets.
|
||||||
|
* @return 1 on success, 0 on failure (because output MTU is too large)
|
||||||
|
*/
|
||||||
|
int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight) WARN_UNUSED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the queue.
|
||||||
|
* All flows must have been freed.
|
||||||
|
*
|
||||||
|
* @param m the object
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueue_Free (PacketPassFairQueue *m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares for freeing the entire queue. Must be called to allow freeing
|
||||||
|
* the flows in the process of freeing the entire queue.
|
||||||
|
* After this function is called, flows and the queue must be freed
|
||||||
|
* before any further I/O.
|
||||||
|
* May be called multiple times.
|
||||||
|
* The queue enters freeing state.
|
||||||
|
*
|
||||||
|
* @param m the object
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueue_PrepareFree (PacketPassFairQueue *m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the MTU of the queue.
|
||||||
|
*
|
||||||
|
* @param m the object
|
||||||
|
*/
|
||||||
|
int PacketPassFairQueue_GetMTU (PacketPassFairQueue *m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a queue flow.
|
||||||
|
* Queue must not be in freeing state.
|
||||||
|
* Must not be called from queue calls to output.
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
* @param m queue to attach to
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueueFlow_Init (PacketPassFairQueueFlow *flow, PacketPassFairQueue *m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees a queue flow.
|
||||||
|
* Unless the queue is in freeing state:
|
||||||
|
* - The flow must not be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}.
|
||||||
|
* - Must not be called from queue calls to output.
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does nothing.
|
||||||
|
* It must be possible to free the flow (see {@link PacketPassFairQueueFlow_Free}).
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueueFlow_AssertFree (PacketPassFairQueueFlow *flow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the flow is busy. If the flow is considered busy, it must not
|
||||||
|
* be freed. At any given time, at most one flow will be indicated as busy.
|
||||||
|
* Queue must not be in freeing state.
|
||||||
|
* Must not be called from queue calls to output.
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
* @return 0 if not busy, 1 is busy
|
||||||
|
*/
|
||||||
|
int PacketPassFairQueueFlow_IsBusy (PacketPassFairQueueFlow *flow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests the output to stop processing the current packet as soon as possible.
|
||||||
|
* Cancel functionality must be enabled for the queue.
|
||||||
|
* The flow must be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}.
|
||||||
|
* Queue must not be in freeing state.
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueueFlow_RequestCancel (PacketPassFairQueueFlow *flow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up a callback to be called when the flow is no longer busy.
|
||||||
|
* The handler will be called as soon as the flow is no longer busy, i.e. it is not
|
||||||
|
* possible that this flow is no longer busy before the handler is called.
|
||||||
|
* The flow must be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}.
|
||||||
|
* Queue must not be in freeing state.
|
||||||
|
* Must not be called from queue calls to output.
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
* @param handler callback function. NULL to disable.
|
||||||
|
* @param user value passed to callback function. Ignored if handler is NULL.
|
||||||
|
*/
|
||||||
|
void PacketPassFairQueueFlow_SetBusyHandler (PacketPassFairQueueFlow *flow, PacketPassFairQueue_handler_busy handler, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input interface of the flow.
|
||||||
|
*
|
||||||
|
* @param flow the object
|
||||||
|
* @return input interface
|
||||||
|
*/
|
||||||
|
PacketPassInterface * PacketPassFairQueueFlow_GetInput (PacketPassFairQueueFlow *flow);
|
||||||
|
|
||||||
|
#endif
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#define SAVL_PARAM_NAME PacketPassFairQueue__Tree
|
||||||
|
#define SAVL_PARAM_FEATURE_COUNTS 0
|
||||||
|
#define SAVL_PARAM_FEATURE_NOKEYS 1
|
||||||
|
#define SAVL_PARAM_TYPE_ENTRY struct PacketPassFairQueueFlow_s
|
||||||
|
#define SAVL_PARAM_TYPE_ARG int
|
||||||
|
#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_flows((entry1), (entry2))
|
||||||
|
#define SAVL_PARAM_MEMBER_NODE queued.tree_node
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassInterface.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
void _PacketPassInterface_job_operation (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PPI_STATE_OPERATION_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PPI_STATE_BUSY;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _PacketPassInterface_job_requestcancel (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PPI_STATE_BUSY)
|
||||||
|
ASSERT(i->cancel_requested)
|
||||||
|
ASSERT(i->handler_requestcancel)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_requestcancel(i->user_provider);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _PacketPassInterface_job_done (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PPI_STATE_DONE_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PPI_STATE_NONE;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_done(i->user_user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassInterface.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Interface allowing a packet sender to pass data packets to a packet receiver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETPASSINTERFACE_H
|
||||||
|
#define BADVPN_FLOW_PACKETPASSINTERFACE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "base/BPending.h"
|
||||||
|
|
||||||
|
#define PPI_STATE_NONE 1
|
||||||
|
#define PPI_STATE_OPERATION_PENDING 2
|
||||||
|
#define PPI_STATE_BUSY 3
|
||||||
|
#define PPI_STATE_DONE_PENDING 4
|
||||||
|
|
||||||
|
typedef void (*PacketPassInterface_handler_send) (void *user, uint8_t *data, int data_len);
|
||||||
|
|
||||||
|
typedef void (*PacketPassInterface_handler_requestcancel) (void *user);
|
||||||
|
|
||||||
|
typedef void (*PacketPassInterface_handler_done) (void *user);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// provider data
|
||||||
|
int mtu;
|
||||||
|
PacketPassInterface_handler_send handler_operation;
|
||||||
|
PacketPassInterface_handler_requestcancel handler_requestcancel;
|
||||||
|
void *user_provider;
|
||||||
|
|
||||||
|
// user data
|
||||||
|
PacketPassInterface_handler_done handler_done;
|
||||||
|
void *user_user;
|
||||||
|
|
||||||
|
// operation job
|
||||||
|
BPending job_operation;
|
||||||
|
uint8_t *job_operation_data;
|
||||||
|
int job_operation_len;
|
||||||
|
|
||||||
|
// requestcancel job
|
||||||
|
BPending job_requestcancel;
|
||||||
|
|
||||||
|
// done job
|
||||||
|
BPending job_done;
|
||||||
|
|
||||||
|
// state
|
||||||
|
int state;
|
||||||
|
int cancel_requested;
|
||||||
|
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketPassInterface;
|
||||||
|
|
||||||
|
static void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg);
|
||||||
|
|
||||||
|
static void PacketPassInterface_Free (PacketPassInterface *i);
|
||||||
|
|
||||||
|
static void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel);
|
||||||
|
|
||||||
|
static void PacketPassInterface_Done (PacketPassInterface *i);
|
||||||
|
|
||||||
|
static int PacketPassInterface_GetMTU (PacketPassInterface *i);
|
||||||
|
|
||||||
|
static void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user);
|
||||||
|
|
||||||
|
static void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len);
|
||||||
|
|
||||||
|
static void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i);
|
||||||
|
|
||||||
|
static int PacketPassInterface_HasCancel (PacketPassInterface *i);
|
||||||
|
|
||||||
|
void _PacketPassInterface_job_operation (PacketPassInterface *i);
|
||||||
|
void _PacketPassInterface_job_requestcancel (PacketPassInterface *i);
|
||||||
|
void _PacketPassInterface_job_done (PacketPassInterface *i);
|
||||||
|
|
||||||
|
void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(mtu >= 0)
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
i->mtu = mtu;
|
||||||
|
i->handler_operation = handler_operation;
|
||||||
|
i->handler_requestcancel = NULL;
|
||||||
|
i->user_provider = user;
|
||||||
|
|
||||||
|
// set no user
|
||||||
|
i->handler_done = NULL;
|
||||||
|
|
||||||
|
// init jobs
|
||||||
|
BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketPassInterface_job_operation, i);
|
||||||
|
BPending_Init(&i->job_requestcancel, pg, (BPending_handler)_PacketPassInterface_job_requestcancel, i);
|
||||||
|
BPending_Init(&i->job_done, pg, (BPending_handler)_PacketPassInterface_job_done, i);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PPI_STATE_NONE;
|
||||||
|
|
||||||
|
DebugObject_Init(&i->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInterface_Free (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&i->d_obj);
|
||||||
|
|
||||||
|
// free jobs
|
||||||
|
BPending_Free(&i->job_done);
|
||||||
|
BPending_Free(&i->job_requestcancel);
|
||||||
|
BPending_Free(&i->job_operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel)
|
||||||
|
{
|
||||||
|
ASSERT(!i->handler_requestcancel)
|
||||||
|
ASSERT(!i->handler_done)
|
||||||
|
ASSERT(handler_requestcancel)
|
||||||
|
|
||||||
|
i->handler_requestcancel = handler_requestcancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInterface_Done (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PPI_STATE_BUSY)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// unset requestcancel job
|
||||||
|
BPending_Unset(&i->job_requestcancel);
|
||||||
|
|
||||||
|
// schedule done
|
||||||
|
BPending_Set(&i->job_done);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PPI_STATE_DONE_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketPassInterface_GetMTU (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
return i->mtu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user)
|
||||||
|
{
|
||||||
|
ASSERT(handler_done)
|
||||||
|
ASSERT(!i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
i->handler_done = handler_done;
|
||||||
|
i->user_user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(data_len >= 0)
|
||||||
|
ASSERT(data_len <= i->mtu)
|
||||||
|
ASSERT(!(data_len > 0) || data)
|
||||||
|
ASSERT(i->state == PPI_STATE_NONE)
|
||||||
|
ASSERT(i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule operation
|
||||||
|
i->job_operation_data = data;
|
||||||
|
i->job_operation_len = data_len;
|
||||||
|
BPending_Set(&i->job_operation);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PPI_STATE_OPERATION_PENDING;
|
||||||
|
i->cancel_requested = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PPI_STATE_OPERATION_PENDING || i->state == PPI_STATE_BUSY || i->state == PPI_STATE_DONE_PENDING)
|
||||||
|
ASSERT(i->handler_requestcancel)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// ignore multiple cancel requests
|
||||||
|
if (i->cancel_requested) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember we requested cancel
|
||||||
|
i->cancel_requested = 1;
|
||||||
|
|
||||||
|
if (i->state == PPI_STATE_OPERATION_PENDING) {
|
||||||
|
// unset operation job
|
||||||
|
BPending_Unset(&i->job_operation);
|
||||||
|
|
||||||
|
// set done job
|
||||||
|
BPending_Set(&i->job_done);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PPI_STATE_DONE_PENDING;
|
||||||
|
} else if (i->state == PPI_STATE_BUSY) {
|
||||||
|
// set requestcancel job
|
||||||
|
BPending_Set(&i->job_requestcancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketPassInterface_HasCancel (PacketPassInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
return !!i->handler_requestcancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketProtoDecoder.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/byteorder.h"
|
||||||
|
#include "misc/minmax.h"
|
||||||
|
#include "base/BLog.h"
|
||||||
|
|
||||||
|
#include "flow/PacketProtoDecoder.h"
|
||||||
|
|
||||||
|
#include "generated/blog_channel_PacketProtoDecoder.h"
|
||||||
|
|
||||||
|
static void process_data (PacketProtoDecoder *enc);
|
||||||
|
static void input_handler_done (PacketProtoDecoder *enc, int data_len);
|
||||||
|
static void output_handler_done (PacketProtoDecoder *enc);
|
||||||
|
|
||||||
|
void process_data (PacketProtoDecoder *enc)
|
||||||
|
{
|
||||||
|
int was_error = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint8_t *data = enc->buf + enc->buf_start;
|
||||||
|
int left = enc->buf_used;
|
||||||
|
|
||||||
|
// check if header was received
|
||||||
|
if (left < sizeof(struct packetproto_header)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
struct packetproto_header header;
|
||||||
|
memcpy(&header, data, sizeof(header));
|
||||||
|
data += sizeof(struct packetproto_header);
|
||||||
|
left -= sizeof(struct packetproto_header);
|
||||||
|
int data_len = ltoh16(header.len);
|
||||||
|
|
||||||
|
// check data length
|
||||||
|
if (data_len > enc->output_mtu) {
|
||||||
|
BLog(BLOG_NOTICE, "error: packet too large");
|
||||||
|
was_error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if whole packet was received
|
||||||
|
if (left < data_len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update buffer
|
||||||
|
enc->buf_start += sizeof(struct packetproto_header) + data_len;
|
||||||
|
enc->buf_used -= sizeof(struct packetproto_header) + data_len;
|
||||||
|
|
||||||
|
// submit packet
|
||||||
|
PacketPassInterface_Sender_Send(enc->output, data, data_len);
|
||||||
|
return;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
if (was_error) {
|
||||||
|
// reset buffer
|
||||||
|
enc->buf_start = 0;
|
||||||
|
enc->buf_used = 0;
|
||||||
|
} else {
|
||||||
|
// if we reached the end of the buffer, wrap around to allow more data to be received
|
||||||
|
if (enc->buf_start + enc->buf_used == enc->buf_size) {
|
||||||
|
memmove(enc->buf, enc->buf + enc->buf_start, enc->buf_used);
|
||||||
|
enc->buf_start = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// receive data
|
||||||
|
StreamRecvInterface_Receiver_Recv(enc->input, enc->buf + (enc->buf_start + enc->buf_used), enc->buf_size - (enc->buf_start + enc->buf_used));
|
||||||
|
|
||||||
|
// if we had error, report it
|
||||||
|
if (was_error) {
|
||||||
|
enc->handler_error(enc->user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_handler_done (PacketProtoDecoder *enc, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(data_len > 0)
|
||||||
|
ASSERT(data_len <= enc->buf_size - (enc->buf_start + enc->buf_used))
|
||||||
|
DebugObject_Access(&enc->d_obj);
|
||||||
|
|
||||||
|
// update buffer
|
||||||
|
enc->buf_used += data_len;
|
||||||
|
|
||||||
|
// process data
|
||||||
|
process_data(enc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void output_handler_done (PacketProtoDecoder *enc)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&enc->d_obj);
|
||||||
|
|
||||||
|
// process data
|
||||||
|
process_data(enc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error)
|
||||||
|
{
|
||||||
|
// init arguments
|
||||||
|
enc->input = input;
|
||||||
|
enc->output = output;
|
||||||
|
enc->user = user;
|
||||||
|
enc->handler_error = handler_error;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
StreamRecvInterface_Receiver_Init(enc->input, (StreamRecvInterface_handler_done)input_handler_done, enc);
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketPassInterface_Sender_Init(enc->output, (PacketPassInterface_handler_done)output_handler_done, enc);
|
||||||
|
|
||||||
|
// set output MTU, limit by maximum payload size
|
||||||
|
enc->output_mtu = bmin_int(PacketPassInterface_GetMTU(enc->output), PACKETPROTO_MAXPAYLOAD);
|
||||||
|
|
||||||
|
// init buffer state
|
||||||
|
enc->buf_size = PACKETPROTO_ENCLEN(enc->output_mtu);
|
||||||
|
enc->buf_start = 0;
|
||||||
|
enc->buf_used = 0;
|
||||||
|
|
||||||
|
// allocate buffer
|
||||||
|
if (!(enc->buf = (uint8_t *)malloc(enc->buf_size))) {
|
||||||
|
goto fail0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start receiving
|
||||||
|
StreamRecvInterface_Receiver_Recv(enc->input, enc->buf, enc->buf_size);
|
||||||
|
|
||||||
|
DebugObject_Init(&enc->d_obj);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail0:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketProtoDecoder_Free (PacketProtoDecoder *enc)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&enc->d_obj);
|
||||||
|
|
||||||
|
// free buffer
|
||||||
|
free(enc->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketProtoDecoder_Reset (PacketProtoDecoder *enc)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&enc->d_obj);
|
||||||
|
|
||||||
|
enc->buf_start += enc->buf_used;
|
||||||
|
enc->buf_used = 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketProtoDecoder.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Object which decodes a stream according to PacketProto.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETPROTODECODER_H
|
||||||
|
#define BADVPN_FLOW_PACKETPROTODECODER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "protocol/packetproto.h"
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/StreamRecvInterface.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler called when a protocol error occurs.
|
||||||
|
* When an error occurs, the decoder is reset to the initial state.
|
||||||
|
*
|
||||||
|
* @param user as in {@link PacketProtoDecoder_Init}
|
||||||
|
*/
|
||||||
|
typedef void (*PacketProtoDecoder_handler_error) (void *user);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
StreamRecvInterface *input;
|
||||||
|
PacketPassInterface *output;
|
||||||
|
void *user;
|
||||||
|
PacketProtoDecoder_handler_error handler_error;
|
||||||
|
int output_mtu;
|
||||||
|
int buf_size;
|
||||||
|
int buf_start;
|
||||||
|
int buf_used;
|
||||||
|
uint8_t *buf;
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketProtoDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*
|
||||||
|
* @param enc the object
|
||||||
|
* @param input input interface. The decoder will accept packets with payload size up to its MTU
|
||||||
|
* (but the payload can never be more than PACKETPROTO_MAXPAYLOAD).
|
||||||
|
* @param output output interface
|
||||||
|
* @param pg pending group
|
||||||
|
* @param user argument to handlers
|
||||||
|
* @param handler_error error handler
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error) WARN_UNUSED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param enc the object
|
||||||
|
*/
|
||||||
|
void PacketProtoDecoder_Free (PacketProtoDecoder *enc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the internal buffer.
|
||||||
|
* The next data received from the input will be treated as a new
|
||||||
|
* PacketProto stream.
|
||||||
|
*
|
||||||
|
* @param enc the object
|
||||||
|
*/
|
||||||
|
void PacketProtoDecoder_Reset (PacketProtoDecoder *enc);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketProtoEncoder.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "protocol/packetproto.h"
|
||||||
|
#include "misc/balign.h"
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/byteorder.h"
|
||||||
|
|
||||||
|
#include "flow/PacketProtoEncoder.h"
|
||||||
|
|
||||||
|
static void output_handler_recv (PacketProtoEncoder *enc, uint8_t *data)
|
||||||
|
{
|
||||||
|
ASSERT(!enc->output_packet)
|
||||||
|
ASSERT(data)
|
||||||
|
DebugObject_Access(&enc->d_obj);
|
||||||
|
|
||||||
|
// schedule receive
|
||||||
|
enc->output_packet = data;
|
||||||
|
PacketRecvInterface_Receiver_Recv(enc->input, enc->output_packet + sizeof(struct packetproto_header));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_handler_done (PacketProtoEncoder *enc, int in_len)
|
||||||
|
{
|
||||||
|
ASSERT(enc->output_packet)
|
||||||
|
DebugObject_Access(&enc->d_obj);
|
||||||
|
|
||||||
|
// write length
|
||||||
|
struct packetproto_header pp;
|
||||||
|
pp.len = htol16(in_len);
|
||||||
|
memcpy(enc->output_packet, &pp, sizeof(pp));
|
||||||
|
|
||||||
|
// finish output packet
|
||||||
|
enc->output_packet = NULL;
|
||||||
|
PacketRecvInterface_Done(&enc->output, PACKETPROTO_ENCLEN(in_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(PacketRecvInterface_GetMTU(input) <= PACKETPROTO_MAXPAYLOAD)
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
enc->input = input;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketRecvInterface_Receiver_Init(enc->input, (PacketRecvInterface_handler_done)input_handler_done, enc);
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketRecvInterface_Init(
|
||||||
|
&enc->output, PACKETPROTO_ENCLEN(PacketRecvInterface_GetMTU(enc->input)),
|
||||||
|
(PacketRecvInterface_handler_recv)output_handler_recv, enc, pg
|
||||||
|
);
|
||||||
|
|
||||||
|
// set no output packet
|
||||||
|
enc->output_packet = NULL;
|
||||||
|
|
||||||
|
DebugObject_Init(&enc->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketProtoEncoder_Free (PacketProtoEncoder *enc)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&enc->d_obj);
|
||||||
|
|
||||||
|
// free input
|
||||||
|
PacketRecvInterface_Free(&enc->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketRecvInterface * PacketProtoEncoder_GetOutput (PacketProtoEncoder *enc)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&enc->d_obj);
|
||||||
|
|
||||||
|
return &enc->output;
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketProtoEncoder.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Object which encodes packets according to PacketProto.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETPROTOENCODER_H
|
||||||
|
#define BADVPN_FLOW_PACKETPROTOENCODER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/PacketRecvInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object which encodes packets according to PacketProto.
|
||||||
|
*
|
||||||
|
* Input is with {@link PacketRecvInterface}.
|
||||||
|
* Output is with {@link PacketRecvInterface}.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
PacketRecvInterface *input;
|
||||||
|
PacketRecvInterface output;
|
||||||
|
uint8_t *output_packet;
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketProtoEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*
|
||||||
|
* @param enc the object
|
||||||
|
* @param input input interface. Its MTU must be <=PACKETPROTO_MAXPAYLOAD.
|
||||||
|
* @param pg pending group
|
||||||
|
*/
|
||||||
|
void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param enc the object
|
||||||
|
*/
|
||||||
|
void PacketProtoEncoder_Free (PacketProtoEncoder *enc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the output interface.
|
||||||
|
* The MTU of the output interface is PACKETPROTO_ENCLEN(MTU of input interface).
|
||||||
|
*
|
||||||
|
* @param enc the object
|
||||||
|
* @return output interface
|
||||||
|
*/
|
||||||
|
PacketRecvInterface * PacketProtoEncoder_GetOutput (PacketProtoEncoder *enc);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketProtoFlow.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "protocol/packetproto.h"
|
||||||
|
#include "misc/debug.h"
|
||||||
|
|
||||||
|
#include "flow/PacketProtoFlow.h"
|
||||||
|
|
||||||
|
int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(input_mtu >= 0)
|
||||||
|
ASSERT(input_mtu <= PACKETPROTO_MAXPAYLOAD)
|
||||||
|
ASSERT(num_packets > 0)
|
||||||
|
ASSERT(PacketPassInterface_GetMTU(output) >= PACKETPROTO_ENCLEN(input_mtu))
|
||||||
|
|
||||||
|
// init async input
|
||||||
|
BufferWriter_Init(&o->ainput, input_mtu, pg);
|
||||||
|
|
||||||
|
// init encoder
|
||||||
|
PacketProtoEncoder_Init(&o->encoder, BufferWriter_GetOutput(&o->ainput), pg);
|
||||||
|
|
||||||
|
// init buffer
|
||||||
|
if (!PacketBuffer_Init(&o->buffer, PacketProtoEncoder_GetOutput(&o->encoder), output, num_packets, pg)) {
|
||||||
|
goto fail0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail0:
|
||||||
|
PacketProtoEncoder_Free(&o->encoder);
|
||||||
|
BufferWriter_Free(&o->ainput);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketProtoFlow_Free (PacketProtoFlow *o)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
|
||||||
|
// free buffer
|
||||||
|
PacketBuffer_Free(&o->buffer);
|
||||||
|
|
||||||
|
// free encoder
|
||||||
|
PacketProtoEncoder_Free(&o->encoder);
|
||||||
|
|
||||||
|
// free async input
|
||||||
|
BufferWriter_Free(&o->ainput);
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
return &o->ainput;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketProtoFlow.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Buffer which encodes packets with PacketProto, with {@link BufferWriter}
|
||||||
|
* input and {@link PacketPassInterface} output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETPROTOFLOW_H
|
||||||
|
#define BADVPN_FLOW_PACKETPROTOFLOW_H
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/BufferWriter.h"
|
||||||
|
#include "flow/PacketProtoEncoder.h"
|
||||||
|
#include "flow/PacketBuffer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer which encodes packets with PacketProto, with {@link BufferWriter}
|
||||||
|
* input and {@link PacketPassInterface} output.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
BufferWriter ainput;
|
||||||
|
PacketProtoEncoder encoder;
|
||||||
|
PacketBuffer buffer;
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketProtoFlow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param input_mtu maximum input packet size. Must be >=0 and <=PACKETPROTO_MAXPAYLOAD.
|
||||||
|
* @param num_packets minimum number of packets the buffer should hold. Must be >0.
|
||||||
|
* @param output output interface. Its MTU must be >=PACKETPROTO_ENCLEN(input_mtu).
|
||||||
|
* @param pg pending group
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg) WARN_UNUSED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void PacketProtoFlow_Free (PacketProtoFlow *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input interface.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @return input interface
|
||||||
|
*/
|
||||||
|
BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketRecvInterface.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flow/PacketRecvInterface.h"
|
||||||
|
|
||||||
|
void _PacketRecvInterface_job_operation (PacketRecvInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PRI_STATE_OPERATION_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PRI_STATE_BUSY;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_operation(i->user_provider, i->job_operation_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _PacketRecvInterface_job_done (PacketRecvInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == PRI_STATE_DONE_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PRI_STATE_NONE;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_done(i->user_user, i->job_done_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketRecvInterface.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Interface allowing a packet receiver to receive data packets from a packet sender.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETRECVINTERFACE_H
|
||||||
|
#define BADVPN_FLOW_PACKETRECVINTERFACE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "base/BPending.h"
|
||||||
|
|
||||||
|
#define PRI_STATE_NONE 1
|
||||||
|
#define PRI_STATE_OPERATION_PENDING 2
|
||||||
|
#define PRI_STATE_BUSY 3
|
||||||
|
#define PRI_STATE_DONE_PENDING 4
|
||||||
|
|
||||||
|
typedef void (*PacketRecvInterface_handler_recv) (void *user, uint8_t *data);
|
||||||
|
|
||||||
|
typedef void (*PacketRecvInterface_handler_done) (void *user, int data_len);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// provider data
|
||||||
|
int mtu;
|
||||||
|
PacketRecvInterface_handler_recv handler_operation;
|
||||||
|
void *user_provider;
|
||||||
|
|
||||||
|
// user data
|
||||||
|
PacketRecvInterface_handler_done handler_done;
|
||||||
|
void *user_user;
|
||||||
|
|
||||||
|
// operation job
|
||||||
|
BPending job_operation;
|
||||||
|
uint8_t *job_operation_data;
|
||||||
|
|
||||||
|
// done job
|
||||||
|
BPending job_done;
|
||||||
|
int job_done_len;
|
||||||
|
|
||||||
|
// state
|
||||||
|
int state;
|
||||||
|
|
||||||
|
DebugObject d_obj;
|
||||||
|
} PacketRecvInterface;
|
||||||
|
|
||||||
|
static void PacketRecvInterface_Init (PacketRecvInterface *i, int mtu, PacketRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg);
|
||||||
|
|
||||||
|
static void PacketRecvInterface_Free (PacketRecvInterface *i);
|
||||||
|
|
||||||
|
static void PacketRecvInterface_Done (PacketRecvInterface *i, int data_len);
|
||||||
|
|
||||||
|
static int PacketRecvInterface_GetMTU (PacketRecvInterface *i);
|
||||||
|
|
||||||
|
static void PacketRecvInterface_Receiver_Init (PacketRecvInterface *i, PacketRecvInterface_handler_done handler_done, void *user);
|
||||||
|
|
||||||
|
static void PacketRecvInterface_Receiver_Recv (PacketRecvInterface *i, uint8_t *data);
|
||||||
|
|
||||||
|
void _PacketRecvInterface_job_operation (PacketRecvInterface *i);
|
||||||
|
void _PacketRecvInterface_job_done (PacketRecvInterface *i);
|
||||||
|
|
||||||
|
void PacketRecvInterface_Init (PacketRecvInterface *i, int mtu, PacketRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(mtu >= 0)
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
i->mtu = mtu;
|
||||||
|
i->handler_operation = handler_operation;
|
||||||
|
i->user_provider = user;
|
||||||
|
|
||||||
|
// set no user
|
||||||
|
i->handler_done = NULL;
|
||||||
|
|
||||||
|
// init jobs
|
||||||
|
BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketRecvInterface_job_operation, i);
|
||||||
|
BPending_Init(&i->job_done, pg, (BPending_handler)_PacketRecvInterface_job_done, i);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PRI_STATE_NONE;
|
||||||
|
|
||||||
|
DebugObject_Init(&i->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketRecvInterface_Free (PacketRecvInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&i->d_obj);
|
||||||
|
|
||||||
|
// free jobs
|
||||||
|
BPending_Free(&i->job_done);
|
||||||
|
BPending_Free(&i->job_operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketRecvInterface_Done (PacketRecvInterface *i, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(data_len >= 0)
|
||||||
|
ASSERT(data_len <= i->mtu)
|
||||||
|
ASSERT(i->state == PRI_STATE_BUSY)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule done
|
||||||
|
i->job_done_len = data_len;
|
||||||
|
BPending_Set(&i->job_done);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PRI_STATE_DONE_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketRecvInterface_GetMTU (PacketRecvInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
return i->mtu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketRecvInterface_Receiver_Init (PacketRecvInterface *i, PacketRecvInterface_handler_done handler_done, void *user)
|
||||||
|
{
|
||||||
|
ASSERT(handler_done)
|
||||||
|
ASSERT(!i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
i->handler_done = handler_done;
|
||||||
|
i->user_user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketRecvInterface_Receiver_Recv (PacketRecvInterface *i, uint8_t *data)
|
||||||
|
{
|
||||||
|
ASSERT(!(i->mtu > 0) || data)
|
||||||
|
ASSERT(i->state == PRI_STATE_NONE)
|
||||||
|
ASSERT(i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule operation
|
||||||
|
i->job_operation_data = data;
|
||||||
|
BPending_Set(&i->job_operation);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = PRI_STATE_OPERATION_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketStreamSender.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
|
||||||
|
#include "flow/PacketStreamSender.h"
|
||||||
|
|
||||||
|
static void send_data (PacketStreamSender *s)
|
||||||
|
{
|
||||||
|
ASSERT(s->in_len >= 0)
|
||||||
|
|
||||||
|
if (s->in_used < s->in_len) {
|
||||||
|
// send more data
|
||||||
|
StreamPassInterface_Sender_Send(s->output, s->in + s->in_used, s->in_len - s->in_used);
|
||||||
|
} else {
|
||||||
|
// finish input packet
|
||||||
|
s->in_len = -1;
|
||||||
|
PacketPassInterface_Done(&s->input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_handler_send (PacketStreamSender *s, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(s->in_len == -1)
|
||||||
|
ASSERT(data_len >= 0)
|
||||||
|
DebugObject_Access(&s->d_obj);
|
||||||
|
|
||||||
|
// set input packet
|
||||||
|
s->in_len = data_len;
|
||||||
|
s->in = data;
|
||||||
|
s->in_used = 0;
|
||||||
|
|
||||||
|
// send
|
||||||
|
send_data(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_handler_done (PacketStreamSender *s, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(s->in_len >= 0)
|
||||||
|
ASSERT(data_len > 0)
|
||||||
|
ASSERT(data_len <= s->in_len - s->in_used)
|
||||||
|
DebugObject_Access(&s->d_obj);
|
||||||
|
|
||||||
|
// update number of bytes sent
|
||||||
|
s->in_used += data_len;
|
||||||
|
|
||||||
|
// send
|
||||||
|
send_data(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketStreamSender_Init (PacketStreamSender *s, StreamPassInterface *output, int mtu, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(mtu >= 0)
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
s->output = output;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)input_handler_send, s, pg);
|
||||||
|
|
||||||
|
// init output
|
||||||
|
StreamPassInterface_Sender_Init(s->output, (StreamPassInterface_handler_done)output_handler_done, s);
|
||||||
|
|
||||||
|
// have no input packet
|
||||||
|
s->in_len = -1;
|
||||||
|
|
||||||
|
DebugObject_Init(&s->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketStreamSender_Free (PacketStreamSender *s)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&s->d_obj);
|
||||||
|
|
||||||
|
// free input
|
||||||
|
PacketPassInterface_Free(&s->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPassInterface * PacketStreamSender_GetInput (PacketStreamSender *s)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&s->d_obj);
|
||||||
|
|
||||||
|
return &s->input;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketStreamSender.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Object which forwards packets obtained with {@link PacketPassInterface}
|
||||||
|
* as a stream with {@link StreamPassInterface} (i.e. it concatenates them).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_PACKETSTREAMSENDER_H
|
||||||
|
#define BADVPN_FLOW_PACKETSTREAMSENDER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
#include "flow/StreamPassInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object which forwards packets obtained with {@link PacketPassInterface}
|
||||||
|
* as a stream with {@link StreamPassInterface} (i.e. it concatenates them).
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
DebugObject d_obj;
|
||||||
|
PacketPassInterface input;
|
||||||
|
StreamPassInterface *output;
|
||||||
|
int in_len;
|
||||||
|
uint8_t *in;
|
||||||
|
int in_used;
|
||||||
|
} PacketStreamSender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
*
|
||||||
|
* @param s the object
|
||||||
|
* @param output output interface
|
||||||
|
* @param mtu input MTU. Must be >=0.
|
||||||
|
* @param pg pending group
|
||||||
|
*/
|
||||||
|
void PacketStreamSender_Init (PacketStreamSender *s, StreamPassInterface *output, int mtu, BPendingGroup *pg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param s the object
|
||||||
|
*/
|
||||||
|
void PacketStreamSender_Free (PacketStreamSender *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input interface.
|
||||||
|
* Its MTU will be as in {@link PacketStreamSender_Init}.
|
||||||
|
*
|
||||||
|
* @param s the object
|
||||||
|
* @return input interface
|
||||||
|
*/
|
||||||
|
PacketPassInterface * PacketStreamSender_GetInput (PacketStreamSender *s);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* @file SinglePacketBuffer.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "misc/balloc.h"
|
||||||
|
|
||||||
|
#include "flow/SinglePacketBuffer.h"
|
||||||
|
|
||||||
|
static void input_handler_done (SinglePacketBuffer *o, int in_len)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
PacketPassInterface_Sender_Send(o->output, o->buf, in_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_handler_done (SinglePacketBuffer *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
PacketRecvInterface_Receiver_Recv(o->input, o->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SinglePacketBuffer_Init (SinglePacketBuffer *o, PacketRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
ASSERT(PacketPassInterface_GetMTU(output) >= PacketRecvInterface_GetMTU(input))
|
||||||
|
|
||||||
|
// init arguments
|
||||||
|
o->input = input;
|
||||||
|
o->output = output;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o);
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o);
|
||||||
|
|
||||||
|
// init buffer
|
||||||
|
if (!(o->buf = (uint8_t *)BAlloc(PacketRecvInterface_GetMTU(o->input)))) {
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// schedule receive
|
||||||
|
PacketRecvInterface_Receiver_Recv(o->input, o->buf);
|
||||||
|
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail1:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePacketBuffer_Free (SinglePacketBuffer *o)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
|
||||||
|
// free buffer
|
||||||
|
BFree(o->buf);
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* @file SinglePacketBuffer.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output
|
||||||
|
* than can store only a single packet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_SINGLEPACKETBUFFER_H
|
||||||
|
#define BADVPN_FLOW_SINGLEPACKETBUFFER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "flow/PacketRecvInterface.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output
|
||||||
|
* than can store only a single packet.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
DebugObject d_obj;
|
||||||
|
PacketRecvInterface *input;
|
||||||
|
PacketPassInterface *output;
|
||||||
|
uint8_t *buf;
|
||||||
|
} SinglePacketBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
* Output MTU must be >= input MTU.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param input input interface
|
||||||
|
* @param output output interface
|
||||||
|
* @param pg pending group
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int SinglePacketBuffer_Init (SinglePacketBuffer *o, PacketRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg) WARN_UNUSED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void SinglePacketBuffer_Free (SinglePacketBuffer *o);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* @file StreamPassInterface.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flow/StreamPassInterface.h"
|
||||||
|
|
||||||
|
void _StreamPassInterface_job_operation (StreamPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == SPI_STATE_OPERATION_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SPI_STATE_BUSY;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _StreamPassInterface_job_done (StreamPassInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == SPI_STATE_DONE_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SPI_STATE_NONE;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_done(i->user_user, i->job_done_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/**
|
||||||
|
* @file StreamPassInterface.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Interface allowing a stream sender to pass stream data to a stream receiver.
|
||||||
|
*
|
||||||
|
* Note that this interface behaves exactly the same and has the same code as
|
||||||
|
* {@link StreamRecvInterface} if names and its external semantics are disregarded.
|
||||||
|
* If you modify this file, you should probably modify {@link StreamRecvInterface}
|
||||||
|
* too.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_STREAMPASSINTERFACE_H
|
||||||
|
#define BADVPN_FLOW_STREAMPASSINTERFACE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "base/BPending.h"
|
||||||
|
|
||||||
|
#define SPI_STATE_NONE 1
|
||||||
|
#define SPI_STATE_OPERATION_PENDING 2
|
||||||
|
#define SPI_STATE_BUSY 3
|
||||||
|
#define SPI_STATE_DONE_PENDING 4
|
||||||
|
|
||||||
|
typedef void (*StreamPassInterface_handler_send) (void *user, uint8_t *data, int data_len);
|
||||||
|
|
||||||
|
typedef void (*StreamPassInterface_handler_done) (void *user, int data_len);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// provider data
|
||||||
|
StreamPassInterface_handler_send handler_operation;
|
||||||
|
void *user_provider;
|
||||||
|
|
||||||
|
// user data
|
||||||
|
StreamPassInterface_handler_done handler_done;
|
||||||
|
void *user_user;
|
||||||
|
|
||||||
|
// operation job
|
||||||
|
BPending job_operation;
|
||||||
|
uint8_t *job_operation_data;
|
||||||
|
int job_operation_len;
|
||||||
|
|
||||||
|
// done job
|
||||||
|
BPending job_done;
|
||||||
|
int job_done_len;
|
||||||
|
|
||||||
|
// state
|
||||||
|
int state;
|
||||||
|
|
||||||
|
DebugObject d_obj;
|
||||||
|
} StreamPassInterface;
|
||||||
|
|
||||||
|
static void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg);
|
||||||
|
|
||||||
|
static void StreamPassInterface_Free (StreamPassInterface *i);
|
||||||
|
|
||||||
|
static void StreamPassInterface_Done (StreamPassInterface *i, int data_len);
|
||||||
|
|
||||||
|
static void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user);
|
||||||
|
|
||||||
|
static void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len);
|
||||||
|
|
||||||
|
void _StreamPassInterface_job_operation (StreamPassInterface *i);
|
||||||
|
void _StreamPassInterface_job_done (StreamPassInterface *i);
|
||||||
|
|
||||||
|
void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
// init arguments
|
||||||
|
i->handler_operation = handler_operation;
|
||||||
|
i->user_provider = user;
|
||||||
|
|
||||||
|
// set no user
|
||||||
|
i->handler_done = NULL;
|
||||||
|
|
||||||
|
// init jobs
|
||||||
|
BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamPassInterface_job_operation, i);
|
||||||
|
BPending_Init(&i->job_done, pg, (BPending_handler)_StreamPassInterface_job_done, i);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SPI_STATE_NONE;
|
||||||
|
|
||||||
|
DebugObject_Init(&i->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamPassInterface_Free (StreamPassInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&i->d_obj);
|
||||||
|
|
||||||
|
// free jobs
|
||||||
|
BPending_Free(&i->job_done);
|
||||||
|
BPending_Free(&i->job_operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamPassInterface_Done (StreamPassInterface *i, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == SPI_STATE_BUSY)
|
||||||
|
ASSERT(data_len > 0)
|
||||||
|
ASSERT(data_len <= i->job_operation_len)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule done
|
||||||
|
i->job_done_len = data_len;
|
||||||
|
BPending_Set(&i->job_done);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SPI_STATE_DONE_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user)
|
||||||
|
{
|
||||||
|
ASSERT(handler_done)
|
||||||
|
ASSERT(!i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
i->handler_done = handler_done;
|
||||||
|
i->user_user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(data_len > 0)
|
||||||
|
ASSERT(data)
|
||||||
|
ASSERT(i->state == SPI_STATE_NONE)
|
||||||
|
ASSERT(i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule operation
|
||||||
|
i->job_operation_data = data;
|
||||||
|
i->job_operation_len = data_len;
|
||||||
|
BPending_Set(&i->job_operation);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SPI_STATE_OPERATION_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* @file StreamRecvInterface.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flow/StreamRecvInterface.h"
|
||||||
|
|
||||||
|
void _StreamRecvInterface_job_operation (StreamRecvInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == SRI_STATE_OPERATION_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SRI_STATE_BUSY;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _StreamRecvInterface_job_done (StreamRecvInterface *i)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == SRI_STATE_DONE_PENDING)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SRI_STATE_NONE;
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
i->handler_done(i->user_user, i->job_done_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/**
|
||||||
|
* @file StreamRecvInterface.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* Interface allowing a stream receiver to receive stream data from a stream sender.
|
||||||
|
*
|
||||||
|
* Note that this interface behaves exactly the same and has the same code as
|
||||||
|
* {@link StreamPassInterface} if names and its external semantics are disregarded.
|
||||||
|
* If you modify this file, you should probably modify {@link StreamPassInterface}
|
||||||
|
* too.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_FLOW_STREAMRECVINTERFACE_H
|
||||||
|
#define BADVPN_FLOW_STREAMRECVINTERFACE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "misc/debug.h"
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "base/BPending.h"
|
||||||
|
|
||||||
|
#define SRI_STATE_NONE 1
|
||||||
|
#define SRI_STATE_OPERATION_PENDING 2
|
||||||
|
#define SRI_STATE_BUSY 3
|
||||||
|
#define SRI_STATE_DONE_PENDING 4
|
||||||
|
|
||||||
|
typedef void (*StreamRecvInterface_handler_recv) (void *user, uint8_t *data, int data_len);
|
||||||
|
|
||||||
|
typedef void (*StreamRecvInterface_handler_done) (void *user, int data_len);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// provider data
|
||||||
|
StreamRecvInterface_handler_recv handler_operation;
|
||||||
|
void *user_provider;
|
||||||
|
|
||||||
|
// user data
|
||||||
|
StreamRecvInterface_handler_done handler_done;
|
||||||
|
void *user_user;
|
||||||
|
|
||||||
|
// operation job
|
||||||
|
BPending job_operation;
|
||||||
|
uint8_t *job_operation_data;
|
||||||
|
int job_operation_len;
|
||||||
|
|
||||||
|
// done job
|
||||||
|
BPending job_done;
|
||||||
|
int job_done_len;
|
||||||
|
|
||||||
|
// state
|
||||||
|
int state;
|
||||||
|
|
||||||
|
DebugObject d_obj;
|
||||||
|
} StreamRecvInterface;
|
||||||
|
|
||||||
|
static void StreamRecvInterface_Init (StreamRecvInterface *i, StreamRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg);
|
||||||
|
|
||||||
|
static void StreamRecvInterface_Free (StreamRecvInterface *i);
|
||||||
|
|
||||||
|
static void StreamRecvInterface_Done (StreamRecvInterface *i, int data_len);
|
||||||
|
|
||||||
|
static void StreamRecvInterface_Receiver_Init (StreamRecvInterface *i, StreamRecvInterface_handler_done handler_done, void *user);
|
||||||
|
|
||||||
|
static void StreamRecvInterface_Receiver_Recv (StreamRecvInterface *i, uint8_t *data, int data_len);
|
||||||
|
|
||||||
|
void _StreamRecvInterface_job_operation (StreamRecvInterface *i);
|
||||||
|
void _StreamRecvInterface_job_done (StreamRecvInterface *i);
|
||||||
|
|
||||||
|
void StreamRecvInterface_Init (StreamRecvInterface *i, StreamRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg)
|
||||||
|
{
|
||||||
|
// init arguments
|
||||||
|
i->handler_operation = handler_operation;
|
||||||
|
i->user_provider = user;
|
||||||
|
|
||||||
|
// set no user
|
||||||
|
i->handler_done = NULL;
|
||||||
|
|
||||||
|
// init jobs
|
||||||
|
BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamRecvInterface_job_operation, i);
|
||||||
|
BPending_Init(&i->job_done, pg, (BPending_handler)_StreamRecvInterface_job_done, i);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SRI_STATE_NONE;
|
||||||
|
|
||||||
|
DebugObject_Init(&i->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamRecvInterface_Free (StreamRecvInterface *i)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&i->d_obj);
|
||||||
|
|
||||||
|
// free jobs
|
||||||
|
BPending_Free(&i->job_done);
|
||||||
|
BPending_Free(&i->job_operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamRecvInterface_Done (StreamRecvInterface *i, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(i->state == SRI_STATE_BUSY)
|
||||||
|
ASSERT(data_len > 0)
|
||||||
|
ASSERT(data_len <= i->job_operation_len)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule done
|
||||||
|
i->job_done_len = data_len;
|
||||||
|
BPending_Set(&i->job_done);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SRI_STATE_DONE_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamRecvInterface_Receiver_Init (StreamRecvInterface *i, StreamRecvInterface_handler_done handler_done, void *user)
|
||||||
|
{
|
||||||
|
ASSERT(handler_done)
|
||||||
|
ASSERT(!i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
i->handler_done = handler_done;
|
||||||
|
i->user_user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamRecvInterface_Receiver_Recv (StreamRecvInterface *i, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
ASSERT(data_len > 0)
|
||||||
|
ASSERT(data)
|
||||||
|
ASSERT(i->state == SRI_STATE_NONE)
|
||||||
|
ASSERT(i->handler_done)
|
||||||
|
DebugObject_Access(&i->d_obj);
|
||||||
|
|
||||||
|
// schedule operation
|
||||||
|
i->job_operation_data = data;
|
||||||
|
i->job_operation_len = data_len;
|
||||||
|
BPending_Set(&i->job_operation);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
i->state = SRI_STATE_OPERATION_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+131
@@ -0,0 +1,131 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassInactivityMonitor.c
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PacketPassInactivityMonitor.h"
|
||||||
|
|
||||||
|
static void input_handler_send (PacketPassInactivityMonitor *o, uint8_t *data, int data_len)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// schedule send
|
||||||
|
PacketPassInterface_Sender_Send(o->output, data, data_len);
|
||||||
|
|
||||||
|
// stop timer
|
||||||
|
BReactor_RemoveTimer(o->reactor, &o->timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_handler_requestcancel (PacketPassInactivityMonitor *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// request cancel
|
||||||
|
PacketPassInterface_Sender_RequestCancel(o->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_handler_done (PacketPassInactivityMonitor *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// output no longer busy, restart timer
|
||||||
|
BReactor_SetTimer(o->reactor, &o->timer);
|
||||||
|
|
||||||
|
// call done
|
||||||
|
PacketPassInterface_Done(&o->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timer_handler (PacketPassInactivityMonitor *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
// restart timer
|
||||||
|
BReactor_SetTimer(o->reactor, &o->timer);
|
||||||
|
|
||||||
|
// call handler
|
||||||
|
if (o->handler) {
|
||||||
|
o->handler(o->user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInactivityMonitor_Init (PacketPassInactivityMonitor *o, PacketPassInterface *output, BReactor *reactor, btime_t interval, PacketPassInactivityMonitor_handler handler, void *user)
|
||||||
|
{
|
||||||
|
// init arguments
|
||||||
|
o->output = output;
|
||||||
|
o->reactor = reactor;
|
||||||
|
o->handler = handler;
|
||||||
|
o->user = user;
|
||||||
|
|
||||||
|
// init input
|
||||||
|
PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, BReactor_PendingGroup(o->reactor));
|
||||||
|
if (PacketPassInterface_HasCancel(o->output)) {
|
||||||
|
PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init output
|
||||||
|
PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o);
|
||||||
|
|
||||||
|
// init timer
|
||||||
|
BTimer_Init(&o->timer, interval, (BTimer_handler)timer_handler, o);
|
||||||
|
BReactor_SetTimer(o->reactor, &o->timer);
|
||||||
|
|
||||||
|
DebugObject_Init(&o->d_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInactivityMonitor_Free (PacketPassInactivityMonitor *o)
|
||||||
|
{
|
||||||
|
DebugObject_Free(&o->d_obj);
|
||||||
|
|
||||||
|
// free timer
|
||||||
|
BReactor_RemoveTimer(o->reactor, &o->timer);
|
||||||
|
|
||||||
|
// free input
|
||||||
|
PacketPassInterface_Free(&o->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPassInterface * PacketPassInactivityMonitor_GetInput (PacketPassInactivityMonitor *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
return &o->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInactivityMonitor_SetHandler (PacketPassInactivityMonitor *o, PacketPassInactivityMonitor_handler handler, void *user)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
o->handler = handler;
|
||||||
|
o->user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketPassInactivityMonitor_Force (PacketPassInactivityMonitor *o)
|
||||||
|
{
|
||||||
|
DebugObject_Access(&o->d_obj);
|
||||||
|
|
||||||
|
BReactor_SetTimerAfter(o->reactor, &o->timer, 0);
|
||||||
|
}
|
||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* @file PacketPassInactivityMonitor.h
|
||||||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
|
*
|
||||||
|
* @section LICENSE
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the author 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 AUTHOR 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.
|
||||||
|
*
|
||||||
|
* @section DESCRIPTION
|
||||||
|
*
|
||||||
|
* A {@link PacketPassInterface} layer for detecting inactivity.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BADVPN_PACKETPASSINACTIVITYMONITOR_H
|
||||||
|
#define BADVPN_PACKETPASSINACTIVITYMONITOR_H
|
||||||
|
|
||||||
|
#include "base/DebugObject.h"
|
||||||
|
#include "system/BReactor.h"
|
||||||
|
#include "flow/PacketPassInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler function invoked when inactivity is detected.
|
||||||
|
* It is guaranteed that the interfaces are in not sending state.
|
||||||
|
*
|
||||||
|
* @param user value given to {@link PacketPassInactivityMonitor_Init}
|
||||||
|
*/
|
||||||
|
typedef void (*PacketPassInactivityMonitor_handler) (void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link PacketPassInterface} layer for detecting inactivity.
|
||||||
|
* It reports inactivity to a user provided handler function.
|
||||||
|
*
|
||||||
|
* The object behaves like that:
|
||||||
|
* ("timer set" means started with the given timeout whether if was running or not,
|
||||||
|
* "timer unset" means stopped if it was running)
|
||||||
|
* - There is a timer.
|
||||||
|
* - The timer is set when the object is initialized.
|
||||||
|
* - When the input calls Send, the call is passed on to the output.
|
||||||
|
* If the output accepted the packet, the timer is set. If the output
|
||||||
|
* blocked the packet, the timer is unset.
|
||||||
|
* - When the output calls Done, the timer is set, and the call is
|
||||||
|
* passed on to the input.
|
||||||
|
* - When the input calls Cancel, the timer is set, and the call is
|
||||||
|
* passed on to the output.
|
||||||
|
* - When the timer expires, the timer is set, ant the user's handler
|
||||||
|
* function is invoked.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
DebugObject d_obj;
|
||||||
|
PacketPassInterface *output;
|
||||||
|
BReactor *reactor;
|
||||||
|
PacketPassInactivityMonitor_handler handler;
|
||||||
|
void *user;
|
||||||
|
PacketPassInterface input;
|
||||||
|
BTimer timer;
|
||||||
|
} PacketPassInactivityMonitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the object.
|
||||||
|
* See {@link PacketPassInactivityMonitor} for details.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param output output interface
|
||||||
|
* @param reactor reactor we live in
|
||||||
|
* @param interval timer value in milliseconds
|
||||||
|
* @param handler handler function for reporting inactivity, or NULL to disable
|
||||||
|
* @param user value passed to handler functions
|
||||||
|
*/
|
||||||
|
void PacketPassInactivityMonitor_Init (PacketPassInactivityMonitor *o, PacketPassInterface *output, BReactor *reactor, btime_t interval, PacketPassInactivityMonitor_handler handler, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the object.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void PacketPassInactivityMonitor_Free (PacketPassInactivityMonitor *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input interface.
|
||||||
|
* The MTU of the interface will be the same as of the output interface.
|
||||||
|
* The interface supports cancel functionality if the output interface supports it.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @return input interface
|
||||||
|
*/
|
||||||
|
PacketPassInterface * PacketPassInactivityMonitor_GetInput (PacketPassInactivityMonitor *o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets or removes the inactivity handler.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
* @param handler handler function for reporting inactivity, or NULL to disable
|
||||||
|
* @param user value passed to handler functions
|
||||||
|
*/
|
||||||
|
void PacketPassInactivityMonitor_SetHandler (PacketPassInactivityMonitor *o, PacketPassInactivityMonitor_handler handler, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the timer to expire immediately in order to force an inactivity report.
|
||||||
|
*
|
||||||
|
* @param o the object
|
||||||
|
*/
|
||||||
|
void PacketPassInactivityMonitor_Force (PacketPassInactivityMonitor *o);
|
||||||
|
|
||||||
|
#endif
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BArpProbe
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BConnection
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDHCPClient
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDHCPClientCore
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDatagram
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BEncryption
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BInputProcess
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BLockReactor
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BNetwork
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BPredicate
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BProcess
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BReactor
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSSLConnection
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSignal
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSocksClient
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BTap
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BThreadSignal
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BThreadWork
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BTime
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BUnixSignal
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DPReceive
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DPRelay
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DataProto
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DatagramPeerIO
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_FragmentProtoAssembler
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_FrameDecider
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_LineBuffer
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_Listener
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDBuildProgram
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigParser
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigTokenizer
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDIfConfig
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef BLOG_CURRENT_CHANNEL
|
||||||
|
#undef BLOG_CURRENT_CHANNEL
|
||||||
|
#endif
|
||||||
|
#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDInterfaceMonitor
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user