reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
AsyncSocketBase.hxx
Go to the documentation of this file.
1#ifndef ASYNC_SOCKET_BASE_HXX
2#define ASYNC_SOCKET_BASE_HXX
3
4#include <asio.hpp>
5#ifdef USE_SSL
6#include <asio/ssl.hpp>
7#endif
8
9#include "DataBuffer.hxx"
10#include "StunTuple.hxx"
11
12#include <chrono>
13#include <cstddef>
14#include <deque>
15#include <functional>
16#include <memory>
17#include <utility>
18#include <vector>
19
20constexpr size_t RECEIVE_BUFFER_SIZE = 4096; // ?slg? should we shrink this to something closer to MTU (1500 bytes)? !hbr! never actually increase it otherwise re-assembled UDP packets get lost. (was 2048)
21
22namespace reTurn {
23
24class AsyncSocketBaseHandler;
26
28 public std::enable_shared_from_this<AsyncSocketBase>
29{
30public:
31 using BeforeClosedHandler = std::function<void(unsigned int)>;
32
33 explicit AsyncSocketBase(asio::io_context& ioService);
34 virtual ~AsyncSocketBase();
35
36 virtual unsigned int getSocketDescriptor() = 0;
37
39
41 virtual asio::error_code bind(const asio::ip::address& address, unsigned short port) = 0;
42 virtual void connect(const std::string& address, unsigned short port) = 0;
44 virtual void send(const StunTuple& destination, const std::shared_ptr<DataBuffer>& data); // Send unframed data
45 virtual void send(const StunTuple& destination, unsigned short channel, const std::shared_ptr<DataBuffer>& data); // send with turn framing
47 virtual void receive();
48 virtual void framedReceive();
49 virtual void close();
50
52 asio::ip::address& getConnectedAddress() noexcept { return mConnectedAddress; }
53 unsigned short getConnectedPort() const noexcept { return mConnectedPort; }
54
56
58 virtual void doSend(const StunTuple& destination, unsigned short channel, const std::shared_ptr<DataBuffer>& data, const std::size_t bufferStartPos = 0);
59 virtual void doSend(const StunTuple& destination, const std::shared_ptr<DataBuffer>& data, const std::size_t bufferStartPos = 0);
60 virtual void doReceive();
61 virtual void doFramedReceive();
62
64 virtual void onConnectSuccess() { resip_assert(false); }
65 virtual void onConnectFailure(const asio::error_code& e) { resip_assert(false); }
66 virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, const std::shared_ptr<DataBuffer>& data) = 0;
67 virtual void onReceiveFailure(const asio::error_code& e) = 0;
68 virtual void onSendSuccess() = 0;
69 virtual void onSendFailure(const asio::error_code& e) = 0;
70
72 static std::shared_ptr<DataBuffer> allocateBuffer(size_t size);
73
76 static size_t channelDataPadding(size_t length) { return (4 - length % 4) % 4; }
77
83 static void setExclusiveAddressUse(asio::ip::udp::socket& socket);
84
85 // Stubbed out async handlers needed by Protocol specific Subclasses of this - the requirement for these
86 // to be in the base class all revolves around the shared_from_this() use/requirement
87 virtual void start() { resip_assert(false); }
88 virtual void stop() { resip_assert(false); }
89 virtual void handleReadHeader(const asio::error_code& e) { resip_assert(false); }
90 virtual void handleServerHandshake(const asio::error_code& e) { resip_assert(false); }
91 virtual void handleTcpResolve(const asio::error_code& ec, const asio::ip::tcp::resolver::results_type& endpoints) { resip_assert(false); }
92 virtual void handleUdpResolve(const asio::error_code& ec, const asio::ip::udp::resolver::results_type& endpoints) { resip_assert(false); }
93 virtual void handleConnect(const asio::error_code& ec, const asio::ip::tcp::endpoint& endpoint) { resip_assert(false); }
94 virtual void handleClientHandshake(const asio::error_code& ec, const asio::ip::tcp::endpoint& endpoint) { resip_assert(false); }
95
96protected:
98 virtual void handleSend(const asio::error_code& e);
99 virtual void handleReceive(const asio::error_code& e, size_t bytesTransferred);
100
105 asio::error_code openAndBind(asio::ip::tcp::socket& socket);
106 void asyncConnect(asio::ip::tcp::socket& socket, const asio::ip::tcp::resolver::results_type& endpoints);
107 asio::ip::tcp::endpoint mLocalTcpEndpoint;
108
113 void startIdleTimer(unsigned int timeoutSeconds, std::function<bool()> inUse);
114 void noteReceived() { mLastReceived = std::chrono::steady_clock::now(); }
115 void stopIdleTimer();
116
118 asio::io_context& mIOService;
119
121 std::shared_ptr<DataBuffer> mReceiveBuffer;
123
125 asio::ip::address mConnectedAddress;
126 unsigned short mConnectedPort;
128
131
135
136private:
137 void asyncConnectFrom(asio::ip::tcp::socket& socket, asio::ip::tcp::resolver::results_type endpoints,
138 asio::ip::tcp::resolver::results_type::const_iterator next, asio::error_code lastError);
139
140 void waitIdle(std::chrono::steady_clock::duration wait);
141 std::unique_ptr<asio::steady_timer> mIdleTimer;
142 std::chrono::steady_clock::duration mIdleTimeout;
143 std::function<bool()> mInUse;
144 std::chrono::steady_clock::time_point mLastReceived;
145
146 virtual void transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers) = 0;
147 virtual void transportReceive() = 0;
148 virtual void transportFramedReceive() = 0;
149 virtual void transportClose() = 0;
150
151 virtual asio::ip::address getSenderEndpointAddress() = 0;
152 virtual unsigned short getSenderEndpointPort() = 0;
153
154 virtual void sendFirstQueuedData();
155 class SendData
156 {
157 public:
158 SendData(const StunTuple& destination, std::shared_ptr<DataBuffer> frameData, std::shared_ptr<DataBuffer> data, size_t bufferStartPos = 0, size_t padding = 0) :
159 mDestination(destination), mFrameData(frameData), mData(data), mBufferStartPos(bufferStartPos), mPadding(padding) {}
160 StunTuple mDestination;
161 std::shared_ptr<DataBuffer> mFrameData;
162 std::shared_ptr<DataBuffer> mData;
163 size_t mBufferStartPos;
164 size_t mPadding; // bytes sent after the data: ChannelData over TCP/TLS is padded to a multiple of 4
165 };
167 typedef std::deque<SendData> SendDataQueue;
168 SendDataQueue mSendDataQueue;
169};
170
171typedef std::shared_ptr<AsyncSocketBase> ConnectionPtr;
172
173}
174
175#endif
176
177
178/* ====================================================================
179
180 Copyright (c) 2008-2026 SIP Spectrum, Inc. https://www.sipspectrum.com
181 Copyright (c) 2007-2008, Plantronics, Inc.
182 All rights reserved.
183
184 Redistribution and use in source and binary forms, with or without
185 modification, are permitted provided that the following conditions are
186 met:
187
188 1. Redistributions of source code must retain the above copyright
189 notice, this list of conditions and the following disclaimer.
190
191 2. Redistributions in binary form must reproduce the above copyright
192 notice, this list of conditions and the following disclaimer in the
193 documentation and/or other materials provided with the distribution.
194
195 3. Neither the name of Plantronics nor the names of its contributors
196 may be used to endorse or promote products derived from this
197 software without specific prior written permission.
198
199 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
201 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
204 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
205 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
206 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
207 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
208 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
209 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
210
211 ==================================================================== */
constexpr size_t RECEIVE_BUFFER_SIZE
#define resip_assert(x)
This file needs to work for both C and C++ code.
virtual void handleConnect(const asio::error_code &ec, const asio::ip::tcp::endpoint &endpoint)
virtual void handleReceive(const asio::error_code &e, size_t bytesTransferred)
asio::ip::address & getConnectedAddress() noexcept
asio::ip::tcp::endpoint mLocalTcpEndpoint
asio::error_code openAndBind(asio::ip::tcp::socket &socket)
For TCP and TLS client sockets.
virtual void onReceiveSuccess(const asio::ip::address &address, unsigned short port, const std::shared_ptr< DataBuffer > &data)=0
virtual void handleTcpResolve(const asio::error_code &ec, const asio::ip::tcp::resolver::results_type &endpoints)
BeforeClosedHandler mOnBeforeSocketCloseFp
Provides an opportunity for the app to clean up, e.g., QoS-related data or resources just before the ...
static size_t channelDataPadding(size_t length)
Over TCP and TLS, a TURN ChannelData message is padded to a multiple of 4 bytes, the padding not coun...
virtual void handleClientHandshake(const asio::error_code &ec, const asio::ip::tcp::endpoint &endpoint)
virtual void onConnectFailure(const asio::error_code &e)
virtual void onConnectSuccess()
Class override callbacks.
virtual void handleSend(const asio::error_code &e)
Handle completion of a sendData operation.
static std::shared_ptr< DataBuffer > allocateBuffer(size_t size)
Utility API.
unsigned short getConnectedPort() const noexcept
std::function< void(unsigned int)> BeforeClosedHandler
virtual void handleReadHeader(const asio::error_code &e)
virtual void onReceiveFailure(const asio::error_code &e)=0
void asyncConnect(asio::ip::tcp::socket &socket, const asio::ip::tcp::resolver::results_type &endpoints)
virtual void onSendFailure(const asio::error_code &e)=0
virtual void onSendSuccess()=0
asio::io_context & mIOService
The io_context used to perform asynchronous operations.
virtual void setOnBeforeSocketClosedFp(BeforeClosedHandler fp)
virtual void doSend(const StunTuple &destination, unsigned short channel, const std::shared_ptr< DataBuffer > &data, const std::size_t bufferStartPos=0)
Use these if you already operating within the ioService thread.
std::shared_ptr< DataBuffer > mReceiveBuffer
Receive Buffer and state.
bool isConnected() const noexcept
AsyncSocketBaseHandler * mAsyncSocketBaseHandler
Handlers.
virtual void send(const StunTuple &destination, const std::shared_ptr< DataBuffer > &data)
Note: destination is ignored for TCP and TLS connections.
virtual void handleServerHandshake(const asio::error_code &e)
void startIdleTimer(unsigned int timeoutSeconds, std::function< bool()> inUse)
For server connections (TcpConnectionIdleTimeout): the connection is closed, with close(),...
static void setExclusiveAddressUse(asio::ip::udp::socket &socket)
For a UDP socket, between open() and bind().
asio::ip::address mConnectedAddress
Connected Info and State.
virtual unsigned int getSocketDescriptor()=0
virtual void receive()
Overlapped calls to receive functions have no effect.
virtual asio::error_code bind(const asio::ip::address &address, unsigned short port)=0
Note: The following API's are thread safe and queue the request to be handled by the ioService thread...
virtual void handleUdpResolve(const asio::error_code &ec, const asio::ip::udp::resolver::results_type &endpoints)
virtual void registerAsyncSocketBaseHandler(AsyncSocketBaseHandler *handler)
virtual void connect(const std::string &address, unsigned short port)=0
std::shared_ptr< AsyncSocketBase > ConnectionPtr
void list()
Definition userAdmin.cxx:66