Exemple #1
0
void AudioCapture::attach(const PacketDelegateBase& delegate)
{
    PacketSignal::attach(delegate);
    TraceLS(this) << "Added Delegate: " << refCount() << endl;
    if (refCount() == 1)
        start();
}
void TCPConnectionPair::onPeerConnectError(void* sender, const Error& error)
{
	TraceLS(this) << "Peer Connect request error: " << error.message << endl;	
	assert(sender == &peer);
	allocation.sendPeerConnectResponse(this, false);

	// The TCPConnectionPair will be deleted on next call to onConnectionClosed
}
Exemple #3
0
SSLSocket::SSLSocket(SSLContext::Ptr context, SSLSession::Ptr session, uv::Loop* loop) : 
    TCPSocket(loop),
    _context(context), 
    _session(session), 
    _sslAdapter(this)
{
    TraceLS(this) << "Create" << endl;
}
Exemple #4
0
SSLAdapter::~SSLAdapter() 
{    
    TraceLS(this) << "Destroy" << endl;
    if (_ssl) {
        SSL_free(_ssl);
        _ssl = nullptr;
    }
}
Exemple #5
0
void WebSocketAdapter::handleClientResponse(const MutableBuffer& buffer)
{
	TraceLS(this) << "Client response: " << buffer.size() << endl;
	http::Parser parser(&_response);
	if (!parser.parse(bufferCast<char *>(buffer), buffer.size())) {
		throw std::runtime_error("WebSocket error: Cannot parse response: Incomplete HTTP message");
	}
	
	// TODO: Handle resending request for authentication
	// Should we implement some king of callback for this?

	// Parse and check the response
	if (framer.checkHandshakeResponse(_response)) {				
		TraceLS(this) << "Handshake success" << endl;
		SocketAdapter::onSocketConnect();
	}			
}
Exemple #6
0
void AudioCapture::close()
{
    TraceLS(this) << "Closing" << endl;
    try {
        Mutex::ScopedLock lock(_mutex);
        _opened = false;
        if (_audio.isStreamOpen())
            _audio.closeStream();
        TraceLS(this) << "Closing: OK" << endl;
    }
    catch (RtAudioError& e) {
        setError("Cannot close audio capture: " + e.getMessage());
    }
    catch (...) {
        setError("Cannot close audio capture.");
    }
}
Exemple #7
0
WebSocketAdapter::WebSocketAdapter(const net::Socket::Ptr& socket, ws::Mode mode, http::Request& request, http::Response& response) : 
	SocketAdapter(socket.get()), socket(socket), framer(mode), _request(request), _response(response)
{
	TraceLS(this) << "Create" << endl;
	
	//setSendAdapter(socket.get());
	socket->addReceiver(this);
}
Exemple #8
0
void SSLSocket::onRead(const char* data, std::size_t len)
{
    TraceLS(this) << "On SSL read: " << len << endl;

    // SSL encrypted data is sent to the SSL conetext
    _sslAdapter.addIncomingData(data, len);
    _sslAdapter.flush();
}
Exemple #9
0
SSLAdapter::SSLAdapter(net::SSLSocket* socket) :
    _socket(socket),
    _ssl(nullptr),
    _readBIO(nullptr),
    _writeBIO(nullptr)
{
    TraceLS(this) << "Create" << endl;
}
TCPConnectionPair::TCPConnectionPair(TCPAllocation& allocation) :
	allocation(allocation), client(nullptr), peer(nullptr), earlyPeerData(0),
	connectionID(util::randomNumber()), isDataConnection(false)
{		
	while (!allocation.pairs().add(connectionID, this, false)) {
		connectionID = util::randomNumber();
	}
	TraceLS(this) << "Create: " << connectionID << endl;	
}
Exemple #11
0
void TCPSocket::connect(const net::Address& peerAddress) 
{
    TraceLS(this) << "Connecting to " << peerAddress << endl;
    init();
    auto req = new uv_connect_t;
    req->data = this;
    int r = uv_tcp_connect(req, ptr<uv_tcp_t>(), peerAddress.addr(), internal::onConnect);
    if (r) setAndThrowError("TCP connect failed", r);
}
Exemple #12
0
std::size_t WebSocketFramer::writeFrame(const char* data, std::size_t len, int flags, BitWriter& frame)
{
	assert(flags == ws::SendFlags::Text || 
		flags == ws::SendFlags::Binary);	
	assert(frame.position() == 0);
	//assert(frame.limit() >= std::size_t(len + MAX_HEADER_LENGTH));
			
	frame.putU8(static_cast<UInt8>(flags));
	UInt8 lenByte(0);
	if (_maskPayload) {
		lenByte |= FRAME_FLAG_MASK;
	}
	if (len < 126) {
		lenByte |= static_cast<UInt8>(len);
		frame.putU8(lenByte);
	}
	else if (len < 65536) {
		lenByte |= 126;
		frame.putU8(lenByte);
		frame.putU16(static_cast<UInt16>(len));
	}
	else {
		lenByte |= 127;
		frame.putU8(lenByte);
		frame.putU64(static_cast<UInt16>(len));
	}	

	if (_maskPayload) {
		auto mask = _rnd.next();
		auto m = reinterpret_cast<const char*>(&mask);
		auto b = reinterpret_cast<const char*>(data);
		frame.put(m, 4);
		//auto p = frame.current();
		for (unsigned i = 0; i < len; i++) {
			//p[i] = b[i] ^ m[i % 4];
			frame.putU8(b[i] ^ m[i % 4]);
		}
	}
	else {
		//memcpy(frame.current(), data, len); // offset?
		frame.put(data, len);
	}
	
	// Update frame length to include payload plus header
	//frame.skip(len);

#if 0
	TraceLS(this) << "Write frame: " 
		 << "\n\tinputLength: " << len
		 << "\n\tframePosition: " << frame.position() 
		 << "\n\tframeLimit: " << frame.limit() 
		 << "\n\tframeAvailable: " << frame.available() 
		 << endl;
#endif

	return frame.position();
}
Exemple #13
0
void TCPSocket::onRead(const char* data, std::size_t len)
{
    TraceLS(this) << "On read: " << len << endl;

    // Note: The const_cast here is relatively safe since the given 
    // data pointer is the underlying _buffer.data() pointer, but
    // a better way should be devised.
    onRecv(mutableBuffer(const_cast<char*>(data), len));
}
Exemple #14
0
void TCPSocket::onAcceptConnection(uv_stream_t*, int status) 
{        
    if (status == 0) {
        TraceLS(this) << "On accept connection" << endl;
        acceptConnection();
    }
    else
        ErrorLS(this) << "Accept connection failed" << endl;
}
Exemple #15
0
SSLSocket::SSLSocket(uv::Loop* loop) : 
    TCPSocket(loop),
    // TODO: Using client context, should assert no bind()/listen() on this socket
    _context(SSLManager::instance().defaultClientContext()), 
    _session(nullptr), 
    _sslAdapter(this)
{
    TraceLS(this) << "Create" << endl;
}
Exemple #16
0
void WebSocketAdapter::onSocketConnect()
{
	TraceLS(this) << "On connect" << endl;
	
	// Send the WS handshake request
	// The Connect signal will be sent after the 
	// handshake is complete
	sendClientRequest();
}
Exemple #17
0
void SSLAdapter::init(SSL* ssl) 
{
    TraceLS(this) << "Init: " << ssl << endl;
    assert(_socket);
    //assert(_socket->initialized());
    _ssl = ssl;
    _readBIO = BIO_new(BIO_s_mem());
    _writeBIO = BIO_new(BIO_s_mem());
    SSL_set_bio(_ssl, _readBIO, _writeBIO);
}
Exemple #18
0
void AudioCapture::stop()
{
    TraceLS(this) << "Stopping" << endl;

    if (running()) {
        try {
            Mutex::ScopedLock lock(_mutex);
            TraceLS(this) << "Stopping: Before" << endl;
            _audio.stopStream();
            TraceLS(this) << "Stopping: OK" << endl;
        }
        catch (RtAudioError& e) {
            setError("Cannot stop audio capture: " + e.getMessage());
        }
        catch (...) {
            setError("Cannot stop audio capture.");
        }
    }
}
Exemple #19
0
void AudioCapture::start()
{
    TraceLS(this) << "Starting" << endl;

    if (!running()) {
        try {
            Mutex::ScopedLock lock(_mutex);
            _audio.startStream();
            _error = "";
            TraceLS(this) << "Starting: OK" << endl;
        }
        catch (RtAudioError& e) {
            setError("Cannot start audio capture: " + e.getMessage());
        }
        catch (...) {
            setError("Cannot start audio capture.");
        }
    }
}
Exemple #20
0
bool SSLSocket::shutdown()
{
    TraceLS(this) << "Shutdown" << endl;
    try {
        // Try to gracefully shutdown the SSL connection
        _sslAdapter.shutdown();
    }
    catch (...) {}
    return TCPSocket::shutdown();
}
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
}
Exemple #22
0
void TCPSocket::acceptConnection()
{
    // Create the shared socket pointer;
    // if it is not handled it will be destroyed.
    // TODO: Allow accepted sockets to use different event loops.
    auto socket = net::makeSocket<net::TCPSocket>(loop()); //std::make_shared<net::TCPSocket>(this->loop());
    TraceLS(this) << "Accept connection: " << socket->ptr() << endl;
    uv_accept(ptr<uv_stream_t>(), socket->ptr<uv_stream_t>()); // uv_accept should always work
    socket->readStart();        
    AcceptConnection.emit(Socket::self(), socket);
}
Exemple #23
0
int AudioCapture::audioCallback(void* /* outputBuffer */, void* inputBuffer, unsigned int nBufferFrames,
                                double streamTime, RtAudioStreamStatus status, void* data)
{
    AudioCapture* self = (AudioCapture*)data;
    AudioPacket packet;

    if (status)
        ErrorL << "Stream over/underflow detected" << endl;

    assert(inputBuffer);
    if (inputBuffer == nullptr) {
        ErrorL << "Input buffer is nullptr." << endl;
        return 2;
    }

    {
        Mutex::ScopedLock lock(self->_mutex);

        int size = 2;
        RtAudioFormat format = self->_format;
        // 8-bit signed integer.
        if (format == RTAUDIO_SINT8)
            size = 1;
        // 16-bit signed integer.
        else if (format == RTAUDIO_SINT16)
            size = 2;
        // Lower 3 bytes of 32-bit signed integer.
        else if (format == RTAUDIO_SINT24)
            size = 4;
        // 32-bit signed integer.
        else if (format == RTAUDIO_SINT32)
            size = 4;
        // Normalized between plus/minus 1.0.
        else if (format == RTAUDIO_FLOAT32)
            size = 4;
        // Normalized between plus/minus 1.0.
        else if (format == RTAUDIO_FLOAT64)
            size = 8;
        else assert(0 && "unknown audio capture format");

        packet.setData((char*)inputBuffer, nBufferFrames * self->_channels * size);
        packet.time = streamTime;
    }

    // TraceL << "Captured audio packet: "
    //      << "\n\tPacket Ptr: " << inputBuffer
    //      << "\n\tPacket Size: " << packet.size()
    //      << "\n\tStream Time: " << packet.time
    //      << endl;

    TraceLS(self) << "Emitting: " << packet.time << std::endl;
    self->emit(packet);
    return 0;
}
Exemple #24
0
void WebSocketAdapter::sendClientRequest()
{
	framer.createHandshakeRequest(_request);

	std::ostringstream oss;
	_request.write(oss);
	TraceLS(this) << "Client request: " << oss.str() << endl;
	
	assert(socket);
	/*socket->*/SocketAdapter::send(oss.str().c_str(), oss.str().length());
}
Exemple #25
0
void SSLAdapter::shutdown()
{
    TraceLS(this) << "Shutdown" << endl;
    if (_ssl) {        
        TraceLS(this) << "Shutdown SSL" << endl;

        // Don't shut down the socket more than once.
        int shutdownState = SSL_get_shutdown(_ssl);
        bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
        if (!shutdownSent) {
            // A proper clean shutdown would require us to
            // retry the shutdown if we get a zero return
            // value, until SSL_shutdown() returns 1.
            // However, this will lead to problems with
            // most web browsers, so we just set the shutdown
            // flag by calling SSL_shutdown() once and be
            // done with it.
            int rc = SSL_shutdown(_ssl);
            if (rc < 0) handleError(rc);
        }
    }
}
Exemple #26
0
void TCPSocket::init()
{
    if (ptr()) return;

    TraceLS(this) << "Init" << endl;
    auto tcp = new uv_tcp_t;
    tcp->data = this;
    _ptr = reinterpret_cast<uv_handle_t*>(tcp);
    _closed = false;
    _error.reset();
    int r = uv_tcp_init(loop(), tcp);
    if (r)
        setUVError("Cannot initialize TCP socket", r);
}
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);
}
void TCPConnectionPair::onClientDataReceived(void*, const MutableBuffer& buffer, const net::Address& peerAddress)
{
	TraceLS(this) << "Client => Peer: " << buffer.size() << endl;	
	//assert(packet.buffer.position() == 0);
	//if (packet.size() < 300)
	//	TraceLS(this) << "Client => Peer: " << packet.buffer << endl;	

	if (peer) {
		allocation.updateUsage(buffer.size());
		if (allocation.deleted())
			return;

		peer->send(bufferCast<char*>(buffer), buffer.size());
	}
}
Exemple #29
0
void TCPSocket::onConnect(uv_connect_t* handle, int status)
{
    TraceLS(this) << "On connect" << endl;
    
    // Error handled by static callback proxy
    if (status == 0) {
        if (readStart())
            onSocketConnect();
    }
    else {
        setUVError("Connection failed", status);    
        //ErrorLS(this) << "Connection failed: " << error().message << endl;
    }
    delete handle;
}
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
}