void Application::finalize() { DebugLS(this) << "Finalizing" << std::endl; #ifdef _DEBUG // Print active handles uv_walk(loop, Application::onPrintHandle, nullptr); #endif // Shutdown the garbage collector to free memory GarbageCollector::destroy(); // Run until handles are closed run(); assert(loop->active_handles == 0); //assert(loop->active_reqs == 0); DebugLS(this) << "Finalization complete" << std::endl; }
void Application::onShutdownSignal(uv_signal_t* req, int /* signum */) { auto cmd = reinterpret_cast<internal::ShutdownCmd*>(req->data); DebugLS(cmd->self) << "Got shutdown signal" << std::endl; uv_close((uv_handle_t*)req, [](uv_handle_t* handle) { delete handle; }); if (cmd->callback) cmd->callback(cmd->opaque); delete cmd; }
void TCPConnectionPair::onPeerDataReceived(void*, const MutableBuffer& buffer, const net::Address& peerAddress) { TraceLS(this) << "Peer => Client: " << buffer.size() << endl; //assert(pkt.buffer.position() == 0); //if (pkt.buffer.available() < 300) // TraceLS(this) << "Peer => Client: " << pkt.buffer << endl; //auto socket = reinterpret_cast<net::Socket*>(sender); //char* buf = bufferCast<char*>(buf); //Buffer& buf = pkt.buffer; const char* buf = bufferCast<const char*>(buffer); std::size_t len = buffer.size(); if (client) { allocation.updateUsage(len); if (allocation.deleted()) return; //assert(buf.position() == 0); client->send(buf, len); } // Flash policy requests // TODO: Handle elsewhere? Bloody flash... else if (len == 23 && (strcmp(buf, "<policy-file-request/>") == 0)) { TraceLS(this) << "Handle flash policy" << endl; std::string policy("<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>"); //assert(peer->get() == pkt.info->socket); peer->send(policy.c_str(), policy.length() + 1); peer->close(); } // Buffer early media // TODO: Make buffer size server option else { size_t maxSize = allocation.server().options().earlyMediaBufferSize; DebugLS(this) << "Buffering early data: " << len << endl; //#ifdef _DEBUG // DebugLS(this) << "Printing early data: " << std::string(buf, len) << endl; //#endif if (len > maxSize) WarnL << "Dropping early media: Oversize packet: " << len << endl; if (earlyPeerData.size() > maxSize) WarnL << "Dropping early media: Buffer at capacity >= " << maxSize << endl; //earlyPeerData.append(static_cast<const char*>(pkt.data()), len); earlyPeerData.insert(earlyPeerData.end(), buf, buf + len); } }
void Application::waitForShutdown(std::function<void(void*)> callback, void* opaque) { auto cmd = new internal::ShutdownCmd; cmd->self = this; cmd->opaque = opaque; cmd->callback = callback; auto sig = new uv_signal_t; sig->data = cmd; uv_signal_init(loop, sig); uv_signal_start(sig, Application::onShutdownSignal, SIGINT); DebugLS(this) << "Wait for shutdown" << std::endl; run(); }
Application::~Application() { DebugLS(this) << "Destroy" << std::endl; }
Application::Application(uv::Loop* loop) : loop(loop) { DebugLS(this) << "Create" << std::endl; }
void onServerAllocationRemoved(Server* server, IAllocation* alloc) { DebugLS(this) << "Allocation removed" << endl; }
StreamingOptions::StreamingOptions(MediaServer* server, av::VideoCapture::Ptr videoCapture, av::AudioCapture::Ptr audioCapture) : server(server), videoCapture(videoCapture), audioCapture(audioCapture) { DebugLS(this) << "Destroy" << endl; }
void onAllocationPermissionsCreated(turn::Client& client, const turn::PermissionList& permissions) { DebugLS(this) << "Permissions Created" << endl; }
void onRelayConnectionDataReceived(turn::Client& client, const char* data, std::size_t size, const net::Address& peerAddr) { DebugLS(this) << "Received Data: " << std::string(data, size) << ": " << peerAddr << endl; }
void onRelayConnectionClosed(TCPClient& client, const net::TCPSocket::Ptr& socket, const net::Address& peerAddr) { DebugLS(this) << "Connection Closed" << endl; }
void onRelayConnectionCreated(TCPClient& client, const net::TCPSocket::Ptr& socket, const net::Address& peerAddr) //UInt32 connectionID, { DebugLS(this) << "Relay Connection Created: " << peerAddr << endl; }
void onTimer(TCPClient& client) { DebugLS(this) << "onTimer" << endl; }
void onClientStateChange(turn::Client& client, turn::ClientState& state, const turn::ClientState&) { DebugLS(this) << "State change: " << state.toString() << endl; }
StreamingOptions::~StreamingOptions() { DebugLS(this) << "Destroy" << endl; }
void WebSocketAdapter::onSocketRecv(const MutableBuffer& buffer, const net::Address& peerAddress) { TraceLS(this) << "On recv: " << buffer.size() << endl; // << ": " << buffer //assert(buffer.position() == 0); if (framer.handshakeComplete()) { // Note: The spec wants us to buffer partial frames, but our // software does not require this feature, and furthermore // it goes against our nocopy where possible policy. // This may need to change in the future, but for now // we just parse and emit packets as they arrive. // // Incoming frames may be joined, so we parse them // in a loop until the read buffer is empty. BitReader reader(buffer); int total = reader.available(); int offset = reader.position(); while (offset < total) { char* payload = nullptr; UInt64 payloadLength = 0; try { // Restore buffer state for next read //reader.position(offset); //reader.limit(total); #if 0 TraceLS(this) << "Read frame at: " << "\n\tinputPosition: " << offset << "\n\tinputLength: " << total << "\n\tbufferPosition: " << reader.position() << "\n\tbufferAvailable: " << reader.available() << "\n\tbufferLimit: " << reader.limit() << "\n\tbuffer: " << std::string(reader.current(), reader.limit()) << endl; #endif // Parse a frame to throw //int payloadLength = framer.readFrame(reader); payloadLength = framer.readFrame(reader, payload); assert(payload); // Update the next frame offset offset = reader.position(); // + payloadLength; if (offset < total) DebugLS(this) << "Splitting joined packet at " << offset << " of " << total << endl; // Drop empty packets if (!payloadLength) { DebugLS(this) << "Dropping empty frame" << endl; continue; } } catch (std::exception& exc) { WarnL << "Parser error: " << exc.what() << endl; socket->setError(exc.what()); return; } // Emit the result packet assert(payload); assert(payloadLength); SocketAdapter::onSocketRecv(mutableBuffer(payload, (std::size_t)payloadLength), peerAddress); } assert(offset == total); } else { try { if (framer.mode() == ws::ClientSide) handleClientResponse(buffer); else handleServerRequest(buffer); } catch (std::exception& exc) { WarnL << "Read error: " << exc.what() << endl; socket->setError(exc.what()); } return; } }
void TCPSocket::onError(const scy::Error& error) { DebugLS(this) << "Error: " << error.message << endl; onSocketError(error); close(); // close on error }
void onServerAllocationCreated(Server* server, IAllocation* alloc) { DebugLS(this) << "Allocation created" << endl; }