1 /** 2 * Copyright (c) 2017, Andrew Gault, Nick Chadwick and Guillaume Egles. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of the <organization> nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #pragma once 29 30 /** 31 * Wrapper around usrsctp. 32 */ 33 34 #include "ChunkQueue.hpp" 35 #include "PeerConnection.hpp" 36 37 #include <thread> 38 39 #include <usrsctp.h> 40 41 namespace rtcdcpp { 42 43 #define MAX_OUT_STREAM 256 44 #define MAX_IN_STREAM 256 45 46 class SCTPWrapper { 47 public: 48 using MsgReceivedCallbackPtr = std::function<void(ChunkPtr chunk, uint16_t sid, uint32_t ppid)>; 49 using DTLSEncryptCallbackPtr = std::function<void(ChunkPtr)>; 50 51 SCTPWrapper(DTLSEncryptCallbackPtr dtlsEncryptCB, MsgReceivedCallbackPtr msgReceivedCB); 52 virtual ~SCTPWrapper(); 53 54 bool Initialize(); 55 void Start(); 56 void Stop(); 57 // int GetStreamCursor(); 58 // void SetStreamCursor(int i); 59 60 // Handle a decrypted SCTP packet 61 void DTLSForSCTP(ChunkPtr chunk); 62 63 // Send a message to the remote connection 64 // Note, this will cause 1+ DTLSEncrypt callback calls 65 void GSForSCTP(ChunkPtr chunk, uint16_t sid, uint32_t ppid); 66 67 private: 68 // PeerConnection *peer_connection; 69 bool started{false}; 70 struct socket *sock; 71 uint16_t local_port; 72 uint16_t remote_port; 73 int stream_cursor; 74 75 bool connectSentData{false}; 76 std::mutex connectMtx; 77 std::condition_variable connectCV; 78 79 ChunkQueue send_queue; 80 ChunkQueue recv_queue; 81 82 const DTLSEncryptCallbackPtr dtlsEncryptCallback; 83 const MsgReceivedCallbackPtr msgReceivedCallback; 84 85 std::atomic<bool> should_stop{false}; 86 std::thread recv_thread; 87 std::thread connect_thread; 88 89 void RunConnect(); 90 void RecvLoop(); 91 92 // SCTP has output a packet ready for DTLS 93 int OnSCTPForDTLS(void *data, size_t len, uint8_t tos, uint8_t set_df); 94 95 // SCTP has received a packet for GameSurge 96 int OnSCTPForGS(struct socket *sock, union sctp_sockstore addr, void *data, size_t len, struct sctp_rcvinfo recv_info, int flags); 97 98 void OnMsgReceived(const uint8_t *data, size_t len, int ppid, int sid); 99 void OnNotification(union sctp_notification *notify, size_t len); 100 101 // usrsctp callbacks 102 static int _OnSCTPForDTLS(void *sctp_ptr, void *data, size_t len, uint8_t tos, uint8_t set_df); 103 static void _DebugLog(const char *format, ...); 104 static int _OnSCTPForGS(struct socket *sock, union sctp_sockstore addr, void *data, size_t len, struct sctp_rcvinfo recv_info, int flags, 105 void *user_data); 106 107 std::shared_ptr<Logger> logger = GetLogger("rtcdcpp.SCTP"); 108 }; 109 } 110