bool TCPClient::createAndBindConnection(UInt32 connectionID, const net::Address& peerAddress) { //assert (!closed()); //Mutex::ScopedLock lock(_mutex); TraceL << "Create and bind connection: " << peerAddress << endl; try { net::TCPSocket::Ptr conn(net::makeSocket<net::TCPSocket>()); //std::make_shared<net::TCPSocket>()); conn->Connect += sdelegate(this, &TCPClient::onRelayConnectionConnect); conn->Error += sdelegate(this, &TCPClient::onRelayConnectionError); conn->Close += sdelegate(this, &TCPClient::onRelayConnectionClosed); auto req = new RelayConnectionBinding; req->connectionID = connectionID; req->peerAddress = peerAddress; conn->opaque = req; conn->connect(_options.serverAddr); // will throw on error _connections.add(peerAddress, conn); return true; } catch (std::exception& exc) { // Socket instance deleted via state callback ErrorL << "ConnectionBind Error: " << exc.what() << endl; } return false; }
void testClient() { smpl::Client::Options options; options.host = SERVER_HOST; options.port = SERVER_PORT; options.user = "******"; options.name = "crash"; options.type = "testapp"; // NOTE: The server should allow anonymous // authentication for this test. //options.token = ""; used for authentication #if USE_SSL smpl::SSLClient client(options); #else smpl::TCPClient client(options); #endif client.Announce += sdelegate(this, &Tests::onClientAnnounce); client.StateChange += sdelegate(this, &Tests::onClientStateChange); client.CreatePresence += sdelegate(this, &Tests::onCreatePresence); client.connect(); app.waitForShutdown([](void* opaque) { reinterpret_cast<smpl::Client*>(opaque)->close(); }, &client); DebugL << "Event loop ended" << endl; }
void TCPConnectionPair::setPeerSocket(const net::TCPSocket::Ptr& socket) { TraceLS(this) << "Set peer socket: " << connectionID << ": " << socket->peerAddress() << endl; //<< ": " << socket./*base().*/refCount() assert(peer == nullptr); //assert(socket./*base().*/refCount() == 1); peer = socket; peer->Close += sdelegate(this, &TCPConnectionPair::onConnectionClosed); // Receive and buffer early media from peer peer->Recv += sdelegate(this, &TCPConnectionPair::onPeerDataReceived); net::setServerSocketBufSize<uv_tcp_t>(*socket.get(), SERVER_SOCK_BUF_SIZE); // TODO: make option }
void Client::addConnection(ClientConnection::Ptr conn) { TraceS(this) << "Adding connection: " << conn << endl; conn->Close += sdelegate(this, &Client::onConnectionClose, -1); // lowest priority _connections.push_back(conn); }
void run() { initiator->AllocationCreated += sdelegate(this, &ClientTest::onInitiatorAllocationCreated); // TODO: Use STUN binding request to get IP initiator->initiate(TURN_AUTHORIZE_PEER_IP); }
void TCPConnectionPair::onPeerConnectSuccess(void* sender) { TraceLS(this) << "Peer Connect request success" << endl; assert(sender == &peer); peer->Connect -= sdelegate(this, &TCPConnectionPair::onPeerConnectSuccess); peer->Error -= sdelegate(this, &TCPConnectionPair::onPeerConnectError); // If no ConnectionBind request associated with this peer data // connection is received after 30 seconds, the peer data connection // MUST be closed. allocation.sendPeerConnectResponse(this, true); // TODO: Ensure this is implemented properly startTimeout(); }
void runTimerTest() { TraceL << "Timer Test: Starting" << endl; Timer timer; timer.Timeout += sdelegate(this, &Tests::onOnTimerTimeout); timer.start(10, 10); runLoop(); }
void StreamManager::onAdd(PacketStream* stream) { // Stream name can't be empty assert(!stream->name().empty()); // Receive callbacks after all other listeners // so we can delete the stream when it closes. DebugL << "stream added: " << stream->name() << endl; stream->StateChange += sdelegate(this, &StreamManager::onStreamStateChange, -1); }
void TCPConnectionPair::setClientSocket(const net::TCPSocket::Ptr& socket) { TraceLS(this) << "Set client socket: " << connectionID << ": " << socket->peerAddress() << endl; //<< ": " << socket./*base().*/refCount() assert(client == nullptr); //assert(socket./*base().*/refCount() == 2); client = socket; client->Close += sdelegate(this, &TCPConnectionPair::onConnectionClosed); net::setServerSocketBufSize<uv_tcp_t>(*socket.get(), SERVER_SOCK_BUF_SIZE); // TODO: make option }
bool TCPConnectionPair::makeDataConnection() { TraceLS(this) << "Make data connection: " << connectionID << endl; if (!peer || !client) return false; peer->Recv += sdelegate(this, &TCPConnectionPair::onPeerDataReceived); client->Recv += sdelegate(this, &TCPConnectionPair::onClientDataReceived); // Relase and unbind the client socket from the server. // The client socket instance, events and data will be // managed by the TCPConnectionPair from now on. allocation.server().releaseTCPSocket(client.get()); // Send early data from peer to client if (earlyPeerData.size()) { TraceLS(this) << "Flushing early media: " << earlyPeerData.size() << endl; client->send(earlyPeerData.data(), earlyPeerData.size()); earlyPeerData.clear(); } return (isDataConnection = true); }
UDPAllocation::UDPAllocation(Server& server, const FiveTuple& tuple, const std::string& username, const UInt32& lifetime) : ServerAllocation(server, tuple, username, lifetime)//, //_relaySocket(new net::UDPSocket) //server.reactor(), server.runner() { // Handle data from the relay socket directly from the allocation. // This will remove the need for allocation lookups when receiving // data from peers. _relaySocket.bind(net::Address(server.options().listenAddr.host(), 0)); _relaySocket.Recv += sdelegate(this, &UDPAllocation::onPeerDataReceived); TraceL << " Initializing on address: " << _relaySocket.address() << endl; }
void TCPClient::freeConnection(const net::Address& peerAddress) //const net::TCPSocket::Ptr& socket) { TraceL << "Freeing TCP connection: " << socket << endl; auto socket = connections().get(peerAddress); socket->Recv -= sdelegate(this, &TCPClient::onRelayDataReceived); socket->Connect -= sdelegate(this, &TCPClient::onRelayConnectionConnect); socket->Error -= sdelegate(this, &TCPClient::onRelayConnectionError); socket->Close -= sdelegate(this, &TCPClient::onRelayConnectionClosed); //assert(socket->base().refCount() == 1); //assert(connections().has(socket->address())); connections().remove(peerAddress); // destroy socket //auto map = connections().map(); //for (auto conn : map) { //assert(it->second->base().refCount() == 1); // The connection will be removed via onRelayConnectionClosed //it->second->close(); //} delete reinterpret_cast<RelayConnectionBinding*>(socket->opaque); //delete socket; //deleteLater<net::TCPSocket>(socket); // deferred }
bool TCPConnectionPair::doPeerConnect(const net::Address& peerAddr) { try { assert(!transactionID.empty()); peer = std::make_shared<net::TCPSocket>(); peer->opaque = this; peer->Close += sdelegate(this, &TCPConnectionPair::onConnectionClosed); // Start receiving early media peer->Recv += sdelegate(this, &TCPConnectionPair::onPeerDataReceived); // Connect request specific events peer->Connect += sdelegate(this, &TCPConnectionPair::onPeerConnectSuccess); peer->Error += sdelegate(this, &TCPConnectionPair::onPeerConnectError); client->connect(peerAddr); } catch (std::exception& exc) { ErrorLS(this) << "Peer connect error: " << exc.what() << endl; assert(0); return false; } return true; }
bool RecordingMode::activate() { DebugL << "Activating" << endl; try { env().media().RecordingStopped += sdelegate(this, &RecordingMode::onRecordingStopped); startRecording(); _isActive = true; } catch (std::exception& exc) { _error = std::string(exc.what()); ErrorL << "Activation error: " << _error << endl; return false; } return true; }
void run(const Client::Options& o, int times, int timeout) { //if (timeout) // Timer::getDefault().start(TimerCallback<ClientTestRunner>(this, &ClientTestRunner::onTimeout, timeout)); nTimes = times; for (int i = 0; i < nTimes; i++) { auto client = new turn::ClientTest(i, o); //, reactor, runner client->initiator->TestComplete += sdelegate(this, &ClientTestRunner::onTestComplete); client->run(); tests.push_back(client); } //done.wait(); }
void runUDPSocketTest() { // Notes: Sending over home wireless network via // ADSL to US server round trip stays around 200ms // when sending 1450kb packets at 50ms intervals. // At 40ms send intervals latency increated to around 400ms. TraceL << "UDP Socket Test: Starting" << endl; //UDPPacketSize = 10000; UDPPacketSize = 1450; UDPNumPacketsWanted = 100; UDPNumPacketsReceived = 0; //serverBindAddr.swap(net::Address("0.0.0.0", 1337)); // udpServerAddr.swap(net::Address("74.207.248.97", 1337)); // //udpServerAddr.swap(net::Address("127.0.0.1", 1337)); // //clientBindAddr.swap(net::Address("0.0.0.0", 1338)); //clientSendAddr.swap(net::Address("58.7.41.244", 1337)); // //clientSendAddr.swap(net::Address("127.0.0.1", 1337)); // //net::UDPSocket serverSock; //serverSock.Recv += sdelegate(this, &Tests::onUDPSocketServerRecv); //serverSock.bind(serverBindAddr); //this->serverSock = &serverSock; net::UDPSocket clientSock; //clientSock.Recv += sdelegate(this, &Tests::onUDPClientSocketRecv); assert(0 && "fixme"); clientSock.bind(net::Address("0.0.0.0", 0)); clientSock.connect(udpServerAddr); this->udpClientSock = &clientSock; //for (unsigned i = 0; i < UDPNumPacketsWanted; i++) // clientSock.send("bounce", 6, serverBindAddr); // Start the send timer Timer timer; timer.Timeout += sdelegate(this, &Tests::onUDPClientSendTimer); timer.start(50, 50); timer.handle().ref(); runLoop(); //this->serverSock = nullptr; this->udpClientSock = nullptr; }
void StreamManager::closeAll() { Mutex::ScopedLock lock(_mutex); DebugL << "Close all streams: " << _map.size() << endl; StreamManager::Map::iterator it = _map.begin(); StreamManager::Map::iterator it2; while (it != _map.end()) { it2 = it++; (*it2).second->StateChange -= sdelegate(this, &StreamManager::onStreamStateChange); (*it2).second->close(); if (_freeClosedStreams) { StreamManager::Deleter func; func((*it2).second); } _map.erase(it2); } }
void TCPClient::handleConnectionBindResponse(const stun::Message& response) { TraceL << "ConnectionBind success response" << endl; auto transaction = reinterpret_cast<stun::Transaction*>(response.opaque); auto req = reinterpret_cast<RelayConnectionBinding*>(transaction->socket->opaque); auto conn = connections().get(req->peerAddress, nullptr); if (!conn) { assert(0); return; } // Data will now be transferred as-is to and from the peer. conn->Recv += sdelegate(this, &TCPClient::onRelayDataReceived); _observer.onRelayConnectionCreated(*this, conn, req->peerAddress); TraceL << "ConnectionBind success response: OK" << endl; }
void StreamManager::onStreamStateChange(void* sender, PacketStreamState& state, const PacketStreamState&) { DebugL << "Stream state change: " << state << endl; // Cantch stream closed state and free it if necessary if (state.equals(PacketStreamState::Closed)) { PacketStream* stream = reinterpret_cast<PacketStream*>(sender); stream->StateChange -= sdelegate(this, &StreamManager::onStreamStateChange); bool success = false; if (_freeClosedStreams) { DebugL << "On stream close: freeing: " << stream->name() << endl; success = Manager::free(stream->name()); } else { DebugL << "On stream close: removing: " << stream->name() << endl; success = !!Manager::remove(stream->name()); } if (!success) { WarnL << "Cannot remove stream: " << stream->name() << endl; assert(0); } } }
void TCPClient::onRelayConnectionConnect(void* sender) { TraceL << "onRelayConnectionConnect" << endl; auto conn =reinterpret_cast<net::Socket*>(sender); conn->Connect -= sdelegate(this, &TCPClient::onRelayConnectionConnect); auto req = reinterpret_cast<RelayConnectionBinding*>(conn->opaque); assert(connections().has(req->peerAddress)); // TODO: How to get peerAddress here? //net::TCPSocket& socket = _connections.get(peerAddress, conn); auto transaction = createTransaction(connections().get(req->peerAddress)); transaction->request().setClass(stun::Message::Request); transaction->request().setMethod(stun::Message::ConnectionBind); auto connAttr = new stun::ConnectionID; connAttr->setValue(req->connectionID); transaction->request().add(connAttr); //assert(transaction->socket() == &conn); sendAuthenticatedTransaction(transaction); }
TCPConnectionPair::~TCPConnectionPair() { TraceLS(this) << "Destroy: " << connectionID << endl; if (client) { //assert(client->base().refCount() == 2); client->Recv -= sdelegate(this, &TCPConnectionPair::onClientDataReceived); client->Close -= sdelegate(this, &TCPConnectionPair::onConnectionClosed); client->close(); } if (peer) { //assert(peer->base().refCount() == 1); peer->Recv -= sdelegate(this, &TCPConnectionPair::onPeerDataReceived); peer->Connect -= sdelegate(this, &TCPConnectionPair::onPeerConnectSuccess); peer->Error -= sdelegate(this, &TCPConnectionPair::onPeerConnectError); peer->Close -= sdelegate(this, &TCPConnectionPair::onConnectionClosed); peer->close(); } assert(allocation.pairs().exists(connectionID)); allocation.pairs().remove(connectionID); }
UDPAllocation::~UDPAllocation() { TraceL << "Destroy" << endl; _relaySocket.Recv -= sdelegate(this, &UDPAllocation::onPeerDataReceived); _relaySocket.close(); }
void StreamManager::onRemove(PacketStream* stream) { DebugL << "stream removed: " << stream->name() << endl; stream->StateChange -= sdelegate(this, &StreamManager::onStreamStateChange); }