// static
LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
{
	if (!listen_socket->getSocket())
	{
		status = APR_ENOSOCKET;
		return LLSocket::ptr_t();
	}
	LLSocket::ptr_t rv(new LLSocket);
	LL_DEBUGS() << "accepting socket" << LL_ENDL;
	status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool());
	if (status != APR_SUCCESS)
	{
		rv->mSocket = NULL;
		rv.reset();
		return rv;
	}
	rv->mPort = PORT_EPHEMERAL;
	rv->setNonBlocking();
	return rv;
}
Exemple #2
0
// static
LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
{
	LLMemType m1(LLMemType::MTYPE_IO_TCP);
	if (!listen_socket->getSocket())
	{
		status = APR_ENOSOCKET;
		return LLSocket::ptr_t();
	}
	LLSocket::ptr_t rv(new LLSocket);
	lldebugs << "accepting socket" << llendl;
	status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool());
	if (status != APR_SUCCESS)
	{
		rv->mSocket = NULL;
		rv.reset();
		return rv;
	}
	rv->mPort = PORT_EPHEMERAL;
	rv->setNonBlocking();
	return rv;
}
Exemple #3
0
/**
 * @brief Send one TCP packet and receive one in return.
 *
 * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking
 * operation would impact the operation of the viewer.
 *
 * @param handle_ptr 	Pointer to a connected LLSocket of type STREAM_TCP.
 * @param dataout		Data to send.
 * @param outlen		Length of dataout.
 * @param datain		Buffer for received data. Undefined if return value is not APR_SUCCESS.
 * @param maxinlen		Maximum possible length of received data.  Short reads are allowed.
 * @return 				Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
 */
static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
{
	apr_socket_t* apr_socket = handle->getSocket();
	apr_status_t rv = APR_SUCCESS;

	apr_size_t expected_len = outlen;

	handle->setBlocking(1000);

  	rv = apr_socket_send(apr_socket, dataout, &outlen);
	if (APR_SUCCESS != rv)
	{
		LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL;
		ll_apr_warn_status(rv);
	}
	else if (expected_len != outlen)
	{
		LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len <<
				" Sent: " << outlen << LL_ENDL;
		rv = -1;
	}

	if (APR_SUCCESS == rv)
	{
		expected_len = maxinlen;
		rv = apr_socket_recv(apr_socket, datain, &maxinlen);
		if (rv != APR_SUCCESS)
		{
			LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
			ll_apr_warn_status(rv);
		}
		else if (expected_len < maxinlen)
		{
			LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len <<
					" Received: " << maxinlen << LL_ENDL;
			rv = -1;
		}
	}

	handle->setNonBlocking();

	return rv;
}