├── .clang-format ├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── app ├── common │ ├── server_base.cpp │ └── server_base.h ├── sp │ ├── sp_cs_manager.cpp │ ├── sp_cs_manager.h │ ├── sp_np_manager.cpp │ ├── sp_np_manager.h │ ├── sp_tracker_manager.cpp │ ├── sp_tracker_manager.h │ └── superpeer_server.cpp └── tracker │ ├── tracker_np_manager.cpp │ ├── tracker_np_manager.h │ ├── tracker_server.cpp │ ├── tracker_sp_manager.cpp │ └── tracker_sp_manager.h ├── build_all.sh ├── common.mk ├── core ├── async_logger.cpp ├── async_logger.h ├── bitrate_calculator.cpp ├── bitrate_calculator.h ├── buffer.cpp ├── buffer.h ├── core_struct.h ├── debug_utility.cpp ├── debug_utility.h ├── error_code.h ├── hash.h ├── interval_array.h ├── logger.cpp ├── logger.h ├── message.cpp ├── message.h ├── p2p_protocol.h ├── resource.h ├── socket.cpp ├── socket.h ├── socket_connect.cpp ├── socket_connect.h ├── socket_handler.h ├── streamer.cpp ├── streamer.h ├── struct_define.h ├── system_time.cpp ├── system_time.h ├── tcp_listener.cpp ├── tcp_listener.h ├── thread.cpp ├── thread.h ├── timer.cpp ├── timer.h ├── udp_listener.cpp └── udp_listener.h ├── doc ├── rabbitstreamer_architecture.png └── system_architecture.png ├── protocol ├── common │ ├── buffer_queue.cpp │ └── buffer_queue.h ├── sp │ ├── sp_cs_connector.cpp │ ├── sp_cs_connector.h │ ├── sp_np_connector.cpp │ ├── sp_np_connector.h │ ├── sp_source_manager.cpp │ ├── sp_source_manager.h │ ├── sp_tracker_connector.cpp │ └── sp_tracker_connector.h └── tracker │ ├── tracker_np_connector.cpp │ ├── tracker_np_connector.h │ ├── tracker_np_manager.cpp │ ├── tracker_np_manager.h │ ├── tracker_sp_connector.cpp │ ├── tracker_sp_connector.h │ ├── tracker_streamer_manager.cpp │ └── tracker_streamer_manager.h ├── tests └── streamer_test.cpp └── third_party ├── md5 ├── md5.cpp └── md5.h └── st-1.9.zip /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Right 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | AfterExternBlock: false 33 | BeforeCatch: false 34 | BeforeElse: false 35 | IndentBraces: false 36 | SplitEmptyFunction: true 37 | SplitEmptyRecord: true 38 | SplitEmptyNamespace: true 39 | BreakBeforeBinaryOperators: None 40 | BreakBeforeBraces: Attach 41 | BreakBeforeInheritanceComma: false 42 | BreakBeforeTernaryOperators: true 43 | BreakConstructorInitializersBeforeComma: false 44 | BreakConstructorInitializers: BeforeColon 45 | BreakAfterJavaFieldAnnotations: false 46 | BreakStringLiterals: true 47 | ColumnLimit: 80 48 | CommentPragmas: '^ IWYU pragma:' 49 | CompactNamespaces: false 50 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 51 | ConstructorInitializerIndentWidth: 4 52 | ContinuationIndentWidth: 4 53 | Cpp11BracedListStyle: true 54 | DerivePointerAlignment: false 55 | DisableFormat: false 56 | ExperimentalAutoDetectBinPacking: false 57 | FixNamespaceComments: true 58 | ForEachMacros: 59 | - foreach 60 | - Q_FOREACH 61 | - BOOST_FOREACH 62 | IncludeBlocks: Preserve 63 | IncludeCategories: 64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 65 | Priority: 2 66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 67 | Priority: 3 68 | - Regex: '.*' 69 | Priority: 1 70 | IncludeIsMainRegex: '(Test)?$' 71 | IndentCaseLabels: false 72 | IndentPPDirectives: None 73 | IndentWidth: 4 74 | IndentWrappedFunctionNames: false 75 | JavaScriptQuotes: Leave 76 | JavaScriptWrapImports: true 77 | KeepEmptyLinesAtTheStartOfBlocks: true 78 | MacroBlockBegin: '' 79 | MacroBlockEnd: '' 80 | MaxEmptyLinesToKeep: 1 81 | NamespaceIndentation: None 82 | ObjCBlockIndentWidth: 2 83 | ObjCSpaceAfterProperty: false 84 | ObjCSpaceBeforeProtocolList: true 85 | PenaltyBreakAssignment: 2 86 | PenaltyBreakBeforeFirstCallParameter: 19 87 | PenaltyBreakComment: 300 88 | PenaltyBreakFirstLessLess: 120 89 | PenaltyBreakString: 1000 90 | PenaltyExcessCharacter: 1000000 91 | PenaltyReturnTypeOnItsOwnLine: 60 92 | PointerAlignment: Right 93 | RawStringFormats: 94 | - Delimiter: pb 95 | Language: TextProto 96 | BasedOnStyle: google 97 | ReflowComments: true 98 | SortIncludes: true 99 | SortUsingDeclarations: true 100 | SpaceAfterCStyleCast: false 101 | SpaceAfterTemplateKeyword: true 102 | SpaceBeforeAssignmentOperators: true 103 | SpaceBeforeParens: ControlStatements 104 | SpaceInEmptyParentheses: false 105 | SpacesBeforeTrailingComments: 1 106 | SpacesInAngles: false 107 | SpacesInContainerLiterals: true 108 | SpacesInCStyleCastParentheses: false 109 | SpacesInParentheses: false 110 | SpacesInSquareBrackets: false 111 | Standard: Cpp11 112 | TabWidth: 8 113 | UseTab: Never 114 | ... 115 | 116 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # commonly generated files 2 | *.pyc 3 | *~ 4 | .*.sw? 5 | .DS_Store 6 | .classpath 7 | .cproject 8 | .dart_tool 9 | .gdb_history 10 | .checkstyle 11 | .gdbinit 12 | .landmines 13 | .packages 14 | .project 15 | .pub 16 | .pydevproject 17 | cscope.* 18 | Session.vim 19 | tags 20 | Thumbs.db 21 | .idea 22 | pubspec.lock 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/googletest"] 2 | path = third_party/googletest 3 | url = https://github.com/google/googletest.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | COMM_MAKE = 1 2 | COMM_ECHO = 1 3 | include common.mk 4 | 5 | CFLAGS += -g -fno-strict-aliasing -Wall -export-dynamic \ 6 | -Wall -pipe -D_GNU_SOURCE -D_REENTRANT -fPIC -Wno-deprecated -m64 -std=c++11 7 | 8 | LINKS += -g -L./lib -L./objs/st -lrabbitstreamer -ldl -lstdc++ -lst 9 | 10 | LINKS += -Wl,-rpath=./objs/st 11 | 12 | LINKS += -L./third_party/googletest/build/lib -lgtestd -lgtest_maind 13 | #LINKS += -Wl,-rpath=./third_party/googletest/build/lib 14 | 15 | LINKS += -lpthread 16 | 17 | THIRD_PARTY_MD5 = third_party/md5/md5.o 18 | 19 | PROGS = rabbitstreamer superpeer_server tracker_server rabbitstreamertests 20 | 21 | all:$(PROGS) 22 | 23 | rabbitstreamer: librabbitstreamer.a 24 | 25 | librabbitstreamer.a: $(OBJS) 26 | $(ARSTATICLIB) 27 | 28 | superpeer_server: app/sp/superpeer_server.o 29 | $(BUILDEXE) 30 | 31 | tracker_server: app/tracker/tracker_server.o 32 | $(BUILDEXE) 33 | 34 | rabbitstreamertests: $(TESTSOBJS) 35 | $(BUILDEXE) 36 | 37 | clean: 38 | $(CLEAN) *.o $(PROGS) 39 | rm -rf lib 40 | rm -rf objs 41 | rm $(OBJS) 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rabbitstreamer 2 | Rabbitstreamer is the P2P based media streaming suite, includes streaming server which can stream media through P2P protocol, streaming player which can play the streaming data from streaming server and the peers. 3 | 4 | Here is the architecture of the system 5 | 6 | Super Peer and Tracker Server are implemented in this project. 7 | 8 | RabbitPlayer is implemented in [rabbitplayer](https://github.com/wenxiaoming/rabbitplayer). 9 | 10 | P2PCapturer is implemented in [p2pcapturer](https://github.com/wenxiaoming/p2pcapturer). 11 | 12 | ![system architecture](https://github.com/wenxiaoming/rabbitstreamer/blob/master/doc/system_architecture.png) 13 | 14 | Here is the architecture of the rabbitstreamer 15 | 16 | ![rabbitstreamer architecture](https://github.com/wenxiaoming/rabbitstreamer/blob/master/doc/rabbitstreamer_architecture.png) 17 | 18 | ## How to sync and build 19 | 20 | git clone https://github.com/wenxiaoming/rabbitstreamer.git 21 | 22 | cd rabbitstreamer/ 23 | 24 | git submodule init 25 | 26 | git submodule update 27 | 28 | cd third_party/googletest/ 29 | 30 | mkdir build 31 | 32 | cd build/ 33 | 34 | cmake ../ -DCMAKE_BUILD_TYPE=Debug 35 | 36 | make 37 | 38 | cd ../../../ 39 | 40 | ./build_all.sh 41 | 42 | -------------------------------------------------------------------------------- /app/common/server_base.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "server_base.h" 26 | #include "core/system_time.h" 27 | #include "protocol/sp/sp_source_manager.h" 28 | #include 29 | 30 | #define SYS_CYCLE_INTERVAL 1000 31 | 32 | using namespace rs::protocol::sp; 33 | 34 | namespace rs { 35 | namespace app { 36 | namespace common { 37 | 38 | RsBaseServer::RsBaseServer(ServerType type) { servertype = type; } 39 | 40 | RsBaseServer::~RsBaseServer() {} 41 | 42 | void RsBaseServer::loop() { 43 | while (true) { 44 | st_usleep(SYS_CYCLE_INTERVAL * 1000); 45 | 46 | SystemTime::instance()->update_system_time_ms(); 47 | if (servertype == ServerType::SUPER_PEER) 48 | RsSourceManager::instance()->write_source_channel_list_txt(); 49 | } 50 | } 51 | 52 | } // namespace common 53 | } // namespace app 54 | } // namespace rs 55 | -------------------------------------------------------------------------------- /app/common/server_base.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef APP_RS_SERVER_BASE_H 26 | #define APP_RS_SERVER_BASE_H 27 | #include 28 | 29 | namespace rs { 30 | namespace app { 31 | namespace common { 32 | 33 | 34 | class RsBaseServer { 35 | public: 36 | enum class ServerType :uint8_t { 37 | SUPER_PEER, 38 | TRACKER, 39 | }; 40 | explicit RsBaseServer(ServerType type); 41 | virtual ~RsBaseServer(); 42 | 43 | public: 44 | void loop(); 45 | 46 | private: 47 | ServerType servertype; 48 | }; 49 | 50 | } // namespace common 51 | } // namespace app 52 | } // namespace rs 53 | 54 | #endif /* APP_RS_SERVER_BASE_H */ 55 | -------------------------------------------------------------------------------- /app/sp/sp_cs_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "sp_cs_manager.h" 25 | #include "core/resource.h" 26 | 27 | namespace rs { 28 | namespace app { 29 | namespace sp { 30 | 31 | SpCsManager::SpCsManager(string ip, int port) 32 | : ip_addr(ip), listen_port(port) {} 33 | 34 | SpCsManager::~SpCsManager() {} 35 | 36 | int SpCsManager::start_listener() { 37 | tcp_listener = make_unique_ptr(ip_addr, listen_port, this); 38 | tcp_listener->start_listen(); 39 | return 0; 40 | } 41 | 42 | // the cs connect sp, the connection is ok, then call this function 43 | int SpCsManager::handle_tcp_connect(st_netfd_t stfd) { 44 | std::unique_ptr cs_sp_protocol = 45 | make_unique_ptr(stfd); 46 | cs_sp_protocol->start_thread(); 47 | return 0; 48 | } 49 | 50 | } // namespace sp 51 | } // namespace app 52 | } // namespace rs -------------------------------------------------------------------------------- /app/sp/sp_cs_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef APP_SP_CS_MANAGER_H_ 25 | #define APP_SP_CS_MANAGER_H_ 26 | 27 | #include 28 | #include "core/tcp_listener.h" 29 | #include "protocol/sp/sp_cs_connector.h" 30 | 31 | using namespace rs::core; 32 | using namespace rs::protocol::sp; 33 | 34 | namespace rs { 35 | namespace app { 36 | namespace sp { 37 | 38 | class SpCsManager : public ITcpHandler { 39 | public: 40 | SpCsManager(string ip, int port); 41 | ~SpCsManager(); 42 | 43 | public: 44 | int start_listener(); 45 | 46 | public: 47 | // implement interface ITcpHandler 48 | virtual int handle_tcp_connect(st_netfd_t stfd); 49 | 50 | private: 51 | std::unique_ptr tcp_listener = nullptr; 52 | string ip_addr; 53 | int listen_port; 54 | std::unique_ptr cs_sp_protocol = nullptr; 55 | }; 56 | 57 | } // namespace sp 58 | } // namespace app 59 | } // namespace rs 60 | 61 | #endif /* APP_SP_CS_MANAGER_H */ 62 | -------------------------------------------------------------------------------- /app/sp/sp_np_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "sp_np_manager.h" 25 | #include "core/resource.h" 26 | 27 | namespace rs { 28 | namespace app { 29 | namespace sp { 30 | 31 | SpNpManager::SpNpManager(string ip, uint32_t port) 32 | : ip_addr(ip), listen_port(port) {} 33 | 34 | SpNpManager::~SpNpManager() {} 35 | 36 | int SpNpManager::start_listener() { 37 | tcp_listener = make_unique_ptr(ip_addr, listen_port, this); 38 | tcp_listener->start_listen(); 39 | return 0; 40 | } 41 | 42 | int SpNpManager::handle_tcp_connect(st_netfd_t stfd) { 43 | std::unique_ptr np_sp_protocol = 44 | make_unique_ptr(stfd); 45 | np_sp_protocol->start_thread(); 46 | np_sp_protocol_vector.push_back(std::move(np_sp_protocol)); 47 | return 0; 48 | } 49 | 50 | } // namespace sp 51 | } // namespace app 52 | } // namespace rs 53 | -------------------------------------------------------------------------------- /app/sp/sp_np_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef APP_SP_NP_MANAGER_H_ 25 | #define APP_SP_NP_MANAGER_H_ 26 | 27 | #include "core/tcp_listener.h" 28 | #include "protocol/sp/sp_np_connector.h" 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace rs::core; 34 | using namespace rs::protocol::sp; 35 | 36 | namespace rs { 37 | namespace app { 38 | namespace sp { 39 | 40 | class SpNpManager : public ITcpHandler { 41 | public: 42 | SpNpManager(std::string ip, uint32_t port); 43 | ~SpNpManager(); 44 | 45 | public: 46 | int start_listener(); 47 | 48 | public: 49 | // implement interface ITcpHandler 50 | virtual int handle_tcp_connect(st_netfd_t stfd); 51 | 52 | private: 53 | std::unique_ptr tcp_listener = nullptr; 54 | string ip_addr; 55 | uint32_t listen_port; 56 | std::vector> np_sp_protocol_vector; 57 | }; 58 | 59 | } // namespace sp 60 | } // namespace app 61 | } // namespace rs 62 | 63 | #endif /* APP_SP_NP_MANAGER_H */ 64 | -------------------------------------------------------------------------------- /app/sp/sp_tracker_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "sp_tracker_manager.h" 25 | #include "core/error_code.h" 26 | #include "core/resource.h" 27 | 28 | namespace rs { 29 | namespace app { 30 | namespace sp { 31 | 32 | SpTrackerManager::SpTrackerManager(string ip, uint32_t port) 33 | : ip_addr(ip), ip_port(port) {} 34 | 35 | SpTrackerManager::~SpTrackerManager() {} 36 | 37 | int SpTrackerManager::start_connect() { 38 | int ret = ERROR_SUCCESS; 39 | 40 | tracker_protocol = 41 | make_unique_ptr(ip_addr, ip_port); 42 | 43 | tracker_protocol->start_connect(); 44 | 45 | return ret; 46 | } 47 | 48 | } // namespace sp 49 | } // namespace app 50 | } // namespace rs 51 | -------------------------------------------------------------------------------- /app/sp/sp_tracker_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef APP_SP_TRACKER_MANAGER_H_ 25 | #define APP_SP_TRACKER_MANAGER_H_ 26 | 27 | #include "protocol/sp/sp_tracker_connector.h" 28 | #include 29 | #include 30 | 31 | using namespace std; 32 | using namespace rs::protocol::sp; 33 | 34 | namespace rs { 35 | namespace app { 36 | namespace sp { 37 | 38 | class SpTrackerManager { 39 | public: 40 | SpTrackerManager(string ip, uint32_t port); 41 | ~SpTrackerManager(); 42 | 43 | public: 44 | int start_connect(); 45 | 46 | private: 47 | string ip_addr; 48 | uint32_t ip_port; 49 | std::unique_ptr tracker_protocol = nullptr; 50 | }; 51 | 52 | } // namespace sp 53 | } // namespace app 54 | } // namespace rs 55 | 56 | #endif /* APP_SP_TRACKER_MANAGER_H_ */ 57 | -------------------------------------------------------------------------------- /app/sp/superpeer_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include "app/common/server_base.h" 27 | #include "app/sp/sp_cs_manager.h" 28 | #include "app/sp/sp_np_manager.h" 29 | #include "app/sp/sp_tracker_manager.h" 30 | #include "core/async_logger.h" 31 | #include "protocol/sp/sp_source_manager.h" 32 | #include "core/resource.h" 33 | 34 | using namespace rs::app::common; 35 | using namespace rs::protocol::sp; 36 | using namespace rs::app::sp; 37 | 38 | int main() { 39 | init_log_system(); 40 | 41 | rs_st_init(); 42 | 43 | // start the listener of super peer server 44 | std::unique_ptr np_manager = make_unique_ptr("68.168.137.118", 2222); 45 | np_manager->start_listener(); 46 | 47 | // listen from capture server 48 | std::unique_ptr cs_manager = make_unique_ptr("68.168.137.118", 12345); 49 | cs_manager->start_listener(); 50 | 51 | // listen from normal peer or supoer peer 52 | RsSourceManager::instance()->initialize("", "", "68.168.137.118:3333"); 53 | 54 | // update and check status with tracker server 55 | std::unique_ptr tracker_manager = 56 | make_unique_ptr("68.168.137.118", 4444); 57 | tracker_manager->start_connect(); 58 | 59 | std::unique_ptr server = make_unique_ptr(RsBaseServer::ServerType::SUPER_PEER); 60 | server->loop(); 61 | 62 | deinit_log_system(); 63 | 64 | printf("hello sp!\n"); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /app/tracker/tracker_np_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "tracker_np_manager.h" 24 | #include "core/resource.h" 25 | 26 | namespace rs { 27 | namespace app { 28 | namespace tracker { 29 | 30 | TrackerNpManager::TrackerNpManager(string ip, int port) 31 | : ip_addr(ip), listen_port(port) {} 32 | 33 | TrackerNpManager::~TrackerNpManager() {} 34 | 35 | int TrackerNpManager::start_listener() { 36 | udp_listener = make_unique_ptr(ip_addr, listen_port, this); 37 | udp_listener->start_listen(); 38 | np_tracker = make_unique_ptr(); 39 | return 0; 40 | } 41 | 42 | int TrackerNpManager::handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, 43 | char *buf, int nb_buf) { 44 | np_tracker->handle_udp_packet(st_fd, from, buf, nb_buf); 45 | return 0; 46 | } 47 | 48 | } // namespace tracker 49 | } // namespace app 50 | } // namespace rs 51 | -------------------------------------------------------------------------------- /app/tracker/tracker_np_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef APP_TRACKER_NP_MANAGER_H_ 24 | #define APP_TRACKER_NP_MANAGER_H_ 25 | 26 | #include "core/udp_listener.h" 27 | #include "protocol/tracker/tracker_np_connector.h" 28 | #include 29 | 30 | using namespace rs::protocol::tracker; 31 | 32 | namespace rs { 33 | namespace app { 34 | namespace tracker { 35 | 36 | class TrackerNpManager : public IUdpHandler { 37 | public: 38 | TrackerNpManager(string ip, int port); 39 | ~TrackerNpManager(); 40 | 41 | public: 42 | int start_listener(); 43 | 44 | public: 45 | // implement interface IUdpHandler 46 | virtual int handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, 47 | char *buf, int nb_buf) override final; 48 | 49 | private: 50 | std::unique_ptr udp_listener = nullptr; 51 | string ip_addr; 52 | int listen_port; 53 | std::unique_ptr np_tracker = nullptr; 54 | }; 55 | 56 | } // namespace tracker 57 | } // namespace app 58 | } // namespace rs 59 | 60 | #endif /* APP_TRACKER_NP_MANAGER_H_ */ 61 | -------------------------------------------------------------------------------- /app/tracker/tracker_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include "app/common/server_base.h" 26 | #include "app/tracker/tracker_np_manager.h" 27 | #include "app/tracker/tracker_sp_manager.h" 28 | #include "core/async_logger.h" 29 | #include "core/resource.h" 30 | 31 | using namespace rs::app::common; 32 | using namespace rs::app::tracker; 33 | 34 | int main() { 35 | init_log_system(); 36 | 37 | rs_st_init(); 38 | 39 | std::unique_ptr sp_tracker = make_unique_ptr("68.168.137.118", 4444); 40 | sp_tracker->start_listener(); 41 | 42 | std::unique_ptr np_tracker = make_unique_ptr("68.168.137.118", 3333); 43 | np_tracker->start_listener(); 44 | 45 | std::unique_ptr server = make_unique_ptr(RsBaseServer::ServerType::TRACKER); 46 | server->loop(); 47 | 48 | printf("hello tracker!\n"); 49 | 50 | deinit_log_system(); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /app/tracker/tracker_sp_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "tracker_sp_manager.h" 24 | #include "core/resource.h" 25 | 26 | namespace rs { 27 | namespace app { 28 | namespace tracker { 29 | 30 | TrackerSpManager::TrackerSpManager(string ip, int port) 31 | : ip_addr(ip), listen_port(port) {} 32 | 33 | TrackerSpManager::~TrackerSpManager() {} 34 | 35 | int TrackerSpManager::start_listener() { 36 | udp_listener = make_unique_ptr(ip_addr, listen_port, this); 37 | udp_listener->start_listen(); 38 | sp_tracker = make_unique_ptr(); 39 | return 0; 40 | } 41 | 42 | int TrackerSpManager::handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, 43 | char *buf, int nb_buf) { 44 | sp_tracker->handle_udp_packet(st_fd, from, buf, nb_buf); 45 | return 0; 46 | } 47 | 48 | } // namespace tracker 49 | } // namespace app 50 | } // namespace rs 51 | -------------------------------------------------------------------------------- /app/tracker/tracker_sp_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef APP_TRACKER_SP_MANAGER_H_ 24 | #define APP_TRACKER_SP_MANAGER_H_ 25 | 26 | #include "core/udp_listener.h" 27 | #include "protocol/tracker/tracker_sp_connector.h" 28 | #include 29 | 30 | using namespace rs::protocol::tracker; 31 | 32 | namespace rs { 33 | namespace app { 34 | namespace tracker { 35 | 36 | class TrackerSpManager : public IUdpHandler { 37 | public: 38 | TrackerSpManager(string ip, int port); 39 | ~TrackerSpManager(); 40 | 41 | public: 42 | int start_listener(); 43 | 44 | public: 45 | // implement interface IUdpHandler 46 | virtual int handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, 47 | char *buf, int nb_buf) override final; 48 | 49 | private: 50 | std::unique_ptr udp_listener = nullptr; 51 | string ip_addr; 52 | int listen_port; 53 | std::unique_ptr sp_tracker = nullptr; 54 | }; 55 | 56 | } // namespace tracker 57 | } // namespace app 58 | } // namespace rs 59 | 60 | #endif /* APP_TRACKER_SP_MANAGER_H_ */ 61 | -------------------------------------------------------------------------------- /build_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | if [ ! -f "objs" ]; then 5 | echo "mkdir objs" 6 | mkdir objs 7 | fi 8 | #set the library path for libst.so 9 | echo "set the library path for libst.so" 10 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:objs/st 11 | echo $LD_LIBRARY_PATH 12 | 13 | THIRD_PARTY_FOLDER=third_party 14 | RS_OBJS=objs 15 | 16 | #build st-1.9 17 | echo "build st-1.9t"; 18 | _ST_MAKE=linux-debug && _ST_EXTRA_CFLAGS="-DMD_HAVE_EPOLL" 19 | 20 | rm -rf ${RS_OBJS}/st-1.9 && cd ${RS_OBJS} && 21 | unzip -q ../${THIRD_PARTY_FOLDER}/st-1.9.zip && cd st-1.9 && chmod +w * && 22 | make ${_ST_MAKE} EXTRA_CFLAGS="${_ST_EXTRA_CFLAGS}" && 23 | cd .. && rm -rf st && ln -sf st-1.9/obj st && cd .. 24 | 25 | # check status 26 | ret=$?; if [[ $ret -ne 0 ]]; then echo "build st-1.9 failed, ret=$ret"; exit $ret; fi 27 | 28 | 29 | #make clean 30 | make 31 | 32 | -------------------------------------------------------------------------------- /common.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Tencent is pleased to support the open source community by making Libco available. 3 | # 4 | # Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | 20 | 21 | ##### Makefile Rules ########## 22 | SRCROOT=. 23 | 24 | ##define the compliers 25 | CPP = g++ 26 | CC = gcc 27 | AR = ar -rc 28 | RANLIB = ranlib 29 | 30 | CPPSHARE = $(CPP) -fPIC -shared -g -pipe -L$(SRCROOT)/solib/ -o 31 | CSHARE = $(CC) -fPIC -shared -g -pipe -L$(SRCROOT)/solib/ -o 32 | 33 | ifeq ($v,release) 34 | CFLAGS= -rdynamic -g $(INCLS) -fPIC -DLINUX -pipe -Wno-deprecated -c 35 | else 36 | CFLAGS= -rdynamic -g $(INCLS) -fPIC -DLINUX -pipe -c -fno-inline 37 | endif 38 | 39 | ifneq ($v,release) 40 | BFLAGS= -g 41 | endif 42 | 43 | STATICLIBPATH=$(SRCROOT)/lib 44 | DYNAMICLIBPATH=$(SRCROOT)/solib 45 | 46 | INCLS += -I$(SRCROOT) 47 | INCLS += -Iobjs/st -Ithird_party/md5 48 | INCLS += -Ithird_party/googletest/googletest/include 49 | 50 | ## default links 51 | ifeq ($(LINKS_DYNAMIC), 1) 52 | LINKS += -L$(DYNAMICLIBPATH) -L$(STATICLIBPATH) 53 | else 54 | LINKS += -L$(STATICLIBPATH) 55 | endif 56 | 57 | CPPSRCS = $(wildcard *.c ./third_party/md5/*.cpp ./app/common/*.cpp ./app/sp/*.cpp ./app/tracker/*.cpp ./core/*.cpp ./protocol/*.cpp ./protocol/sp/*.cpp ./protocol/tracker/*.cpp ./protocol/common/*.cpp) 58 | CSRCS = $(wildcard *.c ./third_party/md5/*.c ./app/common/*.c ./app/sp/*.c ./core/*.c ./protocol/*.c ./protocol/sp/*.c ./protocol/tracker/*.c ./protocol/common/*.c) 59 | CPPOBJS = $(patsubst %.cpp,%.o,$(CPPSRCS)) 60 | COBJS = $(patsubst %.c,%.o,$(CSRCS)) 61 | 62 | TESTSSRCS = $(wildcard ./tests/*.cpp) 63 | TESTSOBJS = $(patsubst %.cpp,%.o,$(TESTSSRCS)) 64 | 65 | SRCS = $(CPPSRCS) $(CSRCS) $(TESTSSRCS) 66 | OBJS = $(CPPOBJS) $(COBJS) $(TESTSOBJS) 67 | 68 | CPPCOMPI=$(CPP) $(CFLAGS) -Wno-deprecated 69 | CCCOMPI=$(CC) $(CFLAGS) 70 | 71 | BUILDEXE = $(CPP) $(BFLAGS) -o $@ $^ $(LINKS) 72 | CLEAN = rm -f *.o 73 | 74 | CPPCOMPILE = $(CPPCOMPI) $< $(FLAGS) $(INCLS) $(MTOOL_INCL) -o $@ 75 | CCCOMPILE = $(CCCOMPI) $< $(FLAGS) $(INCLS) $(MTOOL_INCL) -o $@ 76 | 77 | ARSTATICLIB = $(AR) $@.tmp $^ $(AR_FLAGS); \ 78 | if [ $$? -ne 0 ]; then exit 1; fi; \ 79 | test -d $(STATICLIBPATH) || mkdir -p $(STATICLIBPATH); \ 80 | mv -f $@.tmp $(STATICLIBPATH)/$@; 81 | 82 | BUILDSHARELIB = $(CPPSHARE) $@.tmp $^ $(BS_FLAGS); \ 83 | if [ $$? -ne 0 ]; then exit 1; fi; \ 84 | test -d $(DYNAMICLIBPATH) || mkdir -p $(DYNAMICLIBPATH); \ 85 | mv -f $@.tmp $(DYNAMICLIBPATH)/$@; 86 | 87 | .cpp.o: 88 | $(CPPCOMPILE) 89 | .c.o: 90 | $(CCCOMPILE) 91 | -------------------------------------------------------------------------------- /core/async_logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "async_logger.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | using namespace std; 36 | 37 | namespace rs { 38 | namespace core { 39 | 40 | RsThreadContext::RsThreadContext() {} 41 | 42 | RsThreadContext::~RsThreadContext() {} 43 | 44 | int RsThreadContext::generate_id() { 45 | static int id = 100; 46 | 47 | int gid = id++; 48 | cache[st_thread_self()] = gid; 49 | return gid; 50 | } 51 | 52 | int RsThreadContext::get_id() { return cache[st_thread_self()]; } 53 | 54 | int RsThreadContext::set_id(int v) { 55 | st_thread_t self = st_thread_self(); 56 | 57 | int ov = 0; 58 | if (cache.find(self) != cache.end()) { 59 | ov = cache[self]; 60 | } 61 | 62 | cache[self] = v; 63 | 64 | return ov; 65 | } 66 | 67 | // the max size of a line of log. 68 | #define LOG_MAX_SIZE 4096 69 | // the tail append to each log. 70 | #define LOG_TAIL '\n' 71 | // reserved for the end of log data, it must be strlen(LOG_TAIL) 72 | #define LOG_TAIL_SIZE 1 73 | 74 | #define MAX_PATH 255 75 | 76 | RsAsyncLogger::RsAsyncLogger() { log_data = new char[LOG_MAX_SIZE]; } 77 | 78 | RsAsyncLogger::~RsAsyncLogger() { 79 | if (log_data) 80 | delete[] log_data; 81 | 82 | if (fd > 0) { 83 | ::close(fd); 84 | fd = -1; 85 | } 86 | } 87 | 88 | int RsAsyncLogger::initialize() { 89 | int ret = ERROR_SUCCESS; 90 | return ret; 91 | } 92 | 93 | void RsAsyncLogger::log(LogLevel level, const char *tag, int context_id, 94 | const char *fmt, ...) { 95 | string level_name; 96 | 97 | if (log_level > level) 98 | return; 99 | 100 | switch (level) { 101 | case Verbose: 102 | level_name = "verb"; 103 | break; 104 | case Info: 105 | level_name = "info"; 106 | break; 107 | case Trace: 108 | level_name = "trace"; 109 | break; 110 | case Warn: 111 | level_name = "warn"; 112 | break; 113 | case Error: 114 | level_name = "error"; 115 | break; 116 | default: 117 | level_name = "unknow"; 118 | break; 119 | } 120 | 121 | int size = 0; 122 | if (!generate_header(false, tag, context_id, level_name.c_str(), &size)) { 123 | return; 124 | } 125 | 126 | va_list ap; 127 | va_start(ap, fmt); 128 | // we reserved 1 bytes for the new line. 129 | size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); 130 | va_end(ap); 131 | 132 | write_log(fd, log_data, size, level); 133 | } 134 | 135 | bool RsAsyncLogger::generate_header(bool error, const char *tag, int context_id, 136 | const char *level_name, int *header_size) { 137 | // clock time 138 | timeval tv; 139 | if (gettimeofday(&tv, NULL) == -1) { 140 | return false; 141 | } 142 | 143 | // to calendar time 144 | struct tm *tm; 145 | if (utc) { 146 | if ((tm = gmtime(&tv.tv_sec)) == NULL) { 147 | return false; 148 | } 149 | } else { 150 | if ((tm = localtime(&tv.tv_sec)) == NULL) { 151 | return false; 152 | } 153 | } 154 | 155 | // write log header 156 | int log_header_size = -1; 157 | 158 | if (error) { 159 | if (tag) { 160 | log_header_size = snprintf( 161 | log_data, LOG_MAX_SIZE, 162 | "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d][%d] ", 163 | 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, 164 | tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, 165 | tag, getpid(), context_id, errno); 166 | } else { 167 | log_header_size = snprintf( 168 | log_data, LOG_MAX_SIZE, 169 | "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d][%d] ", 170 | 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, 171 | tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, 172 | getpid(), context_id, errno); 173 | } 174 | } else { 175 | if (tag) { 176 | log_header_size = snprintf( 177 | log_data, LOG_MAX_SIZE, 178 | "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d] ", 179 | 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, 180 | tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, 181 | tag, getpid(), context_id); 182 | } else { 183 | log_header_size = snprintf( 184 | log_data, LOG_MAX_SIZE, 185 | "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d] ", 186 | 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, 187 | tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, 188 | getpid(), context_id); 189 | } 190 | } 191 | 192 | if (log_header_size == -1) { 193 | return false; 194 | } 195 | 196 | // write the header size. 197 | *header_size = min(LOG_MAX_SIZE - 1, log_header_size); 198 | 199 | return true; 200 | } 201 | 202 | void RsAsyncLogger::write_log(int &fd, char *str_log, int size, int level) { 203 | // ensure the tail and EOF of string 204 | // LOG_TAIL_SIZE for the TAIL char. 205 | // 1 for the last char(0). 206 | size = min(LOG_MAX_SIZE - 1 - LOG_TAIL_SIZE, size); 207 | 208 | // add some to the end of char. 209 | str_log[size++] = LOG_TAIL; 210 | 211 | // if not to file, to console and return. 212 | if (!log_to_file_tank) { 213 | // if is error msg, then print color msg. 214 | // \033[31m : red text code in shell 215 | // \033[32m : green text code in shell 216 | // \033[33m : yellow text code in shell 217 | // \033[0m : normal text code 218 | if (level <= Trace) { 219 | printf("%.*s", size, str_log); 220 | } else if (level == Warn) { 221 | printf("\033[33m%.*s\033[0m", size, str_log); 222 | } else { 223 | printf("\033[31m%.*s\033[0m", size, str_log); 224 | } 225 | 226 | return; 227 | } 228 | 229 | // open log file. if specified 230 | if (fd < 0) { 231 | open_log_file(); 232 | } 233 | 234 | // write log to file. 235 | if (fd > 0) { 236 | ::write(fd, str_log, size); 237 | } 238 | } 239 | 240 | void RsAsyncLogger::open_log_file() { 241 | timeval tv; 242 | if (gettimeofday(&tv, NULL) == -1) { 243 | return; 244 | } 245 | 246 | struct tm *tm; 247 | if ((tm = localtime(&tv.tv_sec)) == NULL) { 248 | return; 249 | } 250 | 251 | char filename[MAX_PATH]; 252 | snprintf(filename, MAX_PATH, "log-%d-%02d-%02d-%02d-%02d-%02d.%03d\0", 253 | 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, 254 | tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000)); 255 | 256 | fd = ::open(filename, O_RDWR | O_APPEND); 257 | 258 | if (fd == -1 && errno == ENOENT) { 259 | fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 260 | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); 261 | } 262 | } 263 | 264 | static RsLogBase *sRsLog = nullptr; 265 | 266 | static RsContextBase *sRscontext = nullptr; 267 | 268 | void init_log_system() { 269 | sRsLog = new RsAsyncLogger(); 270 | sRscontext = new RsThreadContext(); 271 | } 272 | 273 | void deinit_log_system() { 274 | if (sRsLog) 275 | delete sRsLog; 276 | 277 | if (sRscontext) 278 | delete sRscontext; 279 | } 280 | 281 | RsLogBase *rs_log() { return sRsLog; } 282 | 283 | RsContextBase *rs_context() { return sRscontext; } 284 | 285 | } // namespace core 286 | } // namespace rs -------------------------------------------------------------------------------- /core/async_logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef CORE_RS_ASYNC_LOGGER_H_ 25 | #define CORE_RS_ASYNC_LOGGER_H_ 26 | 27 | #include "logger.h" 28 | #include 29 | #include 30 | 31 | using namespace std; 32 | 33 | namespace rs { 34 | namespace core { 35 | 36 | class RsThreadContext : public RsContextBase { 37 | private: 38 | map cache; 39 | 40 | public: 41 | RsThreadContext(); 42 | virtual ~RsThreadContext(); 43 | 44 | public: 45 | virtual int generate_id(); 46 | virtual int get_id(); 47 | virtual int set_id(int v); 48 | }; 49 | 50 | class RsAsyncLogger : public RsLogBase { 51 | public: 52 | RsAsyncLogger(); 53 | virtual ~RsAsyncLogger(); 54 | 55 | public: 56 | virtual int initialize(); 57 | 58 | public: 59 | virtual void log(LogLevel level, const char *tag, int context_id, 60 | const char *fmt, ...); 61 | 62 | private: 63 | virtual bool generate_header(bool error, const char *tag, int context_id, 64 | const char *level_name, int *header_size); 65 | virtual void write_log(int &fd, char *str_log, int size, int level); 66 | virtual void open_log_file(); 67 | 68 | private: 69 | int log_level = Verbose; 70 | char *log_data; 71 | int fd = -1; 72 | bool log_to_file_tank = true; 73 | bool utc = false; 74 | }; 75 | 76 | } // namespace core 77 | } // namespace rs 78 | 79 | #endif /* CORE_RS_ASYNC_LOGGER_H_ */ 80 | -------------------------------------------------------------------------------- /core/bitrate_calculator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "bitrate_calculator.h" 24 | #include "logger.h" 25 | #include 26 | 27 | namespace rs { 28 | namespace core { 29 | 30 | RsBitrateCalculator::RsBitrateCalculator(string name) 31 | : calculator_name(name), recv_buffer_size(0), last_recv_msec(0) {} 32 | 33 | RsBitrateCalculator::~RsBitrateCalculator() {} 34 | 35 | void RsBitrateCalculator::update_buffersize(uint32_t size) { 36 | timeval tv; 37 | recv_buffer_size += size; 38 | if (gettimeofday(&tv, NULL) == -1) { 39 | return; 40 | } 41 | 42 | uint32_t curr_ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; 43 | uint32_t delta_ms = curr_ms - last_recv_msec; 44 | if (delta_ms > 1000) { 45 | RSLOGI("%s bitrate:%d kbps", calculator_name.c_str(), 46 | 1000 * recv_buffer_size / (1024 * delta_ms)); 47 | recv_buffer_size = 0; 48 | last_recv_msec = curr_ms; 49 | } 50 | } 51 | 52 | } // namespace core 53 | } // namespace rs -------------------------------------------------------------------------------- /core/bitrate_calculator.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_BITRATE_CALCULATOR_H_ 24 | #define CORE_BITRATE_CALCULATOR_H_ 25 | 26 | #include 27 | #include 28 | 29 | using namespace std; 30 | 31 | namespace rs { 32 | namespace core { 33 | 34 | class RsBitrateCalculator { 35 | public: 36 | RsBitrateCalculator(string name); 37 | virtual ~RsBitrateCalculator(); 38 | 39 | public: 40 | void update_buffersize(uint32_t size); 41 | 42 | private: 43 | string calculator_name; 44 | uint32_t recv_buffer_size; 45 | uint32_t last_recv_msec; 46 | }; 47 | 48 | } // namespace core 49 | } // namespace rs 50 | 51 | #endif /* CORE_BITRATE_CALCULATOR_H_ */ 52 | -------------------------------------------------------------------------------- /core/buffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "buffer.h" 25 | #include "system_time.h" 26 | #include "debug_utility.h" 27 | #include "error_code.h" 28 | #include 29 | #include 30 | #include 31 | 32 | namespace rs { 33 | namespace core { 34 | 35 | #define DEFAULT_RECV_BUFFER_SIZE 131072 36 | #define MAX_SOCKET_BUFFER 262144 37 | 38 | RsBuffer::RsBuffer() { 39 | buffer_size = DEFAULT_RECV_BUFFER_SIZE; 40 | buffer = (char *)malloc(buffer_size); 41 | curr_ptr = end_ptr = buffer; 42 | } 43 | 44 | RsBuffer::~RsBuffer() { 45 | if (buffer) 46 | free(buffer); 47 | buffer = NULL; 48 | } 49 | 50 | int RsBuffer::current_size() { return (int)(end_ptr - curr_ptr); } 51 | 52 | char *RsBuffer::bytes() { return curr_ptr; } 53 | 54 | void RsBuffer::set_buffer(int size) { 55 | // never exceed the max size. 56 | if (size > MAX_SOCKET_BUFFER) { 57 | return; 58 | } 59 | 60 | // the user-space buffer size limit to a max value. 61 | int nb_resize_buf = std::min(size, MAX_SOCKET_BUFFER); 62 | 63 | // only realloc when buffer changed bigger 64 | if (nb_resize_buf <= buffer_size) { 65 | return; 66 | } 67 | 68 | // realloc for buffer change bigger. 69 | int start = (int)(curr_ptr - buffer); 70 | int nb_bytes = (int)(end_ptr - curr_ptr); 71 | 72 | buffer = (char *)realloc(buffer, nb_resize_buf); 73 | buffer_size = nb_resize_buf; 74 | curr_ptr = buffer + start; 75 | end_ptr = curr_ptr + nb_bytes; 76 | } 77 | 78 | char RsBuffer::read_byte() { return *curr_ptr++; } 79 | 80 | char *RsBuffer::read_nbytes(int size) { 81 | char *ptr = curr_ptr; 82 | curr_ptr += size; 83 | 84 | return ptr; 85 | } 86 | 87 | void RsBuffer::skip(int size) { curr_ptr += size; } 88 | 89 | int RsBuffer::fill_buffer(RsSocket *io, int size) { 90 | int ret = ERROR_SUCCESS; 91 | if (size < 0) 92 | print_backtrace(); 93 | assert(size >= 0); 94 | // current buffer is enough 95 | if (end_ptr - curr_ptr >= size) { 96 | return ret; 97 | } 98 | 99 | // the bytes will be consumed 100 | int exists_bytes = (int)(end_ptr - curr_ptr); 101 | 102 | // enlarge the buffer 103 | if (buffer_size < size) 104 | set_buffer(size); // TODO,handle the error 105 | 106 | // the free space of buffer, 107 | int free_space = (int)(buffer + buffer_size - end_ptr); 108 | 109 | if (!exists_bytes) 110 | curr_ptr = end_ptr = buffer; // reset when buffer is consumed 111 | // completely. 112 | else if (free_space < size) { 113 | // move current buffer to the beginning. 114 | buffer = (char *)memmove(buffer, curr_ptr, exists_bytes); 115 | curr_ptr = buffer; 116 | end_ptr = curr_ptr + exists_bytes; 117 | free_space = (int)(buffer + buffer_size - end_ptr); 118 | } 119 | 120 | // fill required size of bytes to the buffer. 121 | while (end_ptr - curr_ptr < size) { 122 | ssize_t nread; 123 | if ((ret = io->read(end_ptr, free_space, &nread)) != ERROR_SUCCESS) { 124 | print_backtrace(); 125 | return ret; // TODO:FIXME, how to handle this error 126 | } 127 | assert((int)nread > 0); 128 | end_ptr += nread; 129 | free_space -= nread; 130 | } 131 | 132 | return ret; 133 | } 134 | 135 | } // namespace core 136 | } // namespace rs -------------------------------------------------------------------------------- /core/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef CORE_BUFFER_H_ 25 | #define CORE_BUFFER_H_ 26 | 27 | #include "socket.h" 28 | 29 | namespace rs { 30 | namespace core { 31 | 32 | class RsBuffer { 33 | public: 34 | RsBuffer(); 35 | virtual ~RsBuffer(); 36 | 37 | public: 38 | int current_size(); 39 | char *bytes(); 40 | void set_buffer(int size); 41 | 42 | public: 43 | char read_byte(); 44 | 45 | char *read_nbytes(int size); 46 | 47 | void skip(int size); 48 | 49 | int fill_buffer(RsSocket *io, int size); 50 | 51 | private: 52 | /***************************************** 53 | buffer_size 54 | ________________|________________ 55 | | | 56 | buffer curr_ptr end_ptr | 57 | |____________|___________|________| 58 | 59 | ******************************************/ 60 | char *curr_ptr; // the pointer for the current position of the using buffer 61 | char *end_ptr; // the pointer for the end position of the using buffer 62 | 63 | char *buffer; // the pointer for the base position of the buffer 64 | int buffer_size; // the total size of the buffer 65 | }; 66 | 67 | } // namespace core 68 | } // namespace rs 69 | 70 | #endif /* CORE_BUFFER_H_ */ 71 | -------------------------------------------------------------------------------- /core/core_struct.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef RS_CORE_STRUCT_H 24 | #define RS_CORE_STRUCT_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define MD5_LEN 32 // MD5值的长度 32 | 33 | using namespace std; 34 | 35 | namespace rs { 36 | namespace core { 37 | 38 | class NetAddress { 39 | public: 40 | NetAddress() { 41 | memset(this, 0, sizeof(NetAddress)); 42 | sin_family = AF_INET; 43 | } 44 | NetAddress &operator=(const NetAddress &addr) { 45 | if (&addr == this) 46 | return *this; 47 | 48 | memcpy(this, &addr, sizeof(NetAddress)); 49 | return *this; 50 | } 51 | 52 | bool operator==(const NetAddress &addr) const { 53 | return ((this->sin_addr.s_addr == addr.sin_addr.s_addr) && 54 | (this->sin_port == addr.sin_port)); 55 | } 56 | 57 | bool operator!=(const NetAddress &addr) const { return !(*this == addr); } 58 | 59 | bool IsNatIP() { 60 | unsigned long wan_ip; 61 | unsigned char temp; 62 | // 63 | memcpy(&wan_ip, &(sin_addr.s_addr), sizeof(wan_ip)); 64 | /* 65 | * all nat addresses 66 | * A 10.0.0.0---10.255.255.255     1 67 | * B 172.16.0.0---172.31.255.255    16 68 | * C 192.168.0.0---192.168.255.255   255 69 | */ 70 | bool nat = false; 71 | memcpy(&temp, &wan_ip, 1); 72 | if (temp == 10) // A 73 | nat = true; 74 | else if (temp == 192) { 75 | memcpy(&temp, (char *)(&wan_ip) + 1, 1); 76 | if (temp == 168) // B 77 | nat = true; 78 | } else if (temp == 172) { 79 | memcpy(&temp, (char *)(&wan_ip) + 1, 1); 80 | if (temp >= 16 && temp <= 31) // C 81 | nat = true; 82 | } 83 | // 84 | return nat; 85 | } 86 | 87 | int16_t sin_family; 88 | uint16_t sin_port; 89 | struct in_addr sin_addr; 90 | }; 91 | 92 | class P2PAddress { 93 | public: 94 | bool IsNAT() const { return !(0xffffffff == subnetIP.sin_addr.s_addr); }; 95 | NetAddress outerIP; 96 | NetAddress subnetIP; 97 | bool operator==(const P2PAddress &addr) const { 98 | return ((addr.outerIP.sin_addr.s_addr == outerIP.sin_addr.s_addr) && 99 | (addr.subnetIP == subnetIP)); 100 | }; 101 | 102 | P2PAddress &operator=(const P2PAddress &addr) { 103 | if (&addr == this) 104 | return *this; 105 | outerIP = addr.outerIP; 106 | subnetIP = addr.subnetIP; 107 | return *this; 108 | }; 109 | }; 110 | 111 | class CorePeerInfo { 112 | public: 113 | CorePeerInfo() { memset(this, 0, sizeof(CorePeerInfo)); }; 114 | unsigned layer : 8; 115 | unsigned isMaxIn : 1; 116 | unsigned isMaxOut : 1; 117 | unsigned isMaxFreeIn : 1; 118 | unsigned isMaxFreeOut : 1; 119 | unsigned isSuperPeer : 1; 120 | unsigned : 19; 121 | }; 122 | 123 | class PeerInfoWithAddr : public CorePeerInfo, public P2PAddress {}; 124 | 125 | class TransferInfo { 126 | public: 127 | TransferInfo() { memset(this, 0, sizeof(TransferInfo)); }; 128 | uint64_t totalDownBytes; 129 | uint64_t totalUpBytes; 130 | float currDownSpeed; 131 | float currUpSpeed; 132 | float avgDownSpeed; 133 | float avgUpSpeed; 134 | }; 135 | 136 | class BlockInterval { 137 | public: 138 | BlockInterval() : start(UINT32_MAX){}; 139 | BlockInterval(unsigned int s, unsigned int ss) : start(s), size(ss){}; 140 | 141 | static bool cmp_size(const BlockInterval &i1, const BlockInterval &i2) { 142 | return (i1.size < i2.size); 143 | }; 144 | static bool cmp_start(const BlockInterval &i1, const BlockInterval &i2) { 145 | return (i1.start < i2.start); 146 | }; 147 | bool operator==(const BlockInterval &a) const { 148 | return (start == a.start && size == a.size); 149 | }; 150 | BlockInterval &operator=(const BlockInterval &another) { 151 | if (&another == this) 152 | return *this; 153 | 154 | start = another.start; 155 | size = another.size; 156 | return *this; 157 | } 158 | 159 | static void and_op(const BlockInterval &i1, const BlockInterval &i2, 160 | BlockInterval &result) { 161 | result.start = max(i1.start, i2.start); 162 | result.size = min(i1.start + i1.size, i2.start + i2.size); 163 | if (result.size > result.start) 164 | result.size = result.size - result.start; 165 | else 166 | result.size = 0; 167 | }; 168 | 169 | public: 170 | uint32_t start; 171 | uint32_t size; 172 | }; 173 | 174 | class MD5_Hash_Str { 175 | public: 176 | bool operator<(const MD5_Hash_Str other) const { 177 | return strncasecmp(hash_, other.hash_, MD5_LEN) < 0; 178 | } 179 | bool operator==(const MD5_Hash_Str other) const { 180 | return strncmp(hash_, other.hash_, MD5_LEN) == 0; 181 | } 182 | MD5_Hash_Str &operator=(const MD5_Hash_Str other) { 183 | memcpy(hash_, other.hash_, sizeof(hash_)); 184 | blockInterval = other.blockInterval; 185 | } 186 | char hash_[MD5_LEN + 1]; 187 | BlockInterval blockInterval; 188 | }; 189 | 190 | #define MEDIA_BLOCK_SIZE 16384 191 | 192 | #define MAX_BUFFER_SIZE 1024 193 | 194 | #define UUID_LENGTH 16 195 | 196 | } // namespace core 197 | } // namespace rs 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /core/debug_utility.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "debug_utility.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace rs { 30 | namespace core { 31 | 32 | void print_backtrace(void) { 33 | int i; 34 | int MAX_CALLSTACK_DEPTH = 32; 35 | void *traceback[MAX_CALLSTACK_DEPTH]; 36 | 37 | char cmd[512] = "addr2line -f -e "; 38 | char *prog = cmd + strlen(cmd); 39 | 40 | int r = readlink("/proc/self/exe", prog, sizeof(cmd) - (prog - cmd) - 1); 41 | 42 | /*printf("%s\n",cmd);*/ 43 | FILE *fp = popen(cmd, "w"); 44 | 45 | int depth = backtrace(traceback, MAX_CALLSTACK_DEPTH); 46 | for (i = 0; i < depth; i++) { 47 | /*printf("%p\n",traceback[i]);*/ 48 | fprintf(fp, "%p\n\r", traceback[i]); 49 | } 50 | fclose(fp); 51 | } 52 | 53 | } // namespace core 54 | } // namespace rs -------------------------------------------------------------------------------- /core/debug_utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_RS_DEBUG_UTILITY_H_ 24 | #define CORE_RS_DEBUG_UTILITY_H_ 25 | 26 | namespace rs { 27 | namespace core { 28 | 29 | void print_backtrace(void); 30 | } 31 | } // namespace rs 32 | 33 | #endif /* CORE_RS_DEBUG_UTILITY_H_ */ 34 | -------------------------------------------------------------------------------- /core/error_code.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef RS_ERROR_CODE_H 24 | #define RS_ERROR_CODE_H 25 | 26 | namespace rs { 27 | namespace core { 28 | 29 | #define ERROR_SUCCESS 0 30 | // system error. 31 | #define ERROR_SOCKET_CREATE 1000 32 | #define ERROR_SOCKET_SETREUSE 1001 33 | #define ERROR_SOCKET_BIND 1002 34 | #define ERROR_SOCKET_LISTEN 1003 35 | #define ERROR_SOCKET_CLOSED 1004 36 | #define ERROR_SOCKET_GET_PEER_NAME 1005 37 | #define ERROR_SOCKET_GET_PEER_IP 1006 38 | #define ERROR_SOCKET_READ 1007 39 | #define ERROR_SOCKET_READ_FULLY 1008 40 | #define ERROR_SOCKET_WRITE 1009 41 | #define ERROR_SOCKET_WAIT 1010 42 | #define ERROR_SOCKET_TIMEOUT 1011 43 | #define ERROR_SOCKET_CONNECT 1012 44 | 45 | #define ERROR_ST_SET_EPOLL 1013 46 | #define ERROR_ST_INITIALIZE 1014 47 | #define ERROR_ST_OPEN_SOCKET 1015 48 | #define ERROR_ST_CREATE_LISTEN_THREAD 1016 49 | #define ERROR_ST_CREATE_CYCLE_THREAD 1017 50 | #define ERROR_ST_CONNECT 1018 51 | #define ERROR_READER_BUFFER_OVERFLOW 1022 52 | 53 | #define ERROR_SYSTEM_FAIL_TO_ALLOCATE 1059 54 | // source manager error 55 | #define ERROR_SOURCE_MGR_NOT_FOUND 2000 56 | #define ERROR_SOURCE_MGR_FAILT_TO_CREATE_SOURCE 2001 57 | 58 | } // namespace core 59 | } // namespace rs 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /core/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2020 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef RS_CORE_HASH_H_ 25 | #define RS_CORE_HASH_H_ 26 | 27 | #include 28 | 29 | namespace rs { 30 | namespace core { 31 | 32 | template inline void hash_combine(size_t seed, const T &value) { 33 | seed ^= std::hash()(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 34 | } 35 | 36 | template inline void has_key(size_t &seed, const T &value) { 37 | hash_combine(seed, value); 38 | } 39 | 40 | template 41 | inline void hash_key(size &seed, const T &value, const Args &... args) { 42 | hash_combine(seed, value); 43 | hash_key(seed, args...); 44 | } 45 | 46 | template inline size_t hash_key(const Args &... args) { 47 | size_t seed = 0; 48 | hash_val(seed, args...); 49 | return seed; 50 | } 51 | 52 | } // namespace core 53 | } // namespace rs 54 | 55 | #endif -------------------------------------------------------------------------------- /core/logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "logger.h" 24 | 25 | namespace rs { 26 | namespace core { 27 | 28 | RsLogBase::RsLogBase() {} 29 | 30 | RsLogBase::~RsLogBase() {} 31 | 32 | int RsLogBase::initialize() { return ERROR_SUCCESS; } 33 | 34 | void RsLogBase::log(LogLevel level, const char *tag, int context_id, 35 | const char *fmt, ...) {} 36 | 37 | RsContextBase::RsContextBase() {} 38 | 39 | RsContextBase::~RsContextBase() {} 40 | 41 | int RsContextBase::generate_id() { return 0; } 42 | 43 | int RsContextBase::get_id() { return 0; } 44 | 45 | int RsContextBase::set_id(int v) { return 0; } 46 | 47 | } // namespace core 48 | } // namespace rs -------------------------------------------------------------------------------- /core/logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_LOGGER_H_ 24 | #define CORE_LOGGER_H_ 25 | 26 | #include "error_code.h" 27 | 28 | namespace rs { 29 | namespace core { 30 | 31 | class RsLogBase { 32 | public: 33 | enum LogLevel { Verbose, Info, Trace, Warn, Error, Disabled }; 34 | 35 | public: 36 | RsLogBase(); 37 | virtual ~RsLogBase(); 38 | 39 | public: 40 | virtual int initialize(); 41 | 42 | public: 43 | virtual void log(LogLevel level, const char *tag, int context_id, 44 | const char *fmt, ...); 45 | }; 46 | 47 | // the context for multiple clients. 48 | class RsContextBase { 49 | public: 50 | RsContextBase(); 51 | virtual ~RsContextBase(); 52 | 53 | public: 54 | virtual int generate_id(); 55 | 56 | virtual int get_id(); 57 | 58 | virtual int set_id(int v); 59 | }; 60 | 61 | void init_log_system(); 62 | 63 | void deinit_log_system(); 64 | 65 | RsLogBase *rs_log(); 66 | RsContextBase *rs_context(); 67 | 68 | // donot print method 69 | #if 1 70 | #define RSLOGV(msg, ...) \ 71 | rs_log()->log(RsLogBase::Verbose, NULL, rs_context()->get_id(), msg, \ 72 | ##__VA_ARGS__) 73 | #define RSLOGI(msg, ...) \ 74 | rs_log()->log(RsLogBase::Info, NULL, rs_context()->get_id(), msg, \ 75 | ##__VA_ARGS__) 76 | #define RSLOGT(msg, ...) \ 77 | rs_log()->log(RsLogBase::Trace, NULL, rs_context()->get_id(), msg, \ 78 | ##__VA_ARGS__) 79 | #define RSLOGW(msg, ...) \ 80 | rs_log()->log(RsLogBase::Warn, NULL, rs_context()->get_id(), msg, \ 81 | ##__VA_ARGS__) 82 | #define RSLOGE(msg, ...) \ 83 | rs_log()->log(RsLogBase::Error, NULL, rs_context()->get_id(), msg, \ 84 | ##__VA_ARGS__) 85 | // use __FUNCTION__ to print c method 86 | #elif 0 87 | #define RSLOGV(msg, ...) \ 88 | rs_log->log(Verbose, __FUNCTION__, rs_context->get_id(), msg, ##__VA_ARGS__) 89 | #define RSLOGI(msg, ...) \ 90 | rs_log->log(Info, __FUNCTION__, rs_context->get_id(), msg, ##__VA_ARGS__) 91 | #define RSLOGT(msg, ...) \ 92 | rs_log->log(Trace, __FUNCTION__, rs_context->get_id(), msg, ##__VA_ARGS__) 93 | #define RSLOGW(msg, ...) \ 94 | rs_log->log(Warn, __FUNCTION__, rs_context->get_id(), msg, ##__VA_ARGS__) 95 | #define RSLOGE(msg, ...) \ 96 | rs_log->log(Error, __FUNCTION__, rs_context->get_id(), msg, ##__VA_ARGS__) 97 | // use __PRETTY_FUNCTION__ to print c++ class:method 98 | #else 99 | #define RSLOGV(msg, ...) \ 100 | rs_log->log(Verbose, __PRETTY_FUNCTION__, rs_context->get_id(), msg, \ 101 | ##__VA_ARGS__) 102 | #define RSLOGI(msg, ...) \ 103 | rs_log->log(Info, __PRETTY_FUNCTION__, rs_context->get_id(), msg, \ 104 | ##__VA_ARGS__) 105 | #define RSLOGT(msg, ...) \ 106 | rs_log->log(Trace, __PRETTY_FUNCTION__, rs_context->get_id(), msg, \ 107 | ##__VA_ARGS__) 108 | #define RSLOGW(msg, ...) \ 109 | rs_log->log(Warn, __PRETTY_FUNCTION__, rs_context->get_id(), msg, \ 110 | ##__VA_ARGS__) 111 | #define RSLOGE(msg, ...) \ 112 | rs_log->log(Error, __PRETTY_FUNCTION__, rs_context->get_id(), msg, \ 113 | ##__VA_ARGS__) 114 | #endif 115 | 116 | } // namespace core 117 | } // namespace rs 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /core/p2p_protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef CORE_RS_P2P_PROTOCOL_H__ 25 | #define CORE_RS_P2P_PROTOCOL_H__ 26 | 27 | namespace rs { 28 | namespace core { 29 | 30 | // Capture Server = CS; Super Peer = SP; Tracker Server = TS; Normal Peer = NP; 31 | // SP<------SPandTS(UDP)------>TS 32 | // NP<------NPandTS(UDP)------>TS 33 | // CS<------CSandSP(TCP)------>SP 34 | // SP<------SPandSP(TCP)------>SP 35 | // SP<------SPandSP(TCP)------>NP 36 | // NP<------NPandNP(TCP)------>NP 37 | 38 | // message format 39 | // |msg size(UINT32)|msg type(BYTE)|msg content(...)| 40 | // |<-----msg size is the total size of message---->| 41 | 42 | enum P2PMESSAGE { 43 | // CS<---->SP 44 | // |size of channel name(UINT8)|channel name(...)| 45 | // |userid(UINT32)|md5 password(MD5_LEN)| 46 | // |max blocksize(UINT32)|max filesize(UINT32)|channel bitRate(float)| 47 | // |isSource(bool)|size of CHANNEL DATA(UINT32)|CHANNEL DATA(...)| 48 | CS2SP_REGISTER = 0x10, 49 | // |channel bitRate(float)| 50 | CS2SP_UPDATE = 0x11, 51 | // |block id(UINT32)|block size(UINT32)| 52 | // |block data(...)| 53 | CS2SP_BLOCK = 0x12, 54 | // |media data length(UINT32)|media data(...)| 55 | CS2SP_MEDIA_TYPE = 0x13, 56 | 57 | // |start block ID(UINT32)| 58 | SP2CS_WELCOME = 0x14, 59 | // |err msg type(UINT16)|should quit(bool)| 60 | SP2CS_MSG = 0x15, 61 | 62 | // TS<---->SP 63 | // |userID(UINT32)|md5 password(MD5_LEN)|service port(USHORT)| 64 | SP2TS_REGISTER = 0x20, 65 | // |UUID(16 bytes)| 66 | // |resource number(UINT32)|connection number(UINT16)|bandwidth 67 | // usage(float)| |exceed max connection(bool)| 68 | SP2TS_STATUS = 0x21, 69 | // |UUID(16 bytes)| 70 | // |resource count(UINT32)|first resource MD5(MD5_LEN)|first resource block 71 | // interval(BlockInterval)...| 72 | SP2TS_RES_LIST = 0x22, 73 | // |UUID(16 bytes)| 74 | SP2TS_GET_SP = 0x23, 75 | // |UUID(16 bytes)| 76 | SP2TS_LOGOUT = 0x24, 77 | 78 | // |UUID(16 bytes)| 79 | TS2SP_WELCOME = 0x25, 80 | // |err msg type(UINT16)|should quit(bool)| 81 | TS2SP_MSG = 0x26, 82 | //|count(UINT8)|first spaddress(NormalAddress)...| 83 | TS2SP_SP_LIST = 0x27, 84 | 85 | TS2SP_GET_RES_LIST = 0x28, 86 | 87 | // TS<---->NP 88 | // |login id(UINT32)|md5 password(MD5_LEN)| 89 | // |version of client(float)|listening port(USHORT)| 90 | // |size of local ip list(UINT8)|first ip addr(in_addr)|...| 91 | NP2TS_LOGIN = 0x30, 92 | // |UUID(16 BYTEs)| 93 | // |RESOURCE MD5(MD5_LEN)| 94 | NP2TS_REQ_RES = 0x31, 95 | // |UUID(16 BYTEs)| 96 | // |info of peer(CorePeerInfo)| 97 | // |Interval count(UINT8)|first BlockInterval|...| 98 | // |Transfer Info(TransferInfo)| 99 | // |playing block(UINT32)|Current Buffering Time(UINT16)|Buffered 100 | // Count(UINT16)|Buffered Time(UINT16)| |Connect Fail Count(UINT16)|Incoming 101 | // Connection Count(UINT16)|Outgoing Connection Count(UINT16)| |Avg Incoming 102 | // Connection Elapsed Time(UINT16)|Avg OutgoingConnection Elapsed 103 | // Time(UINT16)| |Message Percent(float)| 104 | NP2TS_REPORT = 0x32, 105 | // |UUID(16 BYTEs)|current block(UINT32)| 106 | NP2TS_NEED_PEERS = 0x33, 107 | // |UUID(16 BYTEs)| 108 | NP2TS_RES_INTERVAL = 0x34, 109 | // |UUID(16 BYTEs)| 110 | NP2TS_LOGOUT = 0x35, 111 | 112 | // |UUID(16 BYTEs)|ip of peer(P2PAddress)| 113 | TS2NP_WELCOME = 0x36, 114 | // |SP list size(UINT8)|first SP addr(NormalAddress)|..| 115 | // |peer list size(UINT8)|peer1(PeerInfoWithAddr)|...|SP 116 | // addr(NormalAddress)| 117 | TS2NP_PEERS = 0x37, 118 | // |resource block interval(BlockInterval)| 119 | TS2NP_RES_INTERVAL = 0x38, 120 | // |err msg type(UINT16)|should quit(bool)| 121 | TS2NP_MSG = 0x39, 122 | 123 | // NP<---->NP 124 | // |NP version(float)| 125 | // |RESOURCE MD5(MD5_LEN)|Passive Connection(bool)| 126 | // |info of peer(PeerInfoWithAddr)| 127 | NP2NP_HELLO = 0x40, 128 | // |info of peer(CorePeerInfo)|refresh(bool)| 129 | // |Interval count(UINT8)|first BlockInterval|...| 130 | NP2NP_REPORT = 0x41, 131 | // |peer list size(UINT8)|first peer(PeerInfoWithAddr)|...| 132 | NP2NP_NEAR_PEERS = 0x42, 133 | // |block count(UINT8)|first blockid(UINT32)|...| 134 | NP2NP_PUSHLIST = 0x43, 135 | // |block ID(UINT32))|block size(UINT32)|block data(...)| 136 | NP2NP_RESPONSE = 0x44, 137 | // |startid(UINT32)|length(UINT32)|media data length(UINT32)|media 138 | // data(...)| |program name size(UINT8)|program name(...)|program time in 139 | // seconds(UINT32)|channel name size(UINT8)|channel name(...)| 140 | NP2NP_MEDIATYPE = 0x45, 141 | // |err msg type(UINT16)|should quit(bool)| 142 | NP2NP_MSG = 0x46, 143 | 144 | // SP<---->SP 145 | // |RESOURCE MD5(MD5_LEN)|source superpeer address(NormalAddress)| 146 | // |block count(UINT8)|first blockid(UINT32)|...| 147 | SP2SP_PUSHLIST = 0x50, 148 | // |RESOURCE MD5(MD5_LEN)| 149 | // |block ID(UINT32))|block size(UINT32)|block data(...)| 150 | SP2SP_RESPONSE = 0x51, 151 | // |RESOURCE MD5(MD5_LEN)| 152 | // |startid(UINT32)|length(UINT32)|media data length(UINT32)|media 153 | // data(...)| |program name size(UINT8)|program name(...)|program time in 154 | // seconds(UINT32)|channel name size(UINT8)|channel name(...)| 155 | SP2SP_MEDIATYPE = 0x52, 156 | // |RESOURCE MD5(MD5_LEN)| 157 | // |err msg type(UINT16)|should quit(bool)| 158 | SP2SP_MSG = 0x53, 159 | }; 160 | 161 | } // namespace core 162 | } // namespace rs 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /core/resource.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2020 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef RS_CORE_RESOURCE_H_ 24 | #define RS_CORE_RESOURCE_H_ 25 | 26 | namespace rs { 27 | namespace core { 28 | 29 | #include 30 | 31 | template 32 | inline typename std::enable_if::value, 33 | std::unique_ptr>::type 34 | make_unique_ptr(Args &&... args) { 35 | return std::unique_ptr(new Type(std::forward(args)...)); 36 | } 37 | 38 | template 39 | inline typename std::enable_if::value && 40 | 0 == std::extent::value, 41 | std::unique_ptr>::type 42 | make_unique_ptr(size_t size) { 43 | typedef typename remove_extent::type U; 44 | return std::unique_ptr(new U[size]()); 45 | } 46 | 47 | template 48 | typename std::enable_if::value != 0, void>::type 49 | make_unique_ptr(Args &&... args) = delete; 50 | 51 | } // namespace core 52 | } // namespace rs 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /core/socket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "socket.h" 25 | #include "error_code.h" 26 | #include "logger.h" 27 | 28 | namespace rs { 29 | namespace core { 30 | 31 | RsSocket::RsSocket(st_netfd_t client_stfd) { 32 | stfd = client_stfd; 33 | send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT; 34 | recv_bytes = send_bytes = 0; 35 | } 36 | 37 | RsSocket::~RsSocket() {} 38 | 39 | bool RsSocket::is_never_timeout(int64_t timeout_us) { 40 | return timeout_us == (int64_t)ST_UTIME_NO_TIMEOUT; 41 | } 42 | 43 | void RsSocket::set_recv_timeout(int64_t timeout_us) { 44 | recv_timeout = timeout_us; 45 | } 46 | 47 | int64_t RsSocket::get_recv_timeout() { return recv_timeout; } 48 | 49 | void RsSocket::set_send_timeout(int64_t timeout_us) { 50 | send_timeout = timeout_us; 51 | } 52 | 53 | int64_t RsSocket::get_send_timeout() { return send_timeout; } 54 | 55 | int64_t RsSocket::get_recv_bytes() { return recv_bytes; } 56 | 57 | int64_t RsSocket::get_send_bytes() { return send_bytes; } 58 | 59 | int RsSocket::read(void *buf, size_t size, ssize_t *nread) { 60 | int ret = ERROR_SUCCESS; 61 | 62 | ssize_t nb_read = st_read(stfd, buf, size, recv_timeout); 63 | if (nread) { 64 | *nread = nb_read; 65 | } 66 | 67 | if (nb_read <= 0) { 68 | if (nb_read < 0 && errno == ETIME) { 69 | return ERROR_SOCKET_TIMEOUT; 70 | } 71 | 72 | if (nb_read == 0) { 73 | errno = ECONNRESET; 74 | } 75 | 76 | return ERROR_SOCKET_READ; 77 | } 78 | 79 | recv_bytes += nb_read; 80 | 81 | return ret; 82 | } 83 | 84 | int RsSocket::read_fully(void *buf, size_t size, ssize_t *nread) { 85 | int ret = ERROR_SUCCESS; 86 | 87 | ssize_t nb_read = st_read_fully(stfd, buf, size, recv_timeout); 88 | if (nread) { 89 | *nread = nb_read; 90 | } 91 | 92 | if (nb_read != (ssize_t)size) { 93 | if (nb_read < 0 && errno == ETIME) { 94 | return ERROR_SOCKET_TIMEOUT; 95 | } 96 | 97 | if (nb_read >= 0) { 98 | errno = ECONNRESET; 99 | } 100 | 101 | return ERROR_SOCKET_READ_FULLY; 102 | } 103 | 104 | recv_bytes += nb_read; 105 | 106 | return ret; 107 | } 108 | 109 | int RsSocket::write(void *buf, size_t size, ssize_t *nwrite) { 110 | int ret = ERROR_SUCCESS; 111 | 112 | ssize_t nb_write = st_write(stfd, buf, size, send_timeout); 113 | if (nwrite) { 114 | *nwrite = nb_write; 115 | } 116 | 117 | if (nb_write <= 0) { 118 | if (nb_write < 0 && errno == ETIME) { 119 | return ERROR_SOCKET_TIMEOUT; 120 | } 121 | 122 | return ERROR_SOCKET_WRITE; 123 | } 124 | 125 | send_bytes += nb_write; 126 | 127 | return ret; 128 | } 129 | 130 | int RsSocket::writev(const iovec *iov, int iov_size, ssize_t *nwrite) { 131 | int ret = ERROR_SUCCESS; 132 | 133 | ssize_t nb_write = st_writev(stfd, iov, iov_size, send_timeout); 134 | if (nwrite) { 135 | *nwrite = nb_write; 136 | } 137 | 138 | if (nb_write <= 0) { 139 | if (nb_write < 0 && errno == ETIME) { 140 | return ERROR_SOCKET_TIMEOUT; 141 | } 142 | 143 | return ERROR_SOCKET_WRITE; 144 | } 145 | 146 | send_bytes += nb_write; 147 | 148 | return ret; 149 | } 150 | 151 | #ifdef __linux__ 152 | #include 153 | 154 | bool rs_st_epoll_is_supported(void) { 155 | struct epoll_event ev; 156 | 157 | ev.events = EPOLLIN; 158 | ev.data.ptr = NULL; 159 | /* Guaranteed to fail */ 160 | epoll_ctl(-1, EPOLL_CTL_ADD, -1, &ev); 161 | 162 | return (errno != ENOSYS); 163 | } 164 | #endif 165 | 166 | int rs_st_init() { 167 | int ret = ERROR_SUCCESS; 168 | 169 | #ifdef __linux__ 170 | if (!rs_st_epoll_is_supported()) { 171 | ret = ERROR_ST_SET_EPOLL; 172 | RSLOGE("epoll required on Linux. ret=%d", ret); 173 | return ret; 174 | } 175 | #endif 176 | 177 | if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { 178 | ret = ERROR_ST_SET_EPOLL; 179 | RSLOGE("st_set_eventsys use %s failed. ret=%d", st_get_eventsys_name(), 180 | ret); 181 | return ret; 182 | } 183 | RSLOGE("st_set_eventsys to %s", st_get_eventsys_name()); 184 | 185 | if (st_init() != 0) { 186 | ret = ERROR_ST_INITIALIZE; 187 | RSLOGE("st_init failed. ret=%d", ret); 188 | return ret; 189 | } 190 | RSLOGE("st_init success, use %s", st_get_eventsys_name()); 191 | 192 | return ret; 193 | } 194 | 195 | void rs_close_stfd(st_netfd_t &stfd) { 196 | if (stfd) { 197 | int fd = st_netfd_fileno(stfd); 198 | st_netfd_close(stfd); 199 | stfd = NULL; 200 | 201 | // st does not close it sometimes, 202 | // close it manually. 203 | close(fd); 204 | } 205 | } 206 | 207 | } // namespace core 208 | } // namespace rs -------------------------------------------------------------------------------- /core/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_SOCKET_H_ 24 | #define CORE_SOCKET_H_ 25 | 26 | #include 27 | 28 | namespace rs { 29 | namespace core { 30 | 31 | class RsSocket { 32 | private: 33 | int64_t recv_timeout; 34 | int64_t send_timeout; 35 | int64_t recv_bytes; 36 | int64_t send_bytes; 37 | st_netfd_t stfd; 38 | 39 | public: 40 | explicit RsSocket(st_netfd_t client_stfd); 41 | virtual ~RsSocket(); 42 | 43 | public: 44 | virtual bool is_never_timeout(int64_t timeout_us); 45 | virtual void set_recv_timeout(int64_t timeout_us); 46 | virtual int64_t get_recv_timeout(); 47 | virtual void set_send_timeout(int64_t timeout_us); 48 | virtual int64_t get_send_timeout(); 49 | virtual int64_t get_recv_bytes(); 50 | virtual int64_t get_send_bytes(); 51 | 52 | public: 53 | /** 54 | * @param nread, the actual read bytes, ignore if NULL. 55 | */ 56 | virtual int read(void *buf, size_t size, ssize_t *nread); 57 | virtual int read_fully(void *buf, size_t size, ssize_t *nread); 58 | /** 59 | * @param nwrite, the actual write bytes, ignore if NULL. 60 | */ 61 | virtual int write(void *buf, size_t size, ssize_t *nwrite); 62 | virtual int writev(const iovec *iov, int iov_size, ssize_t *nwrite); 63 | }; 64 | 65 | // initialize st, requires epoll. 66 | extern int rs_st_init(); 67 | 68 | // close the netfd, and close the underlayer fd. 69 | extern void rs_close_stfd(st_netfd_t &stfd); 70 | 71 | } // namespace core 72 | } // namespace rs 73 | 74 | #endif /* CORE_RSSOCKET_H_ */ 75 | -------------------------------------------------------------------------------- /core/socket_connect.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "socket_connect.h" 24 | #include "error_code.h" 25 | #include "logger.h" 26 | #include "socket.h" 27 | #include "st.h" 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | namespace rs { 36 | namespace core { 37 | 38 | int socket_connect(int socket_type, string server, int port, int64_t timeout, 39 | st_netfd_t *pstfd) { 40 | int ret = ERROR_SUCCESS; 41 | 42 | *pstfd = NULL; 43 | st_netfd_t stfd = NULL; 44 | sockaddr_in addr; 45 | 46 | int sock = 0; 47 | if (socket_type) 48 | sock = socket(AF_INET, SOCK_STREAM, 0); 49 | else 50 | sock = socket(AF_INET, SOCK_DGRAM, 0); 51 | 52 | if (sock == -1) { 53 | ret = ERROR_SOCKET_CREATE; 54 | RSLOGE("create socket error. ret=%d", ret); 55 | return ret; 56 | } 57 | 58 | stfd = st_netfd_open_socket(sock); 59 | if (stfd == NULL) { 60 | ret = ERROR_ST_OPEN_SOCKET; 61 | RSLOGE("st_netfd_open_socket failed. ret=%d", ret); 62 | return ret; 63 | } 64 | 65 | addr.sin_family = AF_INET; 66 | addr.sin_port = htons(port); 67 | addr.sin_addr.s_addr = inet_addr(server.c_str()); 68 | 69 | if (st_connect(stfd, (const struct sockaddr *)&addr, sizeof(sockaddr_in), 70 | timeout) == -1) { 71 | ret = ERROR_ST_CONNECT; 72 | RSLOGE("connect to server error. ip=%s, port=%d, ret=%d", 73 | server.c_str(), port, ret); 74 | goto failed; 75 | } 76 | 77 | RSLOGE("connect ok. server=%s, ip=%s, port=%d", server.c_str(), 78 | server.c_str(), port); 79 | 80 | *pstfd = stfd; 81 | return ret; 82 | 83 | failed: 84 | if (stfd) { 85 | rs_close_stfd(stfd); 86 | } 87 | return ret; 88 | } 89 | 90 | } // namespace core 91 | } // namespace rs -------------------------------------------------------------------------------- /core/socket_connect.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_SOCKET_CONNECT_H_ 24 | #define CORE_SOCKET_CONNECT_H_ 25 | 26 | #include 27 | #include 28 | 29 | using namespace std; 30 | 31 | namespace rs { 32 | namespace core { 33 | 34 | // client open socket and connect to server. 35 | int socket_connect(int socket_type, string server, int port, int64_t timeout, 36 | st_netfd_t *pstfd); 37 | 38 | } // namespace core 39 | } // namespace rs 40 | 41 | #endif /* CORE_RS_SOCKET_CONNECT_H_ */ 42 | -------------------------------------------------------------------------------- /core/socket_handler.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef CORE_SOCKET_HANDLER_H_ 25 | #define CORE_SOCKET_HANDLER_H_ 26 | 27 | #include 28 | #include 29 | 30 | namespace rs { 31 | namespace core { 32 | 33 | class ITcpHandler { 34 | public: 35 | ITcpHandler() {} 36 | virtual ~ITcpHandler() {} 37 | 38 | public: 39 | virtual int handle_tcp_connect(st_netfd_t stfd) = 0; 40 | }; 41 | 42 | class IUdpHandler { 43 | public: 44 | IUdpHandler() {} 45 | virtual ~IUdpHandler() {} 46 | 47 | public: 48 | virtual int handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, 49 | char *buf, int nb_buf) = 0; 50 | }; 51 | 52 | } // namespace core 53 | } // namespace rs 54 | 55 | #endif /* CORE_RS_SOCKET_HANDLER_H_ */ 56 | -------------------------------------------------------------------------------- /core/streamer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "streamer.h" 25 | 26 | namespace rs { 27 | namespace core { 28 | 29 | RsStreamer::RsStreamer() { 30 | curr = base = NULL; 31 | size = 0; 32 | } 33 | 34 | RsStreamer::~RsStreamer() {} 35 | 36 | void RsStreamer::initialize(char *buf, int nb) { 37 | base = curr = buf; 38 | size = nb; 39 | } 40 | 41 | uint8_t RsStreamer::read_char() { 42 | uint8_t value = 0; 43 | get_as_type(value); 44 | return value; 45 | } 46 | 47 | uint16_t RsStreamer::read_short() { 48 | uint16_t value = 0; 49 | get_as_type(value); 50 | return value; 51 | } 52 | 53 | uint32_t RsStreamer::read_int() { 54 | uint32_t value = 0; 55 | get_as_type(value); 56 | return value; 57 | } 58 | 59 | uint64_t RsStreamer::read_long() { 60 | uint64_t value = 0; 61 | get_as_type(value); 62 | return value; 63 | } 64 | 65 | char *RsStreamer::read_nbytes(int nb) { 66 | char *buf = curr; 67 | assert((curr + nb) <= (base + size)); 68 | curr += nb; 69 | return buf; 70 | } 71 | 72 | void RsStreamer::skip(int nb) { 73 | assert((curr + nb) <= (base + size)); 74 | curr += nb; 75 | } 76 | 77 | void RsStreamer::write_char(char value) { *curr++ = value; } 78 | 79 | void RsStreamer::write_short(uint16_t value) { set_as_type(value); } 80 | 81 | void RsStreamer::write_int(uint32_t value) { set_as_type(value); } 82 | 83 | void RsStreamer::write_long(uint64_t value) { set_as_type(value); } 84 | 85 | void RsStreamer::write_nbytes(char *buf, int nb) { 86 | memcpy(curr, buf, nb); 87 | curr += nb; 88 | } 89 | 90 | } // namespace core 91 | } // namespace rs -------------------------------------------------------------------------------- /core/streamer.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef CORE_STREAMER_H_ 25 | #define CORE_STREAMER_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace rs { 32 | namespace core { 33 | 34 | class RsStreamer { 35 | public: 36 | RsStreamer(); 37 | virtual ~RsStreamer(); 38 | void initialize(char *buf, int nb); 39 | 40 | private: 41 | template void get_as_type(T &x) { 42 | int typesize = sizeof(T); 43 | assert((curr + typesize) <= (base + size)); 44 | memcpy((char *)&x, curr, typesize); 45 | curr += typesize; 46 | } 47 | 48 | template void set_as_type(T &x) { 49 | int typesize = sizeof(T); 50 | assert((curr + typesize) <= (base + size)); 51 | memcpy(curr, (char *)&x, typesize); 52 | curr += typesize; 53 | } 54 | 55 | public: 56 | char *get_buffer() { return base; } 57 | 58 | uint32_t get_size() { return size; } 59 | 60 | public: 61 | // for read 62 | uint8_t read_char(); 63 | uint16_t read_short(); 64 | uint32_t read_int(); 65 | uint64_t read_long(); 66 | void skip(int nb); 67 | char *read_nbytes(int nb); 68 | 69 | public: 70 | // for write 71 | void write_char(char value); 72 | void write_short(uint16_t value); 73 | void write_int(uint32_t value); 74 | void write_long(uint64_t value); 75 | void write_nbytes(char *buf, int nb); 76 | 77 | private: 78 | char *base; 79 | char *curr; 80 | int size; 81 | }; 82 | 83 | } // namespace core 84 | } // namespace rs 85 | 86 | #endif /* CORE_STREAMER_H_ */ 87 | -------------------------------------------------------------------------------- /core/struct_define.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef CORE_STRUCT_DEFINE_H__ 25 | #define CORE_STRUCT_DEFINE_H__ 26 | 27 | #include "../core/core_struct.h" 28 | #include "../core/interval_array.h" 29 | #include 30 | 31 | namespace rs { 32 | namespace core { 33 | 34 | class map_str { 35 | public: 36 | bool operator<(const map_str other) const { 37 | return strncasecmp(str_, other.str_, UUID_LENGTH) < 0; 38 | } 39 | 40 | bool operator!=(const map_str other) const { 41 | return strncasecmp(str_, other.str_, UUID_LENGTH) != 0; 42 | } 43 | 44 | map_str &operator=(const map_str &other) { 45 | if (&other == this) 46 | return *this; 47 | 48 | memcpy(str_, other.str_, sizeof(str_)); 49 | 50 | return *this; 51 | } 52 | 53 | char str_[UUID_LENGTH + 1]; 54 | }; 55 | // channelNode 56 | struct ChannelNode { 57 | ChannelNode() { 58 | userID = 0; 59 | pswd[0] = 0; 60 | servicePort = 0; 61 | resourceCount = 0; 62 | conNum = 0; 63 | exceedMaxConn = 0; 64 | bandwidth = 0; 65 | memset(&spAddress, 0, sizeof(NetAddress)); 66 | 67 | time(&last_recv_report_time_); 68 | pHash = NULL; 69 | spService = NULL; 70 | } 71 | 72 | ~ChannelNode() { delete_pHash(); } 73 | 74 | ChannelNode &operator=(const ChannelNode &pNode) { 75 | userID = pNode.userID; 76 | memcpy(pswd, pNode.pswd, sizeof(pswd)); 77 | servicePort = pNode.servicePort; 78 | resourceCount = pNode.resourceCount; 79 | conNum = pNode.conNum; 80 | exceedMaxConn = pNode.exceedMaxConn; 81 | bandwidth = pNode.bandwidth; 82 | memcpy(&spAddress, &(pNode.spAddress), sizeof(NetAddress)); 83 | spService = pNode.spService; 84 | 85 | time(&last_recv_report_time_); 86 | 87 | new_pHash(); 88 | 89 | for (int i = 0; i < resourceCount; i++) { 90 | pHash[i] = pNode.pHash[i]; 91 | } 92 | 93 | return (*this); 94 | } 95 | 96 | time_t last_recv_report_time_; 97 | uint32_t userID; 98 | uint8_t pswd[33]; 99 | uint16_t servicePort; 100 | uint32_t resourceCount; 101 | uint16_t conNum; 102 | bool exceedMaxConn; 103 | float bandwidth; 104 | NetAddress spAddress; 105 | void *spService; 106 | 107 | MD5_Hash_Str *pHash; 108 | 109 | void new_pHash() { 110 | if (0 < resourceCount) { 111 | pHash = new MD5_Hash_Str[resourceCount]; 112 | } else { 113 | pHash = NULL; 114 | } 115 | } 116 | 117 | void delete_pHash() { 118 | if (NULL != pHash) 119 | delete[] pHash; 120 | // 121 | pHash = NULL; 122 | } 123 | }; 124 | 125 | // npnode 126 | struct NPNode { 127 | map_str digits; 128 | time_t last_recv_report_time_; 129 | float fVersion; // version of client(float) 130 | uint16_t port; // listening port(USHORT) 131 | P2PAddress clientAddress; //// 132 | 133 | CorePeerInfo coreInfo; 134 | TransferInfo transInfo; 135 | uint32_t playingBlock; // playing block(UINT32) 136 | uint16_t currentBufferingTime; // Current Buffering Time(UINT16) 137 | uint16_t bufferedCount; // Buffered Count(UINT16) 138 | uint16_t bufferedTime; // Buffered Time(UINT16) 139 | uint16_t connectFailCount; // Connect Fail Count(UINT16) 140 | uint16_t incomingConnectionCount; // Incoming Connection Count(UINT16) 141 | uint16_t outgoingConnectionCount; // Outgoing Connection Count(UINT16) 142 | uint16_t AvgincomingConnectionElapsedTime; // Avg Incoming Connection 143 | // Elapsed Time(UINT16) 144 | uint16_t AvgoutgoingConnectionElapsedTime; // Avg OutgoingConnection Elapsed 145 | // Time(UINT16) 146 | float msgPercent; // Message Percent(float) 147 | 148 | uint8_t countInterval; 149 | IntervalArray intervalArray; 150 | 151 | MD5_Hash_Str channelID_md5; 152 | 153 | NPNode() { 154 | memset(this, 0, sizeof(NPNode)); 155 | time(&last_recv_report_time_); 156 | } 157 | 158 | NPNode &operator=(const NPNode &node) { 159 | if (&node == this) 160 | return *this; 161 | 162 | digits = node.digits; 163 | last_recv_report_time_ = node.last_recv_report_time_; 164 | fVersion = node.fVersion; // version of client(float) 165 | port = node.port; // listening port(USHORT) 166 | clientAddress = node.clientAddress; //// 167 | 168 | coreInfo = node.coreInfo; 169 | transInfo = node.transInfo; 170 | playingBlock = node.playingBlock; // playing block(UINT32) 171 | currentBufferingTime = 172 | node.currentBufferingTime; // Current Buffering Time(UINT16) 173 | bufferedCount = node.bufferedCount; // Buffered Count(UINT16) 174 | bufferedTime = node.bufferedTime; // Buffered Time(UINT16) 175 | connectFailCount = node.connectFailCount; // Connect Fail Count(UINT16) 176 | incomingConnectionCount = 177 | node.AvgincomingConnectionElapsedTime; // Incoming Connection 178 | // Count(UINT16) 179 | outgoingConnectionCount = 180 | node.outgoingConnectionCount; // Outgoing Connection Count(UINT16) 181 | AvgincomingConnectionElapsedTime = 182 | node.AvgincomingConnectionElapsedTime; // Avg Incoming Connection 183 | // Elapsed Time(UINT16) 184 | AvgoutgoingConnectionElapsedTime = 185 | node.AvgoutgoingConnectionElapsedTime; // Avg OutgoingConnection 186 | // Elapsed Time(UINT16) 187 | msgPercent = node.msgPercent; // Message Percent(float) 188 | 189 | countInterval = node.countInterval; 190 | intervalArray = node.intervalArray; 191 | 192 | channelID_md5 = node.channelID_md5; 193 | 194 | return *this; 195 | } 196 | }; 197 | 198 | } // namespace core 199 | } // namespace rs 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /core/system_time.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2020 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "system_time.h" 25 | #include 26 | #include 27 | 28 | #define rs_min(a, b) (((a) < (b)) ? (a) : (b)) 29 | #define rs_max(a, b) (((a) < (b)) ? (b) : (a)) 30 | 31 | namespace rs { 32 | namespace core { 33 | 34 | SystemTime *SystemTime::p = new SystemTime; 35 | SystemTime *SystemTime::instance() { return p; } 36 | 37 | constexpr uint64_t kSystemTime_Resolution_us = 300 * 1000; 38 | 39 | SystemTime::SystemTime() { 40 | 41 | } 42 | 43 | SystemTime::~SystemTime() {} 44 | 45 | int64_t SystemTime::update_system_time_ms() { 46 | timeval now; 47 | 48 | if (gettimeofday(&now, NULL) < 0) { 49 | return -1; 50 | } 51 | 52 | int64_t now_us = ((int64_t)now.tv_sec) * 1000 * 1000 + (int64_t)now.tv_usec; 53 | 54 | if (system_time_us_cache <= 0) { 55 | system_time_us_cache = now_us; 56 | system_time_startup_time = now_us; 57 | return system_time_us_cache / 1000; 58 | } 59 | 60 | // use relative time. 61 | int64_t diff = now_us - system_time_us_cache; 62 | diff = rs_max(0, diff); 63 | if (diff < 0 || diff > 1000 * kSystemTime_Resolution_us) { 64 | system_time_startup_time += diff; 65 | } 66 | 67 | system_time_us_cache = now_us; 68 | 69 | return system_time_us_cache / 1000; 70 | } 71 | 72 | int64_t SystemTime::get_system_time_ms() { 73 | if (system_time_us_cache <= 0) { 74 | update_system_time_ms(); 75 | } 76 | 77 | return system_time_us_cache / 1000; 78 | } 79 | 80 | int64_t SystemTime::get_system_startup_time_ms() { 81 | if (system_time_startup_time <= 0) { 82 | update_system_time_ms(); 83 | } 84 | 85 | return system_time_startup_time / 1000; 86 | } 87 | 88 | } // namespace core 89 | } // namespace rs -------------------------------------------------------------------------------- /core/system_time.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2020 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_SYSTEM_TIME_H 24 | #define CORE_SYSTEM_TIME_H 25 | 26 | #include 27 | #include 28 | 29 | namespace rs { 30 | namespace core { 31 | 32 | class SystemTime { 33 | public: 34 | SystemTime(); 35 | virtual ~SystemTime(); 36 | 37 | public: 38 | // for single instance 39 | static SystemTime *instance(); 40 | 41 | public: 42 | int64_t get_system_time_ms(); 43 | int64_t get_system_startup_time_ms(); 44 | int64_t update_system_time_ms(); 45 | 46 | private: 47 | static SystemTime *p; 48 | 49 | private: 50 | int64_t system_time_us_cache = 0; 51 | int64_t system_time_startup_time = 0; 52 | }; 53 | 54 | } // namespace core 55 | } // namespace rs 56 | 57 | #endif -------------------------------------------------------------------------------- /core/tcp_listener.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "tcp_listener.h" 24 | #include "error_code.h" 25 | #include "logger.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace rs { 34 | namespace core { 35 | 36 | // nginx also set to 512 37 | #define SERVER_LISTEN_BACKLOG 512 38 | 39 | RsTcpListener::RsTcpListener(string ip, int port, ITcpHandler *handler) 40 | : RsThread("tcplistener") { 41 | ip_addr = ip; 42 | listen_port = port; 43 | tcp_handler = handler; 44 | } 45 | 46 | RsTcpListener::~RsTcpListener() {} 47 | 48 | int RsTcpListener::start_listen() { 49 | int ret = ERROR_SUCCESS; 50 | 51 | socket_fd = socket(AF_INET, SOCK_STREAM, 0); 52 | 53 | if (socket_fd == -1) { 54 | ret = ERROR_SOCKET_CREATE; 55 | return ret; 56 | } 57 | 58 | int reuse_flag = 1; 59 | if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag, 60 | sizeof(reuse_flag)) == -1) { 61 | ret = ERROR_SOCKET_SETREUSE; 62 | return ret; 63 | } 64 | 65 | sockaddr_in addr; 66 | addr.sin_family = AF_INET; 67 | addr.sin_port = htons(listen_port); 68 | addr.sin_addr.s_addr = inet_addr(ip_addr.c_str()); 69 | if (bind(socket_fd, (const sockaddr *)&addr, sizeof(addr)) == -1) { 70 | ret = ERROR_SOCKET_BIND; 71 | return ret; 72 | } 73 | 74 | if (::listen(socket_fd, SERVER_LISTEN_BACKLOG) == -1) { 75 | ret = ERROR_SOCKET_LISTEN; 76 | return ret; 77 | } 78 | 79 | st_socket_fd = st_netfd_open_socket(socket_fd); 80 | 81 | if (st_socket_fd == NULL) { 82 | ret = ERROR_ST_OPEN_SOCKET; 83 | return ret; 84 | } 85 | 86 | // call baseclass RsThread's method start_thread() to start the thread. 87 | start_thread(); 88 | 89 | return ret; 90 | } 91 | 92 | int RsTcpListener::on_thread_start() { 93 | int ret = ERROR_SUCCESS; 94 | 95 | return ret; 96 | } 97 | 98 | int RsTcpListener::on_before_loop() { 99 | int ret = ERROR_SUCCESS; 100 | 101 | return ret; 102 | } 103 | 104 | int RsTcpListener::loop() { 105 | int ret = ERROR_SUCCESS; 106 | 107 | st_netfd_t client_stfd = 108 | st_accept(st_socket_fd, NULL, NULL, ST_UTIME_NO_TIMEOUT); 109 | 110 | if (client_stfd == NULL) { 111 | // ignore error. 112 | if (errno != EINTR) { 113 | RSLOGE("ignore accept thread stoppped for accept client error"); 114 | } 115 | return ret; 116 | } 117 | 118 | if ((ret = tcp_handler->handle_tcp_connect(client_stfd)) != ERROR_SUCCESS) { 119 | RSLOGE("accept client error. ret=%d", ret); 120 | return ret; 121 | } 122 | 123 | return ret; 124 | } 125 | 126 | int RsTcpListener::on_end_loop() { 127 | int ret = ERROR_SUCCESS; 128 | 129 | return ret; 130 | } 131 | 132 | int RsTcpListener::on_thread_stop() { 133 | int ret = ERROR_SUCCESS; 134 | 135 | return ret; 136 | } 137 | 138 | } // namespace core 139 | } // namespace rs 140 | -------------------------------------------------------------------------------- /core/tcp_listener.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_TCP_LISTENER_H 24 | #define CORE_TCP_LISTENER_H 25 | 26 | #include "socket_handler.h" 27 | #include "st.h" 28 | #include "thread.h" 29 | #include 30 | 31 | using namespace std; 32 | 33 | namespace rs { 34 | namespace core { 35 | 36 | class RsTcpListener : public RsThread { 37 | public: 38 | RsTcpListener(string ip, int port, ITcpHandler *handler); 39 | ~RsTcpListener(); 40 | 41 | public: 42 | int start_listen(); 43 | 44 | public: 45 | // implement rs_thread's virtual function 46 | virtual int on_thread_start(); 47 | virtual int on_before_loop(); 48 | virtual int loop(); 49 | virtual int on_end_loop(); 50 | virtual int on_thread_stop(); 51 | 52 | private: 53 | int socket_fd; 54 | st_netfd_t st_socket_fd; 55 | 56 | string ip_addr; 57 | int listen_port; 58 | 59 | ITcpHandler *tcp_handler; 60 | }; 61 | 62 | } // namespace core 63 | } // namespace rs 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /core/thread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "thread.h" 24 | #include "error_code.h" 25 | #include "logger.h" 26 | #include "st.h" 27 | 28 | namespace rs { 29 | namespace core { 30 | 31 | RsThread::RsThread(const char *name) { 32 | _name = name; 33 | _cid = -1; 34 | tid = 0; 35 | cycle_interval_us = 0; 36 | loop_flag = false; 37 | } 38 | 39 | RsThread::~RsThread() { tid = 0; } 40 | 41 | int RsThread::start_thread() { 42 | int ret = ERROR_SUCCESS; 43 | 44 | if (tid) { 45 | RSLOGE("thread %s already running.", _name); 46 | return ret; 47 | } 48 | 49 | if ((tid = st_thread_create(thread_intermediary, this, (_joinable ? 1 : 0), 50 | 0)) == NULL) { 51 | ret = ERROR_ST_CREATE_CYCLE_THREAD; 52 | RSLOGE("st_thread_create failed. ret=%d", ret); 53 | return ret; 54 | } 55 | 56 | disposed = false; 57 | // we set to loop to true for thread to run. 58 | loop_flag = true; 59 | 60 | // wait for cid to ready, for parent thread to get the cid. 61 | while (_cid < 0) { 62 | st_usleep(10 * 1000); 63 | } 64 | 65 | // now, cycle thread can run. 66 | can_run = true; 67 | 68 | return ret; 69 | } 70 | 71 | void RsThread::thread_loop() { 72 | int ret = ERROR_SUCCESS; 73 | 74 | _cid = 0; // hard code; 75 | 76 | on_thread_start(); 77 | 78 | // thread is running now. 79 | really_terminated = false; 80 | 81 | // wait for cid to ready, for parent thread to get the cid. 82 | while (!can_run && loop_flag) { 83 | st_usleep(10 * 1000); 84 | } 85 | 86 | while (loop_flag) { 87 | if ((ret = on_before_loop()) != ERROR_SUCCESS) { 88 | RSLOGE( 89 | "thread %s on before cycle failed, ignored and retry, ret=%d", 90 | _name, ret); 91 | goto failed; 92 | } 93 | RSLOGE("thread %s on before cycle success", _name); 94 | 95 | if ((ret = loop()) != ERROR_SUCCESS) { 96 | goto failed; 97 | } 98 | 99 | if ((ret = on_end_loop()) != ERROR_SUCCESS) { 100 | RSLOGE("thread %s on end cycle failed, ignored and retry, ret=%d", 101 | _name, ret); 102 | goto failed; 103 | } 104 | RSLOGE("thread %s on end cycle success", _name); 105 | 106 | failed: 107 | if (!loop_flag) { 108 | break; 109 | } 110 | 111 | if (cycle_interval_us != 0) { 112 | st_usleep(cycle_interval_us); 113 | } 114 | } 115 | 116 | // readly terminated now. 117 | really_terminated = true; 118 | 119 | on_thread_stop(); 120 | } 121 | 122 | void RsThread::stop_thread() {} 123 | 124 | // the thread loop 125 | void *RsThread::thread_intermediary(void *arg) { 126 | RsThread *obj = (RsThread *)arg; 127 | 128 | obj->thread_loop(); 129 | } 130 | 131 | void RsThread::dispose() {} 132 | 133 | } // namespace core 134 | } // namespace rs -------------------------------------------------------------------------------- /core/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_THREAD_H_ 24 | #define CORE_THREAD_H_ 25 | 26 | #include "st.h" 27 | 28 | namespace rs { 29 | namespace core { 30 | 31 | // every thread must inherit from this class to support actual threading 32 | // operation 33 | class RsThread { 34 | public: 35 | explicit RsThread(const char *name); 36 | virtual ~RsThread(); 37 | 38 | public: 39 | int start_thread(); 40 | void stop_thread(); 41 | // inherited class must implement those functions 42 | virtual int on_thread_start() = 0; 43 | virtual int on_before_loop() = 0; 44 | virtual int loop() = 0; 45 | virtual int on_end_loop() = 0; 46 | virtual int on_thread_stop() = 0; 47 | 48 | private: 49 | virtual void dispose(); 50 | static void *thread_intermediary(void *arg); 51 | void thread_loop(); 52 | 53 | public: 54 | bool loop_flag; 55 | 56 | private: 57 | st_thread_t tid; 58 | int _cid; 59 | 60 | bool can_run; 61 | bool really_terminated; 62 | bool _joinable; 63 | const char *_name; 64 | bool disposed; 65 | 66 | public: 67 | int64_t cycle_interval_us; 68 | }; 69 | 70 | } // namespace core 71 | } // namespace rs 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /core/timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "timer.h" 24 | #include "system_time.h" 25 | #include "error_code.h" 26 | #include 27 | #include 28 | #include 29 | 30 | namespace rs { 31 | namespace core { 32 | 33 | #define SYS_TIMER_LOOP_INTERVAL 500 // sleep for 500ms 34 | 35 | RsTimer *RsTimer::p = new RsTimer; 36 | RsTimer *RsTimer::instance() { return p; } 37 | 38 | RsTimer::RsTimer() : RsThread("rstimer") { 39 | last_thread_time = 0; 40 | thread_start_flag = false; 41 | } 42 | 43 | RsTimer::~RsTimer() {} 44 | 45 | int RsTimer::on_end_loop() { 46 | int ret = ERROR_SUCCESS; 47 | 48 | return ret; 49 | } 50 | 51 | int RsTimer::on_thread_stop() { 52 | int ret = ERROR_SUCCESS; 53 | 54 | return ret; 55 | } 56 | 57 | int RsTimer::on_thread_start() { 58 | int ret = ERROR_SUCCESS; 59 | 60 | return ret; 61 | } 62 | 63 | int RsTimer::on_before_loop() { 64 | int ret = ERROR_SUCCESS; 65 | 66 | return ret; 67 | } 68 | 69 | int RsTimer::loop() { 70 | int ret = ERROR_SUCCESS; 71 | check_timeout(); 72 | st_usleep(SYS_TIMER_LOOP_INTERVAL * 1000); 73 | return ret; 74 | } 75 | void RsTimer::add_timer(int64_t timeout, int64_t timerid, 76 | ITimerHandler *callback) { 77 | assert(callback != NULL); 78 | if (!thread_start_flag) { 79 | start_thread(); 80 | thread_start_flag = true; 81 | } 82 | timer_item item; 83 | item.timeout = timeout; 84 | item.timerid = timerid; 85 | item.callback = callback; 86 | item.last_signal_time = 0; 87 | timer_vector.push_back(item); 88 | } 89 | 90 | void RsTimer::delete_timer(int64_t timeout, int64_t timerid, 91 | ITimerHandler *callback) { 92 | timer_item item; 93 | item.timeout = timeout; 94 | item.timerid = timerid; 95 | item.callback = callback; 96 | timer_vector.erase(remove(timer_vector.begin(), timer_vector.end(), item)); 97 | } 98 | 99 | void RsTimer::check_timeout() { 100 | int64_t curr = SystemTime::instance()->get_system_time_ms(); 101 | 102 | vector::iterator iter = timer_vector.begin(); 103 | // init the first signal time 104 | if (last_thread_time == 0) { 105 | last_thread_time = curr; 106 | for (; iter < timer_vector.end(); iter++) { 107 | iter->last_signal_time = curr; 108 | } 109 | return; 110 | } 111 | int64_t delta = 0; 112 | // iterate the vector to trigger the timer's callback 113 | iter = timer_vector.begin(); 114 | for (; iter < timer_vector.end(); iter++) { 115 | int64_t timeout = iter->timeout; 116 | delta = curr - iter->last_signal_time; 117 | if (delta >= timeout) { 118 | (iter->callback)->handle_timeout(iter->timerid); 119 | iter->last_signal_time = curr; 120 | } 121 | } 122 | return; 123 | } 124 | 125 | } // namespace core 126 | } // namespace rs -------------------------------------------------------------------------------- /core/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_TIMER_H_ 24 | #define CORE_TIMER_H_ 25 | #include "thread.h" 26 | #include 27 | #include 28 | 29 | using namespace std; 30 | 31 | namespace rs { 32 | namespace core { 33 | 34 | class ITimerHandler { 35 | public: 36 | ITimerHandler() {} 37 | virtual ~ITimerHandler() {} 38 | 39 | public: 40 | virtual int handle_timeout(int64_t timerid) = 0; 41 | }; 42 | 43 | typedef struct timer_item { 44 | int64_t timeout; 45 | int64_t timerid; 46 | int64_t last_signal_time; 47 | ITimerHandler *callback; 48 | 49 | bool operator==(const timer_item &rhs) { 50 | if ((callback == rhs.callback) && (timeout == rhs.timeout) && 51 | (timerid == rhs.timerid)) 52 | return true; 53 | return false; 54 | } 55 | } timer_item; 56 | 57 | class RsTimer : public RsThread { 58 | private: 59 | static RsTimer *p; 60 | 61 | public: 62 | RsTimer(); 63 | virtual ~RsTimer(); 64 | 65 | public: 66 | // for single instance 67 | static RsTimer *instance(); 68 | 69 | public: 70 | // implement rs_thread's virtual function 71 | virtual int on_thread_start() override final; 72 | virtual int on_before_loop() override final; 73 | virtual int loop() override final; 74 | virtual int on_end_loop() override final; 75 | virtual int on_thread_stop() override final; 76 | 77 | public: 78 | // for others to get timer service 79 | void add_timer(int64_t timeout, int64_t timerid, ITimerHandler *callback); 80 | void delete_timer(int64_t timeout, int64_t timerid, 81 | ITimerHandler *callback); 82 | 83 | private: 84 | void check_timeout(); 85 | 86 | private: 87 | bool thread_start_flag; 88 | int64_t last_thread_time; 89 | vector timer_vector; 90 | }; 91 | 92 | } // namespace core 93 | } // namespace rs 94 | 95 | #endif /* CORE_TIMER_H_ */ 96 | -------------------------------------------------------------------------------- /core/udp_listener.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "udp_listener.h" 24 | #include "error_code.h" 25 | #include "logger.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace rs { 34 | namespace core { 35 | 36 | #define UDP_RECEIVE_BUFFER_SIZE 65535 37 | 38 | RsUdpListener::RsUdpListener(string ip, int port, IUdpHandler *handler) 39 | : RsThread("udplistener") { 40 | ip_addr = ip; 41 | listen_port = port; 42 | udp_handler = handler; 43 | 44 | buffer_size = UDP_RECEIVE_BUFFER_SIZE; 45 | recv_buffer = new char[UDP_RECEIVE_BUFFER_SIZE]; 46 | } 47 | 48 | RsUdpListener::~RsUdpListener() { 49 | 50 | } 51 | 52 | int RsUdpListener::start_listen() { 53 | int ret = ERROR_SUCCESS; 54 | 55 | socket_fd = socket(AF_INET, SOCK_DGRAM, 0); 56 | 57 | if (socket_fd == -1) { 58 | ret = ERROR_SOCKET_CREATE; 59 | return ret; 60 | } 61 | 62 | int reuse_flag = 1; 63 | if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag, 64 | sizeof(reuse_flag))) { 65 | ret = ERROR_SOCKET_SETREUSE; 66 | return ret; 67 | } 68 | 69 | sockaddr_in addr; 70 | addr.sin_family = AF_INET; 71 | addr.sin_port = htons(listen_port); 72 | addr.sin_addr.s_addr = inet_addr(ip_addr.c_str()); 73 | if (bind(socket_fd, (const sockaddr *)&addr, sizeof(addr)) == -1) { 74 | ret = ERROR_SOCKET_BIND; 75 | return ret; 76 | } 77 | 78 | st_socket_fd = st_netfd_open_socket(socket_fd); 79 | 80 | if (st_socket_fd == NULL) { 81 | ret = ERROR_ST_OPEN_SOCKET; 82 | return ret; 83 | } 84 | 85 | // call baseclass RsThread's method start_thread() to start the thread. 86 | start_thread(); 87 | 88 | return ret; 89 | } 90 | 91 | int RsUdpListener::on_thread_start() { 92 | int ret = ERROR_SUCCESS; 93 | 94 | return ret; 95 | } 96 | 97 | int RsUdpListener::on_before_loop() { 98 | int ret = ERROR_SUCCESS; 99 | 100 | return ret; 101 | } 102 | 103 | int RsUdpListener::loop() { 104 | int ret = ERROR_SUCCESS; 105 | sockaddr_in addr; 106 | int from_size = sizeof(sockaddr_in); 107 | int read_size = 108 | st_recvfrom(st_socket_fd, recv_buffer, buffer_size, (sockaddr *)&addr, 109 | &from_size, ST_UTIME_NO_TIMEOUT); 110 | 111 | if (read_size <= 0) { 112 | // ignore it since nothing received from the peer 113 | return ret; 114 | } 115 | 116 | if (ret = udp_handler->handle_udp_packet(st_socket_fd, &addr, recv_buffer, 117 | read_size) != ERROR_SUCCESS) { 118 | RSLOGE("accept client error. ret=%d", ret); 119 | return ret; 120 | } 121 | 122 | return ret; 123 | } 124 | 125 | int RsUdpListener::on_end_loop() { 126 | int ret = ERROR_SUCCESS; 127 | 128 | return ret; 129 | } 130 | 131 | int RsUdpListener::on_thread_stop() { 132 | int ret = ERROR_SUCCESS; 133 | 134 | return ret; 135 | } 136 | 137 | } // namespace core 138 | } // namespace rs -------------------------------------------------------------------------------- /core/udp_listener.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2018 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef CORE_UDP_LISTENER_H_ 24 | #define CORE_UDP_LISTENER_H_ 25 | 26 | #include "socket_handler.h" 27 | #include "st.h" 28 | #include "thread.h" 29 | #include 30 | 31 | using namespace std; 32 | 33 | namespace rs { 34 | namespace core { 35 | 36 | class RsUdpListener : public RsThread { 37 | 38 | public: 39 | RsUdpListener(string ip, int port, IUdpHandler *handler); 40 | ~RsUdpListener(); 41 | 42 | public: 43 | int start_listen(); 44 | 45 | public: 46 | // implement rs_thread's virtual function 47 | virtual int on_thread_start() override final; 48 | virtual int on_before_loop() override final; 49 | virtual int loop() override final; 50 | virtual int on_end_loop() override final; 51 | virtual int on_thread_stop() override final; 52 | 53 | private: 54 | int socket_fd; 55 | st_netfd_t st_socket_fd; 56 | 57 | string ip_addr; 58 | int listen_port; 59 | 60 | char *recv_buffer; 61 | int buffer_size; 62 | IUdpHandler *udp_handler; 63 | }; 64 | 65 | } // namespace core 66 | } // namespace rs 67 | 68 | #endif /* CORE_UDP_LISTENER_H_ */ 69 | -------------------------------------------------------------------------------- /doc/rabbitstreamer_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenxiaoming/rabbitstreamer/6a8b11d8885485a5cd740bba2326ec5dbad1fea0/doc/rabbitstreamer_architecture.png -------------------------------------------------------------------------------- /doc/system_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenxiaoming/rabbitstreamer/6a8b11d8885485a5cd740bba2326ec5dbad1fea0/doc/system_architecture.png -------------------------------------------------------------------------------- /protocol/common/buffer_queue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "buffer_queue.h" 25 | #include "core/core_struct.h" 26 | #include "core/error_code.h" 27 | #include 28 | 29 | namespace rs { 30 | namespace protocol { 31 | 32 | RsBufferQueue::RsBufferQueue(const MD5_Hash_Str &hash, const string &name, 33 | bool source) 34 | : queue_index(0), dequeue_index(0), min_block_id(0), min_block_index(0), 35 | buffer_full_flag(false), buffer_number(0), source_hash(hash), 36 | source_name(name), is_source(source) { 37 | 38 | time(&create_time); 39 | } 40 | 41 | RsBufferQueue::~RsBufferQueue() {} 42 | 43 | void RsBufferQueue::reserve_buffer(int size) { 44 | buffer_number = size; 45 | for (int i = 0; i < buffer_number; i++) { 46 | media_buffer *buf = new media_buffer; 47 | buf->flag = BUFFER_AVAILABLE; 48 | buf->buffer = new char[MEDIA_BLOCK_SIZE]; 49 | buf->block_id = 0; 50 | buf->block_size = MEDIA_BLOCK_SIZE; 51 | buffer_vector.push_back(buf); 52 | } 53 | } 54 | 55 | RsBufferQueue::media_buffer *RsBufferQueue::queue_buffer() { 56 | media_buffer *buf = buffer_vector[queue_index]; 57 | buf->flag = BUFFER_WRITING; 58 | 59 | if (buffer_full_flag) { 60 | min_block_id++; 61 | min_block_index = 62 | (queue_index + 1) % (buffer_number); // the min block's index is the 63 | // next one of queue index 64 | } 65 | 66 | // printf("RsBufferQueue::queue_buffer() min_block_id:%d \n", min_block_id); 67 | return buf; 68 | } 69 | 70 | int RsBufferQueue::update_buffer_attr(int block_id, BUFFER_FLAG flag) { 71 | int ret = ERROR_SUCCESS; 72 | media_buffer *buf = buffer_vector[queue_index]; 73 | buf->block_id = block_id; 74 | buf->flag = flag; 75 | if (!buffer_full_flag && ((queue_index + 1) == buffer_number)) 76 | buffer_full_flag = true; 77 | 78 | queue_index = (queue_index + 1) % (buffer_number); 79 | return ret; 80 | } 81 | 82 | RsBufferQueue::media_buffer *RsBufferQueue::dequeue_buffer(int block_id) { 83 | int curr_buf_size = buffer_full_flag ? buffer_number : queue_index; 84 | if ((min_block_id > block_id) || 85 | (block_id >= (min_block_id + curr_buf_size))) { // TODO:confirm >= or > 86 | printf("block_id:%d min_block_id:%d curr_buf_size:%d \n", block_id, 87 | min_block_id, curr_buf_size); 88 | printf("RsBufferQueue::dequeue_buffer() return NULL \n"); 89 | return NULL; 90 | } else 91 | printf("RsBufferQueue::dequeue_buffer() block_id:%d min_block_id:%d \n", 92 | block_id, min_block_id); 93 | 94 | int offset = block_id - min_block_id; 95 | if (offset < (buffer_number - min_block_index)) 96 | return buffer_vector[min_block_index + offset]; 97 | else 98 | return buffer_vector[offset - ((buffer_number - min_block_index))]; 99 | } 100 | 101 | int RsBufferQueue::get_buffer_interval(int &start, int &end) { 102 | start = min_block_id; 103 | if (buffer_full_flag) 104 | end = start + buffer_number; 105 | else 106 | end = start + queue_index; 107 | return 0; 108 | } 109 | 110 | void RsBufferQueue::set_header(const char *header, int size) { 111 | media_header.media_type = new char[size]; // FIXME:where to release it? 112 | memcpy(media_header.media_type, header, size); 113 | media_header.header_size = size; 114 | } 115 | 116 | void RsBufferQueue::get_header(char *&header, int &size) { 117 | header = media_header.media_type; 118 | size = media_header.header_size; 119 | } 120 | 121 | } // namespace protocol 122 | } // namespace rs -------------------------------------------------------------------------------- /protocol/common/buffer_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef PROTOCOL_BUFFER_QUEUE_H_ 25 | #define PROTOCOL_BUFFER_QUEUE_H_ 26 | 27 | #include "core/core_struct.h" 28 | #include 29 | #include 30 | #include 31 | 32 | using namespace rs::core; 33 | 34 | namespace rs { 35 | namespace protocol { 36 | 37 | // RsBufferQueue is similar to android's gui's BufferQueue 38 | // it will use queue_buffer to get one free buffer for storing buffer from 39 | // capture server and the socket from NP will use dequeue_buffer to get one 40 | // media buffer for consuming in the player. currently sp or tracker runs within 41 | // one thread using st, no need to lock the resource in it 42 | class RsBufferQueue { 43 | public: 44 | enum BUFFER_FLAG : uint8_t { BUFFER_WRITING, BUFFER_READING, BUFFER_AVAILABLE }; 45 | 46 | struct media_buffer { 47 | BUFFER_FLAG flag; 48 | int block_id; 49 | int block_size; 50 | char *buffer; 51 | }; 52 | 53 | struct media_type_header { 54 | char *media_type; 55 | int header_size; 56 | }; 57 | 58 | public: 59 | RsBufferQueue(const MD5_Hash_Str &hash, const string &name, bool source); 60 | virtual ~RsBufferQueue(); 61 | 62 | public: 63 | void reserve_buffer(int size); 64 | media_buffer *queue_buffer(); 65 | media_buffer *dequeue_buffer(int block_id); 66 | int update_buffer_attr(int block_id, BUFFER_FLAG flag); 67 | 68 | public: 69 | int get_buffer_interval(int &start, int &end); 70 | MD5_Hash_Str get_source_hash() { return source_hash; } 71 | string get_source_name() { return source_name; } 72 | time_t get_create_time() { return create_time; } 73 | bool is_source_flag() { return is_source; } 74 | 75 | public: 76 | void set_header(const char *header, int size); 77 | void get_header(char *&header, int &size); 78 | 79 | private: 80 | // disable copy and assign 81 | RsBufferQueue(const RsBufferQueue &); 82 | RsBufferQueue &operator=(const RsBufferQueue &); 83 | 84 | private: 85 | media_type_header media_header; 86 | // the time when source is created 87 | time_t create_time; 88 | // hash code of this source 89 | MD5_Hash_Str source_hash; 90 | // name of this source 91 | string source_name; 92 | // it is source or cached 93 | bool is_source; 94 | 95 | private: 96 | int queue_index; 97 | int dequeue_index; 98 | int buffer_number; 99 | int min_block_id; // the min block id 100 | int min_block_index; // the min block's index in the queue 101 | bool buffer_full_flag; 102 | std::vector buffer_vector; 103 | }; 104 | 105 | } // namespace protocol 106 | } // namespace rs 107 | 108 | #endif /* PROTOCOL_BUFFER_QUEUE_H_ */ 109 | -------------------------------------------------------------------------------- /protocol/sp/sp_cs_connector.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef PROTOCOL_SP_CS_CONNECTOR_H_ 25 | #define PROTOCOL_SP_CS_CONNECTOR_H_ 26 | 27 | #include "core/bitrate_calculator.h" 28 | #include "core/buffer.h" 29 | #include "core/core_struct.h" 30 | #include "core/socket.h" 31 | #include "core/thread.h" 32 | 33 | using namespace rs::core; 34 | 35 | namespace rs { 36 | namespace protocol { 37 | namespace sp { 38 | 39 | class RsCsSpProtocol : public RsThread { 40 | public: 41 | explicit RsCsSpProtocol(st_netfd_t stfd); 42 | virtual ~RsCsSpProtocol(); 43 | 44 | protected: 45 | int get_msg(); 46 | int get_register(char *msg, int size); 47 | int get_update(char *msg, int size); 48 | int get_block(char *msg, int size); 49 | int get_mediatype(char *msg, int size); 50 | 51 | int send_welcome(); 52 | int send_err_msg(); 53 | 54 | public: 55 | // implement rs_thread's virtual function 56 | virtual int on_thread_start() override final; 57 | virtual int on_before_loop() override final; 58 | virtual int loop() override final; 59 | virtual int on_end_loop() override final; 60 | virtual int on_thread_stop() override final; 61 | 62 | private: 63 | template int get_as_type(char *buf, T &x) { 64 | int typesize = sizeof(T); 65 | memcpy((char *)&x, buf, typesize); 66 | return 0; 67 | } 68 | 69 | private: 70 | MD5_Hash_Str chnl_hash; 71 | st_netfd_t st_fd = nullptr; 72 | RsSocket *io_socket = nullptr; 73 | char *read_buffer = nullptr; 74 | int read_size = 0; 75 | RsBuffer *cs_buffer = nullptr; 76 | RsBitrateCalculator *calculator = nullptr; 77 | }; 78 | 79 | } // namespace sp 80 | } // namespace protocol 81 | } // namespace rs 82 | 83 | #endif /* PROTOCOL_SP_CS_PROTOCOL_H_ */ 84 | -------------------------------------------------------------------------------- /protocol/sp/sp_np_connector.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef PROTOCOL_SP_NP_CONNECTOR_H_ 25 | #define PROTOCOL_SP_NP_CONNECTOR_H_ 26 | 27 | #include "core/bitrate_calculator.h" 28 | #include "core/buffer.h" 29 | #include "core/p2p_protocol.h" 30 | #include "core/socket.h" 31 | #include "core/thread.h" 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace rs::core; 37 | 38 | namespace rs { 39 | namespace protocol { 40 | namespace sp { 41 | 42 | class RsNpSpProtocol : public RsThread { 43 | public: 44 | explicit RsNpSpProtocol(st_netfd_t stfd); 45 | virtual ~RsNpSpProtocol(); 46 | 47 | public: 48 | int get_push_list(char *msg, int size); 49 | int send_push_list(char *resource_hash, uint8_t count, uint32_t *array); 50 | int send_media_type(char *resource_hash); 51 | 52 | public: 53 | // implement rs_thread's virtual function 54 | virtual int on_thread_start() override final; 55 | virtual int on_before_loop() override final; 56 | virtual int loop() override final; 57 | virtual int on_end_loop() override final; 58 | virtual int on_thread_stop() override final; 59 | 60 | private: 61 | int send_one_block(char *resource_hash, uint8_t count, uint32_t id); 62 | 63 | private: 64 | st_netfd_t st_fd = nullptr; 65 | RsSocket *io_socket = nullptr; 66 | RsBuffer *np_buffer = nullptr; 67 | bool media_type_flag = false; 68 | RsBitrateCalculator *calculator = nullptr; 69 | }; 70 | 71 | } // namespace sp 72 | } // namespace protocol 73 | } // namespace rs 74 | 75 | #endif /* PROTOCOL_SP_NP_PROTOCOL_H_ */ 76 | -------------------------------------------------------------------------------- /protocol/sp/sp_source_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "sp_source_manager.h" 25 | #include "core/error_code.h" 26 | #include 27 | 28 | namespace rs { 29 | namespace protocol { 30 | namespace sp { 31 | 32 | RsSourceManager *RsSourceManager::p = new RsSourceManager; 33 | RsSourceManager *RsSourceManager::instance() { return p; } 34 | 35 | RsSourceManager::~RsSourceManager() {} 36 | 37 | RsBufferQueue *RsSourceManager::get_buffer_queue(MD5_Hash_Str hash) { 38 | map::iterator iter = 39 | source_hashmap.find(hash); 40 | if (iter == source_hashmap.end()) 41 | return NULL; 42 | 43 | return iter->second; 44 | } 45 | 46 | int RsSourceManager::write_source_channel_list_txt() { 47 | char temp[512]; 48 | string xml_store_path_ = "./"; 49 | sprintf(temp, ("%schannel.txt"), xml_store_path_.c_str()); 50 | FILE *txt_file = fopen(temp, "wt"); 51 | if (txt_file == NULL) { 52 | return -1; 53 | } 54 | 55 | map::iterator iter = source_hashmap.begin(); 56 | for (; iter != source_hashmap.end(); ++iter) { 57 | // add source channel to list 58 | if (iter->second->is_source_flag()) { 59 | sprintf( 60 | temp, 61 | ("Name: %s\r\nURL: myseelitetest://%s/%s/%s\r\nStart: %d\r\n"), 62 | iter->second->get_source_name().c_str(), 63 | tracker_address.c_str(), iter->second->get_source_hash().hash_, 64 | iter->second->get_source_name().c_str(), 65 | iter->second->get_create_time()); 66 | if (fwrite(temp, 1, strlen(temp), txt_file) != strlen(temp)) { 67 | fclose(txt_file); 68 | return -1; 69 | } 70 | } 71 | } 72 | 73 | fclose(txt_file); 74 | return 0; 75 | } 76 | 77 | int RsSourceManager::initialize(const string &data_store_path, 78 | const string &xml_store_path, 79 | const string &tracker_addr) { 80 | int ret = ERROR_SUCCESS; 81 | tracker_address = tracker_addr; 82 | return ret; 83 | } 84 | 85 | int RsSourceManager::create_source(const MD5_Hash_Str &source_hash, 86 | const string &source_name, bool source) { 87 | int ret = ERROR_SUCCESS; 88 | 89 | RsBufferQueue *buffer_queue = get_buffer_queue(source_hash); 90 | if (buffer_queue) { 91 | } else { 92 | buffer_queue = new RsBufferQueue(source_hash, source_name, source); 93 | if (buffer_queue) { 94 | buffer_queue->reserve_buffer(MAX_BUFFER_SIZE); 95 | } 96 | 97 | bool ret = source_hashmap 98 | .insert(std::pair( 99 | source_hash, buffer_queue)) 100 | .second; 101 | if (!ret) { 102 | delete buffer_queue; 103 | return ERROR_SOURCE_MGR_FAILT_TO_CREATE_SOURCE; 104 | } 105 | } 106 | return ret; 107 | } 108 | 109 | int RsSourceManager::queue_block(const MD5_Hash_Str &chnl_hash, char **block, 110 | int size) { 111 | int ret = ERROR_SUCCESS; 112 | 113 | RsBufferQueue *buffer_queue = get_buffer_queue(chnl_hash); 114 | if (!buffer_queue) { 115 | return ERROR_SOURCE_MGR_NOT_FOUND; 116 | } 117 | 118 | RsBufferQueue::media_buffer *buf = buffer_queue->queue_buffer(); 119 | *block = buf->buffer; 120 | return ret; 121 | } 122 | 123 | int RsSourceManager::dequeue_block(const MD5_Hash_Str &chnl_hash, int block_id, 124 | char *&block, uint32_t &block_size, 125 | bool ¬found) { 126 | int ret = ERROR_SUCCESS; 127 | 128 | RsBufferQueue *buffer_queue = get_buffer_queue(chnl_hash); 129 | if (!buffer_queue) { 130 | return ERROR_SOURCE_MGR_NOT_FOUND; 131 | } 132 | 133 | RsBufferQueue::media_buffer *buf = buffer_queue->dequeue_buffer(block_id); 134 | if (buf) { 135 | block = buf->buffer; 136 | block_size = buf->block_size; 137 | notfound = false; 138 | } else 139 | notfound = true; 140 | 141 | return ret; 142 | } 143 | 144 | int RsSourceManager::set_block_available(const MD5_Hash_Str &chnl_hash, 145 | int block_id) { 146 | int ret = ERROR_SUCCESS; 147 | 148 | RsBufferQueue *buffer_queue = get_buffer_queue(chnl_hash); 149 | if (!buffer_queue) { 150 | return ERROR_SOURCE_MGR_NOT_FOUND; 151 | } 152 | buffer_queue->update_buffer_attr(block_id, RsBufferQueue::BUFFER_AVAILABLE); 153 | return ret; 154 | } 155 | 156 | void RsSourceManager::get_source_list(list &source_list) { 157 | map::iterator iter = source_hashmap.begin(); 158 | source_status state; 159 | for (; iter != source_hashmap.end(); iter++) { 160 | int start = 0; 161 | int end = 0; 162 | state.chnl_hash = iter->second->get_source_hash(); 163 | state.chnl_name_ = iter->second->get_source_name(); 164 | state.created_time_ = iter->second->get_create_time(); 165 | iter->second->get_buffer_interval(start, end); 166 | // printf("start:%d end:%d\n", start, end); 167 | state.block_inter_.start = start; 168 | state.block_inter_.size = (end - start); 169 | source_list.insert(source_list.end(), state); 170 | } 171 | } 172 | 173 | // save media header 174 | int RsSourceManager::add_header(const MD5_Hash_Str &chnl_hash, 175 | const char *header, int size) { 176 | int ret = ERROR_SUCCESS; 177 | RsBufferQueue *buffer_queue = get_buffer_queue(chnl_hash); 178 | if (!buffer_queue) { 179 | return ERROR_SOURCE_MGR_NOT_FOUND; 180 | } 181 | buffer_queue->set_header(header, size); 182 | return ret; 183 | } 184 | 185 | // get media header 186 | int RsSourceManager::get_header(const MD5_Hash_Str &chnl_hash, char *&header, 187 | int &size) { 188 | int ret = ERROR_SUCCESS; 189 | RsBufferQueue *buffer_queue = get_buffer_queue(chnl_hash); 190 | if (!buffer_queue) { 191 | return ERROR_SOURCE_MGR_NOT_FOUND; 192 | } 193 | buffer_queue->get_header(header, size); 194 | return ret; 195 | } 196 | 197 | } // namespace sp 198 | } // namespace protocol 199 | } // namespace rs 200 | -------------------------------------------------------------------------------- /protocol/sp/sp_source_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef PROTOCOL_SP_SOURCE_MANAGER_H_ 24 | #define PROTOCOL_SP_SOURCE_MANAGER_H_ 25 | 26 | #include "core/core_struct.h" 27 | #include "protocol/common/buffer_queue.h" 28 | #include 29 | #include 30 | 31 | using namespace rs::core; 32 | 33 | namespace rs { 34 | namespace protocol { 35 | namespace sp { 36 | 37 | // manage the source from capture server, it is single instance 38 | class RsSourceManager { 39 | public: 40 | struct source_status { 41 | // hash of channel 42 | MD5_Hash_Str chnl_hash; 43 | string program_name; 44 | uint32_t program_time; 45 | // Channel Name 46 | string chnl_name_; 47 | // Channel created time 48 | time_t created_time_; 49 | // block interval of channel 50 | BlockInterval block_inter_; 51 | }; 52 | 53 | private: 54 | RsSourceManager() {} 55 | static RsSourceManager *p; 56 | 57 | public: 58 | virtual ~RsSourceManager(); 59 | 60 | public: 61 | // for single instance 62 | static RsSourceManager *instance(); 63 | 64 | public: 65 | void reserve_buffer(MD5_Hash_Str hash, int size); 66 | void queue_buffer(MD5_Hash_Str hash); 67 | void dequeue_buffer(MD5_Hash_Str hash); 68 | 69 | public: 70 | // add a new channel 71 | int create_source(const MD5_Hash_Str &source_hash, 72 | const string &source_name, bool source); 73 | // save a block into queue 74 | int queue_block(const MD5_Hash_Str &chnl_hash, char **block, int size); 75 | // get a block from queue 76 | int dequeue_block(const MD5_Hash_Str &chnl_hash, int block_id, char *&block, 77 | uint32_t &block_size, bool ¬found); 78 | 79 | // update buffer's flag 80 | int set_block_available(const MD5_Hash_Str &chnl_hash, int block_id); 81 | // get source channel list 82 | void get_source_list(list &source_list); 83 | // save media header 84 | int add_header(const MD5_Hash_Str &chnl_hash, const char *header, int size); 85 | // get media header 86 | int get_header(const MD5_Hash_Str &chnl_hash, char *&header, int &size); 87 | 88 | int write_source_channel_list_txt(); 89 | // not implemented 90 | //////////////////////////////////////////// 91 | int initialize(const string &data_store_path, const string &xml_store_path, 92 | const string &tracker_addr); 93 | 94 | // check the status of channel 95 | void check_channel(); 96 | 97 | bool find_channel_is_source(const MD5_Hash_Str &chnl_hash); 98 | 99 | // set this channel as deactivated 100 | int deactivate_channel(const MD5_Hash_Str &chnl_hash); 101 | 102 | // check if this channel exists 103 | bool find_channel(const MD5_Hash_Str &chnl_hash) { 104 | return get_buffer_queue(chnl_hash) != NULL; 105 | } 106 | 107 | int get_max_blockid(const MD5_Hash_Str &chnl_hash, int &block_id); 108 | 109 | private: 110 | RsBufferQueue *get_buffer_queue(MD5_Hash_Str hash); 111 | 112 | private: 113 | std::map source_hashmap; 114 | string tracker_address; 115 | }; 116 | 117 | } // namespace sp 118 | } // namespace protocol 119 | } // namespace rs 120 | 121 | #endif /* PROTOCOL_SP_SOURCE_MANAGER_H_ */ 122 | -------------------------------------------------------------------------------- /protocol/sp/sp_tracker_connector.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "sp_tracker_connector.h" 24 | #include "core/error_code.h" 25 | #include "core/message.h" 26 | #include "core/p2p_protocol.h" 27 | #include "core/socket_connect.h" 28 | #include "sp_source_manager.h" 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace rs { 39 | namespace protocol { 40 | namespace sp { 41 | 42 | #define TRACKER_UDP_CONNECT_TIMEOUT_US (int64_t)(1 * 1000 * 1000LL) 43 | 44 | #define UDP_MAX_PACKET_SIZE 65535 45 | 46 | #define UDP_PACKET_RECV_CYCLE_INTERVAL_MS 0 47 | 48 | #define TRACKER_TIMEOUT 1000 // timeout is 1s 49 | #define TRACKER_GET_SP_LIST_TIMEOUT 50 * 1000 // timeout is 50s 50 | 51 | #define TRACKER_TIMER_ID 0 52 | #define TRACKER_GET_SP_LIST_TIMER_ID 1 53 | 54 | using source_status = RsSourceManager::source_status; 55 | 56 | RsSpTrackerProtocol::RsSpTrackerProtocol(string ip, int port) 57 | : RsThread("trackerprotocol"), ip_address(ip), ip_port(port) { 58 | sp_port = 2222; // hard code the port for np to access sp through tcp 59 | buf_size = UDP_MAX_PACKET_SIZE; 60 | recv_buf = new char[UDP_MAX_PACKET_SIZE]; 61 | register_flag = false; 62 | register_retry = 0; 63 | 64 | cycle_interval_us = 120 * 1000; // sleep 120ms 65 | } 66 | 67 | RsSpTrackerProtocol::~RsSpTrackerProtocol() { 68 | if (io) 69 | delete io; 70 | 71 | if (recv_buf) 72 | delete[] recv_buf; 73 | } 74 | 75 | int RsSpTrackerProtocol::start_connect() { 76 | int ret = ERROR_SUCCESS; 77 | // open socket. 78 | int64_t timeout = TRACKER_UDP_CONNECT_TIMEOUT_US; 79 | // register two timers 80 | RsTimer::instance()->add_timer(TRACKER_TIMEOUT, TRACKER_TIMER_ID, this); 81 | RsTimer::instance()->add_timer(TRACKER_GET_SP_LIST_TIMEOUT, 82 | TRACKER_GET_SP_LIST_TIMER_ID, this); 83 | 84 | bool is_tcp = false; 85 | 86 | ret = socket_connect(is_tcp, ip_address, ip_port, 87 | TRACKER_UDP_CONNECT_TIMEOUT_US, &tracker_udp_fd); 88 | 89 | if (ERROR_SUCCESS == ret) { 90 | io = new RsSocket(tracker_udp_fd); 91 | start_thread(); 92 | } 93 | 94 | return ret; 95 | } 96 | 97 | int RsSpTrackerProtocol::on_end_loop() { 98 | int ret = ERROR_SUCCESS; 99 | 100 | return ret; 101 | } 102 | 103 | int RsSpTrackerProtocol::on_thread_stop() { 104 | int ret = ERROR_SUCCESS; 105 | 106 | return ret; 107 | } 108 | 109 | int RsSpTrackerProtocol::on_thread_start() { 110 | int ret = ERROR_SUCCESS; 111 | 112 | return ret; 113 | } 114 | 115 | int RsSpTrackerProtocol::on_before_loop() { 116 | int ret = ERROR_SUCCESS; 117 | 118 | return ret; 119 | } 120 | 121 | int RsSpTrackerProtocol::send_register() { 122 | printf("%s\n", __FUNCTION__); 123 | int ret = ERROR_SUCCESS; 124 | Sp2TsRegister register_msg; 125 | register_msg.service_port = sp_port; 126 | char *payload = NULL; 127 | int payload_nb = 0; 128 | // RsMessage* msg = register_msg; 129 | register_msg.pack(payload, payload_nb); 130 | ssize_t nsize; 131 | if ((payload != NULL) && (payload_nb != 0)) 132 | io->write(payload, payload_nb, &nsize); 133 | st_usleep(1000); // release CPU cycle to others 134 | return ret; 135 | } 136 | 137 | int RsSpTrackerProtocol::send_res_list() { 138 | int ret = ERROR_SUCCESS; 139 | list source_list; 140 | RsSourceManager::instance()->get_source_list(source_list); 141 | Sp2TsResList res_list; 142 | memcpy(res_list.sp_uuid, sp_id, UUID_LENGTH); 143 | res_list.resource_count = source_list.size(); 144 | 145 | if (!res_list.resource_count) 146 | return ret; 147 | 148 | // printf("%s\n", __FUNCTION__); 149 | int index = 0; 150 | res_list.res_info = new resource_info[res_list.resource_count]; 151 | // update res list for each source 152 | list::iterator iter = source_list.begin(); 153 | for (; iter != source_list.end(); iter++) { 154 | memcpy(res_list.res_info[index].res_md5, iter->chnl_hash.hash_, 155 | MD5_LEN); 156 | res_list.res_info[index].block_interval = iter->block_inter_; 157 | index++; 158 | } 159 | 160 | char *payload = NULL; 161 | int payload_nb = 0; 162 | res_list.pack(payload, payload_nb); 163 | ssize_t nsize; 164 | if ((payload != NULL) && (payload_nb != 0)) 165 | io->write(payload, payload_nb, &nsize); 166 | 167 | return ret; 168 | } 169 | 170 | int RsSpTrackerProtocol::send_sp_list() { 171 | // printf("%s\n", __FUNCTION__); 172 | int ret = ERROR_SUCCESS; 173 | Sp2TsSpList sp_list; 174 | memcpy(sp_list.sp_uuid, sp_id, UUID_LENGTH); 175 | char *payload = NULL; 176 | int payload_nb = 0; 177 | sp_list.pack(payload, payload_nb); 178 | ssize_t nsize; 179 | if ((payload != NULL) && (payload_nb != 0)) 180 | io->write(payload, payload_nb, &nsize); 181 | return ret; 182 | } 183 | 184 | int RsSpTrackerProtocol::get_welcome(char *msg, int size) { 185 | printf("%s\n", __FUNCTION__); 186 | int ret = ERROR_SUCCESS; 187 | Ts2SpWelcome welcome_msg; 188 | RsStreamer streamer; 189 | streamer.initialize(msg, size); 190 | welcome_msg.parse(&streamer); 191 | memcpy(sp_id, welcome_msg.sp_uuid, UUID_LENGTH); 192 | register_flag = true; 193 | return ret; 194 | } 195 | 196 | int RsSpTrackerProtocol::get_sp_list(char *msg, int size) { 197 | int ret = ERROR_SUCCESS; 198 | printf("%s\n", __FUNCTION__); 199 | return ret; 200 | } 201 | 202 | int RsSpTrackerProtocol::get_res_interval(char *msg, int size) { 203 | int ret = ERROR_SUCCESS; 204 | // printf("%s\n", __FUNCTION__); 205 | if (register_flag) 206 | send_res_list(); 207 | else 208 | send_register(); 209 | return ret; 210 | } 211 | 212 | int RsSpTrackerProtocol::loop() { 213 | int ret = ERROR_SUCCESS; 214 | 215 | sockaddr_in from; 216 | int from_len = sizeof(sockaddr_in); 217 | int read_size = 0; 218 | 219 | if ((read_size = 220 | st_recvfrom(tracker_udp_fd, recv_buf, buf_size, (sockaddr *)&from, 221 | &from_len, ST_UTIME_NO_TIMEOUT)) <= 0) { 222 | return ret; 223 | } 224 | 225 | // get message size 226 | char *temp = recv_buf; 227 | int msg_size = 0; 228 | memcpy((char *)&msg_size, recv_buf, 4); 229 | recv_buf += 4; 230 | 231 | // get the message type 232 | char msg_type = 0; 233 | msg_type = *recv_buf; 234 | recv_buf += 1; 235 | 236 | switch (msg_type) { 237 | case TS2SP_WELCOME: 238 | get_welcome(temp + 5, msg_size - 5); 239 | break; 240 | case TS2SP_SP_LIST: 241 | get_sp_list(temp + 5, msg_size - 5); 242 | break; 243 | case TS2SP_GET_RES_LIST: 244 | get_res_interval(temp + 5, msg_size - 5); 245 | break; 246 | } 247 | 248 | if (UDP_PACKET_RECV_CYCLE_INTERVAL_MS > 0) { 249 | st_usleep(UDP_PACKET_RECV_CYCLE_INTERVAL_MS * 1000); 250 | } 251 | return ret; 252 | } 253 | 254 | int RsSpTrackerProtocol::handle_timeout(int64_t timerid) { 255 | int ret = ERROR_SUCCESS; 256 | 257 | if (!register_flag) // send register info if not register 258 | return send_register(); 259 | 260 | switch (timerid) { 261 | case TRACKER_TIMER_ID: 262 | send_res_list(); 263 | break; 264 | case TRACKER_GET_SP_LIST_TIMER_ID: 265 | send_sp_list(); 266 | break; 267 | } 268 | return ret; 269 | } 270 | 271 | } // namespace sp 272 | } // namespace protocol 273 | } // namespace rs 274 | -------------------------------------------------------------------------------- /protocol/sp/sp_tracker_connector.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef PROTOCOL_SP_TRACKER_PROTOCOL_H_ 25 | #define PROTOCOL_SP_TRACKER_PROTOCOL_H_ 26 | 27 | #include "core/core_struct.h" 28 | #include "core/system_time.h" 29 | #include "core/socket.h" 30 | #include "core/thread.h" 31 | #include "core/timer.h" 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace std; 37 | 38 | using namespace rs::core; 39 | 40 | namespace rs { 41 | namespace protocol { 42 | namespace sp { 43 | 44 | class RsSpTrackerProtocol : public RsThread, public virtual ITimerHandler { 45 | public: 46 | RsSpTrackerProtocol(string ip, int port); 47 | virtual ~RsSpTrackerProtocol(); 48 | 49 | public: 50 | int start_connect(); 51 | 52 | public: 53 | // implement rs_thread's virtual function 54 | virtual int on_thread_start() override final; 55 | virtual int on_before_loop() override final; 56 | virtual int loop() override final; 57 | virtual int on_end_loop() override final; 58 | virtual int on_thread_stop() override final; 59 | 60 | public: 61 | // implement ITimerHandler 62 | virtual int handle_timeout(int64_t timerid) override final; 63 | 64 | private: 65 | char *recv_buf = nullptr; 66 | int buf_size; 67 | bool register_flag; 68 | int register_retry; 69 | 70 | private: 71 | int64_t last_thread_time; 72 | 73 | private: 74 | string ip_address; 75 | int ip_port; 76 | st_netfd_t tracker_udp_fd; 77 | RsSocket *io = nullptr; 78 | 79 | protected: 80 | int get_welcome(char *msg, int size); 81 | int get_sp_list(char *msg, int size); 82 | int get_res_interval(char *msg, int size); 83 | 84 | int send_register(); 85 | int send_res_list(); 86 | int send_sp_list(); 87 | int send_status(); 88 | int send_logout(); 89 | 90 | // uuid of super peer on tracker 91 | char sp_id[UUID_LENGTH]; 92 | // received welcome 93 | bool login_done; 94 | // sp port 95 | uint16_t sp_port; 96 | }; 97 | 98 | } // namespace sp 99 | } // namespace protocol 100 | } // namespace rs 101 | 102 | #endif /* PROTOCOL_SP_TRACKER_PROTOCOL_H_ */ 103 | -------------------------------------------------------------------------------- /protocol/tracker/tracker_np_connector.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef PROTOCOL_TRACKER_NP_PROTOCOL_H_ 24 | #define PROTOCOL_TRACKER_NP_PROTOCOL_H_ 25 | 26 | #include "core/core_struct.h" 27 | #include "core/system_time.h" 28 | #include "core/socket.h" 29 | #include "core/struct_define.h" 30 | #include "core/thread.h" 31 | #include "core/timer.h" 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace std; 37 | 38 | using namespace rs::core; 39 | 40 | // class map_str; 41 | 42 | namespace rs { 43 | namespace protocol { 44 | namespace tracker { 45 | 46 | // handle communication between tracker and np 47 | class RsNpTracker : public RsThread, public virtual ITimerHandler { 48 | public: 49 | RsNpTracker(); 50 | virtual ~RsNpTracker(); 51 | 52 | public: 53 | // implement rs_thread's virtual function 54 | virtual int on_thread_start() override final; 55 | virtual int on_before_loop() override final; 56 | virtual int loop() override final; 57 | virtual int on_end_loop() override final; 58 | virtual int on_thread_stop() override final; 59 | 60 | private: 61 | void generate_uuid(map_str &digits); 62 | int send_buffer(char *buf, int size); 63 | 64 | public: 65 | // implement ITimerHandler 66 | virtual int handle_timeout(int64_t timerid) override final; 67 | 68 | public: 69 | int handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, char *buf, 70 | int nb_buf); 71 | 72 | private: 73 | char *recv_buf; 74 | int buf_size; 75 | bool register_flag; 76 | int register_retry; 77 | 78 | private: 79 | int64_t last_thread_time; 80 | 81 | private: 82 | // string ip_address; 83 | // int ip_port; 84 | st_netfd_t sp_fd; 85 | RsSocket *io; 86 | sockaddr_in last_receive_addr; 87 | 88 | private: 89 | int get_login(char *msg, int size); 90 | int get_req_res(char *msg, int size); 91 | int get_report(char *msg, int size); 92 | int get_need_peers(char *msg, int size); 93 | int get_logout(char *msg, int size); 94 | int get_res_interval(char *msg, int size); 95 | 96 | int send_peers(map_str uuid, MD5_Hash_Str resHash, 97 | uint32_t currentblockID = 0); 98 | int send_welcome(map_str digits, P2PAddress p2pAddr); 99 | int send_res_interval(MD5_Hash_Str channel_hash); 100 | void send_msg(); 101 | 102 | private: 103 | BlockInterval last_send_blockinterval; 104 | }; 105 | 106 | } // namespace tracker 107 | } // namespace protocol 108 | } // namespace rs 109 | #endif 110 | -------------------------------------------------------------------------------- /protocol/tracker/tracker_np_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "tracker_np_manager.h" 24 | #include "core/logger.h" 25 | #include "md5.h" 26 | #include 27 | 28 | using namespace std; 29 | 30 | namespace rs { 31 | namespace protocol { 32 | namespace tracker { 33 | 34 | RsTrackerNpCoordinator *RsTrackerNpCoordinator::p = 35 | new RsTrackerNpCoordinator(); 36 | RsTrackerNpCoordinator *RsTrackerNpCoordinator::instance() { return p; } 37 | 38 | RsTrackerNpCoordinator::RsTrackerNpCoordinator() { npnode_map.clear(); } 39 | 40 | RsTrackerNpCoordinator::~RsTrackerNpCoordinator() { 41 | for (const auto &val : npnode_map) { 42 | NPNode *temp = val.second; 43 | delete temp; 44 | } 45 | // 46 | npnode_map.clear(); 47 | } 48 | 49 | int RsTrackerNpCoordinator::timer_check() { 50 | for (CMIt it = npnode_map.begin(); it != npnode_map.end();) { 51 | CMIt i = it; 52 | it++; 53 | time_t curr_time; 54 | // delete the NPNode if it idles too long 55 | time(&curr_time); 56 | if ((curr_time - (i->second->last_recv_report_time_)) > 57 | MaxIdleTime::MAX_IDLE_TIME_SEC) { 58 | RSLOGE("NPNode removed due to long time idle.\n"); 59 | 60 | // delete this NPNode 61 | NPNode *temp = i->second; 62 | delete temp; 63 | 64 | npnode_map.erase(i); 65 | } 66 | } 67 | 68 | return 0; 69 | } 70 | 71 | int RsTrackerNpCoordinator::insert_Node(map_str digits, NPNode *node) { 72 | NPNode *pNode = get_Node(digits); 73 | if (NULL == pNode) { 74 | // create a new channel 75 | RSLOGE("creating new NPNode(%s)\n", digits.str_); 76 | 77 | try { 78 | pNode = new NPNode(); 79 | if (!pNode) { 80 | RSLOGE("node = new NPNode(); error | new_Node.\n"); 81 | return 0; 82 | } 83 | 84 | *pNode = *node; 85 | 86 | bool ret = 87 | npnode_map.insert(std::pair(digits, pNode)) 88 | .second; 89 | if (!ret) { 90 | RSLOGE("npnode_map.insert error | new_Node.\n"); 91 | delete pNode; 92 | pNode = NULL; 93 | return 0; 94 | } 95 | } catch (...) { 96 | RSLOGE("new NPNode Exception error | new_Node.\n"); 97 | pNode = NULL; 98 | } 99 | } else { 100 | *pNode = *node; 101 | } 102 | // 103 | return 0; 104 | } 105 | 106 | int RsTrackerNpCoordinator::deleteNode(map_str digits) { 107 | CMIt it = npnode_map.find(digits); 108 | // 109 | if (it != npnode_map.end()) { 110 | delete (it->second); 111 | 112 | npnode_map.erase(it); 113 | } 114 | // 115 | return 0; 116 | } 117 | 118 | int RsTrackerNpCoordinator::get_Node(map_str digits, NPNode *node) { 119 | CCMIt it = npnode_map.find(digits); 120 | if (it == npnode_map.end()) { 121 | return -1; 122 | } 123 | // 124 | *node = *(it->second); 125 | return 0; 126 | } 127 | 128 | NPNode *RsTrackerNpCoordinator::get_Node(map_str digits) { 129 | CCMIt it = npnode_map.find(digits); 130 | if (it == npnode_map.end()) { 131 | return NULL; 132 | } 133 | // 134 | return it->second; 135 | } 136 | 137 | // get the node peers's address, then we can connect with these peers to get media block 138 | int RsTrackerNpCoordinator::get_np_address(MD5_Hash_Str resHash, map_str uuid, 139 | PeerInfoWithAddr *&pPeerInfoWithAddr, 140 | int inCount, 141 | uint32_t currentblockID) { 142 | 143 | // todo, no need to allocate memory every time 144 | pPeerInfoWithAddr = new PeerInfoWithAddr[inCount]; 145 | 146 | vector groupID; 147 | 148 | // split the npnode_map into groups, one group has 30 nodes 149 | int iSize = npnode_map.size(); 150 | int iRange = iSize / 30 + 1; 151 | 152 | // store the group id in groupID 153 | for (int i = 0; i < iRange; i++) { 154 | groupID.push_back(i); 155 | } 156 | 157 | int r1 = rand(); 158 | 159 | int index = 0; 160 | do { 161 | int iPos = 0; 162 | 163 | // find the group id 164 | for (int f = 0; f < iRange; f++) { 165 | int r1 = rand(); 166 | if (r1 != 0) { 167 | int id = r1 % iRange; 168 | iPos = groupID[id]; 169 | groupID[id] = -1; 170 | } 171 | 172 | // we have tried this group before 173 | if (-1 == iPos) 174 | continue; 175 | } 176 | 177 | // we have tried all groups, just exits the loop 178 | if (-1 == iPos) 179 | break; 180 | 181 | // seek to the specific group by its group id iPos 182 | CCMIt it = npnode_map.begin(); 183 | for (int m = 0; m < iPos * 30; m++) { 184 | it++; 185 | } 186 | 187 | for (int iLimit = 0; it != npnode_map.end(); it++) { 188 | if (30 <= iLimit) { // try 30 times at most 189 | break; 190 | } 191 | 192 | // we have got enough nodes 193 | if (index >= inCount) { 194 | break; 195 | } 196 | 197 | if (it->second->channelID_md5 == resHash // same channel 198 | && it->second->digits != uuid // not himself 199 | && it->second->intervalArray.FindBlock( 200 | currentblockID)) { // the node has the block whose id is currentblockID 201 | *(CorePeerInfo *)&pPeerInfoWithAddr[index] = 202 | it->second->coreInfo; 203 | *(P2PAddress *)&pPeerInfoWithAddr[index] = 204 | it->second->clientAddress; 205 | index++; 206 | } 207 | } 208 | 209 | if (it != npnode_map.end()) 210 | break; 211 | if (index >= inCount) { 212 | break; 213 | } 214 | 215 | } while (true); 216 | 217 | return index; 218 | } 219 | 220 | } // namespace tracker 221 | } // namespace protocol 222 | } // namespace rs -------------------------------------------------------------------------------- /protocol/tracker/tracker_np_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef PROTOCOL_TRACKER_NP_MANAGER_ 24 | #define PROTOCOL_TRACKER_NP_MANAGER_ 25 | 26 | #include "core/struct_define.h" 27 | #include 28 | 29 | using namespace rs::core; 30 | 31 | namespace rs { 32 | namespace protocol { 33 | namespace tracker { 34 | 35 | // manager of all channels 36 | class RsTrackerNpCoordinator { 37 | private: 38 | RsTrackerNpCoordinator(); 39 | static RsTrackerNpCoordinator *p; 40 | 41 | public: 42 | virtual ~RsTrackerNpCoordinator(); 43 | 44 | public: 45 | // for single instance 46 | static RsTrackerNpCoordinator *instance(); 47 | 48 | int timer_check(); 49 | // add a new channel 50 | int insert_Node(map_str digits, NPNode *node); 51 | // delete this node 52 | int deleteNode(map_str digits); 53 | 54 | // find a channel 55 | int get_Node(map_str digits, NPNode *node); 56 | 57 | // find sp address 58 | int get_np_address(MD5_Hash_Str resHash, map_str uuid, 59 | PeerInfoWithAddr *&pPeerInfoWithAddr, int inCount, 60 | uint32_t currentblockID); 61 | 62 | protected: 63 | NPNode *get_Node(map_str digits); 64 | 65 | private: 66 | using HashMap = std::map; 67 | using CMIt = std::map::iterator; 68 | using CCMIt = std::map::const_iterator; 69 | using CMPair = std::pair; 70 | 71 | HashMap npnode_map; 72 | 73 | enum MaxIdleTime : uint16_t { 74 | // if a live channel stopped receiving block from cs for more than 75 | // MAX_IDLE_TIME_SEC, it will be deleted 76 | MAX_IDLE_TIME_SEC = 600, 77 | }; 78 | }; 79 | 80 | } // namespace tracker 81 | } // namespace protocol 82 | } // namespace rs 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /protocol/tracker/tracker_sp_connector.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef PROTOCOL_TRACKER_SP_PROTOCOL_H_ 24 | #define PROTOCOL_TRACKER_SP_PROTOCOL_H_ 25 | 26 | #include "core/core_struct.h" 27 | #include "core/system_time.h" 28 | #include "core/socket.h" 29 | #include "core/struct_define.h" 30 | #include "core/thread.h" 31 | #include "core/timer.h" 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace std; 37 | 38 | using namespace rs::core; 39 | 40 | namespace rs { 41 | namespace protocol { 42 | namespace tracker { 43 | 44 | // handle communication between tracker and sp 45 | class RsSpTracker : public RsThread, public virtual ITimerHandler { 46 | public: 47 | RsSpTracker(); 48 | virtual ~RsSpTracker(); 49 | 50 | public: 51 | // implement rs_thread's virtual function 52 | virtual int on_thread_start() override final; 53 | virtual int on_before_loop() override final; 54 | virtual int loop() override final; 55 | virtual int on_end_loop() override final; 56 | virtual int on_thread_stop() override final; 57 | 58 | private: 59 | void generate_uuid(map_str &digits); 60 | int send_buffer(char *buf, int size); 61 | 62 | public: 63 | // implement ITimerHandler 64 | virtual int handle_timeout(int64_t timerid) override final; 65 | 66 | public: 67 | int handle_udp_packet(st_netfd_t st_fd, sockaddr_in *from, char *buf, 68 | int nb_buf); 69 | 70 | private: 71 | char *recv_buf; 72 | int buf_size; 73 | bool register_flag; 74 | int register_retry; 75 | 76 | private: 77 | int64_t last_thread_time; 78 | 79 | private: 80 | // string ip_address; 81 | // int ip_port; 82 | st_netfd_t sp_fd; 83 | RsSocket *io; 84 | sockaddr_in last_receive_addr; 85 | 86 | protected: 87 | int send_welcome(map_str uuid); 88 | int send_sp_list(map_str uuid); 89 | int send_errormsg(); 90 | int send_res_interval(); 91 | 92 | // handle message from sp to tracker 93 | int get_register(char *msg, int size); 94 | int get_res_list(char *msg, int size); 95 | int get_sp_list(char *msg, int size); 96 | int get_status(char *msg, int size); 97 | int get_logout(char *msg, int size); 98 | // uuid of super peer on tracker 99 | char sp_id[UUID_LENGTH]; 100 | // recved welcome 101 | bool login_done; 102 | }; 103 | 104 | } // namespace tracker 105 | } // namespace protocol 106 | } // namespace rs 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /protocol/tracker/tracker_streamer_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "tracker_streamer_manager.h" 24 | #include "core/logger.h" 25 | #include "third_party/md5/md5.h" 26 | #include "tracker_sp_connector.h" 27 | #include 28 | 29 | namespace rs { 30 | namespace protocol { 31 | namespace tracker { 32 | 33 | RsTrackerStreamManager *RsTrackerStreamManager::p = new RsTrackerStreamManager; 34 | RsTrackerStreamManager *RsTrackerStreamManager::instance() { return p; } 35 | 36 | RsTrackerStreamManager::RsTrackerStreamManager() { channel_map.clear(); } 37 | RsTrackerStreamManager::~RsTrackerStreamManager() { 38 | for (const auto &val : channel_map) { 39 | ChannelNode *temp = val.second; 40 | delete temp; 41 | } 42 | channel_map.clear(); 43 | } 44 | 45 | int RsTrackerStreamManager::initialize(const string &block_data_store_path) { 46 | return 0; 47 | } 48 | 49 | int RsTrackerStreamManager::timer_check() { 50 | for (CMIt it = channel_map.begin(); it != channel_map.end();) { 51 | CMIt i = it; 52 | it++; 53 | time_t curr_time; 54 | time(&curr_time); 55 | // delete the channel if it idles too long 56 | if ((curr_time - i->second->last_recv_report_time_) > 57 | MaxIdleTime::MAX_IDLE_TIME_SEC) { 58 | RSLOGE("Channel removed due to long time idle.\n"); 59 | 60 | // delete this channel 61 | ChannelNode *temp = i->second; 62 | delete temp; 63 | channel_map.erase(i); 64 | } 65 | } 66 | return 0; 67 | } 68 | 69 | int RsTrackerStreamManager::signal_get_res_interval(MD5_Hash_Str Channel_hash) { 70 | for (const auto &val : channel_map) { 71 | for (int i = 0; i < val.second->resourceCount; i++) { 72 | if (val.second->pHash[i] == Channel_hash) { 73 | RsSpTracker *sp = 74 | static_cast(val.second->spService); 75 | if (sp) { 76 | // sp->send_TS2SP_GET_RES_LIST(); //Kevin.Wen,fixme 77 | return 0; 78 | } 79 | } 80 | } 81 | } 82 | 83 | return 1; 84 | } 85 | 86 | int RsTrackerStreamManager::get_channel_interval(MD5_Hash_Str Channel_hash, 87 | BlockInterval &blockInterval) { 88 | for (const auto &val : channel_map) { 89 | for (int i = 0; i < val.second->resourceCount; i++) { 90 | if (val.second->pHash[i] == Channel_hash) { 91 | blockInterval = val.second->pHash[i].blockInterval; 92 | return 0; 93 | } 94 | } 95 | } 96 | 97 | return 1; 98 | } 99 | 100 | int RsTrackerStreamManager::get_channel_count() { return channel_map.size(); } 101 | 102 | int RsTrackerStreamManager::insert_channel(map_str strMd5, ChannelNode *chnl) { 103 | ChannelNode Node; 104 | if (get_channel(strMd5, &Node) == -1) { 105 | try { 106 | ChannelNode *pNode = new ChannelNode(); 107 | if (!pNode) { 108 | RSLOGE("pNode = new ChannelNode() error | new_channel.\n"); 109 | return 0; 110 | } 111 | 112 | *pNode = *chnl; 113 | bool ret = 114 | channel_map 115 | .insert(std::pair(strMd5, pNode)) 116 | .second; 117 | if (!ret) { 118 | RSLOGE("channel_map.insert error | new_channel.\n"); 119 | delete pNode; 120 | pNode = NULL; 121 | return 0; 122 | } 123 | } catch (...) { 124 | RSLOGE("new ChannelNode Exception error | new_channel.\n"); 125 | } 126 | } else { 127 | ChannelNode *pNode = get_node(strMd5); 128 | if (NULL != pNode) { 129 | *pNode = *chnl; 130 | } 131 | } 132 | return 0; 133 | } 134 | 135 | int RsTrackerStreamManager::delete_channel(map_str uuid) { 136 | CMIt it = channel_map.find(uuid); 137 | if (it == channel_map.end()) { 138 | return NULL; 139 | } 140 | 141 | delete it->second; 142 | channel_map.erase(it); 143 | 144 | return 0; 145 | } 146 | 147 | int RsTrackerStreamManager::get_channel(map_str chnlhash, ChannelNode *Node) { 148 | CCMIt it = channel_map.find(chnlhash); 149 | if (it == channel_map.end()) { 150 | return -1; 151 | } 152 | 153 | *Node = *(it->second); 154 | return 0; 155 | } 156 | 157 | ChannelNode *RsTrackerStreamManager::get_node(map_str chnlhash) { 158 | CCMIt it = channel_map.find(chnlhash); 159 | if (it == channel_map.end()) { 160 | return NULL; 161 | } 162 | return it->second; 163 | } 164 | 165 | int RsTrackerStreamManager::get_cp_address(NetAddress *&pSPAddr, 166 | map_str chnlhash) { 167 | pSPAddr = new NetAddress[1]; 168 | CCMIt it = channel_map.find(chnlhash); 169 | if (it == channel_map.end()) { 170 | delete pSPAddr; 171 | pSPAddr = NULL; 172 | return -1; 173 | } 174 | 175 | pSPAddr[0] = it->second->spAddress; 176 | return 0; 177 | } 178 | 179 | int RsTrackerStreamManager::get_all_cp_address(NetAddress *&pSPAddr, int &inCount, 180 | map_str uuid) { 181 | inCount = get_channel_count(); 182 | 183 | if (0 == inCount) 184 | return 0; 185 | 186 | get_cp_address(pSPAddr, inCount, uuid); 187 | } 188 | 189 | int RsTrackerStreamManager::get_cp_address(NetAddress *&pSPAddr, int &inCount, 190 | map_str uuid) { 191 | NetAddress *sel = NULL; 192 | get_cp_address(sel, uuid); 193 | 194 | inCount = get_channel_count() - 1; 195 | if (0 >= inCount) { 196 | pSPAddr = NULL; 197 | inCount = 0; 198 | delete sel; 199 | return 0; 200 | } 201 | 202 | pSPAddr = new NetAddress[inCount]; 203 | 204 | int index = 0; 205 | for (const auto &val : channel_map) { 206 | if (NULL == sel || sel[0] != val.second->spAddress) { 207 | pSPAddr[index] = val.second->spAddress; 208 | index++; 209 | } 210 | } 211 | inCount = index; 212 | 213 | delete sel; 214 | return index; 215 | } 216 | 217 | int RsTrackerStreamManager::get_cp_address(NetAddress *&pSPAddr, int inCount) { 218 | time_t seed; 219 | time(&seed); 220 | srand(seed); 221 | 222 | pSPAddr = new NetAddress[inCount]; 223 | 224 | int imax = channel_map.size(); 225 | int imaxPos = imax - inCount; 226 | int iPos = 0; 227 | if (imaxPos > 0) { 228 | int iR = rand(); 229 | iPos = iR % imaxPos; 230 | } 231 | 232 | int index = 0; 233 | int i = 0; 234 | for (const auto &val : channel_map) { 235 | if (i >= iPos) { 236 | if (index >= inCount) { 237 | break; 238 | } 239 | 240 | pSPAddr[index] = val.second->spAddress; 241 | index++; 242 | } 243 | i++; 244 | } 245 | 246 | return index; 247 | } 248 | 249 | int RsTrackerStreamManager::get_sp_address(MD5_Hash_Str resHash, 250 | NetAddress *&pSPAddr, int inCount) { 251 | pSPAddr = new NetAddress[inCount]; 252 | 253 | int index = 0; 254 | for (const auto &val : channel_map) { 255 | if (index >= inCount) { 256 | break; 257 | } 258 | for (int i = 0; i < val.second->resourceCount; i++) { 259 | if (val.second->pHash[i] == resHash) { 260 | pSPAddr[index] = val.second->spAddress; 261 | index++; 262 | break; 263 | } 264 | } 265 | } 266 | 267 | return index; 268 | } 269 | 270 | } // namespace tracker 271 | } // namespace protocol 272 | } // namespace rs 273 | -------------------------------------------------------------------------------- /protocol/tracker/tracker_streamer_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016-2017 RabbitStreamer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef PROTOCOL_TRACKER_STREAMER_MANAGER_H_ 24 | #define PROTOCOL_TRACKER_STREAMER_MANAGER_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "core/struct_define.h" 31 | 32 | using namespace std; 33 | using namespace rs::core; 34 | 35 | namespace rs { 36 | namespace protocol { 37 | namespace tracker { 38 | 39 | class RsTrackerStreamManager { 40 | private: 41 | RsTrackerStreamManager(); 42 | static RsTrackerStreamManager *p; 43 | 44 | public: 45 | virtual ~RsTrackerStreamManager(); 46 | 47 | public: 48 | // for single instance 49 | static RsTrackerStreamManager *instance(); 50 | 51 | int initialize(const string &block_data_store_path); 52 | 53 | int timer_check(); 54 | // return is the count result 55 | int get_channel_count(); 56 | // add a new channel 57 | int insert_channel(map_str strMd5, ChannelNode *chnl); 58 | int delete_channel(map_str uuid); 59 | 60 | // find a channel 61 | int get_channel(map_str chnlhash, ChannelNode *Node); 62 | 63 | // find sp address 64 | int get_cp_address(NetAddress *&pSPAddr, map_str chnlhash); 65 | int get_cp_address(NetAddress *&pSPAddr, int &inCount, map_str uuid); 66 | int get_all_cp_address(NetAddress *&pSPAddr, int &inCount, map_str uuid); 67 | int get_cp_address(NetAddress *&pSPAddr, int inCount); 68 | int get_sp_address(MD5_Hash_Str resHash, NetAddress *&pSPAddr, int inCount); 69 | 70 | // 71 | int get_channel_interval(MD5_Hash_Str Channel_hash, 72 | BlockInterval &blockInterval); 73 | 74 | int signal_get_res_interval(MD5_Hash_Str Channel_hash); 75 | // 76 | protected: 77 | ChannelNode *get_node(map_str chnlhash); 78 | 79 | private: 80 | using ChannelHashMap = std::map; 81 | using CMIt = std::map::iterator; 82 | using CCMIt = std::map::const_iterator; 83 | using CMPair = std::pair; 84 | 85 | ChannelHashMap channel_map; 86 | 87 | enum MaxIdleTime : uint16_t { 88 | // if a live channel stopped receiving block from cs for more than 89 | // MAX_IDLE_TIME_SEC, it will be deleted 90 | MAX_IDLE_TIME_SEC = 100, 91 | }; 92 | }; 93 | 94 | } // namespace tracker 95 | } // namespace protocol 96 | } // namespace rs 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /tests/streamer_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "core/streamer.h" 5 | 6 | using namespace rs::core; 7 | 8 | TEST(StreamerTest, construct) { 9 | RsStreamer *streamer = new RsStreamer; 10 | char buf[] = {0x1, 0x2, 0x3, 0x4}; 11 | streamer->initialize(buf, sizeof(buf)); 12 | 13 | delete streamer; 14 | } -------------------------------------------------------------------------------- /third_party/md5/md5.h: -------------------------------------------------------------------------------- 1 | // MD5.CC - source code for the C++/object oriented translation and 2 | // modification of MD5. 3 | 4 | // Translation and modification (c) 1995 by Mordechai T. Abzug 5 | 6 | // This translation/ modification is provided "as is," without express or 7 | // implied warranty of any kind. 8 | 9 | // The translator/ modifier does not claim (1) that MD5 will do what you think 10 | // it does; (2) that this translation/ modification is accurate; or (3) that 11 | // this software is "merchantible." (Language for this disclaimer partially 12 | // copied from the disclaimer below). 13 | 14 | /* based on: 15 | 16 | MD5.H - header file for MD5C.C 17 | MDDRIVER.C - test driver for MD2, MD4 and MD5 18 | 19 | Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 20 | rights reserved. 21 | 22 | License to copy and use this software is granted provided that it 23 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest 24 | Algorithm" in all material mentioning or referencing this software 25 | or this function. 26 | 27 | License is also granted to make and use derivative works provided 28 | that such works are identified as "derived from the RSA Data 29 | Security, Inc. MD5 Message-Digest Algorithm" in all material 30 | mentioning or referencing the derived work. 31 | 32 | RSA Data Security, Inc. makes no representations concerning either 33 | the merchantability of this software or the suitability of this 34 | software for any particular purpose. It is provided "as is" 35 | without express or implied warranty of any kind. 36 | 37 | These notices must be retained in any copies of any part of this 38 | documentation and/or software. 39 | 40 | */ 41 | 42 | #ifndef _MD5_H__ 43 | #define _MD5_H__ 44 | 45 | class MD5 { 46 | 47 | public: 48 | // methods for controlled operation: 49 | MD5 (); // simple initializer 50 | void update (const unsigned char *input, unsigned int input_length); 51 | void update (FILE *file); 52 | void finalize (); 53 | 54 | // constructors for special circumstances. All these constructors finalize 55 | // the MD5 context. 56 | MD5 (const unsigned char *string, unsigned int len); // digest string, finalize 57 | MD5 (FILE *file); // digest file, close, finalize 58 | 59 | // methods to acquire finalized result 60 | unsigned char *raw_digest (); // digest as a 16-byte binary array 61 | char * hex_digest (); // digest as a 33-byte ascii-hex string 62 | 63 | 64 | 65 | private: 66 | 67 | // first, some types: 68 | typedef unsigned int uint4; // assumes integer is 4 words long 69 | typedef unsigned short int uint2; // assumes short integer is 2 words long 70 | typedef unsigned char uint1; // assumes char is 1 word long 71 | 72 | // next, the private data: 73 | uint4 state[4]; 74 | uint4 count[2]; // number of *bits*, mod 2^64 75 | uint1 buffer[64]; // input buffer 76 | uint1 digest[16]; 77 | uint1 finalized; 78 | 79 | // last, the private methods, mostly static: 80 | void init (); // called by all constructors 81 | void transform (const uint1 *buffer); // does the real update work. Note 82 | // that length is implied to be 64. 83 | 84 | static void encode (uint1 *dest, uint4 *src, uint4 length); 85 | static void decode (uint4 *dest, const uint1 *src, uint4 length); 86 | static void memcpy (uint1 *dest, const uint1 *src, uint4 length); 87 | static void memset (uint1 *start, uint1 val, uint4 length); 88 | 89 | static inline uint4 rotate_left (uint4 x, uint4 n); 90 | static inline uint4 F (uint4 x, uint4 y, uint4 z); 91 | static inline uint4 G (uint4 x, uint4 y, uint4 z); 92 | static inline uint4 H (uint4 x, uint4 y, uint4 z); 93 | static inline uint4 I (uint4 x, uint4 y, uint4 z); 94 | static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 95 | uint4 s, uint4 ac); 96 | static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 97 | uint4 s, uint4 ac); 98 | static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 99 | uint4 s, uint4 ac); 100 | static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 101 | uint4 s, uint4 ac); 102 | 103 | }; 104 | 105 | #endif -------------------------------------------------------------------------------- /third_party/st-1.9.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wenxiaoming/rabbitstreamer/6a8b11d8885485a5cd740bba2326ec5dbad1fea0/third_party/st-1.9.zip --------------------------------------------------------------------------------