reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
UdpRelayServer.cxx
Go to the documentation of this file.
1#include <functional>
2
3#include "UdpRelayServer.hxx"
4#include "StunMessage.hxx"
5#include "TurnAllocation.hxx"
6#include "StunTuple.hxx"
7#include <rutil/Logger.hxx>
8#include "ReTurnSubsystem.hxx"
9
10#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN
11
12using namespace std;
13
14namespace reTurn {
15
16UdpRelayServer::UdpRelayServer(asio::io_context& ioService, TurnAllocation& turnAllocation)
17: AsyncUdpSocketBase(ioService),
18 mTurnAllocation(turnAllocation),
19 mStopping(false),
20 mBindSuccess(false)
21{
22 asio::error_code ec = bind(turnAllocation.getRequestedTuple().getAddress(), turnAllocation.getRequestedTuple().getPort());
23 if(ec)
24 {
25 ErrLog(<< "UdpRelayServer failed to start properly. [" << mTurnAllocation.getRequestedTuple().getAddress().to_string() << ":" << mTurnAllocation.getRequestedTuple().getPort() << "], error=" << ec.value() << "-" << ec.message());
26 }
27 else
28 {
29 mBindSuccess = true;
30 InfoLog(<< "UdpRelayServer started. [" << mTurnAllocation.getRequestedTuple().getAddress().to_string() << ":" << mTurnAllocation.getRequestedTuple().getPort() << "]");
31 }
32}
33
35{
36 InfoLog(<< "~UdpRelayServer - destroyed. [" << mTurnAllocation.getRequestedTuple().getAddress().to_string() << ":" << mTurnAllocation.getRequestedTuple().getPort() << "]");
37}
38
39bool
41{
42 if(mBindSuccess)
43 {
44 // Note: This function is required, since you cannot call shared_from_this in the constructor: shared_from_this requires that at least one shared ptr exists already
45 doReceive();
46 return true;
47 }
48 else
49 {
50 stop();
51 return false;
52 }
53}
54
55void
57{
58 asio::error_code ec;
59 mStopping = true;
60 mSocket.close(ec);
61}
62
63void
64UdpRelayServer::onReceiveSuccess(const asio::ip::address& address, unsigned short port, const std::shared_ptr<DataBuffer>& data)
65{
66 if(mStopping)
67 {
68 return;
69 }
70 if (data->size() > 0)
71 {
72 DebugLog(<< "Read " << (int)data->size() << " bytes from udp relay socket (" << address.to_string() << ":" << port << "): ");
73 /*
74 cout << std::hex;
75 for(int i = 0; i < (int)data->size(); i++)
76 {
77 std::cout << (char)(*data)[i] << "(" << int((*data)[i]) << ") ";
78 }
79 std::cout << std::dec << std::endl;
80 */
81
82 // If active destination is not set, then send to client as a DataInd, otherwise send packet as is
83 mTurnAllocation.sendDataToClient(StunTuple(StunTuple::UDP, address, port), data);
84 }
85 doReceive();
86}
87
88void
89UdpRelayServer::onReceiveFailure(const asio::error_code& e)
90{
91 if(!mStopping && e != asio::error::operation_aborted && e != asio::error::bad_descriptor)
92 {
93 doReceive();
94 }
95}
96
97void
98UdpRelayServer::onSendSuccess()
99{
100}
101
102void
103UdpRelayServer::onSendFailure(const asio::error_code& error)
104{
105 if(!mStopping && error != asio::error::operation_aborted)
106 {
107 if(mLastSendErrorCode == error)
108 {
109 DebugLog(<< "UdpRelayServer::onSendFailure: [" << mTurnAllocation.getRequestedTuple().getAddress().to_string() << ":" << mTurnAllocation.getRequestedTuple().getPort() << "] " << error.value() << "-" << error.message());
110 }
111 else
112 {
113 mLastSendErrorCode = error;
114 WarningLog(<< "UdpRelayServer::onSendFailure: [" << mTurnAllocation.getRequestedTuple().getAddress().to_string() << ":" << mTurnAllocation.getRequestedTuple().getPort() << "] " << error.value() << "-" << error.message());
115 }
116 }
117}
118
119}
120
121
122/* ====================================================================
123
124 Copyright (c) 2007-2008, Plantronics, Inc.
125 All rights reserved.
126
127 Redistribution and use in source and binary forms, with or without
128 modification, are permitted provided that the following conditions are
129 met:
130
131 1. Redistributions of source code must retain the above copyright
132 notice, this list of conditions and the following disclaimer.
133
134 2. Redistributions in binary form must reproduce the above copyright
135 notice, this list of conditions and the following disclaimer in the
136 documentation and/or other materials provided with the distribution.
137
138 3. Neither the name of Plantronics nor the names of its contributors
139 may be used to endorse or promote products derived from this
140 software without specific prior written permission.
141
142 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
143 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
144 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
145 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
146 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
147 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
148 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
149 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
150 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
151 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
152 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153
154 ==================================================================== */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
asio::ip::udp::socket mSocket
asio::error_code bind(const asio::ip::address &address, unsigned short port) override
Note: The following API's are thread safe and queue the request to be handled by the ioService thread...
const asio::ip::address & getAddress() const
Definition StunTuple.hxx:44
unsigned int getPort() const
Definition StunTuple.hxx:47
const StunTuple & getRequestedTuple() const noexcept
void sendDataToClient(const StunTuple &peerAddress, const std::shared_ptr< DataBuffer > &data)
bool startReceiving()
Starts processing.
void stop()
Causes this object to destroy itself safely (ie. waiting for asynchronous callbacks to finish)
UdpRelayServer(asio::io_context &ioService, TurnAllocation &turnAllocation)
Create the server to listen on the specified UDP address and port.