Exemple #1
0
void SSLAdapter::flush() 
{
    //TraceL << "Flushing" << endl;

    if (!initialized()) {
        int r = SSL_connect(_ssl);
        if (r < 0) {
            TraceL << "Flush: Handle error" << endl;
            handleError(r);
        }
        return;
    }
    
    // Read any decrypted SSL data from the read BIO
    // NOTE: Overwriting the socket's raw SSL recv buffer
    int nread = 0;
    while ((nread = SSL_read(_ssl, _socket->_buffer.data(), _socket->_buffer.capacity())) > 0) {
        //_socket->_buffer.limit(nread);
        _socket->onRecv(mutableBuffer(_socket->_buffer.data(), nread));
    }
    
    // Flush any pending outgoing data
    if (SSL_is_init_finished(_ssl)) { 
        if (_bufferOut.size() > 0) {
            int r = SSL_write(_ssl, &_bufferOut[0], _bufferOut.size()); // causes the write_bio to fill up (which we need to flush)
            if (r < 0) {
                handleError(r);
            }
            _bufferOut.clear();
            flushWriteBIO();
        }
    }
}
void ConnectionAdapter::onParserChunk(const char* buf, std::size_t len)
{
    TraceS(this) << "On parser chunk: " << len << endl;

    // Dispatch the payload
    net::SocketAdapter::onSocketRecv(mutableBuffer(const_cast<char*>(buf), len),
        _connection.socket()->peerAddress());
}
Exemple #3
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 #4
0
void SSLAdapter::flushReadBIO()
{
    int npending = BIO_ctrl_pending(_readBIO);
    if (npending > 0) {
        int nread;
        char buffer[MAX_TCP_PACKET_SIZE]; // TODO: allocate npending bytes
        while ((nread = SSL_read(_ssl, buffer, MAX_TCP_PACKET_SIZE)) > 0) {
            _socket->onRecv(mutableBuffer(buffer, nread));
        }
    }
}
void UDPSocket::onRecv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned /* flags */) 
{    
    auto socket = static_cast<UDPSocket*>(handle->data);
    TraceL << "On recv: " << nread << endl;
            
    if (nread < 0) {
        //assert(0 && "unexpected error");    
        TraceL << "Recv error: " << uv_err_name(nread)<< endl;
        socket->setUVError("UDP error", nread);
        return;
    }
    
    if (nread == 0) {
        assert(addr == NULL);
        // Returning unused buffer, this is not an error
        // 11/12/13: This happens on linux but not windows
        //socket->setUVError("End of file", UV_EOF);
        return;
    }
    
    socket->onRecv(mutableBuffer(buf->base, nread), net::Address(addr, sizeof(*addr)));
}
Exemple #6
0
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;
	}	
}