From b07f42955666cc44571d9f527a4e540a5431fabf Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 3 Jan 2017 15:13:22 -0500 Subject: [PATCH] remove udt and make websocketpp includes public --- CMakeLists.txt | 9 +- include/fc/network/udt_socket.hpp | 70 - src/network/udt_socket.cpp | 405 ----- tests/CMakeLists.txt | 7 - vendor/udt4/CMakeLists.txt | 26 - vendor/udt4/LICENSE.txt | 32 - vendor/udt4/README.txt | 43 - vendor/udt4/src/api.cpp | 2392 -------------------------- vendor/udt4/src/api.h | 268 --- vendor/udt4/src/buffer.cpp | 652 ------- vendor/udt4/src/buffer.h | 275 --- vendor/udt4/src/cache.cpp | 123 -- vendor/udt4/src/cache.h | 293 ---- vendor/udt4/src/ccc.cpp | 314 ---- vendor/udt4/src/ccc.h | 278 --- vendor/udt4/src/channel.cpp | 340 ---- vendor/udt4/src/channel.h | 171 -- vendor/udt4/src/common.cpp | 765 --------- vendor/udt4/src/common.h | 321 ---- vendor/udt4/src/core.cpp | 2675 ----------------------------- vendor/udt4/src/core.h | 458 ----- vendor/udt4/src/epoll.cpp | 367 ---- vendor/udt4/src/epoll.h | 173 -- vendor/udt4/src/list.cpp | 703 -------- vendor/udt4/src/list.h | 202 --- vendor/udt4/src/md5.cpp | 381 ---- vendor/udt4/src/md5.h | 91 - vendor/udt4/src/packet.cpp | 411 ----- vendor/udt4/src/packet.h | 223 --- vendor/udt4/src/queue.cpp | 1253 -------------- vendor/udt4/src/queue.h | 527 ------ vendor/udt4/src/udt.h | 359 ---- vendor/udt4/src/window.cpp | 286 --- vendor/udt4/src/window.h | 187 -- 34 files changed, 3 insertions(+), 15077 deletions(-) delete mode 100644 include/fc/network/udt_socket.hpp delete mode 100644 src/network/udt_socket.cpp delete mode 100644 vendor/udt4/CMakeLists.txt delete mode 100644 vendor/udt4/LICENSE.txt delete mode 100644 vendor/udt4/README.txt delete mode 100644 vendor/udt4/src/api.cpp delete mode 100644 vendor/udt4/src/api.h delete mode 100644 vendor/udt4/src/buffer.cpp delete mode 100644 vendor/udt4/src/buffer.h delete mode 100644 vendor/udt4/src/cache.cpp delete mode 100644 vendor/udt4/src/cache.h delete mode 100644 vendor/udt4/src/ccc.cpp delete mode 100644 vendor/udt4/src/ccc.h delete mode 100644 vendor/udt4/src/channel.cpp delete mode 100644 vendor/udt4/src/channel.h delete mode 100644 vendor/udt4/src/common.cpp delete mode 100644 vendor/udt4/src/common.h delete mode 100644 vendor/udt4/src/core.cpp delete mode 100644 vendor/udt4/src/core.h delete mode 100644 vendor/udt4/src/epoll.cpp delete mode 100644 vendor/udt4/src/epoll.h delete mode 100644 vendor/udt4/src/list.cpp delete mode 100644 vendor/udt4/src/list.h delete mode 100644 vendor/udt4/src/md5.cpp delete mode 100644 vendor/udt4/src/md5.h delete mode 100644 vendor/udt4/src/packet.cpp delete mode 100644 vendor/udt4/src/packet.h delete mode 100644 vendor/udt4/src/queue.cpp delete mode 100644 vendor/udt4/src/queue.h delete mode 100644 vendor/udt4/src/udt.h delete mode 100644 vendor/udt4/src/window.cpp delete mode 100644 vendor/udt4/src/window.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad88c8..b6d7774 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,7 +226,6 @@ set( fc_sources src/crypto/rand.cpp src/network/tcp_socket.cpp src/network/udp_socket.cpp - src/network/udt_socket.cpp src/network/http/http_connection.cpp src/network/http/http_server.cpp src/network/http/websocket.cpp @@ -253,7 +252,6 @@ list(APPEND sources "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp") list(APPEND sources ${fc_headers}) add_subdirectory( vendor/websocketpp ) -add_subdirectory( vendor/udt4 ) add_subdirectory( vendor/equihash ) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY ) @@ -348,22 +346,21 @@ target_include_directories(fc ${Boost_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} "vendor/diff-match-patch-cpp-stl" + ${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp "${readline_includes}" PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/vendor/boost_1.51/include ${CMAKE_CURRENT_SOURCE_DIR}/vendor/cyoencode-1.0.2/src - ${CMAKE_CURRENT_SOURCE_DIR}/vendor/udt4/src - ${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp ${CMAKE_CURRENT_SOURCE_DIR}/vendor/equihash ) -#target_link_libraries( fc PUBLIC udt ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${ECC_LIB} ) +#target_link_libraries( fc PUBLIC ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${ECC_LIB} ) IF(NOT WIN32) set(LINK_USR_LOCAL_LIB -L/usr/local/lib) ENDIF() -target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} udt equihash ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} ) +target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} equihash ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} ) if(MSVC) set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" ) diff --git a/include/fc/network/udt_socket.hpp b/include/fc/network/udt_socket.hpp deleted file mode 100644 index 1210427..0000000 --- a/include/fc/network/udt_socket.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace fc { - namespace ip { class endpoint; } - - class udt_socket : public virtual iostream, public noncopyable - { - public: - udt_socket(); - ~udt_socket(); - - void bind( const fc::ip::endpoint& local_endpoint ); - void connect_to( const fc::ip::endpoint& remote_endpoint ); - - fc::ip::endpoint remote_endpoint() const; - fc::ip::endpoint local_endpoint() const; - - using istream::get; - void get( char& c ) - { - read( &c, 1 ); - } - - - /// istream interface - /// @{ - virtual size_t readsome( char* buffer, size_t max ); - virtual size_t readsome( const std::shared_ptr& buf, size_t len, size_t offset ); - virtual bool eof()const; - /// @} - - /// ostream interface - /// @{ - virtual size_t writesome( const char* buffer, size_t len ); - virtual size_t writesome( const std::shared_ptr& buf, size_t len, size_t offset ); - virtual void flush(); - virtual void close(); - /// @} - - void open(); - bool is_open()const; - - private: - friend class udt_server; - int _udt_socket_id; - }; - typedef std::shared_ptr udt_socket_ptr; - - class udt_server : public noncopyable - { - public: - udt_server(); - ~udt_server(); - - void close(); - void accept( udt_socket& s ); - - void listen( const fc::ip::endpoint& ep ); - fc::ip::endpoint local_endpoint() const; - - private: - int _udt_socket_id; - }; - -} // fc diff --git a/src/network/udt_socket.cpp b/src/network/udt_socket.cpp deleted file mode 100644 index 655e16c..0000000 --- a/src/network/udt_socket.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#ifndef WIN32 -# include -#endif - -namespace fc { - - void check_udt_errors() - { - UDT::ERRORINFO& error_info = UDT::getlasterror(); - if( error_info.getErrorCode() ) - { - std::string error_message = error_info.getErrorMessage(); - error_info.clear(); - FC_CAPTURE_AND_THROW( udt_exception, (error_message) ); - } - } - - class udt_epoll_service - { - public: - udt_epoll_service() - :_epoll_thread("udt_epoll") - { - UDT::startup(); - check_udt_errors(); - _epoll_id = UDT::epoll_create(); - _epoll_loop = _epoll_thread.async( [=](){ poll_loop(); }, "udt_poll_loop" ); - } - - ~udt_epoll_service() - { - _epoll_loop.cancel("udt_epoll_service is destructing"); - _epoll_loop.wait(); - UDT::cleanup(); - } - - void poll_loop() - { - std::set read_ready; - std::set write_ready; - while( !_epoll_loop.canceled() ) - { - UDT::epoll_wait( _epoll_id, - &read_ready, - &write_ready, 100000000 ); - - { synchronized(_read_promises_mutex) - for( auto sock : read_ready ) - { - auto itr = _read_promises.find( sock ); - if( itr != _read_promises.end() ) - { - itr->second->set_value(); - _read_promises.erase(itr); - } - } - } // synchronized read promise mutex - - { synchronized(_write_promises_mutex) - for( auto sock : write_ready ) - { - auto itr = _write_promises.find( sock ); - if( itr != _write_promises.end() ) - { - itr->second->set_value(); - _write_promises.erase(itr); - } - } - } // synchronized write promise mutex - } // while not canceled - } // poll_loop - - - void notify_read( int udt_socket_id, - const promise::ptr& p ) - { - int events = UDT_EPOLL_IN | UDT_EPOLL_ERR; - if( 0 != UDT::epoll_add_usock( _epoll_id, - udt_socket_id, - &events ) ) - { - check_udt_errors(); - } - { synchronized(_read_promises_mutex) - - _read_promises[udt_socket_id] = p; - } - } - - void notify_write( int udt_socket_id, - const promise::ptr& p ) - { - int events = UDT_EPOLL_OUT | UDT_EPOLL_ERR; - if( 0 != UDT::epoll_add_usock( _epoll_id, - udt_socket_id, - &events ) ) - { - check_udt_errors(); - } - - { synchronized(_write_promises_mutex) - _write_promises[udt_socket_id] = p; - } - } - void remove( int udt_socket_id ) - { - { synchronized(_read_promises_mutex) - auto read_itr = _read_promises.find( udt_socket_id ); - if( read_itr != _read_promises.end() ) - { - read_itr->second->set_exception( fc::copy_exception( fc::exception() ) ); - _read_promises.erase(read_itr); - } - } - { synchronized(_write_promises_mutex) - auto write_itr = _write_promises.find( udt_socket_id ); - if( write_itr != _write_promises.end() ) - { - write_itr->second->set_exception( fc::copy_exception( fc::exception() ) ); - _write_promises.erase(write_itr); - } - } - UDT::epoll_remove_usock( _epoll_id, udt_socket_id ); - } - - private: - fc::mutex _read_promises_mutex; - fc::mutex _write_promises_mutex; - std::unordered_map::ptr > _read_promises; - std::unordered_map::ptr > _write_promises; - - fc::future _epoll_loop; - fc::thread _epoll_thread; - int _epoll_id; - }; - - - udt_epoll_service& default_epool_service() - { - static udt_epoll_service* default_service = new udt_epoll_service(); - return *default_service; - } - - - - udt_socket::udt_socket() - :_udt_socket_id( UDT::INVALID_SOCK ) - { - } - - udt_socket::~udt_socket() - { - try { - close(); - } catch ( const fc::exception& e ) - { - wlog( "${e}", ("e", e.to_detail_string() ) ); - } - } - - void udt_socket::bind( const fc::ip::endpoint& local_endpoint ) - { try { - if( !is_open() ) - open(); - - sockaddr_in local_addr; - local_addr.sin_family = AF_INET; - local_addr.sin_port = htons(local_endpoint.port()); - local_addr.sin_addr.s_addr = htonl(local_endpoint.get_address()); - - if( UDT::ERROR == UDT::bind(_udt_socket_id, (sockaddr*)&local_addr, sizeof(local_addr)) ) - check_udt_errors(); - } FC_CAPTURE_AND_RETHROW() } - - void udt_socket::connect_to( const ip::endpoint& remote_endpoint ) - { try { - if( !is_open() ) - open(); - - sockaddr_in serv_addr; - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(remote_endpoint.port()); - serv_addr.sin_addr.s_addr = htonl(remote_endpoint.get_address()); - - // UDT doesn't allow now blocking connects... - fc::thread connect_thread("connect_thread"); - connect_thread.async( [&](){ - if( UDT::ERROR == UDT::connect(_udt_socket_id, (sockaddr*)&serv_addr, sizeof(serv_addr)) ) - check_udt_errors(); - }, "udt_socket::connect_to").wait(); - - bool block = false; - UDT::setsockopt(_udt_socket_id, 0, UDT_SNDSYN, &block, sizeof(bool)); - UDT::setsockopt(_udt_socket_id, 0, UDT_RCVSYN, &block, sizeof(bool)); - check_udt_errors(); - - } FC_CAPTURE_AND_RETHROW( (remote_endpoint) ) } - - ip::endpoint udt_socket::remote_endpoint() const - { try { - sockaddr_in peer_addr; - int peer_addr_size = sizeof(peer_addr); - int error_code = UDT::getpeername( _udt_socket_id, (struct sockaddr*)&peer_addr, &peer_addr_size ); - if( error_code == UDT::ERROR ) - check_udt_errors(); - return ip::endpoint( ip::address( htonl( peer_addr.sin_addr.s_addr ) ), htons(peer_addr.sin_port) ); - } FC_CAPTURE_AND_RETHROW() } - - ip::endpoint udt_socket::local_endpoint() const - { try { - sockaddr_in sock_addr; - int addr_size = sizeof(sock_addr); - int error_code = UDT::getsockname( _udt_socket_id, (struct sockaddr*)&sock_addr, &addr_size ); - if( error_code == UDT::ERROR ) - check_udt_errors(); - return ip::endpoint( ip::address( htonl( sock_addr.sin_addr.s_addr ) ), htons(sock_addr.sin_port) ); - } FC_CAPTURE_AND_RETHROW() } - - - /// @{ - size_t udt_socket::readsome( char* buffer, size_t max ) - { try { - auto bytes_read = UDT::recv( _udt_socket_id, buffer, max, 0 ); - while( bytes_read == UDT::ERROR ) - { - if( UDT::getlasterror().getErrorCode() == CUDTException::EASYNCRCV ) - { - UDT::getlasterror().clear(); - promise::ptr p(new promise("udt_socket::readsome")); - default_epool_service().notify_read( _udt_socket_id, p ); - p->wait(); - bytes_read = UDT::recv( _udt_socket_id, buffer, max, 0 ); - } - else - check_udt_errors(); - } - return bytes_read; - } FC_CAPTURE_AND_RETHROW( (max) ) } - - size_t udt_socket::readsome( const std::shared_ptr& buf, size_t len, size_t offset ) - { - return readsome(buf.get() + offset, len); - } - - bool udt_socket::eof()const - { - // TODO... - return false; - } - /// @} - - /// ostream interface - /// @{ - size_t udt_socket::writesome( const char* buffer, size_t len ) - { try { - auto bytes_sent = UDT::send(_udt_socket_id, buffer, len, 0); - - while( UDT::ERROR == bytes_sent ) - { - if( UDT::getlasterror().getErrorCode() == CUDTException::EASYNCSND ) - { - UDT::getlasterror().clear(); - promise::ptr p(new promise("udt_socket::writesome")); - default_epool_service().notify_write( _udt_socket_id, p ); - p->wait(); - bytes_sent = UDT::send(_udt_socket_id, buffer, len, 0); - continue; - } - else - check_udt_errors(); - } - return bytes_sent; - } FC_CAPTURE_AND_RETHROW( (len) ) } - - size_t udt_socket::writesome( const std::shared_ptr& buf, size_t len, size_t offset ) - { - return writesome(buf.get() + offset, len); - } - - void udt_socket::flush(){} - - void udt_socket::close() - { try { - if( is_open() ) - { - default_epool_service().remove( _udt_socket_id ); - UDT::close( _udt_socket_id ); - check_udt_errors(); - _udt_socket_id = UDT::INVALID_SOCK; - } - else - { - wlog( "already closed" ); - } - } FC_CAPTURE_AND_RETHROW() } - /// @} - - void udt_socket::open() - { - _udt_socket_id = UDT::socket(AF_INET, SOCK_STREAM, 0); - if( _udt_socket_id == UDT::INVALID_SOCK ) - check_udt_errors(); - } - - bool udt_socket::is_open()const - { - return _udt_socket_id != UDT::INVALID_SOCK; - } - - - - - - - udt_server::udt_server() - :_udt_socket_id( UDT::INVALID_SOCK ) - { - _udt_socket_id = UDT::socket(AF_INET, SOCK_STREAM, 0); - if( _udt_socket_id == UDT::INVALID_SOCK ) - check_udt_errors(); - - bool block = false; - UDT::setsockopt(_udt_socket_id, 0, UDT_SNDSYN, &block, sizeof(bool)); - check_udt_errors(); - UDT::setsockopt(_udt_socket_id, 0, UDT_RCVSYN, &block, sizeof(bool)); - check_udt_errors(); - } - - udt_server::~udt_server() - { - try { - close(); - } catch ( const fc::exception& e ) - { - wlog( "${e}", ("e", e.to_detail_string() ) ); - } - } - - void udt_server::close() - { try { - if( _udt_socket_id != UDT::INVALID_SOCK ) - { - UDT::close( _udt_socket_id ); - check_udt_errors(); - default_epool_service().remove( _udt_socket_id ); - _udt_socket_id = UDT::INVALID_SOCK; - } - } FC_CAPTURE_AND_RETHROW() } - - void udt_server::accept( udt_socket& s ) - { try { - FC_ASSERT( !s.is_open() ); - int namelen; - sockaddr_in their_addr; - - - while( s._udt_socket_id == UDT::INVALID_SOCK ) - { - s._udt_socket_id = UDT::accept( _udt_socket_id, (sockaddr*)&their_addr, &namelen ); - if( UDT::getlasterror().getErrorCode() == CUDTException::EASYNCRCV ) - { - UDT::getlasterror().clear(); - promise::ptr p(new promise("udt_server::accept")); - default_epool_service().notify_read( _udt_socket_id, p ); - p->wait(); - s._udt_socket_id = UDT::accept( _udt_socket_id, (sockaddr*)&their_addr, &namelen ); - } - else - check_udt_errors(); - } - } FC_CAPTURE_AND_RETHROW() } - - void udt_server::listen( const ip::endpoint& ep ) - { try { - sockaddr_in my_addr; - my_addr.sin_family = AF_INET; - my_addr.sin_port = htons(ep.port()); - my_addr.sin_addr.s_addr = INADDR_ANY; - memset(&(my_addr.sin_zero), '\0', 8); - - if( UDT::ERROR == UDT::bind(_udt_socket_id, (sockaddr*)&my_addr, sizeof(my_addr)) ) - check_udt_errors(); - - UDT::listen(_udt_socket_id, 10); - check_udt_errors(); - } FC_CAPTURE_AND_RETHROW( (ep) ) } - - fc::ip::endpoint udt_server::local_endpoint() const - { try { - sockaddr_in sock_addr; - int addr_size = sizeof(sock_addr); - int error_code = UDT::getsockname( _udt_socket_id, (struct sockaddr*)&sock_addr, &addr_size ); - if( error_code == UDT::ERROR ) - check_udt_errors(); - return ip::endpoint( ip::address( htonl( sock_addr.sin_addr.s_addr ) ), htons(sock_addr.sin_port) ); - } FC_CAPTURE_AND_RETHROW() } - -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 50ff992..a1c9fef 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,13 +29,6 @@ target_link_libraries( hmac_test fc ) add_executable( blinding_test blinding_test.cpp ) target_link_libraries( blinding_test fc ) - -add_executable( udt_server udts.cpp ) -target_link_libraries( udt_server fc udt ) - -add_executable( udt_client udtc.cpp ) -target_link_libraries( udt_client fc udt ) - add_executable( ecc_test crypto/ecc_test.cpp ) target_link_libraries( ecc_test fc ) diff --git a/vendor/udt4/CMakeLists.txt b/vendor/udt4/CMakeLists.txt deleted file mode 100644 index cee52ed..0000000 --- a/vendor/udt4/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ - -IF( APPLE ) - add_definitions( -DOSX ) -ELSEIF( WIN32 ) - add_definitions( -DWIN32 ) -ELSE() - add_definitions( -DLINUX ) -ENDIF() - -set( udt_sources - src/api.cpp - src/buffer.cpp - src/cache.cpp - src/ccc.cpp - src/channel.cpp - src/common.cpp - src/core.cpp - src/epoll.cpp - src/list.cpp - src/md5.cpp - src/packet.cpp - src/queue.cpp - src/window.cpp - ) - -add_library( udt ${udt_sources} ) diff --git a/vendor/udt4/LICENSE.txt b/vendor/udt4/LICENSE.txt deleted file mode 100644 index eec89df..0000000 --- a/vendor/udt4/LICENSE.txt +++ /dev/null @@ -1,32 +0,0 @@ -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/udt4/README.txt b/vendor/udt4/README.txt deleted file mode 100644 index 105be42..0000000 --- a/vendor/udt4/README.txt +++ /dev/null @@ -1,43 +0,0 @@ -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All Rights Reserved. -Copyright (c) 2011 - 2012, Google, Inc. All Rights Reserved. - -UDP-based Data Transfer (UDT) Library - version 4 -Author: Yunhong Gu [yunhong.gu @ gmail.com] - -UDT version 4 is free software under BSD License. See ./LICENSE.txt. - -============================================================================ - -UDT Website: -http://udt.sf.net -http://sf.net/projects/udt/ - - -CONTENT: -./src: UDT source code -./app: Example programs -./doc: UDT documentation (HTML) -./win: Visual C++ project files for the Windows version of UDT - - -To make: - make -e os=XXX arch=YYY - -XXX: [LINUX(default), BSD, OSX] -YYY: [IA32(default), POWERPC, IA64, AMD64] - -For example, on OS X, you may need to do "make -e os=OSX arch=POWERPC"; -on 32-bit i386 Linux system, simply use "make". - -On Windows systems, use the Visual C++ project files in ./win directory. - -Note for BSD users, please use GNU Make. - -To use UDT in your application: -Read index.htm in ./doc. The documentation is in HTML format and requires your -browser to support JavaScript. - - -Questions? please post to the UDT project forum: -https://sourceforge.net/projects/udt/forums diff --git a/vendor/udt4/src/api.cpp b/vendor/udt4/src/api.cpp deleted file mode 100644 index e444218..0000000 --- a/vendor/udt4/src/api.cpp +++ /dev/null @@ -1,2392 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 07/09/2011 -*****************************************************************************/ - -#ifdef WIN32 - #include - #include - #ifdef LEGACY_WIN32 - #include - #endif -#else - #include -#endif -#include -#include "api.h" -#include "core.h" - -using namespace std; - -CUDTSocket::CUDTSocket(): -m_Status(INIT), -m_TimeStamp(0), -m_iIPversion(0), -m_pSelfAddr(NULL), -m_pPeerAddr(NULL), -m_SocketID(0), -m_ListenSocket(0), -m_PeerID(0), -m_iISN(0), -m_pUDT(NULL), -m_pQueuedSockets(NULL), -m_pAcceptSockets(NULL), -m_AcceptCond(), -m_AcceptLock(), -m_uiBackLog(0), -m_iMuxID(-1) -{ - #ifndef WIN32 - pthread_mutex_init(&m_AcceptLock, NULL); - pthread_cond_init(&m_AcceptCond, NULL); - pthread_mutex_init(&m_ControlLock, NULL); - #else - m_AcceptLock = CreateMutex(NULL, false, NULL); - m_AcceptCond = CreateEvent(NULL, false, false, NULL); - m_ControlLock = CreateMutex(NULL, false, NULL); - #endif -} - -CUDTSocket::~CUDTSocket() -{ - if (AF_INET == m_iIPversion) - { - delete (sockaddr_in*)m_pSelfAddr; - delete (sockaddr_in*)m_pPeerAddr; - } - else - { - delete (sockaddr_in6*)m_pSelfAddr; - delete (sockaddr_in6*)m_pPeerAddr; - } - - delete m_pUDT; - m_pUDT = NULL; - - delete m_pQueuedSockets; - delete m_pAcceptSockets; - - #ifndef WIN32 - pthread_mutex_destroy(&m_AcceptLock); - pthread_cond_destroy(&m_AcceptCond); - pthread_mutex_destroy(&m_ControlLock); - #else - CloseHandle(m_AcceptLock); - CloseHandle(m_AcceptCond); - CloseHandle(m_ControlLock); - #endif -} - -//////////////////////////////////////////////////////////////////////////////// - -CUDTUnited::CUDTUnited(): -m_Sockets(), -m_ControlLock(), -m_IDLock(), -m_SocketID(0), -m_TLSError(), -m_mMultiplexer(), -m_MultiplexerLock(), -m_pCache(NULL), -m_bClosing(false), -m_GCStopLock(), -m_GCStopCond(), -m_InitLock(), -m_iInstanceCount(0), -m_bGCStatus(false), -m_GCThread(), -m_ClosedSockets() -{ - // Socket ID MUST start from a random value - srand((unsigned int)CTimer::getTime()); - m_SocketID = 1 + (int)((1 << 30) * (double(rand()) / RAND_MAX)); - - #ifndef WIN32 - pthread_mutex_init(&m_ControlLock, NULL); - pthread_mutex_init(&m_IDLock, NULL); - pthread_mutex_init(&m_InitLock, NULL); - #else - m_ControlLock = CreateMutex(NULL, false, NULL); - m_IDLock = CreateMutex(NULL, false, NULL); - m_InitLock = CreateMutex(NULL, false, NULL); - #endif - - #ifndef WIN32 - pthread_key_create(&m_TLSError, TLSDestroy); - #else - m_TLSError = TlsAlloc(); - m_TLSLock = CreateMutex(NULL, false, NULL); - #endif - - m_pCache = new CCache; -} - -CUDTUnited::~CUDTUnited() -{ - #ifndef WIN32 - pthread_mutex_destroy(&m_ControlLock); - pthread_mutex_destroy(&m_IDLock); - pthread_mutex_destroy(&m_InitLock); - #else - CloseHandle(m_ControlLock); - CloseHandle(m_IDLock); - CloseHandle(m_InitLock); - #endif - - #ifndef WIN32 - pthread_key_delete(m_TLSError); - #else - TlsFree(m_TLSError); - CloseHandle(m_TLSLock); - #endif - - delete m_pCache; -} - -int CUDTUnited::startup() -{ - CGuard gcinit(m_InitLock); - - if (m_iInstanceCount++ > 0) - return 0; - - // Global initialization code - #ifdef WIN32 - WORD wVersionRequested; - WSADATA wsaData; - wVersionRequested = MAKEWORD(2, 2); - - if (0 != WSAStartup(wVersionRequested, &wsaData)) - throw CUDTException(1, 0, WSAGetLastError()); - #endif - - //init CTimer::EventLock - - if (m_bGCStatus) - return true; - - m_bClosing = false; - #ifndef WIN32 - pthread_mutex_init(&m_GCStopLock, NULL); - pthread_cond_init(&m_GCStopCond, NULL); - pthread_create(&m_GCThread, NULL, garbageCollect, this); - #else - m_GCStopLock = CreateMutex(NULL, false, NULL); - m_GCStopCond = CreateEvent(NULL, false, false, NULL); - DWORD ThreadID; - m_GCThread = CreateThread(NULL, 0, garbageCollect, this, 0, &ThreadID); - #endif - - m_bGCStatus = true; - - return 0; -} - -int CUDTUnited::cleanup() -{ - CGuard gcinit(m_InitLock); - - if (--m_iInstanceCount > 0) - return 0; - - //destroy CTimer::EventLock - - if (!m_bGCStatus) - return 0; - - m_bClosing = true; - #ifndef WIN32 - pthread_cond_signal(&m_GCStopCond); - pthread_join(m_GCThread, NULL); - pthread_mutex_destroy(&m_GCStopLock); - pthread_cond_destroy(&m_GCStopCond); - #else - SetEvent(m_GCStopCond); - WaitForSingleObject(m_GCThread, INFINITE); - CloseHandle(m_GCThread); - CloseHandle(m_GCStopLock); - CloseHandle(m_GCStopCond); - #endif - - m_bGCStatus = false; - - // Global destruction code - #ifdef WIN32 - WSACleanup(); - #endif - - return 0; -} - -UDTSOCKET CUDTUnited::newSocket(int af, int type) -{ - if ((type != SOCK_STREAM) && (type != SOCK_DGRAM)) - throw CUDTException(5, 3, 0); - - CUDTSocket* ns = NULL; - - try - { - ns = new CUDTSocket; - ns->m_pUDT = new CUDT; - if (AF_INET == af) - { - ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in); - ((sockaddr_in*)(ns->m_pSelfAddr))->sin_port = 0; - } - else - { - ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in6); - ((sockaddr_in6*)(ns->m_pSelfAddr))->sin6_port = 0; - } - } - catch (...) - { - delete ns; - throw CUDTException(3, 2, 0); - } - - CGuard::enterCS(m_IDLock); - ns->m_SocketID = -- m_SocketID; - CGuard::leaveCS(m_IDLock); - - ns->m_Status = INIT; - ns->m_ListenSocket = 0; - ns->m_pUDT->m_SocketID = ns->m_SocketID; - ns->m_pUDT->m_iSockType = (SOCK_STREAM == type) ? UDT_STREAM : UDT_DGRAM; - ns->m_pUDT->m_iIPversion = ns->m_iIPversion = af; - ns->m_pUDT->m_pCache = m_pCache; - - // protect the m_Sockets structure. - CGuard::enterCS(m_ControlLock); - try - { - m_Sockets[ns->m_SocketID] = ns; - } - catch (...) - { - //failure and rollback - CGuard::leaveCS(m_ControlLock); - delete ns; - ns = NULL; - } - CGuard::leaveCS(m_ControlLock); - - if (NULL == ns) - throw CUDTException(3, 2, 0); - - return ns->m_SocketID; -} - -int CUDTUnited::newConnection(const UDTSOCKET listen, const sockaddr* peer, CHandShake* hs) -{ - CUDTSocket* ns = NULL; - CUDTSocket* ls = locate(listen); - - if (NULL == ls) - return -1; - - // if this connection has already been processed - if (NULL != (ns = locate(peer, hs->m_iID, hs->m_iISN))) - { - if (ns->m_pUDT->m_bBroken) - { - // last connection from the "peer" address has been broken - ns->m_Status = CLOSED; - ns->m_TimeStamp = CTimer::getTime(); - - CGuard::enterCS(ls->m_AcceptLock); - ls->m_pQueuedSockets->erase(ns->m_SocketID); - ls->m_pAcceptSockets->erase(ns->m_SocketID); - CGuard::leaveCS(ls->m_AcceptLock); - } - else - { - // connection already exist, this is a repeated connection request - // respond with existing HS information - - hs->m_iISN = ns->m_pUDT->m_iISN; - hs->m_iMSS = ns->m_pUDT->m_iMSS; - hs->m_iFlightFlagSize = ns->m_pUDT->m_iFlightFlagSize; - hs->m_iReqType = -1; - hs->m_iID = ns->m_SocketID; - - return 0; - - //except for this situation a new connection should be started - } - } - - // exceeding backlog, refuse the connection request - if (ls->m_pQueuedSockets->size() >= ls->m_uiBackLog) - return -1; - - try - { - ns = new CUDTSocket; - ns->m_pUDT = new CUDT(*(ls->m_pUDT)); - if (AF_INET == ls->m_iIPversion) - { - ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in); - ((sockaddr_in*)(ns->m_pSelfAddr))->sin_port = 0; - ns->m_pPeerAddr = (sockaddr*)(new sockaddr_in); - memcpy(ns->m_pPeerAddr, peer, sizeof(sockaddr_in)); - } - else - { - ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in6); - ((sockaddr_in6*)(ns->m_pSelfAddr))->sin6_port = 0; - ns->m_pPeerAddr = (sockaddr*)(new sockaddr_in6); - memcpy(ns->m_pPeerAddr, peer, sizeof(sockaddr_in6)); - } - } - catch (...) - { - delete ns; - return -1; - } - - CGuard::enterCS(m_IDLock); - ns->m_SocketID = -- m_SocketID; - CGuard::leaveCS(m_IDLock); - - ns->m_ListenSocket = listen; - ns->m_iIPversion = ls->m_iIPversion; - ns->m_pUDT->m_SocketID = ns->m_SocketID; - ns->m_PeerID = hs->m_iID; - ns->m_iISN = hs->m_iISN; - - int error = 0; - - try - { - // bind to the same addr of listening socket - ns->m_pUDT->open(); - updateMux(ns, ls); - ns->m_pUDT->connect(peer, hs); - } - catch (...) - { - error = 1; - goto ERR_ROLLBACK; - } - - ns->m_Status = CONNECTED; - - // copy address information of local node - ns->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(ns->m_pSelfAddr); - CIPAddress::pton(ns->m_pSelfAddr, ns->m_pUDT->m_piSelfIP, ns->m_iIPversion); - - // protect the m_Sockets structure. - CGuard::enterCS(m_ControlLock); - try - { - m_Sockets[ns->m_SocketID] = ns; - m_PeerRec[(ns->m_PeerID << 30) + ns->m_iISN].insert(ns->m_SocketID); - } - catch (...) - { - error = 2; - } - CGuard::leaveCS(m_ControlLock); - - CGuard::enterCS(ls->m_AcceptLock); - try - { - ls->m_pQueuedSockets->insert(ns->m_SocketID); - } - catch (...) - { - error = 3; - } - CGuard::leaveCS(ls->m_AcceptLock); - - // acknowledge users waiting for new connections on the listening socket - m_EPoll.update_events(listen, ls->m_pUDT->m_sPollID, UDT_EPOLL_IN, true); - - CTimer::triggerEvent(); - - ERR_ROLLBACK: - if (error > 0) - { - ns->m_pUDT->close(); - ns->m_Status = CLOSED; - ns->m_TimeStamp = CTimer::getTime(); - - return -1; - } - - // wake up a waiting accept() call - #ifndef WIN32 - pthread_mutex_lock(&(ls->m_AcceptLock)); - pthread_cond_signal(&(ls->m_AcceptCond)); - pthread_mutex_unlock(&(ls->m_AcceptLock)); - #else - SetEvent(ls->m_AcceptCond); - #endif - - return 1; -} - -CUDT* CUDTUnited::lookup(const UDTSOCKET u) -{ - // protects the m_Sockets structure - CGuard cg(m_ControlLock); - - map::iterator i = m_Sockets.find(u); - - if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) - throw CUDTException(5, 4, 0); - - return i->second->m_pUDT; -} - -UDTSTATUS CUDTUnited::getStatus(const UDTSOCKET u) -{ - // protects the m_Sockets structure - CGuard cg(m_ControlLock); - - map::iterator i = m_Sockets.find(u); - - if (i == m_Sockets.end()) - { - if (m_ClosedSockets.find(u) != m_ClosedSockets.end()) - return CLOSED; - - return NONEXIST; - } - - if (i->second->m_pUDT->m_bBroken) - return BROKEN; - - return i->second->m_Status; -} - -int CUDTUnited::bind(const UDTSOCKET u, const sockaddr* name, int namelen) -{ - CUDTSocket* s = locate(u); - if (NULL == s) - throw CUDTException(5, 4, 0); - - CGuard cg(s->m_ControlLock); - - // cannot bind a socket more than once - if (INIT != s->m_Status) - throw CUDTException(5, 0, 0); - - // check the size of SOCKADDR structure - if (AF_INET == s->m_iIPversion) - { - if (namelen != sizeof(sockaddr_in)) - throw CUDTException(5, 3, 0); - } - else - { - if (namelen != sizeof(sockaddr_in6)) - throw CUDTException(5, 3, 0); - } - - s->m_pUDT->open(); - updateMux(s, name); - s->m_Status = OPENED; - - // copy address information of local node - s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); - - return 0; -} - -int CUDTUnited::bind(UDTSOCKET u, UDPSOCKET udpsock) -{ - CUDTSocket* s = locate(u); - if (NULL == s) - throw CUDTException(5, 4, 0); - - CGuard cg(s->m_ControlLock); - - // cannot bind a socket more than once - if (INIT != s->m_Status) - throw CUDTException(5, 0, 0); - - sockaddr_in name4; - sockaddr_in6 name6; - sockaddr* name; - socklen_t namelen; - - if (AF_INET == s->m_iIPversion) - { - namelen = sizeof(sockaddr_in); - name = (sockaddr*)&name4; - } - else - { - namelen = sizeof(sockaddr_in6); - name = (sockaddr*)&name6; - } - - if (-1 == ::getsockname(udpsock, name, &namelen)) - throw CUDTException(5, 3); - - s->m_pUDT->open(); - updateMux(s, name, &udpsock); - s->m_Status = OPENED; - - // copy address information of local node - s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); - - return 0; -} - -int CUDTUnited::listen(const UDTSOCKET u, int backlog) -{ - CUDTSocket* s = locate(u); - if (NULL == s) - throw CUDTException(5, 4, 0); - - CGuard cg(s->m_ControlLock); - - // do nothing if the socket is already listening - if (LISTENING == s->m_Status) - return 0; - - // a socket can listen only if is in OPENED status - if (OPENED != s->m_Status) - throw CUDTException(5, 5, 0); - - // listen is not supported in rendezvous connection setup - if (s->m_pUDT->m_bRendezvous) - throw CUDTException(5, 7, 0); - - if (backlog <= 0) - throw CUDTException(5, 3, 0); - - s->m_uiBackLog = backlog; - - try - { - s->m_pQueuedSockets = new set; - s->m_pAcceptSockets = new set; - } - catch (...) - { - delete s->m_pQueuedSockets; - delete s->m_pAcceptSockets; - throw CUDTException(3, 2, 0); - } - - s->m_pUDT->listen(); - - s->m_Status = LISTENING; - - return 0; -} - -UDTSOCKET CUDTUnited::accept(const UDTSOCKET listen, sockaddr* addr, int* addrlen) -{ - if ((NULL != addr) && (NULL == addrlen)) - throw CUDTException(5, 3, 0); - - CUDTSocket* ls = locate(listen); - - if (ls == NULL) - throw CUDTException(5, 4, 0); - - // the "listen" socket must be in LISTENING status - if (LISTENING != ls->m_Status) - throw CUDTException(5, 6, 0); - - // no "accept" in rendezvous connection setup - if (ls->m_pUDT->m_bRendezvous) - throw CUDTException(5, 7, 0); - - UDTSOCKET u = CUDT::INVALID_SOCK; - bool accepted = false; - - // !!only one conection can be set up each time!! - #ifndef WIN32 - while (!accepted) - { - pthread_mutex_lock(&(ls->m_AcceptLock)); - - if ((LISTENING != ls->m_Status) || ls->m_pUDT->m_bBroken) - { - // This socket has been closed. - accepted = true; - } - else if (ls->m_pQueuedSockets->size() > 0) - { - u = *(ls->m_pQueuedSockets->begin()); - ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); - ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); - accepted = true; - } - else if (!ls->m_pUDT->m_bSynRecving) - { - accepted = true; - } - - if (!accepted && (LISTENING == ls->m_Status)) - pthread_cond_wait(&(ls->m_AcceptCond), &(ls->m_AcceptLock)); - - if (ls->m_pQueuedSockets->empty()) - m_EPoll.update_events(listen, ls->m_pUDT->m_sPollID, UDT_EPOLL_IN, false); - - pthread_mutex_unlock(&(ls->m_AcceptLock)); - } - #else - while (!accepted) - { - WaitForSingleObject(ls->m_AcceptLock, INFINITE); - - if (ls->m_pQueuedSockets->size() > 0) - { - u = *(ls->m_pQueuedSockets->begin()); - ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); - ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); - - accepted = true; - } - else if (!ls->m_pUDT->m_bSynRecving) - accepted = true; - - ReleaseMutex(ls->m_AcceptLock); - - if (!accepted & (LISTENING == ls->m_Status)) - WaitForSingleObject(ls->m_AcceptCond, INFINITE); - - if ((LISTENING != ls->m_Status) || ls->m_pUDT->m_bBroken) - { - // Send signal to other threads that are waiting to accept. - SetEvent(ls->m_AcceptCond); - accepted = true; - } - - if (ls->m_pQueuedSockets->empty()) - m_EPoll.update_events(listen, ls->m_pUDT->m_sPollID, UDT_EPOLL_IN, false); - } - #endif - - if (u == CUDT::INVALID_SOCK) - { - // non-blocking receiving, no connection available - if (!ls->m_pUDT->m_bSynRecving) - throw CUDTException(6, 2, 0); - - // listening socket is closed - throw CUDTException(5, 6, 0); - } - - if ((addr != NULL) && (addrlen != NULL)) - { - if (AF_INET == locate(u)->m_iIPversion) - *addrlen = sizeof(sockaddr_in); - else - *addrlen = sizeof(sockaddr_in6); - - // copy address information of peer node - memcpy(addr, locate(u)->m_pPeerAddr, *addrlen); - } - - return u; -} - -int CUDTUnited::connect(const UDTSOCKET u, const sockaddr* name, int namelen) -{ - CUDTSocket* s = locate(u); - if (NULL == s) - throw CUDTException(5, 4, 0); - - CGuard cg(s->m_ControlLock); - - // check the size of SOCKADDR structure - if (AF_INET == s->m_iIPversion) - { - if (namelen != sizeof(sockaddr_in)) - throw CUDTException(5, 3, 0); - } - else - { - if (namelen != sizeof(sockaddr_in6)) - throw CUDTException(5, 3, 0); - } - - // a socket can "connect" only if it is in INIT or OPENED status - if (INIT == s->m_Status) - { - if (!s->m_pUDT->m_bRendezvous) - { - s->m_pUDT->open(); - updateMux(s); - s->m_Status = OPENED; - } - else - throw CUDTException(5, 8, 0); - } - else if (OPENED != s->m_Status) - throw CUDTException(5, 2, 0); - - // connect_complete() may be called before connect() returns. - // So we need to update the status before connect() is called, - // otherwise the status may be overwritten with wrong value (CONNECTED vs. CONNECTING). - s->m_Status = CONNECTING; - try - { - s->m_pUDT->connect(name); - } - catch (CUDTException e) - { - s->m_Status = OPENED; - throw e; - } - - // record peer address - delete s->m_pPeerAddr; - if (AF_INET == s->m_iIPversion) - { - s->m_pPeerAddr = (sockaddr*)(new sockaddr_in); - memcpy(s->m_pPeerAddr, name, sizeof(sockaddr_in)); - } - else - { - s->m_pPeerAddr = (sockaddr*)(new sockaddr_in6); - memcpy(s->m_pPeerAddr, name, sizeof(sockaddr_in6)); - } - - return 0; -} - -void CUDTUnited::connect_complete(const UDTSOCKET u) -{ - CUDTSocket* s = locate(u); - if (NULL == s) - throw CUDTException(5, 4, 0); - - // copy address information of local node - // the local port must be correctly assigned BEFORE CUDT::connect(), - // otherwise if connect() fails, the multiplexer cannot be located by garbage collection and will cause leak - s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); - CIPAddress::pton(s->m_pSelfAddr, s->m_pUDT->m_piSelfIP, s->m_iIPversion); - - s->m_Status = CONNECTED; -} - -int CUDTUnited::close(const UDTSOCKET u) -{ - CUDTSocket* s = locate(u); - if (NULL == s) - throw CUDTException(5, 4, 0); - - CGuard socket_cg(s->m_ControlLock); - - if (s->m_Status == LISTENING) - { - if (s->m_pUDT->m_bBroken) - return 0; - - s->m_TimeStamp = CTimer::getTime(); - s->m_pUDT->m_bBroken = true; - - // broadcast all "accept" waiting - #ifndef WIN32 - pthread_mutex_lock(&(s->m_AcceptLock)); - pthread_cond_broadcast(&(s->m_AcceptCond)); - pthread_mutex_unlock(&(s->m_AcceptLock)); - #else - SetEvent(s->m_AcceptCond); - #endif - - return 0; - } - - s->m_pUDT->close(); - - // synchronize with garbage collection. - CGuard manager_cg(m_ControlLock); - - // since "s" is located before m_ControlLock, locate it again in case it became invalid - map::iterator i = m_Sockets.find(u); - if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) - return 0; - s = i->second; - - s->m_Status = CLOSED; - - // a socket will not be immediated removed when it is closed - // in order to prevent other methods from accessing invalid address - // a timer is started and the socket will be removed after approximately 1 second - s->m_TimeStamp = CTimer::getTime(); - - m_Sockets.erase(s->m_SocketID); - m_ClosedSockets.insert(pair(s->m_SocketID, s)); - - CTimer::triggerEvent(); - - return 0; -} - -int CUDTUnited::getpeername(const UDTSOCKET u, sockaddr* name, int* namelen) -{ - if (CONNECTED != getStatus(u)) - throw CUDTException(2, 2, 0); - - CUDTSocket* s = locate(u); - - if (NULL == s) - throw CUDTException(5, 4, 0); - - if (!s->m_pUDT->m_bConnected || s->m_pUDT->m_bBroken) - throw CUDTException(2, 2, 0); - - if (AF_INET == s->m_iIPversion) - *namelen = sizeof(sockaddr_in); - else - *namelen = sizeof(sockaddr_in6); - - // copy address information of peer node - memcpy(name, s->m_pPeerAddr, *namelen); - - return 0; -} - -int CUDTUnited::getsockname(const UDTSOCKET u, sockaddr* name, int* namelen) -{ - CUDTSocket* s = locate(u); - - if (NULL == s) - throw CUDTException(5, 4, 0); - - if (s->m_pUDT->m_bBroken) - throw CUDTException(5, 4, 0); - - if (INIT == s->m_Status) - throw CUDTException(2, 2, 0); - - if (AF_INET == s->m_iIPversion) - *namelen = sizeof(sockaddr_in); - else - *namelen = sizeof(sockaddr_in6); - - // copy address information of local node - memcpy(name, s->m_pSelfAddr, *namelen); - - return 0; -} - -int CUDTUnited::select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout) -{ - uint64_t entertime = CTimer::getTime(); - - uint64_t to; - if (NULL == timeout) - to = 0xFFFFFFFFFFFFFFFFULL; - else - to = timeout->tv_sec * 1000000 + timeout->tv_usec; - - // initialize results - int count = 0; - set rs, ws, es; - - // retrieve related UDT sockets - vector ru, wu, eu; - CUDTSocket* s; - if (NULL != readfds) - for (set::iterator i1 = readfds->begin(); i1 != readfds->end(); ++ i1) - { - if (BROKEN == getStatus(*i1)) - { - rs.insert(*i1); - ++ count; - } - else if (NULL == (s = locate(*i1))) - throw CUDTException(5, 4, 0); - else - ru.push_back(s); - } - if (NULL != writefds) - for (set::iterator i2 = writefds->begin(); i2 != writefds->end(); ++ i2) - { - if (BROKEN == getStatus(*i2)) - { - ws.insert(*i2); - ++ count; - } - else if (NULL == (s = locate(*i2))) - throw CUDTException(5, 4, 0); - else - wu.push_back(s); - } - if (NULL != exceptfds) - for (set::iterator i3 = exceptfds->begin(); i3 != exceptfds->end(); ++ i3) - { - if (BROKEN == getStatus(*i3)) - { - es.insert(*i3); - ++ count; - } - else if (NULL == (s = locate(*i3))) - throw CUDTException(5, 4, 0); - else - eu.push_back(s); - } - - do - { - // query read sockets - for (vector::iterator j1 = ru.begin(); j1 != ru.end(); ++ j1) - { - s = *j1; - - if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && ((s->m_pUDT->m_iSockType == UDT_STREAM) || (s->m_pUDT->m_pRcvBuffer->getRcvMsgNum() > 0))) - || (!s->m_pUDT->m_bListening && (s->m_pUDT->m_bBroken || !s->m_pUDT->m_bConnected)) - || (s->m_pUDT->m_bListening && (s->m_pQueuedSockets->size() > 0)) - || (s->m_Status == CLOSED)) - { - rs.insert(s->m_SocketID); - ++ count; - } - } - - // query write sockets - for (vector::iterator j2 = wu.begin(); j2 != wu.end(); ++ j2) - { - s = *j2; - - if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pSndBuffer->getCurrBufSize() < s->m_pUDT->m_iSndBufSize)) - || s->m_pUDT->m_bBroken || !s->m_pUDT->m_bConnected || (s->m_Status == CLOSED)) - { - ws.insert(s->m_SocketID); - ++ count; - } - } - - // query exceptions on sockets - for (vector::iterator j3 = eu.begin(); j3 != eu.end(); ++ j3) - { - // check connection request status, not supported now - } - - if (0 < count) - break; - - CTimer::waitForEvent(); - } while (to > CTimer::getTime() - entertime); - - if (NULL != readfds) - *readfds = rs; - - if (NULL != writefds) - *writefds = ws; - - if (NULL != exceptfds) - *exceptfds = es; - - return count; -} - -int CUDTUnited::selectEx(const vector& fds, vector* readfds, vector* writefds, vector* exceptfds, int64_t msTimeOut) -{ - uint64_t entertime = CTimer::getTime(); - - uint64_t to; - if (msTimeOut >= 0) - to = msTimeOut * 1000; - else - to = 0xFFFFFFFFFFFFFFFFULL; - - // initialize results - int count = 0; - if (NULL != readfds) - readfds->clear(); - if (NULL != writefds) - writefds->clear(); - if (NULL != exceptfds) - exceptfds->clear(); - - do - { - for (vector::const_iterator i = fds.begin(); i != fds.end(); ++ i) - { - CUDTSocket* s = locate(*i); - - if ((NULL == s) || s->m_pUDT->m_bBroken || (s->m_Status == CLOSED)) - { - if (NULL != exceptfds) - { - exceptfds->push_back(*i); - ++ count; - } - continue; - } - - if (NULL != readfds) - { - if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && ((s->m_pUDT->m_iSockType == UDT_STREAM) || (s->m_pUDT->m_pRcvBuffer->getRcvMsgNum() > 0))) - || (s->m_pUDT->m_bListening && (s->m_pQueuedSockets->size() > 0))) - { - readfds->push_back(s->m_SocketID); - ++ count; - } - } - - if (NULL != writefds) - { - if (s->m_pUDT->m_bConnected && (s->m_pUDT->m_pSndBuffer->getCurrBufSize() < s->m_pUDT->m_iSndBufSize)) - { - writefds->push_back(s->m_SocketID); - ++ count; - } - } - } - - if (count > 0) - break; - - CTimer::waitForEvent(); - } while (to > CTimer::getTime() - entertime); - - return count; -} - -int CUDTUnited::epoll_create() -{ - return m_EPoll.create(); -} - -int CUDTUnited::epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) -{ - CUDTSocket* s = locate(u); - int ret = -1; - if (NULL != s) - { - ret = m_EPoll.add_usock(eid, u, events); - s->m_pUDT->addEPoll(eid); - } - else - { - throw CUDTException(5, 4); - } - - return ret; -} - -int CUDTUnited::epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) -{ - return m_EPoll.add_ssock(eid, s, events); -} - -int CUDTUnited::epoll_remove_usock(const int eid, const UDTSOCKET u) -{ - int ret = m_EPoll.remove_usock(eid, u); - - CUDTSocket* s = locate(u); - if (NULL != s) - { - s->m_pUDT->removeEPoll(eid); - } - //else - //{ - // throw CUDTException(5, 4); - //} - - return ret; -} - -int CUDTUnited::epoll_remove_ssock(const int eid, const SYSSOCKET s) -{ - return m_EPoll.remove_ssock(eid, s); -} - -int CUDTUnited::epoll_wait(const int eid, set* readfds, set* writefds, int64_t msTimeOut, set* lrfds, set* lwfds) -{ - return m_EPoll.wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); -} - -int CUDTUnited::epoll_release(const int eid) -{ - return m_EPoll.release(eid); -} - -CUDTSocket* CUDTUnited::locate(const UDTSOCKET u) -{ - CGuard cg(m_ControlLock); - - map::iterator i = m_Sockets.find(u); - - if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) - return NULL; - - return i->second; -} - -CUDTSocket* CUDTUnited::locate(const sockaddr* peer, const UDTSOCKET id, int32_t isn) -{ - CGuard cg(m_ControlLock); - - map >::iterator i = m_PeerRec.find((id << 30) + isn); - if (i == m_PeerRec.end()) - return NULL; - - for (set::iterator j = i->second.begin(); j != i->second.end(); ++ j) - { - map::iterator k = m_Sockets.find(*j); - // this socket might have been closed and moved m_ClosedSockets - if (k == m_Sockets.end()) - continue; - - if (CIPAddress::ipcmp(peer, k->second->m_pPeerAddr, k->second->m_iIPversion)) - return k->second; - } - - return NULL; -} - -void CUDTUnited::checkBrokenSockets() -{ - CGuard cg(m_ControlLock); - - // set of sockets To Be Closed and To Be Removed - vector tbc; - vector tbr; - - for (map::iterator i = m_Sockets.begin(); i != m_Sockets.end(); ++ i) - { - // check broken connection - if (i->second->m_pUDT->m_bBroken) - { - if (i->second->m_Status == LISTENING) - { - // for a listening socket, it should wait an extra 3 seconds in case a client is connecting - if (CTimer::getTime() - i->second->m_TimeStamp < 3000000) - continue; - } - else if ((i->second->m_pUDT->m_pRcvBuffer != NULL) && (i->second->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && (i->second->m_pUDT->m_iBrokenCounter -- > 0)) - { - // if there is still data in the receiver buffer, wait longer - continue; - } - - //close broken connections and start removal timer - i->second->m_Status = CLOSED; - i->second->m_TimeStamp = CTimer::getTime(); - tbc.push_back(i->first); - m_ClosedSockets[i->first] = i->second; - - // remove from listener's queue - map::iterator ls = m_Sockets.find(i->second->m_ListenSocket); - if (ls == m_Sockets.end()) - { - ls = m_ClosedSockets.find(i->second->m_ListenSocket); - if (ls == m_ClosedSockets.end()) - continue; - } - - CGuard::enterCS(ls->second->m_AcceptLock); - ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); - ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); - CGuard::leaveCS(ls->second->m_AcceptLock); - } - } - - for (map::iterator j = m_ClosedSockets.begin(); j != m_ClosedSockets.end(); ++ j) - { - if (j->second->m_pUDT->m_ullLingerExpiration > 0) - { - // asynchronous close: - if ((NULL == j->second->m_pUDT->m_pSndBuffer) || (0 == j->second->m_pUDT->m_pSndBuffer->getCurrBufSize()) || (j->second->m_pUDT->m_ullLingerExpiration <= CTimer::getTime())) - { - j->second->m_pUDT->m_ullLingerExpiration = 0; - j->second->m_pUDT->m_bClosing = true; - j->second->m_TimeStamp = CTimer::getTime(); - } - } - - // timeout 1 second to destroy a socket AND it has been removed from RcvUList - if ((CTimer::getTime() - j->second->m_TimeStamp > 1000000) && ((NULL == j->second->m_pUDT->m_pRNode) || !j->second->m_pUDT->m_pRNode->m_bOnList)) - { - tbr.push_back(j->first); - } - } - - // move closed sockets to the ClosedSockets structure - for (vector::iterator k = tbc.begin(); k != tbc.end(); ++ k) - m_Sockets.erase(*k); - - // remove those timeout sockets - for (vector::iterator l = tbr.begin(); l != tbr.end(); ++ l) - removeSocket(*l); -} - -void CUDTUnited::removeSocket(const UDTSOCKET u) -{ - map::iterator i = m_ClosedSockets.find(u); - - // invalid socket ID - if (i == m_ClosedSockets.end()) - return; - - // decrease multiplexer reference count, and remove it if necessary - const int mid = i->second->m_iMuxID; - - if (NULL != i->second->m_pQueuedSockets) - { - CGuard::enterCS(i->second->m_AcceptLock); - - // if it is a listener, close all un-accepted sockets in its queue and remove them later - for (set::iterator q = i->second->m_pQueuedSockets->begin(); q != i->second->m_pQueuedSockets->end(); ++ q) - { - m_Sockets[*q]->m_pUDT->m_bBroken = true; - m_Sockets[*q]->m_pUDT->close(); - m_Sockets[*q]->m_TimeStamp = CTimer::getTime(); - m_Sockets[*q]->m_Status = CLOSED; - m_ClosedSockets[*q] = m_Sockets[*q]; - m_Sockets.erase(*q); - } - - CGuard::leaveCS(i->second->m_AcceptLock); - } - - // remove from peer rec - map >::iterator j = m_PeerRec.find((i->second->m_PeerID << 30) + i->second->m_iISN); - if (j != m_PeerRec.end()) - { - j->second.erase(u); - if (j->second.empty()) - m_PeerRec.erase(j); - } - - // delete this one - i->second->m_pUDT->close(); - delete i->second; - m_ClosedSockets.erase(i); - - map::iterator m; - m = m_mMultiplexer.find(mid); - if (m == m_mMultiplexer.end()) - { - //something is wrong!!! - return; - } - - m->second.m_iRefCount --; - if (0 == m->second.m_iRefCount) - { - m->second.m_pChannel->close(); - delete m->second.m_pSndQueue; - delete m->second.m_pRcvQueue; - delete m->second.m_pTimer; - delete m->second.m_pChannel; - m_mMultiplexer.erase(m); - } -} - -void CUDTUnited::setError(CUDTException* e) -{ - #ifndef WIN32 - delete (CUDTException*)pthread_getspecific(m_TLSError); - pthread_setspecific(m_TLSError, e); - #else - CGuard tg(m_TLSLock); - delete (CUDTException*)TlsGetValue(m_TLSError); - TlsSetValue(m_TLSError, e); - m_mTLSRecord[GetCurrentThreadId()] = e; - #endif -} - -CUDTException* CUDTUnited::getError() -{ - #ifndef WIN32 - if(NULL == pthread_getspecific(m_TLSError)) - pthread_setspecific(m_TLSError, new CUDTException); - return (CUDTException*)pthread_getspecific(m_TLSError); - #else - CGuard tg(m_TLSLock); - if(NULL == TlsGetValue(m_TLSError)) - { - CUDTException* e = new CUDTException; - TlsSetValue(m_TLSError, e); - m_mTLSRecord[GetCurrentThreadId()] = e; - } - return (CUDTException*)TlsGetValue(m_TLSError); - #endif -} - -#ifdef WIN32 -void CUDTUnited::checkTLSValue() -{ - CGuard tg(m_TLSLock); - - vector tbr; - for (map::iterator i = m_mTLSRecord.begin(); i != m_mTLSRecord.end(); ++ i) - { - HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, FALSE, i->first); - if (NULL == h) - { - tbr.push_back(i->first); - break; - } - if (WAIT_OBJECT_0 == WaitForSingleObject(h, 0)) - { - delete i->second; - tbr.push_back(i->first); - } - CloseHandle(h); - } - for (vector::iterator j = tbr.begin(); j != tbr.end(); ++ j) - m_mTLSRecord.erase(*j); -} -#endif - -void CUDTUnited::updateMux(CUDTSocket* s, const sockaddr* addr, const UDPSOCKET* udpsock) -{ - CGuard cg(m_ControlLock); - - if ((s->m_pUDT->m_bReuseAddr) && (NULL != addr)) - { - int port = (AF_INET == s->m_pUDT->m_iIPversion) ? ntohs(((sockaddr_in*)addr)->sin_port) : ntohs(((sockaddr_in6*)addr)->sin6_port); - - // find a reusable address - for (map::iterator i = m_mMultiplexer.begin(); i != m_mMultiplexer.end(); ++ i) - { - if ((i->second.m_iIPversion == s->m_pUDT->m_iIPversion) && (i->second.m_iMSS == s->m_pUDT->m_iMSS) && i->second.m_bReusable) - { - if (i->second.m_iPort == port) - { - // reuse the existing multiplexer - ++ i->second.m_iRefCount; - s->m_pUDT->m_pSndQueue = i->second.m_pSndQueue; - s->m_pUDT->m_pRcvQueue = i->second.m_pRcvQueue; - s->m_iMuxID = i->second.m_iID; - return; - } - } - } - } - - // a new multiplexer is needed - CMultiplexer m; - m.m_iMSS = s->m_pUDT->m_iMSS; - m.m_iIPversion = s->m_pUDT->m_iIPversion; - m.m_iRefCount = 1; - m.m_bReusable = s->m_pUDT->m_bReuseAddr; - m.m_iID = s->m_SocketID; - - m.m_pChannel = new CChannel(s->m_pUDT->m_iIPversion); - m.m_pChannel->setSndBufSize(s->m_pUDT->m_iUDPSndBufSize); - m.m_pChannel->setRcvBufSize(s->m_pUDT->m_iUDPRcvBufSize); - - try - { - if (NULL != udpsock) - m.m_pChannel->open(*udpsock); - else - m.m_pChannel->open(addr); - } - catch (CUDTException& e) - { - m.m_pChannel->close(); - delete m.m_pChannel; - throw e; - } - - sockaddr* sa = (AF_INET == s->m_pUDT->m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; - m.m_pChannel->getSockAddr(sa); - m.m_iPort = (AF_INET == s->m_pUDT->m_iIPversion) ? ntohs(((sockaddr_in*)sa)->sin_port) : ntohs(((sockaddr_in6*)sa)->sin6_port); - if (AF_INET == s->m_pUDT->m_iIPversion) delete (sockaddr_in*)sa; else delete (sockaddr_in6*)sa; - - m.m_pTimer = new CTimer; - - m.m_pSndQueue = new CSndQueue; - m.m_pSndQueue->init(m.m_pChannel, m.m_pTimer); - m.m_pRcvQueue = new CRcvQueue; - m.m_pRcvQueue->init(32, s->m_pUDT->m_iPayloadSize, m.m_iIPversion, 1024, m.m_pChannel, m.m_pTimer); - - m_mMultiplexer[m.m_iID] = m; - - s->m_pUDT->m_pSndQueue = m.m_pSndQueue; - s->m_pUDT->m_pRcvQueue = m.m_pRcvQueue; - s->m_iMuxID = m.m_iID; -} - -void CUDTUnited::updateMux(CUDTSocket* s, const CUDTSocket* ls) -{ - CGuard cg(m_ControlLock); - - int port = (AF_INET == ls->m_iIPversion) ? ntohs(((sockaddr_in*)ls->m_pSelfAddr)->sin_port) : ntohs(((sockaddr_in6*)ls->m_pSelfAddr)->sin6_port); - - // find the listener's address - for (map::iterator i = m_mMultiplexer.begin(); i != m_mMultiplexer.end(); ++ i) - { - if (i->second.m_iPort == port) - { - // reuse the existing multiplexer - ++ i->second.m_iRefCount; - s->m_pUDT->m_pSndQueue = i->second.m_pSndQueue; - s->m_pUDT->m_pRcvQueue = i->second.m_pRcvQueue; - s->m_iMuxID = i->second.m_iID; - return; - } - } -} - -#ifndef WIN32 - void* CUDTUnited::garbageCollect(void* p) -#else - DWORD WINAPI CUDTUnited::garbageCollect(LPVOID p) -#endif -{ - CUDTUnited* self = (CUDTUnited*)p; - - CGuard gcguard(self->m_GCStopLock); - - while (!self->m_bClosing) - { - self->checkBrokenSockets(); - - #ifdef WIN32 - self->checkTLSValue(); - #endif - - #ifndef WIN32 - timeval now; - timespec timeout; - gettimeofday(&now, 0); - timeout.tv_sec = now.tv_sec + 1; - timeout.tv_nsec = now.tv_usec * 1000; - - pthread_cond_timedwait(&self->m_GCStopCond, &self->m_GCStopLock, &timeout); - #else - WaitForSingleObject(self->m_GCStopCond, 1000); - #endif - } - - // remove all sockets and multiplexers - CGuard::enterCS(self->m_ControlLock); - for (map::iterator i = self->m_Sockets.begin(); i != self->m_Sockets.end(); ++ i) - { - i->second->m_pUDT->m_bBroken = true; - i->second->m_pUDT->close(); - i->second->m_Status = CLOSED; - i->second->m_TimeStamp = CTimer::getTime(); - self->m_ClosedSockets[i->first] = i->second; - - // remove from listener's queue - map::iterator ls = self->m_Sockets.find(i->second->m_ListenSocket); - if (ls == self->m_Sockets.end()) - { - ls = self->m_ClosedSockets.find(i->second->m_ListenSocket); - if (ls == self->m_ClosedSockets.end()) - continue; - } - - CGuard::enterCS(ls->second->m_AcceptLock); - ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); - ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); - CGuard::leaveCS(ls->second->m_AcceptLock); - } - self->m_Sockets.clear(); - - for (map::iterator j = self->m_ClosedSockets.begin(); j != self->m_ClosedSockets.end(); ++ j) - { - j->second->m_TimeStamp = 0; - } - CGuard::leaveCS(self->m_ControlLock); - - while (true) - { - self->checkBrokenSockets(); - - CGuard::enterCS(self->m_ControlLock); - bool empty = self->m_ClosedSockets.empty(); - CGuard::leaveCS(self->m_ControlLock); - - if (empty) - break; - - CTimer::sleep(); - } - - #ifndef WIN32 - return NULL; - #else - return 0; - #endif -} - -//////////////////////////////////////////////////////////////////////////////// - -int CUDT::startup() -{ - return s_UDTUnited.startup(); -} - -int CUDT::cleanup() -{ - return s_UDTUnited.cleanup(); -} - -UDTSOCKET CUDT::socket(int af, int type, int) -{ - if (!s_UDTUnited.m_bGCStatus) - s_UDTUnited.startup(); - - try - { - return s_UDTUnited.newSocket(af, type); - } - catch (CUDTException& e) - { - s_UDTUnited.setError(new CUDTException(e)); - return INVALID_SOCK; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return INVALID_SOCK; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return INVALID_SOCK; - } -} - -int CUDT::bind(UDTSOCKET u, const sockaddr* name, int namelen) -{ - try - { - return s_UDTUnited.bind(u, name, namelen); - } - catch (CUDTException& e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::bind(UDTSOCKET u, UDPSOCKET udpsock) -{ - try - { - return s_UDTUnited.bind(u, udpsock); - } - catch (CUDTException& e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::listen(UDTSOCKET u, int backlog) -{ - try - { - return s_UDTUnited.listen(u, backlog); - } - catch (CUDTException& e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -UDTSOCKET CUDT::accept(UDTSOCKET u, sockaddr* addr, int* addrlen) -{ - try - { - return s_UDTUnited.accept(u, addr, addrlen); - } - catch (CUDTException& e) - { - s_UDTUnited.setError(new CUDTException(e)); - return INVALID_SOCK; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return INVALID_SOCK; - } -} - -int CUDT::connect(UDTSOCKET u, const sockaddr* name, int namelen) -{ - try - { - return s_UDTUnited.connect(u, name, namelen); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::close(UDTSOCKET u) -{ - try - { - return s_UDTUnited.close(u); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::getpeername(UDTSOCKET u, sockaddr* name, int* namelen) -{ - try - { - return s_UDTUnited.getpeername(u, name, namelen); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::getsockname(UDTSOCKET u, sockaddr* name, int* namelen) -{ - try - { - return s_UDTUnited.getsockname(u, name, namelen);; - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::getsockopt(UDTSOCKET u, int, UDTOpt optname, void* optval, int* optlen) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - udt->getOpt(optname, optval, *optlen); - return 0; - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::setsockopt(UDTSOCKET u, int, UDTOpt optname, const void* optval, int optlen) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - udt->setOpt(optname, optval, optlen); - return 0; - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::send(UDTSOCKET u, const char* buf, int len, int) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - return udt->send(buf, len); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::recv(UDTSOCKET u, char* buf, int len, int) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - return udt->recv(buf, len); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - return udt->sendmsg(buf, len, ttl, inorder); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::recvmsg(UDTSOCKET u, char* buf, int len) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - return udt->recvmsg(buf, len); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int64_t CUDT::sendfile(UDTSOCKET u, fstream& ifs, int64_t& offset, int64_t size, int block) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - return udt->sendfile(ifs, offset, size, block); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int64_t CUDT::recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset, int64_t size, int block) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - return udt->recvfile(ofs, offset, size, block); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::select(int, ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout) -{ - if ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds)) - { - s_UDTUnited.setError(new CUDTException(5, 3, 0)); - return ERROR; - } - - try - { - return s_UDTUnited.select(readfds, writefds, exceptfds, timeout); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::selectEx(const vector& fds, vector* readfds, vector* writefds, vector* exceptfds, int64_t msTimeOut) -{ - if ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds)) - { - s_UDTUnited.setError(new CUDTException(5, 3, 0)); - return ERROR; - } - - try - { - return s_UDTUnited.selectEx(fds, readfds, writefds, exceptfds, msTimeOut); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (bad_alloc&) - { - s_UDTUnited.setError(new CUDTException(3, 2, 0)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_create() -{ - try - { - return s_UDTUnited.epoll_create(); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) -{ - try - { - return s_UDTUnited.epoll_add_usock(eid, u, events); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) -{ - try - { - return s_UDTUnited.epoll_add_ssock(eid, s, events); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_remove_usock(const int eid, const UDTSOCKET u) -{ - try - { - return s_UDTUnited.epoll_remove_usock(eid, u); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_remove_ssock(const int eid, const SYSSOCKET s) -{ - try - { - return s_UDTUnited.epoll_remove_ssock(eid, s); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_wait(const int eid, set* readfds, set* writefds, int64_t msTimeOut, set* lrfds, set* lwfds) -{ - try - { - return s_UDTUnited.epoll_wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -int CUDT::epoll_release(const int eid) -{ - try - { - return s_UDTUnited.epoll_release(eid); - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -CUDTException& CUDT::getlasterror() -{ - return *s_UDTUnited.getError(); -} - -int CUDT::perfmon(UDTSOCKET u, CPerfMon* perf, bool clear) -{ - try - { - CUDT* udt = s_UDTUnited.lookup(u); - udt->sample(perf, clear); - return 0; - } - catch (CUDTException e) - { - s_UDTUnited.setError(new CUDTException(e)); - return ERROR; - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return ERROR; - } -} - -CUDT* CUDT::getUDTHandle(UDTSOCKET u) -{ - try - { - return s_UDTUnited.lookup(u); - } - catch (...) - { - return NULL; - } -} - -UDTSTATUS CUDT::getsockstate(UDTSOCKET u) -{ - try - { - return s_UDTUnited.getStatus(u); - } - catch (...) - { - s_UDTUnited.setError(new CUDTException(-1, 0, 0)); - return NONEXIST; - } -} - - -//////////////////////////////////////////////////////////////////////////////// - -namespace UDT -{ - -int startup() -{ - return CUDT::startup(); -} - -int cleanup() -{ - return CUDT::cleanup(); -} - -UDTSOCKET socket(int af, int type, int protocol) -{ - return CUDT::socket(af, type, protocol); -} - -int bind(UDTSOCKET u, const struct sockaddr* name, int namelen) -{ - return CUDT::bind(u, name, namelen); -} - -int bind2(UDTSOCKET u, UDPSOCKET udpsock) -{ - return CUDT::bind(u, udpsock); -} - -int listen(UDTSOCKET u, int backlog) -{ - return CUDT::listen(u, backlog); -} - -UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen) -{ - return CUDT::accept(u, addr, addrlen); -} - -int connect(UDTSOCKET u, const struct sockaddr* name, int namelen) -{ - return CUDT::connect(u, name, namelen); -} - -int close(UDTSOCKET u) -{ - return CUDT::close(u); -} - -int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen) -{ - return CUDT::getpeername(u, name, namelen); -} - -int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen) -{ - return CUDT::getsockname(u, name, namelen); -} - -int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optlen) -{ - return CUDT::getsockopt(u, level, optname, optval, optlen); -} - -int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int optlen) -{ - return CUDT::setsockopt(u, level, optname, optval, optlen); -} - -int send(UDTSOCKET u, const char* buf, int len, int flags) -{ - return CUDT::send(u, buf, len, flags); -} - -int recv(UDTSOCKET u, char* buf, int len, int flags) -{ - return CUDT::recv(u, buf, len, flags); -} - -int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) -{ - return CUDT::sendmsg(u, buf, len, ttl, inorder); -} - -int recvmsg(UDTSOCKET u, char* buf, int len) -{ - return CUDT::recvmsg(u, buf, len); -} - -int64_t sendfile(UDTSOCKET u, fstream& ifs, int64_t& offset, int64_t size, int block) -{ - return CUDT::sendfile(u, ifs, offset, size, block); -} - -int64_t recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset, int64_t size, int block) -{ - return CUDT::recvfile(u, ofs, offset, size, block); -} - -int64_t sendfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block) -{ - fstream ifs(path, ios::binary | ios::in); - int64_t ret = CUDT::sendfile(u, ifs, *offset, size, block); - ifs.close(); - return ret; -} - -int64_t recvfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block) -{ - fstream ofs(path, ios::binary | ios::out); - int64_t ret = CUDT::recvfile(u, ofs, *offset, size, block); - ofs.close(); - return ret; -} - -int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout) -{ - return CUDT::select(nfds, readfds, writefds, exceptfds, timeout); -} - -int selectEx(const vector& fds, vector* readfds, vector* writefds, vector* exceptfds, int64_t msTimeOut) -{ - return CUDT::selectEx(fds, readfds, writefds, exceptfds, msTimeOut); -} - -int epoll_create() -{ - return CUDT::epoll_create(); -} - -int epoll_add_usock(int eid, UDTSOCKET u, const int* events) -{ - return CUDT::epoll_add_usock(eid, u, events); -} - -int epoll_add_ssock(int eid, SYSSOCKET s, const int* events) -{ - return CUDT::epoll_add_ssock(eid, s, events); -} - -int epoll_remove_usock(int eid, UDTSOCKET u) -{ - return CUDT::epoll_remove_usock(eid, u); -} - -int epoll_remove_ssock(int eid, SYSSOCKET s) -{ - return CUDT::epoll_remove_ssock(eid, s); -} - -int epoll_wait(int eid, set* readfds, set* writefds, int64_t msTimeOut, set* lrfds, set* lwfds) -{ - return CUDT::epoll_wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); -} - -#define SET_RESULT(val, num, fds, it) \ - if ((val != NULL) && !val->empty()) \ - { \ - if (*num > static_cast(val->size())) \ - *num = val->size(); \ - int count = 0; \ - for (it = val->begin(); it != val->end(); ++ it) \ - { \ - if (count >= *num) \ - break; \ - fds[count ++] = *it; \ - } \ - } -int epoll_wait2(int eid, UDTSOCKET* readfds, int* rnum, UDTSOCKET* writefds, int* wnum, int64_t msTimeOut, - SYSSOCKET* lrfds, int* lrnum, SYSSOCKET* lwfds, int* lwnum) -{ - // This API is an alternative format for epoll_wait, created for compatability with other languages. - // Users need to pass in an array for holding the returned sockets, with the maximum array length - // stored in *rnum, etc., which will be updated with returned number of sockets. - - set readset; - set writeset; - set lrset; - set lwset; - set* rval = NULL; - set* wval = NULL; - set* lrval = NULL; - set* lwval = NULL; - if ((readfds != NULL) && (rnum != NULL)) - rval = &readset; - if ((writefds != NULL) && (wnum != NULL)) - wval = &writeset; - if ((lrfds != NULL) && (lrnum != NULL)) - lrval = &lrset; - if ((lwfds != NULL) && (lwnum != NULL)) - lwval = &lwset; - - int ret = CUDT::epoll_wait(eid, rval, wval, msTimeOut, lrval, lwval); - if (ret > 0) - { - set::const_iterator i; - SET_RESULT(rval, rnum, readfds, i); - SET_RESULT(wval, wnum, writefds, i); - set::const_iterator j; - SET_RESULT(lrval, lrnum, lrfds, j); - SET_RESULT(lwval, lwnum, lwfds, j); - } - return ret; -} - -int epoll_release(int eid) -{ - return CUDT::epoll_release(eid); -} - -ERRORINFO& getlasterror() -{ - return CUDT::getlasterror(); -} - -int getlasterror_code() -{ - return CUDT::getlasterror().getErrorCode(); -} - -const char* getlasterror_desc() -{ - return CUDT::getlasterror().getErrorMessage(); -} - -int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear) -{ - return CUDT::perfmon(u, perf, clear); -} - -UDTSTATUS getsockstate(UDTSOCKET u) -{ - return CUDT::getsockstate(u); -} - -} // namespace UDT diff --git a/vendor/udt4/src/api.h b/vendor/udt4/src/api.h deleted file mode 100644 index 24f1a02..0000000 --- a/vendor/udt4/src/api.h +++ /dev/null @@ -1,268 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 09/28/2010 -*****************************************************************************/ - -#ifndef __UDT_API_H__ -#define __UDT_API_H__ - - -#include -#include -#include "udt.h" -#include "packet.h" -#include "queue.h" -#include "cache.h" -#include "epoll.h" - -class CUDT; - -class CUDTSocket -{ -public: - CUDTSocket(); - ~CUDTSocket(); - - UDTSTATUS m_Status; // current socket state - - uint64_t m_TimeStamp; // time when the socket is closed - - int m_iIPversion; // IP version - sockaddr* m_pSelfAddr; // pointer to the local address of the socket - sockaddr* m_pPeerAddr; // pointer to the peer address of the socket - - UDTSOCKET m_SocketID; // socket ID - UDTSOCKET m_ListenSocket; // ID of the listener socket; 0 means this is an independent socket - - UDTSOCKET m_PeerID; // peer socket ID - int32_t m_iISN; // initial sequence number, used to tell different connection from same IP:port - - CUDT* m_pUDT; // pointer to the UDT entity - - std::set* m_pQueuedSockets; // set of connections waiting for accept() - std::set* m_pAcceptSockets; // set of accept()ed connections - - pthread_cond_t m_AcceptCond; // used to block "accept" call - pthread_mutex_t m_AcceptLock; // mutex associated to m_AcceptCond - - unsigned int m_uiBackLog; // maximum number of connections in queue - - int m_iMuxID; // multiplexer ID - - pthread_mutex_t m_ControlLock; // lock this socket exclusively for control APIs: bind/listen/connect - -private: - CUDTSocket(const CUDTSocket&); - CUDTSocket& operator=(const CUDTSocket&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CUDTUnited -{ -friend class CUDT; -friend class CRendezvousQueue; - -public: - CUDTUnited(); - ~CUDTUnited(); - -public: - - // Functionality: - // initialize the UDT library. - // Parameters: - // None. - // Returned value: - // 0 if success, otherwise -1 is returned. - - int startup(); - - // Functionality: - // release the UDT library. - // Parameters: - // None. - // Returned value: - // 0 if success, otherwise -1 is returned. - - int cleanup(); - - // Functionality: - // Create a new UDT socket. - // Parameters: - // 0) [in] af: IP version, IPv4 (AF_INET) or IPv6 (AF_INET6). - // 1) [in] type: socket type, SOCK_STREAM or SOCK_DGRAM - // Returned value: - // The new UDT socket ID, or INVALID_SOCK. - - UDTSOCKET newSocket(int af, int type); - - // Functionality: - // Create a new UDT connection. - // Parameters: - // 0) [in] listen: the listening UDT socket; - // 1) [in] peer: peer address. - // 2) [in/out] hs: handshake information from peer side (in), negotiated value (out); - // Returned value: - // If the new connection is successfully created: 1 success, 0 already exist, -1 error. - - int newConnection(const UDTSOCKET listen, const sockaddr* peer, CHandShake* hs); - - // Functionality: - // look up the UDT entity according to its ID. - // Parameters: - // 0) [in] u: the UDT socket ID. - // Returned value: - // Pointer to the UDT entity. - - CUDT* lookup(const UDTSOCKET u); - - // Functionality: - // Check the status of the UDT socket. - // Parameters: - // 0) [in] u: the UDT socket ID. - // Returned value: - // UDT socket status, or NONEXIST if not found. - - UDTSTATUS getStatus(const UDTSOCKET u); - - // socket APIs - - int bind(const UDTSOCKET u, const sockaddr* name, int namelen); - int bind(const UDTSOCKET u, UDPSOCKET udpsock); - int listen(const UDTSOCKET u, int backlog); - UDTSOCKET accept(const UDTSOCKET listen, sockaddr* addr, int* addrlen); - int connect(const UDTSOCKET u, const sockaddr* name, int namelen); - int close(const UDTSOCKET u); - int getpeername(const UDTSOCKET u, sockaddr* name, int* namelen); - int getsockname(const UDTSOCKET u, sockaddr* name, int* namelen); - int select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout); - int selectEx(const std::vector& fds, std::vector* readfds, std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); - int epoll_create(); - int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events = NULL); - int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); - int epoll_remove_usock(const int eid, const UDTSOCKET u); - int epoll_remove_ssock(const int eid, const SYSSOCKET s); - int epoll_wait(const int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, std::set* lrfds = NULL, std::set* lwfds = NULL); - int epoll_release(const int eid); - - // Functionality: - // record the UDT exception. - // Parameters: - // 0) [in] e: pointer to a UDT exception instance. - // Returned value: - // None. - - void setError(CUDTException* e); - - // Functionality: - // look up the most recent UDT exception. - // Parameters: - // None. - // Returned value: - // pointer to a UDT exception instance. - - CUDTException* getError(); - -private: -// void init(); - -private: - std::map m_Sockets; // stores all the socket structures - - pthread_mutex_t m_ControlLock; // used to synchronize UDT API - - pthread_mutex_t m_IDLock; // used to synchronize ID generation - UDTSOCKET m_SocketID; // seed to generate a new unique socket ID - - std::map > m_PeerRec;// record sockets from peers to avoid repeated connection request, int64_t = (socker_id << 30) + isn - -private: - pthread_key_t m_TLSError; // thread local error record (last error) - #ifndef WIN32 - static void TLSDestroy(void* e) {if (NULL != e) delete (CUDTException*)e;} - #else - std::map m_mTLSRecord; - void checkTLSValue(); - pthread_mutex_t m_TLSLock; - #endif - -private: - void connect_complete(const UDTSOCKET u); - CUDTSocket* locate(const UDTSOCKET u); - CUDTSocket* locate(const sockaddr* peer, const UDTSOCKET id, int32_t isn); - void updateMux(CUDTSocket* s, const sockaddr* addr = NULL, const UDPSOCKET* = NULL); - void updateMux(CUDTSocket* s, const CUDTSocket* ls); - -private: - std::map m_mMultiplexer; // UDP multiplexer - pthread_mutex_t m_MultiplexerLock; - -private: - CCache* m_pCache; // UDT network information cache - -private: - volatile bool m_bClosing; - pthread_mutex_t m_GCStopLock; - pthread_cond_t m_GCStopCond; - - pthread_mutex_t m_InitLock; - int m_iInstanceCount; // number of startup() called by application - bool m_bGCStatus; // if the GC thread is working (true) - - pthread_t m_GCThread; - #ifndef WIN32 - static void* garbageCollect(void*); - #else - static DWORD WINAPI garbageCollect(LPVOID); - #endif - - std::map m_ClosedSockets; // temporarily store closed sockets - - void checkBrokenSockets(); - void removeSocket(const UDTSOCKET u); - -private: - CEPoll m_EPoll; // handling epoll data structures and events - -private: - CUDTUnited(const CUDTUnited&); - CUDTUnited& operator=(const CUDTUnited&); -}; - -#endif diff --git a/vendor/udt4/src/buffer.cpp b/vendor/udt4/src/buffer.cpp deleted file mode 100644 index 327ab76..0000000 --- a/vendor/udt4/src/buffer.cpp +++ /dev/null @@ -1,652 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 03/12/2011 -*****************************************************************************/ - -#include -#include -#include "buffer.h" - -using namespace std; - -CSndBuffer::CSndBuffer(int size, int mss): -m_BufLock(), -m_pBlock(NULL), -m_pFirstBlock(NULL), -m_pCurrBlock(NULL), -m_pLastBlock(NULL), -m_pBuffer(NULL), -m_iNextMsgNo(1), -m_iSize(size), -m_iMSS(mss), -m_iCount(0) -{ - // initial physical buffer of "size" - m_pBuffer = new Buffer; - m_pBuffer->m_pcData = new char [m_iSize * m_iMSS]; - m_pBuffer->m_iSize = m_iSize; - m_pBuffer->m_pNext = NULL; - - // circular linked list for out bound packets - m_pBlock = new Block; - Block* pb = m_pBlock; - for (int i = 1; i < m_iSize; ++ i) - { - pb->m_pNext = new Block; - pb->m_iMsgNo = 0; - pb = pb->m_pNext; - } - pb->m_pNext = m_pBlock; - - pb = m_pBlock; - char* pc = m_pBuffer->m_pcData; - for (int i = 0; i < m_iSize; ++ i) - { - pb->m_pcData = pc; - pb = pb->m_pNext; - pc += m_iMSS; - } - - m_pFirstBlock = m_pCurrBlock = m_pLastBlock = m_pBlock; - - #ifndef WIN32 - pthread_mutex_init(&m_BufLock, NULL); - #else - m_BufLock = CreateMutex(NULL, false, NULL); - #endif -} - -CSndBuffer::~CSndBuffer() -{ - Block* pb = m_pBlock->m_pNext; - while (pb != m_pBlock) - { - Block* temp = pb; - pb = pb->m_pNext; - delete temp; - } - delete m_pBlock; - - while (m_pBuffer != NULL) - { - Buffer* temp = m_pBuffer; - m_pBuffer = m_pBuffer->m_pNext; - delete [] temp->m_pcData; - delete temp; - } - - #ifndef WIN32 - pthread_mutex_destroy(&m_BufLock); - #else - CloseHandle(m_BufLock); - #endif -} - -void CSndBuffer::addBuffer(const char* data, int len, int ttl, bool order) -{ - int size = len / m_iMSS; - if ((len % m_iMSS) != 0) - size ++; - - // dynamically increase sender buffer - while (size + m_iCount >= m_iSize) - increase(); - - uint64_t time = CTimer::getTime(); - int32_t inorder = order; - inorder <<= 29; - - Block* s = m_pLastBlock; - for (int i = 0; i < size; ++ i) - { - int pktlen = len - i * m_iMSS; - if (pktlen > m_iMSS) - pktlen = m_iMSS; - - memcpy(s->m_pcData, data + i * m_iMSS, pktlen); - s->m_iLength = pktlen; - - s->m_iMsgNo = m_iNextMsgNo | inorder; - if (i == 0) - s->m_iMsgNo |= 0x80000000; - if (i == size - 1) - s->m_iMsgNo |= 0x40000000; - - s->m_OriginTime = time; - s->m_iTTL = ttl; - - s = s->m_pNext; - } - m_pLastBlock = s; - - CGuard::enterCS(m_BufLock); - m_iCount += size; - CGuard::leaveCS(m_BufLock); - - m_iNextMsgNo ++; - if (m_iNextMsgNo == CMsgNo::m_iMaxMsgNo) - m_iNextMsgNo = 1; -} - -int CSndBuffer::addBufferFromFile(fstream& ifs, int len) -{ - int size = len / m_iMSS; - if ((len % m_iMSS) != 0) - size ++; - - // dynamically increase sender buffer - while (size + m_iCount >= m_iSize) - increase(); - - Block* s = m_pLastBlock; - int total = 0; - for (int i = 0; i < size; ++ i) - { - if (ifs.bad() || ifs.fail() || ifs.eof()) - break; - - int pktlen = len - i * m_iMSS; - if (pktlen > m_iMSS) - pktlen = m_iMSS; - - ifs.read(s->m_pcData, pktlen); - if ((pktlen = ifs.gcount()) <= 0) - break; - - // currently file transfer is only available in streaming mode, message is always in order, ttl = infinite - s->m_iMsgNo = m_iNextMsgNo | 0x20000000; - if (i == 0) - s->m_iMsgNo |= 0x80000000; - if (i == size - 1) - s->m_iMsgNo |= 0x40000000; - - s->m_iLength = pktlen; - s->m_iTTL = -1; - s = s->m_pNext; - - total += pktlen; - } - m_pLastBlock = s; - - CGuard::enterCS(m_BufLock); - m_iCount += size; - CGuard::leaveCS(m_BufLock); - - m_iNextMsgNo ++; - if (m_iNextMsgNo == CMsgNo::m_iMaxMsgNo) - m_iNextMsgNo = 1; - - return total; -} - -int CSndBuffer::readData(char** data, int32_t& msgno) -{ - // No data to read - if (m_pCurrBlock == m_pLastBlock) - return 0; - - *data = m_pCurrBlock->m_pcData; - int readlen = m_pCurrBlock->m_iLength; - msgno = m_pCurrBlock->m_iMsgNo; - - m_pCurrBlock = m_pCurrBlock->m_pNext; - - return readlen; -} - -int CSndBuffer::readData(char** data, const int offset, int32_t& msgno, int& msglen) -{ - CGuard bufferguard(m_BufLock); - - Block* p = m_pFirstBlock; - - for (int i = 0; i < offset; ++ i) - p = p->m_pNext; - - if ((p->m_iTTL >= 0) && ((CTimer::getTime() - p->m_OriginTime) / 1000 > (uint64_t)p->m_iTTL)) - { - msgno = p->m_iMsgNo & 0x1FFFFFFF; - - msglen = 1; - p = p->m_pNext; - bool move = false; - while (msgno == (p->m_iMsgNo & 0x1FFFFFFF)) - { - if (p == m_pCurrBlock) - move = true; - p = p->m_pNext; - if (move) - m_pCurrBlock = p; - msglen ++; - } - - return -1; - } - - *data = p->m_pcData; - int readlen = p->m_iLength; - msgno = p->m_iMsgNo; - - return readlen; -} - -void CSndBuffer::ackData(int offset) -{ - CGuard bufferguard(m_BufLock); - - for (int i = 0; i < offset; ++ i) - m_pFirstBlock = m_pFirstBlock->m_pNext; - - m_iCount -= offset; - - CTimer::triggerEvent(); -} - -int CSndBuffer::getCurrBufSize() const -{ - return m_iCount; -} - -void CSndBuffer::increase() -{ - int unitsize = m_pBuffer->m_iSize; - - // new physical buffer - Buffer* nbuf = NULL; - try - { - nbuf = new Buffer; - nbuf->m_pcData = new char [unitsize * m_iMSS]; - } - catch (...) - { - delete nbuf; - throw CUDTException(3, 2, 0); - } - nbuf->m_iSize = unitsize; - nbuf->m_pNext = NULL; - - // insert the buffer at the end of the buffer list - Buffer* p = m_pBuffer; - while (NULL != p->m_pNext) - p = p->m_pNext; - p->m_pNext = nbuf; - - // new packet blocks - Block* nblk = NULL; - try - { - nblk = new Block; - } - catch (...) - { - delete nblk; - throw CUDTException(3, 2, 0); - } - Block* pb = nblk; - for (int i = 1; i < unitsize; ++ i) - { - pb->m_pNext = new Block; - pb = pb->m_pNext; - } - - // insert the new blocks onto the existing one - pb->m_pNext = m_pLastBlock->m_pNext; - m_pLastBlock->m_pNext = nblk; - - pb = nblk; - char* pc = nbuf->m_pcData; - for (int i = 0; i < unitsize; ++ i) - { - pb->m_pcData = pc; - pb = pb->m_pNext; - pc += m_iMSS; - } - - m_iSize += unitsize; -} - -//////////////////////////////////////////////////////////////////////////////// - -CRcvBuffer::CRcvBuffer(CUnitQueue* queue, int bufsize): -m_pUnit(NULL), -m_iSize(bufsize), -m_pUnitQueue(queue), -m_iStartPos(0), -m_iLastAckPos(0), -m_iMaxPos(0), -m_iNotch(0) -{ - m_pUnit = new CUnit* [m_iSize]; - for (int i = 0; i < m_iSize; ++ i) - m_pUnit[i] = NULL; -} - -CRcvBuffer::~CRcvBuffer() -{ - for (int i = 0; i < m_iSize; ++ i) - { - if (NULL != m_pUnit[i]) - { - m_pUnit[i]->m_iFlag = 0; - -- m_pUnitQueue->m_iCount; - } - } - - delete [] m_pUnit; -} - -int CRcvBuffer::addData(CUnit* unit, int offset) -{ - int pos = (m_iLastAckPos + offset) % m_iSize; - if (offset > m_iMaxPos) - m_iMaxPos = offset; - - if (NULL != m_pUnit[pos]) - return -1; - - m_pUnit[pos] = unit; - - unit->m_iFlag = 1; - ++ m_pUnitQueue->m_iCount; - - return 0; -} - -int CRcvBuffer::readBuffer(char* data, int len) -{ - int p = m_iStartPos; - int lastack = m_iLastAckPos; - int rs = len; - - while ((p != lastack) && (rs > 0)) - { - int unitsize = m_pUnit[p]->m_Packet.getLength() - m_iNotch; - if (unitsize > rs) - unitsize = rs; - - memcpy(data, m_pUnit[p]->m_Packet.m_pcData + m_iNotch, unitsize); - data += unitsize; - - if ((rs > unitsize) || (rs == m_pUnit[p]->m_Packet.getLength() - m_iNotch)) - { - CUnit* tmp = m_pUnit[p]; - m_pUnit[p] = NULL; - tmp->m_iFlag = 0; - -- m_pUnitQueue->m_iCount; - - if (++ p == m_iSize) - p = 0; - - m_iNotch = 0; - } - else - m_iNotch += rs; - - rs -= unitsize; - } - - m_iStartPos = p; - return len - rs; -} - -int CRcvBuffer::readBufferToFile(fstream& ofs, int len) -{ - int p = m_iStartPos; - int lastack = m_iLastAckPos; - int rs = len; - - while ((p != lastack) && (rs > 0)) - { - int unitsize = m_pUnit[p]->m_Packet.getLength() - m_iNotch; - if (unitsize > rs) - unitsize = rs; - - ofs.write(m_pUnit[p]->m_Packet.m_pcData + m_iNotch, unitsize); - if (ofs.fail()) - break; - - if ((rs > unitsize) || (rs == m_pUnit[p]->m_Packet.getLength() - m_iNotch)) - { - CUnit* tmp = m_pUnit[p]; - m_pUnit[p] = NULL; - tmp->m_iFlag = 0; - -- m_pUnitQueue->m_iCount; - - if (++ p == m_iSize) - p = 0; - - m_iNotch = 0; - } - else - m_iNotch += rs; - - rs -= unitsize; - } - - m_iStartPos = p; - - return len - rs; -} - -void CRcvBuffer::ackData(int len) -{ - m_iLastAckPos = (m_iLastAckPos + len) % m_iSize; - m_iMaxPos -= len; - if (m_iMaxPos < 0) - m_iMaxPos = 0; - - CTimer::triggerEvent(); -} - -int CRcvBuffer::getAvailBufSize() const -{ - // One slot must be empty in order to tell the difference between "empty buffer" and "full buffer" - return m_iSize - getRcvDataSize() - 1; -} - -int CRcvBuffer::getRcvDataSize() const -{ - if (m_iLastAckPos >= m_iStartPos) - return m_iLastAckPos - m_iStartPos; - - return m_iSize + m_iLastAckPos - m_iStartPos; -} - -void CRcvBuffer::dropMsg(int32_t msgno) -{ - for (int i = m_iStartPos, n = (m_iLastAckPos + m_iMaxPos) % m_iSize; i != n; i = (i + 1) % m_iSize) - if ((NULL != m_pUnit[i]) && (msgno == m_pUnit[i]->m_Packet.m_iMsgNo)) - m_pUnit[i]->m_iFlag = 3; -} - -int CRcvBuffer::readMsg(char* data, int len) -{ - int p, q; - bool passack; - if (!scanMsg(p, q, passack)) - return 0; - - int rs = len; - while (p != (q + 1) % m_iSize) - { - int unitsize = m_pUnit[p]->m_Packet.getLength(); - if ((rs >= 0) && (unitsize > rs)) - unitsize = rs; - - if (unitsize > 0) - { - memcpy(data, m_pUnit[p]->m_Packet.m_pcData, unitsize); - data += unitsize; - rs -= unitsize; - } - - if (!passack) - { - CUnit* tmp = m_pUnit[p]; - m_pUnit[p] = NULL; - tmp->m_iFlag = 0; - -- m_pUnitQueue->m_iCount; - } - else - m_pUnit[p]->m_iFlag = 2; - - if (++ p == m_iSize) - p = 0; - } - - if (!passack) - m_iStartPos = (q + 1) % m_iSize; - - return len - rs; -} - -int CRcvBuffer::getRcvMsgNum() -{ - int p, q; - bool passack; - return scanMsg(p, q, passack) ? 1 : 0; -} - -bool CRcvBuffer::scanMsg(int& p, int& q, bool& passack) -{ - // empty buffer - if ((m_iStartPos == m_iLastAckPos) && (m_iMaxPos <= 0)) - return false; - - //skip all bad msgs at the beginning - while (m_iStartPos != m_iLastAckPos) - { - if (NULL == m_pUnit[m_iStartPos]) - { - if (++ m_iStartPos == m_iSize) - m_iStartPos = 0; - continue; - } - - if ((1 == m_pUnit[m_iStartPos]->m_iFlag) && (m_pUnit[m_iStartPos]->m_Packet.getMsgBoundary() > 1)) - { - bool good = true; - - // look ahead for the whole message - for (int i = m_iStartPos; i != m_iLastAckPos;) - { - if ((NULL == m_pUnit[i]) || (1 != m_pUnit[i]->m_iFlag)) - { - good = false; - break; - } - - if ((m_pUnit[i]->m_Packet.getMsgBoundary() == 1) || (m_pUnit[i]->m_Packet.getMsgBoundary() == 3)) - break; - - if (++ i == m_iSize) - i = 0; - } - - if (good) - break; - } - - CUnit* tmp = m_pUnit[m_iStartPos]; - m_pUnit[m_iStartPos] = NULL; - tmp->m_iFlag = 0; - -- m_pUnitQueue->m_iCount; - - if (++ m_iStartPos == m_iSize) - m_iStartPos = 0; - } - - p = -1; // message head - q = m_iStartPos; // message tail - passack = m_iStartPos == m_iLastAckPos; - bool found = false; - - // looking for the first message - for (int i = 0, n = m_iMaxPos + getRcvDataSize(); i <= n; ++ i) - { - if ((NULL != m_pUnit[q]) && (1 == m_pUnit[q]->m_iFlag)) - { - switch (m_pUnit[q]->m_Packet.getMsgBoundary()) - { - case 3: // 11 - p = q; - found = true; - break; - - case 2: // 10 - p = q; - break; - - case 1: // 01 - if (p != -1) - found = true; - } - } - else - { - // a hole in this message, not valid, restart search - p = -1; - } - - if (found) - { - // the msg has to be ack'ed or it is allowed to read out of order, and was not read before - if (!passack || !m_pUnit[q]->m_Packet.getMsgOrderFlag()) - break; - - found = false; - } - - if (++ q == m_iSize) - q = 0; - - if (q == m_iLastAckPos) - passack = true; - } - - // no msg found - if (!found) - { - // if the message is larger than the receiver buffer, return part of the message - if ((p != -1) && ((q + 1) % m_iSize == p)) - found = true; - } - - return found; -} diff --git a/vendor/udt4/src/buffer.h b/vendor/udt4/src/buffer.h deleted file mode 100644 index 4377e79..0000000 --- a/vendor/udt4/src/buffer.h +++ /dev/null @@ -1,275 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 05/05/2009 -*****************************************************************************/ - -#ifndef __UDT_BUFFER_H__ -#define __UDT_BUFFER_H__ - - -#include "udt.h" -#include "list.h" -#include "queue.h" -#include - -class CSndBuffer -{ -public: - CSndBuffer(int size = 32, int mss = 1500); - ~CSndBuffer(); - - // Functionality: - // Insert a user buffer into the sending list. - // Parameters: - // 0) [in] data: pointer to the user data block. - // 1) [in] len: size of the block. - // 2) [in] ttl: time to live in milliseconds - // 3) [in] order: if the block should be delivered in order, for DGRAM only - // Returned value: - // None. - - void addBuffer(const char* data, int len, int ttl = -1, bool order = false); - - // Functionality: - // Read a block of data from file and insert it into the sending list. - // Parameters: - // 0) [in] ifs: input file stream. - // 1) [in] len: size of the block. - // Returned value: - // actual size of data added from the file. - - int addBufferFromFile(std::fstream& ifs, int len); - - // Functionality: - // Find data position to pack a DATA packet from the furthest reading point. - // Parameters: - // 0) [out] data: the pointer to the data position. - // 1) [out] msgno: message number of the packet. - // Returned value: - // Actual length of data read. - - int readData(char** data, int32_t& msgno); - - // Functionality: - // Find data position to pack a DATA packet for a retransmission. - // Parameters: - // 0) [out] data: the pointer to the data position. - // 1) [in] offset: offset from the last ACK point. - // 2) [out] msgno: message number of the packet. - // 3) [out] msglen: length of the message - // Returned value: - // Actual length of data read. - - int readData(char** data, const int offset, int32_t& msgno, int& msglen); - - // Functionality: - // Update the ACK point and may release/unmap/return the user data according to the flag. - // Parameters: - // 0) [in] offset: number of packets acknowledged. - // Returned value: - // None. - - void ackData(int offset); - - // Functionality: - // Read size of data still in the sending list. - // Parameters: - // None. - // Returned value: - // Current size of the data in the sending list. - - int getCurrBufSize() const; - -private: - void increase(); - -private: - pthread_mutex_t m_BufLock; // used to synchronize buffer operation - - struct Block - { - char* m_pcData; // pointer to the data block - int m_iLength; // length of the block - - int32_t m_iMsgNo; // message number - uint64_t m_OriginTime; // original request time - int m_iTTL; // time to live (milliseconds) - - Block* m_pNext; // next block - } *m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock; - - // m_pBlock: The head pointer - // m_pFirstBlock: The first block - // m_pCurrBlock: The current block - // m_pLastBlock: The last block (if first == last, buffer is empty) - - struct Buffer - { - char* m_pcData; // buffer - int m_iSize; // size - Buffer* m_pNext; // next buffer - } *m_pBuffer; // physical buffer - - int32_t m_iNextMsgNo; // next message number - - int m_iSize; // buffer size (number of packets) - int m_iMSS; // maximum seqment/packet size - - int m_iCount; // number of used blocks - -private: - CSndBuffer(const CSndBuffer&); - CSndBuffer& operator=(const CSndBuffer&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CRcvBuffer -{ -public: - CRcvBuffer(CUnitQueue* queue, int bufsize = 65536); - ~CRcvBuffer(); - - // Functionality: - // Write data into the buffer. - // Parameters: - // 0) [in] unit: pointer to a data unit containing new packet - // 1) [in] offset: offset from last ACK point. - // Returned value: - // 0 is success, -1 if data is repeated. - - int addData(CUnit* unit, int offset); - - // Functionality: - // Read data into a user buffer. - // Parameters: - // 0) [in] data: pointer to user buffer. - // 1) [in] len: length of user buffer. - // Returned value: - // size of data read. - - int readBuffer(char* data, int len); - - // Functionality: - // Read data directly into file. - // Parameters: - // 0) [in] file: C++ file stream. - // 1) [in] len: expected length of data to write into the file. - // Returned value: - // size of data read. - - int readBufferToFile(std::fstream& ofs, int len); - - // Functionality: - // Update the ACK point of the buffer. - // Parameters: - // 0) [in] len: size of data to be acknowledged. - // Returned value: - // 1 if a user buffer is fulfilled, otherwise 0. - - void ackData(int len); - - // Functionality: - // Query how many buffer space left for data receiving. - // Parameters: - // None. - // Returned value: - // size of available buffer space (including user buffer) for data receiving. - - int getAvailBufSize() const; - - // Functionality: - // Query how many data has been continuously received (for reading). - // Parameters: - // None. - // Returned value: - // size of valid (continous) data for reading. - - int getRcvDataSize() const; - - // Functionality: - // mark the message to be dropped from the message list. - // Parameters: - // 0) [in] msgno: message nuumer. - // Returned value: - // None. - - void dropMsg(int32_t msgno); - - // Functionality: - // read a message. - // Parameters: - // 0) [out] data: buffer to write the message into. - // 1) [in] len: size of the buffer. - // Returned value: - // actuall size of data read. - - int readMsg(char* data, int len); - - // Functionality: - // Query how many messages are available now. - // Parameters: - // None. - // Returned value: - // number of messages available for recvmsg. - - int getRcvMsgNum(); - -private: - bool scanMsg(int& start, int& end, bool& passack); - -private: - CUnit** m_pUnit; // pointer to the protocol buffer - int m_iSize; // size of the protocol buffer - CUnitQueue* m_pUnitQueue; // the shared unit queue - - int m_iStartPos; // the head position for I/O (inclusive) - int m_iLastAckPos; // the last ACKed position (exclusive) - // EMPTY: m_iStartPos = m_iLastAckPos FULL: m_iStartPos = m_iLastAckPos + 1 - int m_iMaxPos; // the furthest data position - - int m_iNotch; // the starting read point of the first unit - -private: - CRcvBuffer(); - CRcvBuffer(const CRcvBuffer&); - CRcvBuffer& operator=(const CRcvBuffer&); -}; - - -#endif diff --git a/vendor/udt4/src/cache.cpp b/vendor/udt4/src/cache.cpp deleted file mode 100644 index ea0aad1..0000000 --- a/vendor/udt4/src/cache.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 05/05/2009 -*****************************************************************************/ - -#ifdef WIN32 - #include - #include - #ifdef LEGACY_WIN32 - #include - #endif -#endif - -#include -#include "cache.h" -#include "core.h" - -using namespace std; - -CInfoBlock& CInfoBlock::operator=(const CInfoBlock& obj) -{ - std::copy(obj.m_piIP, obj.m_piIP + 3, m_piIP); - m_iIPversion = obj.m_iIPversion; - m_ullTimeStamp = obj.m_ullTimeStamp; - m_iRTT = obj.m_iRTT; - m_iBandwidth = obj.m_iBandwidth; - m_iLossRate = obj.m_iLossRate; - m_iReorderDistance = obj.m_iReorderDistance; - m_dInterval = obj.m_dInterval; - m_dCWnd = obj.m_dCWnd; - - return *this; -} - -bool CInfoBlock::operator==(const CInfoBlock& obj) -{ - if (m_iIPversion != obj.m_iIPversion) - return false; - - else if (m_iIPversion == AF_INET) - return (m_piIP[0] == obj.m_piIP[0]); - - for (int i = 0; i < 4; ++ i) - { - if (m_piIP[i] != obj.m_piIP[i]) - return false; - } - - return true; -} - -CInfoBlock* CInfoBlock::clone() -{ - CInfoBlock* obj = new CInfoBlock; - - std::copy(m_piIP, m_piIP + 3, obj->m_piIP); - obj->m_iIPversion = m_iIPversion; - obj->m_ullTimeStamp = m_ullTimeStamp; - obj->m_iRTT = m_iRTT; - obj->m_iBandwidth = m_iBandwidth; - obj->m_iLossRate = m_iLossRate; - obj->m_iReorderDistance = m_iReorderDistance; - obj->m_dInterval = m_dInterval; - obj->m_dCWnd = m_dCWnd; - - return obj; -} - -int CInfoBlock::getKey() -{ - if (m_iIPversion == AF_INET) - return m_piIP[0]; - - return m_piIP[0] + m_piIP[1] + m_piIP[2] + m_piIP[3]; -} - -void CInfoBlock::convert(const sockaddr* addr, int ver, uint32_t ip[]) -{ - if (ver == AF_INET) - { - ip[0] = ((sockaddr_in*)addr)->sin_addr.s_addr; - ip[1] = ip[2] = ip[3] = 0; - } - else - { - memcpy((char*)ip, (char*)((sockaddr_in6*)addr)->sin6_addr.s6_addr, 16); - } -} diff --git a/vendor/udt4/src/cache.h b/vendor/udt4/src/cache.h deleted file mode 100644 index 22d9624..0000000 --- a/vendor/udt4/src/cache.h +++ /dev/null @@ -1,293 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/27/2011 -*****************************************************************************/ - -#ifndef __UDT_CACHE_H__ -#define __UDT_CACHE_H__ - -#include -#include - -#include "common.h" -#include "udt.h" - -class CCacheItem -{ -public: - virtual ~CCacheItem() {} - -public: - virtual CCacheItem& operator=(const CCacheItem&) = 0; - - // The "==" operator SHOULD only compare key values. - virtual bool operator==(const CCacheItem&) = 0; - - // Functionality: - // get a deep copy clone of the current item - // Parameters: - // None. - // Returned value: - // Pointer to the new item, or NULL if failed. - - virtual CCacheItem* clone() = 0; - - // Functionality: - // get a random key value between 0 and MAX_INT to be used for the hash in cache - // Parameters: - // None. - // Returned value: - // A random hash key. - - virtual int getKey() = 0; - - // If there is any shared resources between the cache item and its clone, - // the shared resource should be released by this function. - virtual void release() {} -}; - -template class CCache -{ -public: - CCache(int size = 1024): - m_iMaxSize(size), - m_iHashSize(size * 3), - m_iCurrSize(0) - { - m_vHashPtr.resize(m_iHashSize); - CGuard::createMutex(m_Lock); - } - - ~CCache() - { - clear(); - CGuard::releaseMutex(m_Lock); - } - -public: - // Functionality: - // find the matching item in the cache. - // Parameters: - // 0) [in/out] data: storage for the retrieved item; initially it must carry the key information - // Returned value: - // 0 if found a match, otherwise -1. - - int lookup(T* data) - { - CGuard cacheguard(m_Lock); - - int key = data->getKey(); - if (key < 0) - return -1; - if (key >= m_iMaxSize) - key %= m_iHashSize; - - const ItemPtrList& item_list = m_vHashPtr[key]; - for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i) - { - if (*data == ***i) - { - // copy the cached info - *data = ***i; - return 0; - } - } - - return -1; - } - - // Functionality: - // update an item in the cache, or insert one if it doesn't exist; oldest item may be removed - // Parameters: - // 0) [in] data: the new item to updated/inserted to the cache - // Returned value: - // 0 if success, otherwise -1. - - int update(T* data) - { - CGuard cacheguard(m_Lock); - - int key = data->getKey(); - if (key < 0) - return -1; - if (key >= m_iMaxSize) - key %= m_iHashSize; - - T* curr = NULL; - - ItemPtrList& item_list = m_vHashPtr[key]; - for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i) - { - if (*data == ***i) - { - // update the existing entry with the new value - ***i = *data; - curr = **i; - - // remove the current entry - m_StorageList.erase(*i); - item_list.erase(i); - - // re-insert to the front - m_StorageList.push_front(curr); - item_list.push_front(m_StorageList.begin()); - - return 0; - } - } - - // create new entry and insert to front - curr = data->clone(); - m_StorageList.push_front(curr); - item_list.push_front(m_StorageList.begin()); - - ++ m_iCurrSize; - if (m_iCurrSize >= m_iMaxSize) - { - // Cache overflow, remove oldest entry. - T* last_data = m_StorageList.back(); - int last_key = last_data->getKey() % m_iHashSize; - - item_list = m_vHashPtr[last_key]; - for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i) - { - if (*last_data == ***i) - { - item_list.erase(i); - break; - } - } - - last_data->release(); - delete last_data; - m_StorageList.pop_back(); - -- m_iCurrSize; - } - - return 0; - } - - // Functionality: - // Specify the cache size (i.e., max number of items). - // Parameters: - // 0) [in] size: max cache size. - // Returned value: - // None. - - void setSizeLimit(int size) - { - m_iMaxSize = size; - m_iHashSize = size * 3; - m_vHashPtr.resize(m_iHashSize); - } - - // Functionality: - // Clear all entries in the cache, restore to initialization state. - // Parameters: - // None. - // Returned value: - // None. - - void clear() - { - for (typename std::list::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i) - { - (*i)->release(); - delete *i; - } - m_StorageList.clear(); - for (typename std::vector::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i) - i->clear(); - m_iCurrSize = 0; - } - -private: - std::list m_StorageList; - typedef typename std::list::iterator ItemPtr; - typedef std::list ItemPtrList; - std::vector m_vHashPtr; - - int m_iMaxSize; - int m_iHashSize; - int m_iCurrSize; - - pthread_mutex_t m_Lock; - -private: - CCache(const CCache&); - CCache& operator=(const CCache&); -}; - - -class CInfoBlock -{ -public: - uint32_t m_piIP[4]; // IP address, machine read only, not human readable format - int m_iIPversion; // IP version - uint64_t m_ullTimeStamp; // last update time - int m_iRTT; // RTT - int m_iBandwidth; // estimated bandwidth - int m_iLossRate; // average loss rate - int m_iReorderDistance; // packet reordering distance - double m_dInterval; // inter-packet time, congestion control - double m_dCWnd; // congestion window size, congestion control - -public: - virtual ~CInfoBlock() {} - virtual CInfoBlock& operator=(const CInfoBlock& obj); - virtual bool operator==(const CInfoBlock& obj); - virtual CInfoBlock* clone(); - virtual int getKey(); - virtual void release() {} - -public: - - // Functionality: - // convert sockaddr structure to an integer array - // Parameters: - // 0) [in] addr: network address - // 1) [in] ver: IP version - // 2) [out] ip: the result machine readable IP address in integer array - // Returned value: - // None. - - static void convert(const sockaddr* addr, int ver, uint32_t ip[]); -}; - - -#endif diff --git a/vendor/udt4/src/ccc.cpp b/vendor/udt4/src/ccc.cpp deleted file mode 100644 index 048b7ec..0000000 --- a/vendor/udt4/src/ccc.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 02/21/2013 -*****************************************************************************/ - - -#include "core.h" -#include "ccc.h" -#include -#include - -CCC::CCC(): -m_iSYNInterval(CUDT::m_iSYNInterval), -m_dPktSndPeriod(1.0), -m_dCWndSize(16.0), -m_iBandwidth(), -m_dMaxCWndSize(), -m_iMSS(), -m_iSndCurrSeqNo(), -m_iRcvRate(), -m_iRTT(), -m_pcParam(NULL), -m_iPSize(0), -m_UDT(), -m_iACKPeriod(0), -m_iACKInterval(0), -m_bUserDefinedRTO(false), -m_iRTO(-1), -m_PerfInfo() -{ -} - -CCC::~CCC() -{ - delete [] m_pcParam; -} - -void CCC::setACKTimer(int msINT) -{ - m_iACKPeriod = msINT > m_iSYNInterval ? m_iSYNInterval : msINT; -} - -void CCC::setACKInterval(int pktINT) -{ - m_iACKInterval = pktINT; -} - -void CCC::setRTO(int usRTO) -{ - m_bUserDefinedRTO = true; - m_iRTO = usRTO; -} - -void CCC::sendCustomMsg(CPacket& pkt) const -{ - CUDT* u = CUDT::getUDTHandle(m_UDT); - - if (NULL != u) - { - pkt.m_iID = u->m_PeerID; - u->m_pSndQueue->sendto(u->m_pPeerAddr, pkt); - } -} - -const CPerfMon* CCC::getPerfInfo() -{ - try - { - CUDT* u = CUDT::getUDTHandle(m_UDT); - if (NULL != u) - u->sample(&m_PerfInfo, false); - } - catch (...) - { - return NULL; - } - - return &m_PerfInfo; -} - -void CCC::setMSS(int mss) -{ - m_iMSS = mss; -} - -void CCC::setBandwidth(int bw) -{ - m_iBandwidth = bw; -} - -void CCC::setSndCurrSeqNo(int32_t seqno) -{ - m_iSndCurrSeqNo = seqno; -} - -void CCC::setRcvRate(int rcvrate) -{ - m_iRcvRate = rcvrate; -} - -void CCC::setMaxCWndSize(int cwnd) -{ - m_dMaxCWndSize = cwnd; -} - -void CCC::setRTT(int rtt) -{ - m_iRTT = rtt; -} - -void CCC::setUserParam(const char* param, int size) -{ - delete [] m_pcParam; - m_pcParam = new char[size]; - memcpy(m_pcParam, param, size); - m_iPSize = size; -} - -// -CUDTCC::CUDTCC(): -m_iRCInterval(), -m_LastRCTime(), -m_bSlowStart(), -m_iLastAck(), -m_bLoss(), -m_iLastDecSeq(), -m_dLastDecPeriod(), -m_iNAKCount(), -m_iDecRandom(), -m_iAvgNAKNum(), -m_iDecCount() -{ -} - -void CUDTCC::init() -{ - m_iRCInterval = m_iSYNInterval; - m_LastRCTime = CTimer::getTime(); - setACKTimer(m_iRCInterval); - - m_bSlowStart = true; - m_iLastAck = m_iSndCurrSeqNo; - m_bLoss = false; - m_iLastDecSeq = CSeqNo::decseq(m_iLastAck); - m_dLastDecPeriod = 1; - m_iAvgNAKNum = 0; - m_iNAKCount = 0; - m_iDecRandom = 1; - - m_dCWndSize = 16; - m_dPktSndPeriod = 1; -} - -void CUDTCC::onACK(int32_t ack) -{ - int64_t B = 0; - double inc = 0; - // Note: 1/24/2012 - // The minimum increase parameter is increased from "1.0 / m_iMSS" to 0.01 - // because the original was too small and caused sending rate to stay at low level - // for long time. - const double min_inc = 0.01; - - uint64_t currtime = CTimer::getTime(); - if (currtime - m_LastRCTime < (uint64_t)m_iRCInterval) - return; - - m_LastRCTime = currtime; - - if (m_bSlowStart) - { - m_dCWndSize += CSeqNo::seqlen(m_iLastAck, ack); - m_iLastAck = ack; - - if (m_dCWndSize > m_dMaxCWndSize) - { - m_bSlowStart = false; - if (m_iRcvRate > 0) - m_dPktSndPeriod = 1000000.0 / m_iRcvRate; - else - m_dPktSndPeriod = (m_iRTT + m_iRCInterval) / m_dCWndSize; - } - } - else - m_dCWndSize = m_iRcvRate / 1000000.0 * (m_iRTT + m_iRCInterval) + 16; - - // During Slow Start, no rate increase - if (m_bSlowStart) - return; - - if (m_bLoss) - { - m_bLoss = false; - return; - } - - B = (int64_t)(m_iBandwidth - 1000000.0 / m_dPktSndPeriod); - if ((m_dPktSndPeriod > m_dLastDecPeriod) && ((m_iBandwidth / 9) < B)) - B = m_iBandwidth / 9; - if (B <= 0) - inc = min_inc; - else - { - // inc = max(10 ^ ceil(log10( B * MSS * 8 ) * Beta / MSS, 1/MSS) - // Beta = 1.5 * 10^(-6) - - inc = pow(10.0, ceil(log10(B * m_iMSS * 8.0))) * 0.0000015 / m_iMSS; - - if (inc < min_inc) - inc = min_inc; - } - - m_dPktSndPeriod = (m_dPktSndPeriod * m_iRCInterval) / (m_dPktSndPeriod * inc + m_iRCInterval); -} - -void CUDTCC::onLoss(const int32_t* losslist, int) -{ - //Slow Start stopped, if it hasn't yet - if (m_bSlowStart) - { - m_bSlowStart = false; - if (m_iRcvRate > 0) - { - // Set the sending rate to the receiving rate. - m_dPktSndPeriod = 1000000.0 / m_iRcvRate; - return; - } - // If no receiving rate is observed, we have to compute the sending - // rate according to the current window size, and decrease it - // using the method below. - m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval); - } - - m_bLoss = true; - - if (CSeqNo::seqcmp(losslist[0] & 0x7FFFFFFF, m_iLastDecSeq) > 0) - { - m_dLastDecPeriod = m_dPktSndPeriod; - m_dPktSndPeriod = ceil(m_dPktSndPeriod * 1.125); - - m_iAvgNAKNum = (int)ceil(m_iAvgNAKNum * 0.875 + m_iNAKCount * 0.125); - m_iNAKCount = 1; - m_iDecCount = 1; - - m_iLastDecSeq = m_iSndCurrSeqNo; - - // remove global synchronization using randomization - srand(m_iLastDecSeq); - m_iDecRandom = (int)ceil(m_iAvgNAKNum * (double(rand()) / RAND_MAX)); - if (m_iDecRandom < 1) - m_iDecRandom = 1; - } - else if ((m_iDecCount ++ < 5) && (0 == (++ m_iNAKCount % m_iDecRandom))) - { - // 0.875^5 = 0.51, rate should not be decreased by more than half within a congestion period - m_dPktSndPeriod = ceil(m_dPktSndPeriod * 1.125); - m_iLastDecSeq = m_iSndCurrSeqNo; - } -} - -void CUDTCC::onTimeout() -{ - if (m_bSlowStart) - { - m_bSlowStart = false; - if (m_iRcvRate > 0) - m_dPktSndPeriod = 1000000.0 / m_iRcvRate; - else - m_dPktSndPeriod = m_dCWndSize / (m_iRTT + m_iRCInterval); - } - else - { - /* - m_dLastDecPeriod = m_dPktSndPeriod; - m_dPktSndPeriod = ceil(m_dPktSndPeriod * 2); - m_iLastDecSeq = m_iLastAck; - */ - } -} diff --git a/vendor/udt4/src/ccc.h b/vendor/udt4/src/ccc.h deleted file mode 100644 index 5585975..0000000 --- a/vendor/udt4/src/ccc.h +++ /dev/null @@ -1,278 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 02/28/2012 -*****************************************************************************/ - - -#ifndef __UDT_CCC_H__ -#define __UDT_CCC_H__ - - -#include "udt.h" -#include "packet.h" - - -class UDT_API CCC -{ -friend class CUDT; - -public: - CCC(); - virtual ~CCC(); - -private: - CCC(const CCC&); - CCC& operator=(const CCC&) {return *this;} - -public: - - // Functionality: - // Callback function to be called (only) at the start of a UDT connection. - // note that this is different from CCC(), which is always called. - // Parameters: - // None. - // Returned value: - // None. - - virtual void init() {} - - // Functionality: - // Callback function to be called when a UDT connection is closed. - // Parameters: - // None. - // Returned value: - // None. - - virtual void close() {} - - // Functionality: - // Callback function to be called when an ACK packet is received. - // Parameters: - // 0) [in] ackno: the data sequence number acknowledged by this ACK. - // Returned value: - // None. - - virtual void onACK(int32_t) {} - - // Functionality: - // Callback function to be called when a loss report is received. - // Parameters: - // 0) [in] losslist: list of sequence number of packets, in the format describled in packet.cpp. - // 1) [in] size: length of the loss list. - // Returned value: - // None. - - virtual void onLoss(const int32_t*, int) {} - - // Functionality: - // Callback function to be called when a timeout event occurs. - // Parameters: - // None. - // Returned value: - // None. - - virtual void onTimeout() {} - - // Functionality: - // Callback function to be called when a data is sent. - // Parameters: - // 0) [in] seqno: the data sequence number. - // 1) [in] size: the payload size. - // Returned value: - // None. - - virtual void onPktSent(const CPacket*) {} - - // Functionality: - // Callback function to be called when a data is received. - // Parameters: - // 0) [in] seqno: the data sequence number. - // 1) [in] size: the payload size. - // Returned value: - // None. - - virtual void onPktReceived(const CPacket*) {} - - // Functionality: - // Callback function to Process a user defined packet. - // Parameters: - // 0) [in] pkt: the user defined packet. - // Returned value: - // None. - - virtual void processCustomMsg(const CPacket*) {} - -protected: - - // Functionality: - // Set periodical acknowldging and the ACK period. - // Parameters: - // 0) [in] msINT: the period to send an ACK. - // Returned value: - // None. - - void setACKTimer(int msINT); - - // Functionality: - // Set packet-based acknowldging and the number of packets to send an ACK. - // Parameters: - // 0) [in] pktINT: the number of packets to send an ACK. - // Returned value: - // None. - - void setACKInterval(int pktINT); - - // Functionality: - // Set RTO value. - // Parameters: - // 0) [in] msRTO: RTO in macroseconds. - // Returned value: - // None. - - void setRTO(int usRTO); - - // Functionality: - // Send a user defined control packet. - // Parameters: - // 0) [in] pkt: user defined packet. - // Returned value: - // None. - - void sendCustomMsg(CPacket& pkt) const; - - // Functionality: - // retrieve performance information. - // Parameters: - // None. - // Returned value: - // Pointer to a performance info structure. - - const CPerfMon* getPerfInfo(); - - // Functionality: - // Set user defined parameters. - // Parameters: - // 0) [in] param: the paramters in one buffer. - // 1) [in] size: the size of the buffer. - // Returned value: - // None. - - void setUserParam(const char* param, int size); - -private: - void setMSS(int mss); - void setMaxCWndSize(int cwnd); - void setBandwidth(int bw); - void setSndCurrSeqNo(int32_t seqno); - void setRcvRate(int rcvrate); - void setRTT(int rtt); - -protected: - const int32_t& m_iSYNInterval; // UDT constant parameter, SYN - - double m_dPktSndPeriod; // Packet sending period, in microseconds - double m_dCWndSize; // Congestion window size, in packets - - int m_iBandwidth; // estimated bandwidth, packets per second - double m_dMaxCWndSize; // maximum cwnd size, in packets - - int m_iMSS; // Maximum Packet Size, including all packet headers - int32_t m_iSndCurrSeqNo; // current maximum seq no sent out - int m_iRcvRate; // packet arrive rate at receiver side, packets per second - int m_iRTT; // current estimated RTT, microsecond - - char* m_pcParam; // user defined parameter - int m_iPSize; // size of m_pcParam - -private: - UDTSOCKET m_UDT; // The UDT entity that this congestion control algorithm is bound to - - int m_iACKPeriod; // Periodical timer to send an ACK, in milliseconds - int m_iACKInterval; // How many packets to send one ACK, in packets - - bool m_bUserDefinedRTO; // if the RTO value is defined by users - int m_iRTO; // RTO value, microseconds - - CPerfMon m_PerfInfo; // protocol statistics information -}; - -class CCCVirtualFactory -{ -public: - virtual ~CCCVirtualFactory() {} - - virtual CCC* create() = 0; - virtual CCCVirtualFactory* clone() = 0; -}; - -template -class CCCFactory: public CCCVirtualFactory -{ -public: - virtual ~CCCFactory() {} - - virtual CCC* create() {return new T;} - virtual CCCVirtualFactory* clone() {return new CCCFactory;} -}; - -class CUDTCC: public CCC -{ -public: - CUDTCC(); - -public: - virtual void init(); - virtual void onACK(int32_t); - virtual void onLoss(const int32_t*, int); - virtual void onTimeout(); - -private: - int m_iRCInterval; // UDT Rate control interval - uint64_t m_LastRCTime; // last rate increase time - bool m_bSlowStart; // if in slow start phase - int32_t m_iLastAck; // last ACKed seq no - bool m_bLoss; // if loss happened since last rate increase - int32_t m_iLastDecSeq; // max pkt seq no sent out when last decrease happened - double m_dLastDecPeriod; // value of pktsndperiod when last decrease happened - int m_iNAKCount; // NAK counter - int m_iDecRandom; // random threshold on decrease by number of loss events - int m_iAvgNAKNum; // average number of NAKs per congestion - int m_iDecCount; // number of decreases in a congestion epoch -}; - -#endif diff --git a/vendor/udt4/src/channel.cpp b/vendor/udt4/src/channel.cpp deleted file mode 100644 index 7b010f0..0000000 --- a/vendor/udt4/src/channel.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -****************************************************************************/ - -/**************************************************************************** -written by - Yunhong Gu, last updated 01/27/2011 -*****************************************************************************/ - -#ifndef WIN32 - #include - #include - #include - #include - #include - #include - #include -#else - #include - #include - #ifdef LEGACY_WIN32 - #include - #endif -#endif -#include "channel.h" -#include "packet.h" - -#ifdef WIN32 - #define socklen_t int -#endif - -#ifndef WIN32 - #define NET_ERROR errno -#else - #define NET_ERROR WSAGetLastError() -#endif - - -CChannel::CChannel(): -m_iIPversion(AF_INET), -m_iSockAddrSize(sizeof(sockaddr_in)), -m_iSocket(), -m_iSndBufSize(65536), -m_iRcvBufSize(65536) -{ -} - -CChannel::CChannel(int version): -m_iIPversion(version), -m_iSocket(), -m_iSndBufSize(65536), -m_iRcvBufSize(65536) -{ - m_iSockAddrSize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); -} - -CChannel::~CChannel() -{ -} - -void CChannel::open(const sockaddr* addr) -{ - // construct an socket - m_iSocket = ::socket(m_iIPversion, SOCK_DGRAM, 0); - - #ifdef WIN32 - if (INVALID_SOCKET == m_iSocket) - #else - if (m_iSocket < 0) - #endif - throw CUDTException(1, 0, NET_ERROR); - - if (NULL != addr) - { - socklen_t namelen = m_iSockAddrSize; - - if (0 != ::bind(m_iSocket, addr, namelen)) - throw CUDTException(1, 3, NET_ERROR); - } - else - { - //sendto or WSASendTo will also automatically bind the socket - addrinfo hints; - addrinfo* res; - - memset(&hints, 0, sizeof(struct addrinfo)); - - hints.ai_flags = AI_PASSIVE; - hints.ai_family = m_iIPversion; - hints.ai_socktype = SOCK_DGRAM; - - if (0 != ::getaddrinfo(NULL, "0", &hints, &res)) - throw CUDTException(1, 3, NET_ERROR); - - if (0 != ::bind(m_iSocket, res->ai_addr, res->ai_addrlen)) - throw CUDTException(1, 3, NET_ERROR); - - ::freeaddrinfo(res); - } - - setUDPSockOpt(); -} - -void CChannel::open(UDPSOCKET udpsock) -{ - m_iSocket = udpsock; - setUDPSockOpt(); -} - -void CChannel::setUDPSockOpt() -{ - #if defined(BSD) || defined(OSX) - // BSD system will fail setsockopt if the requested buffer size exceeds system maximum value - int maxsize = 64000; - if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) - ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&maxsize, sizeof(int)); - if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int))) - ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&maxsize, sizeof(int)); - #else - // for other systems, if requested is greated than maximum, the maximum value will be automactally used - if ((0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) || - (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int)))) - throw CUDTException(1, 3, NET_ERROR); - #endif - - timeval tv; - tv.tv_sec = 0; - #if defined (BSD) || defined (OSX) - // Known BSD bug as the day I wrote this code. - // A small time out value will cause the socket to block forever. - tv.tv_usec = 10000; - #else - tv.tv_usec = 100; - #endif - - #ifdef UNIX - // Set non-blocking I/O - // UNIX does not support SO_RCVTIMEO - int opts = ::fcntl(m_iSocket, F_GETFL); - if (-1 == ::fcntl(m_iSocket, F_SETFL, opts | O_NONBLOCK)) - throw CUDTException(1, 3, NET_ERROR); - #elif WIN32 - DWORD ot = 1; //milliseconds - if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&ot, sizeof(DWORD))) - throw CUDTException(1, 3, NET_ERROR); - #else - // Set receiving time-out value - if (0 != ::setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(timeval))) - throw CUDTException(1, 3, NET_ERROR); - #endif -} - -void CChannel::close() const -{ - #ifndef WIN32 - ::close(m_iSocket); - #else - ::closesocket(m_iSocket); - #endif -} - -int CChannel::getSndBufSize() -{ - socklen_t size = sizeof(socklen_t); - ::getsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char *)&m_iSndBufSize, &size); - return m_iSndBufSize; -} - -int CChannel::getRcvBufSize() -{ - socklen_t size = sizeof(socklen_t); - ::getsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char *)&m_iRcvBufSize, &size); - return m_iRcvBufSize; -} - -void CChannel::setSndBufSize(int size) -{ - m_iSndBufSize = size; -} - -void CChannel::setRcvBufSize(int size) -{ - m_iRcvBufSize = size; -} - -void CChannel::getSockAddr(sockaddr* addr) const -{ - socklen_t namelen = m_iSockAddrSize; - ::getsockname(m_iSocket, addr, &namelen); -} - -void CChannel::getPeerAddr(sockaddr* addr) const -{ - socklen_t namelen = m_iSockAddrSize; - ::getpeername(m_iSocket, addr, &namelen); -} - -int CChannel::sendto(const sockaddr* addr, CPacket& packet) const -{ - // convert control information into network order - if (packet.getFlag()) - for (int i = 0, n = packet.getLength() / 4; i < n; ++ i) - *((uint32_t *)packet.m_pcData + i) = htonl(*((uint32_t *)packet.m_pcData + i)); - - // convert packet header into network order - //for (int j = 0; j < 4; ++ j) - // packet.m_nHeader[j] = htonl(packet.m_nHeader[j]); - uint32_t* p = packet.m_nHeader; - for (int j = 0; j < 4; ++ j) - { - *p = htonl(*p); - ++ p; - } - - #ifndef WIN32 - msghdr mh; - mh.msg_name = (sockaddr*)addr; - mh.msg_namelen = m_iSockAddrSize; - mh.msg_iov = (iovec*)packet.m_PacketVector; - mh.msg_iovlen = 2; - mh.msg_control = NULL; - mh.msg_controllen = 0; - mh.msg_flags = 0; - - int res = ::sendmsg(m_iSocket, &mh, 0); - #else - DWORD size = CPacket::m_iPktHdrSize + packet.getLength(); - int addrsize = m_iSockAddrSize; - int res = ::WSASendTo(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, 0, addr, addrsize, NULL, NULL); - res = (0 == res) ? size : -1; - #endif - - // convert back into local host order - //for (int k = 0; k < 4; ++ k) - // packet.m_nHeader[k] = ntohl(packet.m_nHeader[k]); - p = packet.m_nHeader; - for (int k = 0; k < 4; ++ k) - { - *p = ntohl(*p); - ++ p; - } - - if (packet.getFlag()) - { - for (int l = 0, n = packet.getLength() / 4; l < n; ++ l) - *((uint32_t *)packet.m_pcData + l) = ntohl(*((uint32_t *)packet.m_pcData + l)); - } - - return res; -} - -int CChannel::recvfrom(sockaddr* addr, CPacket& packet) const -{ - #ifndef WIN32 - msghdr mh; - mh.msg_name = addr; - mh.msg_namelen = m_iSockAddrSize; - mh.msg_iov = packet.m_PacketVector; - mh.msg_iovlen = 2; - mh.msg_control = NULL; - mh.msg_controllen = 0; - mh.msg_flags = 0; - - #ifdef UNIX - fd_set set; - timeval tv; - FD_ZERO(&set); - FD_SET(m_iSocket, &set); - tv.tv_sec = 0; - tv.tv_usec = 10000; - ::select(m_iSocket+1, &set, NULL, &set, &tv); - #endif - - int res = ::recvmsg(m_iSocket, &mh, 0); - #else - DWORD size = CPacket::m_iPktHdrSize + packet.getLength(); - DWORD flag = 0; - int addrsize = m_iSockAddrSize; - - int res = ::WSARecvFrom(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, &flag, addr, &addrsize, NULL, NULL); - res = (0 == res) ? size : -1; - #endif - - if (res <= 0) - { - packet.setLength(-1); - return -1; - } - - packet.setLength(res - CPacket::m_iPktHdrSize); - - // convert back into local host order - //for (int i = 0; i < 4; ++ i) - // packet.m_nHeader[i] = ntohl(packet.m_nHeader[i]); - uint32_t* p = packet.m_nHeader; - for (int i = 0; i < 4; ++ i) - { - *p = ntohl(*p); - ++ p; - } - - if (packet.getFlag()) - { - for (int j = 0, n = packet.getLength() / 4; j < n; ++ j) - *((uint32_t *)packet.m_pcData + j) = ntohl(*((uint32_t *)packet.m_pcData + j)); - } - - return packet.getLength(); -} diff --git a/vendor/udt4/src/channel.h b/vendor/udt4/src/channel.h deleted file mode 100644 index 0e47acc..0000000 --- a/vendor/udt4/src/channel.h +++ /dev/null @@ -1,171 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/27/2011 -*****************************************************************************/ - -#ifndef __UDT_CHANNEL_H__ -#define __UDT_CHANNEL_H__ - - -#include "udt.h" -#include "packet.h" - - -class CChannel -{ -public: - CChannel(); - CChannel(int version); - ~CChannel(); - - // Functionality: - // Open a UDP channel. - // Parameters: - // 0) [in] addr: The local address that UDP will use. - // Returned value: - // None. - - void open(const sockaddr* addr = NULL); - - // Functionality: - // Open a UDP channel based on an existing UDP socket. - // Parameters: - // 0) [in] udpsock: UDP socket descriptor. - // Returned value: - // None. - - void open(UDPSOCKET udpsock); - - // Functionality: - // Disconnect and close the UDP entity. - // Parameters: - // None. - // Returned value: - // None. - - void close() const; - - // Functionality: - // Get the UDP sending buffer size. - // Parameters: - // None. - // Returned value: - // Current UDP sending buffer size. - - int getSndBufSize(); - - // Functionality: - // Get the UDP receiving buffer size. - // Parameters: - // None. - // Returned value: - // Current UDP receiving buffer size. - - int getRcvBufSize(); - - // Functionality: - // Set the UDP sending buffer size. - // Parameters: - // 0) [in] size: expected UDP sending buffer size. - // Returned value: - // None. - - void setSndBufSize(int size); - - // Functionality: - // Set the UDP receiving buffer size. - // Parameters: - // 0) [in] size: expected UDP receiving buffer size. - // Returned value: - // None. - - void setRcvBufSize(int size); - - // Functionality: - // Query the socket address that the channel is using. - // Parameters: - // 0) [out] addr: pointer to store the returned socket address. - // Returned value: - // None. - - void getSockAddr(sockaddr* addr) const; - - // Functionality: - // Query the peer side socket address that the channel is connect to. - // Parameters: - // 0) [out] addr: pointer to store the returned socket address. - // Returned value: - // None. - - void getPeerAddr(sockaddr* addr) const; - - // Functionality: - // Send a packet to the given address. - // Parameters: - // 0) [in] addr: pointer to the destination address. - // 1) [in] packet: reference to a CPacket entity. - // Returned value: - // Actual size of data sent. - - int sendto(const sockaddr* addr, CPacket& packet) const; - - // Functionality: - // Receive a packet from the channel and record the source address. - // Parameters: - // 0) [in] addr: pointer to the source address. - // 1) [in] packet: reference to a CPacket entity. - // Returned value: - // Actual size of data received. - - int recvfrom(sockaddr* addr, CPacket& packet) const; - -private: - void setUDPSockOpt(); - -private: - int m_iIPversion; // IP version - int m_iSockAddrSize; // socket address structure size (pre-defined to avoid run-time test) - - UDPSOCKET m_iSocket; // socket descriptor - - int m_iSndBufSize; // UDP sending buffer size - int m_iRcvBufSize; // UDP receiving buffer size -}; - - -#endif diff --git a/vendor/udt4/src/common.cpp b/vendor/udt4/src/common.cpp deleted file mode 100644 index 3b6ffda..0000000 --- a/vendor/udt4/src/common.cpp +++ /dev/null @@ -1,765 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 07/25/2010 -*****************************************************************************/ - - -#ifndef WIN32 - #include - #include - #include - #ifdef OSX - #include - #endif -#else - #include - #include - #ifdef LEGACY_WIN32 - #include - #endif -#endif - -#include -#include "md5.h" -#include "common.h" - -bool CTimer::m_bUseMicroSecond = false; -uint64_t CTimer::s_ullCPUFrequency = CTimer::readCPUFrequency(); -#ifndef WIN32 - pthread_mutex_t CTimer::m_EventLock = PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t CTimer::m_EventCond = PTHREAD_COND_INITIALIZER; -#else - pthread_mutex_t CTimer::m_EventLock = CreateMutex(NULL, false, NULL); - pthread_cond_t CTimer::m_EventCond = CreateEvent(NULL, false, false, NULL); -#endif - -CTimer::CTimer(): -m_ullSchedTime(), -m_TickCond(), -m_TickLock() -{ - #ifndef WIN32 - pthread_mutex_init(&m_TickLock, NULL); - pthread_cond_init(&m_TickCond, NULL); - #else - m_TickLock = CreateMutex(NULL, false, NULL); - m_TickCond = CreateEvent(NULL, false, false, NULL); - #endif -} - -CTimer::~CTimer() -{ - #ifndef WIN32 - pthread_mutex_destroy(&m_TickLock); - pthread_cond_destroy(&m_TickCond); - #else - CloseHandle(m_TickLock); - CloseHandle(m_TickCond); - #endif -} - -void CTimer::rdtsc(uint64_t &x) -{ - if (m_bUseMicroSecond) - { - x = getTime(); - return; - } - - #ifdef IA32 - uint32_t lval, hval; - //asm volatile ("push %eax; push %ebx; push %ecx; push %edx"); - //asm volatile ("xor %eax, %eax; cpuid"); - asm volatile ("rdtsc" : "=a" (lval), "=d" (hval)); - //asm volatile ("pop %edx; pop %ecx; pop %ebx; pop %eax"); - x = hval; - x = (x << 32) | lval; - #elif defined(IA64) - asm ("mov %0=ar.itc" : "=r"(x) :: "memory"); - #elif defined(AMD64) - uint32_t lval, hval; - asm ("rdtsc" : "=a" (lval), "=d" (hval)); - x = hval; - x = (x << 32) | lval; - #elif defined(WIN32) - //HANDLE hCurThread = ::GetCurrentThread(); - //DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1); - BOOL ret = QueryPerformanceCounter((LARGE_INTEGER *)&x); - //SetThreadAffinityMask(hCurThread, dwOldMask); - if (!ret) - x = getTime() * s_ullCPUFrequency; - #elif defined(OSX) - x = mach_absolute_time(); - #else - // use system call to read time clock for other archs - x = getTime(); - #endif -} - -uint64_t CTimer::readCPUFrequency() -{ - uint64_t frequency = 1; // 1 tick per microsecond. - - #if defined(IA32) || defined(IA64) || defined(AMD64) - uint64_t t1, t2; - - rdtsc(t1); - timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 100000000; - nanosleep(&ts, NULL); - rdtsc(t2); - - // CPU clocks per microsecond - frequency = (t2 - t1) / 100000; - #elif defined(WIN32) - int64_t ccf; - if (QueryPerformanceFrequency((LARGE_INTEGER *)&ccf)) - frequency = ccf / 1000000; - #elif defined(OSX) - mach_timebase_info_data_t info; - mach_timebase_info(&info); - frequency = info.denom * 1000ULL / info.numer; - #endif - - // Fall back to microsecond if the resolution is not high enough. - if (frequency < 10) - { - frequency = 1; - m_bUseMicroSecond = true; - } - return frequency; -} - -uint64_t CTimer::getCPUFrequency() -{ - return s_ullCPUFrequency; -} - -void CTimer::sleep(uint64_t interval) -{ - uint64_t t; - rdtsc(t); - - // sleep next "interval" time - sleepto(t + interval); -} - -void CTimer::sleepto(uint64_t nexttime) -{ - // Use class member such that the method can be interrupted by others - m_ullSchedTime = nexttime; - - uint64_t t; - rdtsc(t); - - while (t < m_ullSchedTime) - { - #ifndef NO_BUSY_WAITING - #ifdef IA32 - __asm__ volatile ("pause; rep; nop; nop; nop; nop; nop;"); - #elif IA64 - __asm__ volatile ("nop 0; nop 0; nop 0; nop 0; nop 0;"); - #elif AMD64 - __asm__ volatile ("nop; nop; nop; nop; nop;"); - #endif - #else - #ifndef WIN32 - timeval now; - timespec timeout; - gettimeofday(&now, 0); - if (now.tv_usec < 990000) - { - timeout.tv_sec = now.tv_sec; - timeout.tv_nsec = (now.tv_usec + 10000) * 1000; - } - else - { - timeout.tv_sec = now.tv_sec + 1; - timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000; - } - pthread_mutex_lock(&m_TickLock); - pthread_cond_timedwait(&m_TickCond, &m_TickLock, &timeout); - pthread_mutex_unlock(&m_TickLock); - #else - WaitForSingleObject(m_TickCond, 1); - #endif - #endif - - rdtsc(t); - } -} - -void CTimer::interrupt() -{ - // schedule the sleepto time to the current CCs, so that it will stop - rdtsc(m_ullSchedTime); - tick(); -} - -void CTimer::tick() -{ - #ifndef WIN32 - pthread_cond_signal(&m_TickCond); - #else - SetEvent(m_TickCond); - #endif -} - -uint64_t CTimer::getTime() -{ - //For Cygwin and other systems without microsecond level resolution, uncomment the following three lines - //uint64_t x; - //rdtsc(x); - //return x / s_ullCPUFrequency; - //Specific fix may be necessary if rdtsc is not available either. - - #ifndef WIN32 - timeval t; - gettimeofday(&t, 0); - return t.tv_sec * 1000000ULL + t.tv_usec; - #else - LARGE_INTEGER ccf; - HANDLE hCurThread = ::GetCurrentThread(); - DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1); - if (QueryPerformanceFrequency(&ccf)) - { - LARGE_INTEGER cc; - if (QueryPerformanceCounter(&cc)) - { - SetThreadAffinityMask(hCurThread, dwOldMask); - return (cc.QuadPart * 1000000ULL / ccf.QuadPart); - } - } - - SetThreadAffinityMask(hCurThread, dwOldMask); - return GetTickCount() * 1000ULL; - #endif -} - -void CTimer::triggerEvent() -{ - #ifndef WIN32 - pthread_cond_signal(&m_EventCond); - #else - SetEvent(m_EventCond); - #endif -} - -void CTimer::waitForEvent() -{ - #ifndef WIN32 - timeval now; - timespec timeout; - gettimeofday(&now, 0); - if (now.tv_usec < 990000) - { - timeout.tv_sec = now.tv_sec; - timeout.tv_nsec = (now.tv_usec + 10000) * 1000; - } - else - { - timeout.tv_sec = now.tv_sec + 1; - timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000; - } - pthread_mutex_lock(&m_EventLock); - pthread_cond_timedwait(&m_EventCond, &m_EventLock, &timeout); - pthread_mutex_unlock(&m_EventLock); - #else - WaitForSingleObject(m_EventCond, 1); - #endif -} - -void CTimer::sleep() -{ - #ifndef WIN32 - usleep(10); - #else - Sleep(1); - #endif -} - - -// -// Automatically lock in constructor -CGuard::CGuard(pthread_mutex_t& lock): -m_Mutex(lock), -m_iLocked() -{ - #ifndef WIN32 - m_iLocked = pthread_mutex_lock(&m_Mutex); - #else - m_iLocked = WaitForSingleObject(m_Mutex, INFINITE); - #endif -} - -// Automatically unlock in destructor -CGuard::~CGuard() -{ - #ifndef WIN32 - if (0 == m_iLocked) - pthread_mutex_unlock(&m_Mutex); - #else - if (WAIT_FAILED != m_iLocked) - ReleaseMutex(m_Mutex); - #endif -} - -void CGuard::enterCS(pthread_mutex_t& lock) -{ - #ifndef WIN32 - pthread_mutex_lock(&lock); - #else - WaitForSingleObject(lock, INFINITE); - #endif -} - -void CGuard::leaveCS(pthread_mutex_t& lock) -{ - #ifndef WIN32 - pthread_mutex_unlock(&lock); - #else - ReleaseMutex(lock); - #endif -} - -void CGuard::createMutex(pthread_mutex_t& lock) -{ - #ifndef WIN32 - pthread_mutex_init(&lock, NULL); - #else - lock = CreateMutex(NULL, false, NULL); - #endif -} - -void CGuard::releaseMutex(pthread_mutex_t& lock) -{ - #ifndef WIN32 - pthread_mutex_destroy(&lock); - #else - CloseHandle(lock); - #endif -} - -void CGuard::createCond(pthread_cond_t& cond) -{ - #ifndef WIN32 - pthread_cond_init(&cond, NULL); - #else - cond = CreateEvent(NULL, false, false, NULL); - #endif -} - -void CGuard::releaseCond(pthread_cond_t& cond) -{ - #ifndef WIN32 - pthread_cond_destroy(&cond); - #else - CloseHandle(cond); - #endif - -} - -// -CUDTException::CUDTException(int major, int minor, int err): -m_iMajor(major), -m_iMinor(minor) -{ - if (-1 == err) - #ifndef WIN32 - m_iErrno = errno; - #else - m_iErrno = GetLastError(); - #endif - else - m_iErrno = err; -} - -CUDTException::CUDTException(const CUDTException& e): -m_iMajor(e.m_iMajor), -m_iMinor(e.m_iMinor), -m_iErrno(e.m_iErrno), -m_strMsg() -{ -} - -CUDTException::~CUDTException() -{ -} - -const char* CUDTException::getErrorMessage() -{ - // translate "Major:Minor" code into text message. - - switch (m_iMajor) - { - case 0: - m_strMsg = "Success"; - break; - - case 1: - m_strMsg = "Connection setup failure"; - - switch (m_iMinor) - { - case 1: - m_strMsg += ": connection time out"; - break; - - case 2: - m_strMsg += ": connection rejected"; - break; - - case 3: - m_strMsg += ": unable to create/configure UDP socket"; - break; - - case 4: - m_strMsg += ": abort for security reasons"; - break; - - default: - break; - } - - break; - - case 2: - switch (m_iMinor) - { - case 1: - m_strMsg = "Connection was broken"; - break; - - case 2: - m_strMsg = "Connection does not exist"; - break; - - default: - break; - } - - break; - - case 3: - m_strMsg = "System resource failure"; - - switch (m_iMinor) - { - case 1: - m_strMsg += ": unable to create new threads"; - break; - - case 2: - m_strMsg += ": unable to allocate buffers"; - break; - - default: - break; - } - - break; - - case 4: - m_strMsg = "File system failure"; - - switch (m_iMinor) - { - case 1: - m_strMsg += ": cannot seek read position"; - break; - - case 2: - m_strMsg += ": failure in read"; - break; - - case 3: - m_strMsg += ": cannot seek write position"; - break; - - case 4: - m_strMsg += ": failure in write"; - break; - - default: - break; - } - - break; - - case 5: - m_strMsg = "Operation not supported"; - - switch (m_iMinor) - { - case 1: - m_strMsg += ": Cannot do this operation on a BOUND socket"; - break; - - case 2: - m_strMsg += ": Cannot do this operation on a CONNECTED socket"; - break; - - case 3: - m_strMsg += ": Bad parameters"; - break; - - case 4: - m_strMsg += ": Invalid socket ID"; - break; - - case 5: - m_strMsg += ": Cannot do this operation on an UNBOUND socket"; - break; - - case 6: - m_strMsg += ": Socket is not in listening state"; - break; - - case 7: - m_strMsg += ": Listen/accept is not supported in rendezous connection setup"; - break; - - case 8: - m_strMsg += ": Cannot call connect on UNBOUND socket in rendezvous connection setup"; - break; - - case 9: - m_strMsg += ": This operation is not supported in SOCK_STREAM mode"; - break; - - case 10: - m_strMsg += ": This operation is not supported in SOCK_DGRAM mode"; - break; - - case 11: - m_strMsg += ": Another socket is already listening on the same port"; - break; - - case 12: - m_strMsg += ": Message is too large to send (it must be less than the UDT send buffer size)"; - break; - - case 13: - m_strMsg += ": Invalid epoll ID"; - break; - - default: - break; - } - - break; - - case 6: - m_strMsg = "Non-blocking call failure"; - - switch (m_iMinor) - { - case 1: - m_strMsg += ": no buffer available for sending"; - break; - - case 2: - m_strMsg += ": no data available for reading"; - break; - - default: - break; - } - - break; - - case 7: - m_strMsg = "The peer side has signalled an error"; - - break; - - default: - m_strMsg = "Unknown error"; - } - - // Adding "errno" information - if ((0 != m_iMajor) && (0 < m_iErrno)) - { - m_strMsg += ": "; - #ifndef WIN32 - char errmsg[1024]; - if (strerror_r(m_iErrno, errmsg, 1024) == 0) - m_strMsg += errmsg; - #else - LPVOID lpMsgBuf; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, m_iErrno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); - m_strMsg += (char*)lpMsgBuf; - LocalFree(lpMsgBuf); - #endif - } - - // period - #ifndef WIN32 - m_strMsg += "."; - #endif - - return m_strMsg.c_str(); -} - -int CUDTException::getErrorCode() const -{ - return m_iMajor * 1000 + m_iMinor; -} - -void CUDTException::clear() -{ - m_iMajor = 0; - m_iMinor = 0; - m_iErrno = 0; -} - -const int CUDTException::SUCCESS = 0; -const int CUDTException::ECONNSETUP = 1000; -const int CUDTException::ENOSERVER = 1001; -const int CUDTException::ECONNREJ = 1002; -const int CUDTException::ESOCKFAIL = 1003; -const int CUDTException::ESECFAIL = 1004; -const int CUDTException::ECONNFAIL = 2000; -const int CUDTException::ECONNLOST = 2001; -const int CUDTException::ENOCONN = 2002; -const int CUDTException::ERESOURCE = 3000; -const int CUDTException::ETHREAD = 3001; -const int CUDTException::ENOBUF = 3002; -const int CUDTException::EFILE = 4000; -const int CUDTException::EINVRDOFF = 4001; -const int CUDTException::ERDPERM = 4002; -const int CUDTException::EINVWROFF = 4003; -const int CUDTException::EWRPERM = 4004; -const int CUDTException::EINVOP = 5000; -const int CUDTException::EBOUNDSOCK = 5001; -const int CUDTException::ECONNSOCK = 5002; -const int CUDTException::EINVPARAM = 5003; -const int CUDTException::EINVSOCK = 5004; -const int CUDTException::EUNBOUNDSOCK = 5005; -const int CUDTException::ENOLISTEN = 5006; -const int CUDTException::ERDVNOSERV = 5007; -const int CUDTException::ERDVUNBOUND = 5008; -const int CUDTException::ESTREAMILL = 5009; -const int CUDTException::EDGRAMILL = 5010; -const int CUDTException::EDUPLISTEN = 5011; -const int CUDTException::ELARGEMSG = 5012; -const int CUDTException::EINVPOLLID = 5013; -const int CUDTException::EASYNCFAIL = 6000; -const int CUDTException::EASYNCSND = 6001; -const int CUDTException::EASYNCRCV = 6002; -const int CUDTException::ETIMEOUT = 6003; -const int CUDTException::EPEERERR = 7000; -const int CUDTException::EUNKNOWN = -1; - - -// -bool CIPAddress::ipcmp(const sockaddr* addr1, const sockaddr* addr2, int ver) -{ - if (AF_INET == ver) - { - sockaddr_in* a1 = (sockaddr_in*)addr1; - sockaddr_in* a2 = (sockaddr_in*)addr2; - - if ((a1->sin_port == a2->sin_port) && (a1->sin_addr.s_addr == a2->sin_addr.s_addr)) - return true; - } - else - { - sockaddr_in6* a1 = (sockaddr_in6*)addr1; - sockaddr_in6* a2 = (sockaddr_in6*)addr2; - - if (a1->sin6_port == a2->sin6_port) - { - for (int i = 0; i < 16; ++ i) - if (*((char*)&(a1->sin6_addr) + i) != *((char*)&(a2->sin6_addr) + i)) - return false; - - return true; - } - } - - return false; -} - -void CIPAddress::ntop(const sockaddr* addr, uint32_t ip[4], int ver) -{ - if (AF_INET == ver) - { - sockaddr_in* a = (sockaddr_in*)addr; - ip[0] = a->sin_addr.s_addr; - } - else - { - sockaddr_in6* a = (sockaddr_in6*)addr; - ip[3] = (a->sin6_addr.s6_addr[15] << 24) + (a->sin6_addr.s6_addr[14] << 16) + (a->sin6_addr.s6_addr[13] << 8) + a->sin6_addr.s6_addr[12]; - ip[2] = (a->sin6_addr.s6_addr[11] << 24) + (a->sin6_addr.s6_addr[10] << 16) + (a->sin6_addr.s6_addr[9] << 8) + a->sin6_addr.s6_addr[8]; - ip[1] = (a->sin6_addr.s6_addr[7] << 24) + (a->sin6_addr.s6_addr[6] << 16) + (a->sin6_addr.s6_addr[5] << 8) + a->sin6_addr.s6_addr[4]; - ip[0] = (a->sin6_addr.s6_addr[3] << 24) + (a->sin6_addr.s6_addr[2] << 16) + (a->sin6_addr.s6_addr[1] << 8) + a->sin6_addr.s6_addr[0]; - } -} - -void CIPAddress::pton(sockaddr* addr, const uint32_t ip[4], int ver) -{ - if (AF_INET == ver) - { - sockaddr_in* a = (sockaddr_in*)addr; - a->sin_addr.s_addr = ip[0]; - } - else - { - sockaddr_in6* a = (sockaddr_in6*)addr; - for (int i = 0; i < 4; ++ i) - { - a->sin6_addr.s6_addr[i * 4] = ip[i] & 0xFF; - a->sin6_addr.s6_addr[i * 4 + 1] = (unsigned char)((ip[i] & 0xFF00) >> 8); - a->sin6_addr.s6_addr[i * 4 + 2] = (unsigned char)((ip[i] & 0xFF0000) >> 16); - a->sin6_addr.s6_addr[i * 4 + 3] = (unsigned char)((ip[i] & 0xFF000000) >> 24); - } - } -} - -// -void CMD5::compute(const char* input, unsigned char result[16]) -{ - md5_state_t state; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)input, strlen(input)); - md5_finish(&state, result); -} diff --git a/vendor/udt4/src/common.h b/vendor/udt4/src/common.h deleted file mode 100644 index 20c0bb4..0000000 --- a/vendor/udt4/src/common.h +++ /dev/null @@ -1,321 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 08/01/2009 -*****************************************************************************/ - -#ifndef __UDT_COMMON_H__ -#define __UDT_COMMON_H__ - - -#ifndef WIN32 - #include - #include - #include -#else - #include -#endif -#include -#include -#include "udt.h" - - -#ifdef WIN32 - // Windows compability - typedef HANDLE pthread_t; - typedef HANDLE pthread_mutex_t; - typedef HANDLE pthread_cond_t; - typedef DWORD pthread_key_t; -#endif - - -//////////////////////////////////////////////////////////////////////////////// - -class CTimer -{ -public: - CTimer(); - ~CTimer(); - -public: - - // Functionality: - // Sleep for "interval" CCs. - // Parameters: - // 0) [in] interval: CCs to sleep. - // Returned value: - // None. - - void sleep(uint64_t interval); - - // Functionality: - // Seelp until CC "nexttime". - // Parameters: - // 0) [in] nexttime: next time the caller is waken up. - // Returned value: - // None. - - void sleepto(uint64_t nexttime); - - // Functionality: - // Stop the sleep() or sleepto() methods. - // Parameters: - // None. - // Returned value: - // None. - - void interrupt(); - - // Functionality: - // trigger the clock for a tick, for better granuality in no_busy_waiting timer. - // Parameters: - // None. - // Returned value: - // None. - - void tick(); - -public: - - // Functionality: - // Read the CPU clock cycle into x. - // Parameters: - // 0) [out] x: to record cpu clock cycles. - // Returned value: - // None. - - static void rdtsc(uint64_t &x); - - // Functionality: - // return the CPU frequency. - // Parameters: - // None. - // Returned value: - // CPU frequency. - - static uint64_t getCPUFrequency(); - - // Functionality: - // check the current time, 64bit, in microseconds. - // Parameters: - // None. - // Returned value: - // current time in microseconds. - - static uint64_t getTime(); - - // Functionality: - // trigger an event such as new connection, close, new data, etc. for "select" call. - // Parameters: - // None. - // Returned value: - // None. - - static void triggerEvent(); - - // Functionality: - // wait for an event to br triggered by "triggerEvent". - // Parameters: - // None. - // Returned value: - // None. - - static void waitForEvent(); - - // Functionality: - // sleep for a short interval. exact sleep time does not matter - // Parameters: - // None. - // Returned value: - // None. - - static void sleep(); - -private: - uint64_t getTimeInMicroSec(); - -private: - uint64_t m_ullSchedTime; // next schedulled time - - pthread_cond_t m_TickCond; - pthread_mutex_t m_TickLock; - - static pthread_cond_t m_EventCond; - static pthread_mutex_t m_EventLock; - -private: - static uint64_t s_ullCPUFrequency; // CPU frequency : clock cycles per microsecond - static uint64_t readCPUFrequency(); - static bool m_bUseMicroSecond; // No higher resolution timer available, use gettimeofday(). -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CGuard -{ -public: - CGuard(pthread_mutex_t& lock); - ~CGuard(); - -public: - static void enterCS(pthread_mutex_t& lock); - static void leaveCS(pthread_mutex_t& lock); - - static void createMutex(pthread_mutex_t& lock); - static void releaseMutex(pthread_mutex_t& lock); - - static void createCond(pthread_cond_t& cond); - static void releaseCond(pthread_cond_t& cond); - -private: - pthread_mutex_t& m_Mutex; // Alias name of the mutex to be protected - int m_iLocked; // Locking status - - CGuard& operator=(const CGuard&); -}; - - - -//////////////////////////////////////////////////////////////////////////////// - -// UDT Sequence Number 0 - (2^31 - 1) - -// seqcmp: compare two seq#, considering the wraping -// seqlen: length from the 1st to the 2nd seq#, including both -// seqoff: offset from the 2nd to the 1st seq# -// incseq: increase the seq# by 1 -// decseq: decrease the seq# by 1 -// incseq: increase the seq# by a given offset - -class CSeqNo -{ -public: - inline static int seqcmp(int32_t seq1, int32_t seq2) - {return (abs(seq1 - seq2) < m_iSeqNoTH) ? (seq1 - seq2) : (seq2 - seq1);} - - inline static int seqlen(int32_t seq1, int32_t seq2) - {return (seq1 <= seq2) ? (seq2 - seq1 + 1) : (seq2 - seq1 + m_iMaxSeqNo + 2);} - - inline static int seqoff(int32_t seq1, int32_t seq2) - { - if (abs(seq1 - seq2) < m_iSeqNoTH) - return seq2 - seq1; - - if (seq1 < seq2) - return seq2 - seq1 - m_iMaxSeqNo - 1; - - return seq2 - seq1 + m_iMaxSeqNo + 1; - } - - inline static int32_t incseq(int32_t seq) - {return (seq == m_iMaxSeqNo) ? 0 : seq + 1;} - - inline static int32_t decseq(int32_t seq) - {return (seq == 0) ? m_iMaxSeqNo : seq - 1;} - - inline static int32_t incseq(int32_t seq, int32_t inc) - {return (m_iMaxSeqNo - seq >= inc) ? seq + inc : seq - m_iMaxSeqNo + inc - 1;} - -public: - static const int32_t m_iSeqNoTH; // threshold for comparing seq. no. - static const int32_t m_iMaxSeqNo; // maximum sequence number used in UDT -}; - -//////////////////////////////////////////////////////////////////////////////// - -// UDT ACK Sub-sequence Number: 0 - (2^31 - 1) - -class CAckNo -{ -public: - inline static int32_t incack(int32_t ackno) - {return (ackno == m_iMaxAckSeqNo) ? 0 : ackno + 1;} - -public: - static const int32_t m_iMaxAckSeqNo; // maximum ACK sub-sequence number used in UDT -}; - -//////////////////////////////////////////////////////////////////////////////// - -// UDT Message Number: 0 - (2^29 - 1) - -class CMsgNo -{ -public: - inline static int msgcmp(int32_t msgno1, int32_t msgno2) - {return (abs(msgno1 - msgno2) < m_iMsgNoTH) ? (msgno1 - msgno2) : (msgno2 - msgno1);} - - inline static int msglen(int32_t msgno1, int32_t msgno2) - {return (msgno1 <= msgno2) ? (msgno2 - msgno1 + 1) : (msgno2 - msgno1 + m_iMaxMsgNo + 2);} - - inline static int msgoff(int32_t msgno1, int32_t msgno2) - { - if (abs(msgno1 - msgno2) < m_iMsgNoTH) - return msgno2 - msgno1; - - if (msgno1 < msgno2) - return msgno2 - msgno1 - m_iMaxMsgNo - 1; - - return msgno2 - msgno1 + m_iMaxMsgNo + 1; - } - - inline static int32_t incmsg(int32_t msgno) - {return (msgno == m_iMaxMsgNo) ? 0 : msgno + 1;} - -public: - static const int32_t m_iMsgNoTH; // threshold for comparing msg. no. - static const int32_t m_iMaxMsgNo; // maximum message number used in UDT -}; - -//////////////////////////////////////////////////////////////////////////////// - -struct CIPAddress -{ - static bool ipcmp(const sockaddr* addr1, const sockaddr* addr2, int ver = AF_INET); - static void ntop(const sockaddr* addr, uint32_t ip[4], int ver = AF_INET); - static void pton(sockaddr* addr, const uint32_t ip[4], int ver = AF_INET); -}; - -//////////////////////////////////////////////////////////////////////////////// - -struct CMD5 -{ - static void compute(const char* input, unsigned char result[16]); -}; - - -#endif diff --git a/vendor/udt4/src/core.cpp b/vendor/udt4/src/core.cpp deleted file mode 100644 index ba989aa..0000000 --- a/vendor/udt4/src/core.cpp +++ /dev/null @@ -1,2675 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 02/28/2012 -*****************************************************************************/ - -#ifndef WIN32 - #include - #include - #include - #include - #include - #include -#else - #include - #include - #ifdef LEGACY_WIN32 - #include - #endif -#endif -#include -#include -#include "queue.h" -#include "core.h" - -using namespace std; - - -CUDTUnited CUDT::s_UDTUnited; - -const UDTSOCKET CUDT::INVALID_SOCK = -1; -const int CUDT::ERROR = -1; - -const UDTSOCKET UDT::INVALID_SOCK = CUDT::INVALID_SOCK; -const int UDT::ERROR = CUDT::ERROR; - -const int32_t CSeqNo::m_iSeqNoTH = 0x3FFFFFFF; -const int32_t CSeqNo::m_iMaxSeqNo = 0x7FFFFFFF; -const int32_t CAckNo::m_iMaxAckSeqNo = 0x7FFFFFFF; -const int32_t CMsgNo::m_iMsgNoTH = 0xFFFFFFF; -const int32_t CMsgNo::m_iMaxMsgNo = 0x1FFFFFFF; - -const int CUDT::m_iVersion = 4; -const int CUDT::m_iSYNInterval = 10000; -const int CUDT::m_iSelfClockInterval = 64; - - -CUDT::CUDT() -{ - m_pSndBuffer = NULL; - m_pRcvBuffer = NULL; - m_pSndLossList = NULL; - m_pRcvLossList = NULL; - m_pACKWindow = NULL; - m_pSndTimeWindow = NULL; - m_pRcvTimeWindow = NULL; - - m_pSndQueue = NULL; - m_pRcvQueue = NULL; - m_pPeerAddr = NULL; - m_pSNode = NULL; - m_pRNode = NULL; - - // Initilize mutex and condition variables - initSynch(); - - // Default UDT configurations - m_iMSS = 1500; - m_bSynSending = true; - m_bSynRecving = true; - m_iFlightFlagSize = 25600; - m_iSndBufSize = 8192; - m_iRcvBufSize = 8192; //Rcv buffer MUST NOT be bigger than Flight Flag size - m_Linger.l_onoff = 1; - m_Linger.l_linger = 180; - m_iUDPSndBufSize = 65536; - m_iUDPRcvBufSize = m_iRcvBufSize * m_iMSS; - m_iSockType = UDT_STREAM; - m_iIPversion = AF_INET; - m_bRendezvous = false; - m_iSndTimeOut = -1; - m_iRcvTimeOut = -1; - m_bReuseAddr = true; - m_llMaxBW = -1; - - m_pCCFactory = new CCCFactory; - m_pCC = NULL; - m_pCache = NULL; - - // Initial status - m_bOpened = false; - m_bListening = false; - m_bConnecting = false; - m_bConnected = false; - m_bClosing = false; - m_bShutdown = false; - m_bBroken = false; - m_bPeerHealth = true; - m_ullLingerExpiration = 0; -} - -CUDT::CUDT(const CUDT& ancestor) -{ - m_pSndBuffer = NULL; - m_pRcvBuffer = NULL; - m_pSndLossList = NULL; - m_pRcvLossList = NULL; - m_pACKWindow = NULL; - m_pSndTimeWindow = NULL; - m_pRcvTimeWindow = NULL; - - m_pSndQueue = NULL; - m_pRcvQueue = NULL; - m_pPeerAddr = NULL; - m_pSNode = NULL; - m_pRNode = NULL; - - // Initilize mutex and condition variables - initSynch(); - - // Default UDT configurations - m_iMSS = ancestor.m_iMSS; - m_bSynSending = ancestor.m_bSynSending; - m_bSynRecving = ancestor.m_bSynRecving; - m_iFlightFlagSize = ancestor.m_iFlightFlagSize; - m_iSndBufSize = ancestor.m_iSndBufSize; - m_iRcvBufSize = ancestor.m_iRcvBufSize; - m_Linger = ancestor.m_Linger; - m_iUDPSndBufSize = ancestor.m_iUDPSndBufSize; - m_iUDPRcvBufSize = ancestor.m_iUDPRcvBufSize; - m_iSockType = ancestor.m_iSockType; - m_iIPversion = ancestor.m_iIPversion; - m_bRendezvous = ancestor.m_bRendezvous; - m_iSndTimeOut = ancestor.m_iSndTimeOut; - m_iRcvTimeOut = ancestor.m_iRcvTimeOut; - m_bReuseAddr = true; // this must be true, because all accepted sockets shared the same port with the listener - m_llMaxBW = ancestor.m_llMaxBW; - - m_pCCFactory = ancestor.m_pCCFactory->clone(); - m_pCC = NULL; - m_pCache = ancestor.m_pCache; - - // Initial status - m_bOpened = false; - m_bListening = false; - m_bConnecting = false; - m_bConnected = false; - m_bClosing = false; - m_bShutdown = false; - m_bBroken = false; - m_bPeerHealth = true; - m_ullLingerExpiration = 0; -} - -CUDT::~CUDT() -{ - // release mutex/condtion variables - destroySynch(); - - // destroy the data structures - delete m_pSndBuffer; - delete m_pRcvBuffer; - delete m_pSndLossList; - delete m_pRcvLossList; - delete m_pACKWindow; - delete m_pSndTimeWindow; - delete m_pRcvTimeWindow; - delete m_pCCFactory; - delete m_pCC; - delete m_pPeerAddr; - delete m_pSNode; - delete m_pRNode; -} - -void CUDT::setOpt(UDTOpt optName, const void* optval, int) -{ - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - - CGuard cg(m_ConnectionLock); - CGuard sendguard(m_SendLock); - CGuard recvguard(m_RecvLock); - - switch (optName) - { - case UDT_MSS: - if (m_bOpened) - throw CUDTException(5, 1, 0); - - if (*(int*)optval < int(28 + CHandShake::m_iContentSize)) - throw CUDTException(5, 3, 0); - - m_iMSS = *(int*)optval; - - // Packet size cannot be greater than UDP buffer size - if (m_iMSS > m_iUDPSndBufSize) - m_iMSS = m_iUDPSndBufSize; - if (m_iMSS > m_iUDPRcvBufSize) - m_iMSS = m_iUDPRcvBufSize; - - break; - - case UDT_SNDSYN: - m_bSynSending = *(bool *)optval; - break; - - case UDT_RCVSYN: - m_bSynRecving = *(bool *)optval; - break; - - case UDT_CC: - if (m_bConnecting || m_bConnected) - throw CUDTException(5, 1, 0); - if (NULL != m_pCCFactory) - delete m_pCCFactory; - m_pCCFactory = ((CCCVirtualFactory *)optval)->clone(); - - break; - - case UDT_FC: - if (m_bConnecting || m_bConnected) - throw CUDTException(5, 2, 0); - - if (*(int*)optval < 1) - throw CUDTException(5, 3); - - // Mimimum recv flight flag size is 32 packets - if (*(int*)optval > 32) - m_iFlightFlagSize = *(int*)optval; - else - m_iFlightFlagSize = 32; - - break; - - case UDT_SNDBUF: - if (m_bOpened) - throw CUDTException(5, 1, 0); - - if (*(int*)optval <= 0) - throw CUDTException(5, 3, 0); - - m_iSndBufSize = *(int*)optval / (m_iMSS - 28); - - break; - - case UDT_RCVBUF: - if (m_bOpened) - throw CUDTException(5, 1, 0); - - if (*(int*)optval <= 0) - throw CUDTException(5, 3, 0); - - // Mimimum recv buffer size is 32 packets - if (*(int*)optval > (m_iMSS - 28) * 32) - m_iRcvBufSize = *(int*)optval / (m_iMSS - 28); - else - m_iRcvBufSize = 32; - - // recv buffer MUST not be greater than FC size - if (m_iRcvBufSize > m_iFlightFlagSize) - m_iRcvBufSize = m_iFlightFlagSize; - - break; - - case UDT_LINGER: - m_Linger = *(linger*)optval; - break; - - case UDP_SNDBUF: - if (m_bOpened) - throw CUDTException(5, 1, 0); - - m_iUDPSndBufSize = *(int*)optval; - - if (m_iUDPSndBufSize < m_iMSS) - m_iUDPSndBufSize = m_iMSS; - - break; - - case UDP_RCVBUF: - if (m_bOpened) - throw CUDTException(5, 1, 0); - - m_iUDPRcvBufSize = *(int*)optval; - - if (m_iUDPRcvBufSize < m_iMSS) - m_iUDPRcvBufSize = m_iMSS; - - break; - - case UDT_RENDEZVOUS: - if (m_bConnecting || m_bConnected) - throw CUDTException(5, 1, 0); - m_bRendezvous = *(bool *)optval; - break; - - case UDT_SNDTIMEO: - m_iSndTimeOut = *(int*)optval; - break; - - case UDT_RCVTIMEO: - m_iRcvTimeOut = *(int*)optval; - break; - - case UDT_REUSEADDR: - if (m_bOpened) - throw CUDTException(5, 1, 0); - m_bReuseAddr = *(bool*)optval; - break; - - case UDT_MAXBW: - m_llMaxBW = *(int64_t*)optval; - break; - - default: - throw CUDTException(5, 0, 0); - } -} - -void CUDT::getOpt(UDTOpt optName, void* optval, int& optlen) -{ - CGuard cg(m_ConnectionLock); - - switch (optName) - { - case UDT_MSS: - *(int*)optval = m_iMSS; - optlen = sizeof(int); - break; - - case UDT_SNDSYN: - *(bool*)optval = m_bSynSending; - optlen = sizeof(bool); - break; - - case UDT_RCVSYN: - *(bool*)optval = m_bSynRecving; - optlen = sizeof(bool); - break; - - case UDT_CC: - if (!m_bOpened) - throw CUDTException(5, 5, 0); - *(CCC**)optval = m_pCC; - optlen = sizeof(CCC*); - - break; - - case UDT_FC: - *(int*)optval = m_iFlightFlagSize; - optlen = sizeof(int); - break; - - case UDT_SNDBUF: - *(int*)optval = m_iSndBufSize * (m_iMSS - 28); - optlen = sizeof(int); - break; - - case UDT_RCVBUF: - *(int*)optval = m_iRcvBufSize * (m_iMSS - 28); - optlen = sizeof(int); - break; - - case UDT_LINGER: - if (optlen < (int)(sizeof(linger))) - throw CUDTException(5, 3, 0); - - *(linger*)optval = m_Linger; - optlen = sizeof(linger); - break; - - case UDP_SNDBUF: - *(int*)optval = m_iUDPSndBufSize; - optlen = sizeof(int); - break; - - case UDP_RCVBUF: - *(int*)optval = m_iUDPRcvBufSize; - optlen = sizeof(int); - break; - - case UDT_RENDEZVOUS: - *(bool *)optval = m_bRendezvous; - optlen = sizeof(bool); - break; - - case UDT_SNDTIMEO: - *(int*)optval = m_iSndTimeOut; - optlen = sizeof(int); - break; - - case UDT_RCVTIMEO: - *(int*)optval = m_iRcvTimeOut; - optlen = sizeof(int); - break; - - case UDT_REUSEADDR: - *(bool *)optval = m_bReuseAddr; - optlen = sizeof(bool); - break; - - case UDT_MAXBW: - *(int64_t*)optval = m_llMaxBW; - optlen = sizeof(int64_t); - break; - - case UDT_STATE: - *(int32_t*)optval = s_UDTUnited.getStatus(m_SocketID); - optlen = sizeof(int32_t); - break; - - case UDT_EVENT: - { - int32_t event = 0; - if (m_bBroken) - event |= UDT_EPOLL_ERR; - else - { - if (m_pRcvBuffer && (m_pRcvBuffer->getRcvDataSize() > 0)) - event |= UDT_EPOLL_IN; - if (m_pSndBuffer && (m_iSndBufSize > m_pSndBuffer->getCurrBufSize())) - event |= UDT_EPOLL_OUT; - } - *(int32_t*)optval = event; - optlen = sizeof(int32_t); - break; - } - - case UDT_SNDDATA: - if (m_pSndBuffer) - *(int32_t*)optval = m_pSndBuffer->getCurrBufSize(); - else - *(int32_t*)optval = 0; - optlen = sizeof(int32_t); - break; - - case UDT_RCVDATA: - if (m_pRcvBuffer) - *(int32_t*)optval = m_pRcvBuffer->getRcvDataSize(); - else - *(int32_t*)optval = 0; - optlen = sizeof(int32_t); - break; - - default: - throw CUDTException(5, 0, 0); - } -} - -void CUDT::open() -{ - CGuard cg(m_ConnectionLock); - - // Initial sequence number, loss, acknowledgement, etc. - m_iPktSize = m_iMSS - 28; - m_iPayloadSize = m_iPktSize - CPacket::m_iPktHdrSize; - - m_iEXPCount = 1; - m_iBandwidth = 1; - m_iDeliveryRate = 16; - m_iAckSeqNo = 0; - m_ullLastAckTime = 0; - - // trace information - m_StartTime = CTimer::getTime(); - m_llSentTotal = m_llRecvTotal = m_iSndLossTotal = m_iRcvLossTotal = m_iRetransTotal = m_iSentACKTotal = m_iRecvACKTotal = m_iSentNAKTotal = m_iRecvNAKTotal = 0; - m_LastSampleTime = CTimer::getTime(); - m_llTraceSent = m_llTraceRecv = m_iTraceSndLoss = m_iTraceRcvLoss = m_iTraceRetrans = m_iSentACK = m_iRecvACK = m_iSentNAK = m_iRecvNAK = 0; - m_llSndDuration = m_llSndDurationTotal = 0; - - // structures for queue - if (NULL == m_pSNode) - m_pSNode = new CSNode; - m_pSNode->m_pUDT = this; - m_pSNode->m_llTimeStamp = 1; - m_pSNode->m_iHeapLoc = -1; - - if (NULL == m_pRNode) - m_pRNode = new CRNode; - m_pRNode->m_pUDT = this; - m_pRNode->m_llTimeStamp = 1; - m_pRNode->m_pPrev = m_pRNode->m_pNext = NULL; - m_pRNode->m_bOnList = false; - - m_iRTT = 10 * m_iSYNInterval; - m_iRTTVar = m_iRTT >> 1; - m_ullCPUFrequency = CTimer::getCPUFrequency(); - - // set up the timers - m_ullSYNInt = m_iSYNInterval * m_ullCPUFrequency; - - // set minimum NAK and EXP timeout to 100ms - m_ullMinNakInt = 300000 * m_ullCPUFrequency; - m_ullMinExpInt = 300000 * m_ullCPUFrequency; - - m_ullACKInt = m_ullSYNInt; - m_ullNAKInt = m_ullMinNakInt; - - uint64_t currtime; - CTimer::rdtsc(currtime); - m_ullLastRspTime = currtime; - m_ullNextACKTime = currtime + m_ullSYNInt; - m_ullNextNAKTime = currtime + m_ullNAKInt; - - m_iPktCount = 0; - m_iLightACKCount = 1; - - m_ullTargetTime = 0; - m_ullTimeDiff = 0; - - // Now UDT is opened. - m_bOpened = true; -} - -void CUDT::listen() -{ - CGuard cg(m_ConnectionLock); - - if (!m_bOpened) - throw CUDTException(5, 0, 0); - - if (m_bConnecting || m_bConnected) - throw CUDTException(5, 2, 0); - - // listen can be called more than once - if (m_bListening) - return; - - // if there is already another socket listening on the same port - if (m_pRcvQueue->setListener(this) < 0) - throw CUDTException(5, 11, 0); - - m_bListening = true; -} - -void CUDT::connect(const sockaddr* serv_addr) -{ - CGuard cg(m_ConnectionLock); - - if (!m_bOpened) - throw CUDTException(5, 0, 0); - - if (m_bListening) - throw CUDTException(5, 2, 0); - - if (m_bConnecting || m_bConnected) - throw CUDTException(5, 2, 0); - - // record peer/server address - delete m_pPeerAddr; - m_pPeerAddr = (AF_INET == m_iIPversion) ? (sockaddr*)new sockaddr_in : (sockaddr*)new sockaddr_in6; - memcpy(m_pPeerAddr, serv_addr, (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6)); - - // register this socket in the rendezvous queue - // RendezevousQueue is used to temporarily store incoming handshake, non-rendezvous connections also require this function - uint64_t ttl = 3000000; - if (m_bRendezvous) - ttl *= 10; - ttl += CTimer::getTime(); - m_pRcvQueue->registerConnector(m_SocketID, this, m_iIPversion, serv_addr, ttl); - - // This is my current configurations - m_ConnReq.m_iVersion = m_iVersion; - m_ConnReq.m_iType = m_iSockType; - m_ConnReq.m_iMSS = m_iMSS; - m_ConnReq.m_iFlightFlagSize = (m_iRcvBufSize < m_iFlightFlagSize)? m_iRcvBufSize : m_iFlightFlagSize; - m_ConnReq.m_iReqType = (!m_bRendezvous) ? 1 : 0; - m_ConnReq.m_iID = m_SocketID; - CIPAddress::ntop(serv_addr, m_ConnReq.m_piPeerIP, m_iIPversion); - - // Random Initial Sequence Number - srand((unsigned int)CTimer::getTime()); - m_iISN = m_ConnReq.m_iISN = (int32_t)(CSeqNo::m_iMaxSeqNo * (double(rand()) / RAND_MAX)); - - m_iLastDecSeq = m_iISN - 1; - m_iSndLastAck = m_iISN; - m_iSndLastDataAck = m_iISN; - m_iSndCurrSeqNo = m_iISN - 1; - m_iSndLastAck2 = m_iISN; - m_ullSndLastAck2Time = CTimer::getTime(); - - // Inform the server my configurations. - CPacket request; - char* reqdata = new char [m_iPayloadSize]; - request.pack(0, NULL, reqdata, m_iPayloadSize); - // ID = 0, connection request - request.m_iID = 0; - - int hs_size = m_iPayloadSize; - m_ConnReq.serialize(reqdata, hs_size); - request.setLength(hs_size); - m_pSndQueue->sendto(serv_addr, request); - m_llLastReqTime = CTimer::getTime(); - - m_bConnecting = true; - - // asynchronous connect, return immediately - if (!m_bSynRecving) - { - delete [] reqdata; - return; - } - - // Wait for the negotiated configurations from the peer side. - CPacket response; - char* resdata = new char [m_iPayloadSize]; - response.pack(0, NULL, resdata, m_iPayloadSize); - - CUDTException e(0, 0); - - while (!m_bClosing) - { - // avoid sending too many requests, at most 1 request per 250ms - if (CTimer::getTime() - m_llLastReqTime > 250000) - { - m_ConnReq.serialize(reqdata, hs_size); - request.setLength(hs_size); - if (m_bRendezvous) - request.m_iID = m_ConnRes.m_iID; - m_pSndQueue->sendto(serv_addr, request); - m_llLastReqTime = CTimer::getTime(); - } - - response.setLength(m_iPayloadSize); - if (m_pRcvQueue->recvfrom(m_SocketID, response) > 0) - { - if (connect(response) <= 0) - break; - - // new request/response should be sent out immediately on receving a response - m_llLastReqTime = 0; - } - - if (CTimer::getTime() > ttl) - { - // timeout - e = CUDTException(1, 1, 0); - break; - } - } - - delete [] reqdata; - delete [] resdata; - - if (e.getErrorCode() == 0) - { - if (m_bClosing) // if the socket is closed before connection... - e = CUDTException(1); - else if (1002 == m_ConnRes.m_iReqType) // connection request rejected - e = CUDTException(1, 2, 0); - else if ((!m_bRendezvous) && (m_iISN != m_ConnRes.m_iISN)) // secuity check - e = CUDTException(1, 4, 0); - } - - if (e.getErrorCode() != 0) - throw e; -} - -int CUDT::connect(const CPacket& response) throw () -{ - // this is the 2nd half of a connection request. If the connection is setup successfully this returns 0. - // returning -1 means there is an error. - // returning 1 or 2 means the connection is in process and needs more handshake - - if (!m_bConnecting) - return -1; - - if (m_bRendezvous && ((0 == response.getFlag()) || (1 == response.getType())) && (0 != m_ConnRes.m_iType)) - { - //a data packet or a keep-alive packet comes, which means the peer side is already connected - // in this situation, the previously recorded response will be used - goto POST_CONNECT; - } - - if ((1 != response.getFlag()) || (0 != response.getType())) - return -1; - - m_ConnRes.deserialize(response.m_pcData, response.getLength()); - - if (m_bRendezvous) - { - // regular connect should NOT communicate with rendezvous connect - // rendezvous connect require 3-way handshake - if (1 == m_ConnRes.m_iReqType) - return -1; - - if ((0 == m_ConnReq.m_iReqType) || (0 == m_ConnRes.m_iReqType)) - { - m_ConnReq.m_iReqType = -1; - // the request time must be updated so that the next handshake can be sent out immediately. - m_llLastReqTime = 0; - return 1; - } - } - else - { - // set cookie - if (1 == m_ConnRes.m_iReqType) - { - m_ConnReq.m_iReqType = -1; - m_ConnReq.m_iCookie = m_ConnRes.m_iCookie; - m_llLastReqTime = 0; - return 1; - } - } - -POST_CONNECT: - // Remove from rendezvous queue - m_pRcvQueue->removeConnector(m_SocketID); - - // Re-configure according to the negotiated values. - m_iMSS = m_ConnRes.m_iMSS; - m_iFlowWindowSize = m_ConnRes.m_iFlightFlagSize; - m_iPktSize = m_iMSS - 28; - m_iPayloadSize = m_iPktSize - CPacket::m_iPktHdrSize; - m_iPeerISN = m_ConnRes.m_iISN; - m_iRcvLastAck = m_ConnRes.m_iISN; - m_iRcvLastAckAck = m_ConnRes.m_iISN; - m_iRcvCurrSeqNo = m_ConnRes.m_iISN - 1; - m_PeerID = m_ConnRes.m_iID; - memcpy(m_piSelfIP, m_ConnRes.m_piPeerIP, 16); - - // Prepare all data structures - try - { - m_pSndBuffer = new CSndBuffer(32, m_iPayloadSize); - m_pRcvBuffer = new CRcvBuffer(&(m_pRcvQueue->m_UnitQueue), m_iRcvBufSize); - // after introducing lite ACK, the sndlosslist may not be cleared in time, so it requires twice space. - m_pSndLossList = new CSndLossList(m_iFlowWindowSize * 2); - m_pRcvLossList = new CRcvLossList(m_iFlightFlagSize); - m_pACKWindow = new CACKWindow(1024); - m_pRcvTimeWindow = new CPktTimeWindow(16, 64); - m_pSndTimeWindow = new CPktTimeWindow(); - } - catch (...) - { - throw CUDTException(3, 2, 0); - } - - CInfoBlock ib; - ib.m_iIPversion = m_iIPversion; - CInfoBlock::convert(m_pPeerAddr, m_iIPversion, ib.m_piIP); - if (m_pCache->lookup(&ib) >= 0) - { - m_iRTT = ib.m_iRTT; - m_iBandwidth = ib.m_iBandwidth; - } - - m_pCC = m_pCCFactory->create(); - m_pCC->m_UDT = m_SocketID; - m_pCC->setMSS(m_iMSS); - m_pCC->setMaxCWndSize(m_iFlowWindowSize); - m_pCC->setSndCurrSeqNo(m_iSndCurrSeqNo); - m_pCC->setRcvRate(m_iDeliveryRate); - m_pCC->setRTT(m_iRTT); - m_pCC->setBandwidth(m_iBandwidth); - m_pCC->init(); - - m_ullInterval = (uint64_t)(m_pCC->m_dPktSndPeriod * m_ullCPUFrequency); - m_dCongestionWindow = m_pCC->m_dCWndSize; - - // And, I am connected too. - m_bConnecting = false; - m_bConnected = true; - - // register this socket for receiving data packets - m_pRNode->m_bOnList = true; - m_pRcvQueue->setNewEntry(this); - - // acknowledge the management module. - s_UDTUnited.connect_complete(m_SocketID); - - // acknowledde any waiting epolls to write - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, true); - - return 0; -} - -void CUDT::connect(const sockaddr* peer, CHandShake* hs) -{ - CGuard cg(m_ConnectionLock); - - // Uses the smaller MSS between the peers - if (hs->m_iMSS > m_iMSS) - hs->m_iMSS = m_iMSS; - else - m_iMSS = hs->m_iMSS; - - // exchange info for maximum flow window size - m_iFlowWindowSize = hs->m_iFlightFlagSize; - hs->m_iFlightFlagSize = (m_iRcvBufSize < m_iFlightFlagSize)? m_iRcvBufSize : m_iFlightFlagSize; - - m_iPeerISN = hs->m_iISN; - - m_iRcvLastAck = hs->m_iISN; - m_iRcvLastAckAck = hs->m_iISN; - m_iRcvCurrSeqNo = hs->m_iISN - 1; - - m_PeerID = hs->m_iID; - hs->m_iID = m_SocketID; - - // use peer's ISN and send it back for security check - m_iISN = hs->m_iISN; - - m_iLastDecSeq = m_iISN - 1; - m_iSndLastAck = m_iISN; - m_iSndLastDataAck = m_iISN; - m_iSndCurrSeqNo = m_iISN - 1; - m_iSndLastAck2 = m_iISN; - m_ullSndLastAck2Time = CTimer::getTime(); - - // this is a reponse handshake - hs->m_iReqType = -1; - - // get local IP address and send the peer its IP address (because UDP cannot get local IP address) - memcpy(m_piSelfIP, hs->m_piPeerIP, 16); - CIPAddress::ntop(peer, hs->m_piPeerIP, m_iIPversion); - - m_iPktSize = m_iMSS - 28; - m_iPayloadSize = m_iPktSize - CPacket::m_iPktHdrSize; - - // Prepare all structures - try - { - m_pSndBuffer = new CSndBuffer(32, m_iPayloadSize); - m_pRcvBuffer = new CRcvBuffer(&(m_pRcvQueue->m_UnitQueue), m_iRcvBufSize); - m_pSndLossList = new CSndLossList(m_iFlowWindowSize * 2); - m_pRcvLossList = new CRcvLossList(m_iFlightFlagSize); - m_pACKWindow = new CACKWindow(1024); - m_pRcvTimeWindow = new CPktTimeWindow(16, 64); - m_pSndTimeWindow = new CPktTimeWindow(); - } - catch (...) - { - throw CUDTException(3, 2, 0); - } - - CInfoBlock ib; - ib.m_iIPversion = m_iIPversion; - CInfoBlock::convert(peer, m_iIPversion, ib.m_piIP); - if (m_pCache->lookup(&ib) >= 0) - { - m_iRTT = ib.m_iRTT; - m_iBandwidth = ib.m_iBandwidth; - } - - m_pCC = m_pCCFactory->create(); - m_pCC->m_UDT = m_SocketID; - m_pCC->setMSS(m_iMSS); - m_pCC->setMaxCWndSize(m_iFlowWindowSize); - m_pCC->setSndCurrSeqNo(m_iSndCurrSeqNo); - m_pCC->setRcvRate(m_iDeliveryRate); - m_pCC->setRTT(m_iRTT); - m_pCC->setBandwidth(m_iBandwidth); - m_pCC->init(); - - m_ullInterval = (uint64_t)(m_pCC->m_dPktSndPeriod * m_ullCPUFrequency); - m_dCongestionWindow = m_pCC->m_dCWndSize; - - m_pPeerAddr = (AF_INET == m_iIPversion) ? (sockaddr*)new sockaddr_in : (sockaddr*)new sockaddr_in6; - memcpy(m_pPeerAddr, peer, (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6)); - - // And of course, it is connected. - m_bConnected = true; - - // register this socket for receiving data packets - m_pRNode->m_bOnList = true; - m_pRcvQueue->setNewEntry(this); - - //send the response to the peer, see listen() for more discussions about this - CPacket response; - int size = CHandShake::m_iContentSize; - char* buffer = new char[size]; - hs->serialize(buffer, size); - response.pack(0, NULL, buffer, size); - response.m_iID = m_PeerID; - m_pSndQueue->sendto(peer, response); - delete [] buffer; -} - -void CUDT::close() -{ - if (!m_bOpened) - return; - - if (0 != m_Linger.l_onoff) - { - uint64_t entertime = CTimer::getTime(); - - while (!m_bBroken && m_bConnected && (m_pSndBuffer->getCurrBufSize() > 0) && (CTimer::getTime() - entertime < m_Linger.l_linger * 1000000ULL)) - { - // linger has been checked by previous close() call and has expired - if (m_ullLingerExpiration >= entertime) - break; - - if (!m_bSynSending) - { - // if this socket enables asynchronous sending, return immediately and let GC to close it later - if (0 == m_ullLingerExpiration) - m_ullLingerExpiration = entertime + m_Linger.l_linger * 1000000ULL; - - return; - } - - #ifndef WIN32 - timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - #else - Sleep(1); - #endif - } - } - - // remove this socket from the snd queue - if (m_bConnected) - m_pSndQueue->m_pSndUList->remove(this); - - // trigger any pending IO events. - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_ERR, true); - // then remove itself from all epoll monitoring - try - { - for (set::iterator i = m_sPollID.begin(); i != m_sPollID.end(); ++ i) - s_UDTUnited.m_EPoll.remove_usock(*i, m_SocketID); - } - catch (...) - { - } - - if (!m_bOpened) - return; - - // Inform the threads handler to stop. - m_bClosing = true; - - CGuard cg(m_ConnectionLock); - - // Signal the sender and recver if they are waiting for data. - releaseSynch(); - - if (m_bListening) - { - m_bListening = false; - m_pRcvQueue->removeListener(this); - } - else if (m_bConnecting) - { - m_pRcvQueue->removeConnector(m_SocketID); - } - - if (m_bConnected) - { - if (!m_bShutdown) - sendCtrl(5); - - m_pCC->close(); - - // Store current connection information. - CInfoBlock ib; - ib.m_iIPversion = m_iIPversion; - CInfoBlock::convert(m_pPeerAddr, m_iIPversion, ib.m_piIP); - ib.m_iRTT = m_iRTT; - ib.m_iBandwidth = m_iBandwidth; - m_pCache->update(&ib); - - m_bConnected = false; - } - - // waiting all send and recv calls to stop - CGuard sendguard(m_SendLock); - CGuard recvguard(m_RecvLock); - - // CLOSED. - m_bOpened = false; -} - -int CUDT::send(const char* data, int len) -{ - if (UDT_DGRAM == m_iSockType) - throw CUDTException(5, 10, 0); - - // throw an exception if not connected - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - - if (len <= 0) - return 0; - - CGuard sendguard(m_SendLock); - - if (m_pSndBuffer->getCurrBufSize() == 0) - { - // delay the EXP timer to avoid mis-fired timeout - uint64_t currtime; - CTimer::rdtsc(currtime); - m_ullLastRspTime = currtime; - } - - if (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) - { - if (!m_bSynSending) - throw CUDTException(6, 1, 0); - else - { - // wait here during a blocking sending - #ifndef WIN32 - pthread_mutex_lock(&m_SendBlockLock); - if (m_iSndTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) && m_bPeerHealth) - pthread_cond_wait(&m_SendBlockCond, &m_SendBlockLock); - } - else - { - uint64_t exptime = CTimer::getTime() + m_iSndTimeOut * 1000ULL; - timespec locktime; - - locktime.tv_sec = exptime / 1000000; - locktime.tv_nsec = (exptime % 1000000) * 1000; - - while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) && m_bPeerHealth && (CTimer::getTime() < exptime)) - pthread_cond_timedwait(&m_SendBlockCond, &m_SendBlockLock, &locktime); - } - pthread_mutex_unlock(&m_SendBlockLock); - #else - if (m_iSndTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) && m_bPeerHealth) - WaitForSingleObject(m_SendBlockCond, INFINITE); - } - else - { - uint64_t exptime = CTimer::getTime() + m_iSndTimeOut * 1000ULL; - - while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) && m_bPeerHealth && (CTimer::getTime() < exptime)) - WaitForSingleObject(m_SendBlockCond, DWORD((exptime - CTimer::getTime()) / 1000)); - } - #endif - - // check the connection status - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - else if (!m_bPeerHealth) - { - m_bPeerHealth = true; - throw CUDTException(7); - } - } - } - - if (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) - { - if (m_iSndTimeOut >= 0) - throw CUDTException(6, 3, 0); - - return 0; - } - - int size = (m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize; - if (size > len) - size = len; - - // record total time used for sending - if (0 == m_pSndBuffer->getCurrBufSize()) - m_llSndDurationCounter = CTimer::getTime(); - - // insert the user buffer into the sening list - m_pSndBuffer->addBuffer(data, size); - - // insert this socket to snd list if it is not on the list yet - m_pSndQueue->m_pSndUList->update(this, false); - - if (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) - { - // write is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, false); - } - - return size; -} - -int CUDT::recv(char* data, int len) -{ - if (UDT_DGRAM == m_iSockType) - throw CUDTException(5, 10, 0); - - // throw an exception if not connected - if (!m_bConnected) - throw CUDTException(2, 2, 0); - else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) - throw CUDTException(2, 1, 0); - - if (len <= 0) - return 0; - - CGuard recvguard(m_RecvLock); - - if (0 == m_pRcvBuffer->getRcvDataSize()) - { - if (!m_bSynRecving) - throw CUDTException(6, 2, 0); - else - { - #ifndef WIN32 - pthread_mutex_lock(&m_RecvDataLock); - if (m_iRcvTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) - pthread_cond_wait(&m_RecvDataCond, &m_RecvDataLock); - } - else - { - uint64_t exptime = CTimer::getTime() + m_iRcvTimeOut * 1000ULL; - timespec locktime; - - locktime.tv_sec = exptime / 1000000; - locktime.tv_nsec = (exptime % 1000000) * 1000; - - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) - { - pthread_cond_timedwait(&m_RecvDataCond, &m_RecvDataLock, &locktime); - if (CTimer::getTime() >= exptime) - break; - } - } - pthread_mutex_unlock(&m_RecvDataLock); - #else - if (m_iRcvTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) - WaitForSingleObject(m_RecvDataCond, INFINITE); - } - else - { - uint64_t enter_time = CTimer::getTime(); - - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) - { - int diff = int(CTimer::getTime() - enter_time) / 1000; - if (diff >= m_iRcvTimeOut) - break; - WaitForSingleObject(m_RecvDataCond, DWORD(m_iRcvTimeOut - diff )); - } - } - #endif - } - } - - // throw an exception if not connected - if (!m_bConnected) - throw CUDTException(2, 2, 0); - else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) - throw CUDTException(2, 1, 0); - - int res = m_pRcvBuffer->readBuffer(data, len); - - if (m_pRcvBuffer->getRcvDataSize() <= 0) - { - // read is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, false); - } - - if ((res <= 0) && (m_iRcvTimeOut >= 0)) - throw CUDTException(6, 3, 0); - - return res; -} - -int CUDT::sendmsg(const char* data, int len, int msttl, bool inorder) -{ - if (UDT_STREAM == m_iSockType) - throw CUDTException(5, 9, 0); - - // throw an exception if not connected - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - - if (len <= 0) - return 0; - - if (len > m_iSndBufSize * m_iPayloadSize) - throw CUDTException(5, 12, 0); - - CGuard sendguard(m_SendLock); - - if (m_pSndBuffer->getCurrBufSize() == 0) - { - // delay the EXP timer to avoid mis-fired timeout - uint64_t currtime; - CTimer::rdtsc(currtime); - m_ullLastRspTime = currtime; - } - - if ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len) - { - if (!m_bSynSending) - throw CUDTException(6, 1, 0); - else - { - // wait here during a blocking sending - #ifndef WIN32 - pthread_mutex_lock(&m_SendBlockLock); - if (m_iSndTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len)) - pthread_cond_wait(&m_SendBlockCond, &m_SendBlockLock); - } - else - { - uint64_t exptime = CTimer::getTime() + m_iSndTimeOut * 1000ULL; - timespec locktime; - - locktime.tv_sec = exptime / 1000000; - locktime.tv_nsec = (exptime % 1000000) * 1000; - - while (!m_bBroken && m_bConnected && !m_bClosing && ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len) && (CTimer::getTime() < exptime)) - pthread_cond_timedwait(&m_SendBlockCond, &m_SendBlockLock, &locktime); - } - pthread_mutex_unlock(&m_SendBlockLock); - #else - if (m_iSndTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len)) - WaitForSingleObject(m_SendBlockCond, INFINITE); - } - else - { - uint64_t exptime = CTimer::getTime() + m_iSndTimeOut * 1000ULL; - - while (!m_bBroken && m_bConnected && !m_bClosing && ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len) && (CTimer::getTime() < exptime)) - WaitForSingleObject(m_SendBlockCond, DWORD((exptime - CTimer::getTime()) / 1000)); - } - #endif - - // check the connection status - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - } - } - - if ((m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iPayloadSize < len) - { - if (m_iSndTimeOut >= 0) - throw CUDTException(6, 3, 0); - - return 0; - } - - // record total time used for sending - if (0 == m_pSndBuffer->getCurrBufSize()) - m_llSndDurationCounter = CTimer::getTime(); - - // insert the user buffer into the sening list - m_pSndBuffer->addBuffer(data, len, msttl, inorder); - - // insert this socket to the snd list if it is not on the list yet - m_pSndQueue->m_pSndUList->update(this, false); - - if (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) - { - // write is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, false); - } - - return len; -} - -int CUDT::recvmsg(char* data, int len) -{ - if (UDT_STREAM == m_iSockType) - throw CUDTException(5, 9, 0); - - // throw an exception if not connected - if (!m_bConnected) - throw CUDTException(2, 2, 0); - - if (len <= 0) - return 0; - - CGuard recvguard(m_RecvLock); - - if (m_bBroken || m_bClosing) - { - int res = m_pRcvBuffer->readMsg(data, len); - - if (m_pRcvBuffer->getRcvMsgNum() <= 0) - { - // read is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, false); - } - - if (0 == res) - throw CUDTException(2, 1, 0); - else - return res; - } - - if (!m_bSynRecving) - { - int res = m_pRcvBuffer->readMsg(data, len); - if (0 == res) - throw CUDTException(6, 2, 0); - else - return res; - } - - int res = 0; - bool timeout = false; - - do - { - #ifndef WIN32 - pthread_mutex_lock(&m_RecvDataLock); - - if (m_iRcvTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == (res = m_pRcvBuffer->readMsg(data, len)))) - pthread_cond_wait(&m_RecvDataCond, &m_RecvDataLock); - } - else - { - uint64_t exptime = CTimer::getTime() + m_iRcvTimeOut * 1000ULL; - timespec locktime; - - locktime.tv_sec = exptime / 1000000; - locktime.tv_nsec = (exptime % 1000000) * 1000; - - if (pthread_cond_timedwait(&m_RecvDataCond, &m_RecvDataLock, &locktime) == ETIMEDOUT) - timeout = true; - - res = m_pRcvBuffer->readMsg(data, len); - } - pthread_mutex_unlock(&m_RecvDataLock); - #else - if (m_iRcvTimeOut < 0) - { - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == (res = m_pRcvBuffer->readMsg(data, len)))) - WaitForSingleObject(m_RecvDataCond, INFINITE); - } - else - { - if (WaitForSingleObject(m_RecvDataCond, DWORD(m_iRcvTimeOut)) == WAIT_TIMEOUT) - timeout = true; - - res = m_pRcvBuffer->readMsg(data, len); - } - #endif - - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - } while ((0 == res) && !timeout); - - if (m_pRcvBuffer->getRcvMsgNum() <= 0) - { - // read is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, false); - } - - if ((res <= 0) && (m_iRcvTimeOut >= 0)) - throw CUDTException(6, 3, 0); - - return res; -} - -int64_t CUDT::sendfile(fstream& ifs, int64_t& offset, int64_t size, int block) -{ - if (UDT_DGRAM == m_iSockType) - throw CUDTException(5, 10, 0); - - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - - if (size <= 0) - return 0; - - CGuard sendguard(m_SendLock); - - if (m_pSndBuffer->getCurrBufSize() == 0) - { - // delay the EXP timer to avoid mis-fired timeout - uint64_t currtime; - CTimer::rdtsc(currtime); - m_ullLastRspTime = currtime; - } - - int64_t tosend = size; - int unitsize; - - // positioning... - try - { - ifs.seekg((streamoff)offset); - } - catch (...) - { - throw CUDTException(4, 1); - } - - // sending block by block - while (tosend > 0) - { - if (ifs.fail()) - throw CUDTException(4, 4); - - if (ifs.eof()) - break; - - unitsize = int((tosend >= block) ? block : tosend); - - #ifndef WIN32 - pthread_mutex_lock(&m_SendBlockLock); - while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) && m_bPeerHealth) - pthread_cond_wait(&m_SendBlockCond, &m_SendBlockLock); - pthread_mutex_unlock(&m_SendBlockLock); - #else - while (!m_bBroken && m_bConnected && !m_bClosing && (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) && m_bPeerHealth) - WaitForSingleObject(m_SendBlockCond, INFINITE); - #endif - - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - else if (!m_bConnected) - throw CUDTException(2, 2, 0); - else if (!m_bPeerHealth) - { - // reset peer health status, once this error returns, the app should handle the situation at the peer side - m_bPeerHealth = true; - throw CUDTException(7); - } - - // record total time used for sending - if (0 == m_pSndBuffer->getCurrBufSize()) - m_llSndDurationCounter = CTimer::getTime(); - - int64_t sentsize = m_pSndBuffer->addBufferFromFile(ifs, unitsize); - - if (sentsize > 0) - { - tosend -= sentsize; - offset += sentsize; - } - - // insert this socket to snd list if it is not on the list yet - m_pSndQueue->m_pSndUList->update(this, false); - } - - if (m_iSndBufSize <= m_pSndBuffer->getCurrBufSize()) - { - // write is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, false); - } - - return size - tosend; -} - -int64_t CUDT::recvfile(fstream& ofs, int64_t& offset, int64_t size, int block) -{ - if (UDT_DGRAM == m_iSockType) - throw CUDTException(5, 10, 0); - - if (!m_bConnected) - throw CUDTException(2, 2, 0); - else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) - throw CUDTException(2, 1, 0); - - if (size <= 0) - return 0; - - CGuard recvguard(m_RecvLock); - - int64_t torecv = size; - int unitsize = block; - int recvsize; - - // positioning... - try - { - ofs.seekp((streamoff)offset); - } - catch (...) - { - throw CUDTException(4, 3); - } - - // receiving... "recvfile" is always blocking - while (torecv > 0) - { - if (ofs.fail()) - { - // send the sender a signal so it will not be blocked forever - int32_t err_code = CUDTException::EFILE; - sendCtrl(8, &err_code); - - throw CUDTException(4, 4); - } - - #ifndef WIN32 - pthread_mutex_lock(&m_RecvDataLock); - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) - pthread_cond_wait(&m_RecvDataCond, &m_RecvDataLock); - pthread_mutex_unlock(&m_RecvDataLock); - #else - while (!m_bBroken && m_bConnected && !m_bClosing && (0 == m_pRcvBuffer->getRcvDataSize())) - WaitForSingleObject(m_RecvDataCond, INFINITE); - #endif - - if (!m_bConnected) - throw CUDTException(2, 2, 0); - else if ((m_bBroken || m_bClosing) && (0 == m_pRcvBuffer->getRcvDataSize())) - throw CUDTException(2, 1, 0); - - unitsize = int((torecv >= block) ? block : torecv); - recvsize = m_pRcvBuffer->readBufferToFile(ofs, unitsize); - - if (recvsize > 0) - { - torecv -= recvsize; - offset += recvsize; - } - } - - if (m_pRcvBuffer->getRcvDataSize() <= 0) - { - // read is not available any more - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, false); - } - - return size - torecv; -} - -void CUDT::sample(CPerfMon* perf, bool clear) -{ - if (!m_bConnected) - throw CUDTException(2, 2, 0); - if (m_bBroken || m_bClosing) - throw CUDTException(2, 1, 0); - - uint64_t currtime = CTimer::getTime(); - perf->msTimeStamp = (currtime - m_StartTime) / 1000; - - perf->pktSent = m_llTraceSent; - perf->pktRecv = m_llTraceRecv; - perf->pktSndLoss = m_iTraceSndLoss; - perf->pktRcvLoss = m_iTraceRcvLoss; - perf->pktRetrans = m_iTraceRetrans; - perf->pktSentACK = m_iSentACK; - perf->pktRecvACK = m_iRecvACK; - perf->pktSentNAK = m_iSentNAK; - perf->pktRecvNAK = m_iRecvNAK; - perf->usSndDuration = m_llSndDuration; - - perf->pktSentTotal = m_llSentTotal; - perf->pktRecvTotal = m_llRecvTotal; - perf->pktSndLossTotal = m_iSndLossTotal; - perf->pktRcvLossTotal = m_iRcvLossTotal; - perf->pktRetransTotal = m_iRetransTotal; - perf->pktSentACKTotal = m_iSentACKTotal; - perf->pktRecvACKTotal = m_iRecvACKTotal; - perf->pktSentNAKTotal = m_iSentNAKTotal; - perf->pktRecvNAKTotal = m_iRecvNAKTotal; - perf->usSndDurationTotal = m_llSndDurationTotal; - - double interval = double(currtime - m_LastSampleTime); - - perf->mbpsSendRate = double(m_llTraceSent) * m_iPayloadSize * 8.0 / interval; - perf->mbpsRecvRate = double(m_llTraceRecv) * m_iPayloadSize * 8.0 / interval; - - perf->usPktSndPeriod = m_ullInterval / double(m_ullCPUFrequency); - perf->pktFlowWindow = m_iFlowWindowSize; - perf->pktCongestionWindow = (int)m_dCongestionWindow; - perf->pktFlightSize = CSeqNo::seqlen(m_iSndLastAck, CSeqNo::incseq(m_iSndCurrSeqNo)) - 1; - perf->msRTT = m_iRTT/1000.0; - perf->mbpsBandwidth = m_iBandwidth * m_iPayloadSize * 8.0 / 1000000.0; - - #ifndef WIN32 - if (0 == pthread_mutex_trylock(&m_ConnectionLock)) - #else - if (WAIT_OBJECT_0 == WaitForSingleObject(m_ConnectionLock, 0)) - #endif - { - perf->byteAvailSndBuf = (NULL == m_pSndBuffer) ? 0 : (m_iSndBufSize - m_pSndBuffer->getCurrBufSize()) * m_iMSS; - perf->byteAvailRcvBuf = (NULL == m_pRcvBuffer) ? 0 : m_pRcvBuffer->getAvailBufSize() * m_iMSS; - - #ifndef WIN32 - pthread_mutex_unlock(&m_ConnectionLock); - #else - ReleaseMutex(m_ConnectionLock); - #endif - } - else - { - perf->byteAvailSndBuf = 0; - perf->byteAvailRcvBuf = 0; - } - - if (clear) - { - m_llTraceSent = m_llTraceRecv = m_iTraceSndLoss = m_iTraceRcvLoss = m_iTraceRetrans = m_iSentACK = m_iRecvACK = m_iSentNAK = m_iRecvNAK = 0; - m_llSndDuration = 0; - m_LastSampleTime = currtime; - } -} - -void CUDT::CCUpdate() -{ - m_ullInterval = (uint64_t)(m_pCC->m_dPktSndPeriod * m_ullCPUFrequency); - m_dCongestionWindow = m_pCC->m_dCWndSize; - - if (m_llMaxBW <= 0) - return; - const double minSP = 1000000.0 / (double(m_llMaxBW) / m_iMSS) * m_ullCPUFrequency; - if (m_ullInterval < minSP) - m_ullInterval = minSP; -} - -void CUDT::initSynch() -{ - #ifndef WIN32 - pthread_mutex_init(&m_SendBlockLock, NULL); - pthread_cond_init(&m_SendBlockCond, NULL); - pthread_mutex_init(&m_RecvDataLock, NULL); - pthread_cond_init(&m_RecvDataCond, NULL); - pthread_mutex_init(&m_SendLock, NULL); - pthread_mutex_init(&m_RecvLock, NULL); - pthread_mutex_init(&m_AckLock, NULL); - pthread_mutex_init(&m_ConnectionLock, NULL); - #else - m_SendBlockLock = CreateMutex(NULL, false, NULL); - m_SendBlockCond = CreateEvent(NULL, false, false, NULL); - m_RecvDataLock = CreateMutex(NULL, false, NULL); - m_RecvDataCond = CreateEvent(NULL, false, false, NULL); - m_SendLock = CreateMutex(NULL, false, NULL); - m_RecvLock = CreateMutex(NULL, false, NULL); - m_AckLock = CreateMutex(NULL, false, NULL); - m_ConnectionLock = CreateMutex(NULL, false, NULL); - #endif -} - -void CUDT::destroySynch() -{ - #ifndef WIN32 - pthread_mutex_destroy(&m_SendBlockLock); - pthread_cond_destroy(&m_SendBlockCond); - pthread_mutex_destroy(&m_RecvDataLock); - pthread_cond_destroy(&m_RecvDataCond); - pthread_mutex_destroy(&m_SendLock); - pthread_mutex_destroy(&m_RecvLock); - pthread_mutex_destroy(&m_AckLock); - pthread_mutex_destroy(&m_ConnectionLock); - #else - CloseHandle(m_SendBlockLock); - CloseHandle(m_SendBlockCond); - CloseHandle(m_RecvDataLock); - CloseHandle(m_RecvDataCond); - CloseHandle(m_SendLock); - CloseHandle(m_RecvLock); - CloseHandle(m_AckLock); - CloseHandle(m_ConnectionLock); - #endif -} - -void CUDT::releaseSynch() -{ - #ifndef WIN32 - // wake up user calls - pthread_mutex_lock(&m_SendBlockLock); - pthread_cond_signal(&m_SendBlockCond); - pthread_mutex_unlock(&m_SendBlockLock); - - pthread_mutex_lock(&m_SendLock); - pthread_mutex_unlock(&m_SendLock); - - pthread_mutex_lock(&m_RecvDataLock); - pthread_cond_signal(&m_RecvDataCond); - pthread_mutex_unlock(&m_RecvDataLock); - - pthread_mutex_lock(&m_RecvLock); - pthread_mutex_unlock(&m_RecvLock); - #else - SetEvent(m_SendBlockCond); - WaitForSingleObject(m_SendLock, INFINITE); - ReleaseMutex(m_SendLock); - SetEvent(m_RecvDataCond); - WaitForSingleObject(m_RecvLock, INFINITE); - ReleaseMutex(m_RecvLock); - #endif -} - -void CUDT::sendCtrl(int pkttype, void* lparam, void* rparam, int size) -{ - CPacket ctrlpkt; - - switch (pkttype) - { - case 2: //010 - Acknowledgement - { - int32_t ack; - - // If there is no loss, the ACK is the current largest sequence number plus 1; - // Otherwise it is the smallest sequence number in the receiver loss list. - if (0 == m_pRcvLossList->getLossLength()) - ack = CSeqNo::incseq(m_iRcvCurrSeqNo); - else - ack = m_pRcvLossList->getFirstLostSeq(); - - if (ack == m_iRcvLastAckAck) - break; - - // send out a lite ACK - // to save time on buffer processing and bandwidth/AS measurement, a lite ACK only feeds back an ACK number - if (4 == size) - { - ctrlpkt.pack(pkttype, NULL, &ack, size); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - } - - uint64_t currtime; - CTimer::rdtsc(currtime); - - // There are new received packets to acknowledge, update related information. - if (CSeqNo::seqcmp(ack, m_iRcvLastAck) > 0) - { - int acksize = CSeqNo::seqoff(m_iRcvLastAck, ack); - - m_iRcvLastAck = ack; - - m_pRcvBuffer->ackData(acksize); - - // signal a waiting "recv" call if there is any data available - #ifndef WIN32 - pthread_mutex_lock(&m_RecvDataLock); - if (m_bSynRecving) - pthread_cond_signal(&m_RecvDataCond); - pthread_mutex_unlock(&m_RecvDataLock); - #else - if (m_bSynRecving) - SetEvent(m_RecvDataCond); - #endif - - // acknowledge any waiting epolls to read - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, true); - } - else if (ack == m_iRcvLastAck) - { - if ((currtime - m_ullLastAckTime) < ((m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency)) - break; - } - else - break; - - // Send out the ACK only if has not been received by the sender before - if (CSeqNo::seqcmp(m_iRcvLastAck, m_iRcvLastAckAck) > 0) - { - int32_t data[6]; - - m_iAckSeqNo = CAckNo::incack(m_iAckSeqNo); - data[0] = m_iRcvLastAck; - data[1] = m_iRTT; - data[2] = m_iRTTVar; - data[3] = m_pRcvBuffer->getAvailBufSize(); - // a minimum flow window of 2 is used, even if buffer is full, to break potential deadlock - if (data[3] < 2) - data[3] = 2; - - if (currtime - m_ullLastAckTime > m_ullSYNInt) - { - data[4] = m_pRcvTimeWindow->getPktRcvSpeed(); - data[5] = m_pRcvTimeWindow->getBandwidth(); - ctrlpkt.pack(pkttype, &m_iAckSeqNo, data, 24); - - CTimer::rdtsc(m_ullLastAckTime); - } - else - { - ctrlpkt.pack(pkttype, &m_iAckSeqNo, data, 16); - } - - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - m_pACKWindow->store(m_iAckSeqNo, m_iRcvLastAck); - - ++ m_iSentACK; - ++ m_iSentACKTotal; - } - - break; - } - - case 6: //110 - Acknowledgement of Acknowledgement - ctrlpkt.pack(pkttype, lparam); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - - case 3: //011 - Loss Report - { - if (NULL != rparam) - { - if (1 == size) - { - // only 1 loss packet - ctrlpkt.pack(pkttype, NULL, (int32_t *)rparam + 1, 4); - } - else - { - // more than 1 loss packets - ctrlpkt.pack(pkttype, NULL, rparam, 8); - } - - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - ++ m_iSentNAK; - ++ m_iSentNAKTotal; - } - else if (m_pRcvLossList->getLossLength() > 0) - { - // this is periodically NAK report; make sure NAK cannot be sent back too often - - // read loss list from the local receiver loss list - int32_t* data = new int32_t[m_iPayloadSize / 4]; - int losslen; - m_pRcvLossList->getLossArray(data, losslen, m_iPayloadSize / 4); - - if (0 < losslen) - { - ctrlpkt.pack(pkttype, NULL, data, losslen * 4); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - ++ m_iSentNAK; - ++ m_iSentNAKTotal; - } - - delete [] data; - } - - // update next NAK time, which should wait enough time for the retansmission, but not too long - m_ullNAKInt = (m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency; - int rcv_speed = m_pRcvTimeWindow->getPktRcvSpeed(); - if (rcv_speed > 0) - m_ullNAKInt += (m_pRcvLossList->getLossLength() * 1000000ULL / rcv_speed) * m_ullCPUFrequency; - if (m_ullNAKInt < m_ullMinNakInt) - m_ullNAKInt = m_ullMinNakInt; - - break; - } - - case 4: //100 - Congestion Warning - ctrlpkt.pack(pkttype); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - CTimer::rdtsc(m_ullLastWarningTime); - - break; - - case 1: //001 - Keep-alive - ctrlpkt.pack(pkttype); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - - case 0: //000 - Handshake - ctrlpkt.pack(pkttype, NULL, rparam, sizeof(CHandShake)); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - - case 5: //101 - Shutdown - ctrlpkt.pack(pkttype); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - - case 7: //111 - Msg drop request - ctrlpkt.pack(pkttype, lparam, rparam, 8); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - - case 8: //1000 - acknowledge the peer side a special error - ctrlpkt.pack(pkttype, lparam); - ctrlpkt.m_iID = m_PeerID; - m_pSndQueue->sendto(m_pPeerAddr, ctrlpkt); - - break; - - case 32767: //0x7FFF - Resevered for future use - break; - - default: - break; - } -} - -void CUDT::processCtrl(CPacket& ctrlpkt) -{ - // Just heard from the peer, reset the expiration count. - m_iEXPCount = 1; - uint64_t currtime; - CTimer::rdtsc(currtime); - m_ullLastRspTime = currtime; - - switch (ctrlpkt.getType()) - { - case 2: //010 - Acknowledgement - { - int32_t ack; - - // process a lite ACK - if (4 == ctrlpkt.getLength()) - { - ack = *(int32_t *)ctrlpkt.m_pcData; - if (CSeqNo::seqcmp(ack, m_iSndLastAck) >= 0) - { - m_iFlowWindowSize -= CSeqNo::seqoff(m_iSndLastAck, ack); - m_iSndLastAck = ack; - } - - break; - } - - // read ACK seq. no. - ack = ctrlpkt.getAckSeqNo(); - - // send ACK acknowledgement - // number of ACK2 can be much less than number of ACK - uint64_t now = CTimer::getTime(); - if ((currtime - m_ullSndLastAck2Time > (uint64_t)m_iSYNInterval) || (ack == m_iSndLastAck2)) - { - sendCtrl(6, &ack); - m_iSndLastAck2 = ack; - m_ullSndLastAck2Time = now; - } - - // Got data ACK - ack = *(int32_t *)ctrlpkt.m_pcData; - - // check the validation of the ack - if (CSeqNo::seqcmp(ack, CSeqNo::incseq(m_iSndCurrSeqNo)) > 0) - { - //this should not happen: attack or bug - m_bBroken = true; - m_iBrokenCounter = 0; - break; - } - - if (CSeqNo::seqcmp(ack, m_iSndLastAck) >= 0) - { - // Update Flow Window Size, must update before and together with m_iSndLastAck - m_iFlowWindowSize = *((int32_t *)ctrlpkt.m_pcData + 3); - m_iSndLastAck = ack; - } - - // protect packet retransmission - CGuard::enterCS(m_AckLock); - - int offset = CSeqNo::seqoff(m_iSndLastDataAck, ack); - if (offset <= 0) - { - // discard it if it is a repeated ACK - CGuard::leaveCS(m_AckLock); - break; - } - - // acknowledge the sending buffer - m_pSndBuffer->ackData(offset); - - // record total time used for sending - m_llSndDuration += currtime - m_llSndDurationCounter; - m_llSndDurationTotal += currtime - m_llSndDurationCounter; - m_llSndDurationCounter = currtime; - - // update sending variables - m_iSndLastDataAck = ack; - m_pSndLossList->remove(CSeqNo::decseq(m_iSndLastDataAck)); - - CGuard::leaveCS(m_AckLock); - - #ifndef WIN32 - pthread_mutex_lock(&m_SendBlockLock); - if (m_bSynSending) - pthread_cond_signal(&m_SendBlockCond); - pthread_mutex_unlock(&m_SendBlockLock); - #else - if (m_bSynSending) - SetEvent(m_SendBlockCond); - #endif - - // acknowledde any waiting epolls to write - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, true); - - // insert this socket to snd list if it is not on the list yet - m_pSndQueue->m_pSndUList->update(this, false); - - // Update RTT - //m_iRTT = *((int32_t *)ctrlpkt.m_pcData + 1); - //m_iRTTVar = *((int32_t *)ctrlpkt.m_pcData + 2); - int rtt = *((int32_t *)ctrlpkt.m_pcData + 1); - m_iRTTVar = (m_iRTTVar * 3 + abs(rtt - m_iRTT)) >> 2; - m_iRTT = (m_iRTT * 7 + rtt) >> 3; - - m_pCC->setRTT(m_iRTT); - - if (ctrlpkt.getLength() > 16) - { - // Update Estimated Bandwidth and packet delivery rate - if (*((int32_t *)ctrlpkt.m_pcData + 4) > 0) - m_iDeliveryRate = (m_iDeliveryRate * 7 + *((int32_t *)ctrlpkt.m_pcData + 4)) >> 3; - - if (*((int32_t *)ctrlpkt.m_pcData + 5) > 0) - m_iBandwidth = (m_iBandwidth * 7 + *((int32_t *)ctrlpkt.m_pcData + 5)) >> 3; - - m_pCC->setRcvRate(m_iDeliveryRate); - m_pCC->setBandwidth(m_iBandwidth); - } - - m_pCC->onACK(ack); - CCUpdate(); - - ++ m_iRecvACK; - ++ m_iRecvACKTotal; - - break; - } - - case 6: //110 - Acknowledgement of Acknowledgement - { - int32_t ack; - int rtt = -1; - - // update RTT - rtt = m_pACKWindow->acknowledge(ctrlpkt.getAckSeqNo(), ack); - if (rtt <= 0) - break; - - //if increasing delay detected... - // sendCtrl(4); - - // RTT EWMA - m_iRTTVar = (m_iRTTVar * 3 + abs(rtt - m_iRTT)) >> 2; - m_iRTT = (m_iRTT * 7 + rtt) >> 3; - - m_pCC->setRTT(m_iRTT); - - // update last ACK that has been received by the sender - if (CSeqNo::seqcmp(ack, m_iRcvLastAckAck) > 0) - m_iRcvLastAckAck = ack; - - break; - } - - case 3: //011 - Loss Report - { - int32_t* losslist = (int32_t *)(ctrlpkt.m_pcData); - - m_pCC->onLoss(losslist, ctrlpkt.getLength() / 4); - CCUpdate(); - - bool secure = true; - - // decode loss list message and insert loss into the sender loss list - for (int i = 0, n = (int)(ctrlpkt.getLength() / 4); i < n; ++ i) - { - if (0 != (losslist[i] & 0x80000000)) - { - if ((CSeqNo::seqcmp(losslist[i] & 0x7FFFFFFF, losslist[i + 1]) > 0) || (CSeqNo::seqcmp(losslist[i + 1], m_iSndCurrSeqNo) > 0)) - { - // seq_a must not be greater than seq_b; seq_b must not be greater than the most recent sent seq - secure = false; - break; - } - - int num = 0; - if (CSeqNo::seqcmp(losslist[i] & 0x7FFFFFFF, m_iSndLastAck) >= 0) - num = m_pSndLossList->insert(losslist[i] & 0x7FFFFFFF, losslist[i + 1]); - else if (CSeqNo::seqcmp(losslist[i + 1], m_iSndLastAck) >= 0) - num = m_pSndLossList->insert(m_iSndLastAck, losslist[i + 1]); - - m_iTraceSndLoss += num; - m_iSndLossTotal += num; - - ++ i; - } - else if (CSeqNo::seqcmp(losslist[i], m_iSndLastAck) >= 0) - { - if (CSeqNo::seqcmp(losslist[i], m_iSndCurrSeqNo) > 0) - { - //seq_a must not be greater than the most recent sent seq - secure = false; - break; - } - - int num = m_pSndLossList->insert(losslist[i], losslist[i]); - - m_iTraceSndLoss += num; - m_iSndLossTotal += num; - } - } - - if (!secure) - { - //this should not happen: attack or bug - m_bBroken = true; - m_iBrokenCounter = 0; - break; - } - - // the lost packet (retransmission) should be sent out immediately - m_pSndQueue->m_pSndUList->update(this); - - ++ m_iRecvNAK; - ++ m_iRecvNAKTotal; - - break; - } - - case 4: //100 - Delay Warning - // One way packet delay is increasing, so decrease the sending rate - m_ullInterval = (uint64_t)ceil(m_ullInterval * 1.125); - m_iLastDecSeq = m_iSndCurrSeqNo; - - break; - - case 1: //001 - Keep-alive - // The only purpose of keep-alive packet is to tell that the peer is still alive - // nothing needs to be done. - - break; - - case 0: //000 - Handshake - { - CHandShake req; - req.deserialize(ctrlpkt.m_pcData, ctrlpkt.getLength()); - if ((req.m_iReqType > 0) || (m_bRendezvous && (req.m_iReqType != -2))) - { - // The peer side has not received the handshake message, so it keeps querying - // resend the handshake packet - - CHandShake initdata; - initdata.m_iISN = m_iISN; - initdata.m_iMSS = m_iMSS; - initdata.m_iFlightFlagSize = m_iFlightFlagSize; - initdata.m_iReqType = (!m_bRendezvous) ? -1 : -2; - initdata.m_iID = m_SocketID; - - char* hs = new char [m_iPayloadSize]; - int hs_size = m_iPayloadSize; - initdata.serialize(hs, hs_size); - sendCtrl(0, NULL, hs, hs_size); - delete [] hs; - } - - break; - } - - case 5: //101 - Shutdown - m_bShutdown = true; - m_bClosing = true; - m_bBroken = true; - m_iBrokenCounter = 60; - - // Signal the sender and recver if they are waiting for data. - releaseSynch(); - - CTimer::triggerEvent(); - - break; - - case 7: //111 - Msg drop request - m_pRcvBuffer->dropMsg(ctrlpkt.getMsgSeq()); - m_pRcvLossList->remove(*(int32_t*)ctrlpkt.m_pcData, *(int32_t*)(ctrlpkt.m_pcData + 4)); - - // move forward with current recv seq no. - if ((CSeqNo::seqcmp(*(int32_t*)ctrlpkt.m_pcData, CSeqNo::incseq(m_iRcvCurrSeqNo)) <= 0) - && (CSeqNo::seqcmp(*(int32_t*)(ctrlpkt.m_pcData + 4), m_iRcvCurrSeqNo) > 0)) - { - m_iRcvCurrSeqNo = *(int32_t*)(ctrlpkt.m_pcData + 4); - } - - break; - - case 8: // 1000 - An error has happened to the peer side - //int err_type = packet.getAddInfo(); - - // currently only this error is signalled from the peer side - // if recvfile() failes (e.g., due to disk fail), blcoked sendfile/send should return immediately - // giving the app a chance to fix the issue - - m_bPeerHealth = false; - - break; - - case 32767: //0x7FFF - reserved and user defined messages - m_pCC->processCustomMsg(&ctrlpkt); - CCUpdate(); - - break; - - default: - break; - } -} - -int CUDT::packData(CPacket& packet, uint64_t& ts) -{ - int payload = 0; - bool probe = false; - - uint64_t entertime; - CTimer::rdtsc(entertime); - - if ((0 != m_ullTargetTime) && (entertime > m_ullTargetTime)) - m_ullTimeDiff += entertime - m_ullTargetTime; - - // Loss retransmission always has higher priority. - if ((packet.m_iSeqNo = m_pSndLossList->getLostSeq()) >= 0) - { - // protect m_iSndLastDataAck from updating by ACK processing - CGuard ackguard(m_AckLock); - - int offset = CSeqNo::seqoff(m_iSndLastDataAck, packet.m_iSeqNo); - if (offset < 0) - return 0; - - int msglen; - - payload = m_pSndBuffer->readData(&(packet.m_pcData), offset, packet.m_iMsgNo, msglen); - - if (-1 == payload) - { - int32_t seqpair[2]; - seqpair[0] = packet.m_iSeqNo; - seqpair[1] = CSeqNo::incseq(seqpair[0], msglen); - sendCtrl(7, &packet.m_iMsgNo, seqpair, 8); - - // only one msg drop request is necessary - m_pSndLossList->remove(seqpair[1]); - - // skip all dropped packets - if (CSeqNo::seqcmp(m_iSndCurrSeqNo, CSeqNo::incseq(seqpair[1])) < 0) - m_iSndCurrSeqNo = CSeqNo::incseq(seqpair[1]); - - return 0; - } - else if (0 == payload) - return 0; - - ++ m_iTraceRetrans; - ++ m_iRetransTotal; - } - else - { - // If no loss, pack a new packet. - - // check congestion/flow window limit - int cwnd = (m_iFlowWindowSize < (int)m_dCongestionWindow) ? m_iFlowWindowSize : (int)m_dCongestionWindow; - if (cwnd >= CSeqNo::seqlen(m_iSndLastAck, CSeqNo::incseq(m_iSndCurrSeqNo))) - { - if (0 != (payload = m_pSndBuffer->readData(&(packet.m_pcData), packet.m_iMsgNo))) - { - m_iSndCurrSeqNo = CSeqNo::incseq(m_iSndCurrSeqNo); - m_pCC->setSndCurrSeqNo(m_iSndCurrSeqNo); - - packet.m_iSeqNo = m_iSndCurrSeqNo; - - // every 16 (0xF) packets, a packet pair is sent - if (0 == (packet.m_iSeqNo & 0xF)) - probe = true; - } - else - { - m_ullTargetTime = 0; - m_ullTimeDiff = 0; - ts = 0; - return 0; - } - } - else - { - m_ullTargetTime = 0; - m_ullTimeDiff = 0; - ts = 0; - return 0; - } - } - - packet.m_iTimeStamp = int(CTimer::getTime() - m_StartTime); - packet.m_iID = m_PeerID; - packet.setLength(payload); - - m_pCC->onPktSent(&packet); - //m_pSndTimeWindow->onPktSent(packet.m_iTimeStamp); - - ++ m_llTraceSent; - ++ m_llSentTotal; - - if (probe) - { - // sends out probing packet pair - ts = entertime; - probe = false; - } - else - { - #ifndef NO_BUSY_WAITING - ts = entertime + m_ullInterval; - #else - if (m_ullTimeDiff >= m_ullInterval) - { - ts = entertime; - m_ullTimeDiff -= m_ullInterval; - } - else - { - ts = entertime + m_ullInterval - m_ullTimeDiff; - m_ullTimeDiff = 0; - } - #endif - } - - m_ullTargetTime = ts; - - return payload; -} - -int CUDT::processData(CUnit* unit) -{ - CPacket& packet = unit->m_Packet; - - // Just heard from the peer, reset the expiration count. - m_iEXPCount = 1; - uint64_t currtime; - CTimer::rdtsc(currtime); - m_ullLastRspTime = currtime; - - m_pCC->onPktReceived(&packet); - ++ m_iPktCount; - // update time information - m_pRcvTimeWindow->onPktArrival(); - - // check if it is probing packet pair - if (0 == (packet.m_iSeqNo & 0xF)) - m_pRcvTimeWindow->probe1Arrival(); - else if (1 == (packet.m_iSeqNo & 0xF)) - m_pRcvTimeWindow->probe2Arrival(); - - ++ m_llTraceRecv; - ++ m_llRecvTotal; - - int32_t offset = CSeqNo::seqoff(m_iRcvLastAck, packet.m_iSeqNo); - if ((offset < 0) || (offset >= m_pRcvBuffer->getAvailBufSize())) - return -1; - - if (m_pRcvBuffer->addData(unit, offset) < 0) - return -1; - - // Loss detection. - if (CSeqNo::seqcmp(packet.m_iSeqNo, CSeqNo::incseq(m_iRcvCurrSeqNo)) > 0) - { - // If loss found, insert them to the receiver loss list - m_pRcvLossList->insert(CSeqNo::incseq(m_iRcvCurrSeqNo), CSeqNo::decseq(packet.m_iSeqNo)); - - // pack loss list for NAK - int32_t lossdata[2]; - lossdata[0] = CSeqNo::incseq(m_iRcvCurrSeqNo) | 0x80000000; - lossdata[1] = CSeqNo::decseq(packet.m_iSeqNo); - - // Generate loss report immediately. - sendCtrl(3, NULL, lossdata, (CSeqNo::incseq(m_iRcvCurrSeqNo) == CSeqNo::decseq(packet.m_iSeqNo)) ? 1 : 2); - - int loss = CSeqNo::seqlen(m_iRcvCurrSeqNo, packet.m_iSeqNo) - 2; - m_iTraceRcvLoss += loss; - m_iRcvLossTotal += loss; - } - - // This is not a regular fixed size packet... - //an irregular sized packet usually indicates the end of a message, so send an ACK immediately - if (packet.getLength() != m_iPayloadSize) - CTimer::rdtsc(m_ullNextACKTime); - - // Update the current largest sequence number that has been received. - // Or it is a retransmitted packet, remove it from receiver loss list. - if (CSeqNo::seqcmp(packet.m_iSeqNo, m_iRcvCurrSeqNo) > 0) - m_iRcvCurrSeqNo = packet.m_iSeqNo; - else - m_pRcvLossList->remove(packet.m_iSeqNo); - - return 0; -} - -int CUDT::listen(sockaddr* addr, CPacket& packet) -{ - if (m_bClosing) - return 1002; - - if (packet.getLength() != CHandShake::m_iContentSize) - return 1004; - - CHandShake hs; - hs.deserialize(packet.m_pcData, packet.getLength()); - - // SYN cookie - char clienthost[NI_MAXHOST]; - char clientport[NI_MAXSERV]; - getnameinfo(addr, (AF_INET == m_iVersion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6), clienthost, sizeof(clienthost), clientport, sizeof(clientport), NI_NUMERICHOST|NI_NUMERICSERV); - int64_t timestamp = (CTimer::getTime() - m_StartTime) / 60000000; // secret changes every one minute - stringstream cookiestr; - cookiestr << clienthost << ":" << clientport << ":" << timestamp; - unsigned char cookie[16]; - CMD5::compute(cookiestr.str().c_str(), cookie); - - if (1 == hs.m_iReqType) - { - hs.m_iCookie = *(int*)cookie; - packet.m_iID = hs.m_iID; - int size = packet.getLength(); - hs.serialize(packet.m_pcData, size); - m_pSndQueue->sendto(addr, packet); - return 0; - } - else - { - if (hs.m_iCookie != *(int*)cookie) - { - timestamp --; - cookiestr << clienthost << ":" << clientport << ":" << timestamp; - CMD5::compute(cookiestr.str().c_str(), cookie); - - if (hs.m_iCookie != *(int*)cookie) - return -1; - } - } - - int32_t id = hs.m_iID; - - // When a peer side connects in... - if ((1 == packet.getFlag()) && (0 == packet.getType())) - { - if ((hs.m_iVersion != m_iVersion) || (hs.m_iType != m_iSockType)) - { - // mismatch, reject the request - hs.m_iReqType = 1002; - int size = CHandShake::m_iContentSize; - hs.serialize(packet.m_pcData, size); - packet.m_iID = id; - m_pSndQueue->sendto(addr, packet); - } - else - { - int result = s_UDTUnited.newConnection(m_SocketID, addr, &hs); - if (result == -1) - hs.m_iReqType = 1002; - - // send back a response if connection failed or connection already existed - // new connection response should be sent in connect() - if (result != 1) - { - int size = CHandShake::m_iContentSize; - hs.serialize(packet.m_pcData, size); - packet.m_iID = id; - m_pSndQueue->sendto(addr, packet); - } - else - { - // a new connection has been created, enable epoll for write - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, true); - } - } - } - - return hs.m_iReqType; -} - -void CUDT::checkTimers() -{ - // update CC parameters - CCUpdate(); - //uint64_t minint = (uint64_t)(m_ullCPUFrequency * m_pSndTimeWindow->getMinPktSndInt() * 0.9); - //if (m_ullInterval < minint) - // m_ullInterval = minint; - - uint64_t currtime; - CTimer::rdtsc(currtime); - - if ((currtime > m_ullNextACKTime) || ((m_pCC->m_iACKInterval > 0) && (m_pCC->m_iACKInterval <= m_iPktCount))) - { - // ACK timer expired or ACK interval is reached - - sendCtrl(2); - CTimer::rdtsc(currtime); - if (m_pCC->m_iACKPeriod > 0) - m_ullNextACKTime = currtime + m_pCC->m_iACKPeriod * m_ullCPUFrequency; - else - m_ullNextACKTime = currtime + m_ullACKInt; - - m_iPktCount = 0; - m_iLightACKCount = 1; - } - else if (m_iSelfClockInterval * m_iLightACKCount <= m_iPktCount) - { - //send a "light" ACK - sendCtrl(2, NULL, NULL, 4); - ++ m_iLightACKCount; - } - - // we are not sending back repeated NAK anymore and rely on the sender's EXP for retransmission - //if ((m_pRcvLossList->getLossLength() > 0) && (currtime > m_ullNextNAKTime)) - //{ - // // NAK timer expired, and there is loss to be reported. - // sendCtrl(3); - // - // CTimer::rdtsc(currtime); - // m_ullNextNAKTime = currtime + m_ullNAKInt; - //} - - uint64_t next_exp_time; - if (m_pCC->m_bUserDefinedRTO) - next_exp_time = m_ullLastRspTime + m_pCC->m_iRTO * m_ullCPUFrequency; - else - { - uint64_t exp_int = (m_iEXPCount * (m_iRTT + 4 * m_iRTTVar) + m_iSYNInterval) * m_ullCPUFrequency; - if (exp_int < m_iEXPCount * m_ullMinExpInt) - exp_int = m_iEXPCount * m_ullMinExpInt; - next_exp_time = m_ullLastRspTime + exp_int; - } - - if (currtime > next_exp_time) - { - // Haven't receive any information from the peer, is it dead?! - // timeout: at least 16 expirations and must be greater than 10 seconds - if ((m_iEXPCount > 16) && (currtime - m_ullLastRspTime > 5000000 * m_ullCPUFrequency)) - { - // - // Connection is broken. - // UDT does not signal any information about this instead of to stop quietly. - // Application will detect this when it calls any UDT methods next time. - // - m_bClosing = true; - m_bBroken = true; - m_iBrokenCounter = 30; - - // update snd U list to remove this socket - m_pSndQueue->m_pSndUList->update(this); - - releaseSynch(); - - // app can call any UDT API to learn the connection_broken error - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN | UDT_EPOLL_OUT | UDT_EPOLL_ERR, true); - - CTimer::triggerEvent(); - - return; - } - - // sender: Insert all the packets sent after last received acknowledgement into the sender loss list. - // recver: Send out a keep-alive packet - if (m_pSndBuffer->getCurrBufSize() > 0) - { - if ((CSeqNo::incseq(m_iSndCurrSeqNo) != m_iSndLastAck) && (m_pSndLossList->getLossLength() == 0)) - { - // resend all unacknowledged packets on timeout, but only if there is no packet in the loss list - int32_t csn = m_iSndCurrSeqNo; - int num = m_pSndLossList->insert(m_iSndLastAck, csn); - m_iTraceSndLoss += num; - m_iSndLossTotal += num; - } - - m_pCC->onTimeout(); - CCUpdate(); - - // immediately restart transmission - m_pSndQueue->m_pSndUList->update(this); - } - else - { - sendCtrl(1); - } - - ++ m_iEXPCount; - // Reset last response time since we just sent a heart-beat. - m_ullLastRspTime = currtime; - } -} - -void CUDT::addEPoll(const int eid) -{ - CGuard::enterCS(s_UDTUnited.m_EPoll.m_EPollLock); - m_sPollID.insert(eid); - CGuard::leaveCS(s_UDTUnited.m_EPoll.m_EPollLock); - - if (!m_bConnected || m_bBroken || m_bClosing) - return; - - if (((UDT_STREAM == m_iSockType) && (m_pRcvBuffer->getRcvDataSize() > 0)) || - ((UDT_DGRAM == m_iSockType) && (m_pRcvBuffer->getRcvMsgNum() > 0))) - { - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, true); - } - if (m_iSndBufSize > m_pSndBuffer->getCurrBufSize()) - { - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_OUT, true); - } -} - -void CUDT::removeEPoll(const int eid) -{ - // clear IO events notifications; - // since this happens after the epoll ID has been removed, they cannot be set again - set remove; - remove.insert(eid); - s_UDTUnited.m_EPoll.update_events(m_SocketID, remove, UDT_EPOLL_IN | UDT_EPOLL_OUT, false); - - CGuard::enterCS(s_UDTUnited.m_EPoll.m_EPollLock); - m_sPollID.erase(eid); - CGuard::leaveCS(s_UDTUnited.m_EPoll.m_EPollLock); -} diff --git a/vendor/udt4/src/core.h b/vendor/udt4/src/core.h deleted file mode 100644 index 47caa79..0000000 --- a/vendor/udt4/src/core.h +++ /dev/null @@ -1,458 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 02/28/2012 -*****************************************************************************/ - -#ifndef __UDT_CORE_H__ -#define __UDT_CORE_H__ - - -#include "udt.h" -#include "common.h" -#include "list.h" -#include "buffer.h" -#include "window.h" -#include "packet.h" -#include "channel.h" -#include "api.h" -#include "ccc.h" -#include "cache.h" -#include "queue.h" - -enum UDTSockType {UDT_STREAM = 1, UDT_DGRAM}; - -class CUDT -{ -friend class CUDTSocket; -friend class CUDTUnited; -friend class CCC; -friend struct CUDTComp; -friend class CCache; -friend class CRendezvousQueue; -friend class CSndQueue; -friend class CRcvQueue; -friend class CSndUList; -friend class CRcvUList; - -private: // constructor and desctructor - CUDT(); - CUDT(const CUDT& ancestor); - const CUDT& operator=(const CUDT&) {return *this;} - ~CUDT(); - -public: //API - static int startup(); - static int cleanup(); - static UDTSOCKET socket(int af, int type = SOCK_STREAM, int protocol = 0); - static int bind(UDTSOCKET u, const sockaddr* name, int namelen); - static int bind(UDTSOCKET u, UDPSOCKET udpsock); - static int listen(UDTSOCKET u, int backlog); - static UDTSOCKET accept(UDTSOCKET u, sockaddr* addr, int* addrlen); - static int connect(UDTSOCKET u, const sockaddr* name, int namelen); - static int close(UDTSOCKET u); - static int getpeername(UDTSOCKET u, sockaddr* name, int* namelen); - static int getsockname(UDTSOCKET u, sockaddr* name, int* namelen); - static int getsockopt(UDTSOCKET u, int level, UDTOpt optname, void* optval, int* optlen); - static int setsockopt(UDTSOCKET u, int level, UDTOpt optname, const void* optval, int optlen); - static int send(UDTSOCKET u, const char* buf, int len, int flags); - static int recv(UDTSOCKET u, char* buf, int len, int flags); - static int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false); - static int recvmsg(UDTSOCKET u, char* buf, int len); - static int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000); - static int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000); - static int select(int nfds, ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout); - static int selectEx(const std::vector& fds, std::vector* readfds, std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); - static int epoll_create(); - static int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events = NULL); - static int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); - static int epoll_remove_usock(const int eid, const UDTSOCKET u); - static int epoll_remove_ssock(const int eid, const SYSSOCKET s); - static int epoll_wait(const int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, std::set* lrfds = NULL, std::set* wrfds = NULL); - static int epoll_release(const int eid); - static CUDTException& getlasterror(); - static int perfmon(UDTSOCKET u, CPerfMon* perf, bool clear = true); - static UDTSTATUS getsockstate(UDTSOCKET u); - -public: // internal API - static CUDT* getUDTHandle(UDTSOCKET u); - -private: - // Functionality: - // initialize a UDT entity and bind to a local address. - // Parameters: - // None. - // Returned value: - // None. - - void open(); - - // Functionality: - // Start listening to any connection request. - // Parameters: - // None. - // Returned value: - // None. - - void listen(); - - // Functionality: - // Connect to a UDT entity listening at address "peer". - // Parameters: - // 0) [in] peer: The address of the listening UDT entity. - // Returned value: - // None. - - void connect(const sockaddr* peer); - - // Functionality: - // Process the response handshake packet. - // Parameters: - // 0) [in] pkt: handshake packet. - // Returned value: - // Return 0 if connected, positive value if connection is in progress, otherwise error code. - - int connect(const CPacket& pkt) throw (); - - // Functionality: - // Connect to a UDT entity listening at address "peer", which has sent "hs" request. - // Parameters: - // 0) [in] peer: The address of the listening UDT entity. - // 1) [in/out] hs: The handshake information sent by the peer side (in), negotiated value (out). - // Returned value: - // None. - - void connect(const sockaddr* peer, CHandShake* hs); - - // Functionality: - // Close the opened UDT entity. - // Parameters: - // None. - // Returned value: - // None. - - void close(); - - // Functionality: - // Request UDT to send out a data block "data" with size of "len". - // Parameters: - // 0) [in] data: The address of the application data to be sent. - // 1) [in] len: The size of the data block. - // Returned value: - // Actual size of data sent. - - int send(const char* data, int len); - - // Functionality: - // Request UDT to receive data to a memory block "data" with size of "len". - // Parameters: - // 0) [out] data: data received. - // 1) [in] len: The desired size of data to be received. - // Returned value: - // Actual size of data received. - - int recv(char* data, int len); - - // Functionality: - // send a message of a memory block "data" with size of "len". - // Parameters: - // 0) [out] data: data received. - // 1) [in] len: The desired size of data to be received. - // 2) [in] ttl: the time-to-live of the message. - // 3) [in] inorder: if the message should be delivered in order. - // Returned value: - // Actual size of data sent. - - int sendmsg(const char* data, int len, int ttl, bool inorder); - - // Functionality: - // Receive a message to buffer "data". - // Parameters: - // 0) [out] data: data received. - // 1) [in] len: size of the buffer. - // Returned value: - // Actual size of data received. - - int recvmsg(char* data, int len); - - // Functionality: - // Request UDT to send out a file described as "fd", starting from "offset", with size of "size". - // Parameters: - // 0) [in] ifs: The input file stream. - // 1) [in, out] offset: From where to read and send data; output is the new offset when the call returns. - // 2) [in] size: How many data to be sent. - // 3) [in] block: size of block per read from disk - // Returned value: - // Actual size of data sent. - - int64_t sendfile(std::fstream& ifs, int64_t& offset, int64_t size, int block = 366000); - - // Functionality: - // Request UDT to receive data into a file described as "fd", starting from "offset", with expected size of "size". - // Parameters: - // 0) [out] ofs: The output file stream. - // 1) [in, out] offset: From where to write data; output is the new offset when the call returns. - // 2) [in] size: How many data to be received. - // 3) [in] block: size of block per write to disk - // Returned value: - // Actual size of data received. - - int64_t recvfile(std::fstream& ofs, int64_t& offset, int64_t size, int block = 7320000); - - // Functionality: - // Configure UDT options. - // Parameters: - // 0) [in] optName: The enum name of a UDT option. - // 1) [in] optval: The value to be set. - // 2) [in] optlen: size of "optval". - // Returned value: - // None. - - void setOpt(UDTOpt optName, const void* optval, int optlen); - - // Functionality: - // Read UDT options. - // Parameters: - // 0) [in] optName: The enum name of a UDT option. - // 1) [in] optval: The value to be returned. - // 2) [out] optlen: size of "optval". - // Returned value: - // None. - - void getOpt(UDTOpt optName, void* optval, int& optlen); - - // Functionality: - // read the performance data since last sample() call. - // Parameters: - // 0) [in, out] perf: pointer to a CPerfMon structure to record the performance data. - // 1) [in] clear: flag to decide if the local performance trace should be cleared. - // Returned value: - // None. - - void sample(CPerfMon* perf, bool clear = true); - -private: - static CUDTUnited s_UDTUnited; // UDT global management base - -public: - static const UDTSOCKET INVALID_SOCK; // invalid socket descriptor - static const int ERROR; // socket api error returned value - -private: // Identification - UDTSOCKET m_SocketID; // UDT socket number - UDTSockType m_iSockType; // Type of the UDT connection (SOCK_STREAM or SOCK_DGRAM) - UDTSOCKET m_PeerID; // peer id, for multiplexer - static const int m_iVersion; // UDT version, for compatibility use - -private: // Packet sizes - int m_iPktSize; // Maximum/regular packet size, in bytes - int m_iPayloadSize; // Maximum/regular payload size, in bytes - -private: // Options - int m_iMSS; // Maximum Segment Size, in bytes - bool m_bSynSending; // Sending syncronization mode - bool m_bSynRecving; // Receiving syncronization mode - int m_iFlightFlagSize; // Maximum number of packets in flight from the peer side - int m_iSndBufSize; // Maximum UDT sender buffer size - int m_iRcvBufSize; // Maximum UDT receiver buffer size - linger m_Linger; // Linger information on close - int m_iUDPSndBufSize; // UDP sending buffer size - int m_iUDPRcvBufSize; // UDP receiving buffer size - int m_iIPversion; // IP version - bool m_bRendezvous; // Rendezvous connection mode - int m_iSndTimeOut; // sending timeout in milliseconds - int m_iRcvTimeOut; // receiving timeout in milliseconds - bool m_bReuseAddr; // reuse an exiting port or not, for UDP multiplexer - int64_t m_llMaxBW; // maximum data transfer rate (threshold) - -private: // congestion control - CCCVirtualFactory* m_pCCFactory; // Factory class to create a specific CC instance - CCC* m_pCC; // congestion control class - CCache* m_pCache; // network information cache - -private: // Status - volatile bool m_bListening; // If the UDT entit is listening to connection - volatile bool m_bConnecting; // The short phase when connect() is called but not yet completed - volatile bool m_bConnected; // Whether the connection is on or off - volatile bool m_bClosing; // If the UDT entity is closing - volatile bool m_bShutdown; // If the peer side has shutdown the connection - volatile bool m_bBroken; // If the connection has been broken - volatile bool m_bPeerHealth; // If the peer status is normal - bool m_bOpened; // If the UDT entity has been opened - int m_iBrokenCounter; // a counter (number of GC checks) to let the GC tag this socket as disconnected - - int m_iEXPCount; // Expiration counter - int m_iBandwidth; // Estimated bandwidth, number of packets per second - int m_iRTT; // RTT, in microseconds - int m_iRTTVar; // RTT variance - int m_iDeliveryRate; // Packet arrival rate at the receiver side - - uint64_t m_ullLingerExpiration; // Linger expiration time (for GC to close a socket with data in sending buffer) - - CHandShake m_ConnReq; // connection request - CHandShake m_ConnRes; // connection response - int64_t m_llLastReqTime; // last time when a connection request is sent - -private: // Sending related data - CSndBuffer* m_pSndBuffer; // Sender buffer - CSndLossList* m_pSndLossList; // Sender loss list - CPktTimeWindow* m_pSndTimeWindow; // Packet sending time window - - volatile uint64_t m_ullInterval; // Inter-packet time, in CPU clock cycles - uint64_t m_ullTimeDiff; // aggregate difference in inter-packet time - - volatile int m_iFlowWindowSize; // Flow control window size - volatile double m_dCongestionWindow; // congestion window size - - volatile int32_t m_iSndLastAck; // Last ACK received - volatile int32_t m_iSndLastDataAck; // The real last ACK that updates the sender buffer and loss list - volatile int32_t m_iSndCurrSeqNo; // The largest sequence number that has been sent - int32_t m_iLastDecSeq; // Sequence number sent last decrease occurs - int32_t m_iSndLastAck2; // Last ACK2 sent back - uint64_t m_ullSndLastAck2Time; // The time when last ACK2 was sent back - - int32_t m_iISN; // Initial Sequence Number - - void CCUpdate(); - -private: // Receiving related data - CRcvBuffer* m_pRcvBuffer; // Receiver buffer - CRcvLossList* m_pRcvLossList; // Receiver loss list - CACKWindow* m_pACKWindow; // ACK history window - CPktTimeWindow* m_pRcvTimeWindow; // Packet arrival time window - - int32_t m_iRcvLastAck; // Last sent ACK - uint64_t m_ullLastAckTime; // Timestamp of last ACK - int32_t m_iRcvLastAckAck; // Last sent ACK that has been acknowledged - int32_t m_iAckSeqNo; // Last ACK sequence number - int32_t m_iRcvCurrSeqNo; // Largest received sequence number - - uint64_t m_ullLastWarningTime; // Last time that a warning message is sent - - int32_t m_iPeerISN; // Initial Sequence Number of the peer side - -private: // synchronization: mutexes and conditions - pthread_mutex_t m_ConnectionLock; // used to synchronize connection operation - - pthread_cond_t m_SendBlockCond; // used to block "send" call - pthread_mutex_t m_SendBlockLock; // lock associated to m_SendBlockCond - - pthread_mutex_t m_AckLock; // used to protected sender's loss list when processing ACK - - pthread_cond_t m_RecvDataCond; // used to block "recv" when there is no data - pthread_mutex_t m_RecvDataLock; // lock associated to m_RecvDataCond - - pthread_mutex_t m_SendLock; // used to synchronize "send" call - pthread_mutex_t m_RecvLock; // used to synchronize "recv" call - - void initSynch(); - void destroySynch(); - void releaseSynch(); - -private: // Generation and processing of packets - void sendCtrl(int pkttype, void* lparam = NULL, void* rparam = NULL, int size = 0); - void processCtrl(CPacket& ctrlpkt); - int packData(CPacket& packet, uint64_t& ts); - int processData(CUnit* unit); - int listen(sockaddr* addr, CPacket& packet); - -private: // Trace - uint64_t m_StartTime; // timestamp when the UDT entity is started - int64_t m_llSentTotal; // total number of sent data packets, including retransmissions - int64_t m_llRecvTotal; // total number of received packets - int m_iSndLossTotal; // total number of lost packets (sender side) - int m_iRcvLossTotal; // total number of lost packets (receiver side) - int m_iRetransTotal; // total number of retransmitted packets - int m_iSentACKTotal; // total number of sent ACK packets - int m_iRecvACKTotal; // total number of received ACK packets - int m_iSentNAKTotal; // total number of sent NAK packets - int m_iRecvNAKTotal; // total number of received NAK packets - int64_t m_llSndDurationTotal; // total real time for sending - - uint64_t m_LastSampleTime; // last performance sample time - int64_t m_llTraceSent; // number of pakctes sent in the last trace interval - int64_t m_llTraceRecv; // number of pakctes received in the last trace interval - int m_iTraceSndLoss; // number of lost packets in the last trace interval (sender side) - int m_iTraceRcvLoss; // number of lost packets in the last trace interval (receiver side) - int m_iTraceRetrans; // number of retransmitted packets in the last trace interval - int m_iSentACK; // number of ACKs sent in the last trace interval - int m_iRecvACK; // number of ACKs received in the last trace interval - int m_iSentNAK; // number of NAKs sent in the last trace interval - int m_iRecvNAK; // number of NAKs received in the last trace interval - int64_t m_llSndDuration; // real time for sending - int64_t m_llSndDurationCounter; // timers to record the sending duration - -private: // Timers - uint64_t m_ullCPUFrequency; // CPU clock frequency, used for Timer, ticks per microsecond - - static const int m_iSYNInterval; // Periodical Rate Control Interval, 10000 microsecond - static const int m_iSelfClockInterval; // ACK interval for self-clocking - - uint64_t m_ullNextACKTime; // Next ACK time, in CPU clock cycles, same below - uint64_t m_ullNextNAKTime; // Next NAK time - - volatile uint64_t m_ullSYNInt; // SYN interval - volatile uint64_t m_ullACKInt; // ACK interval - volatile uint64_t m_ullNAKInt; // NAK interval - volatile uint64_t m_ullLastRspTime; // time stamp of last response from the peer - - uint64_t m_ullMinNakInt; // NAK timeout lower bound; too small value can cause unnecessary retransmission - uint64_t m_ullMinExpInt; // timeout lower bound threshold: too small timeout can cause problem - - int m_iPktCount; // packet counter for ACK - int m_iLightACKCount; // light ACK counter - - uint64_t m_ullTargetTime; // scheduled time of next packet sending - - void checkTimers(); - -private: // for UDP multiplexer - CSndQueue* m_pSndQueue; // packet sending queue - CRcvQueue* m_pRcvQueue; // packet receiving queue - sockaddr* m_pPeerAddr; // peer address - uint32_t m_piSelfIP[4]; // local UDP IP address - CSNode* m_pSNode; // node information for UDT list used in snd queue - CRNode* m_pRNode; // node information for UDT list used in rcv queue - -private: // for epoll - std::set m_sPollID; // set of epoll ID to trigger - void addEPoll(const int eid); - void removeEPoll(const int eid); -}; - - -#endif diff --git a/vendor/udt4/src/epoll.cpp b/vendor/udt4/src/epoll.cpp deleted file mode 100644 index 0e7ddb1..0000000 --- a/vendor/udt4/src/epoll.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/01/2011 -*****************************************************************************/ - -#ifdef LINUX - #include - #include -#endif -#include -#include -#include -#include - -#include "common.h" -#include "epoll.h" -#include "udt.h" - -using namespace std; - -CEPoll::CEPoll(): -m_iIDSeed(0) -{ - CGuard::createMutex(m_EPollLock); -} - -CEPoll::~CEPoll() -{ - CGuard::releaseMutex(m_EPollLock); -} - -int CEPoll::create() -{ - CGuard pg(m_EPollLock); - - int localid = 0; - - #ifdef LINUX - localid = epoll_create(1024); - if (localid < 0) - throw CUDTException(-1, 0, errno); - #else - // on BSD, use kqueue - // on Solaris, use /dev/poll - // on Windows, select - #endif - - if (++ m_iIDSeed >= 0x7FFFFFFF) - m_iIDSeed = 0; - - CEPollDesc desc; - desc.m_iID = m_iIDSeed; - desc.m_iLocalID = localid; - m_mPolls[desc.m_iID] = desc; - - return desc.m_iID; -} - -int CEPoll::add_usock(const int eid, const UDTSOCKET& u, const int* events) -{ - CGuard pg(m_EPollLock); - - map::iterator p = m_mPolls.find(eid); - if (p == m_mPolls.end()) - throw CUDTException(5, 13); - - if (!events || (*events & UDT_EPOLL_IN)) - p->second.m_sUDTSocksIn.insert(u); - if (!events || (*events & UDT_EPOLL_OUT)) - p->second.m_sUDTSocksOut.insert(u); - - return 0; -} - -int CEPoll::add_ssock(const int eid, const SYSSOCKET& s, const int* events) -{ - CGuard pg(m_EPollLock); - - map::iterator p = m_mPolls.find(eid); - if (p == m_mPolls.end()) - throw CUDTException(5, 13); - -#ifdef LINUX - epoll_event ev; - memset(&ev, 0, sizeof(epoll_event)); - - if (NULL == events) - ev.events = EPOLLIN | EPOLLOUT | EPOLLERR; - else - { - ev.events = 0; - if (*events & UDT_EPOLL_IN) - ev.events |= EPOLLIN; - if (*events & UDT_EPOLL_OUT) - ev.events |= EPOLLOUT; - if (*events & UDT_EPOLL_ERR) - ev.events |= EPOLLERR; - } - - ev.data.fd = s; - if (::epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_ADD, s, &ev) < 0) - throw CUDTException(); -#endif - - p->second.m_sLocals.insert(s); - - return 0; -} - -int CEPoll::remove_usock(const int eid, const UDTSOCKET& u) -{ - CGuard pg(m_EPollLock); - - map::iterator p = m_mPolls.find(eid); - if (p == m_mPolls.end()) - throw CUDTException(5, 13); - - p->second.m_sUDTSocksIn.erase(u); - p->second.m_sUDTSocksOut.erase(u); - p->second.m_sUDTSocksEx.erase(u); - - return 0; -} - -int CEPoll::remove_ssock(const int eid, const SYSSOCKET& s) -{ - CGuard pg(m_EPollLock); - - map::iterator p = m_mPolls.find(eid); - if (p == m_mPolls.end()) - throw CUDTException(5, 13); - -#ifdef LINUX - epoll_event ev; // ev is ignored, for compatibility with old Linux kernel only. - if (::epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_DEL, s, &ev) < 0) - throw CUDTException(); -#endif - - p->second.m_sLocals.erase(s); - - return 0; -} - -int CEPoll::wait(const int eid, set* readfds, set* writefds, int64_t msTimeOut, set* lrfds, set* lwfds) -{ - // if all fields is NULL and waiting time is infinite, then this would be a deadlock - if (!readfds && !writefds && !lrfds && lwfds && (msTimeOut < 0)) - throw CUDTException(5, 3, 0); - - // Clear these sets in case the app forget to do it. - if (readfds) readfds->clear(); - if (writefds) writefds->clear(); - if (lrfds) lrfds->clear(); - if (lwfds) lwfds->clear(); - - int total = 0; - - int64_t entertime = CTimer::getTime(); - while (true) - { - CGuard::enterCS(m_EPollLock); - - map::iterator p = m_mPolls.find(eid); - if (p == m_mPolls.end()) - { - CGuard::leaveCS(m_EPollLock); - throw CUDTException(5, 13); - } - - if (p->second.m_sUDTSocksIn.empty() && p->second.m_sUDTSocksOut.empty() && p->second.m_sLocals.empty() && (msTimeOut < 0)) - { - // no socket is being monitored, this may be a deadlock - CGuard::leaveCS(m_EPollLock); - throw CUDTException(5, 3); - } - - // Sockets with exceptions are returned to both read and write sets. - if ((NULL != readfds) && (!p->second.m_sUDTReads.empty() || !p->second.m_sUDTExcepts.empty())) - { - *readfds = p->second.m_sUDTReads; - for (set::const_iterator i = p->second.m_sUDTExcepts.begin(); i != p->second.m_sUDTExcepts.end(); ++ i) - readfds->insert(*i); - total += p->second.m_sUDTReads.size() + p->second.m_sUDTExcepts.size(); - } - if ((NULL != writefds) && (!p->second.m_sUDTWrites.empty() || !p->second.m_sUDTExcepts.empty())) - { - *writefds = p->second.m_sUDTWrites; - for (set::const_iterator i = p->second.m_sUDTExcepts.begin(); i != p->second.m_sUDTExcepts.end(); ++ i) - writefds->insert(*i); - total += p->second.m_sUDTWrites.size() + p->second.m_sUDTExcepts.size(); - } - - if (lrfds || lwfds) - { - #ifdef LINUX - const int max_events = p->second.m_sLocals.size(); - epoll_event ev[max_events]; - int nfds = ::epoll_wait(p->second.m_iLocalID, ev, max_events, 0); - - for (int i = 0; i < nfds; ++ i) - { - if ((NULL != lrfds) && (ev[i].events & EPOLLIN)) - { - lrfds->insert(ev[i].data.fd); - ++ total; - } - if ((NULL != lwfds) && (ev[i].events & EPOLLOUT)) - { - lwfds->insert(ev[i].data.fd); - ++ total; - } - } - #else - //currently "select" is used for all non-Linux platforms. - //faster approaches can be applied for specific systems in the future. - - //"select" has a limitation on the number of sockets - - fd_set readfds; - fd_set writefds; - FD_ZERO(&readfds); - FD_ZERO(&writefds); - - for (set::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i) - { - if (lrfds) - FD_SET(*i, &readfds); - if (lwfds) - FD_SET(*i, &writefds); - } - - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - if (::select(0, &readfds, &writefds, NULL, &tv) > 0) - { - for (set::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i) - { - if (lrfds && FD_ISSET(*i, &readfds)) - { - lrfds->insert(*i); - ++ total; - } - if (lwfds && FD_ISSET(*i, &writefds)) - { - lwfds->insert(*i); - ++ total; - } - } - } - #endif - } - - CGuard::leaveCS(m_EPollLock); - - if (total > 0) - return total; - - if ((msTimeOut >= 0) && (int64_t(CTimer::getTime() - entertime) >= msTimeOut * 1000LL)) - throw CUDTException(6, 3, 0); - - CTimer::waitForEvent(); - } - - return 0; -} - -int CEPoll::release(const int eid) -{ - CGuard pg(m_EPollLock); - - map::iterator i = m_mPolls.find(eid); - if (i == m_mPolls.end()) - throw CUDTException(5, 13); - - #ifdef LINUX - // release local/system epoll descriptor - ::close(i->second.m_iLocalID); - #endif - - m_mPolls.erase(i); - - return 0; -} - -namespace -{ - -void update_epoll_sets(const UDTSOCKET& uid, const set& watch, set& result, bool enable) -{ - if (enable && (watch.find(uid) != watch.end())) - { - result.insert(uid); - } - else if (!enable) - { - result.erase(uid); - } -} - -} // namespace - -int CEPoll::update_events(const UDTSOCKET& uid, std::set& eids, int events, bool enable) -{ - CGuard pg(m_EPollLock); - - map::iterator p; - - vector lost; - for (set::iterator i = eids.begin(); i != eids.end(); ++ i) - { - p = m_mPolls.find(*i); - if (p == m_mPolls.end()) - { - lost.push_back(*i); - } - else - { - if ((events & UDT_EPOLL_IN) != 0) - update_epoll_sets(uid, p->second.m_sUDTSocksIn, p->second.m_sUDTReads, enable); - if ((events & UDT_EPOLL_OUT) != 0) - update_epoll_sets(uid, p->second.m_sUDTSocksOut, p->second.m_sUDTWrites, enable); - if ((events & UDT_EPOLL_ERR) != 0) - update_epoll_sets(uid, p->second.m_sUDTSocksEx, p->second.m_sUDTExcepts, enable); - } - } - - for (vector::iterator i = lost.begin(); i != lost.end(); ++ i) - eids.erase(*i); - - return 0; -} diff --git a/vendor/udt4/src/epoll.h b/vendor/udt4/src/epoll.h deleted file mode 100644 index a19f8ab..0000000 --- a/vendor/udt4/src/epoll.h +++ /dev/null @@ -1,173 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 08/20/2010 -*****************************************************************************/ - -#ifndef __UDT_EPOLL_H__ -#define __UDT_EPOLL_H__ - - -#include -#include -#include "udt.h" - - -struct CEPollDesc -{ - int m_iID; // epoll ID - std::set m_sUDTSocksOut; // set of UDT sockets waiting for write events - std::set m_sUDTSocksIn; // set of UDT sockets waiting for read events - std::set m_sUDTSocksEx; // set of UDT sockets waiting for exceptions - - int m_iLocalID; // local system epoll ID - std::set m_sLocals; // set of local (non-UDT) descriptors - - std::set m_sUDTWrites; // UDT sockets ready for write - std::set m_sUDTReads; // UDT sockets ready for read - std::set m_sUDTExcepts; // UDT sockets with exceptions (connection broken, etc.) -}; - -class CEPoll -{ -friend class CUDT; -friend class CRendezvousQueue; - -public: - CEPoll(); - ~CEPoll(); - -public: // for CUDTUnited API - - // Functionality: - // create a new EPoll. - // Parameters: - // None. - // Returned value: - // new EPoll ID if success, otherwise an error number. - - int create(); - - // Functionality: - // add a UDT socket to an EPoll. - // Parameters: - // 0) [in] eid: EPoll ID. - // 1) [in] u: UDT Socket ID. - // 2) [in] events: events to watch. - // Returned value: - // 0 if success, otherwise an error number. - - int add_usock(const int eid, const UDTSOCKET& u, const int* events = NULL); - - // Functionality: - // add a system socket to an EPoll. - // Parameters: - // 0) [in] eid: EPoll ID. - // 1) [in] s: system Socket ID. - // 2) [in] events: events to watch. - // Returned value: - // 0 if success, otherwise an error number. - - int add_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL); - - // Functionality: - // remove a UDT socket event from an EPoll; socket will be removed if no events to watch - // Parameters: - // 0) [in] eid: EPoll ID. - // 1) [in] u: UDT socket ID. - // Returned value: - // 0 if success, otherwise an error number. - - int remove_usock(const int eid, const UDTSOCKET& u); - - // Functionality: - // remove a system socket event from an EPoll; socket will be removed if no events to watch - // Parameters: - // 0) [in] eid: EPoll ID. - // 1) [in] s: system socket ID. - // Returned value: - // 0 if success, otherwise an error number. - - int remove_ssock(const int eid, const SYSSOCKET& s); - - // Functionality: - // wait for EPoll events or timeout. - // Parameters: - // 0) [in] eid: EPoll ID. - // 1) [out] readfds: UDT sockets available for reading. - // 2) [out] writefds: UDT sockets available for writing. - // 3) [in] msTimeOut: timeout threshold, in milliseconds. - // 4) [out] lrfds: system file descriptors for reading. - // 5) [out] lwfds: system file descriptors for writing. - // Returned value: - // number of sockets available for IO. - - int wait(const int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, std::set* lrfds, std::set* lwfds); - - // Functionality: - // close and release an EPoll. - // Parameters: - // 0) [in] eid: EPoll ID. - // Returned value: - // 0 if success, otherwise an error number. - - int release(const int eid); - -public: // for CUDT to acknowledge IO status - - // Functionality: - // Update events available for a UDT socket. - // Parameters: - // 0) [in] uid: UDT socket ID. - // 1) [in] eids: EPoll IDs to be set - // 1) [in] events: Combination of events to update - // 1) [in] enable: true -> enable, otherwise disable - // Returned value: - // 0 if success, otherwise an error number - - int update_events(const UDTSOCKET& uid, std::set& eids, int events, bool enable); - -private: - int m_iIDSeed; // seed to generate a new ID - pthread_mutex_t m_SeedLock; - - std::map m_mPolls; // all epolls - pthread_mutex_t m_EPollLock; -}; - - -#endif diff --git a/vendor/udt4/src/list.cpp b/vendor/udt4/src/list.cpp deleted file mode 100644 index 00b7e57..0000000 --- a/vendor/udt4/src/list.cpp +++ /dev/null @@ -1,703 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/22/2011 -*****************************************************************************/ - -#include "list.h" - -CSndLossList::CSndLossList(int size): -m_piData1(NULL), -m_piData2(NULL), -m_piNext(NULL), -m_iHead(-1), -m_iLength(0), -m_iSize(size), -m_iLastInsertPos(-1), -m_ListLock() -{ - m_piData1 = new int32_t [m_iSize]; - m_piData2 = new int32_t [m_iSize]; - m_piNext = new int [m_iSize]; - - // -1 means there is no data in the node - for (int i = 0; i < size; ++ i) - { - m_piData1[i] = -1; - m_piData2[i] = -1; - } - - // sender list needs mutex protection - #ifndef WIN32 - pthread_mutex_init(&m_ListLock, 0); - #else - m_ListLock = CreateMutex(NULL, false, NULL); - #endif -} - -CSndLossList::~CSndLossList() -{ - delete [] m_piData1; - delete [] m_piData2; - delete [] m_piNext; - - #ifndef WIN32 - pthread_mutex_destroy(&m_ListLock); - #else - CloseHandle(m_ListLock); - #endif -} - -int CSndLossList::insert(int32_t seqno1, int32_t seqno2) -{ - CGuard listguard(m_ListLock); - - if (0 == m_iLength) - { - // insert data into an empty list - - m_iHead = 0; - m_piData1[m_iHead] = seqno1; - if (seqno2 != seqno1) - m_piData2[m_iHead] = seqno2; - - m_piNext[m_iHead] = -1; - m_iLastInsertPos = m_iHead; - - m_iLength += CSeqNo::seqlen(seqno1, seqno2); - - return m_iLength; - } - - // otherwise find the position where the data can be inserted - int origlen = m_iLength; - int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1); - int loc = (m_iHead + offset + m_iSize) % m_iSize; - - if (offset < 0) - { - // Insert data prior to the head pointer - - m_piData1[loc] = seqno1; - if (seqno2 != seqno1) - m_piData2[loc] = seqno2; - - // new node becomes head - m_piNext[loc] = m_iHead; - m_iHead = loc; - m_iLastInsertPos = loc; - - m_iLength += CSeqNo::seqlen(seqno1, seqno2); - } - else if (offset > 0) - { - if (seqno1 == m_piData1[loc]) - { - m_iLastInsertPos = loc; - - // first seqno is equivlent, compare the second - if (-1 == m_piData2[loc]) - { - if (seqno2 != seqno1) - { - m_iLength += CSeqNo::seqlen(seqno1, seqno2) - 1; - m_piData2[loc] = seqno2; - } - } - else if (CSeqNo::seqcmp(seqno2, m_piData2[loc]) > 0) - { - // new seq pair is longer than old pair, e.g., insert [3, 7] to [3, 5], becomes [3, 7] - m_iLength += CSeqNo::seqlen(m_piData2[loc], seqno2) - 1; - m_piData2[loc] = seqno2; - } - else - // Do nothing if it is already there - return 0; - } - else - { - // searching the prior node - int i; - if ((-1 != m_iLastInsertPos) && (CSeqNo::seqcmp(m_piData1[m_iLastInsertPos], seqno1) < 0)) - i = m_iLastInsertPos; - else - i = m_iHead; - - while ((-1 != m_piNext[i]) && (CSeqNo::seqcmp(m_piData1[m_piNext[i]], seqno1) < 0)) - i = m_piNext[i]; - - if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(m_piData2[i], seqno1) < 0)) - { - m_iLastInsertPos = loc; - - // no overlap, create new node - m_piData1[loc] = seqno1; - if (seqno2 != seqno1) - m_piData2[loc] = seqno2; - - m_piNext[loc] = m_piNext[i]; - m_piNext[i] = loc; - - m_iLength += CSeqNo::seqlen(seqno1, seqno2); - } - else - { - m_iLastInsertPos = i; - - // overlap, coalesce with prior node, insert(3, 7) to [2, 5], ... becomes [2, 7] - if (CSeqNo::seqcmp(m_piData2[i], seqno2) < 0) - { - m_iLength += CSeqNo::seqlen(m_piData2[i], seqno2) - 1; - m_piData2[i] = seqno2; - - loc = i; - } - else - return 0; - } - } - } - else - { - m_iLastInsertPos = m_iHead; - - // insert to head node - if (seqno2 != seqno1) - { - if (-1 == m_piData2[loc]) - { - m_iLength += CSeqNo::seqlen(seqno1, seqno2) - 1; - m_piData2[loc] = seqno2; - } - else if (CSeqNo::seqcmp(seqno2, m_piData2[loc]) > 0) - { - m_iLength += CSeqNo::seqlen(m_piData2[loc], seqno2) - 1; - m_piData2[loc] = seqno2; - } - else - return 0; - } - else - return 0; - } - - // coalesce with next node. E.g., [3, 7], ..., [6, 9] becomes [3, 9] - while ((-1 != m_piNext[loc]) && (-1 != m_piData2[loc])) - { - int i = m_piNext[loc]; - - if (CSeqNo::seqcmp(m_piData1[i], CSeqNo::incseq(m_piData2[loc])) <= 0) - { - // coalesce if there is overlap - if (-1 != m_piData2[i]) - { - if (CSeqNo::seqcmp(m_piData2[i], m_piData2[loc]) > 0) - { - if (CSeqNo::seqcmp(m_piData2[loc], m_piData1[i]) >= 0) - m_iLength -= CSeqNo::seqlen(m_piData1[i], m_piData2[loc]); - - m_piData2[loc] = m_piData2[i]; - } - else - m_iLength -= CSeqNo::seqlen(m_piData1[i], m_piData2[i]); - } - else - { - if (m_piData1[i] == CSeqNo::incseq(m_piData2[loc])) - m_piData2[loc] = m_piData1[i]; - else - m_iLength --; - } - - m_piData1[i] = -1; - m_piData2[i] = -1; - m_piNext[loc] = m_piNext[i]; - } - else - break; - } - - return m_iLength - origlen; -} - -void CSndLossList::remove(int32_t seqno) -{ - CGuard listguard(m_ListLock); - - if (0 == m_iLength) - return; - - // Remove all from the head pointer to a node with a larger seq. no. or the list is empty - int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno); - int loc = (m_iHead + offset + m_iSize) % m_iSize; - - if (0 == offset) - { - // It is the head. Remove the head and point to the next node - loc = (loc + 1) % m_iSize; - - if (-1 == m_piData2[m_iHead]) - loc = m_piNext[m_iHead]; - else - { - m_piData1[loc] = CSeqNo::incseq(seqno); - if (CSeqNo::seqcmp(m_piData2[m_iHead], CSeqNo::incseq(seqno)) > 0) - m_piData2[loc] = m_piData2[m_iHead]; - - m_piData2[m_iHead] = -1; - - m_piNext[loc] = m_piNext[m_iHead]; - } - - m_piData1[m_iHead] = -1; - - if (m_iLastInsertPos == m_iHead) - m_iLastInsertPos = -1; - - m_iHead = loc; - - m_iLength --; - } - else if (offset > 0) - { - int h = m_iHead; - - if (seqno == m_piData1[loc]) - { - // target node is not empty, remove part/all of the seqno in the node. - int temp = loc; - loc = (loc + 1) % m_iSize; - - if (-1 == m_piData2[temp]) - m_iHead = m_piNext[temp]; - else - { - // remove part, e.g., [3, 7] becomes [], [4, 7] after remove(3) - m_piData1[loc] = CSeqNo::incseq(seqno); - if (CSeqNo::seqcmp(m_piData2[temp], m_piData1[loc]) > 0) - m_piData2[loc] = m_piData2[temp]; - m_iHead = loc; - m_piNext[loc] = m_piNext[temp]; - m_piNext[temp] = loc; - m_piData2[temp] = -1; - } - } - else - { - // target node is empty, check prior node - int i = m_iHead; - while ((-1 != m_piNext[i]) && (CSeqNo::seqcmp(m_piData1[m_piNext[i]], seqno) < 0)) - i = m_piNext[i]; - - loc = (loc + 1) % m_iSize; - - if (-1 == m_piData2[i]) - m_iHead = m_piNext[i]; - else if (CSeqNo::seqcmp(m_piData2[i], seqno) > 0) - { - // remove part/all seqno in the prior node - m_piData1[loc] = CSeqNo::incseq(seqno); - if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0) - m_piData2[loc] = m_piData2[i]; - - m_piData2[i] = seqno; - - m_piNext[loc] = m_piNext[i]; - m_piNext[i] = loc; - - m_iHead = loc; - } - else - m_iHead = m_piNext[i]; - } - - // Remove all nodes prior to the new head - while (h != m_iHead) - { - if (m_piData2[h] != -1) - { - m_iLength -= CSeqNo::seqlen(m_piData1[h], m_piData2[h]); - m_piData2[h] = -1; - } - else - m_iLength --; - - m_piData1[h] = -1; - - if (m_iLastInsertPos == h) - m_iLastInsertPos = -1; - - h = m_piNext[h]; - } - } -} - -int CSndLossList::getLossLength() -{ - CGuard listguard(m_ListLock); - - return m_iLength; -} - -int32_t CSndLossList::getLostSeq() -{ - if (0 == m_iLength) - return -1; - - CGuard listguard(m_ListLock); - - if (0 == m_iLength) - return -1; - - if (m_iLastInsertPos == m_iHead) - m_iLastInsertPos = -1; - - // return the first loss seq. no. - int32_t seqno = m_piData1[m_iHead]; - - // head moves to the next node - if (-1 == m_piData2[m_iHead]) - { - //[3, -1] becomes [], and head moves to next node in the list - m_piData1[m_iHead] = -1; - m_iHead = m_piNext[m_iHead]; - } - else - { - // shift to next node, e.g., [3, 7] becomes [], [4, 7] - int loc = (m_iHead + 1) % m_iSize; - - m_piData1[loc] = CSeqNo::incseq(seqno); - if (CSeqNo::seqcmp(m_piData2[m_iHead], m_piData1[loc]) > 0) - m_piData2[loc] = m_piData2[m_iHead]; - - m_piData1[m_iHead] = -1; - m_piData2[m_iHead] = -1; - - m_piNext[loc] = m_piNext[m_iHead]; - m_iHead = loc; - } - - m_iLength --; - - return seqno; -} - -//////////////////////////////////////////////////////////////////////////////// - -CRcvLossList::CRcvLossList(int size): -m_piData1(NULL), -m_piData2(NULL), -m_piNext(NULL), -m_piPrior(NULL), -m_iHead(-1), -m_iTail(-1), -m_iLength(0), -m_iSize(size) -{ - m_piData1 = new int32_t [m_iSize]; - m_piData2 = new int32_t [m_iSize]; - m_piNext = new int [m_iSize]; - m_piPrior = new int [m_iSize]; - - // -1 means there is no data in the node - for (int i = 0; i < size; ++ i) - { - m_piData1[i] = -1; - m_piData2[i] = -1; - } -} - -CRcvLossList::~CRcvLossList() -{ - delete [] m_piData1; - delete [] m_piData2; - delete [] m_piNext; - delete [] m_piPrior; -} - -void CRcvLossList::insert(int32_t seqno1, int32_t seqno2) -{ - // Data to be inserted must be larger than all those in the list - // guaranteed by the UDT receiver - - if (0 == m_iLength) - { - // insert data into an empty list - m_iHead = 0; - m_iTail = 0; - m_piData1[m_iHead] = seqno1; - if (seqno2 != seqno1) - m_piData2[m_iHead] = seqno2; - - m_piNext[m_iHead] = -1; - m_piPrior[m_iHead] = -1; - m_iLength += CSeqNo::seqlen(seqno1, seqno2); - - return; - } - - // otherwise searching for the position where the node should be - int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno1); - int loc = (m_iHead + offset) % m_iSize; - - if ((-1 != m_piData2[m_iTail]) && (CSeqNo::incseq(m_piData2[m_iTail]) == seqno1)) - { - // coalesce with prior node, e.g., [2, 5], [6, 7] becomes [2, 7] - loc = m_iTail; - m_piData2[loc] = seqno2; - } - else - { - // create new node - m_piData1[loc] = seqno1; - - if (seqno2 != seqno1) - m_piData2[loc] = seqno2; - - m_piNext[m_iTail] = loc; - m_piPrior[loc] = m_iTail; - m_piNext[loc] = -1; - m_iTail = loc; - } - - m_iLength += CSeqNo::seqlen(seqno1, seqno2); -} - -bool CRcvLossList::remove(int32_t seqno) -{ - if (0 == m_iLength) - return false; - - // locate the position of "seqno" in the list - int offset = CSeqNo::seqoff(m_piData1[m_iHead], seqno); - if (offset < 0) - return false; - - int loc = (m_iHead + offset) % m_iSize; - - if (seqno == m_piData1[loc]) - { - // This is a seq. no. that starts the loss sequence - - if (-1 == m_piData2[loc]) - { - // there is only 1 loss in the sequence, delete it from the node - if (m_iHead == loc) - { - m_iHead = m_piNext[m_iHead]; - if (-1 != m_iHead) - m_piPrior[m_iHead] = -1; - } - else - { - m_piNext[m_piPrior[loc]] = m_piNext[loc]; - if (-1 != m_piNext[loc]) - m_piPrior[m_piNext[loc]] = m_piPrior[loc]; - else - m_iTail = m_piPrior[loc]; - } - - m_piData1[loc] = -1; - } - else - { - // there are more than 1 loss in the sequence - // move the node to the next and update the starter as the next loss inSeqNo(seqno) - - // find next node - int i = (loc + 1) % m_iSize; - - // remove the "seqno" and change the starter as next seq. no. - m_piData1[i] = CSeqNo::incseq(m_piData1[loc]); - - // process the sequence end - if (CSeqNo::seqcmp(m_piData2[loc], CSeqNo::incseq(m_piData1[loc])) > 0) - m_piData2[i] = m_piData2[loc]; - - // remove the current node - m_piData1[loc] = -1; - m_piData2[loc] = -1; - - // update list pointer - m_piNext[i] = m_piNext[loc]; - m_piPrior[i] = m_piPrior[loc]; - - if (m_iHead == loc) - m_iHead = i; - else - m_piNext[m_piPrior[i]] = i; - - if (m_iTail == loc) - m_iTail = i; - else - m_piPrior[m_piNext[i]] = i; - } - - m_iLength --; - - return true; - } - - // There is no loss sequence in the current position - // the "seqno" may be contained in a previous node - - // searching previous node - int i = (loc - 1 + m_iSize) % m_iSize; - while (-1 == m_piData1[i]) - i = (i - 1 + m_iSize) % m_iSize; - - // not contained in this node, return - if ((-1 == m_piData2[i]) || (CSeqNo::seqcmp(seqno, m_piData2[i]) > 0)) - return false; - - if (seqno == m_piData2[i]) - { - // it is the sequence end - - if (seqno == CSeqNo::incseq(m_piData1[i])) - m_piData2[i] = -1; - else - m_piData2[i] = CSeqNo::decseq(seqno); - } - else - { - // split the sequence - - // construct the second sequence from CSeqNo::incseq(seqno) to the original sequence end - // located at "loc + 1" - loc = (loc + 1) % m_iSize; - - m_piData1[loc] = CSeqNo::incseq(seqno); - if (CSeqNo::seqcmp(m_piData2[i], m_piData1[loc]) > 0) - m_piData2[loc] = m_piData2[i]; - - // the first (original) sequence is between the original sequence start to CSeqNo::decseq(seqno) - if (seqno == CSeqNo::incseq(m_piData1[i])) - m_piData2[i] = -1; - else - m_piData2[i] = CSeqNo::decseq(seqno); - - // update the list pointer - m_piNext[loc] = m_piNext[i]; - m_piNext[i] = loc; - m_piPrior[loc] = i; - - if (m_iTail == i) - m_iTail = loc; - else - m_piPrior[m_piNext[loc]] = loc; - } - - m_iLength --; - - return true; -} - -bool CRcvLossList::remove(int32_t seqno1, int32_t seqno2) -{ - if (seqno1 <= seqno2) - { - for (int32_t i = seqno1; i <= seqno2; ++ i) - remove(i); - } - else - { - for (int32_t j = seqno1; j < CSeqNo::m_iMaxSeqNo; ++ j) - remove(j); - for (int32_t k = 0; k <= seqno2; ++ k) - remove(k); - } - - return true; -} - -bool CRcvLossList::find(int32_t seqno1, int32_t seqno2) const -{ - if (0 == m_iLength) - return false; - - int p = m_iHead; - - while (-1 != p) - { - if ((CSeqNo::seqcmp(m_piData1[p], seqno1) == 0) || - ((CSeqNo::seqcmp(m_piData1[p], seqno1) > 0) && (CSeqNo::seqcmp(m_piData1[p], seqno2) <= 0)) || - ((CSeqNo::seqcmp(m_piData1[p], seqno1) < 0) && (m_piData2[p] != -1) && CSeqNo::seqcmp(m_piData2[p], seqno1) >= 0)) - return true; - - p = m_piNext[p]; - } - - return false; -} - -int CRcvLossList::getLossLength() const -{ - return m_iLength; -} - -int CRcvLossList::getFirstLostSeq() const -{ - if (0 == m_iLength) - return -1; - - return m_piData1[m_iHead]; -} - -void CRcvLossList::getLossArray(int32_t* array, int& len, int limit) -{ - len = 0; - - int i = m_iHead; - - while ((len < limit - 1) && (-1 != i)) - { - array[len] = m_piData1[i]; - if (-1 != m_piData2[i]) - { - // there are more than 1 loss in the sequence - array[len] |= 0x80000000; - ++ len; - array[len] = m_piData2[i]; - } - - ++ len; - - i = m_piNext[i]; - } -} diff --git a/vendor/udt4/src/list.h b/vendor/udt4/src/list.h deleted file mode 100644 index 6be9694..0000000 --- a/vendor/udt4/src/list.h +++ /dev/null @@ -1,202 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/22/2011 -*****************************************************************************/ - -#ifndef __UDT_LIST_H__ -#define __UDT_LIST_H__ - - -#include "udt.h" -#include "common.h" - - -class CSndLossList -{ -public: - CSndLossList(int size = 1024); - ~CSndLossList(); - - // Functionality: - // Insert a seq. no. into the sender loss list. - // Parameters: - // 0) [in] seqno1: sequence number starts. - // 1) [in] seqno2: sequence number ends. - // Returned value: - // number of packets that are not in the list previously. - - int insert(int32_t seqno1, int32_t seqno2); - - // Functionality: - // Remove ALL the seq. no. that are not greater than the parameter. - // Parameters: - // 0) [in] seqno: sequence number. - // Returned value: - // None. - - void remove(int32_t seqno); - - // Functionality: - // Read the loss length. - // Parameters: - // None. - // Returned value: - // The length of the list. - - int getLossLength(); - - // Functionality: - // Read the first (smallest) loss seq. no. in the list and remove it. - // Parameters: - // None. - // Returned value: - // The seq. no. or -1 if the list is empty. - - int32_t getLostSeq(); - -private: - int32_t* m_piData1; // sequence number starts - int32_t* m_piData2; // seqnence number ends - int* m_piNext; // next node in the list - - int m_iHead; // first node - int m_iLength; // loss length - int m_iSize; // size of the static array - int m_iLastInsertPos; // position of last insert node - - pthread_mutex_t m_ListLock; // used to synchronize list operation - -private: - CSndLossList(const CSndLossList&); - CSndLossList& operator=(const CSndLossList&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CRcvLossList -{ -public: - CRcvLossList(int size = 1024); - ~CRcvLossList(); - - // Functionality: - // Insert a series of loss seq. no. between "seqno1" and "seqno2" into the receiver's loss list. - // Parameters: - // 0) [in] seqno1: sequence number starts. - // 1) [in] seqno2: seqeunce number ends. - // Returned value: - // None. - - void insert(int32_t seqno1, int32_t seqno2); - - // Functionality: - // Remove a loss seq. no. from the receiver's loss list. - // Parameters: - // 0) [in] seqno: sequence number. - // Returned value: - // if the packet is removed (true) or no such lost packet is found (false). - - bool remove(int32_t seqno); - - // Functionality: - // Remove all packets between seqno1 and seqno2. - // Parameters: - // 0) [in] seqno1: start sequence number. - // 1) [in] seqno2: end sequence number. - // Returned value: - // if the packet is removed (true) or no such lost packet is found (false). - - bool remove(int32_t seqno1, int32_t seqno2); - - // Functionality: - // Find if there is any lost packets whose sequence number falling seqno1 and seqno2. - // Parameters: - // 0) [in] seqno1: start sequence number. - // 1) [in] seqno2: end sequence number. - // Returned value: - // True if found; otherwise false. - - bool find(int32_t seqno1, int32_t seqno2) const; - - // Functionality: - // Read the loss length. - // Parameters: - // None. - // Returned value: - // the length of the list. - - int getLossLength() const; - - // Functionality: - // Read the first (smallest) seq. no. in the list. - // Parameters: - // None. - // Returned value: - // the sequence number or -1 if the list is empty. - - int getFirstLostSeq() const; - - // Functionality: - // Get a encoded loss array for NAK report. - // Parameters: - // 0) [out] array: the result list of seq. no. to be included in NAK. - // 1) [out] physical length of the result array. - // 2) [in] limit: maximum length of the array. - // Returned value: - // None. - - void getLossArray(int32_t* array, int& len, int limit); - -private: - int32_t* m_piData1; // sequence number starts - int32_t* m_piData2; // sequence number ends - int* m_piNext; // next node in the list - int* m_piPrior; // prior node in the list; - - int m_iHead; // first node in the list - int m_iTail; // last node in the list; - int m_iLength; // loss length - int m_iSize; // size of the static array - -private: - CRcvLossList(const CRcvLossList&); - CRcvLossList& operator=(const CRcvLossList&); -}; - - -#endif diff --git a/vendor/udt4/src/md5.cpp b/vendor/udt4/src/md5.cpp deleted file mode 100644 index d6fd5d3..0000000 --- a/vendor/udt4/src/md5.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.cpp,v 1.3 2008/01/20 22:52:04 lilyco Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/vendor/udt4/src/md5.h b/vendor/udt4/src/md5.h deleted file mode 100644 index f7402e7..0000000 --- a/vendor/udt4/src/md5.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.2 2007/12/24 05:58:37 lilyco Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/vendor/udt4/src/packet.cpp b/vendor/udt4/src/packet.cpp deleted file mode 100644 index e238a04..0000000 --- a/vendor/udt4/src/packet.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 02/12/2011 -*****************************************************************************/ - - -////////////////////////////////////////////////////////////////////////////// -// 0 1 2 3 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Packet Header | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | | -// ~ Data / Control Information Field ~ -// | | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// 0 1 2 3 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |0| Sequence Number | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |ff |o| Message Number | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Time Stamp | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Destination Socket ID | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// bit 0: -// 0: Data Packet -// 1: Control Packet -// bit ff: -// 11: solo message packet -// 10: first packet of a message -// 01: last packet of a message -// bit o: -// 0: in order delivery not required -// 1: in order delivery required -// -// 0 1 2 3 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |1| Type | Reserved | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Additional Info | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Time Stamp | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Destination Socket ID | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// bit 1-15: -// 0: Protocol Connection Handshake -// Add. Info: Undefined -// Control Info: Handshake information (see CHandShake) -// 1: Keep-alive -// Add. Info: Undefined -// Control Info: None -// 2: Acknowledgement (ACK) -// Add. Info: The ACK sequence number -// Control Info: The sequence number to which (but not include) all the previous packets have beed received -// Optional: RTT -// RTT Variance -// available receiver buffer size (in bytes) -// advertised flow window size (number of packets) -// estimated bandwidth (number of packets per second) -// 3: Negative Acknowledgement (NAK) -// Add. Info: Undefined -// Control Info: Loss list (see loss list coding below) -// 4: Congestion/Delay Warning -// Add. Info: Undefined -// Control Info: None -// 5: Shutdown -// Add. Info: Undefined -// Control Info: None -// 6: Acknowledgement of Acknowledement (ACK-square) -// Add. Info: The ACK sequence number -// Control Info: None -// 7: Message Drop Request -// Add. Info: Message ID -// Control Info: first sequence number of the message -// last seqeunce number of the message -// 8: Error Signal from the Peer Side -// Add. Info: Error code -// Control Info: None -// 0x7FFF: Explained by bits 16 - 31 -// -// bit 16 - 31: -// This space is used for future expansion or user defined control packets. -// -// 0 1 2 3 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |1| Sequence Number a (first) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |0| Sequence Number b (last) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |0| Sequence Number (single) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// Loss List Field Coding: -// For any consectutive lost seqeunce numbers that the differnece between -// the last and first is more than 1, only record the first (a) and the -// the last (b) sequence numbers in the loss list field, and modify the -// the first bit of a to 1. -// For any single loss or consectutive loss less than 2 packets, use -// the original sequence numbers in the field. - - -#include -#include "packet.h" - - -const int CPacket::m_iPktHdrSize = 16; -const int CHandShake::m_iContentSize = 48; - - -// Set up the aliases in the constructure -CPacket::CPacket(): -m_iSeqNo((int32_t&)(m_nHeader[0])), -m_iMsgNo((int32_t&)(m_nHeader[1])), -m_iTimeStamp((int32_t&)(m_nHeader[2])), -m_iID((int32_t&)(m_nHeader[3])), -m_pcData((char*&)(m_PacketVector[1].iov_base)), -__pad() -{ - for (int i = 0; i < 4; ++ i) - m_nHeader[i] = 0; - m_PacketVector[0].iov_base = (char *)m_nHeader; - m_PacketVector[0].iov_len = CPacket::m_iPktHdrSize; - m_PacketVector[1].iov_base = NULL; - m_PacketVector[1].iov_len = 0; -} - -CPacket::~CPacket() -{ -} - -int CPacket::getLength() const -{ - return m_PacketVector[1].iov_len; -} - -void CPacket::setLength(int len) -{ - m_PacketVector[1].iov_len = len; -} - -void CPacket::pack(int pkttype, void* lparam, void* rparam, int size) -{ - // Set (bit-0 = 1) and (bit-1~15 = type) - m_nHeader[0] = 0x80000000 | (pkttype << 16); - - // Set additional information and control information field - switch (pkttype) - { - case 2: //0010 - Acknowledgement (ACK) - // ACK packet seq. no. - if (NULL != lparam) - m_nHeader[1] = *(int32_t *)lparam; - - // data ACK seq. no. - // optional: RTT (microsends), RTT variance (microseconds) advertised flow window size (packets), and estimated link capacity (packets per second) - m_PacketVector[1].iov_base = (char *)rparam; - m_PacketVector[1].iov_len = size; - - break; - - case 6: //0110 - Acknowledgement of Acknowledgement (ACK-2) - // ACK packet seq. no. - m_nHeader[1] = *(int32_t *)lparam; - - // control info field should be none - // but "writev" does not allow this - m_PacketVector[1].iov_base = (char *)&__pad; //NULL; - m_PacketVector[1].iov_len = 4; //0; - - break; - - case 3: //0011 - Loss Report (NAK) - // loss list - m_PacketVector[1].iov_base = (char *)rparam; - m_PacketVector[1].iov_len = size; - - break; - - case 4: //0100 - Congestion Warning - // control info field should be none - // but "writev" does not allow this - m_PacketVector[1].iov_base = (char *)&__pad; //NULL; - m_PacketVector[1].iov_len = 4; //0; - - break; - - case 1: //0001 - Keep-alive - // control info field should be none - // but "writev" does not allow this - m_PacketVector[1].iov_base = (char *)&__pad; //NULL; - m_PacketVector[1].iov_len = 4; //0; - - break; - - case 0: //0000 - Handshake - // control info filed is handshake info - m_PacketVector[1].iov_base = (char *)rparam; - m_PacketVector[1].iov_len = size; //sizeof(CHandShake); - - break; - - case 5: //0101 - Shutdown - // control info field should be none - // but "writev" does not allow this - m_PacketVector[1].iov_base = (char *)&__pad; //NULL; - m_PacketVector[1].iov_len = 4; //0; - - break; - - case 7: //0111 - Message Drop Request - // msg id - m_nHeader[1] = *(int32_t *)lparam; - - //first seq no, last seq no - m_PacketVector[1].iov_base = (char *)rparam; - m_PacketVector[1].iov_len = size; - - break; - - case 8: //1000 - Error Signal from the Peer Side - // Error type - m_nHeader[1] = *(int32_t *)lparam; - - // control info field should be none - // but "writev" does not allow this - m_PacketVector[1].iov_base = (char *)&__pad; //NULL; - m_PacketVector[1].iov_len = 4; //0; - - break; - - case 32767: //0x7FFF - Reserved for user defined control packets - // for extended control packet - // "lparam" contains the extended type information for bit 16 - 31 - // "rparam" is the control information - m_nHeader[0] |= *(int32_t *)lparam; - - if (NULL != rparam) - { - m_PacketVector[1].iov_base = (char *)rparam; - m_PacketVector[1].iov_len = size; - } - else - { - m_PacketVector[1].iov_base = (char *)&__pad; - m_PacketVector[1].iov_len = 4; - } - - break; - - default: - break; - } -} - -iovec* CPacket::getPacketVector() -{ - return m_PacketVector; -} - -int CPacket::getFlag() const -{ - // read bit 0 - return m_nHeader[0] >> 31; -} - -int CPacket::getType() const -{ - // read bit 1~15 - return (m_nHeader[0] >> 16) & 0x00007FFF; -} - -int CPacket::getExtendedType() const -{ - // read bit 16~31 - return m_nHeader[0] & 0x0000FFFF; -} - -int32_t CPacket::getAckSeqNo() const -{ - // read additional information field - return m_nHeader[1]; -} - -int CPacket::getMsgBoundary() const -{ - // read [1] bit 0~1 - return m_nHeader[1] >> 30; -} - -bool CPacket::getMsgOrderFlag() const -{ - // read [1] bit 2 - return (1 == ((m_nHeader[1] >> 29) & 1)); -} - -int32_t CPacket::getMsgSeq() const -{ - // read [1] bit 3~31 - return m_nHeader[1] & 0x1FFFFFFF; -} - -CPacket* CPacket::clone() const -{ - CPacket* pkt = new CPacket; - memcpy(pkt->m_nHeader, m_nHeader, m_iPktHdrSize); - pkt->m_pcData = new char[m_PacketVector[1].iov_len]; - memcpy(pkt->m_pcData, m_pcData, m_PacketVector[1].iov_len); - pkt->m_PacketVector[1].iov_len = m_PacketVector[1].iov_len; - - return pkt; -} - -CHandShake::CHandShake(): -m_iVersion(0), -m_iType(0), -m_iISN(0), -m_iMSS(0), -m_iFlightFlagSize(0), -m_iReqType(0), -m_iID(0), -m_iCookie(0) -{ - for (int i = 0; i < 4; ++ i) - m_piPeerIP[i] = 0; -} - -int CHandShake::serialize(char* buf, int& size) -{ - if (size < m_iContentSize) - return -1; - - int32_t* p = (int32_t*)buf; - *p++ = m_iVersion; - *p++ = m_iType; - *p++ = m_iISN; - *p++ = m_iMSS; - *p++ = m_iFlightFlagSize; - *p++ = m_iReqType; - *p++ = m_iID; - *p++ = m_iCookie; - for (int i = 0; i < 4; ++ i) - *p++ = m_piPeerIP[i]; - - size = m_iContentSize; - - return 0; -} - -int CHandShake::deserialize(const char* buf, int size) -{ - if (size < m_iContentSize) - return -1; - - int32_t* p = (int32_t*)buf; - m_iVersion = *p++; - m_iType = *p++; - m_iISN = *p++; - m_iMSS = *p++; - m_iFlightFlagSize = *p++; - m_iReqType = *p++; - m_iID = *p++; - m_iCookie = *p++; - for (int i = 0; i < 4; ++ i) - m_piPeerIP[i] = *p++; - - return 0; -} diff --git a/vendor/udt4/src/packet.h b/vendor/udt4/src/packet.h deleted file mode 100644 index 76cc951..0000000 --- a/vendor/udt4/src/packet.h +++ /dev/null @@ -1,223 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/02/2011 -*****************************************************************************/ - -#ifndef __UDT_PACKET_H__ -#define __UDT_PACKET_H__ - - -#include "udt.h" - -#ifdef WIN32 - struct iovec - { - int iov_len; - char* iov_base; - }; -#endif - -class CChannel; - -class CPacket -{ -friend class CChannel; -friend class CSndQueue; -friend class CRcvQueue; - -public: - int32_t& m_iSeqNo; // alias: sequence number - int32_t& m_iMsgNo; // alias: message number - int32_t& m_iTimeStamp; // alias: timestamp - int32_t& m_iID; // alias: socket ID - char*& m_pcData; // alias: data/control information - - static const int m_iPktHdrSize; // packet header size - -public: - CPacket(); - ~CPacket(); - - // Functionality: - // Get the payload or the control information field length. - // Parameters: - // None. - // Returned value: - // the payload or the control information field length. - - int getLength() const; - - // Functionality: - // Set the payload or the control information field length. - // Parameters: - // 0) [in] len: the payload or the control information field length. - // Returned value: - // None. - - void setLength(int len); - - // Functionality: - // Pack a Control packet. - // Parameters: - // 0) [in] pkttype: packet type filed. - // 1) [in] lparam: pointer to the first data structure, explained by the packet type. - // 2) [in] rparam: pointer to the second data structure, explained by the packet type. - // 3) [in] size: size of rparam, in number of bytes; - // Returned value: - // None. - - void pack(int pkttype, void* lparam = NULL, void* rparam = NULL, int size = 0); - - // Functionality: - // Read the packet vector. - // Parameters: - // None. - // Returned value: - // Pointer to the packet vector. - - iovec* getPacketVector(); - - // Functionality: - // Read the packet flag. - // Parameters: - // None. - // Returned value: - // packet flag (0 or 1). - - int getFlag() const; - - // Functionality: - // Read the packet type. - // Parameters: - // None. - // Returned value: - // packet type filed (000 ~ 111). - - int getType() const; - - // Functionality: - // Read the extended packet type. - // Parameters: - // None. - // Returned value: - // extended packet type filed (0x000 ~ 0xFFF). - - int getExtendedType() const; - - // Functionality: - // Read the ACK-2 seq. no. - // Parameters: - // None. - // Returned value: - // packet header field (bit 16~31). - - int32_t getAckSeqNo() const; - - // Functionality: - // Read the message boundary flag bit. - // Parameters: - // None. - // Returned value: - // packet header field [1] (bit 0~1). - - int getMsgBoundary() const; - - // Functionality: - // Read the message inorder delivery flag bit. - // Parameters: - // None. - // Returned value: - // packet header field [1] (bit 2). - - bool getMsgOrderFlag() const; - - // Functionality: - // Read the message sequence number. - // Parameters: - // None. - // Returned value: - // packet header field [1] (bit 3~31). - - int32_t getMsgSeq() const; - - // Functionality: - // Clone this packet. - // Parameters: - // None. - // Returned value: - // Pointer to the new packet. - - CPacket* clone() const; - -protected: - uint32_t m_nHeader[4]; // The 128-bit header field - iovec m_PacketVector[2]; // The 2-demension vector of UDT packet [header, data] - - int32_t __pad; - -protected: - CPacket& operator=(const CPacket&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CHandShake -{ -public: - CHandShake(); - - int serialize(char* buf, int& size); - int deserialize(const char* buf, int size); - -public: - static const int m_iContentSize; // Size of hand shake data - -public: - int32_t m_iVersion; // UDT version - int32_t m_iType; // UDT socket type - int32_t m_iISN; // random initial sequence number - int32_t m_iMSS; // maximum segment size - int32_t m_iFlightFlagSize; // flow control window size - int32_t m_iReqType; // connection request type: 1: regular connection request, 0: rendezvous connection request, -1/-2: response - int32_t m_iID; // socket ID - int32_t m_iCookie; // cookie - uint32_t m_piPeerIP[4]; // The IP address that the peer's UDP port is bound to -}; - - -#endif diff --git a/vendor/udt4/src/queue.cpp b/vendor/udt4/src/queue.cpp deleted file mode 100644 index 2caea2a..0000000 --- a/vendor/udt4/src/queue.cpp +++ /dev/null @@ -1,1253 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 05/05/2011 -*****************************************************************************/ - -#ifdef WIN32 - #include - #include - #ifdef LEGACY_WIN32 - #include - #endif -#endif -#include - -#include "common.h" -#include "core.h" -#include "queue.h" - -using namespace std; - -CUnitQueue::CUnitQueue(): -m_pQEntry(NULL), -m_pCurrQueue(NULL), -m_pLastQueue(NULL), -m_iSize(0), -m_iCount(0), -m_iMSS(), -m_iIPversion() -{ -} - -CUnitQueue::~CUnitQueue() -{ - CQEntry* p = m_pQEntry; - - while (p != NULL) - { - delete [] p->m_pUnit; - delete [] p->m_pBuffer; - - CQEntry* q = p; - if (p == m_pLastQueue) - p = NULL; - else - p = p->m_pNext; - delete q; - } -} - -int CUnitQueue::init(int size, int mss, int version) -{ - CQEntry* tempq = NULL; - CUnit* tempu = NULL; - char* tempb = NULL; - - try - { - tempq = new CQEntry; - tempu = new CUnit [size]; - tempb = new char [size * mss]; - } - catch (...) - { - delete tempq; - delete [] tempu; - delete [] tempb; - - return -1; - } - - for (int i = 0; i < size; ++ i) - { - tempu[i].m_iFlag = 0; - tempu[i].m_Packet.m_pcData = tempb + i * mss; - } - tempq->m_pUnit = tempu; - tempq->m_pBuffer = tempb; - tempq->m_iSize = size; - - m_pQEntry = m_pCurrQueue = m_pLastQueue = tempq; - m_pQEntry->m_pNext = m_pQEntry; - - m_pAvailUnit = m_pCurrQueue->m_pUnit; - - m_iSize = size; - m_iMSS = mss; - m_iIPversion = version; - - return 0; -} - -int CUnitQueue::increase() -{ - // adjust/correct m_iCount - int real_count = 0; - CQEntry* p = m_pQEntry; - while (p != NULL) - { - CUnit* u = p->m_pUnit; - for (CUnit* end = u + p->m_iSize; u != end; ++ u) - if (u->m_iFlag != 0) - ++ real_count; - - if (p == m_pLastQueue) - p = NULL; - else - p = p->m_pNext; - } - m_iCount = real_count; - if (double(m_iCount) / m_iSize < 0.9) - return -1; - - CQEntry* tempq = NULL; - CUnit* tempu = NULL; - char* tempb = NULL; - - // all queues have the same size - int size = m_pQEntry->m_iSize; - - try - { - tempq = new CQEntry; - tempu = new CUnit [size]; - tempb = new char [size * m_iMSS]; - } - catch (...) - { - delete tempq; - delete [] tempu; - delete [] tempb; - - return -1; - } - - for (int i = 0; i < size; ++ i) - { - tempu[i].m_iFlag = 0; - tempu[i].m_Packet.m_pcData = tempb + i * m_iMSS; - } - tempq->m_pUnit = tempu; - tempq->m_pBuffer = tempb; - tempq->m_iSize = size; - - m_pLastQueue->m_pNext = tempq; - m_pLastQueue = tempq; - m_pLastQueue->m_pNext = m_pQEntry; - - m_iSize += size; - - return 0; -} - -int CUnitQueue::shrink() -{ - // currently queue cannot be shrunk. - return -1; -} - -CUnit* CUnitQueue::getNextAvailUnit() -{ - if (m_iCount * 10 > m_iSize * 9) - increase(); - - if (m_iCount >= m_iSize) - return NULL; - - CQEntry* entrance = m_pCurrQueue; - - do - { - for (CUnit* sentinel = m_pCurrQueue->m_pUnit + m_pCurrQueue->m_iSize - 1; m_pAvailUnit != sentinel; ++ m_pAvailUnit) - if (m_pAvailUnit->m_iFlag == 0) - return m_pAvailUnit; - - if (m_pCurrQueue->m_pUnit->m_iFlag == 0) - { - m_pAvailUnit = m_pCurrQueue->m_pUnit; - return m_pAvailUnit; - } - - m_pCurrQueue = m_pCurrQueue->m_pNext; - m_pAvailUnit = m_pCurrQueue->m_pUnit; - } while (m_pCurrQueue != entrance); - - increase(); - - return NULL; -} - - -CSndUList::CSndUList(): -m_pHeap(NULL), -m_iArrayLength(4096), -m_iLastEntry(-1), -m_ListLock(), -m_pWindowLock(NULL), -m_pWindowCond(NULL), -m_pTimer(NULL) -{ - m_pHeap = new CSNode*[m_iArrayLength]; - - #ifndef WIN32 - pthread_mutex_init(&m_ListLock, NULL); - #else - m_ListLock = CreateMutex(NULL, false, NULL); - #endif -} - -CSndUList::~CSndUList() -{ - delete [] m_pHeap; - - #ifndef WIN32 - pthread_mutex_destroy(&m_ListLock); - #else - CloseHandle(m_ListLock); - #endif -} - -void CSndUList::insert(int64_t ts, const CUDT* u) -{ - CGuard listguard(m_ListLock); - - // increase the heap array size if necessary - if (m_iLastEntry == m_iArrayLength - 1) - { - CSNode** temp = NULL; - - try - { - temp = new CSNode*[m_iArrayLength * 2]; - } - catch(...) - { - return; - } - - memcpy(temp, m_pHeap, sizeof(CSNode*) * m_iArrayLength); - m_iArrayLength *= 2; - delete [] m_pHeap; - m_pHeap = temp; - } - - insert_(ts, u); -} - -void CSndUList::update(const CUDT* u, bool reschedule) -{ - CGuard listguard(m_ListLock); - - CSNode* n = u->m_pSNode; - - if (n->m_iHeapLoc >= 0) - { - if (!reschedule) - return; - - if (n->m_iHeapLoc == 0) - { - n->m_llTimeStamp = 1; - m_pTimer->interrupt(); - return; - } - - remove_(u); - } - - insert_(1, u); -} - -int CSndUList::pop(sockaddr*& addr, CPacket& pkt) -{ - CGuard listguard(m_ListLock); - - if (-1 == m_iLastEntry) - return -1; - - // no pop until the next schedulled time - uint64_t ts; - CTimer::rdtsc(ts); - if (ts < m_pHeap[0]->m_llTimeStamp) - return -1; - - CUDT* u = m_pHeap[0]->m_pUDT; - remove_(u); - - if (!u->m_bConnected || u->m_bBroken) - return -1; - - // pack a packet from the socket - if (u->packData(pkt, ts) <= 0) - return -1; - - addr = u->m_pPeerAddr; - - // insert a new entry, ts is the next processing time - if (ts > 0) - insert_(ts, u); - - return 1; -} - -void CSndUList::remove(const CUDT* u) -{ - CGuard listguard(m_ListLock); - - remove_(u); -} - -uint64_t CSndUList::getNextProcTime() -{ - CGuard listguard(m_ListLock); - - if (-1 == m_iLastEntry) - return 0; - - return m_pHeap[0]->m_llTimeStamp; -} - -void CSndUList::insert_(int64_t ts, const CUDT* u) -{ - CSNode* n = u->m_pSNode; - - // do not insert repeated node - if (n->m_iHeapLoc >= 0) - return; - - m_iLastEntry ++; - m_pHeap[m_iLastEntry] = n; - n->m_llTimeStamp = ts; - - int q = m_iLastEntry; - int p = q; - while (p != 0) - { - p = (q - 1) >> 1; - if (m_pHeap[p]->m_llTimeStamp > m_pHeap[q]->m_llTimeStamp) - { - CSNode* t = m_pHeap[p]; - m_pHeap[p] = m_pHeap[q]; - m_pHeap[q] = t; - t->m_iHeapLoc = q; - q = p; - } - else - break; - } - - n->m_iHeapLoc = q; - - // an earlier event has been inserted, wake up sending worker - if (n->m_iHeapLoc == 0) - m_pTimer->interrupt(); - - // first entry, activate the sending queue - if (0 == m_iLastEntry) - { - #ifndef WIN32 - pthread_mutex_lock(m_pWindowLock); - pthread_cond_signal(m_pWindowCond); - pthread_mutex_unlock(m_pWindowLock); - #else - SetEvent(*m_pWindowCond); - #endif - } -} - -void CSndUList::remove_(const CUDT* u) -{ - CSNode* n = u->m_pSNode; - - if (n->m_iHeapLoc >= 0) - { - // remove the node from heap - m_pHeap[n->m_iHeapLoc] = m_pHeap[m_iLastEntry]; - m_iLastEntry --; - m_pHeap[n->m_iHeapLoc]->m_iHeapLoc = n->m_iHeapLoc; - - int q = n->m_iHeapLoc; - int p = q * 2 + 1; - while (p <= m_iLastEntry) - { - if ((p + 1 <= m_iLastEntry) && (m_pHeap[p]->m_llTimeStamp > m_pHeap[p + 1]->m_llTimeStamp)) - p ++; - - if (m_pHeap[q]->m_llTimeStamp > m_pHeap[p]->m_llTimeStamp) - { - CSNode* t = m_pHeap[p]; - m_pHeap[p] = m_pHeap[q]; - m_pHeap[p]->m_iHeapLoc = p; - m_pHeap[q] = t; - m_pHeap[q]->m_iHeapLoc = q; - - q = p; - p = q * 2 + 1; - } - else - break; - } - - n->m_iHeapLoc = -1; - } - - // the only event has been deleted, wake up immediately - if (0 == m_iLastEntry) - m_pTimer->interrupt(); -} - -// -CSndQueue::CSndQueue(): -m_WorkerThread(), -m_pSndUList(NULL), -m_pChannel(NULL), -m_pTimer(NULL), -m_WindowLock(), -m_WindowCond(), -m_bClosing(false), -m_ExitCond() -{ - #ifndef WIN32 - pthread_cond_init(&m_WindowCond, NULL); - pthread_mutex_init(&m_WindowLock, NULL); - #else - m_WindowLock = CreateMutex(NULL, false, NULL); - m_WindowCond = CreateEvent(NULL, false, false, NULL); - m_ExitCond = CreateEvent(NULL, false, false, NULL); - #endif -} - -CSndQueue::~CSndQueue() -{ - m_bClosing = true; - - #ifndef WIN32 - pthread_mutex_lock(&m_WindowLock); - pthread_cond_signal(&m_WindowCond); - pthread_mutex_unlock(&m_WindowLock); - if (0 != m_WorkerThread) - pthread_join(m_WorkerThread, NULL); - pthread_cond_destroy(&m_WindowCond); - pthread_mutex_destroy(&m_WindowLock); - #else - SetEvent(m_WindowCond); - if (NULL != m_WorkerThread) - WaitForSingleObject(m_ExitCond, INFINITE); - CloseHandle(m_WorkerThread); - CloseHandle(m_WindowLock); - CloseHandle(m_WindowCond); - CloseHandle(m_ExitCond); - #endif - - delete m_pSndUList; -} - -void CSndQueue::init(CChannel* c, CTimer* t) -{ - m_pChannel = c; - m_pTimer = t; - m_pSndUList = new CSndUList; - m_pSndUList->m_pWindowLock = &m_WindowLock; - m_pSndUList->m_pWindowCond = &m_WindowCond; - m_pSndUList->m_pTimer = m_pTimer; - - #ifndef WIN32 - if (0 != pthread_create(&m_WorkerThread, NULL, CSndQueue::worker, this)) - { - m_WorkerThread = 0; - throw CUDTException(3, 1); - } - #else - DWORD threadID; - m_WorkerThread = CreateThread(NULL, 0, CSndQueue::worker, this, 0, &threadID); - if (NULL == m_WorkerThread) - throw CUDTException(3, 1); - #endif -} - -#ifndef WIN32 - void* CSndQueue::worker(void* param) -#else - DWORD WINAPI CSndQueue::worker(LPVOID param) -#endif -{ - CSndQueue* self = (CSndQueue*)param; - - while (!self->m_bClosing) - { - uint64_t ts = self->m_pSndUList->getNextProcTime(); - - if (ts > 0) - { - // wait until next processing time of the first socket on the list - uint64_t currtime; - CTimer::rdtsc(currtime); - if (currtime < ts) - self->m_pTimer->sleepto(ts); - - // it is time to send the next pkt - sockaddr* addr; - CPacket pkt; - if (self->m_pSndUList->pop(addr, pkt) < 0) - continue; - - self->m_pChannel->sendto(addr, pkt); - } - else - { - // wait here if there is no sockets with data to be sent - #ifndef WIN32 - pthread_mutex_lock(&self->m_WindowLock); - if (!self->m_bClosing && (self->m_pSndUList->m_iLastEntry < 0)) - pthread_cond_wait(&self->m_WindowCond, &self->m_WindowLock); - pthread_mutex_unlock(&self->m_WindowLock); - #else - WaitForSingleObject(self->m_WindowCond, INFINITE); - #endif - } - } - - #ifndef WIN32 - return NULL; - #else - SetEvent(self->m_ExitCond); - return 0; - #endif -} - -int CSndQueue::sendto(const sockaddr* addr, CPacket& packet) -{ - // send out the packet immediately (high priority), this is a control packet - m_pChannel->sendto(addr, packet); - return packet.getLength(); -} - - -// -CRcvUList::CRcvUList(): -m_pUList(NULL), -m_pLast(NULL) -{ -} - -CRcvUList::~CRcvUList() -{ -} - -void CRcvUList::insert(const CUDT* u) -{ - CRNode* n = u->m_pRNode; - CTimer::rdtsc(n->m_llTimeStamp); - - if (NULL == m_pUList) - { - // empty list, insert as the single node - n->m_pPrev = n->m_pNext = NULL; - m_pLast = m_pUList = n; - - return; - } - - // always insert at the end for RcvUList - n->m_pPrev = m_pLast; - n->m_pNext = NULL; - m_pLast->m_pNext = n; - m_pLast = n; -} - -void CRcvUList::remove(const CUDT* u) -{ - CRNode* n = u->m_pRNode; - - if (!n->m_bOnList) - return; - - if (NULL == n->m_pPrev) - { - // n is the first node - m_pUList = n->m_pNext; - if (NULL == m_pUList) - m_pLast = NULL; - else - m_pUList->m_pPrev = NULL; - } - else - { - n->m_pPrev->m_pNext = n->m_pNext; - if (NULL == n->m_pNext) - { - // n is the last node - m_pLast = n->m_pPrev; - } - else - n->m_pNext->m_pPrev = n->m_pPrev; - } - - n->m_pNext = n->m_pPrev = NULL; -} - -void CRcvUList::update(const CUDT* u) -{ - CRNode* n = u->m_pRNode; - - if (!n->m_bOnList) - return; - - CTimer::rdtsc(n->m_llTimeStamp); - - // if n is the last node, do not need to change - if (NULL == n->m_pNext) - return; - - if (NULL == n->m_pPrev) - { - m_pUList = n->m_pNext; - m_pUList->m_pPrev = NULL; - } - else - { - n->m_pPrev->m_pNext = n->m_pNext; - n->m_pNext->m_pPrev = n->m_pPrev; - } - - n->m_pPrev = m_pLast; - n->m_pNext = NULL; - m_pLast->m_pNext = n; - m_pLast = n; -} - -// -CHash::CHash(): -m_pBucket(NULL), -m_iHashSize(0) -{ -} - -CHash::~CHash() -{ - for (int i = 0; i < m_iHashSize; ++ i) - { - CBucket* b = m_pBucket[i]; - while (NULL != b) - { - CBucket* n = b->m_pNext; - delete b; - b = n; - } - } - - delete [] m_pBucket; -} - -void CHash::init(int size) -{ - m_pBucket = new CBucket* [size]; - - for (int i = 0; i < size; ++ i) - m_pBucket[i] = NULL; - - m_iHashSize = size; -} - -CUDT* CHash::lookup(int32_t id) -{ - // simple hash function (% hash table size); suitable for socket descriptors - CBucket* b = m_pBucket[id % m_iHashSize]; - - while (NULL != b) - { - if (id == b->m_iID) - return b->m_pUDT; - b = b->m_pNext; - } - - return NULL; -} - -void CHash::insert(int32_t id, CUDT* u) -{ - CBucket* b = m_pBucket[id % m_iHashSize]; - - CBucket* n = new CBucket; - n->m_iID = id; - n->m_pUDT = u; - n->m_pNext = b; - - m_pBucket[id % m_iHashSize] = n; -} - -void CHash::remove(int32_t id) -{ - CBucket* b = m_pBucket[id % m_iHashSize]; - CBucket* p = NULL; - - while (NULL != b) - { - if (id == b->m_iID) - { - if (NULL == p) - m_pBucket[id % m_iHashSize] = b->m_pNext; - else - p->m_pNext = b->m_pNext; - - delete b; - - return; - } - - p = b; - b = b->m_pNext; - } -} - - -// -CRendezvousQueue::CRendezvousQueue(): -m_lRendezvousID(), -m_RIDVectorLock() -{ - #ifndef WIN32 - pthread_mutex_init(&m_RIDVectorLock, NULL); - #else - m_RIDVectorLock = CreateMutex(NULL, false, NULL); - #endif -} - -CRendezvousQueue::~CRendezvousQueue() -{ - #ifndef WIN32 - pthread_mutex_destroy(&m_RIDVectorLock); - #else - CloseHandle(m_RIDVectorLock); - #endif - - for (list::iterator i = m_lRendezvousID.begin(); i != m_lRendezvousID.end(); ++ i) - { - if (AF_INET == i->m_iIPversion) - delete (sockaddr_in*)i->m_pPeerAddr; - else - delete (sockaddr_in6*)i->m_pPeerAddr; - } - - m_lRendezvousID.clear(); -} - -void CRendezvousQueue::insert(const UDTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl) -{ - CGuard vg(m_RIDVectorLock); - - CRL r; - r.m_iID = id; - r.m_pUDT = u; - r.m_iIPversion = ipv; - r.m_pPeerAddr = (AF_INET == ipv) ? (sockaddr*)new sockaddr_in : (sockaddr*)new sockaddr_in6; - memcpy(r.m_pPeerAddr, addr, (AF_INET == ipv) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6)); - r.m_ullTTL = ttl; - - m_lRendezvousID.push_back(r); -} - -void CRendezvousQueue::remove(const UDTSOCKET& id) -{ - CGuard vg(m_RIDVectorLock); - - for (list::iterator i = m_lRendezvousID.begin(); i != m_lRendezvousID.end(); ++ i) - { - if (i->m_iID == id) - { - if (AF_INET == i->m_iIPversion) - delete (sockaddr_in*)i->m_pPeerAddr; - else - delete (sockaddr_in6*)i->m_pPeerAddr; - - m_lRendezvousID.erase(i); - - return; - } - } -} - -CUDT* CRendezvousQueue::retrieve(const sockaddr* addr, UDTSOCKET& id) -{ - CGuard vg(m_RIDVectorLock); - - // TODO: optimize search - for (list::iterator i = m_lRendezvousID.begin(); i != m_lRendezvousID.end(); ++ i) - { - if (CIPAddress::ipcmp(addr, i->m_pPeerAddr, i->m_iIPversion) && ((0 == id) || (id == i->m_iID))) - { - id = i->m_iID; - return i->m_pUDT; - } - } - - return NULL; -} - -void CRendezvousQueue::updateConnStatus() -{ - if (m_lRendezvousID.empty()) - return; - - CGuard vg(m_RIDVectorLock); - - for (list::iterator i = m_lRendezvousID.begin(); i != m_lRendezvousID.end(); ++ i) - { - // avoid sending too many requests, at most 1 request per 250ms - if (CTimer::getTime() - i->m_pUDT->m_llLastReqTime > 250000) - { - if (CTimer::getTime() >= i->m_ullTTL) - { - // connection timer expired, acknowledge app via epoll - i->m_pUDT->m_bConnecting = false; - CUDT::s_UDTUnited.m_EPoll.update_events(i->m_iID, i->m_pUDT->m_sPollID, UDT_EPOLL_ERR, true); - continue; - } - - CPacket request; - char* reqdata = new char [i->m_pUDT->m_iPayloadSize]; - request.pack(0, NULL, reqdata, i->m_pUDT->m_iPayloadSize); - // ID = 0, connection request - request.m_iID = !i->m_pUDT->m_bRendezvous ? 0 : i->m_pUDT->m_ConnRes.m_iID; - int hs_size = i->m_pUDT->m_iPayloadSize; - i->m_pUDT->m_ConnReq.serialize(reqdata, hs_size); - request.setLength(hs_size); - i->m_pUDT->m_pSndQueue->sendto(i->m_pPeerAddr, request); - i->m_pUDT->m_llLastReqTime = CTimer::getTime(); - delete [] reqdata; - } - } -} - -// -CRcvQueue::CRcvQueue(): -m_WorkerThread(), -m_UnitQueue(), -m_pRcvUList(NULL), -m_pHash(NULL), -m_pChannel(NULL), -m_pTimer(NULL), -m_iPayloadSize(), -m_bClosing(false), -m_ExitCond(), -m_LSLock(), -m_pListener(NULL), -m_pRendezvousQueue(NULL), -m_vNewEntry(), -m_IDLock(), -m_mBuffer(), -m_PassLock(), -m_PassCond() -{ - #ifndef WIN32 - pthread_mutex_init(&m_PassLock, NULL); - pthread_cond_init(&m_PassCond, NULL); - pthread_mutex_init(&m_LSLock, NULL); - pthread_mutex_init(&m_IDLock, NULL); - #else - m_PassLock = CreateMutex(NULL, false, NULL); - m_PassCond = CreateEvent(NULL, false, false, NULL); - m_LSLock = CreateMutex(NULL, false, NULL); - m_IDLock = CreateMutex(NULL, false, NULL); - m_ExitCond = CreateEvent(NULL, false, false, NULL); - #endif -} - -CRcvQueue::~CRcvQueue() -{ - m_bClosing = true; - - #ifndef WIN32 - if (0 != m_WorkerThread) - pthread_join(m_WorkerThread, NULL); - pthread_mutex_destroy(&m_PassLock); - pthread_cond_destroy(&m_PassCond); - pthread_mutex_destroy(&m_LSLock); - pthread_mutex_destroy(&m_IDLock); - #else - if (NULL != m_WorkerThread) - WaitForSingleObject(m_ExitCond, INFINITE); - CloseHandle(m_WorkerThread); - CloseHandle(m_PassLock); - CloseHandle(m_PassCond); - CloseHandle(m_LSLock); - CloseHandle(m_IDLock); - CloseHandle(m_ExitCond); - #endif - - delete m_pRcvUList; - delete m_pHash; - delete m_pRendezvousQueue; - - // remove all queued messages - for (map >::iterator i = m_mBuffer.begin(); i != m_mBuffer.end(); ++ i) - { - while (!i->second.empty()) - { - CPacket* pkt = i->second.front(); - delete [] pkt->m_pcData; - delete pkt; - i->second.pop(); - } - } -} - -void CRcvQueue::init(int qsize, int payload, int version, int hsize, CChannel* cc, CTimer* t) -{ - m_iPayloadSize = payload; - - m_UnitQueue.init(qsize, payload, version); - - m_pHash = new CHash; - m_pHash->init(hsize); - - m_pChannel = cc; - m_pTimer = t; - - m_pRcvUList = new CRcvUList; - m_pRendezvousQueue = new CRendezvousQueue; - - #ifndef WIN32 - if (0 != pthread_create(&m_WorkerThread, NULL, CRcvQueue::worker, this)) - { - m_WorkerThread = 0; - throw CUDTException(3, 1); - } - #else - DWORD threadID; - m_WorkerThread = CreateThread(NULL, 0, CRcvQueue::worker, this, 0, &threadID); - if (NULL == m_WorkerThread) - throw CUDTException(3, 1); - #endif -} - -#ifndef WIN32 - void* CRcvQueue::worker(void* param) -#else - DWORD WINAPI CRcvQueue::worker(LPVOID param) -#endif -{ - CRcvQueue* self = (CRcvQueue*)param; - - sockaddr* addr = (AF_INET == self->m_UnitQueue.m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; - CUDT* u = NULL; - int32_t id; - - while (!self->m_bClosing) - { - #ifdef NO_BUSY_WAITING - self->m_pTimer->tick(); - #endif - - // check waiting list, if new socket, insert it to the list - while (self->ifNewEntry()) - { - CUDT* ne = self->getNewEntry(); - if (NULL != ne) - { - self->m_pRcvUList->insert(ne); - self->m_pHash->insert(ne->m_SocketID, ne); - } - } - - // find next available slot for incoming packet - CUnit* unit = self->m_UnitQueue.getNextAvailUnit(); - if (NULL == unit) - { - // no space, skip this packet - CPacket temp; - temp.m_pcData = new char[self->m_iPayloadSize]; - temp.setLength(self->m_iPayloadSize); - self->m_pChannel->recvfrom(addr, temp); - delete [] temp.m_pcData; - goto TIMER_CHECK; - } - - unit->m_Packet.setLength(self->m_iPayloadSize); - - // reading next incoming packet, recvfrom returns -1 is nothing has been received - if (self->m_pChannel->recvfrom(addr, unit->m_Packet) < 0) - goto TIMER_CHECK; - - id = unit->m_Packet.m_iID; - - // ID 0 is for connection request, which should be passed to the listening socket or rendezvous sockets - if (0 == id) - { - if (NULL != self->m_pListener) - self->m_pListener->listen(addr, unit->m_Packet); - else if (NULL != (u = self->m_pRendezvousQueue->retrieve(addr, id))) - { - // asynchronous connect: call connect here - // otherwise wait for the UDT socket to retrieve this packet - if (!u->m_bSynRecving) - u->connect(unit->m_Packet); - else - self->storePkt(id, unit->m_Packet.clone()); - } - } - else if (id > 0) - { - if (NULL != (u = self->m_pHash->lookup(id))) - { - if (CIPAddress::ipcmp(addr, u->m_pPeerAddr, u->m_iIPversion)) - { - if (u->m_bConnected && !u->m_bBroken && !u->m_bClosing) - { - if (0 == unit->m_Packet.getFlag()) - u->processData(unit); - else - u->processCtrl(unit->m_Packet); - - u->checkTimers(); - self->m_pRcvUList->update(u); - } - } - } - else if (NULL != (u = self->m_pRendezvousQueue->retrieve(addr, id))) - { - if (!u->m_bSynRecving) - u->connect(unit->m_Packet); - else - self->storePkt(id, unit->m_Packet.clone()); - } - } - -TIMER_CHECK: - // take care of the timing event for all UDT sockets - - uint64_t currtime; - CTimer::rdtsc(currtime); - - CRNode* ul = self->m_pRcvUList->m_pUList; - uint64_t ctime = currtime - 100000 * CTimer::getCPUFrequency(); - while ((NULL != ul) && (ul->m_llTimeStamp < ctime)) - { - CUDT* u = ul->m_pUDT; - - if (u->m_bConnected && !u->m_bBroken && !u->m_bClosing) - { - u->checkTimers(); - self->m_pRcvUList->update(u); - } - else - { - // the socket must be removed from Hash table first, then RcvUList - self->m_pHash->remove(u->m_SocketID); - self->m_pRcvUList->remove(u); - u->m_pRNode->m_bOnList = false; - } - - ul = self->m_pRcvUList->m_pUList; - } - - // Check connection requests status for all sockets in the RendezvousQueue. - self->m_pRendezvousQueue->updateConnStatus(); - } - - if (AF_INET == self->m_UnitQueue.m_iIPversion) - delete (sockaddr_in*)addr; - else - delete (sockaddr_in6*)addr; - - #ifndef WIN32 - return NULL; - #else - SetEvent(self->m_ExitCond); - return 0; - #endif -} - -int CRcvQueue::recvfrom(int32_t id, CPacket& packet) -{ - CGuard bufferlock(m_PassLock); - - map >::iterator i = m_mBuffer.find(id); - - if (i == m_mBuffer.end()) - { - #ifndef WIN32 - uint64_t now = CTimer::getTime(); - timespec timeout; - - timeout.tv_sec = now / 1000000 + 1; - timeout.tv_nsec = (now % 1000000) * 1000; - - pthread_cond_timedwait(&m_PassCond, &m_PassLock, &timeout); - #else - ReleaseMutex(m_PassLock); - WaitForSingleObject(m_PassCond, 1000); - WaitForSingleObject(m_PassLock, INFINITE); - #endif - - i = m_mBuffer.find(id); - if (i == m_mBuffer.end()) - { - packet.setLength(-1); - return -1; - } - } - - // retrieve the earliest packet - CPacket* newpkt = i->second.front(); - - if (packet.getLength() < newpkt->getLength()) - { - packet.setLength(-1); - return -1; - } - - // copy packet content - memcpy(packet.m_nHeader, newpkt->m_nHeader, CPacket::m_iPktHdrSize); - memcpy(packet.m_pcData, newpkt->m_pcData, newpkt->getLength()); - packet.setLength(newpkt->getLength()); - - delete [] newpkt->m_pcData; - delete newpkt; - - // remove this message from queue, - // if no more messages left for this socket, release its data structure - i->second.pop(); - if (i->second.empty()) - m_mBuffer.erase(i); - - return packet.getLength(); -} - -int CRcvQueue::setListener(CUDT* u) -{ - CGuard lslock(m_LSLock); - - if (NULL != m_pListener) - return -1; - - m_pListener = u; - return 0; -} - -void CRcvQueue::removeListener(const CUDT* u) -{ - CGuard lslock(m_LSLock); - - if (u == m_pListener) - m_pListener = NULL; -} - -void CRcvQueue::registerConnector(const UDTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl) -{ - m_pRendezvousQueue->insert(id, u, ipv, addr, ttl); -} - -void CRcvQueue::removeConnector(const UDTSOCKET& id) -{ - m_pRendezvousQueue->remove(id); - - CGuard bufferlock(m_PassLock); - - map >::iterator i = m_mBuffer.find(id); - if (i != m_mBuffer.end()) - { - while (!i->second.empty()) - { - delete [] i->second.front()->m_pcData; - delete i->second.front(); - i->second.pop(); - } - m_mBuffer.erase(i); - } -} - -void CRcvQueue::setNewEntry(CUDT* u) -{ - CGuard listguard(m_IDLock); - m_vNewEntry.push_back(u); -} - -bool CRcvQueue::ifNewEntry() -{ - return !(m_vNewEntry.empty()); -} - -CUDT* CRcvQueue::getNewEntry() -{ - CGuard listguard(m_IDLock); - - if (m_vNewEntry.empty()) - return NULL; - - CUDT* u = (CUDT*)*(m_vNewEntry.begin()); - m_vNewEntry.erase(m_vNewEntry.begin()); - - return u; -} - -void CRcvQueue::storePkt(int32_t id, CPacket* pkt) -{ - CGuard bufferlock(m_PassLock); - - map >::iterator i = m_mBuffer.find(id); - - if (i == m_mBuffer.end()) - { - m_mBuffer[id].push(pkt); - - #ifndef WIN32 - pthread_cond_signal(&m_PassCond); - #else - SetEvent(m_PassCond); - #endif - } - else - { - //avoid storing too many packets, in case of malfunction or attack - if (i->second.size() > 16) - return; - - i->second.push(pkt); - } -} diff --git a/vendor/udt4/src/queue.h b/vendor/udt4/src/queue.h deleted file mode 100644 index 9feff18..0000000 --- a/vendor/udt4/src/queue.h +++ /dev/null @@ -1,527 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/12/2011 -*****************************************************************************/ - - -#ifndef __UDT_QUEUE_H__ -#define __UDT_QUEUE_H__ - -#include "channel.h" -#include "common.h" -#include "packet.h" -#include -#include -#include -#include - -class CUDT; - -struct CUnit -{ - CPacket m_Packet; // packet - int m_iFlag; // 0: free, 1: occupied, 2: msg read but not freed (out-of-order), 3: msg dropped -}; - -class CUnitQueue -{ -friend class CRcvQueue; -friend class CRcvBuffer; - -public: - CUnitQueue(); - ~CUnitQueue(); - -public: - - // Functionality: - // Initialize the unit queue. - // Parameters: - // 1) [in] size: queue size - // 2) [in] mss: maximum segament size - // 3) [in] version: IP version - // Returned value: - // 0: success, -1: failure. - - int init(int size, int mss, int version); - - // Functionality: - // Increase (double) the unit queue size. - // Parameters: - // None. - // Returned value: - // 0: success, -1: failure. - - int increase(); - - // Functionality: - // Decrease (halve) the unit queue size. - // Parameters: - // None. - // Returned value: - // 0: success, -1: failure. - - int shrink(); - - // Functionality: - // find an available unit for incoming packet. - // Parameters: - // None. - // Returned value: - // Pointer to the available unit, NULL if not found. - - CUnit* getNextAvailUnit(); - -private: - struct CQEntry - { - CUnit* m_pUnit; // unit queue - char* m_pBuffer; // data buffer - int m_iSize; // size of each queue - - CQEntry* m_pNext; - } - *m_pQEntry, // pointer to the first unit queue - *m_pCurrQueue, // pointer to the current available queue - *m_pLastQueue; // pointer to the last unit queue - - CUnit* m_pAvailUnit; // recent available unit - - int m_iSize; // total size of the unit queue, in number of packets - int m_iCount; // total number of valid packets in the queue - - int m_iMSS; // unit buffer size - int m_iIPversion; // IP version - -private: - CUnitQueue(const CUnitQueue&); - CUnitQueue& operator=(const CUnitQueue&); -}; - -struct CSNode -{ - CUDT* m_pUDT; // Pointer to the instance of CUDT socket - uint64_t m_llTimeStamp; // Time Stamp - - int m_iHeapLoc; // location on the heap, -1 means not on the heap -}; - -class CSndUList -{ -friend class CSndQueue; - -public: - CSndUList(); - ~CSndUList(); - -public: - - // Functionality: - // Insert a new UDT instance into the list. - // Parameters: - // 1) [in] ts: time stamp: next processing time - // 2) [in] u: pointer to the UDT instance - // Returned value: - // None. - - void insert(int64_t ts, const CUDT* u); - - // Functionality: - // Update the timestamp of the UDT instance on the list. - // Parameters: - // 1) [in] u: pointer to the UDT instance - // 2) [in] resechedule: if the timestampe shoudl be rescheduled - // Returned value: - // None. - - void update(const CUDT* u, bool reschedule = true); - - // Functionality: - // Retrieve the next packet and peer address from the first entry, and reschedule it in the queue. - // Parameters: - // 0) [out] addr: destination address of the next packet - // 1) [out] pkt: the next packet to be sent - // Returned value: - // 1 if successfully retrieved, -1 if no packet found. - - int pop(sockaddr*& addr, CPacket& pkt); - - // Functionality: - // Remove UDT instance from the list. - // Parameters: - // 1) [in] u: pointer to the UDT instance - // Returned value: - // None. - - void remove(const CUDT* u); - - // Functionality: - // Retrieve the next scheduled processing time. - // Parameters: - // None. - // Returned value: - // Scheduled processing time of the first UDT socket in the list. - - uint64_t getNextProcTime(); - -private: - void insert_(int64_t ts, const CUDT* u); - void remove_(const CUDT* u); - -private: - CSNode** m_pHeap; // The heap array - int m_iArrayLength; // physical length of the array - int m_iLastEntry; // position of last entry on the heap array - - pthread_mutex_t m_ListLock; - - pthread_mutex_t* m_pWindowLock; - pthread_cond_t* m_pWindowCond; - - CTimer* m_pTimer; - -private: - CSndUList(const CSndUList&); - CSndUList& operator=(const CSndUList&); -}; - -struct CRNode -{ - CUDT* m_pUDT; // Pointer to the instance of CUDT socket - uint64_t m_llTimeStamp; // Time Stamp - - CRNode* m_pPrev; // previous link - CRNode* m_pNext; // next link - - bool m_bOnList; // if the node is already on the list -}; - -class CRcvUList -{ -public: - CRcvUList(); - ~CRcvUList(); - -public: - - // Functionality: - // Insert a new UDT instance to the list. - // Parameters: - // 1) [in] u: pointer to the UDT instance - // Returned value: - // None. - - void insert(const CUDT* u); - - // Functionality: - // Remove the UDT instance from the list. - // Parameters: - // 1) [in] u: pointer to the UDT instance - // Returned value: - // None. - - void remove(const CUDT* u); - - // Functionality: - // Move the UDT instance to the end of the list, if it already exists; otherwise, do nothing. - // Parameters: - // 1) [in] u: pointer to the UDT instance - // Returned value: - // None. - - void update(const CUDT* u); - -public: - CRNode* m_pUList; // the head node - -private: - CRNode* m_pLast; // the last node - -private: - CRcvUList(const CRcvUList&); - CRcvUList& operator=(const CRcvUList&); -}; - -class CHash -{ -public: - CHash(); - ~CHash(); - -public: - - // Functionality: - // Initialize the hash table. - // Parameters: - // 1) [in] size: hash table size - // Returned value: - // None. - - void init(int size); - - // Functionality: - // Look for a UDT instance from the hash table. - // Parameters: - // 1) [in] id: socket ID - // Returned value: - // Pointer to a UDT instance, or NULL if not found. - - CUDT* lookup(int32_t id); - - // Functionality: - // Insert an entry to the hash table. - // Parameters: - // 1) [in] id: socket ID - // 2) [in] u: pointer to the UDT instance - // Returned value: - // None. - - void insert(int32_t id, CUDT* u); - - // Functionality: - // Remove an entry from the hash table. - // Parameters: - // 1) [in] id: socket ID - // Returned value: - // None. - - void remove(int32_t id); - -private: - struct CBucket - { - int32_t m_iID; // Socket ID - CUDT* m_pUDT; // Socket instance - - CBucket* m_pNext; // next bucket - } **m_pBucket; // list of buckets (the hash table) - - int m_iHashSize; // size of hash table - -private: - CHash(const CHash&); - CHash& operator=(const CHash&); -}; - -class CRendezvousQueue -{ -public: - CRendezvousQueue(); - ~CRendezvousQueue(); - -public: - void insert(const UDTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl); - void remove(const UDTSOCKET& id); - CUDT* retrieve(const sockaddr* addr, UDTSOCKET& id); - - void updateConnStatus(); - -private: - struct CRL - { - UDTSOCKET m_iID; // UDT socket ID (self) - CUDT* m_pUDT; // UDT instance - int m_iIPversion; // IP version - sockaddr* m_pPeerAddr; // UDT sonnection peer address - uint64_t m_ullTTL; // the time that this request expires - }; - std::list m_lRendezvousID; // The sockets currently in rendezvous mode - - pthread_mutex_t m_RIDVectorLock; -}; - -class CSndQueue -{ -friend class CUDT; -friend class CUDTUnited; - -public: - CSndQueue(); - ~CSndQueue(); - -public: - - // Functionality: - // Initialize the sending queue. - // Parameters: - // 1) [in] c: UDP channel to be associated to the queue - // 2) [in] t: Timer - // Returned value: - // None. - - void init(CChannel* c, CTimer* t); - - // Functionality: - // Send out a packet to a given address. - // Parameters: - // 1) [in] addr: destination address - // 2) [in] packet: packet to be sent out - // Returned value: - // Size of data sent out. - - int sendto(const sockaddr* addr, CPacket& packet); - -private: -#ifndef WIN32 - static void* worker(void* param); -#else - static DWORD WINAPI worker(LPVOID param); -#endif - - pthread_t m_WorkerThread; - -private: - CSndUList* m_pSndUList; // List of UDT instances for data sending - CChannel* m_pChannel; // The UDP channel for data sending - CTimer* m_pTimer; // Timing facility - - pthread_mutex_t m_WindowLock; - pthread_cond_t m_WindowCond; - - volatile bool m_bClosing; // closing the worker - pthread_cond_t m_ExitCond; - -private: - CSndQueue(const CSndQueue&); - CSndQueue& operator=(const CSndQueue&); -}; - -class CRcvQueue -{ -friend class CUDT; -friend class CUDTUnited; - -public: - CRcvQueue(); - ~CRcvQueue(); - -public: - - // Functionality: - // Initialize the receiving queue. - // Parameters: - // 1) [in] size: queue size - // 2) [in] mss: maximum packet size - // 3) [in] version: IP version - // 4) [in] hsize: hash table size - // 5) [in] c: UDP channel to be associated to the queue - // 6) [in] t: timer - // Returned value: - // None. - - void init(int size, int payload, int version, int hsize, CChannel* c, CTimer* t); - - // Functionality: - // Read a packet for a specific UDT socket id. - // Parameters: - // 1) [in] id: Socket ID - // 2) [out] packet: received packet - // Returned value: - // Data size of the packet - - int recvfrom(int32_t id, CPacket& packet); - -private: -#ifndef WIN32 - static void* worker(void* param); -#else - static DWORD WINAPI worker(LPVOID param); -#endif - - pthread_t m_WorkerThread; - -private: - CUnitQueue m_UnitQueue; // The received packet queue - - CRcvUList* m_pRcvUList; // List of UDT instances that will read packets from the queue - CHash* m_pHash; // Hash table for UDT socket looking up - CChannel* m_pChannel; // UDP channel for receving packets - CTimer* m_pTimer; // shared timer with the snd queue - - int m_iPayloadSize; // packet payload size - - volatile bool m_bClosing; // closing the workder - pthread_cond_t m_ExitCond; - -private: - int setListener(CUDT* u); - void removeListener(const CUDT* u); - - void registerConnector(const UDTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl); - void removeConnector(const UDTSOCKET& id); - - void setNewEntry(CUDT* u); - bool ifNewEntry(); - CUDT* getNewEntry(); - - void storePkt(int32_t id, CPacket* pkt); - -private: - pthread_mutex_t m_LSLock; - CUDT* m_pListener; // pointer to the (unique, if any) listening UDT entity - CRendezvousQueue* m_pRendezvousQueue; // The list of sockets in rendezvous mode - - std::vector m_vNewEntry; // newly added entries, to be inserted - pthread_mutex_t m_IDLock; - - std::map > m_mBuffer; // temporary buffer for rendezvous connection request - pthread_mutex_t m_PassLock; - pthread_cond_t m_PassCond; - -private: - CRcvQueue(const CRcvQueue&); - CRcvQueue& operator=(const CRcvQueue&); -}; - -struct CMultiplexer -{ - CSndQueue* m_pSndQueue; // The sending queue - CRcvQueue* m_pRcvQueue; // The receiving queue - CChannel* m_pChannel; // The UDP channel for sending and receiving - CTimer* m_pTimer; // The timer - - int m_iPort; // The UDP port number of this multiplexer - int m_iIPversion; // IP version - int m_iMSS; // Maximum Segment Size - int m_iRefCount; // number of UDT instances that are associated with this multiplexer - bool m_bReusable; // if this one can be shared with others - - int m_iID; // multiplexer ID -}; - -#endif diff --git a/vendor/udt4/src/udt.h b/vendor/udt4/src/udt.h deleted file mode 100644 index 7dc75a3..0000000 --- a/vendor/udt4/src/udt.h +++ /dev/null @@ -1,359 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/18/2011 -*****************************************************************************/ - -#ifndef __UDT_H__ -#define __UDT_H__ - - -#ifndef WIN32 - #include - #include - #include -#else - #ifdef __MINGW__ - #include - #include - #endif - #include -#endif -#include -#include -#include -#include - -#include - - -//////////////////////////////////////////////////////////////////////////////// - -//if compiling on VC6.0 or pre-WindowsXP systems -//use -DLEGACY_WIN32 - -//if compiling with MinGW, it only works on XP or above -//use -D_WIN32_WINNT=0x0501 - - -#ifdef WIN32 - #if !defined(__MINGW__) && defined(UDT_IS_DLL) - // Explicitly define 32-bit and 64-bit numbers - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - #ifndef LEGACY_WIN32 - typedef unsigned __int64 uint64_t; - #else - // VC 6.0 does not support unsigned __int64: may cause potential problems. - typedef __int64 uint64_t; - #endif - - #ifdef UDT_EXPORTS - #define UDT_API __declspec(dllexport) - #else - #define UDT_API __declspec(dllimport) - #endif - #else - #define UDT_API - #endif -#else - #define UDT_API __attribute__ ((visibility("default"))) -#endif - -#define NO_BUSY_WAITING - -#ifdef WIN32 - #ifndef __MINGW__ - typedef SOCKET SYSSOCKET; - #else - typedef int SYSSOCKET; - #endif -#else - typedef int SYSSOCKET; -#endif - -typedef SYSSOCKET UDPSOCKET; -typedef int UDTSOCKET; - -//////////////////////////////////////////////////////////////////////////////// - -typedef std::set ud_set; -#define UD_CLR(u, uset) ((uset)->erase(u)) -#define UD_ISSET(u, uset) ((uset)->find(u) != (uset)->end()) -#define UD_SET(u, uset) ((uset)->insert(u)) -#define UD_ZERO(uset) ((uset)->clear()) - -enum EPOLLOpt -{ - // this values are defined same as linux epoll.h - // so that if system values are used by mistake, they should have the same effect - UDT_EPOLL_IN = 0x1, - UDT_EPOLL_OUT = 0x4, - UDT_EPOLL_ERR = 0x8 -}; - -enum UDTSTATUS {INIT = 1, OPENED, LISTENING, CONNECTING, CONNECTED, BROKEN, CLOSING, CLOSED, NONEXIST}; - -//////////////////////////////////////////////////////////////////////////////// - -enum UDTOpt -{ - UDT_MSS, // the Maximum Transfer Unit - UDT_SNDSYN, // if sending is blocking - UDT_RCVSYN, // if receiving is blocking - UDT_CC, // custom congestion control algorithm - UDT_FC, // Flight flag size (window size) - UDT_SNDBUF, // maximum buffer in sending queue - UDT_RCVBUF, // UDT receiving buffer size - UDT_LINGER, // waiting for unsent data when closing - UDP_SNDBUF, // UDP sending buffer size - UDP_RCVBUF, // UDP receiving buffer size - UDT_MAXMSG, // maximum datagram message size - UDT_MSGTTL, // time-to-live of a datagram message - UDT_RENDEZVOUS, // rendezvous connection mode - UDT_SNDTIMEO, // send() timeout - UDT_RCVTIMEO, // recv() timeout - UDT_REUSEADDR, // reuse an existing port or create a new one - UDT_MAXBW, // maximum bandwidth (bytes per second) that the connection can use - UDT_STATE, // current socket state, see UDTSTATUS, read only - UDT_EVENT, // current avalable events associated with the socket - UDT_SNDDATA, // size of data in the sending buffer - UDT_RCVDATA // size of data available for recv -}; - -//////////////////////////////////////////////////////////////////////////////// - -struct CPerfMon -{ - // global measurements - int64_t msTimeStamp; // time since the UDT entity is started, in milliseconds - int64_t pktSentTotal; // total number of sent data packets, including retransmissions - int64_t pktRecvTotal; // total number of received packets - int pktSndLossTotal; // total number of lost packets (sender side) - int pktRcvLossTotal; // total number of lost packets (receiver side) - int pktRetransTotal; // total number of retransmitted packets - int pktSentACKTotal; // total number of sent ACK packets - int pktRecvACKTotal; // total number of received ACK packets - int pktSentNAKTotal; // total number of sent NAK packets - int pktRecvNAKTotal; // total number of received NAK packets - int64_t usSndDurationTotal; // total time duration when UDT is sending data (idle time exclusive) - - // local measurements - int64_t pktSent; // number of sent data packets, including retransmissions - int64_t pktRecv; // number of received packets - int pktSndLoss; // number of lost packets (sender side) - int pktRcvLoss; // number of lost packets (receiver side) - int pktRetrans; // number of retransmitted packets - int pktSentACK; // number of sent ACK packets - int pktRecvACK; // number of received ACK packets - int pktSentNAK; // number of sent NAK packets - int pktRecvNAK; // number of received NAK packets - double mbpsSendRate; // sending rate in Mb/s - double mbpsRecvRate; // receiving rate in Mb/s - int64_t usSndDuration; // busy sending time (i.e., idle time exclusive) - - // instant measurements - double usPktSndPeriod; // packet sending period, in microseconds - int pktFlowWindow; // flow window size, in number of packets - int pktCongestionWindow; // congestion window size, in number of packets - int pktFlightSize; // number of packets on flight - double msRTT; // RTT, in milliseconds - double mbpsBandwidth; // estimated bandwidth, in Mb/s - int byteAvailSndBuf; // available UDT sender buffer size - int byteAvailRcvBuf; // available UDT receiver buffer size -}; - -//////////////////////////////////////////////////////////////////////////////// - -class UDT_API CUDTException -{ -public: - CUDTException(int major = 0, int minor = 0, int err = -1); - CUDTException(const CUDTException& e); - virtual ~CUDTException(); - - // Functionality: - // Get the description of the exception. - // Parameters: - // None. - // Returned value: - // Text message for the exception description. - - virtual const char* getErrorMessage(); - - // Functionality: - // Get the system errno for the exception. - // Parameters: - // None. - // Returned value: - // errno. - - virtual int getErrorCode() const; - - // Functionality: - // Clear the error code. - // Parameters: - // None. - // Returned value: - // None. - - virtual void clear(); - -private: - int m_iMajor; // major exception categories - -// 0: correct condition -// 1: network setup exception -// 2: network connection broken -// 3: memory exception -// 4: file exception -// 5: method not supported -// 6+: undefined error - - int m_iMinor; // for specific error reasons - int m_iErrno; // errno returned by the system if there is any - std::string m_strMsg; // text error message - - std::string m_strAPI; // the name of UDT function that returns the error - std::string m_strDebug; // debug information, set to the original place that causes the error - -public: // Error Code - static const int SUCCESS; - static const int ECONNSETUP; - static const int ENOSERVER; - static const int ECONNREJ; - static const int ESOCKFAIL; - static const int ESECFAIL; - static const int ECONNFAIL; - static const int ECONNLOST; - static const int ENOCONN; - static const int ERESOURCE; - static const int ETHREAD; - static const int ENOBUF; - static const int EFILE; - static const int EINVRDOFF; - static const int ERDPERM; - static const int EINVWROFF; - static const int EWRPERM; - static const int EINVOP; - static const int EBOUNDSOCK; - static const int ECONNSOCK; - static const int EINVPARAM; - static const int EINVSOCK; - static const int EUNBOUNDSOCK; - static const int ENOLISTEN; - static const int ERDVNOSERV; - static const int ERDVUNBOUND; - static const int ESTREAMILL; - static const int EDGRAMILL; - static const int EDUPLISTEN; - static const int ELARGEMSG; - static const int EINVPOLLID; - static const int EASYNCFAIL; - static const int EASYNCSND; - static const int EASYNCRCV; - static const int ETIMEOUT; - static const int EPEERERR; - static const int EUNKNOWN; -}; - -//////////////////////////////////////////////////////////////////////////////// - -// If you need to export these APIs to be used by a different language, -// declare extern "C" for them, and add a "udt_" prefix to each API. -// The following APIs: sendfile(), recvfile(), epoll_wait(), geterrormsg(), -// include C++ specific feature, please use the corresponding sendfile2(), etc. - -namespace UDT -{ - -typedef CUDTException ERRORINFO; -typedef UDTOpt SOCKOPT; -typedef CPerfMon TRACEINFO; -typedef ud_set UDSET; - -UDT_API extern const UDTSOCKET INVALID_SOCK; -#undef ERROR -UDT_API extern const int ERROR; - -UDT_API int startup(); -UDT_API int cleanup(); -UDT_API UDTSOCKET socket(int af, int type, int protocol); -UDT_API int bind(UDTSOCKET u, const struct sockaddr* name, int namelen); -UDT_API int bind2(UDTSOCKET u, UDPSOCKET udpsock); -UDT_API int listen(UDTSOCKET u, int backlog); -UDT_API UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen); -UDT_API int connect(UDTSOCKET u, const struct sockaddr* name, int namelen); -UDT_API int close(UDTSOCKET u); -UDT_API int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen); -UDT_API int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen); -UDT_API int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optlen); -UDT_API int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int optlen); -UDT_API int send(UDTSOCKET u, const char* buf, int len, int flags); -UDT_API int recv(UDTSOCKET u, char* buf, int len, int flags); -UDT_API int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false); -UDT_API int recvmsg(UDTSOCKET u, char* buf, int len); -UDT_API int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000); -UDT_API int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000); -UDT_API int64_t sendfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 364000); -UDT_API int64_t recvfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 7280000); - -// select and selectEX are DEPRECATED; please use epoll. -UDT_API int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout); -UDT_API int selectEx(const std::vector& fds, std::vector* readfds, - std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); - -UDT_API int epoll_create(); -UDT_API int epoll_add_usock(int eid, UDTSOCKET u, const int* events = NULL); -UDT_API int epoll_add_ssock(int eid, SYSSOCKET s, const int* events = NULL); -UDT_API int epoll_remove_usock(int eid, UDTSOCKET u); -UDT_API int epoll_remove_ssock(int eid, SYSSOCKET s); -UDT_API int epoll_wait(int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, - std::set* lrfds = NULL, std::set* wrfds = NULL); -UDT_API int epoll_wait2(int eid, UDTSOCKET* readfds, int* rnum, UDTSOCKET* writefds, int* wnum, int64_t msTimeOut, - SYSSOCKET* lrfds = NULL, int* lrnum = NULL, SYSSOCKET* lwfds = NULL, int* lwnum = NULL); -UDT_API int epoll_release(int eid); -UDT_API ERRORINFO& getlasterror(); -UDT_API int getlasterror_code(); -UDT_API const char* getlasterror_desc(); -UDT_API int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear = true); -UDT_API UDTSTATUS getsockstate(UDTSOCKET u); - -} // namespace UDT - -#endif diff --git a/vendor/udt4/src/window.cpp b/vendor/udt4/src/window.cpp deleted file mode 100644 index bca37e9..0000000 --- a/vendor/udt4/src/window.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/22/2011 -*****************************************************************************/ - -#include -#include "common.h" -#include "window.h" -#include - -using namespace std; - -CACKWindow::CACKWindow(int size): -m_piACKSeqNo(NULL), -m_piACK(NULL), -m_pTimeStamp(NULL), -m_iSize(size), -m_iHead(0), -m_iTail(0) -{ - m_piACKSeqNo = new int32_t[m_iSize]; - m_piACK = new int32_t[m_iSize]; - m_pTimeStamp = new uint64_t[m_iSize]; - - m_piACKSeqNo[0] = -1; -} - -CACKWindow::~CACKWindow() -{ - delete [] m_piACKSeqNo; - delete [] m_piACK; - delete [] m_pTimeStamp; -} - -void CACKWindow::store(int32_t seq, int32_t ack) -{ - m_piACKSeqNo[m_iHead] = seq; - m_piACK[m_iHead] = ack; - m_pTimeStamp[m_iHead] = CTimer::getTime(); - - m_iHead = (m_iHead + 1) % m_iSize; - - // overwrite the oldest ACK since it is not likely to be acknowledged - if (m_iHead == m_iTail) - m_iTail = (m_iTail + 1) % m_iSize; -} - -int CACKWindow::acknowledge(int32_t seq, int32_t& ack) -{ - if (m_iHead >= m_iTail) - { - // Head has not exceeded the physical boundary of the window - - for (int i = m_iTail, n = m_iHead; i < n; ++ i) - { - // looking for indentical ACK Seq. No. - if (seq == m_piACKSeqNo[i]) - { - // return the Data ACK it carried - ack = m_piACK[i]; - - // calculate RTT - int rtt = int(CTimer::getTime() - m_pTimeStamp[i]); - - if (i + 1 == m_iHead) - { - m_iTail = m_iHead = 0; - m_piACKSeqNo[0] = -1; - } - else - m_iTail = (i + 1) % m_iSize; - - return rtt; - } - } - - // Bad input, the ACK node has been overwritten - return -1; - } - - // Head has exceeded the physical window boundary, so it is behind tail - for (int j = m_iTail, n = m_iHead + m_iSize; j < n; ++ j) - { - // looking for indentical ACK seq. no. - if (seq == m_piACKSeqNo[j % m_iSize]) - { - // return Data ACK - j %= m_iSize; - ack = m_piACK[j]; - - // calculate RTT - int rtt = int(CTimer::getTime() - m_pTimeStamp[j]); - - if (j == m_iHead) - { - m_iTail = m_iHead = 0; - m_piACKSeqNo[0] = -1; - } - else - m_iTail = (j + 1) % m_iSize; - - return rtt; - } - } - - // bad input, the ACK node has been overwritten - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// - -CPktTimeWindow::CPktTimeWindow(int asize, int psize): -m_iAWSize(asize), -m_piPktWindow(NULL), -m_iPktWindowPtr(0), -m_iPWSize(psize), -m_piProbeWindow(NULL), -m_iProbeWindowPtr(0), -m_iLastSentTime(0), -m_iMinPktSndInt(1000000), -m_LastArrTime(), -m_CurrArrTime(), -m_ProbeTime() -{ - m_piPktWindow = new int[m_iAWSize]; - m_piPktReplica = new int[m_iAWSize]; - m_piProbeWindow = new int[m_iPWSize]; - m_piProbeReplica = new int[m_iPWSize]; - - m_LastArrTime = CTimer::getTime(); - - for (int i = 0; i < m_iAWSize; ++ i) - m_piPktWindow[i] = 1000000; - - for (int k = 0; k < m_iPWSize; ++ k) - m_piProbeWindow[k] = 1000; -} - -CPktTimeWindow::~CPktTimeWindow() -{ - delete [] m_piPktWindow; - delete [] m_piPktReplica; - delete [] m_piProbeWindow; - delete [] m_piProbeReplica; -} - -int CPktTimeWindow::getMinPktSndInt() const -{ - return m_iMinPktSndInt; -} - -int CPktTimeWindow::getPktRcvSpeed() const -{ - // get median value, but cannot change the original value order in the window - std::copy(m_piPktWindow, m_piPktWindow + m_iAWSize - 1, m_piPktReplica); - std::nth_element(m_piPktReplica, m_piPktReplica + (m_iAWSize / 2), m_piPktReplica + m_iAWSize - 1); - int median = m_piPktReplica[m_iAWSize / 2]; - - int count = 0; - int sum = 0; - int upper = median << 3; - int lower = median >> 3; - - // median filtering - int* p = m_piPktWindow; - for (int i = 0, n = m_iAWSize; i < n; ++ i) - { - if ((*p < upper) && (*p > lower)) - { - ++ count; - sum += *p; - } - ++ p; - } - - // claculate speed, or return 0 if not enough valid value - if (count > (m_iAWSize >> 1)) - return (int)ceil(1000000.0 / (sum / count)); - else - return 0; -} - -int CPktTimeWindow::getBandwidth() const -{ - // get median value, but cannot change the original value order in the window - std::copy(m_piProbeWindow, m_piProbeWindow + m_iPWSize - 1, m_piProbeReplica); - std::nth_element(m_piProbeReplica, m_piProbeReplica + (m_iPWSize / 2), m_piProbeReplica + m_iPWSize - 1); - int median = m_piProbeReplica[m_iPWSize / 2]; - - int count = 1; - int sum = median; - int upper = median << 3; - int lower = median >> 3; - - // median filtering - int* p = m_piProbeWindow; - for (int i = 0, n = m_iPWSize; i < n; ++ i) - { - if ((*p < upper) && (*p > lower)) - { - ++ count; - sum += *p; - } - ++ p; - } - - return (int)ceil(1000000.0 / (double(sum) / double(count))); -} - -void CPktTimeWindow::onPktSent(int currtime) -{ - int interval = currtime - m_iLastSentTime; - - if ((interval < m_iMinPktSndInt) && (interval > 0)) - m_iMinPktSndInt = interval; - - m_iLastSentTime = currtime; -} - -void CPktTimeWindow::onPktArrival() -{ - m_CurrArrTime = CTimer::getTime(); - - // record the packet interval between the current and the last one - *(m_piPktWindow + m_iPktWindowPtr) = int(m_CurrArrTime - m_LastArrTime); - - // the window is logically circular - ++ m_iPktWindowPtr; - if (m_iPktWindowPtr == m_iAWSize) - m_iPktWindowPtr = 0; - - // remember last packet arrival time - m_LastArrTime = m_CurrArrTime; -} - -void CPktTimeWindow::probe1Arrival() -{ - m_ProbeTime = CTimer::getTime(); -} - -void CPktTimeWindow::probe2Arrival() -{ - m_CurrArrTime = CTimer::getTime(); - - // record the probing packets interval - *(m_piProbeWindow + m_iProbeWindowPtr) = int(m_CurrArrTime - m_ProbeTime); - // the window is logically circular - ++ m_iProbeWindowPtr; - if (m_iProbeWindowPtr == m_iPWSize) - m_iProbeWindowPtr = 0; -} diff --git a/vendor/udt4/src/window.h b/vendor/udt4/src/window.h deleted file mode 100644 index f118a26..0000000 --- a/vendor/udt4/src/window.h +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/22/2011 -*****************************************************************************/ - -#ifndef __UDT_WINDOW_H__ -#define __UDT_WINDOW_H__ - - -#ifndef WIN32 - #include - #include -#endif -#include "udt.h" - - -class CACKWindow -{ -public: - CACKWindow(int size = 1024); - ~CACKWindow(); - - // Functionality: - // Write an ACK record into the window. - // Parameters: - // 0) [in] seq: ACK seq. no. - // 1) [in] ack: DATA ACK no. - // Returned value: - // None. - - void store(int32_t seq, int32_t ack); - - // Functionality: - // Search the ACK-2 "seq" in the window, find out the DATA "ack" and caluclate RTT . - // Parameters: - // 0) [in] seq: ACK-2 seq. no. - // 1) [out] ack: the DATA ACK no. that matches the ACK-2 no. - // Returned value: - // RTT. - - int acknowledge(int32_t seq, int32_t& ack); - -private: - int32_t* m_piACKSeqNo; // Seq. No. for the ACK packet - int32_t* m_piACK; // Data Seq. No. carried by the ACK packet - uint64_t* m_pTimeStamp; // The timestamp when the ACK was sent - - int m_iSize; // Size of the ACK history window - int m_iHead; // Pointer to the lastest ACK record - int m_iTail; // Pointer to the oldest ACK record - -private: - CACKWindow(const CACKWindow&); - CACKWindow& operator=(const CACKWindow&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CPktTimeWindow -{ -public: - CPktTimeWindow(int asize = 16, int psize = 16); - ~CPktTimeWindow(); - - // Functionality: - // read the minimum packet sending interval. - // Parameters: - // None. - // Returned value: - // minimum packet sending interval (microseconds). - - int getMinPktSndInt() const; - - // Functionality: - // Calculate the packes arrival speed. - // Parameters: - // None. - // Returned value: - // Packet arrival speed (packets per second). - - int getPktRcvSpeed() const; - - // Functionality: - // Estimate the bandwidth. - // Parameters: - // None. - // Returned value: - // Estimated bandwidth (packets per second). - - int getBandwidth() const; - - // Functionality: - // Record time information of a packet sending. - // Parameters: - // 0) currtime: timestamp of the packet sending. - // Returned value: - // None. - - void onPktSent(int currtime); - - // Functionality: - // Record time information of an arrived packet. - // Parameters: - // None. - // Returned value: - // None. - - void onPktArrival(); - - // Functionality: - // Record the arrival time of the first probing packet. - // Parameters: - // None. - // Returned value: - // None. - - void probe1Arrival(); - - // Functionality: - // Record the arrival time of the second probing packet and the interval between packet pairs. - // Parameters: - // None. - // Returned value: - // None. - - void probe2Arrival(); - -private: - int m_iAWSize; // size of the packet arrival history window - int* m_piPktWindow; // packet information window - int* m_piPktReplica; - int m_iPktWindowPtr; // position pointer of the packet info. window. - - int m_iPWSize; // size of probe history window size - int* m_piProbeWindow; // record inter-packet time for probing packet pairs - int* m_piProbeReplica; - int m_iProbeWindowPtr; // position pointer to the probing window - - int m_iLastSentTime; // last packet sending time - int m_iMinPktSndInt; // Minimum packet sending interval - - uint64_t m_LastArrTime; // last packet arrival time - uint64_t m_CurrArrTime; // current packet arrival time - uint64_t m_ProbeTime; // arrival time of the first probing packet - -private: - CPktTimeWindow(const CPktTimeWindow&); - CPktTimeWindow &operator=(const CPktTimeWindow&); -}; - - -#endif