├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── LICENSE.Apachev2 ├── LICENSE.BSD ├── README.md ├── build.sh ├── make_common.mak ├── make_linux.mak ├── make_macosx.mak ├── make_windows.mak ├── src ├── api.cpp ├── api.h ├── buffer.cpp ├── buffer.h ├── cache.cpp ├── cache.h ├── ccc.cpp ├── ccc.h ├── channel.cpp ├── channel.h ├── core.cpp ├── core.h ├── epoll.cpp ├── epoll.h ├── list.cpp ├── list.h ├── md5.cpp ├── md5.h ├── packet.cpp ├── packet.h ├── queue.cpp ├── queue.h ├── udt.h ├── udtCommon.cpp ├── udtCommon.h ├── window.cpp └── window.h └── udt-doc ├── 0001-Added-BARCHART-2013-05-11-2013-05-12-already-applied.patch ├── 0002-Refactored-win-osx-and-32-64-bit-preprocessor-symbol.patch ├── 0003-Code-polish.-removed-unnecessary-preprocessor-symbol.patch ├── 0004-Fixed-unitialized-variable.patch ├── LICENSE.txt ├── README.txt ├── RELEASE_NOTES.txt ├── draft-gg-udt-xx.txt ├── udt-2009.ppt └── udt-sc08-poster.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 3 | 4 | # User-specific stuff: 5 | .idea/**/workspace.xml 6 | .idea/**/tasks.xml 7 | .idea/dictionaries 8 | .idea/**/codeStyles/ 9 | .idea/**/codeStyleSettings.xml 10 | 11 | # Sensitive or high-churn files: 12 | .idea/**/dataSources/ 13 | .idea/**/dataSources.ids 14 | .idea/**/dataSources.xml 15 | .idea/**/dataSources.local.xml 16 | .idea/**/sqlDataSources.xml 17 | .idea/**/dynamic.xml 18 | .idea/**/uiDesigner.xml 19 | .idea/**/shelf/ 20 | 21 | 22 | # Gradle: 23 | .idea/**/gradle.xml 24 | # .idea/**/libraries # we want to include our library definitions. 25 | 26 | # CMake 27 | cmake-build-debug/ 28 | 29 | # Mongo Explorer plugin: 30 | .idea/**/mongoSettings.xml 31 | 32 | ## File-based project format: 33 | *.iws 34 | 35 | ## Plugin-specific files: 36 | 37 | 38 | # IntelliJ 39 | out/ 40 | 41 | # mpeltonen/sbt-idea plugin 42 | .idea_modules/ 43 | 44 | # JIRA plugin 45 | atlassian-ide-plugin.xml 46 | 47 | # Cursive Clojure plugin 48 | .idea/replstate.xml 49 | 50 | # Crashlytics plugin (for Android Studio and IntelliJ) 51 | com_crashlytics_export_strings.xml 52 | crashlytics.properties 53 | crashlytics-build.properties 54 | fabric.properties 55 | 56 | ###################### 57 | # End JetBrains IDEs # 58 | ###################### 59 | 60 | /bin/ 61 | /dist/ 62 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT( udt ) 2 | cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR) 3 | 4 | if (CMAKE_BUILD_TYPE STREQUAL "Debug") 5 | add_definitions(-D_DEBUG) 6 | endif() 7 | 8 | add_definitions( 9 | -Wall 10 | -D__UNIX 11 | -DPOSIX_C_SOURCE 12 | -DGNU_SOURCE 13 | -Wno-unused-function 14 | -std=c++11 15 | ) 16 | 17 | SET(LIBRARIES 18 | pthread 19 | m 20 | ${ARCAN_SHMIF_LIBRARY} 21 | ) 22 | 23 | set(SOURCES 24 | src/api.cpp 25 | src/buffer.cpp 26 | src/cache.cpp 27 | src/ccc.cpp 28 | src/channel.cpp 29 | src/core.cpp 30 | src/epoll.cpp 31 | src/list.cpp 32 | src/md5.cpp 33 | src/packet.cpp 34 | src/queue.cpp 35 | src/udtCommon.cpp 36 | src/window.cpp 37 | ) 38 | 39 | add_library(${PROJECT_NAME} ${SOURCES}) 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | - UDT Build System - Apache 2.0 License 2 | https://github.com/dorkbox 3 | Copyright 2015, dorkbox, llc 4 | 5 | 6 | 7 | - Barchart UDT - BSD License 8 | https://github.com/barchart/barchart-udt 9 | Copyright 2009-2013, Barchart, Inc. 10 | 11 | 12 | 13 | - UDTv4 - BSD License 14 | http://udt.sourceforge.net/ 15 | Copyright 2001 - 2011, The Board of Trustees of the University of Illinois 16 | -------------------------------------------------------------------------------- /LICENSE.Apachev2: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a 16 | copy of this software and associated documentation files (the "Software"), 17 | to deal in the Software without restriction, including without limitation 18 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 19 | and/or sell copies of the Software, and to permit persons to whom the 20 | Software is furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included 23 | in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 26 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 28 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 30 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 31 | DEALINGS IN THE SOFTWARE. 32 | "Legal Entity" shall mean the union of the acting entity and all 33 | other entities that control, are controlled by, or are under common 34 | control with that entity. For the purposes of this definition, 35 | "control" means (i) the power, direct or indirect, to cause the 36 | direction or management of such entity, whether by contract or 37 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 38 | outstanding shares, or (iii) beneficial ownership of such entity. 39 | 40 | "You" (or "Your") shall mean an individual or Legal Entity 41 | exercising permissions granted by this License. 42 | 43 | "Source" form shall mean the preferred form for making modifications, 44 | including but not limited to software source code, documentation 45 | source, and configuration files. 46 | 47 | "Object" form shall mean any form resulting from mechanical 48 | transformation or translation of a Source form, including but 49 | not limited to compiled object code, generated documentation, 50 | and conversions to other media types. 51 | 52 | "Work" shall mean the work of authorship, whether in Source or 53 | Object form, made available under the License, as indicated by a 54 | copyright notice that is included in or attached to the work 55 | (an example is provided in the Appendix below). 56 | 57 | "Derivative Works" shall mean any work, whether in Source or Object 58 | form, that is based on (or derived from) the Work and for which the 59 | editorial revisions, annotations, elaborations, or other modifications 60 | represent, as a whole, an original work of authorship. For the purposes 61 | of this License, Derivative Works shall not include works that remain 62 | separable from, or merely link (or bind by name) to the interfaces of, 63 | the Work and Derivative Works thereof. 64 | 65 | "Contribution" shall mean any work of authorship, including 66 | the original version of the Work and any modifications or additions 67 | to that Work or Derivative Works thereof, that is intentionally 68 | submitted to Licensor for inclusion in the Work by the copyright owner 69 | or by an individual or Legal Entity authorized to submit on behalf of 70 | the copyright owner. For the purposes of this definition, "submitted" 71 | means any form of electronic, verbal, or written communication sent 72 | to the Licensor or its representatives, including but not limited to 73 | communication on electronic mailing lists, source code control systems, 74 | and issue tracking systems that are managed by, or on behalf of, the 75 | Licensor for the purpose of discussing and improving the Work, but 76 | excluding communication that is conspicuously marked or otherwise 77 | designated in writing by the copyright owner as "Not a Contribution." 78 | 79 | "Contributor" shall mean Licensor and any individual or Legal Entity 80 | on behalf of whom a Contribution has been received by Licensor and 81 | subsequently incorporated within the Work. 82 | 83 | 2. Grant of Copyright License. Subject to the terms and conditions of 84 | this License, each Contributor hereby grants to You a perpetual, 85 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 86 | copyright license to reproduce, prepare Derivative Works of, 87 | publicly display, publicly perform, sublicense, and distribute the 88 | Work and such Derivative Works in Source or Object form. 89 | 90 | 3. Grant of Patent License. Subject to the terms and conditions of 91 | this License, each Contributor hereby grants to You a perpetual, 92 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 93 | (except as stated in this section) patent license to make, have made, 94 | use, offer to sell, sell, import, and otherwise transfer the Work, 95 | where such license applies only to those patent claims licensable 96 | by such Contributor that are necessarily infringed by their 97 | Contribution(s) alone or by combination of their Contribution(s) 98 | with the Work to which such Contribution(s) was submitted. If You 99 | institute patent litigation against any entity (including a 100 | cross-claim or counterclaim in a lawsuit) alleging that the Work 101 | or a Contribution incorporated within the Work constitutes direct 102 | or contributory patent infringement, then any patent licenses 103 | granted to You under this License for that Work shall terminate 104 | as of the date such litigation is filed. 105 | 106 | 4. Redistribution. You may reproduce and distribute copies of the 107 | Work or Derivative Works thereof in any medium, with or without 108 | modifications, and in Source or Object form, provided that You 109 | meet the following conditions: 110 | 111 | (a) You must give any other recipients of the Work or 112 | Derivative Works a copy of this License; and 113 | 114 | (b) You must cause any modified files to carry prominent notices 115 | stating that You changed the files; and 116 | 117 | (c) You must retain, in the Source form of any Derivative Works 118 | that You distribute, all copyright, patent, trademark, and 119 | attribution notices from the Source form of the Work, 120 | excluding those notices that do not pertain to any part of 121 | the Derivative Works; and 122 | 123 | (d) If the Work includes a "NOTICE" text file as part of its 124 | distribution, then any Derivative Works that You distribute must 125 | include a readable copy of the attribution notices contained 126 | within such NOTICE file, excluding those notices that do not 127 | pertain to any part of the Derivative Works, in at least one 128 | of the following places: within a NOTICE text file distributed 129 | as part of the Derivative Works; within the Source form or 130 | documentation, if provided along with the Derivative Works; or, 131 | within a display generated by the Derivative Works, if and 132 | wherever such third-party notices normally appear. The contents 133 | of the NOTICE file are for informational purposes only and 134 | do not modify the License. You may add Your own attribution 135 | notices within Derivative Works that You distribute, alongside 136 | or as an addendum to the NOTICE text from the Work, provided 137 | that such additional attribution notices cannot be construed 138 | as modifying the License. 139 | 140 | You may add Your own copyright statement to Your modifications and 141 | may provide additional or different license terms and conditions 142 | for use, reproduction, or distribution of Your modifications, or 143 | for any such Derivative Works as a whole, provided Your use, 144 | reproduction, and distribution of the Work otherwise complies with 145 | the conditions stated in this License. 146 | 147 | 5. Submission of Contributions. Unless You explicitly state otherwise, 148 | any Contribution intentionally submitted for inclusion in the Work 149 | by You to the Licensor shall be under the terms and conditions of 150 | this License, without any additional terms or conditions. 151 | Notwithstanding the above, nothing herein shall supersede or modify 152 | the terms of any separate license agreement you may have executed 153 | with Licensor regarding such Contributions. 154 | 155 | 6. Trademarks. This License does not grant permission to use the trade 156 | names, trademarks, service marks, or product names of the Licensor, 157 | except as required for reasonable and customary use in describing the 158 | origin of the Work and reproducing the content of the NOTICE file. 159 | 160 | 7. Disclaimer of Warranty. Unless required by applicable law or 161 | agreed to in writing, Licensor provides the Work (and each 162 | Contributor provides its Contributions) on an "AS IS" BASIS, 163 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 164 | implied, including, without limitation, any warranties or conditions 165 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 166 | PARTICULAR PURPOSE. You are solely responsible for determining the 167 | appropriateness of using or redistributing the Work and assume any 168 | risks associated with Your exercise of permissions under this License. 169 | 170 | 8. Limitation of Liability. In no event and under no legal theory, 171 | whether in tort (including negligence), contract, or otherwise, 172 | unless required by applicable law (such as deliberate and grossly 173 | negligent acts) or agreed to in writing, shall any Contributor be 174 | liable to You for damages, including any direct, indirect, special, 175 | incidental, or consequential damages of any character arising as a 176 | result of this License or out of the use or inability to use the 177 | Work (including but not limited to damages for loss of goodwill, 178 | work stoppage, computer failure or malfunction, or any and all 179 | other commercial damages or losses), even if such Contributor 180 | has been advised of the possibility of such damages. 181 | 182 | 9. Accepting Warranty or Additional Liability. While redistributing 183 | the Work or Derivative Works thereof, You may choose to offer, 184 | and charge a fee for, acceptance of support, warranty, indemnity, 185 | or other liability obligations and/or rights consistent with this 186 | License. However, in accepting such obligations, You may act only 187 | on Your own behalf and on Your sole responsibility, not on behalf 188 | of any other Contributor, and only if You agree to indemnify, 189 | defend, and hold each Contributor harmless for any liability 190 | incurred by, or claims asserted against, such Contributor by reason 191 | of your accepting any such warranty or additional liability. 192 | 193 | END OF TERMS AND CONDITIONS 194 | 195 | APPENDIX: How to apply the Apache License to your work. 196 | 197 | To apply the Apache License to your work, attach the following 198 | boilerplate notice, with the fields enclosed by brackets "[]" 199 | replaced with your own identifying information. (Don't include 200 | the brackets!) The text should be enclosed in the appropriate 201 | comment syntax for the file format. We also recommend that a 202 | file or class name and description of purpose be included on the 203 | same "printed page" as the copyright notice for easier 204 | identification within third-party archives. 205 | 206 | Copyright [yyyy] [name of copyright owner] 207 | 208 | Licensed under the Apache License, Version 2.0 (the "License"); 209 | you may not use this file except in compliance with the License. 210 | You may obtain a copy of the License at 211 | 212 | http://www.apache.org/licenses/LICENSE-2.0 213 | 214 | Unless required by applicable law or agreed to in writing, software 215 | distributed under the License is distributed on an "AS IS" BASIS, 216 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 217 | See the License for the specific language governing permissions and 218 | limitations under the License. -------------------------------------------------------------------------------- /LICENSE.BSD: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | * Neither the name of the nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL TINKERPOP BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Breaking the Data Transfer Bottleneck 2 | 3 | UDT is a reliable UDP based application level data transport protocol for distributed data intensive applications 4 | over wide area high-speed networks. UDT uses UDP to transfer bulk data with its own reliability control and 5 | congestion control mechanisms. The new protocol can transfer data at a much higher speed than TCP does. UDT 6 | is also a highly configurable framework that can accommodate various congestion control algorithms. 7 | - Presentation: [PowerPoint](https://github.com/dorkbox/UDT/blob/master/udt-doc/udt-2009.ppt) 8 | - Poster: [PDF](https://github.com/dorkbox/UDT/blob/master/udt-doc/udt-sc08-poster.pdf) 9 | 10 | ### TCP 11 | 12 | TCP is [slow](http://barchart.github.com/barchart-udt/main/presentation-2009/img6.html). 13 | UDT is [fast](http://barchart.github.com/barchart-udt/main/presentation-2009/img9.html). 14 | 15 | ### UDT 16 | 17 | UDT is developed by [Yunhong Gu](http://www.linkedin.com/in/yunhong) and others at University of Illinois and Google. 18 | 19 | UDT C++ implementation is available under [BSD license](http://udt.sourceforge.net/license.html) 20 | 21 | 22 | ### Key Features 23 | 24 | **Fast**. UDT is designed for extremely high speed networks and it has been used to support global data transfer of terabyte sized data sets. UDT is the core technology in many commercial WAN acceleration products. 25 | 26 | **Fair and Friendly**. Concurrent UDT flows can share the available bandwidth fairly, while UDT also leaves enough bandwidth for TCP. 27 | 28 | **Easy to Use**. UDT resides completely at the application level. Users can simply download the software and start to use it. No kernel reconfiguration is needed. In addition, UDT's API is very similar to the traditional socket API so that existing applications can be easily modified. 29 | 30 | **Highly Configurable**. UDT supports user defined congestion control algorithms with a simple configuration. Users may also modify UDT to suit various situations. This feature can also be used by students and researchers to investigate new control algorithms. 31 | 32 | **Firewall Friendly**. UDT is completely based on UDP, which makes it easier to traverse the firewall. In addition, multiple UDT flows can share a single UDP port, thus a firewall can open only one UDP port for all UDT connections. UDT also supports rendezvous connection setup. 33 | 34 | 35 | ### Supported Platforms 36 | 37 | | ARCH/OS | Linux | Mac OSX | Windows | 38 | |--------------|---------|---------|---------| 39 | | arm-android | ??? | | | 40 | | arm-rpi | ??? | | | 41 | | x86/i386 | YES | YES | YES | 42 | | x86-64/amd64 | YES | YES | YES | 43 | 44 | 45 | ### Current Implementation 46 | - Updates to UDT source 4.11 to fix some misc. CPU timing bugs in Linux (via the sourceforge help forum). 47 | - Cleaned up source for cross-compile environment in linux 48 | - Cleaned up preprocessor symbols and removed deprecated 49 | - Strips unneeded symbols, drastically reducing size 50 | - Static linking to mingw libraries for windows build 51 | 52 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #******************************************************************************* 3 | # 4 | # This will build ALL variants! 5 | # 6 | # This expects the following environment variables set: 7 | # 8 | # COMPILE_OS - linux, macosx, windows 9 | # COMPILE_OS_ARCH - 32, 64, arm 10 | # 11 | # 12 | # possible packages you might need in order to compile: 13 | # gcc-4.8 gcc-4.8-multilib g++-4.8-multilib gdb make libgtk2.0-dev libxtst-dev libc6-dev-i386 mingw-w64 14 | # ccache libssl0.9.8 15 | # 16 | # Then, in gcc_apple_amd64 dir: sudo dpkg -i *.deb (this is 64bit gcc to build macosx binaries) 17 | # 18 | # Because we fake the 32bit/arm library calls during compile time (the libs are 19 | # loaded during run time) we can build 32bit/arm builds on a 64bit system without needing multi-arch 20 | # GTK libraries (fyi: there aren't any... and DO NOT install the i386 ones, since they will REMOVE what 21 | # you already have - buggering your system!) 22 | # 23 | # 24 | # 25 | # TODO: clean up below, verify arm builds. 26 | # # arm: gcc-arm-linux-gnueabi gcc-4.8-arm-linux-gnueabihf 27 | # hf or no hf? beaglebone, rasbpi, ODROID-U3, other ARM devices 28 | # 29 | # ARMv7sf needs gcc-arm-linux-gnueabi, ARMv7hf needs gcc-arm-linux-gnueabihf 30 | # 31 | # To compile for the ARMv7 (BeagleBone Black), follow: 32 | # http://www.michaelhleonard.com/cross-compile-for-beaglebone-black/ 33 | # 34 | # for raspi/BBB 35 | # http://www.michaelhleonard.com/cross-compile-for-beaglebone-black/ 36 | # http://derekmolloy.ie/beaglebone/setting-up-eclipse-on-the-beaglebone-for-c-development/ 37 | # http://stackoverflow.com/questions/9324772/cross-compiling-static-c-hello-world-for-android-using-arm-linux-gnueabi-gcc?rq=1 38 | # 39 | # 40 | #for ANY OTHER OS/ARCH, the easiest, and most straight forward method is to use 41 | # crosstool-ng. http://crosstool-ng.org/ 42 | # howto's: 43 | # http://raspberrypi.stackexchange.com/questions/1/how-do-i-build-a-gcc-4-7-toolchain-for-cross-compiling 44 | # http://www.bootc.net/archives/2012/05/26/how-to-build-a-cross-compiler-for-your-raspberry-pi/ 45 | # http://www.ps3devwiki.com/wiki/Cross_Compiling 46 | # 47 | # 48 | ###################################################################### 49 | # as per: http://stackoverflow.com/questions/8937492/what-is-upxs-best-compression-method 50 | # it is NOT a good idea to compress exe's. WHY? Because they run slower, and HDD space is no longer a concern. 51 | # especially since the executable is ~ 500k. 52 | ###################################################################### 53 | # 54 | # Copyright 2015 dorkbox, llc 55 | # 56 | # Licensed under the Apache License, Version 2.0 (the "License"); 57 | # you may not use this file except in compliance with the License. 58 | # You may obtain a copy of the License at 59 | # 60 | # http://www.apache.org/licenses/LICENSE-2.0 61 | # 62 | # Unless required by applicable law or agreed to in writing, software 63 | # distributed under the License is distributed on an "AS IS" BASIS, 64 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 65 | # See the License for the specific language governing permissions and 66 | # limitations under the License. 67 | ###################################################################### 68 | 69 | readonly true=1 yes=1 no=0 false=0 70 | 71 | 72 | BUILD_ENV=`uname -s`-`uname -m` 73 | 74 | 75 | if [[ "$BUILD_ENV" != "Linux-x86_64" ]]; then 76 | echo " ********" 77 | echo " ******** Can ONLY build on [[ $BUILD_ENV ]]" 78 | echo " ********" 79 | return false 80 | fi 81 | 82 | echo " ********" 83 | echo " ******** Build Environment: [[ $BUILD_ENV ]]" 84 | echo " ********" 85 | 86 | export PROGRAM_DEPLOY=true 87 | 88 | ############# 89 | #core function that will build our targets 90 | ############# 91 | build() { 92 | BUILD_TYPE=$1 93 | export COMPILE_OS=$2 94 | export COMPILE_OS_ARCH=$3 95 | 96 | echo " ********" 97 | echo " ******** Building: ${COMPILE_OS}""_""${COMPILE_OS_ARCH}" 98 | echo " ********" 99 | 100 | # compile 101 | make -f $BUILD_TYPE all 102 | } 103 | 104 | 105 | #################################################################### 106 | #################################################################### 107 | #################################################################### 108 | #################################################################### 109 | # DONE WITH FUNCTIONS 110 | #################################################################### 111 | #################################################################### 112 | #################################################################### 113 | BUILD_ALL=false 114 | 115 | if [ -z "$1" ]; then 116 | BUILD_ALL=true 117 | elif [[ "$1" == "all" ]]; then 118 | BUILD_ALL=true 119 | fi 120 | 121 | 122 | # No args will build all. 123 | if [[ $BUILD_ALL == true ]]; then 124 | if [ -z "$1" ]; then 125 | echo " ******** Building linux (32/64), macosx (32/64), windows (32/64)" 126 | echo " ******** Press enter to continue... " 127 | read VARNAME 128 | fi 129 | 130 | # LINUX 131 | build "make_linux.mak" linux 32 132 | build "make_linux.mak" linux 64 133 | 134 | 135 | # WINDOWS 136 | build "make_windows.mak" windows 32 137 | build "make_windows.mak" windows 64 138 | 139 | 140 | # MAC 141 | build "make_macosx.mak" macosx 32 142 | build "make_macosx.mak" macosx 64 143 | else 144 | # LINUX 145 | if [[ "$1" == "linux" ]]; then 146 | echo " ******** Building linux (32/64)" 147 | 148 | build "make_linux.mak" linux 32 149 | build "make_linux.mak" linux 64 150 | elif [[ "$1" == "linux_32" ]]; then 151 | build "make_linux.mak" linux 32 152 | elif [[ "$1" == "linux_64" ]]; then 153 | build "make_linux.mak" linux 64 154 | 155 | # WINDOWS 156 | elif [[ "$1" == "windows" ]]; then 157 | #all 158 | echo " ******** Building windows (32/64)" 159 | 160 | build "make_windows.mak" windows 32 161 | build "make_windows.mak" windows 64 162 | 163 | elif [[ "$1" == "windows_32" ]]; then 164 | build "make_windows.mak" windows 32 165 | elif [[ "$1" == "windows_64" ]]; then 166 | build "make_windows.mak" windows 64 167 | 168 | # MAC 169 | elif [[ "$1" == "macosx" ]]; then 170 | #all 171 | echo " ******** Building macosx (32/64)" 172 | 173 | build "make_macosx.mak" macosx 32 174 | build "make_macosx.mak" macosx 64 175 | elif [[ "$1" == "macosx_32" ]]; then 176 | build "make_macosx.mak" macosx 32 177 | elif [[ "$1" == "macosx_64" ]]; then 178 | build "make_macosx.mak" macosx 64 179 | 180 | else 181 | echo "Please one of the following:" 182 | echo " [all] - builds all of them" 183 | echo "" 184 | echo "linux" 185 | echo " linux [all] - builds 32 and 64 bit linux" 186 | echo " linux_32 [all] - builds 32 bit linux" 187 | echo " linux_64 [all] - builds 64 bit linux" 188 | echo "" 189 | echo "mac" 190 | echo " macosx [all] - builds 32 and 64 bit mac" 191 | echo " macosx_32 [all] - builds 32 bit mac" 192 | echo " macosx_64 [all] - builds 64 bit mac" 193 | echo "" 194 | echo "windows" 195 | echo " windows [all] - builds 32 and 64 bit windows" 196 | echo " windows_32 [all] - builds 32 bit windows" 197 | echo " windows_64 [all] - builds 64 bit windows" 198 | exit 0 199 | fi 200 | fi 201 | 202 | -------------------------------------------------------------------------------- /make_common.mak: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Makefile for creating the app launcher program. 3 | # 4 | # This + parent makefiles expect the following environment variables set: 5 | # 6 | # COMPILE_OS - linux, macosx, windows 7 | # COMPILE_OS_ARCH - 32, 64, arm 8 | # 9 | ################################################################################ 10 | # 11 | # Copyright 2015 dorkbox, llc 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | ###################################################################### 25 | 26 | 27 | CORE_NAME=libudt-2.3.2 28 | TARGET_PATH=dist 29 | JVM=jvm 30 | 31 | 32 | #setup architecture and path parameters 33 | ifeq ($(COMPILE_OS_ARCH),32) 34 | CCFLAGS +=-DI386 35 | M_ARCH=-m32 36 | DIST_OS_NAME=$(COMPILE_OS)_32 37 | else ifeq ($(COMPILE_OS_ARCH),64) 38 | CCFLAGS +=-DAMD64 39 | M_ARCH=-m64 40 | DIST_OS_NAME=$(COMPILE_OS)_64 41 | else ifeq ($(COMPILE_OS_ARCH),ARM) 42 | #todo finish filling this out 43 | CCFLAGS +=-DARM 44 | endif 45 | 46 | 47 | # mingw doesn't support the M_ARCH flag. 48 | ifeq ($(COMPILE_OS),windows) 49 | M_ARCH = 50 | endif 51 | 52 | CCFLAGS +=${M_ARCH} 53 | 54 | #Makes it small AND FAST 55 | CCFLAGS +=-O2 56 | 57 | ifneq ($(COMPILE_OS),macosx) 58 | CCFLAGS +=-flto 59 | endif 60 | 61 | # warnings and speed/space tricks 62 | FLAGS += \ 63 | -P -ftrapv -funroll-loops -fno-strict-aliasing \ 64 | -fvisibility=hidden -fvisibility-inlines-hidden -finline-functions \ 65 | -Wextra -Wshadow -Wpointer-arith -Wcast-align \ 66 | -Wstrict-overflow=5 -Wsign-compare 67 | 68 | ifneq ($(COMPILE_OS),windows) 69 | CCFLAGS +=-fPIC 70 | endif 71 | 72 | 73 | #common path includes 74 | CCFLAGS += \ 75 | -Isrc/ 76 | 77 | UDT_OBJS = api.o buffer.o cache.o ccc.o channel.o udtCommon.o core.o epoll.o list.o md5.o packet.o queue.o window.o 78 | 79 | $(UDT_OBJS): %.o: src/%.cpp src/%.h src/udt.h 80 | @$(CPP) $(CCFLAGS) $< -c 81 | 82 | lib: $(UDT_OBJS) 83 | @$(CPP) $(CCFLAGS) $(LDFLAGS) -o $(DIST_NAME) $^ $(LIBS) 84 | 85 | udt: lib 86 | 87 | dist-clean: clean 88 | @rm -f *.dll *.so *.dylib 89 | 90 | clean: 91 | @rm -f *.o *.a 92 | 93 | -------------------------------------------------------------------------------- /make_linux.mak: -------------------------------------------------------------------------------- 1 | #******************************************************************************* 2 | # Makefile for creating the GTK launcher program. 3 | # 4 | # This makefile expects the utility "pkg-config" to be in the PATH. 5 | # 6 | # This makefile expect the following environment variables set: 7 | # 8 | # COMPILE_OS - linux, macosx, windows 9 | # COMPILE_OS_ARCH - 32, 64, arm 10 | #******************************************************************************* 11 | # 12 | # Copyright 2015 dorkbox, llc 13 | # 14 | # Licensed under the Apache License, Version 2.0 (the "License"); 15 | # you may not use this file except in compliance with the License. 16 | # You may obtain a copy of the License at 17 | # 18 | # http://www.apache.org/licenses/LICENSE-2.0 19 | # 20 | # Unless required by applicable law or agreed to in writing, software 21 | # distributed under the License is distributed on an "AS IS" BASIS, 22 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | # See the License for the specific language governing permissions and 24 | # limitations under the License. 25 | ###################################################################### 26 | 27 | 28 | include make_common.mak 29 | 30 | DIST_NAME=$(CORE_NAME).so 31 | DIST_PATH=linux_$(COMPILE_OS_ARCH) 32 | 33 | CPP=g++ 34 | STRIP=strip 35 | 36 | LDFLAGS = -shared 37 | LIBS = -lpthread -ldl -lm 38 | 39 | CCFLAGS += \ 40 | -DLINUX \ 41 | -isystem/usr/include \ 42 | -pthread \ 43 | 44 | all: dist-clean udt 45 | @echo "\nDONE WITH COMPILE...." 46 | $(STRIP) --strip-debug --strip-unneeded $(DIST_NAME) 47 | @mkdir -p "$(TARGET_PATH)/$(DIST_OS_NAME)" 48 | mv "$(DIST_NAME)" "$(TARGET_PATH)/$(DIST_OS_NAME)" 49 | @# now cleanup 50 | @$(MAKE) -s -f make_common.mak clean 51 | 52 | -------------------------------------------------------------------------------- /make_macosx.mak: -------------------------------------------------------------------------------- 1 | #********************************************************************** 2 | # Makefile for creating the Carbon eclipse launcher program. 3 | # 4 | # This makefile expects the following environment variables set: 5 | # 6 | # cross compile libs from : https://launchpad.net/~flosoft/+archive/cross-apple/+packages 7 | # 8 | # This makefile expect the following environment variables set: 9 | # 10 | # COMPILE_OS - linux, macosx, windows 11 | # COMPILE_OS_ARCH - 32, 64, arm 12 | #******************************************************************************* 13 | # 14 | # Copyright 2015 dorkbox, llc 15 | # 16 | # Licensed under the Apache License, Version 2.0 (the "License"); 17 | # you may not use this file except in compliance with the License. 18 | # You may obtain a copy of the License at 19 | # 20 | # http://www.apache.org/licenses/LICENSE-2.0 21 | # 22 | # Unless required by applicable law or agreed to in writing, software 23 | # distributed under the License is distributed on an "AS IS" BASIS, 24 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | # See the License for the specific language governing permissions and 26 | # limitations under the License. 27 | ###################################################################### 28 | 29 | 30 | include make_common.mak 31 | 32 | DIST_NAME=$(CORE_NAME).dylib 33 | DIST_PATH=macosx_$(COMPILE_OS_ARCH) 34 | 35 | CPP=i686-apple-darwin10-g++ 36 | STRIP=i686-apple-darwin10-strip 37 | 38 | LDFLAGS = -shared -dynamiclib -compatibility_version 1.0 -current_version 1.0 -mmacosx-version-min=10.5 39 | LIBS = -lpthread -lm 40 | 41 | #setup architecture parameters 42 | ifeq ($(COMPILE_OS_ARCH),32) 43 | CCFLAGS += -arch i386 44 | else 45 | MACOSX_IS_64BIT=true 46 | CCFLAGS += -arch x86_64 47 | endif 48 | 49 | CCFLAGS += -DMACOSX 50 | 51 | all: dist-clean udt 52 | @echo "\nDONE WITH COMPILE...." 53 | @mkdir -p "$(TARGET_PATH)/$(DIST_OS_NAME)" 54 | mv "$(DIST_NAME)" "$(TARGET_PATH)/$(DIST_OS_NAME)" 55 | @# now cleanup 56 | @$(MAKE) -s -f make_common.mak clean 57 | 58 | -------------------------------------------------------------------------------- /make_windows.mak: -------------------------------------------------------------------------------- 1 | #******************************************************************************* 2 | # Makefile for creating the launcher program. 3 | # 4 | # This makefile expects the following environment variables set: 5 | # 6 | # Allow for cross-compiling under linux. 7 | # USES mingw-w64 !!!! (NOT mingw32, which is deprecated) 8 | # 9 | #******************************************************************************* 10 | # 11 | # Copyright 2015 dorkbox, llc 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | ###################################################################### 25 | 26 | include make_common.mak 27 | 28 | DIST_NAME=$(CORE_NAME).dll 29 | DIST_PATH=windows_$(COMPILE_OS_ARCH) 30 | 31 | ifeq ($(COMPILE_OS_ARCH),32) 32 | MINGVER = i686 33 | #mingw flags 34 | CCFLAGS +=-DWINVER=0x0501 35 | 36 | #32 bit support is XP+ 37 | CCFLAGS +=-D_WIN32_WINNT=0x0501 38 | else 39 | MINGVER = x86_64 40 | #mingw flags 41 | CCFLAGS +=-DWINVER=0x0600 42 | 43 | #64 bit support is vista+ ONLY 44 | CCFLAGS +=-D_WIN32_WINNT=0x0600 45 | endif 46 | 47 | CPP = $(shell which $(MINGVER)-w64-mingw32-g++) 48 | STRIP = $(shell which $(MINGVER)-w64-mingw32-strip) 49 | 50 | 51 | LDFLAGS = -shared -static -static-libgcc -static-libstdc++ -Wl,--kill-at 52 | LIBS = -lkernel32 -luser32 -lws2_32 53 | 54 | CCFLAGS += \ 55 | -isystem/usr/$(MINGVER)-w64-mingw32/include \ 56 | -DWINDOWS \ 57 | 58 | all: dist-clean udt 59 | @echo "\nDONE WITH COMPILE...." 60 | @# now cleanup 61 | @# now strip the DLL of unneeded, since it can be HUGE 62 | $(STRIP) --strip-debug --strip-unneeded $(DIST_NAME) 63 | @mkdir -p "$(TARGET_PATH)/$(DIST_OS_NAME)" 64 | mv "$(DIST_NAME)" "$(TARGET_PATH)/$(DIST_OS_NAME)" 65 | @$(MAKE) -s -f make_common.mak clean 66 | 67 | -------------------------------------------------------------------------------- /src/api.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 09/28/2010 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_API_H__ 42 | #define __UDT_API_H__ 43 | 44 | 45 | #include 46 | #include 47 | #include "udt.h" 48 | #include "packet.h" 49 | #include "queue.h" 50 | #include "cache.h" 51 | #include "epoll.h" 52 | 53 | class CUDT; 54 | 55 | class CUDTSocket 56 | { 57 | public: 58 | CUDTSocket(); 59 | ~CUDTSocket(); 60 | 61 | UDTSTATUS m_Status; // current socket state 62 | 63 | uint64_t m_TimeStamp; // time when the socket is closed 64 | 65 | int m_iIPversion; // IP version 66 | sockaddr* m_pSelfAddr; // pointer to the local address of the socket 67 | sockaddr* m_pPeerAddr; // pointer to the peer address of the socket 68 | 69 | UDTSOCKET m_SocketID; // socket ID 70 | UDTSOCKET m_ListenSocket; // ID of the listener socket; 0 means this is an independent socket 71 | 72 | UDTSOCKET m_PeerID; // peer socket ID 73 | int32_t m_iISN; // initial sequence number, used to tell different connection from same IP:port 74 | 75 | CUDT* m_pUDT; // pointer to the UDT entity 76 | 77 | std::set* m_pQueuedSockets; // set of connections waiting for accept() 78 | std::set* m_pAcceptSockets; // set of accept()ed connections 79 | 80 | udt_pthread_cond_t m_AcceptCond; // used to block "accept" call 81 | udt_pthread_mutex_t m_AcceptLock; // mutex associated to m_AcceptCond 82 | 83 | unsigned int m_uiBackLog; // maximum number of connections in queue 84 | 85 | int m_iMuxID; // multiplexer ID 86 | 87 | udt_pthread_mutex_t m_ControlLock; // lock this socket exclusively for control APIs: bind/listen/connect 88 | 89 | private: 90 | CUDTSocket(const CUDTSocket&); 91 | CUDTSocket& operator=(const CUDTSocket&); 92 | }; 93 | 94 | //////////////////////////////////////////////////////////////////////////////// 95 | 96 | class CUDTUnited 97 | { 98 | friend class CUDT; 99 | friend class CRendezvousQueue; 100 | 101 | public: 102 | CUDTUnited(); 103 | ~CUDTUnited(); 104 | 105 | public: 106 | 107 | // Functionality: 108 | // initialize the UDT library. 109 | // Parameters: 110 | // None. 111 | // Returned value: 112 | // 0 if success, otherwise -1 is returned. 113 | 114 | int startup(); 115 | 116 | // Functionality: 117 | // release the UDT library. 118 | // Parameters: 119 | // None. 120 | // Returned value: 121 | // 0 if success, otherwise -1 is returned. 122 | 123 | int cleanup(); 124 | 125 | // Functionality: 126 | // Create a new UDT socket. 127 | // Parameters: 128 | // 0) [in] af: IP version, IPv4 (AF_INET) or IPv6 (AF_INET6). 129 | // 1) [in] type: socket type, SOCK_STREAM or SOCK_DGRAM 130 | // Returned value: 131 | // The new UDT socket ID, or INVALID_SOCK. 132 | 133 | UDTSOCKET newSocket(int af, int type); 134 | 135 | // Functionality: 136 | // Create a new UDT connection. 137 | // Parameters: 138 | // 0) [in] listen: the listening UDT socket; 139 | // 1) [in] peer: peer address. 140 | // 2) [in/out] hs: handshake information from peer side (in), negotiated value (out); 141 | // Returned value: 142 | // If the new connection is successfully created: 1 success, 0 already exist, -1 error. 143 | 144 | int newConnection(const UDTSOCKET listen, const sockaddr* peer, CHandShake* hs); 145 | 146 | // Functionality: 147 | // look up the UDT entity according to its ID. 148 | // Parameters: 149 | // 0) [in] u: the UDT socket ID. 150 | // Returned value: 151 | // Pointer to the UDT entity. 152 | 153 | CUDT* lookup(const UDTSOCKET u); 154 | 155 | // Functionality: 156 | // Check the status of the UDT socket. 157 | // Parameters: 158 | // 0) [in] u: the UDT socket ID. 159 | // Returned value: 160 | // UDT socket status, or NONEXIST if not found. 161 | 162 | UDTSTATUS getStatus(const UDTSOCKET u); 163 | 164 | // socket APIs 165 | 166 | int bind(const UDTSOCKET u, const sockaddr* name, int namelen); 167 | int bind(const UDTSOCKET u, UDPSOCKET udpsock); 168 | int listen(const UDTSOCKET u, int backlog); 169 | UDTSOCKET accept(const UDTSOCKET listen, sockaddr* addr, int* addrlen); 170 | int connect(const UDTSOCKET u, const sockaddr* name, int namelen); 171 | int flush(const UDTSOCKET u); 172 | int close(const UDTSOCKET u); 173 | int getpeername(const UDTSOCKET u, sockaddr* name, int* namelen); 174 | int getsockname(const UDTSOCKET u, sockaddr* name, int* namelen); 175 | int select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout); 176 | int selectEx(const std::vector& fds, std::vector* readfds, std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); 177 | int epoll_create(); 178 | int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events = NULL); 179 | int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); 180 | int epoll_remove_usock(const int eid, const UDTSOCKET u); 181 | int epoll_remove_ssock(const int eid, const SYSSOCKET s); 182 | int epoll_wait(const int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, std::set* lrfds = NULL, std::set* lwfds = NULL); 183 | int epoll_release(const int eid); 184 | 185 | // BARCHART 186 | int epoll_update_usock(const int eid, const UDTSOCKET u, const int* events = NULL); 187 | // BARCHART 188 | int epoll_verify_usock(const int eid, const UDTSOCKET u, int* events); 189 | 190 | // Functionality: 191 | // record the UDT exception. 192 | // Parameters: 193 | // 0) [in] e: pointer to a UDT exception instance. 194 | // Returned value: 195 | // None. 196 | 197 | void setError(CUDTException* e); 198 | 199 | // Functionality: 200 | // look up the most recent UDT exception. 201 | // Parameters: 202 | // None. 203 | // Returned value: 204 | // pointer to a UDT exception instance. 205 | 206 | CUDTException* getError(); 207 | 208 | private: 209 | // void init(); 210 | 211 | private: 212 | std::map m_Sockets; // stores all the socket structures 213 | 214 | udt_pthread_mutex_t m_ControlLock; // used to synchronize UDT API 215 | 216 | udt_pthread_mutex_t m_IDLock; // used to synchronize ID generation 217 | UDTSOCKET m_SocketID; // seed to generate a new unique socket ID 218 | 219 | std::map > m_PeerRec;// record sockets from peers to avoid repeated connection request, int64_t = (socker_id << 30) + isn 220 | 221 | private: 222 | udt_pthread_key_t m_TLSError; // thread local error record (last error) 223 | #ifndef WINDOWS 224 | static void TLSDestroy(void* e) {if (NULL != e) delete (CUDTException*)e;} 225 | #else 226 | std::map m_mTLSRecord; 227 | void checkTLSValue(); 228 | udt_pthread_mutex_t m_TLSLock; 229 | #endif 230 | 231 | private: 232 | void connect_complete(const UDTSOCKET u); 233 | CUDTSocket* locate(const UDTSOCKET u); 234 | CUDTSocket* locate(const sockaddr* peer, const UDTSOCKET id, int32_t isn); 235 | void updateMux(CUDTSocket* s, const sockaddr* addr = NULL, const UDPSOCKET* = NULL); 236 | void updateMux(CUDTSocket* s, const CUDTSocket* ls); 237 | 238 | private: 239 | std::map m_mMultiplexer; // UDP multiplexer 240 | udt_pthread_mutex_t m_MultiplexerLock; 241 | 242 | private: 243 | CCache* m_pCache; // UDT network information cache 244 | 245 | private: 246 | volatile bool m_bClosing; 247 | udt_pthread_mutex_t m_GCStopLock; 248 | udt_pthread_cond_t m_GCStopCond; 249 | 250 | udt_pthread_mutex_t m_InitLock; 251 | int m_iInstanceCount; // number of startup() called by application 252 | bool m_bGCStatus; // if the GC thread is working (true) 253 | 254 | udt_pthread_t m_GCThread; 255 | #ifndef WINDOWS 256 | static void* garbageCollect(void*); 257 | #else 258 | static DWORD WINAPI garbageCollect(LPVOID); 259 | #endif 260 | 261 | std::map m_ClosedSockets; // temporarily store closed sockets 262 | 263 | void checkBrokenSockets(); 264 | void removeSocket(const UDTSOCKET u); 265 | 266 | private: 267 | CEPoll m_EPoll; // handling epoll data structures and events 268 | 269 | private: 270 | CUDTUnited(const CUDTUnited&); 271 | CUDTUnited& operator=(const CUDTUnited&); 272 | }; 273 | 274 | #endif 275 | -------------------------------------------------------------------------------- /src/buffer.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 05/05/2009 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_BUFFER_H__ 42 | #define __UDT_BUFFER_H__ 43 | 44 | 45 | #include "udt.h" 46 | #include "list.h" 47 | #include "queue.h" 48 | #include 49 | 50 | class CSndBuffer 51 | { 52 | public: 53 | CSndBuffer(int size = 32, int mss = 1500); 54 | ~CSndBuffer(); 55 | 56 | // Functionality: 57 | // Insert a user buffer into the sending list. 58 | // Parameters: 59 | // 0) [in] data: pointer to the user data block. 60 | // 1) [in] len: size of the block. 61 | // 2) [in] ttl: time to live in milliseconds 62 | // 3) [in] order: if the block should be delivered in order, for DGRAM only 63 | // Returned value: 64 | // None. 65 | 66 | void addBuffer(const char* data, int len, int ttl = -1, bool order = false); 67 | 68 | // Functionality: 69 | // Read a block of data from file and insert it into the sending list. 70 | // Parameters: 71 | // 0) [in] ifs: input file stream. 72 | // 1) [in] len: size of the block. 73 | // Returned value: 74 | // actual size of data added from the file. 75 | 76 | int addBufferFromFile(std::fstream& ifs, int len); 77 | 78 | // Functionality: 79 | // Find data position to pack a DATA packet from the furthest reading point. 80 | // Parameters: 81 | // 0) [out] data: the pointer to the data position. 82 | // 1) [out] msgno: message number of the packet. 83 | // Returned value: 84 | // Actual length of data read. 85 | 86 | int readData(char** data, int32_t& msgno); 87 | 88 | // Functionality: 89 | // Find data position to pack a DATA packet for a retransmission. 90 | // Parameters: 91 | // 0) [out] data: the pointer to the data position. 92 | // 1) [in] offset: offset from the last ACK point. 93 | // 2) [out] msgno: message number of the packet. 94 | // 3) [out] msglen: length of the message 95 | // Returned value: 96 | // Actual length of data read. 97 | 98 | int readData(char** data, const int offset, int32_t& msgno, int& msglen); 99 | 100 | // Functionality: 101 | // Update the ACK point and may release/unmap/return the user data according to the flag. 102 | // Parameters: 103 | // 0) [in] offset: number of packets acknowledged. 104 | // Returned value: 105 | // None. 106 | 107 | void ackData(int offset); 108 | 109 | // Functionality: 110 | // Read size of data still in the sending list. 111 | // Parameters: 112 | // None. 113 | // Returned value: 114 | // Current size of the data in the sending list. 115 | 116 | int getCurrBufSize() const; 117 | 118 | private: 119 | void increase(); 120 | 121 | private: 122 | udt_pthread_mutex_t m_BufLock; // used to synchronize buffer operation 123 | 124 | struct Block 125 | { 126 | char* m_pcData; // pointer to the data block 127 | int m_iLength; // length of the block 128 | 129 | int32_t m_iMsgNo; // message number 130 | uint64_t m_OriginTime; // original request time 131 | int m_iTTL; // time to live (milliseconds) 132 | 133 | Block* m_pNext; // next block 134 | } *m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock; 135 | 136 | // m_pBlock: The head pointer 137 | // m_pFirstBlock: The first block 138 | // m_pCurrBlock: The current block 139 | // m_pLastBlock: The last block (if first == last, buffer is empty) 140 | 141 | struct Buffer 142 | { 143 | char* m_pcData; // buffer 144 | int m_iSize; // size 145 | Buffer* m_pNext; // next buffer 146 | } *m_pBuffer; // physical buffer 147 | 148 | int32_t m_iNextMsgNo; // next message number 149 | 150 | int m_iSize; // buffer size (number of packets) 151 | int m_iMSS; // maximum seqment/packet size 152 | 153 | int m_iCount; // number of used blocks 154 | 155 | private: 156 | CSndBuffer(const CSndBuffer&); 157 | CSndBuffer& operator=(const CSndBuffer&); 158 | }; 159 | 160 | //////////////////////////////////////////////////////////////////////////////// 161 | 162 | class CRcvBuffer 163 | { 164 | public: 165 | CRcvBuffer(CUnitQueue* queue, int bufsize = 65536); 166 | ~CRcvBuffer(); 167 | 168 | // Functionality: 169 | // Write data into the buffer. 170 | // Parameters: 171 | // 0) [in] unit: pointer to a data unit containing new packet 172 | // 1) [in] offset: offset from last ACK point. 173 | // Returned value: 174 | // 0 is success, -1 if data is repeated. 175 | 176 | int addData(CUnit* unit, int offset); 177 | 178 | // Functionality: 179 | // Read data into a user buffer. 180 | // Parameters: 181 | // 0) [in] data: pointer to user buffer. 182 | // 1) [in] len: length of user buffer. 183 | // Returned value: 184 | // size of data read. 185 | 186 | int readBuffer(char* data, int len); 187 | 188 | // Functionality: 189 | // Read data directly into file. 190 | // Parameters: 191 | // 0) [in] file: C++ file stream. 192 | // 1) [in] len: expected length of data to write into the file. 193 | // Returned value: 194 | // size of data read. 195 | 196 | int readBufferToFile(std::fstream& ofs, int len); 197 | 198 | // Functionality: 199 | // Update the ACK point of the buffer. 200 | // Parameters: 201 | // 0) [in] len: size of data to be acknowledged. 202 | // Returned value: 203 | // 1 if a user buffer is fulfilled, otherwise 0. 204 | 205 | void ackData(int len); 206 | 207 | // Functionality: 208 | // Query how many buffer space left for data receiving. 209 | // Parameters: 210 | // None. 211 | // Returned value: 212 | // size of available buffer space (including user buffer) for data receiving. 213 | 214 | int getAvailBufSize() const; 215 | 216 | // Functionality: 217 | // Query how many data has been continuously received (for reading). 218 | // Parameters: 219 | // None. 220 | // Returned value: 221 | // size of valid (continous) data for reading. 222 | 223 | int getRcvDataSize() const; 224 | 225 | // Functionality: 226 | // mark the message to be dropped from the message list. 227 | // Parameters: 228 | // 0) [in] msgno: message nuumer. 229 | // Returned value: 230 | // None. 231 | 232 | void dropMsg(int32_t msgno); 233 | 234 | // Functionality: 235 | // read a message. 236 | // Parameters: 237 | // 0) [out] data: buffer to write the message into. 238 | // 1) [in] len: size of the buffer. 239 | // Returned value: 240 | // actuall size of data read. 241 | 242 | int readMsg(char* data, int len); 243 | 244 | // Functionality: 245 | // Query how many messages are available now. 246 | // Parameters: 247 | // None. 248 | // Returned value: 249 | // number of messages available for recvmsg. 250 | 251 | int getRcvMsgNum(); 252 | 253 | private: 254 | bool scanMsg(int& start, int& end, bool& passack); 255 | 256 | private: 257 | CUnit** m_pUnit; // pointer to the protocol buffer 258 | int m_iSize; // size of the protocol buffer 259 | CUnitQueue* m_pUnitQueue; // the shared unit queue 260 | 261 | int m_iStartPos; // the head position for I/O (inclusive) 262 | int m_iLastAckPos; // the last ACKed position (exclusive) 263 | // EMPTY: m_iStartPos = m_iLastAckPos FULL: m_iStartPos = m_iLastAckPos + 1 264 | int m_iMaxPos; // the furthest data position 265 | 266 | int m_iNotch; // the starting read point of the first unit 267 | 268 | private: 269 | CRcvBuffer(); 270 | CRcvBuffer(const CRcvBuffer&); 271 | CRcvBuffer& operator=(const CRcvBuffer&); 272 | }; 273 | 274 | 275 | #endif 276 | -------------------------------------------------------------------------------- /src/cache.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 05/05/2009 39 | *****************************************************************************/ 40 | 41 | #ifdef WINDOWS 42 | #include 43 | #include 44 | #include 45 | #endif 46 | 47 | #include 48 | #include "cache.h" 49 | #include "core.h" 50 | 51 | using namespace std; 52 | 53 | CInfoBlock& CInfoBlock::operator=(const CInfoBlock& obj) 54 | { 55 | std::copy(obj.m_piIP, obj.m_piIP + 3, m_piIP); 56 | m_iIPversion = obj.m_iIPversion; 57 | m_ullTimeStamp = obj.m_ullTimeStamp; 58 | m_iRTT = obj.m_iRTT; 59 | m_iBandwidth = obj.m_iBandwidth; 60 | m_iLossRate = obj.m_iLossRate; 61 | m_iReorderDistance = obj.m_iReorderDistance; 62 | m_dInterval = obj.m_dInterval; 63 | m_dCWnd = obj.m_dCWnd; 64 | 65 | return *this; 66 | } 67 | 68 | bool CInfoBlock::operator==(const CInfoBlock& obj) 69 | { 70 | if (m_iIPversion != obj.m_iIPversion) 71 | return false; 72 | 73 | else if (m_iIPversion == AF_INET) 74 | return (m_piIP[0] == obj.m_piIP[0]); 75 | 76 | for (int i = 0; i < 4; ++ i) 77 | { 78 | if (m_piIP[i] != obj.m_piIP[i]) 79 | return false; 80 | } 81 | 82 | return true; 83 | } 84 | 85 | CInfoBlock* CInfoBlock::clone() 86 | { 87 | CInfoBlock* obj = new CInfoBlock; 88 | 89 | std::copy(m_piIP, m_piIP + 3, obj->m_piIP); 90 | obj->m_iIPversion = m_iIPversion; 91 | obj->m_ullTimeStamp = m_ullTimeStamp; 92 | obj->m_iRTT = m_iRTT; 93 | obj->m_iBandwidth = m_iBandwidth; 94 | obj->m_iLossRate = m_iLossRate; 95 | obj->m_iReorderDistance = m_iReorderDistance; 96 | obj->m_dInterval = m_dInterval; 97 | obj->m_dCWnd = m_dCWnd; 98 | 99 | return obj; 100 | } 101 | 102 | int CInfoBlock::getKey() 103 | { 104 | if (m_iIPversion == AF_INET) 105 | return m_piIP[0]; 106 | 107 | return m_piIP[0] + m_piIP[1] + m_piIP[2] + m_piIP[3]; 108 | } 109 | 110 | void CInfoBlock::convert(const sockaddr* addr, int ver, uint32_t ip[]) 111 | { 112 | if (ver == AF_INET) 113 | { 114 | ip[0] = ((sockaddr_in*)addr)->sin_addr.s_addr; 115 | ip[1] = ip[2] = ip[3] = 0; 116 | } 117 | else 118 | { 119 | memcpy((char*)ip, (char*)((sockaddr_in6*)addr)->sin6_addr.s6_addr, 16); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/cache.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/27/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_CACHE_H__ 42 | #define __UDT_CACHE_H__ 43 | 44 | #include 45 | #include 46 | 47 | #include "udtCommon.h" 48 | #include "udt.h" 49 | 50 | class CCacheItem 51 | { 52 | public: 53 | virtual ~CCacheItem() {} 54 | 55 | public: 56 | virtual CCacheItem& operator=(const CCacheItem&) = 0; 57 | 58 | // The "==" operator SHOULD only compare key values. 59 | virtual bool operator==(const CCacheItem&) = 0; 60 | 61 | // Functionality: 62 | // get a deep copy clone of the current item 63 | // Parameters: 64 | // None. 65 | // Returned value: 66 | // Pointer to the new item, or NULL if failed. 67 | 68 | virtual CCacheItem* clone() = 0; 69 | 70 | // Functionality: 71 | // get a random key value between 0 and MAX_INT to be used for the hash in cache 72 | // Parameters: 73 | // None. 74 | // Returned value: 75 | // A random hash key. 76 | 77 | virtual int getKey() = 0; 78 | 79 | // If there is any shared resources between the cache item and its clone, 80 | // the shared resource should be released by this function. 81 | virtual void release() {} 82 | }; 83 | 84 | template class CCache 85 | { 86 | public: 87 | CCache(int size = 1024): 88 | m_iMaxSize(size), 89 | m_iHashSize(size * 3), 90 | m_iCurrSize(0) 91 | { 92 | m_vHashPtr.resize(m_iHashSize); 93 | CGuard::createMutex(m_Lock); 94 | } 95 | 96 | ~CCache() 97 | { 98 | clear(); 99 | CGuard::releaseMutex(m_Lock); 100 | } 101 | 102 | public: 103 | // Functionality: 104 | // find the matching item in the cache. 105 | // Parameters: 106 | // 0) [in/out] data: storage for the retrieved item; initially it must carry the key information 107 | // Returned value: 108 | // 0 if found a match, otherwise -1. 109 | 110 | int lookup(T* data) 111 | { 112 | CGuard cacheguard(m_Lock); 113 | 114 | int key = data->getKey(); 115 | if (key < 0) 116 | return -1; 117 | if (key >= m_iMaxSize) 118 | key %= m_iHashSize; 119 | 120 | const ItemPtrList& item_list = m_vHashPtr[key]; 121 | for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i) 122 | { 123 | if (*data == ***i) 124 | { 125 | // copy the cached info 126 | *data = ***i; 127 | return 0; 128 | } 129 | } 130 | 131 | return -1; 132 | } 133 | 134 | // Functionality: 135 | // update an item in the cache, or insert one if it doesn't exist; oldest item may be removed 136 | // Parameters: 137 | // 0) [in] data: the new item to updated/inserted to the cache 138 | // Returned value: 139 | // 0 if success, otherwise -1. 140 | 141 | int update(T* data) 142 | { 143 | CGuard cacheguard(m_Lock); 144 | 145 | int key = data->getKey(); 146 | if (key < 0) 147 | return -1; 148 | if (key >= m_iMaxSize) 149 | key %= m_iHashSize; 150 | 151 | T* curr = NULL; 152 | 153 | ItemPtrList& item_list = m_vHashPtr[key]; 154 | for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i) 155 | { 156 | if (*data == ***i) 157 | { 158 | // update the existing entry with the new value 159 | ***i = *data; 160 | curr = **i; 161 | 162 | // remove the current entry 163 | m_StorageList.erase(*i); 164 | item_list.erase(i); 165 | 166 | // re-insert to the front 167 | m_StorageList.push_front(curr); 168 | item_list.push_front(m_StorageList.begin()); 169 | 170 | return 0; 171 | } 172 | } 173 | 174 | // create new entry and insert to front 175 | curr = data->clone(); 176 | m_StorageList.push_front(curr); 177 | item_list.push_front(m_StorageList.begin()); 178 | 179 | ++ m_iCurrSize; 180 | if (m_iCurrSize >= m_iMaxSize) 181 | { 182 | // Cache overflow, remove oldest entry. 183 | T* last_data = m_StorageList.back(); 184 | int last_key = last_data->getKey() % m_iHashSize; 185 | 186 | item_list = m_vHashPtr[last_key]; 187 | for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i) 188 | { 189 | if (*last_data == ***i) 190 | { 191 | item_list.erase(i); 192 | break; 193 | } 194 | } 195 | 196 | last_data->release(); 197 | delete last_data; 198 | m_StorageList.pop_back(); 199 | -- m_iCurrSize; 200 | } 201 | 202 | return 0; 203 | } 204 | 205 | // Functionality: 206 | // Specify the cache size (i.e., max number of items). 207 | // Parameters: 208 | // 0) [in] size: max cache size. 209 | // Returned value: 210 | // None. 211 | 212 | void setSizeLimit(int size) 213 | { 214 | m_iMaxSize = size; 215 | m_iHashSize = size * 3; 216 | m_vHashPtr.resize(m_iHashSize); 217 | } 218 | 219 | // Functionality: 220 | // Clear all entries in the cache, restore to initialization state. 221 | // Parameters: 222 | // None. 223 | // Returned value: 224 | // None. 225 | 226 | void clear() 227 | { 228 | for (typename std::list::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i) 229 | { 230 | (*i)->release(); 231 | delete *i; 232 | } 233 | m_StorageList.clear(); 234 | for (typename std::vector::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i) 235 | i->clear(); 236 | m_iCurrSize = 0; 237 | } 238 | 239 | private: 240 | std::list m_StorageList; 241 | typedef typename std::list::iterator ItemPtr; 242 | typedef std::list ItemPtrList; 243 | std::vector m_vHashPtr; 244 | 245 | int m_iMaxSize; 246 | int m_iHashSize; 247 | int m_iCurrSize; 248 | 249 | udt_pthread_mutex_t m_Lock; 250 | 251 | private: 252 | CCache(const CCache&); 253 | CCache& operator=(const CCache&); 254 | }; 255 | 256 | 257 | class CInfoBlock 258 | { 259 | public: 260 | uint32_t m_piIP[4]; // IP address, machine read only, not human readable format 261 | int m_iIPversion; // IP version 262 | uint64_t m_ullTimeStamp; // last update time 263 | int m_iRTT; // RTT 264 | int m_iBandwidth; // estimated bandwidth 265 | int m_iLossRate; // average loss rate 266 | int m_iReorderDistance; // packet reordering distance 267 | double m_dInterval; // inter-packet time, congestion control 268 | double m_dCWnd; // congestion window size, congestion control 269 | 270 | public: 271 | virtual ~CInfoBlock() {} 272 | virtual CInfoBlock& operator=(const CInfoBlock& obj); 273 | virtual bool operator==(const CInfoBlock& obj); 274 | virtual CInfoBlock* clone(); 275 | virtual int getKey(); 276 | virtual void release() {} 277 | 278 | public: 279 | 280 | // Functionality: 281 | // convert sockaddr structure to an integer array 282 | // Parameters: 283 | // 0) [in] addr: network address 284 | // 1) [in] ver: IP version 285 | // 2) [out] ip: the result machine readable IP address in integer array 286 | // Returned value: 287 | // None. 288 | 289 | static void convert(const sockaddr* addr, int ver, uint32_t ip[]); 290 | }; 291 | 292 | 293 | #endif 294 | -------------------------------------------------------------------------------- /src/ccc.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 02/28/2012 39 | *****************************************************************************/ 40 | 41 | 42 | #include "core.h" 43 | #include "ccc.h" 44 | #include 45 | #include 46 | 47 | CCC::CCC(): 48 | m_iSYNInterval(CUDT::m_iSYNInterval), 49 | m_dPktSndPeriod(1.0), 50 | m_dCWndSize(16.0), 51 | m_iBandwidth(), 52 | m_dMaxCWndSize(), 53 | m_iMSS(), 54 | m_iSndCurrSeqNo(), 55 | m_iRcvRate(), 56 | m_iRTT(), 57 | m_pcParam(NULL), 58 | m_iPSize(0), 59 | m_UDT(), 60 | m_iACKPeriod(0), 61 | m_iACKInterval(0), 62 | m_bUserDefinedRTO(false), 63 | m_iRTO(-1), 64 | m_PerfInfo() 65 | { 66 | } 67 | 68 | CCC::~CCC() 69 | { 70 | delete [] m_pcParam; 71 | } 72 | 73 | void CCC::setACKTimer(int msINT) 74 | { 75 | m_iACKPeriod = msINT > m_iSYNInterval ? m_iSYNInterval : msINT; 76 | } 77 | 78 | void CCC::setACKInterval(int pktINT) 79 | { 80 | m_iACKInterval = pktINT; 81 | } 82 | 83 | void CCC::setRTO(int usRTO) 84 | { 85 | m_bUserDefinedRTO = true; 86 | m_iRTO = usRTO; 87 | } 88 | 89 | void CCC::sendCustomMsg(CPacket& pkt) const 90 | { 91 | CUDT* u = CUDT::getUDTHandle(m_UDT); 92 | 93 | if (NULL != u) 94 | { 95 | pkt.m_iID = u->m_PeerID; 96 | u->m_pSndQueue->sendto(u->m_pPeerAddr, pkt); 97 | } 98 | } 99 | 100 | const CPerfMon* CCC::getPerfInfo() 101 | { 102 | try 103 | { 104 | CUDT* u = CUDT::getUDTHandle(m_UDT); 105 | if (NULL != u) 106 | u->sample(&m_PerfInfo, false); 107 | } 108 | catch (...) 109 | { 110 | return NULL; 111 | } 112 | 113 | return &m_PerfInfo; 114 | } 115 | 116 | void CCC::setMSS(int mss) 117 | { 118 | m_iMSS = mss; 119 | } 120 | 121 | void CCC::setBandwidth(int bw) 122 | { 123 | m_iBandwidth = bw; 124 | } 125 | 126 | void CCC::setSndCurrSeqNo(int32_t seqno) 127 | { 128 | m_iSndCurrSeqNo = seqno; 129 | } 130 | 131 | void CCC::setRcvRate(int rcvrate) 132 | { 133 | m_iRcvRate = rcvrate; 134 | } 135 | 136 | void CCC::setMaxCWndSize(int cwnd) 137 | { 138 | m_dMaxCWndSize = cwnd; 139 | } 140 | 141 | void CCC::setRTT(int rtt) 142 | { 143 | m_iRTT = rtt; 144 | } 145 | 146 | void CCC::setUserParam(const char* param, int size) 147 | { 148 | delete [] m_pcParam; 149 | m_pcParam = new char[size]; 150 | memcpy(m_pcParam, param, size); 151 | m_iPSize = size; 152 | } 153 | 154 | // 155 | CUDTCC::CUDTCC(): 156 | m_iRCInterval(), 157 | m_LastRCTime(), 158 | m_bSlowStart(), 159 | m_iLastAck(), 160 | m_bLoss(), 161 | m_iLastDecSeq(), 162 | m_dLastDecPeriod(), 163 | m_iNAKCount(), 164 | m_iDecRandom(), 165 | m_iAvgNAKNum(), 166 | m_iDecCount() 167 | { 168 | } 169 | 170 | void CUDTCC::init() 171 | { 172 | m_iRCInterval = m_iSYNInterval; 173 | m_LastRCTime = CTimer::getTime(); 174 | setACKTimer(m_iRCInterval); 175 | 176 | m_bSlowStart = true; 177 | m_iLastAck = m_iSndCurrSeqNo; 178 | m_bLoss = false; 179 | m_iLastDecSeq = CSeqNo::decseq(m_iLastAck); 180 | m_dLastDecPeriod = 1; 181 | m_iAvgNAKNum = 0; 182 | m_iNAKCount = 0; 183 | m_iDecRandom = 1; 184 | 185 | m_dCWndSize = 16; 186 | m_dPktSndPeriod = 1; 187 | } 188 | 189 | void CUDTCC::onACK(int32_t ack) 190 | { 191 | int64_t B = 0; 192 | double inc = 0; 193 | // Note: 1/24/2012 194 | // The minimum increase parameter is increased from "1.0 / m_iMSS" to 0.01 195 | // because the original was too small and caused sending rate to stay at low level 196 | // for long time. 197 | const double min_inc = 0.01; 198 | 199 | uint64_t currtime = CTimer::getTime(); 200 | if (currtime - m_LastRCTime < (uint64_t)m_iRCInterval) 201 | return; 202 | 203 | m_LastRCTime = currtime; 204 | 205 | if (m_bSlowStart) 206 | { 207 | m_dCWndSize += CSeqNo::seqlen(m_iLastAck, ack); 208 | m_iLastAck = ack; 209 | 210 | if (m_dCWndSize > m_dMaxCWndSize) 211 | { 212 | m_bSlowStart = false; 213 | if (m_iRcvRate > 0) 214 | m_dPktSndPeriod = 1000000.0 / m_iRcvRate; 215 | else 216 | m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval); 217 | } 218 | } 219 | else 220 | m_dCWndSize = m_iRcvRate / 1000000.0 * (m_iRTT + m_iRCInterval) + 16; 221 | 222 | // During Slow Start, no rate increase 223 | if (m_bSlowStart) 224 | return; 225 | 226 | if (m_bLoss) 227 | { 228 | m_bLoss = false; 229 | return; 230 | } 231 | 232 | B = (int64_t)(m_iBandwidth - 1000000.0 / m_dPktSndPeriod); 233 | if ((m_dPktSndPeriod > m_dLastDecPeriod) && ((m_iBandwidth / 9) < B)) 234 | B = m_iBandwidth / 9; 235 | if (B <= 0) 236 | inc = min_inc; 237 | else 238 | { 239 | // inc = max(10 ^ ceil(log10( B * MSS * 8 ) * Beta / MSS, 1/MSS) 240 | // Beta = 1.5 * 10^(-6) 241 | 242 | inc = pow(10.0, ceil(log10(B * m_iMSS * 8.0))) * 0.0000015 / m_iMSS; 243 | 244 | if (inc < min_inc) 245 | inc = min_inc; 246 | } 247 | 248 | m_dPktSndPeriod = (m_dPktSndPeriod * m_iRCInterval) / (m_dPktSndPeriod * inc + m_iRCInterval); 249 | } 250 | 251 | void CUDTCC::onLoss(const int32_t* losslist, int) 252 | { 253 | //Slow Start stopped, if it hasn't yet 254 | if (m_bSlowStart) 255 | { 256 | m_bSlowStart = false; 257 | if (m_iRcvRate > 0) 258 | { 259 | // Set the sending rate to the receiving rate. 260 | m_dPktSndPeriod = 1000000.0 / m_iRcvRate; 261 | return; 262 | } 263 | // If no receiving rate is observed, we have to compute the sending 264 | // rate according to the current window size, and decrease it 265 | // using the method below. 266 | m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval); 267 | } 268 | 269 | m_bLoss = true; 270 | 271 | if (CSeqNo::seqcmp(losslist[0] & 0x7FFFFFFF, m_iLastDecSeq) > 0) 272 | { 273 | m_dLastDecPeriod = m_dPktSndPeriod; 274 | m_dPktSndPeriod = ceil(m_dPktSndPeriod * 1.125); 275 | 276 | m_iAvgNAKNum = (int)ceil(m_iAvgNAKNum * 0.875 + m_iNAKCount * 0.125); 277 | m_iNAKCount = 1; 278 | m_iDecCount = 1; 279 | 280 | m_iLastDecSeq = m_iSndCurrSeqNo; 281 | 282 | // remove global synchronization using randomization 283 | srand(m_iLastDecSeq); 284 | m_iDecRandom = (int)ceil(m_iAvgNAKNum * (double(rand()) / RAND_MAX)); 285 | if (m_iDecRandom < 1) 286 | m_iDecRandom = 1; 287 | } 288 | else if ((m_iDecCount ++ < 5) && (0 == (++ m_iNAKCount % m_iDecRandom))) 289 | { 290 | // 0.875^5 = 0.51, rate should not be decreased by more than half within a congestion period 291 | m_dPktSndPeriod = ceil(m_dPktSndPeriod * 1.125); 292 | m_iLastDecSeq = m_iSndCurrSeqNo; 293 | } 294 | } 295 | 296 | void CUDTCC::onTimeout() 297 | { 298 | if (m_bSlowStart) 299 | { 300 | m_bSlowStart = false; 301 | if (m_iRcvRate > 0) 302 | m_dPktSndPeriod = 1000000.0 / m_iRcvRate; 303 | else 304 | m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval); 305 | } 306 | else 307 | { 308 | /* 309 | m_dLastDecPeriod = m_dPktSndPeriod; 310 | m_dPktSndPeriod = ceil(m_dPktSndPeriod * 2); 311 | m_iLastDecSeq = m_iLastAck; 312 | */ 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /src/ccc.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 02/28/2012 39 | *****************************************************************************/ 40 | 41 | 42 | #ifndef __UDT_CCC_H__ 43 | #define __UDT_CCC_H__ 44 | 45 | 46 | #include "udt.h" 47 | #include "packet.h" 48 | 49 | 50 | class UDT_API CCC 51 | { 52 | friend class CUDT; 53 | 54 | public: 55 | CCC(); 56 | virtual ~CCC(); 57 | 58 | private: 59 | CCC(const CCC&); 60 | CCC& operator=(const CCC&) {return *this;} 61 | 62 | public: 63 | 64 | // Functionality: 65 | // Callback function to be called (only) at the start of a UDT connection. 66 | // note that this is different from CCC(), which is always called. 67 | // Parameters: 68 | // None. 69 | // Returned value: 70 | // None. 71 | 72 | virtual void init() {} 73 | 74 | // Functionality: 75 | // Callback function to be called when a UDT connection is closed. 76 | // Parameters: 77 | // None. 78 | // Returned value: 79 | // None. 80 | 81 | virtual void close() {} 82 | 83 | // Functionality: 84 | // Callback function to be called when an ACK packet is received. 85 | // Parameters: 86 | // 0) [in] ackno: the data sequence number acknowledged by this ACK. 87 | // Returned value: 88 | // None. 89 | 90 | virtual void onACK(int32_t) {} 91 | 92 | // Functionality: 93 | // Callback function to be called when a loss report is received. 94 | // Parameters: 95 | // 0) [in] losslist: list of sequence number of packets, in the format describled in packet.cpp. 96 | // 1) [in] size: length of the loss list. 97 | // Returned value: 98 | // None. 99 | 100 | virtual void onLoss(const int32_t*, int) {} 101 | 102 | // Functionality: 103 | // Callback function to be called when a timeout event occurs. 104 | // Parameters: 105 | // None. 106 | // Returned value: 107 | // None. 108 | 109 | virtual void onTimeout() {} 110 | 111 | // Functionality: 112 | // Callback function to be called when a data is sent. 113 | // Parameters: 114 | // 0) [in] seqno: the data sequence number. 115 | // 1) [in] size: the payload size. 116 | // Returned value: 117 | // None. 118 | 119 | virtual void onPktSent(const CPacket*) {} 120 | 121 | // Functionality: 122 | // Callback function to be called when a data is received. 123 | // Parameters: 124 | // 0) [in] seqno: the data sequence number. 125 | // 1) [in] size: the payload size. 126 | // Returned value: 127 | // None. 128 | 129 | virtual void onPktReceived(const CPacket*) {} 130 | 131 | // Functionality: 132 | // Callback function to Process a user defined packet. 133 | // Parameters: 134 | // 0) [in] pkt: the user defined packet. 135 | // Returned value: 136 | // None. 137 | 138 | virtual void processCustomMsg(const CPacket*) {} 139 | 140 | protected: 141 | 142 | // Functionality: 143 | // Set periodical acknowldging and the ACK period. 144 | // Parameters: 145 | // 0) [in] msINT: the period to send an ACK. 146 | // Returned value: 147 | // None. 148 | 149 | void setACKTimer(int msINT); 150 | 151 | // Functionality: 152 | // Set packet-based acknowldging and the number of packets to send an ACK. 153 | // Parameters: 154 | // 0) [in] pktINT: the number of packets to send an ACK. 155 | // Returned value: 156 | // None. 157 | 158 | void setACKInterval(int pktINT); 159 | 160 | // Functionality: 161 | // Set RTO value. 162 | // Parameters: 163 | // 0) [in] msRTO: RTO in macroseconds. 164 | // Returned value: 165 | // None. 166 | 167 | void setRTO(int usRTO); 168 | 169 | // Functionality: 170 | // Send a user defined control packet. 171 | // Parameters: 172 | // 0) [in] pkt: user defined packet. 173 | // Returned value: 174 | // None. 175 | 176 | void sendCustomMsg(CPacket& pkt) const; 177 | 178 | // Functionality: 179 | // retrieve performance information. 180 | // Parameters: 181 | // None. 182 | // Returned value: 183 | // Pointer to a performance info structure. 184 | 185 | const CPerfMon* getPerfInfo(); 186 | 187 | // Functionality: 188 | // Set user defined parameters. 189 | // Parameters: 190 | // 0) [in] param: the paramters in one buffer. 191 | // 1) [in] size: the size of the buffer. 192 | // Returned value: 193 | // None. 194 | 195 | void setUserParam(const char* param, int size); 196 | 197 | private: 198 | void setMSS(int mss); 199 | void setMaxCWndSize(int cwnd); 200 | void setBandwidth(int bw); 201 | void setSndCurrSeqNo(int32_t seqno); 202 | void setRcvRate(int rcvrate); 203 | void setRTT(int rtt); 204 | 205 | protected: 206 | const int32_t& m_iSYNInterval; // UDT constant parameter, SYN 207 | 208 | double m_dPktSndPeriod; // Packet sending period, in microseconds 209 | double m_dCWndSize; // Congestion window size, in packets 210 | 211 | int m_iBandwidth; // estimated bandwidth, packets per second 212 | double m_dMaxCWndSize; // maximum cwnd size, in packets 213 | 214 | int m_iMSS; // Maximum Packet Size, including all packet headers 215 | int32_t m_iSndCurrSeqNo; // current maximum seq no sent out 216 | int m_iRcvRate; // packet arrive rate at receiver side, packets per second 217 | int m_iRTT; // current estimated RTT, microsecond 218 | 219 | char* m_pcParam; // user defined parameter 220 | int m_iPSize; // size of m_pcParam 221 | 222 | private: 223 | UDTSOCKET m_UDT; // The UDT entity that this congestion control algorithm is bound to 224 | 225 | int m_iACKPeriod; // Periodical timer to send an ACK, in milliseconds 226 | int m_iACKInterval; // How many packets to send one ACK, in packets 227 | 228 | bool m_bUserDefinedRTO; // if the RTO value is defined by users 229 | int m_iRTO; // RTO value, microseconds 230 | 231 | CPerfMon m_PerfInfo; // protocol statistics information 232 | }; 233 | 234 | class CCCVirtualFactory 235 | { 236 | public: 237 | virtual ~CCCVirtualFactory() {} 238 | 239 | virtual CCC* create() = 0; 240 | virtual CCCVirtualFactory* clone() = 0; 241 | }; 242 | 243 | template 244 | class CCCFactory: public CCCVirtualFactory 245 | { 246 | public: 247 | virtual ~CCCFactory() {} 248 | 249 | virtual CCC* create() {return new T;} 250 | virtual CCCVirtualFactory* clone() {return new CCCFactory;} 251 | }; 252 | 253 | class CUDTCC: public CCC 254 | { 255 | public: 256 | CUDTCC(); 257 | 258 | public: 259 | virtual void init(); 260 | virtual void onACK(int32_t); 261 | virtual void onLoss(const int32_t*, int); 262 | virtual void onTimeout(); 263 | 264 | private: 265 | int m_iRCInterval; // UDT Rate control interval 266 | uint64_t m_LastRCTime; // last rate increase time 267 | bool m_bSlowStart; // if in slow start phase 268 | int32_t m_iLastAck; // last ACKed seq no 269 | bool m_bLoss; // if loss happened since last rate increase 270 | int32_t m_iLastDecSeq; // max pkt seq no sent out when last decrease happened 271 | double m_dLastDecPeriod; // value of pktsndperiod when last decrease happened 272 | int m_iNAKCount; // NAK counter 273 | int m_iDecRandom; // random threshold on decrease by number of loss events 274 | int m_iAvgNAKNum; // average number of NAKs per congestion 275 | int m_iDecCount; // number of decreases in a congestion epoch 276 | }; 277 | 278 | #endif 279 | -------------------------------------------------------------------------------- /src/channel.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | ****************************************************************************/ 35 | 36 | /**************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/27/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef WINDOWS 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #else 50 | #include 51 | #include 52 | #include 53 | #endif 54 | #include "channel.h" 55 | #include "packet.h" 56 | 57 | #ifdef WINDOWS 58 | #define socklen_t int 59 | #endif 60 | 61 | #ifndef WINDOWS 62 | #define NET_ERROR errno 63 | #else 64 | #define NET_ERROR WSAGetLastError() 65 | #endif 66 | 67 | 68 | CChannel::CChannel(): 69 | m_iIPversion(AF_INET), 70 | m_iSockAddrSize(sizeof(sockaddr_in)), 71 | m_iSocket(), 72 | m_iSndBufSize(65536), 73 | m_iRcvBufSize(65536) 74 | { 75 | } 76 | 77 | CChannel::CChannel(int version): 78 | m_iIPversion(version), 79 | m_iSocket(), 80 | m_iSndBufSize(65536), 81 | m_iRcvBufSize(65536) 82 | { 83 | m_iSockAddrSize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); 84 | } 85 | 86 | CChannel::~CChannel() 87 | { 88 | } 89 | 90 | void CChannel::open(const sockaddr* addr) 91 | { 92 | // construct an socket 93 | m_iSocket = ::socket(m_iIPversion, SOCK_DGRAM, 0); 94 | 95 | #ifdef WINDOWS 96 | if (INVALID_SOCKET == m_iSocket) 97 | #else 98 | if (m_iSocket < 0) 99 | #endif 100 | throw CUDTException(1, 0, NET_ERROR); 101 | 102 | if (NULL != addr) 103 | { 104 | socklen_t namelen = m_iSockAddrSize; 105 | 106 | if (0 != ::bind(m_iSocket, addr, namelen)) 107 | throw CUDTException(1, 3, NET_ERROR); 108 | } 109 | else 110 | { 111 | //sendto or WSASendTo will also automatically bind the socket 112 | addrinfo hints; 113 | addrinfo* res; 114 | 115 | memset(&hints, 0, sizeof(struct addrinfo)); 116 | 117 | hints.ai_flags = AI_PASSIVE; 118 | hints.ai_family = m_iIPversion; 119 | hints.ai_socktype = SOCK_DGRAM; 120 | 121 | if (0 != ::getaddrinfo(NULL, "0", &hints, &res)) 122 | throw CUDTException(1, 3, NET_ERROR); 123 | 124 | if (0 != ::bind(m_iSocket, res->ai_addr, res->ai_addrlen)) 125 | throw CUDTException(1, 3, NET_ERROR); 126 | 127 | ::freeaddrinfo(res); 128 | } 129 | 130 | setUDPSockOpt(); 131 | } 132 | 133 | void CChannel::open(UDPSOCKET udpsock) 134 | { 135 | m_iSocket = udpsock; 136 | setUDPSockOpt(); 137 | } 138 | 139 | void CChannel::setUDPSockOpt() 140 | { 141 | #if defined(BSD) || defined(MACOSX) 142 | // BSD system will fail setsockopt if the requested buffer size exceeds system maximum value 143 | int maxsize = 64000; 144 | if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) 145 | ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&maxsize, sizeof(int)); 146 | if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int))) 147 | ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&maxsize, sizeof(int)); 148 | #else 149 | // for other systems, if requested is greated than maximum, the maximum value will be automactally used 150 | if ((0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) || 151 | (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int)))) 152 | throw CUDTException(1, 3, NET_ERROR); 153 | #endif 154 | 155 | timeval tv; 156 | tv.tv_sec = 0; 157 | #if defined (BSD) || defined (MACOSX) 158 | // Known BSD bug as the day I wrote this code. 159 | // A small time out value will cause the socket to block forever. 160 | tv.tv_usec = 10000; 161 | #else 162 | tv.tv_usec = 100; 163 | #endif 164 | 165 | #ifdef UNIX 166 | // Set non-blocking I/O 167 | // UNIX does not support SO_RCVTIMEO 168 | int opts = ::fcntl(m_iSocket, F_GETFL); 169 | if (-1 == ::fcntl(m_iSocket, F_SETFL, opts | O_NONBLOCK)) 170 | throw CUDTException(1, 3, NET_ERROR); 171 | #elif WINDOWS 172 | DWORD ot = 1; //milliseconds 173 | if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&ot, sizeof(DWORD))) 174 | throw CUDTException(1, 3, NET_ERROR); 175 | #else 176 | // Set receiving time-out value 177 | if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(timeval))) 178 | throw CUDTException(1, 3, NET_ERROR); 179 | #endif 180 | } 181 | 182 | void CChannel::close() const 183 | { 184 | #ifndef WINDOWS 185 | ::close(m_iSocket); 186 | #else 187 | ::closesocket(m_iSocket); 188 | #endif 189 | } 190 | 191 | int CChannel::getSndBufSize() 192 | { 193 | socklen_t size = sizeof(socklen_t); 194 | ::getsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char *)&m_iSndBufSize, &size); 195 | return m_iSndBufSize; 196 | } 197 | 198 | int CChannel::getRcvBufSize() 199 | { 200 | socklen_t size = sizeof(socklen_t); 201 | ::getsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char *)&m_iRcvBufSize, &size); 202 | return m_iRcvBufSize; 203 | } 204 | 205 | void CChannel::setSndBufSize(int size) 206 | { 207 | m_iSndBufSize = size; 208 | } 209 | 210 | void CChannel::setRcvBufSize(int size) 211 | { 212 | m_iRcvBufSize = size; 213 | } 214 | 215 | void CChannel::getSockAddr(sockaddr* addr) const 216 | { 217 | socklen_t namelen = m_iSockAddrSize; 218 | ::getsockname(m_iSocket, addr, &namelen); 219 | } 220 | 221 | void CChannel::getPeerAddr(sockaddr* addr) const 222 | { 223 | socklen_t namelen = m_iSockAddrSize; 224 | ::getpeername(m_iSocket, addr, &namelen); 225 | } 226 | 227 | int CChannel::sendto(const sockaddr* addr, CPacket& packet) const 228 | { 229 | // convert control information into network order 230 | if (packet.getFlag()) 231 | for (int i = 0, n = packet.getLength() / 4; i < n; ++ i) 232 | *((uint32_t *)packet.m_pcData + i) = htonl(*((uint32_t *)packet.m_pcData + i)); 233 | 234 | // convert packet header into network order 235 | //for (int j = 0; j < 4; ++ j) 236 | // packet.m_nHeader[j] = htonl(packet.m_nHeader[j]); 237 | uint32_t* p = packet.m_nHeader; 238 | for (int j = 0; j < 4; ++ j) 239 | { 240 | *p = htonl(*p); 241 | ++ p; 242 | } 243 | 244 | #ifndef WINDOWS 245 | msghdr mh; 246 | mh.msg_name = (sockaddr*)addr; 247 | mh.msg_namelen = m_iSockAddrSize; 248 | mh.msg_iov = (iovec*)packet.m_PacketVector; 249 | mh.msg_iovlen = 2; 250 | mh.msg_control = NULL; 251 | mh.msg_controllen = 0; 252 | mh.msg_flags = 0; 253 | 254 | int res = ::sendmsg(m_iSocket, &mh, 0); 255 | #else 256 | DWORD size = CPacket::m_iPktHdrSize + packet.getLength(); 257 | int addrsize = m_iSockAddrSize; 258 | int res = ::WSASendTo(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, 0, addr, addrsize, NULL, NULL); 259 | res = (0 == res) ? size : -1; 260 | #endif 261 | 262 | // convert back into local host order 263 | //for (int k = 0; k < 4; ++ k) 264 | // packet.m_nHeader[k] = ntohl(packet.m_nHeader[k]); 265 | p = packet.m_nHeader; 266 | for (int k = 0; k < 4; ++ k) 267 | { 268 | *p = ntohl(*p); 269 | ++ p; 270 | } 271 | 272 | if (packet.getFlag()) 273 | { 274 | for (int l = 0, n = packet.getLength() / 4; l < n; ++ l) 275 | *((uint32_t *)packet.m_pcData + l) = ntohl(*((uint32_t *)packet.m_pcData + l)); 276 | } 277 | 278 | return res; 279 | } 280 | 281 | int CChannel::recvfrom(sockaddr* addr, CPacket& packet) const 282 | { 283 | #ifndef WINDOWS 284 | msghdr mh; 285 | mh.msg_name = addr; 286 | mh.msg_namelen = m_iSockAddrSize; 287 | mh.msg_iov = packet.m_PacketVector; 288 | mh.msg_iovlen = 2; 289 | mh.msg_control = NULL; 290 | mh.msg_controllen = 0; 291 | mh.msg_flags = 0; 292 | 293 | #ifdef UNIX 294 | fd_set set; 295 | timeval tv; 296 | FD_ZERO(&set); 297 | FD_SET(m_iSocket, &set); 298 | tv.tv_sec = 0; 299 | tv.tv_usec = 10000; 300 | ::select(m_iSocket+1, &set, NULL, &set, &tv); 301 | #endif 302 | 303 | int res = ::recvmsg(m_iSocket, &mh, 0); 304 | #else 305 | DWORD size = CPacket::m_iPktHdrSize + packet.getLength(); 306 | DWORD flag = 0; 307 | int addrsize = m_iSockAddrSize; 308 | 309 | int res = ::WSARecvFrom(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, &flag, addr, &addrsize, NULL, NULL); 310 | res = (0 == res) ? size : -1; 311 | #endif 312 | 313 | if (res <= 0) 314 | { 315 | packet.setLength(-1); 316 | return -1; 317 | } 318 | 319 | packet.setLength(res - CPacket::m_iPktHdrSize); 320 | 321 | // convert back into local host order 322 | //for (int i = 0; i < 4; ++ i) 323 | // packet.m_nHeader[i] = ntohl(packet.m_nHeader[i]); 324 | uint32_t* p = packet.m_nHeader; 325 | for (int i = 0; i < 4; ++ i) 326 | { 327 | *p = ntohl(*p); 328 | ++ p; 329 | } 330 | 331 | if (packet.getFlag()) 332 | { 333 | for (int j = 0, n = packet.getLength() / 4; j < n; ++ j) 334 | *((uint32_t *)packet.m_pcData + j) = ntohl(*((uint32_t *)packet.m_pcData + j)); 335 | } 336 | 337 | return packet.getLength(); 338 | } 339 | -------------------------------------------------------------------------------- /src/channel.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/27/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_CHANNEL_H__ 42 | #define __UDT_CHANNEL_H__ 43 | 44 | 45 | #include "udt.h" 46 | #include "packet.h" 47 | 48 | 49 | class CChannel 50 | { 51 | public: 52 | CChannel(); 53 | CChannel(int version); 54 | ~CChannel(); 55 | 56 | // Functionality: 57 | // Open a UDP channel. 58 | // Parameters: 59 | // 0) [in] addr: The local address that UDP will use. 60 | // Returned value: 61 | // None. 62 | 63 | void open(const sockaddr* addr = NULL); 64 | 65 | // Functionality: 66 | // Open a UDP channel based on an existing UDP socket. 67 | // Parameters: 68 | // 0) [in] udpsock: UDP socket descriptor. 69 | // Returned value: 70 | // None. 71 | 72 | void open(UDPSOCKET udpsock); 73 | 74 | // Functionality: 75 | // Disconnect and close the UDP entity. 76 | // Parameters: 77 | // None. 78 | // Returned value: 79 | // None. 80 | 81 | void close() const; 82 | 83 | // Functionality: 84 | // Get the UDP sending buffer size. 85 | // Parameters: 86 | // None. 87 | // Returned value: 88 | // Current UDP sending buffer size. 89 | 90 | int getSndBufSize(); 91 | 92 | // Functionality: 93 | // Get the UDP receiving buffer size. 94 | // Parameters: 95 | // None. 96 | // Returned value: 97 | // Current UDP receiving buffer size. 98 | 99 | int getRcvBufSize(); 100 | 101 | // Functionality: 102 | // Set the UDP sending buffer size. 103 | // Parameters: 104 | // 0) [in] size: expected UDP sending buffer size. 105 | // Returned value: 106 | // None. 107 | 108 | void setSndBufSize(int size); 109 | 110 | // Functionality: 111 | // Set the UDP receiving buffer size. 112 | // Parameters: 113 | // 0) [in] size: expected UDP receiving buffer size. 114 | // Returned value: 115 | // None. 116 | 117 | void setRcvBufSize(int size); 118 | 119 | // Functionality: 120 | // Query the socket address that the channel is using. 121 | // Parameters: 122 | // 0) [out] addr: pointer to store the returned socket address. 123 | // Returned value: 124 | // None. 125 | 126 | void getSockAddr(sockaddr* addr) const; 127 | 128 | // Functionality: 129 | // Query the peer side socket address that the channel is connect to. 130 | // Parameters: 131 | // 0) [out] addr: pointer to store the returned socket address. 132 | // Returned value: 133 | // None. 134 | 135 | void getPeerAddr(sockaddr* addr) const; 136 | 137 | // Functionality: 138 | // Send a packet to the given address. 139 | // Parameters: 140 | // 0) [in] addr: pointer to the destination address. 141 | // 1) [in] packet: reference to a CPacket entity. 142 | // Returned value: 143 | // Actual size of data sent. 144 | 145 | int sendto(const sockaddr* addr, CPacket& packet) const; 146 | 147 | // Functionality: 148 | // Receive a packet from the channel and record the source address. 149 | // Parameters: 150 | // 0) [in] addr: pointer to the source address. 151 | // 1) [in] packet: reference to a CPacket entity. 152 | // Returned value: 153 | // Actual size of data received. 154 | 155 | int recvfrom(sockaddr* addr, CPacket& packet) const; 156 | 157 | private: 158 | void setUDPSockOpt(); 159 | 160 | private: 161 | int m_iIPversion; // IP version 162 | int m_iSockAddrSize; // socket address structure size (pre-defined to avoid run-time test) 163 | 164 | UDPSOCKET m_iSocket; // socket descriptor 165 | 166 | int m_iSndBufSize; // UDP sending buffer size 167 | int m_iRcvBufSize; // UDP receiving buffer size 168 | }; 169 | 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /src/epoll.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/01/2011 39 | *****************************************************************************/ 40 | 41 | #ifdef LINUX 42 | #include 43 | #include 44 | #endif 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include "udtCommon.h" 51 | #include "epoll.h" 52 | #include "udt.h" 53 | 54 | using namespace std; 55 | 56 | CEPoll::CEPoll(): 57 | m_iIDSeed(0) 58 | { 59 | CGuard::createMutex(m_EPollLock); 60 | } 61 | 62 | CEPoll::~CEPoll() 63 | { 64 | CGuard::releaseMutex(m_EPollLock); 65 | } 66 | 67 | int CEPoll::create() 68 | { 69 | CGuard pg(m_EPollLock); 70 | 71 | int localid = 0; 72 | 73 | #ifdef LINUX 74 | localid = epoll_create(1024); 75 | if (localid < 0) 76 | throw CUDTException(-1, 0, errno); 77 | #else 78 | // on BSD, use kqueue 79 | // on Solaris, use /dev/poll 80 | // on Windows, select 81 | #endif 82 | 83 | if (++ m_iIDSeed >= 0x7FFFFFFF) 84 | m_iIDSeed = 0; 85 | 86 | CEPollDesc desc; 87 | desc.m_iID = m_iIDSeed; 88 | desc.m_iLocalID = localid; 89 | m_mPolls[desc.m_iID] = desc; 90 | 91 | return desc.m_iID; 92 | } 93 | 94 | int CEPoll::add_usock(const int eid, const UDTSOCKET& u, const int* events) 95 | { 96 | CGuard pg(m_EPollLock); 97 | 98 | map::iterator p = m_mPolls.find(eid); 99 | if (p == m_mPolls.end()) 100 | throw CUDTException(5, 13); 101 | 102 | // BARCHART: Manage all event types. 103 | if (!events || (*events & UDT_EPOLL_IN)) 104 | p->second.m_sUDTSocksIn.insert(u); 105 | if (!events || (*events & UDT_EPOLL_OUT)) 106 | p->second.m_sUDTSocksOut.insert(u); 107 | if (!events || (*events & UDT_EPOLL_ERR)) 108 | p->second.m_sUDTSocksEx.insert(u); 109 | 110 | return 0; 111 | } 112 | 113 | // BARCHART 114 | int CEPoll::update_usock(const int eid, const UDTSOCKET& u, const int* events) 115 | { 116 | CGuard pg(m_EPollLock); 117 | 118 | map::iterator p = m_mPolls.find(eid); 119 | if (p == m_mPolls.end()){ 120 | throw CUDTException(5, 13); 121 | } 122 | 123 | if(events){ 124 | if (*events & UDT_EPOLL_IN){ 125 | p->second.m_sUDTSocksIn.insert(u); 126 | }else{ 127 | p->second.m_sUDTSocksIn.erase(u); 128 | } 129 | if (*events & UDT_EPOLL_OUT){ 130 | p->second.m_sUDTSocksOut.insert(u); 131 | } else{ 132 | p->second.m_sUDTSocksOut.erase(u); 133 | } 134 | } 135 | 136 | return 0; 137 | } 138 | 139 | // BARCHART 140 | int CEPoll::verify_usock(const int eid, const UDTSOCKET& u, int* events) 141 | { 142 | 143 | CGuard pg(m_EPollLock); 144 | 145 | map::iterator p = m_mPolls.find(eid); 146 | if (p == m_mPolls.end()){ 147 | throw CUDTException(5, 13); 148 | } 149 | 150 | if(events){ 151 | if(p->second.m_sUDTSocksIn.find(u) != p->second.m_sUDTSocksIn.end()){ 152 | *events |= UDT_EPOLL_IN; 153 | } 154 | if(p->second.m_sUDTSocksOut.find(u) != p->second.m_sUDTSocksOut.end()){ 155 | *events |= UDT_EPOLL_OUT; 156 | } 157 | } 158 | 159 | return 0; 160 | 161 | } 162 | 163 | int CEPoll::add_ssock(const int eid, const SYSSOCKET& s, const int* events) 164 | { 165 | CGuard pg(m_EPollLock); 166 | 167 | map::iterator p = m_mPolls.find(eid); 168 | if (p == m_mPolls.end()) 169 | throw CUDTException(5, 13); 170 | 171 | #ifdef LINUX 172 | epoll_event ev; 173 | 174 | if (NULL == events) 175 | ev.events = EPOLLIN | EPOLLOUT | EPOLLERR; 176 | else 177 | { 178 | ev.events = 0; 179 | if (*events & UDT_EPOLL_IN) 180 | ev.events |= EPOLLIN; 181 | if (*events & UDT_EPOLL_OUT) 182 | ev.events |= EPOLLOUT; 183 | if (*events & UDT_EPOLL_ERR) 184 | ev.events |= EPOLLERR; 185 | } 186 | 187 | ev.data.fd = s; 188 | if (::epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_ADD, s, &ev) < 0) 189 | throw CUDTException(); 190 | #endif 191 | 192 | p->second.m_sLocals.insert(s); 193 | 194 | return 0; 195 | } 196 | 197 | int CEPoll::remove_usock(const int eid, const UDTSOCKET& u) 198 | { 199 | CGuard pg(m_EPollLock); 200 | 201 | map::iterator p = m_mPolls.find(eid); 202 | if (p == m_mPolls.end()) 203 | throw CUDTException(5, 13); 204 | 205 | p->second.m_sUDTSocksIn.erase(u); 206 | p->second.m_sUDTSocksOut.erase(u); 207 | 208 | // when the socket is removed from a monitoring, it is not available anymore for any IO notification 209 | p->second.m_sUDTReads.erase(u); 210 | p->second.m_sUDTWrites.erase(u); 211 | 212 | return 0; 213 | } 214 | 215 | int CEPoll::remove_ssock(const int eid, const SYSSOCKET& s) 216 | { 217 | CGuard pg(m_EPollLock); 218 | 219 | map::iterator p = m_mPolls.find(eid); 220 | if (p == m_mPolls.end()) 221 | throw CUDTException(5, 13); 222 | 223 | #ifdef LINUX 224 | epoll_event ev; // ev is ignored, for compatibility with old Linux kernel only. 225 | if (::epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_DEL, s, &ev) < 0) 226 | throw CUDTException(); 227 | #endif 228 | 229 | p->second.m_sLocals.erase(s); 230 | 231 | return 0; 232 | } 233 | 234 | int CEPoll::wait(const int eid, set* readfds, set* writefds, int64_t msTimeOut, set* lrfds, set* lwfds) 235 | { 236 | // if all fields is NULL and waiting time is infinite, then this would be a deadlock 237 | if (!readfds && !writefds && !lrfds && lwfds && (msTimeOut < 0)) 238 | throw CUDTException(5, 3, 0); 239 | 240 | // Clear these sets in case the app forget to do it. 241 | if (readfds) readfds->clear(); 242 | if (writefds) writefds->clear(); 243 | if (lrfds) lrfds->clear(); 244 | if (lwfds) lwfds->clear(); 245 | 246 | int total = 0; 247 | 248 | int64_t entertime = CTimer::getTime(); 249 | while (true) 250 | { 251 | CGuard::enterCS(m_EPollLock); 252 | 253 | map::iterator p = m_mPolls.find(eid); 254 | if (p == m_mPolls.end()) 255 | { 256 | CGuard::leaveCS(m_EPollLock); 257 | throw CUDTException(5, 13); 258 | } 259 | 260 | if (p->second.m_sUDTSocksIn.empty() && p->second.m_sUDTSocksOut.empty() && p->second.m_sLocals.empty() && (msTimeOut < 0)) 261 | { 262 | // no socket is being monitored, this may be a deadlock 263 | CGuard::leaveCS(m_EPollLock); 264 | throw CUDTException(5, 3); 265 | } 266 | 267 | // Sockets with exceptions are returned to both read and write sets. 268 | if ((NULL != readfds) && (!p->second.m_sUDTReads.empty() || !p->second.m_sUDTExcepts.empty())) 269 | { 270 | *readfds = p->second.m_sUDTReads; 271 | for (set::const_iterator i = p->second.m_sUDTExcepts.begin(); i != p->second.m_sUDTExcepts.end(); ++ i) 272 | readfds->insert(*i); 273 | total += p->second.m_sUDTReads.size() + p->second.m_sUDTExcepts.size(); 274 | } 275 | if ((NULL != writefds) && (!p->second.m_sUDTWrites.empty() || !p->second.m_sUDTExcepts.empty())) 276 | { 277 | *writefds = p->second.m_sUDTWrites; 278 | for (set::const_iterator i = p->second.m_sUDTExcepts.begin(); i != p->second.m_sUDTExcepts.end(); ++ i) 279 | writefds->insert(*i); 280 | total += p->second.m_sUDTWrites.size() + p->second.m_sUDTExcepts.size(); 281 | } 282 | 283 | // BARCHART: Remove errors when reported. 284 | if(total > 0 && !p->second.m_sUDTExcepts.empty()){ 285 | p->second.m_sUDTExcepts.clear(); 286 | } 287 | 288 | if (lrfds || lwfds) 289 | { 290 | #ifdef LINUX 291 | const int max_events = p->second.m_sLocals.size(); 292 | epoll_event ev[max_events]; 293 | int nfds = ::epoll_wait(p->second.m_iLocalID, ev, max_events, 0); 294 | 295 | for (int i = 0; i < nfds; ++ i) 296 | { 297 | if ((NULL != lrfds) && (ev[i].events & EPOLLIN)) 298 | { 299 | lrfds->insert(ev[i].data.fd); 300 | ++ total; 301 | } 302 | if ((NULL != lwfds) && (ev[i].events & EPOLLOUT)) 303 | { 304 | lwfds->insert(ev[i].data.fd); 305 | ++ total; 306 | } 307 | } 308 | #else 309 | //currently "select" is used for all non-Linux platforms. 310 | //faster approaches can be applied for specific systems in the future. 311 | 312 | //"select" has a limitation on the number of sockets 313 | 314 | fd_set readfds2; 315 | fd_set writefds2; 316 | FD_ZERO(&readfds2); 317 | FD_ZERO(&writefds2); 318 | 319 | for (set::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i) 320 | { 321 | if (lrfds) 322 | FD_SET(*i, &readfds2); 323 | if (lwfds) 324 | FD_SET(*i, &writefds2); 325 | } 326 | 327 | timeval tv; 328 | tv.tv_sec = 0; 329 | tv.tv_usec = 0; 330 | if (::select(0, &readfds2, &writefds2, NULL, &tv) > 0) 331 | { 332 | for (set::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i) 333 | { 334 | if (lrfds && FD_ISSET(*i, &readfds2)) 335 | { 336 | lrfds->insert(*i); 337 | ++ total; 338 | } 339 | if (lwfds && FD_ISSET(*i, &writefds2)) 340 | { 341 | lwfds->insert(*i); 342 | ++ total; 343 | } 344 | } 345 | } 346 | #endif 347 | } 348 | 349 | CGuard::leaveCS(m_EPollLock); 350 | 351 | if (total > 0) 352 | return total; 353 | 354 | if ((msTimeOut >= 0) && (int64_t(CTimer::getTime() - entertime) >= msTimeOut * 1000LL)) 355 | throw CUDTException(6, 3, 0); 356 | 357 | CTimer::waitForEvent(); 358 | } 359 | 360 | return 0; 361 | } 362 | 363 | int CEPoll::release(const int eid) 364 | { 365 | CGuard pg(m_EPollLock); 366 | 367 | map::iterator i = m_mPolls.find(eid); 368 | if (i == m_mPolls.end()) 369 | throw CUDTException(5, 13); 370 | 371 | #ifdef LINUX 372 | // release local/system epoll descriptor 373 | ::close(i->second.m_iLocalID); 374 | #endif 375 | 376 | m_mPolls.erase(i); 377 | 378 | return 0; 379 | } 380 | 381 | namespace 382 | { 383 | 384 | void update_epoll_sets(const UDTSOCKET& uid, const set& watch, set& result, bool enable) 385 | { 386 | if (enable && (watch.find(uid) != watch.end())) 387 | { 388 | result.insert(uid); 389 | } 390 | else if (!enable) 391 | { 392 | result.erase(uid); 393 | } 394 | } 395 | 396 | } // namespace 397 | 398 | int CEPoll::update_events(const UDTSOCKET& uid, std::set& eids, int events, bool enable) 399 | { 400 | CGuard pg(m_EPollLock); 401 | 402 | map::iterator p; 403 | 404 | vector lost; 405 | for (set::iterator i = eids.begin(); i != eids.end(); ++ i) 406 | { 407 | p = m_mPolls.find(*i); 408 | if (p == m_mPolls.end()) 409 | { 410 | lost.push_back(*i); 411 | } 412 | else 413 | { 414 | if ((events & UDT_EPOLL_IN) != 0) 415 | update_epoll_sets(uid, p->second.m_sUDTSocksIn, p->second.m_sUDTReads, enable); 416 | if ((events & UDT_EPOLL_OUT) != 0) 417 | update_epoll_sets(uid, p->second.m_sUDTSocksOut, p->second.m_sUDTWrites, enable); 418 | if ((events & UDT_EPOLL_ERR) != 0) 419 | update_epoll_sets(uid, p->second.m_sUDTSocksEx, p->second.m_sUDTExcepts, enable); 420 | } 421 | } 422 | 423 | for (vector::iterator i = lost.begin(); i != lost.end(); ++ i) 424 | eids.erase(*i); 425 | 426 | return 0; 427 | } 428 | -------------------------------------------------------------------------------- /src/epoll.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 08/20/2010 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_EPOLL_H__ 42 | #define __UDT_EPOLL_H__ 43 | 44 | 45 | #include 46 | #include 47 | #include "udt.h" 48 | 49 | 50 | struct CEPollDesc 51 | { 52 | int m_iID; // epoll ID 53 | std::set m_sUDTSocksOut; // set of UDT sockets waiting for write events 54 | std::set m_sUDTSocksIn; // set of UDT sockets waiting for read events 55 | std::set m_sUDTSocksEx; // set of UDT sockets waiting for exceptions 56 | 57 | int m_iLocalID; // local system epoll ID 58 | std::set m_sLocals; // set of local (non-UDT) descriptors 59 | 60 | std::set m_sUDTWrites; // UDT sockets ready for write 61 | std::set m_sUDTReads; // UDT sockets ready for read 62 | std::set m_sUDTExcepts; // UDT sockets with exceptions (connection broken, etc.) 63 | }; 64 | 65 | class CEPoll 66 | { 67 | friend class CUDT; 68 | friend class CRendezvousQueue; 69 | 70 | public: 71 | CEPoll(); 72 | ~CEPoll(); 73 | 74 | public: // for CUDTUnited API 75 | 76 | // Functionality: 77 | // create a new EPoll. 78 | // Parameters: 79 | // None. 80 | // Returned value: 81 | // new EPoll ID if success, otherwise an error number. 82 | 83 | int create(); 84 | 85 | // Functionality: 86 | // add a UDT socket to an EPoll. 87 | // Parameters: 88 | // 0) [in] eid: EPoll ID. 89 | // 1) [in] u: UDT Socket ID. 90 | // 2) [in] events: events to watch. 91 | // Returned value: 92 | // 0 if success, otherwise an error number. 93 | 94 | int add_usock(const int eid, const UDTSOCKET& u, const int* events = NULL); 95 | 96 | // BARCHART 97 | int update_usock(const int eid, const UDTSOCKET& u, const int* events = NULL); 98 | // BARCHART 99 | int verify_usock(const int eid, const UDTSOCKET& u, int* events); 100 | 101 | // Functionality: 102 | // add a system socket to an EPoll. 103 | // Parameters: 104 | // 0) [in] eid: EPoll ID. 105 | // 1) [in] s: system Socket ID. 106 | // 2) [in] events: events to watch. 107 | // Returned value: 108 | // 0 if success, otherwise an error number. 109 | 110 | int add_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL); 111 | 112 | // Functionality: 113 | // remove a UDT socket event from an EPoll; socket will be removed if no events to watch 114 | // Parameters: 115 | // 0) [in] eid: EPoll ID. 116 | // 1) [in] u: UDT socket ID. 117 | // Returned value: 118 | // 0 if success, otherwise an error number. 119 | 120 | int remove_usock(const int eid, const UDTSOCKET& u); 121 | 122 | // Functionality: 123 | // remove a system socket event from an EPoll; socket will be removed if no events to watch 124 | // Parameters: 125 | // 0) [in] eid: EPoll ID. 126 | // 1) [in] s: system socket ID. 127 | // Returned value: 128 | // 0 if success, otherwise an error number. 129 | 130 | int remove_ssock(const int eid, const SYSSOCKET& s); 131 | 132 | // Functionality: 133 | // wait for EPoll events or timeout. 134 | // Parameters: 135 | // 0) [in] eid: EPoll ID. 136 | // 1) [out] readfds: UDT sockets available for reading. 137 | // 2) [out] writefds: UDT sockets available for writing. 138 | // 3) [in] msTimeOut: timeout threshold, in milliseconds. 139 | // 4) [out] lrfds: system file descriptors for reading. 140 | // 5) [out] lwfds: system file descriptors for writing. 141 | // Returned value: 142 | // number of sockets available for IO. 143 | 144 | int wait(const int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, std::set* lrfds, std::set* lwfds); 145 | 146 | // Functionality: 147 | // close and release an EPoll. 148 | // Parameters: 149 | // 0) [in] eid: EPoll ID. 150 | // Returned value: 151 | // 0 if success, otherwise an error number. 152 | 153 | int release(const int eid); 154 | 155 | public: // for CUDT to acknowledge IO status 156 | 157 | // Functionality: 158 | // Update events available for a UDT socket. 159 | // Parameters: 160 | // 0) [in] uid: UDT socket ID. 161 | // 1) [in] eids: EPoll IDs to be set 162 | // 1) [in] events: Combination of events to update 163 | // 1) [in] enable: true -> enable, otherwise disable 164 | // Returned value: 165 | // 0 if success, otherwise an error number 166 | 167 | int update_events(const UDTSOCKET& uid, std::set& eids, int events, bool enable); 168 | 169 | private: 170 | int m_iIDSeed; // seed to generate a new ID 171 | udt_pthread_mutex_t m_SeedLock; 172 | 173 | std::map m_mPolls; // all epolls 174 | udt_pthread_mutex_t m_EPollLock; 175 | }; 176 | 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /src/list.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/22/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_LIST_H__ 42 | #define __UDT_LIST_H__ 43 | 44 | 45 | #include "udt.h" 46 | #include "udtCommon.h" 47 | 48 | 49 | class CSndLossList 50 | { 51 | public: 52 | CSndLossList(int size = 1024); 53 | ~CSndLossList(); 54 | 55 | // Functionality: 56 | // Insert a seq. no. into the sender loss list. 57 | // Parameters: 58 | // 0) [in] seqno1: sequence number starts. 59 | // 1) [in] seqno2: sequence number ends. 60 | // Returned value: 61 | // number of packets that are not in the list previously. 62 | 63 | int insert(int32_t seqno1, int32_t seqno2); 64 | 65 | // Functionality: 66 | // Remove ALL the seq. no. that are not greater than the parameter. 67 | // Parameters: 68 | // 0) [in] seqno: sequence number. 69 | // Returned value: 70 | // None. 71 | 72 | void remove(int32_t seqno); 73 | 74 | // Functionality: 75 | // Read the loss length. 76 | // Parameters: 77 | // None. 78 | // Returned value: 79 | // The length of the list. 80 | 81 | int getLossLength(); 82 | 83 | // Functionality: 84 | // Read the first (smallest) loss seq. no. in the list and remove it. 85 | // Parameters: 86 | // None. 87 | // Returned value: 88 | // The seq. no. or -1 if the list is empty. 89 | 90 | int32_t getLostSeq(); 91 | 92 | private: 93 | int32_t* m_piData1; // sequence number starts 94 | int32_t* m_piData2; // seqnence number ends 95 | int* m_piNext; // next node in the list 96 | 97 | int m_iHead; // first node 98 | int m_iLength; // loss length 99 | int m_iSize; // size of the static array 100 | int m_iLastInsertPos; // position of last insert node 101 | 102 | udt_pthread_mutex_t m_ListLock; // used to synchronize list operation 103 | 104 | private: 105 | CSndLossList(const CSndLossList&); 106 | CSndLossList& operator=(const CSndLossList&); 107 | }; 108 | 109 | //////////////////////////////////////////////////////////////////////////////// 110 | 111 | class CRcvLossList 112 | { 113 | public: 114 | CRcvLossList(int size = 1024); 115 | ~CRcvLossList(); 116 | 117 | // Functionality: 118 | // Insert a series of loss seq. no. between "seqno1" and "seqno2" into the receiver's loss list. 119 | // Parameters: 120 | // 0) [in] seqno1: sequence number starts. 121 | // 1) [in] seqno2: seqeunce number ends. 122 | // Returned value: 123 | // None. 124 | 125 | void insert(int32_t seqno1, int32_t seqno2); 126 | 127 | // Functionality: 128 | // Remove a loss seq. no. from the receiver's loss list. 129 | // Parameters: 130 | // 0) [in] seqno: sequence number. 131 | // Returned value: 132 | // if the packet is removed (true) or no such lost packet is found (false). 133 | 134 | bool remove(int32_t seqno); 135 | 136 | // Functionality: 137 | // Remove all packets between seqno1 and seqno2. 138 | // Parameters: 139 | // 0) [in] seqno1: start sequence number. 140 | // 1) [in] seqno2: end sequence number. 141 | // Returned value: 142 | // if the packet is removed (true) or no such lost packet is found (false). 143 | 144 | bool remove(int32_t seqno1, int32_t seqno2); 145 | 146 | // Functionality: 147 | // Find if there is any lost packets whose sequence number falling seqno1 and seqno2. 148 | // Parameters: 149 | // 0) [in] seqno1: start sequence number. 150 | // 1) [in] seqno2: end sequence number. 151 | // Returned value: 152 | // True if found; otherwise false. 153 | 154 | bool find(int32_t seqno1, int32_t seqno2) const; 155 | 156 | // Functionality: 157 | // Read the loss length. 158 | // Parameters: 159 | // None. 160 | // Returned value: 161 | // the length of the list. 162 | 163 | int getLossLength() const; 164 | 165 | // Functionality: 166 | // Read the first (smallest) seq. no. in the list. 167 | // Parameters: 168 | // None. 169 | // Returned value: 170 | // the sequence number or -1 if the list is empty. 171 | 172 | int getFirstLostSeq() const; 173 | 174 | // Functionality: 175 | // Get a encoded loss array for NAK report. 176 | // Parameters: 177 | // 0) [out] array: the result list of seq. no. to be included in NAK. 178 | // 1) [out] physical length of the result array. 179 | // 2) [in] limit: maximum length of the array. 180 | // Returned value: 181 | // None. 182 | 183 | void getLossArray(int32_t* array, int& len, int limit); 184 | 185 | private: 186 | int32_t* m_piData1; // sequence number starts 187 | int32_t* m_piData2; // sequence number ends 188 | int* m_piNext; // next node in the list 189 | int* m_piPrior; // prior node in the list; 190 | 191 | int m_iHead; // first node in the list 192 | int m_iTail; // last node in the list; 193 | int m_iLength; // loss length 194 | int m_iSize; // size of the static array 195 | 196 | private: 197 | CRcvLossList(const CRcvLossList&); 198 | CRcvLossList& operator=(const CRcvLossList&); 199 | }; 200 | 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /src/md5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.cpp,v 1.3 2008/01/20 22:52:04 lilyco Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.c is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order 41 | either statically or dynamically; added missing #include 42 | in library. 43 | 2002-03-11 lpd Corrected argument list for main(), and added int return 44 | type, in test program and T value program. 45 | 2002-02-21 lpd Added missing #include in test program. 46 | 2000-07-03 lpd Patched to eliminate warnings about "constant is 47 | unsigned in ANSI C, signed in traditional"; made test program 48 | self-checking. 49 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 50 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 51 | 1999-05-03 lpd Original version. 52 | */ 53 | 54 | #include "md5.h" 55 | #include 56 | 57 | #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ 58 | #ifdef ARCH_IS_BIG_ENDIAN 59 | # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) 60 | #else 61 | # define BYTE_ORDER 0 62 | #endif 63 | 64 | #define T_MASK ((md5_word_t)~0) 65 | #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) 66 | #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) 67 | #define T3 0x242070db 68 | #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) 69 | #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) 70 | #define T6 0x4787c62a 71 | #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) 72 | #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) 73 | #define T9 0x698098d8 74 | #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) 75 | #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) 76 | #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) 77 | #define T13 0x6b901122 78 | #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) 79 | #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) 80 | #define T16 0x49b40821 81 | #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) 82 | #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) 83 | #define T19 0x265e5a51 84 | #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) 85 | #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) 86 | #define T22 0x02441453 87 | #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) 88 | #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) 89 | #define T25 0x21e1cde6 90 | #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) 91 | #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) 92 | #define T28 0x455a14ed 93 | #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) 94 | #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) 95 | #define T31 0x676f02d9 96 | #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) 97 | #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) 98 | #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) 99 | #define T35 0x6d9d6122 100 | #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) 101 | #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) 102 | #define T38 0x4bdecfa9 103 | #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) 104 | #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) 105 | #define T41 0x289b7ec6 106 | #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) 107 | #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) 108 | #define T44 0x04881d05 109 | #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) 110 | #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) 111 | #define T47 0x1fa27cf8 112 | #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) 113 | #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) 114 | #define T50 0x432aff97 115 | #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) 116 | #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) 117 | #define T53 0x655b59c3 118 | #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) 119 | #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) 120 | #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) 121 | #define T57 0x6fa87e4f 122 | #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) 123 | #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) 124 | #define T60 0x4e0811a1 125 | #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) 126 | #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) 127 | #define T63 0x2ad7d2bb 128 | #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) 129 | 130 | 131 | static void 132 | md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) 133 | { 134 | md5_word_t 135 | a = pms->abcd[0], b = pms->abcd[1], 136 | c = pms->abcd[2], d = pms->abcd[3]; 137 | md5_word_t t; 138 | #if BYTE_ORDER > 0 139 | /* Define storage only for big-endian CPUs. */ 140 | md5_word_t X[16]; 141 | #else 142 | /* Define storage for little-endian or both types of CPUs. */ 143 | md5_word_t xbuf[16]; 144 | const md5_word_t *X; 145 | #endif 146 | 147 | { 148 | #if BYTE_ORDER == 0 149 | /* 150 | * Determine dynamically whether this is a big-endian or 151 | * little-endian machine, since we can use a more efficient 152 | * algorithm on the latter. 153 | */ 154 | static const int w = 1; 155 | 156 | if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ 157 | #endif 158 | #if BYTE_ORDER <= 0 /* little-endian */ 159 | { 160 | /* 161 | * On little-endian machines, we can process properly aligned 162 | * data without copying it. 163 | */ 164 | if (!((data - (const md5_byte_t *)0) & 3)) { 165 | /* data are properly aligned */ 166 | X = (const md5_word_t *)data; 167 | } else { 168 | /* not aligned */ 169 | memcpy(xbuf, data, 64); 170 | X = xbuf; 171 | } 172 | } 173 | #endif 174 | #if BYTE_ORDER == 0 175 | else /* dynamic big-endian */ 176 | #endif 177 | #if BYTE_ORDER >= 0 /* big-endian */ 178 | { 179 | /* 180 | * On big-endian machines, we must arrange the bytes in the 181 | * right order. 182 | */ 183 | const md5_byte_t *xp = data; 184 | int i; 185 | 186 | # if BYTE_ORDER == 0 187 | X = xbuf; /* (dynamic only) */ 188 | # else 189 | # define xbuf X /* (static only) */ 190 | # endif 191 | for (i = 0; i < 16; ++i, xp += 4) 192 | xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); 193 | } 194 | #endif 195 | } 196 | 197 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 198 | 199 | /* Round 1. */ 200 | /* Let [abcd k s i] denote the operation 201 | a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ 202 | #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) 203 | #define SET(a, b, c, d, k, s, Ti)\ 204 | t = a + F(b,c,d) + X[k] + Ti;\ 205 | a = ROTATE_LEFT(t, s) + b 206 | /* Do the following 16 operations. */ 207 | SET(a, b, c, d, 0, 7, T1); 208 | SET(d, a, b, c, 1, 12, T2); 209 | SET(c, d, a, b, 2, 17, T3); 210 | SET(b, c, d, a, 3, 22, T4); 211 | SET(a, b, c, d, 4, 7, T5); 212 | SET(d, a, b, c, 5, 12, T6); 213 | SET(c, d, a, b, 6, 17, T7); 214 | SET(b, c, d, a, 7, 22, T8); 215 | SET(a, b, c, d, 8, 7, T9); 216 | SET(d, a, b, c, 9, 12, T10); 217 | SET(c, d, a, b, 10, 17, T11); 218 | SET(b, c, d, a, 11, 22, T12); 219 | SET(a, b, c, d, 12, 7, T13); 220 | SET(d, a, b, c, 13, 12, T14); 221 | SET(c, d, a, b, 14, 17, T15); 222 | SET(b, c, d, a, 15, 22, T16); 223 | #undef SET 224 | 225 | /* Round 2. */ 226 | /* Let [abcd k s i] denote the operation 227 | a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ 228 | #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) 229 | #define SET(a, b, c, d, k, s, Ti)\ 230 | t = a + G(b,c,d) + X[k] + Ti;\ 231 | a = ROTATE_LEFT(t, s) + b 232 | /* Do the following 16 operations. */ 233 | SET(a, b, c, d, 1, 5, T17); 234 | SET(d, a, b, c, 6, 9, T18); 235 | SET(c, d, a, b, 11, 14, T19); 236 | SET(b, c, d, a, 0, 20, T20); 237 | SET(a, b, c, d, 5, 5, T21); 238 | SET(d, a, b, c, 10, 9, T22); 239 | SET(c, d, a, b, 15, 14, T23); 240 | SET(b, c, d, a, 4, 20, T24); 241 | SET(a, b, c, d, 9, 5, T25); 242 | SET(d, a, b, c, 14, 9, T26); 243 | SET(c, d, a, b, 3, 14, T27); 244 | SET(b, c, d, a, 8, 20, T28); 245 | SET(a, b, c, d, 13, 5, T29); 246 | SET(d, a, b, c, 2, 9, T30); 247 | SET(c, d, a, b, 7, 14, T31); 248 | SET(b, c, d, a, 12, 20, T32); 249 | #undef SET 250 | 251 | /* Round 3. */ 252 | /* Let [abcd k s t] denote the operation 253 | a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ 254 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 255 | #define SET(a, b, c, d, k, s, Ti)\ 256 | t = a + H(b,c,d) + X[k] + Ti;\ 257 | a = ROTATE_LEFT(t, s) + b 258 | /* Do the following 16 operations. */ 259 | SET(a, b, c, d, 5, 4, T33); 260 | SET(d, a, b, c, 8, 11, T34); 261 | SET(c, d, a, b, 11, 16, T35); 262 | SET(b, c, d, a, 14, 23, T36); 263 | SET(a, b, c, d, 1, 4, T37); 264 | SET(d, a, b, c, 4, 11, T38); 265 | SET(c, d, a, b, 7, 16, T39); 266 | SET(b, c, d, a, 10, 23, T40); 267 | SET(a, b, c, d, 13, 4, T41); 268 | SET(d, a, b, c, 0, 11, T42); 269 | SET(c, d, a, b, 3, 16, T43); 270 | SET(b, c, d, a, 6, 23, T44); 271 | SET(a, b, c, d, 9, 4, T45); 272 | SET(d, a, b, c, 12, 11, T46); 273 | SET(c, d, a, b, 15, 16, T47); 274 | SET(b, c, d, a, 2, 23, T48); 275 | #undef SET 276 | 277 | /* Round 4. */ 278 | /* Let [abcd k s t] denote the operation 279 | a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ 280 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) 281 | #define SET(a, b, c, d, k, s, Ti)\ 282 | t = a + I(b,c,d) + X[k] + Ti;\ 283 | a = ROTATE_LEFT(t, s) + b 284 | /* Do the following 16 operations. */ 285 | SET(a, b, c, d, 0, 6, T49); 286 | SET(d, a, b, c, 7, 10, T50); 287 | SET(c, d, a, b, 14, 15, T51); 288 | SET(b, c, d, a, 5, 21, T52); 289 | SET(a, b, c, d, 12, 6, T53); 290 | SET(d, a, b, c, 3, 10, T54); 291 | SET(c, d, a, b, 10, 15, T55); 292 | SET(b, c, d, a, 1, 21, T56); 293 | SET(a, b, c, d, 8, 6, T57); 294 | SET(d, a, b, c, 15, 10, T58); 295 | SET(c, d, a, b, 6, 15, T59); 296 | SET(b, c, d, a, 13, 21, T60); 297 | SET(a, b, c, d, 4, 6, T61); 298 | SET(d, a, b, c, 11, 10, T62); 299 | SET(c, d, a, b, 2, 15, T63); 300 | SET(b, c, d, a, 9, 21, T64); 301 | #undef SET 302 | 303 | /* Then perform the following additions. (That is increment each 304 | of the four registers by the value it had before this block 305 | was started.) */ 306 | pms->abcd[0] += a; 307 | pms->abcd[1] += b; 308 | pms->abcd[2] += c; 309 | pms->abcd[3] += d; 310 | } 311 | 312 | void 313 | md5_init(md5_state_t *pms) 314 | { 315 | pms->count[0] = pms->count[1] = 0; 316 | pms->abcd[0] = 0x67452301; 317 | pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; 318 | pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; 319 | pms->abcd[3] = 0x10325476; 320 | } 321 | 322 | void 323 | md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) 324 | { 325 | const md5_byte_t *p = data; 326 | int left = nbytes; 327 | int offset = (pms->count[0] >> 3) & 63; 328 | md5_word_t nbits = (md5_word_t)(nbytes << 3); 329 | 330 | if (nbytes <= 0) 331 | return; 332 | 333 | /* Update the message length. */ 334 | pms->count[1] += nbytes >> 29; 335 | pms->count[0] += nbits; 336 | if (pms->count[0] < nbits) 337 | pms->count[1]++; 338 | 339 | /* Process an initial partial block. */ 340 | if (offset) { 341 | int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); 342 | 343 | memcpy(pms->buf + offset, p, copy); 344 | if (offset + copy < 64) 345 | return; 346 | p += copy; 347 | left -= copy; 348 | md5_process(pms, pms->buf); 349 | } 350 | 351 | /* Process full blocks. */ 352 | for (; left >= 64; p += 64, left -= 64) 353 | md5_process(pms, p); 354 | 355 | /* Process a final partial block. */ 356 | if (left) 357 | memcpy(pms->buf, p, left); 358 | } 359 | 360 | void 361 | md5_finish(md5_state_t *pms, md5_byte_t digest[16]) 362 | { 363 | static const md5_byte_t pad[64] = { 364 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 366 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 368 | }; 369 | md5_byte_t data[8]; 370 | int i; 371 | 372 | /* Save the length before padding. */ 373 | for (i = 0; i < 8; ++i) 374 | data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); 375 | /* Pad to 56 bytes mod 64. */ 376 | md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); 377 | /* Append the length. */ 378 | md5_append(pms, data, 8); 379 | for (i = 0; i < 16; ++i) 380 | digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); 381 | } 382 | -------------------------------------------------------------------------------- /src/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.h,v 1.2 2007/12/24 05:58:37 lilyco Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.h is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Removed support for non-ANSI compilers; removed 41 | references to Ghostscript; clarified derivation from RFC 1321; 42 | now handles byte order either statically or dynamically. 43 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 44 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 45 | added conditionalization for C++ compilation from Martin 46 | Purschke . 47 | 1999-05-03 lpd Original version. 48 | */ 49 | 50 | #ifndef md5_INCLUDED 51 | # define md5_INCLUDED 52 | 53 | /* 54 | * This package supports both compile-time and run-time determination of CPU 55 | * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be 56 | * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is 57 | * defined as non-zero, the code will be compiled to run only on big-endian 58 | * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to 59 | * run on either big- or little-endian CPUs, but will run slightly less 60 | * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. 61 | */ 62 | 63 | typedef unsigned char md5_byte_t; /* 8-bit byte */ 64 | typedef unsigned int md5_word_t; /* 32-bit word */ 65 | 66 | /* Define the state of the MD5 Algorithm. */ 67 | typedef struct md5_state_s { 68 | md5_word_t count[2]; /* message length in bits, lsw first */ 69 | md5_word_t abcd[4]; /* digest buffer */ 70 | md5_byte_t buf[64]; /* accumulate block */ 71 | } md5_state_t; 72 | 73 | #ifdef __cplusplus 74 | extern "C" 75 | { 76 | #endif 77 | 78 | /* Initialize the algorithm. */ 79 | void md5_init(md5_state_t *pms); 80 | 81 | /* Append a string to the message. */ 82 | void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); 83 | 84 | /* Finish the message and return the digest. */ 85 | void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); 86 | 87 | #ifdef __cplusplus 88 | } /* end extern "C" */ 89 | #endif 90 | 91 | #endif /* md5_INCLUDED */ 92 | -------------------------------------------------------------------------------- /src/packet.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 02/12/2011 39 | *****************************************************************************/ 40 | 41 | 42 | ////////////////////////////////////////////////////////////////////////////// 43 | // 0 1 2 3 44 | // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 45 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46 | // | Packet Header | 47 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 48 | // | | 49 | // ~ Data / Control Information Field ~ 50 | // | | 51 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 52 | // 53 | // 0 1 2 3 54 | // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 55 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 56 | // |0| Sequence Number | 57 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 58 | // |ff |o| Message Number | 59 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 60 | // | Time Stamp | 61 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 62 | // | Destination Socket ID | 63 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 64 | // 65 | // bit 0: 66 | // 0: Data Packet 67 | // 1: Control Packet 68 | // bit ff: 69 | // 11: solo message packet 70 | // 10: first packet of a message 71 | // 01: last packet of a message 72 | // bit o: 73 | // 0: in order delivery not required 74 | // 1: in order delivery required 75 | // 76 | // 0 1 2 3 77 | // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 78 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 79 | // |1| Type | Reserved | 80 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 81 | // | Additional Info | 82 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 83 | // | Time Stamp | 84 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 85 | // | Destination Socket ID | 86 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 87 | // 88 | // bit 1-15: 89 | // 0: Protocol Connection Handshake 90 | // Add. Info: Undefined 91 | // Control Info: Handshake information (see CHandShake) 92 | // 1: Keep-alive 93 | // Add. Info: Undefined 94 | // Control Info: None 95 | // 2: Acknowledgement (ACK) 96 | // Add. Info: The ACK sequence number 97 | // Control Info: The sequence number to which (but not include) all the previous packets have beed received 98 | // Optional: RTT 99 | // RTT Variance 100 | // available receiver buffer size (in bytes) 101 | // advertised flow window size (number of packets) 102 | // estimated bandwidth (number of packets per second) 103 | // 3: Negative Acknowledgement (NAK) 104 | // Add. Info: Undefined 105 | // Control Info: Loss list (see loss list coding below) 106 | // 4: Congestion/Delay Warning 107 | // Add. Info: Undefined 108 | // Control Info: None 109 | // 5: Shutdown 110 | // Add. Info: Undefined 111 | // Control Info: None 112 | // 6: Acknowledgement of Acknowledement (ACK-square) 113 | // Add. Info: The ACK sequence number 114 | // Control Info: None 115 | // 7: Message Drop Request 116 | // Add. Info: Message ID 117 | // Control Info: first sequence number of the message 118 | // last seqeunce number of the message 119 | // 8: Error Signal from the Peer Side 120 | // Add. Info: Error code 121 | // Control Info: None 122 | // 0x7FFF: Explained by bits 16 - 31 123 | // 124 | // bit 16 - 31: 125 | // This space is used for future expansion or user defined control packets. 126 | // 127 | // 0 1 2 3 128 | // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 129 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 130 | // |1| Sequence Number a (first) | 131 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 132 | // |0| Sequence Number b (last) | 133 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 134 | // |0| Sequence Number (single) | 135 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 136 | // 137 | // Loss List Field Coding: 138 | // For any consectutive lost seqeunce numbers that the differnece between 139 | // the last and first is more than 1, only record the first (a) and the 140 | // the last (b) sequence numbers in the loss list field, and modify the 141 | // the first bit of a to 1. 142 | // For any single loss or consectutive loss less than 2 packets, use 143 | // the original sequence numbers in the field. 144 | 145 | 146 | #include 147 | #include "packet.h" 148 | 149 | 150 | const int CPacket::m_iPktHdrSize = 16; 151 | const int CHandShake::m_iContentSize = 48; 152 | 153 | 154 | // Set up the aliases in the constructure 155 | CPacket::CPacket(): 156 | m_iSeqNo((int32_t&)(m_nHeader[0])), 157 | m_iMsgNo((int32_t&)(m_nHeader[1])), 158 | m_iTimeStamp((int32_t&)(m_nHeader[2])), 159 | m_iID((int32_t&)(m_nHeader[3])), 160 | m_pcData((char*&)(m_PacketVector[1].iov_base)), 161 | __pad() 162 | { 163 | for (int i = 0; i < 4; ++ i) 164 | m_nHeader[i] = 0; 165 | m_PacketVector[0].iov_base = (char *)m_nHeader; 166 | m_PacketVector[0].iov_len = CPacket::m_iPktHdrSize; 167 | m_PacketVector[1].iov_base = NULL; 168 | m_PacketVector[1].iov_len = 0; 169 | } 170 | 171 | CPacket::~CPacket() 172 | { 173 | } 174 | 175 | int CPacket::getLength() const 176 | { 177 | return m_PacketVector[1].iov_len; 178 | } 179 | 180 | void CPacket::setLength(int len) 181 | { 182 | m_PacketVector[1].iov_len = len; 183 | } 184 | 185 | void CPacket::pack(int pkttype, void* lparam, void* rparam, int size) 186 | { 187 | // Set (bit-0 = 1) and (bit-1~15 = type) 188 | m_nHeader[0] = 0x80000000 | (pkttype << 16); 189 | 190 | // Set additional information and control information field 191 | switch (pkttype) 192 | { 193 | case 2: //0010 - Acknowledgement (ACK) 194 | // ACK packet seq. no. 195 | if (NULL != lparam) 196 | m_nHeader[1] = *(int32_t *)lparam; 197 | 198 | // data ACK seq. no. 199 | // optional: RTT (microsends), RTT variance (microseconds) advertised flow window size (packets), and estimated link capacity (packets per second) 200 | m_PacketVector[1].iov_base = (char *)rparam; 201 | m_PacketVector[1].iov_len = size; 202 | 203 | break; 204 | 205 | case 6: //0110 - Acknowledgement of Acknowledgement (ACK-2) 206 | // ACK packet seq. no. 207 | m_nHeader[1] = *(int32_t *)lparam; 208 | 209 | // control info field should be none 210 | // but "writev" does not allow this 211 | m_PacketVector[1].iov_base = (char *)&__pad; //NULL; 212 | m_PacketVector[1].iov_len = 4; //0; 213 | 214 | break; 215 | 216 | case 3: //0011 - Loss Report (NAK) 217 | // loss list 218 | m_PacketVector[1].iov_base = (char *)rparam; 219 | m_PacketVector[1].iov_len = size; 220 | 221 | break; 222 | 223 | case 4: //0100 - Congestion Warning 224 | // control info field should be none 225 | // but "writev" does not allow this 226 | m_PacketVector[1].iov_base = (char *)&__pad; //NULL; 227 | m_PacketVector[1].iov_len = 4; //0; 228 | 229 | break; 230 | 231 | case 1: //0001 - Keep-alive 232 | // control info field should be none 233 | // but "writev" does not allow this 234 | m_PacketVector[1].iov_base = (char *)&__pad; //NULL; 235 | m_PacketVector[1].iov_len = 4; //0; 236 | 237 | break; 238 | 239 | case 0: //0000 - Handshake 240 | // control info filed is handshake info 241 | m_PacketVector[1].iov_base = (char *)rparam; 242 | m_PacketVector[1].iov_len = size; //sizeof(CHandShake); 243 | 244 | break; 245 | 246 | case 5: //0101 - Shutdown 247 | // control info field should be none 248 | // but "writev" does not allow this 249 | m_PacketVector[1].iov_base = (char *)&__pad; //NULL; 250 | m_PacketVector[1].iov_len = 4; //0; 251 | 252 | break; 253 | 254 | case 7: //0111 - Message Drop Request 255 | // msg id 256 | m_nHeader[1] = *(int32_t *)lparam; 257 | 258 | //first seq no, last seq no 259 | m_PacketVector[1].iov_base = (char *)rparam; 260 | m_PacketVector[1].iov_len = size; 261 | 262 | break; 263 | 264 | case 8: //1000 - Error Signal from the Peer Side 265 | // Error type 266 | m_nHeader[1] = *(int32_t *)lparam; 267 | 268 | // control info field should be none 269 | // but "writev" does not allow this 270 | m_PacketVector[1].iov_base = (char *)&__pad; //NULL; 271 | m_PacketVector[1].iov_len = 4; //0; 272 | 273 | break; 274 | 275 | case 32767: //0x7FFF - Reserved for user defined control packets 276 | // for extended control packet 277 | // "lparam" contains the extended type information for bit 16 - 31 278 | // "rparam" is the control information 279 | m_nHeader[0] |= *(int32_t *)lparam; 280 | 281 | if (NULL != rparam) 282 | { 283 | m_PacketVector[1].iov_base = (char *)rparam; 284 | m_PacketVector[1].iov_len = size; 285 | } 286 | else 287 | { 288 | m_PacketVector[1].iov_base = (char *)&__pad; 289 | m_PacketVector[1].iov_len = 4; 290 | } 291 | 292 | break; 293 | 294 | default: 295 | break; 296 | } 297 | } 298 | 299 | iovec* CPacket::getPacketVector() 300 | { 301 | return m_PacketVector; 302 | } 303 | 304 | int CPacket::getFlag() const 305 | { 306 | // read bit 0 307 | return m_nHeader[0] >> 31; 308 | } 309 | 310 | int CPacket::getType() const 311 | { 312 | // read bit 1~15 313 | return (m_nHeader[0] >> 16) & 0x00007FFF; 314 | } 315 | 316 | int CPacket::getExtendedType() const 317 | { 318 | // read bit 16~31 319 | return m_nHeader[0] & 0x0000FFFF; 320 | } 321 | 322 | int32_t CPacket::getAckSeqNo() const 323 | { 324 | // read additional information field 325 | return m_nHeader[1]; 326 | } 327 | 328 | int CPacket::getMsgBoundary() const 329 | { 330 | // read [1] bit 0~1 331 | return m_nHeader[1] >> 30; 332 | } 333 | 334 | bool CPacket::getMsgOrderFlag() const 335 | { 336 | // read [1] bit 2 337 | return (1 == ((m_nHeader[1] >> 29) & 1)); 338 | } 339 | 340 | int32_t CPacket::getMsgSeq() const 341 | { 342 | // read [1] bit 3~31 343 | return m_nHeader[1] & 0x1FFFFFFF; 344 | } 345 | 346 | CPacket* CPacket::clone() const 347 | { 348 | CPacket* pkt = new CPacket; 349 | memcpy(pkt->m_nHeader, m_nHeader, m_iPktHdrSize); 350 | pkt->m_pcData = new char[m_PacketVector[1].iov_len]; 351 | memcpy(pkt->m_pcData, m_pcData, m_PacketVector[1].iov_len); 352 | pkt->m_PacketVector[1].iov_len = m_PacketVector[1].iov_len; 353 | 354 | return pkt; 355 | } 356 | 357 | CHandShake::CHandShake(): 358 | m_iVersion(0), 359 | m_iType(0), 360 | m_iISN(0), 361 | m_iMSS(0), 362 | m_iFlightFlagSize(0), 363 | m_iReqType(0), 364 | m_iID(0), 365 | m_iCookie(0) 366 | { 367 | for (int i = 0; i < 4; ++ i) 368 | m_piPeerIP[i] = 0; 369 | } 370 | 371 | int CHandShake::serialize(char* buf, int& size) 372 | { 373 | if (size < m_iContentSize) 374 | return -1; 375 | 376 | int32_t* p = (int32_t*)buf; 377 | *p++ = m_iVersion; 378 | *p++ = m_iType; 379 | *p++ = m_iISN; 380 | *p++ = m_iMSS; 381 | *p++ = m_iFlightFlagSize; 382 | *p++ = m_iReqType; 383 | *p++ = m_iID; 384 | *p++ = m_iCookie; 385 | for (int i = 0; i < 4; ++ i) 386 | *p++ = m_piPeerIP[i]; 387 | 388 | size = m_iContentSize; 389 | 390 | return 0; 391 | } 392 | 393 | int CHandShake::deserialize(const char* buf, int size) 394 | { 395 | if (size < m_iContentSize) 396 | return -1; 397 | 398 | int32_t* p = (int32_t*)buf; 399 | m_iVersion = *p++; 400 | m_iType = *p++; 401 | m_iISN = *p++; 402 | m_iMSS = *p++; 403 | m_iFlightFlagSize = *p++; 404 | m_iReqType = *p++; 405 | m_iID = *p++; 406 | m_iCookie = *p++; 407 | for (int i = 0; i < 4; ++ i) 408 | m_piPeerIP[i] = *p++; 409 | 410 | return 0; 411 | } 412 | -------------------------------------------------------------------------------- /src/packet.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/02/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_PACKET_H__ 42 | #define __UDT_PACKET_H__ 43 | 44 | 45 | #include "udt.h" 46 | 47 | #ifdef WINDOWS 48 | struct iovec 49 | { 50 | int iov_len; 51 | char* iov_base; 52 | }; 53 | #endif 54 | 55 | class CChannel; 56 | 57 | class CPacket 58 | { 59 | friend class CChannel; 60 | friend class CSndQueue; 61 | friend class CRcvQueue; 62 | 63 | public: 64 | int32_t& m_iSeqNo; // alias: sequence number 65 | int32_t& m_iMsgNo; // alias: message number 66 | int32_t& m_iTimeStamp; // alias: timestamp 67 | int32_t& m_iID; // alias: socket ID 68 | char*& m_pcData; // alias: data/control information 69 | 70 | static const int m_iPktHdrSize; // packet header size 71 | 72 | public: 73 | CPacket(); 74 | ~CPacket(); 75 | 76 | // Functionality: 77 | // Get the payload or the control information field length. 78 | // Parameters: 79 | // None. 80 | // Returned value: 81 | // the payload or the control information field length. 82 | 83 | int getLength() const; 84 | 85 | // Functionality: 86 | // Set the payload or the control information field length. 87 | // Parameters: 88 | // 0) [in] len: the payload or the control information field length. 89 | // Returned value: 90 | // None. 91 | 92 | void setLength(int len); 93 | 94 | // Functionality: 95 | // Pack a Control packet. 96 | // Parameters: 97 | // 0) [in] pkttype: packet type filed. 98 | // 1) [in] lparam: pointer to the first data structure, explained by the packet type. 99 | // 2) [in] rparam: pointer to the second data structure, explained by the packet type. 100 | // 3) [in] size: size of rparam, in number of bytes; 101 | // Returned value: 102 | // None. 103 | 104 | void pack(int pkttype, void* lparam = NULL, void* rparam = NULL, int size = 0); 105 | 106 | // Functionality: 107 | // Read the packet vector. 108 | // Parameters: 109 | // None. 110 | // Returned value: 111 | // Pointer to the packet vector. 112 | 113 | iovec* getPacketVector(); 114 | 115 | // Functionality: 116 | // Read the packet flag. 117 | // Parameters: 118 | // None. 119 | // Returned value: 120 | // packet flag (0 or 1). 121 | 122 | int getFlag() const; 123 | 124 | // Functionality: 125 | // Read the packet type. 126 | // Parameters: 127 | // None. 128 | // Returned value: 129 | // packet type filed (000 ~ 111). 130 | 131 | int getType() const; 132 | 133 | // Functionality: 134 | // Read the extended packet type. 135 | // Parameters: 136 | // None. 137 | // Returned value: 138 | // extended packet type filed (0x000 ~ 0xFFF). 139 | 140 | int getExtendedType() const; 141 | 142 | // Functionality: 143 | // Read the ACK-2 seq. no. 144 | // Parameters: 145 | // None. 146 | // Returned value: 147 | // packet header field (bit 16~31). 148 | 149 | int32_t getAckSeqNo() const; 150 | 151 | // Functionality: 152 | // Read the message boundary flag bit. 153 | // Parameters: 154 | // None. 155 | // Returned value: 156 | // packet header field [1] (bit 0~1). 157 | 158 | int getMsgBoundary() const; 159 | 160 | // Functionality: 161 | // Read the message inorder delivery flag bit. 162 | // Parameters: 163 | // None. 164 | // Returned value: 165 | // packet header field [1] (bit 2). 166 | 167 | bool getMsgOrderFlag() const; 168 | 169 | // Functionality: 170 | // Read the message sequence number. 171 | // Parameters: 172 | // None. 173 | // Returned value: 174 | // packet header field [1] (bit 3~31). 175 | 176 | int32_t getMsgSeq() const; 177 | 178 | // Functionality: 179 | // Clone this packet. 180 | // Parameters: 181 | // None. 182 | // Returned value: 183 | // Pointer to the new packet. 184 | 185 | CPacket* clone() const; 186 | 187 | protected: 188 | uint32_t m_nHeader[4]; // The 128-bit header field 189 | iovec m_PacketVector[2]; // The 2-demension vector of UDT packet [header, data] 190 | 191 | int32_t __pad; 192 | 193 | protected: 194 | CPacket& operator=(const CPacket&); 195 | }; 196 | 197 | //////////////////////////////////////////////////////////////////////////////// 198 | 199 | class CHandShake 200 | { 201 | public: 202 | CHandShake(); 203 | 204 | int serialize(char* buf, int& size); 205 | int deserialize(const char* buf, int size); 206 | 207 | public: 208 | static const int m_iContentSize; // Size of hand shake data 209 | 210 | public: 211 | int32_t m_iVersion; // UDT version 212 | int32_t m_iType; // UDT socket type 213 | int32_t m_iISN; // random initial sequence number 214 | int32_t m_iMSS; // maximum segment size 215 | int32_t m_iFlightFlagSize; // flow control window size 216 | int32_t m_iReqType; // connection request type: 1: regular connection request, 0: rendezvous connection request, -1/-2: response 217 | int32_t m_iID; // socket ID 218 | int32_t m_iCookie; // cookie 219 | uint32_t m_piPeerIP[4]; // The IP address that the peer's UDP port is bound to 220 | }; 221 | 222 | 223 | #endif 224 | -------------------------------------------------------------------------------- /src/udt.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/18/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_H__ 42 | #define __UDT_H__ 43 | 44 | 45 | #ifndef WINDOWS 46 | #include 47 | #include 48 | #include 49 | #else 50 | #include 51 | #include 52 | #include 53 | #endif 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | 60 | //////////////////////////////////////////////////////////////////////////////// 61 | 62 | #ifdef WINDOWS 63 | typedef SOCKET SYSSOCKET; 64 | #define UDT_API 65 | #else 66 | typedef int SYSSOCKET; 67 | #define UDT_API __attribute__ ((visibility("default"))) 68 | #endif 69 | 70 | #define NO_BUSY_WAITING 71 | 72 | typedef SYSSOCKET UDPSOCKET; 73 | typedef int UDTSOCKET; 74 | 75 | //////////////////////////////////////////////////////////////////////////////// 76 | 77 | typedef std::set ud_set; 78 | #define UD_CLR(u, uset) ((uset)->erase(u)) 79 | #define UD_ISSET(u, uset) ((uset)->find(u) != (uset)->end()) 80 | #define UD_SET(u, uset) ((uset)->insert(u)) 81 | #define UD_ZERO(uset) ((uset)->clear()) 82 | 83 | enum EPOLLOpt 84 | { 85 | // this values are defined same as linux epoll.h 86 | // so that if system values are used by mistake, they should have the same effect 87 | UDT_EPOLL_IN = 0x1, 88 | UDT_EPOLL_OUT = 0x4, 89 | UDT_EPOLL_ERR = 0x8 90 | }; 91 | 92 | enum UDTSTATUS {INIT = 1, OPENED, LISTENING, CONNECTING, CONNECTED, BROKEN, CLOSING, CLOSED, NONEXIST}; 93 | 94 | //////////////////////////////////////////////////////////////////////////////// 95 | 96 | enum UDTOpt 97 | { 98 | UDT_MSS, // the Maximum Transfer Unit 99 | UDT_SNDSYN, // if sending is blocking 100 | UDT_RCVSYN, // if receiving is blocking 101 | UDT_CC, // custom congestion control algorithm 102 | UDT_FC, // Flight flag size (window size) 103 | UDT_SNDBUF, // maximum buffer in sending queue 104 | UDT_RCVBUF, // UDT receiving buffer size 105 | UDT_LINGER, // waiting for unsent data when closing 106 | UDP_SNDBUF, // UDP sending buffer size 107 | UDP_RCVBUF, // UDP receiving buffer size 108 | UDT_MAXMSG, // maximum datagram message size 109 | UDT_MSGTTL, // time-to-live of a datagram message 110 | UDT_RENDEZVOUS, // rendezvous connection mode 111 | UDT_SNDTIMEO, // send() timeout 112 | UDT_RCVTIMEO, // recv() timeout 113 | UDT_REUSEADDR, // reuse an existing port or create a new one 114 | UDT_MAXBW, // maximum bandwidth (bytes per second) that the connection can use 115 | UDT_STATE, // current socket state, see UDTSTATUS, read only 116 | UDT_EVENT, // current avalable events associated with the socket 117 | UDT_SNDDATA, // size of data in the sending buffer 118 | UDT_RCVDATA // size of data available for recv 119 | }; 120 | 121 | //////////////////////////////////////////////////////////////////////////////// 122 | 123 | struct CPerfMon 124 | { 125 | // global measurements 126 | int64_t msTimeStamp; // time since the UDT entity is started, in milliseconds 127 | int64_t pktSentTotal; // total number of sent data packets, including retransmissions 128 | int64_t pktRecvTotal; // total number of received packets 129 | int pktSndLossTotal; // total number of lost packets (sender side) 130 | int pktRcvLossTotal; // total number of lost packets (receiver side) 131 | int pktRetransTotal; // total number of retransmitted packets 132 | int pktSentACKTotal; // total number of sent ACK packets 133 | int pktRecvACKTotal; // total number of received ACK packets 134 | int pktSentNAKTotal; // total number of sent NAK packets 135 | int pktRecvNAKTotal; // total number of received NAK packets 136 | int64_t usSndDurationTotal; // total time duration when UDT is sending data (idle time exclusive) 137 | 138 | // local measurements 139 | int64_t pktSent; // number of sent data packets, including retransmissions 140 | int64_t pktRecv; // number of received packets 141 | int pktSndLoss; // number of lost packets (sender side) 142 | int pktRcvLoss; // number of lost packets (receiver side) 143 | int pktRetrans; // number of retransmitted packets 144 | int pktSentACK; // number of sent ACK packets 145 | int pktRecvACK; // number of received ACK packets 146 | int pktSentNAK; // number of sent NAK packets 147 | int pktRecvNAK; // number of received NAK packets 148 | double mbpsSendRate; // sending rate in Mb/s 149 | double mbpsRecvRate; // receiving rate in Mb/s 150 | int64_t usSndDuration; // busy sending time (i.e., idle time exclusive) 151 | 152 | // instant measurements 153 | double usPktSndPeriod; // packet sending period, in microseconds 154 | int pktFlowWindow; // flow window size, in number of packets 155 | int pktCongestionWindow; // congestion window size, in number of packets 156 | int pktFlightSize; // number of packets on flight 157 | double msRTT; // RTT, in milliseconds 158 | double mbpsBandwidth; // estimated bandwidth, in Mb/s 159 | int byteAvailSndBuf; // available UDT sender buffer size 160 | int byteAvailRcvBuf; // available UDT receiver buffer size 161 | }; 162 | 163 | //////////////////////////////////////////////////////////////////////////////// 164 | 165 | class UDT_API CUDTException 166 | { 167 | public: 168 | CUDTException(int major = 0, int minor = 0, int err = -1); 169 | CUDTException(const CUDTException& e); 170 | virtual ~CUDTException(); 171 | 172 | // Functionality: 173 | // Get the description of the exception. 174 | // Parameters: 175 | // None. 176 | // Returned value: 177 | // Text message for the exception description. 178 | 179 | virtual const char* getErrorMessage(); 180 | 181 | // Functionality: 182 | // Get the system errno for the exception. 183 | // Parameters: 184 | // None. 185 | // Returned value: 186 | // errno. 187 | 188 | virtual int getErrorCode() const; 189 | 190 | // Functionality: 191 | // Clear the error code. 192 | // Parameters: 193 | // None. 194 | // Returned value: 195 | // None. 196 | 197 | virtual void clear(); 198 | 199 | private: 200 | int m_iMajor; // major exception categories 201 | 202 | // 0: correct condition 203 | // 1: network setup exception 204 | // 2: network connection broken 205 | // 3: memory exception 206 | // 4: file exception 207 | // 5: method not supported 208 | // 6+: undefined error 209 | 210 | int m_iMinor; // for specific error reasons 211 | int m_iErrno; // errno returned by the system if there is any 212 | std::string m_strMsg; // text error message 213 | 214 | std::string m_strAPI; // the name of UDT function that returns the error 215 | std::string m_strDebug; // debug information, set to the original place that causes the error 216 | 217 | public: // Error Code 218 | static const int SUCCESS; 219 | static const int ECONNSETUP; 220 | static const int ENOSERVER; 221 | static const int ECONNREJ; 222 | static const int ESOCKFAIL; 223 | static const int ESECFAIL; 224 | static const int ECONNFAIL; 225 | static const int ECONNLOST; 226 | static const int ENOCONN; 227 | static const int ERESOURCE; 228 | static const int ETHREAD; 229 | static const int ENOBUF; 230 | static const int EFILE; 231 | static const int EINVRDOFF; 232 | static const int ERDPERM; 233 | static const int EINVWROFF; 234 | static const int EWRPERM; 235 | static const int EINVOP; 236 | static const int EBOUNDSOCK; 237 | static const int ECONNSOCK; 238 | static const int EINVPARAM; 239 | static const int EINVSOCK; 240 | static const int EUNBOUNDSOCK; 241 | static const int ENOLISTEN; 242 | static const int ERDVNOSERV; 243 | static const int ERDVUNBOUND; 244 | static const int ESTREAMILL; 245 | static const int EDGRAMILL; 246 | static const int EDUPLISTEN; 247 | static const int ELARGEMSG; 248 | static const int EINVPOLLID; 249 | static const int EASYNCFAIL; 250 | static const int EASYNCSND; 251 | static const int EASYNCRCV; 252 | static const int ETIMEOUT; 253 | static const int EPEERERR; 254 | static const int EUNKNOWN; 255 | }; 256 | 257 | //////////////////////////////////////////////////////////////////////////////// 258 | 259 | // If you need to export these APIs to be used by a different language, 260 | // declare extern "C" for them, and add a "udt_" prefix to each API. 261 | // The following APIs: sendfile(), recvfile(), epoll_wait(), geterrormsg(), 262 | // include C++ specific feature, please use the corresponding sendfile2(), etc. 263 | 264 | namespace UDT 265 | { 266 | 267 | typedef CUDTException ERRORINFO; 268 | typedef UDTOpt SOCKOPT; 269 | typedef CPerfMon TRACEINFO; 270 | typedef ud_set UDSET; 271 | 272 | UDT_API extern const UDTSOCKET INVALID_SOCK; 273 | #undef ERROR 274 | UDT_API extern const int ERROR; 275 | 276 | UDT_API int startup(); 277 | UDT_API int cleanup(); 278 | UDT_API UDTSOCKET socket(int af, int type, int protocol); 279 | UDT_API int bind(UDTSOCKET u, const struct sockaddr* name, int namelen); 280 | UDT_API int bind2(UDTSOCKET u, UDPSOCKET udpsock); 281 | UDT_API int listen(UDTSOCKET u, int backlog); 282 | UDT_API UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen); 283 | UDT_API int connect(UDTSOCKET u, const struct sockaddr* name, int namelen); 284 | UDT_API int flush(UDTSOCKET u); 285 | UDT_API int close(UDTSOCKET u); 286 | UDT_API int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen); 287 | UDT_API int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen); 288 | UDT_API int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optlen); 289 | UDT_API int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int optlen); 290 | UDT_API int send(UDTSOCKET u, const char* buf, int len, int flags); 291 | UDT_API int recv(UDTSOCKET u, char* buf, int len, int flags); 292 | UDT_API int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false); 293 | UDT_API int recvmsg(UDTSOCKET u, char* buf, int len); 294 | UDT_API int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000); 295 | UDT_API int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000); 296 | UDT_API int64_t sendfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 364000); 297 | UDT_API int64_t recvfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 7280000); 298 | 299 | // select and selectEX are DEPRECATED; please use epoll. 300 | UDT_API int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout); 301 | UDT_API int selectEx(const std::vector& fds, std::vector* readfds, 302 | std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); 303 | 304 | // BARCHART 305 | UDT_API int epoll_update_usock(int eid, UDTSOCKET u, const int* events = NULL); 306 | // BARCHART 307 | UDT_API int epoll_verify_usock(int eid, UDTSOCKET u, int* events); 308 | 309 | UDT_API int epoll_create(); 310 | UDT_API int epoll_add_usock(int eid, UDTSOCKET u, const int* events = NULL); 311 | UDT_API int epoll_add_ssock(int eid, SYSSOCKET s, const int* events = NULL); 312 | UDT_API int epoll_remove_usock(int eid, UDTSOCKET u); 313 | UDT_API int epoll_remove_ssock(int eid, SYSSOCKET s); 314 | UDT_API int epoll_wait(int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, 315 | std::set* lrfds = NULL, std::set* wrfds = NULL); 316 | UDT_API int epoll_wait2(int eid, UDTSOCKET* readfds, int* rnum, UDTSOCKET* writefds, int* wnum, int64_t msTimeOut, 317 | SYSSOCKET* lrfds = NULL, int* lrnum = NULL, SYSSOCKET* lwfds = NULL, int* lwnum = NULL); 318 | UDT_API int epoll_release(int eid); 319 | UDT_API ERRORINFO& getlasterror(); 320 | UDT_API int getlasterror_code(); 321 | UDT_API const char* getlasterror_desc(); 322 | UDT_API int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear = true); 323 | UDT_API UDTSTATUS getsockstate(UDTSOCKET u); 324 | 325 | } // namespace UDT 326 | 327 | #endif 328 | -------------------------------------------------------------------------------- /src/udtCommon.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 08/01/2009 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_COMMON_H__ 42 | #define __UDT_COMMON_H__ 43 | 44 | 45 | #ifndef WINDOWS 46 | #include 47 | #include 48 | #include 49 | #else 50 | #include 51 | #include 52 | #include 53 | #endif 54 | #include 55 | #include "udt.h" 56 | 57 | 58 | #ifdef WINDOWS 59 | // Windows compatibility 60 | typedef HANDLE udt_pthread_t; 61 | typedef HANDLE udt_pthread_mutex_t; 62 | typedef HANDLE udt_pthread_cond_t; 63 | typedef DWORD udt_pthread_key_t; 64 | #else 65 | typedef pthread_t udt_pthread_t; 66 | typedef pthread_mutex_t udt_pthread_mutex_t; 67 | typedef pthread_cond_t udt_pthread_cond_t; 68 | typedef pthread_key_t udt_pthread_key_t; 69 | #endif 70 | 71 | 72 | //////////////////////////////////////////////////////////////////////////////// 73 | 74 | class CTimer 75 | { 76 | public: 77 | CTimer(); 78 | ~CTimer(); 79 | 80 | public: 81 | 82 | // Functionality: 83 | // Sleep for "interval" CCs. 84 | // Parameters: 85 | // 0) [in] interval: CCs to sleep. 86 | // Returned value: 87 | // None. 88 | 89 | void sleep(uint64_t interval); 90 | 91 | // Functionality: 92 | // Seelp until CC "nexttime". 93 | // Parameters: 94 | // 0) [in] nexttime: next time the caller is waken up. 95 | // Returned value: 96 | // None. 97 | 98 | void sleepto(uint64_t nexttime); 99 | 100 | // Functionality: 101 | // Stop the sleep() or sleepto() methods. 102 | // Parameters: 103 | // None. 104 | // Returned value: 105 | // None. 106 | 107 | void interrupt(); 108 | 109 | // Functionality: 110 | // trigger the clock for a tick, for better granuality in no_busy_waiting timer. 111 | // Parameters: 112 | // None. 113 | // Returned value: 114 | // None. 115 | 116 | void tick(); 117 | 118 | public: 119 | 120 | // Functionality: 121 | // Read the CPU clock cycle into x. 122 | // Parameters: 123 | // 0) [out] x: to record cpu clock cycles. 124 | // Returned value: 125 | // None. 126 | 127 | static void rdtsc(uint64_t &x); 128 | 129 | // Functionality: 130 | // return the CPU frequency. 131 | // Parameters: 132 | // None. 133 | // Returned value: 134 | // CPU frequency. 135 | 136 | static uint64_t getCPUFrequency(); 137 | 138 | // Functionality: 139 | // check the current time, 64bit, in microseconds. 140 | // Parameters: 141 | // None. 142 | // Returned value: 143 | // current time in microseconds. 144 | 145 | static uint64_t getTime(); 146 | 147 | // Functionality: 148 | // trigger an event such as new connection, close, new data, etc. for "select" call. 149 | // Parameters: 150 | // None. 151 | // Returned value: 152 | // None. 153 | 154 | static void triggerEvent(); 155 | 156 | // Functionality: 157 | // wait for an event to br triggered by "triggerEvent". 158 | // Parameters: 159 | // None. 160 | // Returned value: 161 | // None. 162 | 163 | static void waitForEvent(); 164 | 165 | // Functionality: 166 | // sleep for a short interval. exact sleep time does not matter 167 | // Parameters: 168 | // None. 169 | // Returned value: 170 | // None. 171 | 172 | static void sleep(); 173 | 174 | private: 175 | uint64_t getTimeInMicroSec(); 176 | 177 | private: 178 | uint64_t m_ullSchedTime; // next schedulled time 179 | 180 | udt_pthread_cond_t m_TickCond; 181 | udt_pthread_mutex_t m_TickLock; 182 | 183 | static udt_pthread_cond_t m_EventCond; 184 | static udt_pthread_mutex_t m_EventLock; 185 | 186 | private: 187 | static uint64_t s_ullCPUFrequency; // CPU frequency : clock cycles per microsecond 188 | static uint64_t readCPUFrequency(); 189 | static bool m_bUseMicroSecond; // No higher resolution timer available, use gettimeofday(). 190 | }; 191 | 192 | //////////////////////////////////////////////////////////////////////////////// 193 | 194 | class CGuard 195 | { 196 | public: 197 | CGuard(udt_pthread_mutex_t& lock); 198 | ~CGuard(); 199 | 200 | public: 201 | static void enterCS(udt_pthread_mutex_t& lock); 202 | static void leaveCS(udt_pthread_mutex_t& lock); 203 | 204 | static void createMutex(udt_pthread_mutex_t& lock); 205 | static void releaseMutex(udt_pthread_mutex_t& lock); 206 | 207 | static void createCond(udt_pthread_cond_t& cond); 208 | static void releaseCond(udt_pthread_cond_t& cond); 209 | 210 | private: 211 | udt_pthread_mutex_t& m_Mutex; // Alias name of the mutex to be protected 212 | unsigned int m_iLocked; // Locking status 213 | 214 | CGuard& operator=(const CGuard&); 215 | }; 216 | 217 | 218 | 219 | //////////////////////////////////////////////////////////////////////////////// 220 | 221 | // UDT Sequence Number 0 - (2^31 - 1) 222 | 223 | // seqcmp: compare two seq#, considering the wraping 224 | // seqlen: length from the 1st to the 2nd seq#, including both 225 | // seqoff: offset from the 2nd to the 1st seq# 226 | // incseq: increase the seq# by 1 227 | // decseq: decrease the seq# by 1 228 | // incseq: increase the seq# by a given offset 229 | 230 | class CSeqNo 231 | { 232 | public: 233 | inline static int seqcmp(int32_t seq1, int32_t seq2) 234 | {return (abs(seq1 - seq2) < m_iSeqNoTH) ? (seq1 - seq2) : (seq2 - seq1);} 235 | 236 | inline static int seqlen(int32_t seq1, int32_t seq2) 237 | {return (seq1 <= seq2) ? (seq2 - seq1 + 1) : (seq2 - seq1 + m_iMaxSeqNo + 2);} 238 | 239 | inline static int seqoff(int32_t seq1, int32_t seq2) 240 | { 241 | if (abs(seq1 - seq2) < m_iSeqNoTH) 242 | return seq2 - seq1; 243 | 244 | if (seq1 < seq2) 245 | return seq2 - seq1 - m_iMaxSeqNo - 1; 246 | 247 | return seq2 - seq1 + m_iMaxSeqNo + 1; 248 | } 249 | 250 | inline static int32_t incseq(int32_t seq) 251 | {return (seq == m_iMaxSeqNo) ? 0 : seq + 1;} 252 | 253 | inline static int32_t decseq(int32_t seq) 254 | {return (seq == 0) ? m_iMaxSeqNo : seq - 1;} 255 | 256 | inline static int32_t incseq(int32_t seq, int32_t inc) 257 | {return (m_iMaxSeqNo - seq >= inc) ? seq + inc : seq - m_iMaxSeqNo + inc - 1;} 258 | 259 | public: 260 | static const int32_t m_iSeqNoTH; // threshold for comparing seq. no. 261 | static const int32_t m_iMaxSeqNo; // maximum sequence number used in UDT 262 | }; 263 | 264 | //////////////////////////////////////////////////////////////////////////////// 265 | 266 | // UDT ACK Sub-sequence Number: 0 - (2^31 - 1) 267 | 268 | class CAckNo 269 | { 270 | public: 271 | inline static int32_t incack(int32_t ackno) 272 | {return (ackno == m_iMaxAckSeqNo) ? 0 : ackno + 1;} 273 | 274 | public: 275 | static const int32_t m_iMaxAckSeqNo; // maximum ACK sub-sequence number used in UDT 276 | }; 277 | 278 | //////////////////////////////////////////////////////////////////////////////// 279 | 280 | // UDT Message Number: 0 - (2^29 - 1) 281 | 282 | class CMsgNo 283 | { 284 | public: 285 | inline static int msgcmp(int32_t msgno1, int32_t msgno2) 286 | {return (abs(msgno1 - msgno2) < m_iMsgNoTH) ? (msgno1 - msgno2) : (msgno2 - msgno1);} 287 | 288 | inline static int msglen(int32_t msgno1, int32_t msgno2) 289 | {return (msgno1 <= msgno2) ? (msgno2 - msgno1 + 1) : (msgno2 - msgno1 + m_iMaxMsgNo + 2);} 290 | 291 | inline static int msgoff(int32_t msgno1, int32_t msgno2) 292 | { 293 | if (abs(msgno1 - msgno2) < m_iMsgNoTH) 294 | return msgno2 - msgno1; 295 | 296 | if (msgno1 < msgno2) 297 | return msgno2 - msgno1 - m_iMaxMsgNo - 1; 298 | 299 | return msgno2 - msgno1 + m_iMaxMsgNo + 1; 300 | } 301 | 302 | inline static int32_t incmsg(int32_t msgno) 303 | {return (msgno == m_iMaxMsgNo) ? 0 : msgno + 1;} 304 | 305 | public: 306 | static const int32_t m_iMsgNoTH; // threshold for comparing msg. no. 307 | static const int32_t m_iMaxMsgNo; // maximum message number used in UDT 308 | }; 309 | 310 | //////////////////////////////////////////////////////////////////////////////// 311 | 312 | struct CIPAddress 313 | { 314 | static bool ipcmp(const sockaddr* addr1, const sockaddr* addr2, int ver = AF_INET); 315 | static void ntop(const sockaddr* addr, uint32_t ip[4], int ver = AF_INET); 316 | static void pton(sockaddr* addr, const uint32_t ip[4], int ver = AF_INET); 317 | }; 318 | 319 | //////////////////////////////////////////////////////////////////////////////// 320 | 321 | struct CMD5 322 | { 323 | static void compute(const char* input, unsigned char result[16]); 324 | }; 325 | 326 | 327 | #endif 328 | -------------------------------------------------------------------------------- /src/window.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/22/2011 39 | *****************************************************************************/ 40 | 41 | #include 42 | #include "udtCommon.h" 43 | #include "window.h" 44 | #include 45 | 46 | using namespace std; 47 | 48 | CACKWindow::CACKWindow(int size): 49 | m_piACKSeqNo(NULL), 50 | m_piACK(NULL), 51 | m_pTimeStamp(NULL), 52 | m_iSize(size), 53 | m_iHead(0), 54 | m_iTail(0) 55 | { 56 | m_piACKSeqNo = new int32_t[m_iSize]; 57 | m_piACK = new int32_t[m_iSize]; 58 | m_pTimeStamp = new uint64_t[m_iSize]; 59 | 60 | m_piACKSeqNo[0] = -1; 61 | } 62 | 63 | CACKWindow::~CACKWindow() 64 | { 65 | delete [] m_piACKSeqNo; 66 | delete [] m_piACK; 67 | delete [] m_pTimeStamp; 68 | } 69 | 70 | void CACKWindow::store(int32_t seq, int32_t ack) 71 | { 72 | m_piACKSeqNo[m_iHead] = seq; 73 | m_piACK[m_iHead] = ack; 74 | m_pTimeStamp[m_iHead] = CTimer::getTime(); 75 | 76 | m_iHead = (m_iHead + 1) % m_iSize; 77 | 78 | // overwrite the oldest ACK since it is not likely to be acknowledged 79 | if (m_iHead == m_iTail) 80 | m_iTail = (m_iTail + 1) % m_iSize; 81 | } 82 | 83 | int CACKWindow::acknowledge(int32_t seq, int32_t& ack) 84 | { 85 | if (m_iHead >= m_iTail) 86 | { 87 | // Head has not exceeded the physical boundary of the window 88 | 89 | for (int i = m_iTail, n = m_iHead; i < n; ++ i) 90 | { 91 | // looking for indentical ACK Seq. No. 92 | if (seq == m_piACKSeqNo[i]) 93 | { 94 | // return the Data ACK it carried 95 | ack = m_piACK[i]; 96 | 97 | // calculate RTT 98 | int rtt = int(CTimer::getTime() - m_pTimeStamp[i]); 99 | 100 | if (i + 1 == m_iHead) 101 | { 102 | m_iTail = m_iHead = 0; 103 | m_piACKSeqNo[0] = -1; 104 | } 105 | else 106 | m_iTail = (i + 1) % m_iSize; 107 | 108 | return rtt; 109 | } 110 | } 111 | 112 | // Bad input, the ACK node has been overwritten 113 | return -1; 114 | } 115 | 116 | // Head has exceeded the physical window boundary, so it is behind tail 117 | for (int j = m_iTail, n = m_iHead + m_iSize; j < n; ++ j) 118 | { 119 | // looking for indentical ACK seq. no. 120 | if (seq == m_piACKSeqNo[j % m_iSize]) 121 | { 122 | // return Data ACK 123 | j %= m_iSize; 124 | ack = m_piACK[j]; 125 | 126 | // calculate RTT 127 | int rtt = int(CTimer::getTime() - m_pTimeStamp[j]); 128 | 129 | if (j == m_iHead) 130 | { 131 | m_iTail = m_iHead = 0; 132 | m_piACKSeqNo[0] = -1; 133 | } 134 | else 135 | m_iTail = (j + 1) % m_iSize; 136 | 137 | return rtt; 138 | } 139 | } 140 | 141 | // bad input, the ACK node has been overwritten 142 | return -1; 143 | } 144 | 145 | //////////////////////////////////////////////////////////////////////////////// 146 | 147 | CPktTimeWindow::CPktTimeWindow(int asize, int psize): 148 | m_iAWSize(asize), 149 | m_piPktWindow(NULL), 150 | m_iPktWindowPtr(0), 151 | m_iPWSize(psize), 152 | m_piProbeWindow(NULL), 153 | m_iProbeWindowPtr(0), 154 | m_iLastSentTime(0), 155 | m_iMinPktSndInt(1000000), 156 | m_LastArrTime(), 157 | m_CurrArrTime(), 158 | m_ProbeTime() 159 | { 160 | m_piPktWindow = new int[m_iAWSize]; 161 | m_piPktReplica = new int[m_iAWSize]; 162 | m_piProbeWindow = new int[m_iPWSize]; 163 | m_piProbeReplica = new int[m_iPWSize]; 164 | 165 | m_LastArrTime = CTimer::getTime(); 166 | 167 | for (int i = 0; i < m_iAWSize; ++ i) 168 | m_piPktWindow[i] = 1000000; 169 | 170 | for (int k = 0; k < m_iPWSize; ++ k) 171 | m_piProbeWindow[k] = 1000; 172 | } 173 | 174 | CPktTimeWindow::~CPktTimeWindow() 175 | { 176 | delete [] m_piPktWindow; 177 | delete [] m_piPktReplica; 178 | delete [] m_piProbeWindow; 179 | delete [] m_piProbeReplica; 180 | } 181 | 182 | int CPktTimeWindow::getMinPktSndInt() const 183 | { 184 | return m_iMinPktSndInt; 185 | } 186 | 187 | int CPktTimeWindow::getPktRcvSpeed() const 188 | { 189 | // get median value, but cannot change the original value order in the window 190 | std::copy(m_piPktWindow, m_piPktWindow + m_iAWSize - 1, m_piPktReplica); 191 | std::nth_element(m_piPktReplica, m_piPktReplica + (m_iAWSize / 2), m_piPktReplica + m_iAWSize - 1); 192 | int median = m_piPktReplica[m_iAWSize / 2]; 193 | 194 | int count = 0; 195 | int sum = 0; 196 | int upper = median << 3; 197 | int lower = median >> 3; 198 | 199 | // median filtering 200 | int* p = m_piPktWindow; 201 | for (int i = 0, n = m_iAWSize; i < n; ++ i) 202 | { 203 | if ((*p < upper) && (*p > lower)) 204 | { 205 | ++ count; 206 | sum += *p; 207 | } 208 | ++ p; 209 | } 210 | 211 | // claculate speed, or return 0 if not enough valid value 212 | if (count > (m_iAWSize >> 1)) 213 | return (int)ceil(1000000.0 / (sum / count)); 214 | else 215 | return 0; 216 | } 217 | 218 | int CPktTimeWindow::getBandwidth() const 219 | { 220 | // get median value, but cannot change the original value order in the window 221 | std::copy(m_piProbeWindow, m_piProbeWindow + m_iPWSize - 1, m_piProbeReplica); 222 | std::nth_element(m_piProbeReplica, m_piProbeReplica + (m_iPWSize / 2), m_piProbeReplica + m_iPWSize - 1); 223 | int median = m_piProbeReplica[m_iPWSize / 2]; 224 | 225 | int count = 1; 226 | int sum = median; 227 | int upper = median << 3; 228 | int lower = median >> 3; 229 | 230 | // median filtering 231 | int* p = m_piProbeWindow; 232 | for (int i = 0, n = m_iPWSize; i < n; ++ i) 233 | { 234 | if ((*p < upper) && (*p > lower)) 235 | { 236 | ++ count; 237 | sum += *p; 238 | } 239 | ++ p; 240 | } 241 | 242 | return (int)ceil(1000000.0 / (double(sum) / double(count))); 243 | } 244 | 245 | void CPktTimeWindow::onPktSent(int currtime) 246 | { 247 | int interval = currtime - m_iLastSentTime; 248 | 249 | if ((interval < m_iMinPktSndInt) && (interval > 0)) 250 | m_iMinPktSndInt = interval; 251 | 252 | m_iLastSentTime = currtime; 253 | } 254 | 255 | void CPktTimeWindow::onPktArrival() 256 | { 257 | m_CurrArrTime = CTimer::getTime(); 258 | 259 | // record the packet interval between the current and the last one 260 | *(m_piPktWindow + m_iPktWindowPtr) = int(m_CurrArrTime - m_LastArrTime); 261 | 262 | // the window is logically circular 263 | ++ m_iPktWindowPtr; 264 | if (m_iPktWindowPtr == m_iAWSize) 265 | m_iPktWindowPtr = 0; 266 | 267 | // remember last packet arrival time 268 | m_LastArrTime = m_CurrArrTime; 269 | } 270 | 271 | void CPktTimeWindow::probe1Arrival() 272 | { 273 | m_ProbeTime = CTimer::getTime(); 274 | } 275 | 276 | void CPktTimeWindow::probe2Arrival() 277 | { 278 | m_CurrArrTime = CTimer::getTime(); 279 | 280 | // record the probing packets interval 281 | *(m_piProbeWindow + m_iProbeWindowPtr) = int(m_CurrArrTime - m_ProbeTime); 282 | // the window is logically circular 283 | ++ m_iProbeWindowPtr; 284 | if (m_iProbeWindowPtr == m_iPWSize) 285 | m_iProbeWindowPtr = 0; 286 | } 287 | -------------------------------------------------------------------------------- /src/window.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the 11 | following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the 14 | above copyright notice, this list of conditions 15 | and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the University of Illinois 19 | nor the names of its contributors may be used to 20 | endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | *****************************************************************************/ 35 | 36 | /***************************************************************************** 37 | written by 38 | Yunhong Gu, last updated 01/22/2011 39 | *****************************************************************************/ 40 | 41 | #ifndef __UDT_WINDOW_H__ 42 | #define __UDT_WINDOW_H__ 43 | 44 | 45 | #ifndef WINDOWS 46 | #include 47 | #include 48 | #endif 49 | #include "udt.h" 50 | 51 | 52 | class CACKWindow 53 | { 54 | public: 55 | CACKWindow(int size = 1024); 56 | ~CACKWindow(); 57 | 58 | // Functionality: 59 | // Write an ACK record into the window. 60 | // Parameters: 61 | // 0) [in] seq: ACK seq. no. 62 | // 1) [in] ack: DATA ACK no. 63 | // Returned value: 64 | // None. 65 | 66 | void store(int32_t seq, int32_t ack); 67 | 68 | // Functionality: 69 | // Search the ACK-2 "seq" in the window, find out the DATA "ack" and caluclate RTT . 70 | // Parameters: 71 | // 0) [in] seq: ACK-2 seq. no. 72 | // 1) [out] ack: the DATA ACK no. that matches the ACK-2 no. 73 | // Returned value: 74 | // RTT. 75 | 76 | int acknowledge(int32_t seq, int32_t& ack); 77 | 78 | private: 79 | int32_t* m_piACKSeqNo; // Seq. No. for the ACK packet 80 | int32_t* m_piACK; // Data Seq. No. carried by the ACK packet 81 | uint64_t* m_pTimeStamp; // The timestamp when the ACK was sent 82 | 83 | int m_iSize; // Size of the ACK history window 84 | int m_iHead; // Pointer to the lastest ACK record 85 | int m_iTail; // Pointer to the oldest ACK record 86 | 87 | private: 88 | CACKWindow(const CACKWindow&); 89 | CACKWindow& operator=(const CACKWindow&); 90 | }; 91 | 92 | //////////////////////////////////////////////////////////////////////////////// 93 | 94 | class CPktTimeWindow 95 | { 96 | public: 97 | CPktTimeWindow(int asize = 16, int psize = 16); 98 | ~CPktTimeWindow(); 99 | 100 | // Functionality: 101 | // read the minimum packet sending interval. 102 | // Parameters: 103 | // None. 104 | // Returned value: 105 | // minimum packet sending interval (microseconds). 106 | 107 | int getMinPktSndInt() const; 108 | 109 | // Functionality: 110 | // Calculate the packes arrival speed. 111 | // Parameters: 112 | // None. 113 | // Returned value: 114 | // Packet arrival speed (packets per second). 115 | 116 | int getPktRcvSpeed() const; 117 | 118 | // Functionality: 119 | // Estimate the bandwidth. 120 | // Parameters: 121 | // None. 122 | // Returned value: 123 | // Estimated bandwidth (packets per second). 124 | 125 | int getBandwidth() const; 126 | 127 | // Functionality: 128 | // Record time information of a packet sending. 129 | // Parameters: 130 | // 0) currtime: timestamp of the packet sending. 131 | // Returned value: 132 | // None. 133 | 134 | void onPktSent(int currtime); 135 | 136 | // Functionality: 137 | // Record time information of an arrived packet. 138 | // Parameters: 139 | // None. 140 | // Returned value: 141 | // None. 142 | 143 | void onPktArrival(); 144 | 145 | // Functionality: 146 | // Record the arrival time of the first probing packet. 147 | // Parameters: 148 | // None. 149 | // Returned value: 150 | // None. 151 | 152 | void probe1Arrival(); 153 | 154 | // Functionality: 155 | // Record the arrival time of the second probing packet and the interval between packet pairs. 156 | // Parameters: 157 | // None. 158 | // Returned value: 159 | // None. 160 | 161 | void probe2Arrival(); 162 | 163 | private: 164 | int m_iAWSize; // size of the packet arrival history window 165 | int* m_piPktWindow; // packet information window 166 | int* m_piPktReplica; 167 | int m_iPktWindowPtr; // position pointer of the packet info. window. 168 | 169 | int m_iPWSize; // size of probe history window size 170 | int* m_piProbeWindow; // record inter-packet time for probing packet pairs 171 | int* m_piProbeReplica; 172 | int m_iProbeWindowPtr; // position pointer to the probing window 173 | 174 | int m_iLastSentTime; // last packet sending time 175 | int m_iMinPktSndInt; // Minimum packet sending interval 176 | 177 | uint64_t m_LastArrTime; // last packet arrival time 178 | uint64_t m_CurrArrTime; // current packet arrival time 179 | uint64_t m_ProbeTime; // arrival time of the first probing packet 180 | 181 | private: 182 | CPktTimeWindow(const CPktTimeWindow&); 183 | CPktTimeWindow &operator=(const CPktTimeWindow&); 184 | }; 185 | 186 | 187 | #endif 188 | -------------------------------------------------------------------------------- /udt-doc/0003-Code-polish.-removed-unnecessary-preprocessor-symbol.patch: -------------------------------------------------------------------------------- 1 | From 60a91b17be591edad3c10df0b26d45c79dff7def Mon Sep 17 00:00:00 2001 2 | From: nathan 3 | Date: Thu, 8 Jan 2015 23:31:27 +0100 4 | Subject: [PATCH 3/5] Code polish. removed unnecessary preprocessor symbols 5 | 6 | --- 7 | JavaLauncherApp/make_common.mak | 5 +---- 8 | JavaLauncherApp/src/common.c | 10 +++++----- 9 | 2 files changed, 6 insertions(+), 9 deletions(-) 10 | 11 | diff --git a/JavaLauncherApp/make_common.mak b/JavaLauncherApp/make_common.mak 12 | index 65536b0..1b55a95 100644 13 | --- a/JavaLauncherApp/make_common.mak 14 | +++ b/JavaLauncherApp/make_common.mak 15 | @@ -181,11 +181,8 @@ ifeq ($(COMPILE_OS_ARCH),32) 16 | PROGRAM_PATH+=bin/$(DIST_OS_NAME) 17 | endif 18 | 19 | - 20 | - #udt config 21 | - FLAGS +=-DIA32 22 | else ifeq ($(COMPILE_OS_ARCH),64) 23 | - FLAGS +=-DAMD64 -D_AMD64_ -D__AMD64__ 24 | + FLAGS +=-DAMD64 25 | M_ARCH=-m64 26 | DIST_OS_NAME=$(COMPILE_OS)_64 27 | 28 | diff --git a/JavaLauncherApp/src/common.c b/JavaLauncherApp/src/common.c 29 | index 20f55ee..51a0e51 100644 30 | --- a/JavaLauncherApp/src/common.c 31 | +++ b/JavaLauncherApp/src/common.c 32 | @@ -123,7 +123,7 @@ _TCHAR* findSymlinkCommand(_TCHAR* command, int resolve) { 33 | else { 34 | /* Get the directory PATH where executables reside. */ 35 | path = _tgetenv(_T_STRING("PATH")); 36 | - #ifdef WINDOWS 37 | + #ifdef WINDOWS 38 | /* on windows, prepend the current directory */ 39 | if (path == NULL) 40 | path = _T_STRING(""); 41 | @@ -133,7 +133,7 @@ _TCHAR* findSymlinkCommand(_TCHAR* command, int resolve) { 42 | ch[length] = PATH_SEPARATOR; 43 | _tcscpy(&ch[length + 1], path); 44 | path = ch; 45 | - #endif 46 | + #endif 47 | if (!path) { 48 | return NULL; 49 | } else { 50 | @@ -306,9 +306,9 @@ _TCHAR* fixupPath(_TCHAR* path, _TCHAR* programDir, bool programDirFirst, bool a 51 | } 52 | 53 | _TCHAR * lastDirSeparator(_TCHAR* str) { 54 | - #ifndef WINDOWS 55 | + #ifndef WINDOWS 56 | return _tcsrchr(str, DIR_SEPARATOR); 57 | - #else 58 | + #else 59 | int i = -1; 60 | _TCHAR * c = NULL; 61 | while (str[++i] != 0) { 62 | @@ -316,7 +316,7 @@ _TCHAR * lastDirSeparator(_TCHAR* str) { 63 | c = &str[i]; 64 | } 65 | return c; 66 | - #endif 67 | + #endif 68 | } 69 | 70 | _TCHAR * firstDirSeparator(_TCHAR* str) { 71 | -- 72 | 1.9.1 73 | 74 | -------------------------------------------------------------------------------- /udt-doc/0004-Fixed-unitialized-variable.patch: -------------------------------------------------------------------------------- 1 | From fc0f8e2f8f8abeae9cd71a4fe9c0244981e12d64 Mon Sep 17 00:00:00 2001 2 | From: nathan 3 | Date: Fri, 9 Jan 2015 01:22:45 +0100 4 | Subject: [PATCH 4/5] Fixed unitialized variable 5 | 6 | --- 7 | JavaLauncherApp/src/udt/core.cpp | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/JavaLauncherApp/src/udt/core.cpp b/JavaLauncherApp/src/udt/core.cpp 11 | index c1c8d03..a5acfa7 100644 12 | --- a/JavaLauncherApp/src/udt/core.cpp 13 | +++ b/JavaLauncherApp/src/udt/core.cpp 14 | @@ -2285,7 +2285,7 @@ int CUDT::packData(CPacket& packet, uint64_t& ts) 15 | if (offset < 0) 16 | return 0; 17 | 18 | - int msglen; 19 | + int msglen = 0; 20 | 21 | payload = m_pSndBuffer->readData(&(packet.m_pcData), offset, packet.m_iMsgNo, msglen); 22 | 23 | -- 24 | 1.9.1 25 | 26 | -------------------------------------------------------------------------------- /udt-doc/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above 9 | copyright notice, this list of conditions and the 10 | following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the 13 | above copyright notice, this list of conditions 14 | and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the University of Illinois 18 | nor the names of its contributors may be used to 19 | endorse or promote products derived from this 20 | software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /udt-doc/README.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. 2 | All Rights Reserved. 3 | Copyright (c) 2011 - 2012, Google, Inc. All Rights Reserved. 4 | 5 | UDP-based Data Transfer (UDT) Library - version 4 6 | Author: Yunhong Gu [yunhong.gu @ gmail.com] 7 | 8 | UDT version 4 is free software under BSD License. See ./LICENSE.txt. 9 | 10 | ============================================================================ 11 | 12 | UDT Website: 13 | http://udt.sf.net 14 | http://sf.net/projects/udt/ 15 | -------------------------------------------------------------------------------- /udt-doc/RELEASE_NOTES.txt: -------------------------------------------------------------------------------- 1 | version 4.13 2 | 3 | removed java bits (after performance testing, the JNI wasn't as fast as hoped, likely because of JVM issues) 4 | cleaned up build 5 | added cmake (from Bjorn Stahl, thank you!) 6 | 7 | 8 | version 4.12 9 | 10 | NOTE: Fixed linux timer step from patch in help thread. Also some misc fixes -- see patches. 11 | 12 | 13 | --------------------------------------------------------- 14 | The following notes are from the (no longer maintained) sourceforge repository. 15 | 16 | 17 | version 4.11 18 | 19 | mostly bug fixes since last version. 20 | 21 | 22 | 23 | version 4.10 24 | 25 | added UDT_SNDDATA and UDT_RCVDATA options 26 | fixed a bug that causes unnecessary connection timeout 27 | improved epoll UDT event handling 28 | 29 | 30 | 31 | version 4.9 32 | 33 | asynchronous close 34 | asynchronous connect 35 | some bug fixes, especially on EPOLL 36 | improved cache code 37 | removed unnecessary NAK (reduced loss retransmission) 38 | receiver side error can unblock a blocked sender 39 | 40 | 41 | 42 | version 4.8 43 | 44 | fix a bug that may cause seg fault on concurrent close on the same socket 45 | add epoll support 46 | increase the listener's scalability to 100K concurrent connections 47 | fix a bug that may cause accept/select to return positively when an accepted socket is closed immediately after accept returns 48 | fix a bug that may cause connect to fail if the server closes listening socket immediately after accept returns 49 | fix recvfile fstream write status bug (e.g., when disk is full, recvfile should handle properly now) 50 | 51 | 52 | 53 | version 4.7a 54 | 55 | fix timeout bug introduced in 4.7 56 | initialize CHandShake 57 | 58 | 59 | 60 | version 4.7 61 | 62 | Fix several related bugs that can cause hang/memory leak/segmentation fault during cleanup() 63 | -------------------------------------------------------------------------------- /udt-doc/udt-2009.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dorkbox/UDT/8272c251deb8bfd7289646b7604f1079b59194d0/udt-doc/udt-2009.ppt -------------------------------------------------------------------------------- /udt-doc/udt-sc08-poster.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dorkbox/UDT/8272c251deb8bfd7289646b7604f1079b59194d0/udt-doc/udt-sc08-poster.pdf --------------------------------------------------------------------------------