reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
TcpConnection.cxx
Go to the documentation of this file.
1#include "TcpConnection.hxx"
2#include <vector>
4#include "RequestHandler.hxx"
5#include <rutil/Logger.hxx>
6#include "ReTurnSubsystem.hxx"
7
8#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN
9
10using namespace std;
11using namespace resip;
12
13namespace reTurn {
14
15TcpConnection::TcpConnection(asio::io_context& ioService,
16 ConnectionManager& manager, RequestHandler& handler)
17 : AsyncTcpSocketBase(ioService),
18 mConnectionManager(manager),
19 mRequestHandler(handler)
20{
21}
22
24{
25 DebugLog(<< "TcpConnection destroyed.");
26}
27
28asio::ip::tcp::socket&
30{
31 return mSocket;
32}
33
34void
36{
37 DebugLog(<< "TcpConnection started.");
39 asio::error_code ec;
40 mLocalAddress = mSocket.local_endpoint(ec).address();
41 mLocalPort = mSocket.local_endpoint(ec).port();
42 // Closed if it goes TcpConnectionIdleTimeout without receiving anything while it carries no
43 // allocation
44 startIdleTimer(mRequestHandler.getConfig().mTcpConnectionIdleTimeout, [this]() { return !mTurnAllocationManager.empty(); });
46}
47
48void
50{
52 asio::error_code ec;
53 mSocket.close(ec);
54}
55
56void
58{
59 mConnectionManager.stop(shared_from_this());
60}
61
62void
63TcpConnection::onReceiveSuccess(const asio::ip::address& address, unsigned short port, const std::shared_ptr<DataBuffer>& data)
64{
66 if (data->size() > 4)
67 {
68 /*
69 std::cout << "Read " << bytesTransferred << " bytes from tcp socket (" << address.to_string() << ":" << port << "): " << std::endl;
70 cout << std::hex;
71 for(int i = 0; i < data->size(); i++)
72 {
73 std::cout << (char)(*data)[i] << "(" << int((*data)[i]) << ") ";
74 }
75 std::cout << std::dec << std::endl;
76 */
77
78 if(((*data)[0] & 0xC0) == 0) // Stun/Turn Messages always have bits 0 and 1 as 00 - otherwise ChannelData message
79 {
80 // Try to parse stun message
82 StunTuple(StunTuple::TCP, address, port),
83 (char*)&(*data)[0], (unsigned int)data->size());
84 if(request.isValid())
85 {
86 StunMessage response;
88
89 switch(result)
90 {
92 // No response to send - just receive next message
94 return;
98 // These only happen for UDP server for RFC3489 backwards compatibility
99 resip_assert(false);
100 break;
102 default:
103 break;
104 }
105 constexpr size_t RESPONSE_BUFFER_SIZE = 1024;
106 const auto buffer = allocateBuffer(RESPONSE_BUFFER_SIZE);
107 unsigned int responseSize;
108 responseSize = response.stunEncodeMessage((char*)buffer->data(), RESPONSE_BUFFER_SIZE);
109 buffer->truncate(responseSize); // set size to real size
110
111 doSend(response.mRemoteTuple, buffer);
112 }
113 else
114 {
115 WarningLog(<< "Received invalid StunMessage. Dropping.");
116 }
117 }
118 else // ChannelData message
119 {
120 unsigned short channelNumber;
121 memcpy(&channelNumber, &(*data)[0], 2);
122 channelNumber = ntohs(channelNumber);
123
125 channelNumber,
127 StunTuple(StunTuple::TCP, address, port),
128 data);
129 }
130 }
131 else
132 {
133 WarningLog(<< "Not enough data for stun message or framed message. Closing connection.");
134 close();
135 return;
136 }
137
139}
140
141void
142TcpConnection::onReceiveFailure(const asio::error_code& e)
143{
144 if(e != asio::error::operation_aborted)
145 {
146 InfoLog(<< "TcpConnection::onReceiveFailure: " << e.value() << "-" << e.message());
147 close();
148 }
149}
150
151void
155
156void
157TcpConnection::onSendFailure(const asio::error_code& error)
158{
159 if(error != asio::error::operation_aborted)
160 {
161 InfoLog(<< "TcpConnection::onSendFailure: " << error.value() << "-" << error.message());
162 close();
163 }
164}
165
166}
167
168
169/* ====================================================================
170
171 Copyright (c) 2008-2026 SIP Spectrum, Inc. https://www.sipspectrum.com
172 Copyright (c) 2007-2008, Plantronics, Inc.
173 All rights reserved.
174
175 Redistribution and use in source and binary forms, with or without
176 modification, are permitted provided that the following conditions are
177 met:
178
179 1. Redistributions of source code must retain the above copyright
180 notice, this list of conditions and the following disclaimer.
181
182 2. Redistributions in binary form must reproduce the above copyright
183 notice, this list of conditions and the following disclaimer in the
184 documentation and/or other materials provided with the distribution.
185
186 3. Neither the name of Plantronics nor the names of its contributors
187 may be used to endorse or promote products derived from this
188 software without specific prior written permission.
189
190 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
191 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
194 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
195 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
196 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
197 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
198 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
199 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
200 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
201
202 ==================================================================== */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
#define resip_assert(x)
This file needs to work for both C and C++ code.
static std::shared_ptr< DataBuffer > allocateBuffer(size_t size)
Utility API.
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.
void startIdleTimer(unsigned int timeoutSeconds, std::function< bool()> inUse)
For server connections (TcpConnectionIdleTimeout): the connection is closed, with close(),...
asio::ip::tcp::socket mSocket
Manages open connections so that they may be cleanly stopped when the server needs to shut down,...
void stop(ConnectionPtr c)
Stop the specified connection.
unsigned long mTcpConnectionIdleTimeout
The common handler for all incoming requests.
void processTurnData(TurnAllocationManager &turnAllocationManager, unsigned short channelNumber, const StunTuple &localTuple, const StunTuple &remoteTuple, const std::shared_ptr< DataBuffer > &data)
const ReTurnConfig & getConfig()
ProcessResult processStunMessage(AsyncSocketBase *turnSocket, TurnAllocationManager &turnAllocationManager, StunMessage &request, StunMessage &response, bool isRFC3489BackwardsCompatServer=false)
Process a received StunMessage, and produce a reply Returns true if the response message is to be sen...
unsigned int stunEncodeMessage(char *buf, unsigned int bufLen)
virtual void stop()
Stop all asynchronous operations associated with the connection.
RequestHandler & mRequestHandler
The handler used to process the incoming request.
virtual void onSendFailure(const asio::error_code &e)
asio::ip::tcp::socket & socket()
Get the socket associated with the connection.
virtual void close()
Override close fn in AsyncTcpSocketBase so that we can remove ourselves from connection manager.
asio::ip::address mLocalAddress
virtual void onReceiveSuccess(const asio::ip::address &address, unsigned short port, const std::shared_ptr< DataBuffer > &data)
Handle completion of a receive operation.
unsigned short mLocalPort
virtual void start()
Start the first asynchronous operation for the connection.
virtual void onReceiveFailure(const asio::error_code &e)
virtual void onSendSuccess()
Handle completion of a send operation.
TurnAllocationManager mTurnAllocationManager
Manages turn allocations.
ConnectionManager & mConnectionManager
The connection manager for this connection.
dcm! – add UnusedChecking(_enum) below;