[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user asfgit closed the pull request at: https://github.com/apache/drill/pull/809 --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r117423249 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -234,6 +233,37 @@ void DrillClientImpl::Close() { } /* + * Write bytesToWrite length data bytes pointed by dataPtr. It handles EINTR error + * occurred during write_some sys call and does a retry on that. + * + * Parameters: + * dataPtr - in param - Pointer to data bytes to write on socket. + * bytesToWrite - in param - Length of data bytes to write from dataPtr. + * errorCode- out param - Error code set by boost. + */ +void DrillClientImpl::doWriteToSocket(const char* dataPtr, size_t bytesToWrite, +boost::system::error_code& errorCode) { +if(0 == bytesToWrite) { --- End diff -- Not really. Since write_some will set the proper error code in that case. The handing for `bytesToWrite == 0` was done since that's a success case and didn't want to call write_some on it. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r117423292 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -364,7 +395,41 @@ connectionStatus_t DrillClientImpl::recvHandshake(){ return CONN_SUCCESS; } -void DrillClientImpl::handleHandshake(ByteBuf_t _buf, +/* + * Read bytesToRead length data bytes from socket into inBuf. It handles EINTR error + * occurred during read_some sys call and does a retry on that. + * + * Parameters: + * inBuf- out param - Pointer to buffer to read data into from socket. + * bytesToRead - in param - Length of data bytes to read from socket. + * errorCode- out param - Error code set by boost. + */ +void DrillClientImpl::doReadFromSocket(ByteBuf_t inBuf, size_t bytesToRead, + boost::system::error_code& errorCode) { + +// Check if bytesToRead is zero +if(0 == bytesToRead) { --- End diff -- Same as above. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r117412544 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -364,7 +395,41 @@ connectionStatus_t DrillClientImpl::recvHandshake(){ return CONN_SUCCESS; } -void DrillClientImpl::handleHandshake(ByteBuf_t _buf, +/* + * Read bytesToRead length data bytes from socket into inBuf. It handles EINTR error + * occurred during read_some sys call and does a retry on that. + * + * Parameters: + * inBuf- out param - Pointer to buffer to read data into from socket. + * bytesToRead - in param - Length of data bytes to read from socket. + * errorCode- out param - Error code set by boost. + */ +void DrillClientImpl::doReadFromSocket(ByteBuf_t inBuf, size_t bytesToRead, + boost::system::error_code& errorCode) { + +// Check if bytesToRead is zero +if(0 == bytesToRead) { --- End diff -- Does a NULL inBuf have to be handled ? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r117412175 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -234,6 +233,37 @@ void DrillClientImpl::Close() { } /* + * Write bytesToWrite length data bytes pointed by dataPtr. It handles EINTR error + * occurred during write_some sys call and does a retry on that. + * + * Parameters: + * dataPtr - in param - Pointer to data bytes to write on socket. + * bytesToWrite - in param - Length of data bytes to write from dataPtr. + * errorCode- out param - Error code set by boost. + */ +void DrillClientImpl::doWriteToSocket(const char* dataPtr, size_t bytesToWrite, +boost::system::error_code& errorCode) { +if(0 == bytesToWrite) { --- End diff -- Should you check for a NULL dataPtr ? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115860398 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115614489 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115877434 --- Diff: contrib/native/client/src/clientlib/utils.cpp --- @@ -111,4 +111,52 @@ AllocatedBuffer::~AllocatedBuffer(){ m_bufSize = 0; } +EncryptionContext::EncryptionContext(const bool& encryptionReqd, const int& wrapChunkSize, const int& rawSendSize) { +this->m_bEncryptionReqd = encryptionReqd; +this->m_maxWrapChunkSize = wrapChunkSize; +this->m_rawWrapSendSize = rawSendSize; +} + +EncryptionContext::EncryptionContext() { +this->m_bEncryptionReqd = false; +// SASL Framework only allows 3 octet length field during negotiation so maximum wrap message +// length can be 16MB i.e. 0XFF --- End diff -- Nice catch!. I am changing it to be 65536 now based on recent findings. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115612998 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115557153 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); --- End diff -- _lengthDecoder_ is a function pointer signature that accepts function of DrillClientImpl class with that signature. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115532000 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or --- End diff -- Changed to "_lengthFieldLength_" as on Java side which is borrowed from LengthFieldBasedFrameDecoder --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115614854 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115527833 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -370,6 +453,33 @@ void DrillClientImpl::handleHShakeReadTimeout(const boost::system::error_code & return; } +/* + * Check's if client has explicitly expressed interest in encrypted connections only. It looks for USERPROP_ENCRYPTION + * connection string property. If set to true then returns true else returns false + */ +bool DrillClientImpl::clientNeedsEncryption(const DrillUserProperties* userProperties) { +bool needsEncryption = false; +// check if userProperties is null +if(!userProperties) { +return needsEncryption; +} + +// Loop through the property to find USERPROP_ENCRYPTION and it's value +for (size_t i = 0; i < userProperties->size(); i++) { --- End diff -- DrillUserProperties has a _map_ and a _vector_. The _vector_ stores the actual prop key/value pair and in _map_ we store the prop key and corresponding bits indicating _USERPROP_FLAGS_SERVERPROP|USERPROP_FLAGS_STRING_. This is later used in handshake message to filter out the properties passed by client and the one which is needed for server side to send along with handshake msg. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115612782 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) --- End diff -- Memory for bufferWithLenBytes is deallocated by caller. Added a comment in the function header. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r11119 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the --- End diff -- bufferWithLenBytes may not be a complete RPC Msg. Changed to _bufWithLen --> bufWithLenField_ and _bufferWithLenBytes --> bufWithDataAndLenBytes_ --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115530271 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -495,26 +612,45 @@ connectionStatus_t DrillClientImpl::handleAuthentication(const DrillUserProperti } } +std::stringstream errorMsg; --- End diff -- Fixed name and a bug where in success case with auth only it was printing wrong error message. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115861013 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114442242 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -245,6 +264,64 @@ connectionStatus_t DrillClientImpl::sendSync(rpc::OutBoundRpcMessage& msg){ } } +/* + * Send handler for sending encrypted messages over wire. It encrypts the send buffer using wrap api provided by + * saslAuthenticatorImpl and then transmit the encrypted bytes over wire. + * + * Return: + * connectionStatus_t - CONN_SUCCESS - In case of successful send + * - CONN_FAILURE - In case of failure to send + */ +connectionStatus_t DrillClientImpl::sendSyncEncrypted() { + +boost::system::error_code ec; + +// Split the encoded message into the rawWrapSendSize and then encrypt each chunk. Each encrypted chunk along with +// its encrypted length in network order (added by Cyrus-SASL plugin) is sent over wire. +const int wrapChunkSize = m_encryptionCtxt.getRawWrapSendSize(); +int numChunks = ceil((double)m_wbuf.size() / wrapChunkSize); --- End diff -- 'chunksRemaining' would be better a better name than 'numChunks' because the value is decremented per chunk --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114442866 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -245,6 +264,64 @@ connectionStatus_t DrillClientImpl::sendSync(rpc::OutBoundRpcMessage& msg){ } } +/* + * Send handler for sending encrypted messages over wire. It encrypts the send buffer using wrap api provided by + * saslAuthenticatorImpl and then transmit the encrypted bytes over wire. + * + * Return: + * connectionStatus_t - CONN_SUCCESS - In case of successful send + * - CONN_FAILURE - In case of failure to send + */ +connectionStatus_t DrillClientImpl::sendSyncEncrypted() { + +boost::system::error_code ec; + +// Split the encoded message into the rawWrapSendSize and then encrypt each chunk. Each encrypted chunk along with +// its encrypted length in network order (added by Cyrus-SASL plugin) is sent over wire. +const int wrapChunkSize = m_encryptionCtxt.getRawWrapSendSize(); +int numChunks = ceil((double)m_wbuf.size() / wrapChunkSize); +int lengthToEncrypt = m_wbuf.size(); +int currentChunkLen = std::min(wrapChunkSize, lengthToEncrypt); +uint32_t startIndex = 0, wrappedLen = 0; +const char* wrappedChunk = NULL; +std::stringstream errorMsg; + +// Encrypt and send each chunk +while(numChunks > 0) { +int wrapResult = m_saslAuthenticator->wrap(reinterpret_cast(m_wbuf.data() + startIndex), + currentChunkLen, &wrappedChunk, wrappedLen); +if(SASL_OK != wrapResult) { +errorMsg << "Sasl wrap failed while encrypting chunk of length: " << currentChunkLen << " , EncodeError: " + << wrapResult; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str() + << " ,StartIndex: " << startIndex << ". ChunkNum: " << numChunks + << ", Closing connection.";) +return handleConnError(CONN_FAILURE, getMessage(ERR_CONN_WFAIL, errorMsg.str().c_str())); +} + +// Send the encrypted chunk. +size_t s = m_socket.write_some(boost::asio::buffer(wrappedChunk, wrappedLen), ec); + +if(ec || s==0){ +errorMsg << "Failure while sending encrypted chunk. Error: " << ec.message().c_str(); +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str() << " Chunk:" --- End diff -- Did you want to print the chunk number or chunks remaining? ChunkNum should be Total chunks - Chunks Remaining. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114442367 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -245,6 +264,64 @@ connectionStatus_t DrillClientImpl::sendSync(rpc::OutBoundRpcMessage& msg){ } } +/* + * Send handler for sending encrypted messages over wire. It encrypts the send buffer using wrap api provided by + * saslAuthenticatorImpl and then transmit the encrypted bytes over wire. + * + * Return: + * connectionStatus_t - CONN_SUCCESS - In case of successful send + * - CONN_FAILURE - In case of failure to send + */ +connectionStatus_t DrillClientImpl::sendSyncEncrypted() { + +boost::system::error_code ec; + +// Split the encoded message into the rawWrapSendSize and then encrypt each chunk. Each encrypted chunk along with +// its encrypted length in network order (added by Cyrus-SASL plugin) is sent over wire. +const int wrapChunkSize = m_encryptionCtxt.getRawWrapSendSize(); +int numChunks = ceil((double)m_wbuf.size() / wrapChunkSize); +int lengthToEncrypt = m_wbuf.size(); +int currentChunkLen = std::min(wrapChunkSize, lengthToEncrypt); +uint32_t startIndex = 0, wrappedLen = 0; --- End diff -- "currentChunkOffset" would be a better name than 'startIndex'. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115370795 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115371963 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114442641 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -245,6 +264,64 @@ connectionStatus_t DrillClientImpl::sendSync(rpc::OutBoundRpcMessage& msg){ } } +/* + * Send handler for sending encrypted messages over wire. It encrypts the send buffer using wrap api provided by + * saslAuthenticatorImpl and then transmit the encrypted bytes over wire. + * + * Return: + * connectionStatus_t - CONN_SUCCESS - In case of successful send + * - CONN_FAILURE - In case of failure to send + */ +connectionStatus_t DrillClientImpl::sendSyncEncrypted() { + +boost::system::error_code ec; + +// Split the encoded message into the rawWrapSendSize and then encrypt each chunk. Each encrypted chunk along with +// its encrypted length in network order (added by Cyrus-SASL plugin) is sent over wire. +const int wrapChunkSize = m_encryptionCtxt.getRawWrapSendSize(); +int numChunks = ceil((double)m_wbuf.size() / wrapChunkSize); +int lengthToEncrypt = m_wbuf.size(); +int currentChunkLen = std::min(wrapChunkSize, lengthToEncrypt); +uint32_t startIndex = 0, wrappedLen = 0; +const char* wrappedChunk = NULL; +std::stringstream errorMsg; + +// Encrypt and send each chunk +while(numChunks > 0) { +int wrapResult = m_saslAuthenticator->wrap(reinterpret_cast(m_wbuf.data() + startIndex), + currentChunkLen, &wrappedChunk, wrappedLen); +if(SASL_OK != wrapResult) { +errorMsg << "Sasl wrap failed while encrypting chunk of length: " << currentChunkLen << " , EncodeError: " + << wrapResult; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str() + << " ,StartIndex: " << startIndex << ". ChunkNum: " << numChunks --- End diff -- Did you want to print the chunk number or chunks remaining? ChunkNum should be Total chunks - Chunks Remaining. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115369295 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; --- End diff -- Shouldn't EINTR (interrupted) be handled like a temporary failure, with a subsequent retry? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115371638 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114629588 --- Diff: contrib/native/client/src/clientlib/utils.cpp --- @@ -111,4 +111,52 @@ AllocatedBuffer::~AllocatedBuffer(){ m_bufSize = 0; } +EncryptionContext::EncryptionContext(const bool& encryptionReqd, const int& wrapChunkSize, const int& rawSendSize) { +this->m_bEncryptionReqd = encryptionReqd; +this->m_maxWrapChunkSize = wrapChunkSize; +this->m_rawWrapSendSize = rawSendSize; +} + +EncryptionContext::EncryptionContext() { +this->m_bEncryptionReqd = false; +// SASL Framework only allows 3 octet length field during negotiation so maximum wrap message +// length can be 16MB i.e. 0XFF --- End diff -- // so maximum wrap message length can be 16MB i.e. 0XFF Max maxWrapChunkSize has to be strictly less than 16MB. 0XFF = 16MB - 1 --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114775522 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -370,6 +453,33 @@ void DrillClientImpl::handleHShakeReadTimeout(const boost::system::error_code & return; } +/* + * Check's if client has explicitly expressed interest in encrypted connections only. It looks for USERPROP_ENCRYPTION + * connection string property. If set to true then returns true else returns false + */ +bool DrillClientImpl::clientNeedsEncryption(const DrillUserProperties* userProperties) { +bool needsEncryption = false; +// check if userProperties is null +if(!userProperties) { +return needsEncryption; +} + +// Loop through the property to find USERPROP_ENCRYPTION and it's value +for (size_t i = 0; i < userProperties->size(); i++) { --- End diff -- Not related to your change: I wonder why DrillUserProperties was not implemented as a map? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115369469 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) --- End diff -- what happens to memory allocated for bufferWithLenBytes on error? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114828323 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the --- End diff -- 'bufferWithLenBytes' this name is confusing given that there is already a 'bufWithLen'. How about something like 'bufWithRPCMsg'? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114818140 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); --- End diff -- What does it mean to access a local using the 'this' ptr? Can't this be written as bytes_read = (lengthDecodeHandler)(bufWithLen, rmsgLen); ? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114623038 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114778278 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -495,26 +612,45 @@ connectionStatus_t DrillClientImpl::handleAuthentication(const DrillUserProperti } } +std::stringstream errorMsg; --- End diff -- "logMsg" would be a better name than "errorMsg" because this is also used in a successful path. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r114828848 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or --- End diff -- How about 'bufWithLenSize'? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r115372156 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -854,75 +990,328 @@ void DrillClientImpl::waitForResults(){ } } -status_t DrillClientImpl::readMsg(ByteBuf_t _buf, -AllocatedBufferPtr* allocatedBuffer, +/* + * Decode the length of the message from bufWithLen and then read entire message from the socket. + * Parameters: + * bufWithLen - in param - buffer containing the bytes which has length of the RPC message/encrypted chunk + * bufferWithLenBytes - out param - buffer pointer which points to memory allocated in this function and has the + *entire one RPC message / encrypted chunk along with the length of the message + * lengthBytesLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or + *encrypted chunk + * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use + *lengthDecode and for plain RPC message we use rpcLengthDecode. + * Return: + * status_t- QRY_SUCCESS- In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error. + */ +status_t DrillClientImpl::readLenBytesFromSocket(ByteBuf_t bufWithLen, AllocatedBufferPtr* bufferWithLenBytes, + uint32_t& lengthBytesLength, lengthDecoder lengthDecodeHandler) { + +uint32_t rmsgLen = 0; +size_t bytes_read = 0; +size_t leftover = 0; +boost::system::error_code error; +*bufferWithLenBytes = NULL; +size_t bufferWithLenBytesSize = 0; + +bytes_read = (this->*lengthDecodeHandler)(bufWithLen, rmsgLen); +lengthBytesLength = bytes_read; + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << bytes_read << std::endl;) +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;) + +if(rmsgLen>0){ +leftover = LEN_PREFIX_BUFLEN - bytes_read; + +// Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes + bufferWithLenBytesSize = rmsgLen + bytes_read; +*bufferWithLenBytes = new AllocatedBuffer(bufferWithLenBytesSize); + +if(*bufferWithLenBytes == NULL){ +return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL); +} + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ " + << *bufferWithLenBytes << ", size = " << bufferWithLenBytesSize << " ]\n";) + +// Copy the memory of bufWithLen into bufferWithLenBytesSize +memcpy((*bufferWithLenBytes)->m_pBuffer, bufWithLen, LEN_PREFIX_BUFLEN); + +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. " + << "Now reading data (rmsgLen - leftover) : " << (rmsgLen - leftover) + << std::endl;) + +// Read the entire data left from socket and copy to currentBuffer. +ByteBuf_t b = (*bufferWithLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN; +size_t bytesToRead = rmsgLen - leftover; + +while(1){ +bytes_read = this->m_socket.read_some(boost::asio::buffer(b, bytesToRead), error); +if(error) break; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << bytes_read << std::endl;) +if(bytes_read == bytesToRead) break; +bytesToRead -= bytes_read; +b += bytes_read; +} +} else { +return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL); +} + +return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL) + : QRY_SUCCESS; +} + + +/* + * Function to read entire RPC message from socket and decode it to InboundRpcMessage + * Parameters: + * _buf- in param - Buffer containing the length bytes. + * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes. + * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer + * Return: + * status_t- QRY_SUCCESS - In case of success. + * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
Github user bitblender commented on a diff in the pull request: https://github.com/apache/drill/pull/809#discussion_r11272 --- Diff: contrib/native/client/src/clientlib/drillClientImpl.cpp --- @@ -245,6 +264,64 @@ connectionStatus_t DrillClientImpl::sendSync(rpc::OutBoundRpcMessage& msg){ } } +/* + * Send handler for sending encrypted messages over wire. It encrypts the send buffer using wrap api provided by + * saslAuthenticatorImpl and then transmit the encrypted bytes over wire. + * + * Return: + * connectionStatus_t - CONN_SUCCESS - In case of successful send + * - CONN_FAILURE - In case of failure to send + */ +connectionStatus_t DrillClientImpl::sendSyncEncrypted() { + +boost::system::error_code ec; + +// Split the encoded message into the rawWrapSendSize and then encrypt each chunk. Each encrypted chunk along with +// its encrypted length in network order (added by Cyrus-SASL plugin) is sent over wire. +const int wrapChunkSize = m_encryptionCtxt.getRawWrapSendSize(); +int numChunks = ceil((double)m_wbuf.size() / wrapChunkSize); +int lengthToEncrypt = m_wbuf.size(); +int currentChunkLen = std::min(wrapChunkSize, lengthToEncrypt); +uint32_t startIndex = 0, wrappedLen = 0; +const char* wrappedChunk = NULL; +std::stringstream errorMsg; + +// Encrypt and send each chunk +while(numChunks > 0) { +int wrapResult = m_saslAuthenticator->wrap(reinterpret_cast(m_wbuf.data() + startIndex), + currentChunkLen, &wrappedChunk, wrappedLen); +if(SASL_OK != wrapResult) { +errorMsg << "Sasl wrap failed while encrypting chunk of length: " << currentChunkLen << " , EncodeError: " + << wrapResult; +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str() + << " ,StartIndex: " << startIndex << ". ChunkNum: " << numChunks + << ", Closing connection.";) +return handleConnError(CONN_FAILURE, getMessage(ERR_CONN_WFAIL, errorMsg.str().c_str())); +} + +// Send the encrypted chunk. +size_t s = m_socket.write_some(boost::asio::buffer(wrappedChunk, wrappedLen), ec); + +if(ec || s==0){ +errorMsg << "Failure while sending encrypted chunk. Error: " << ec.message().c_str(); +DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str() << " Chunk:" + << numChunks << ", Original Length: " << currentChunkLen + << ", StartIndex:" << startIndex << ", Closing connection.";) +return handleConnError(CONN_FAILURE, getMessage(ERR_CONN_WFAIL, errorMsg.str().c_str())); --- End diff -- What happens to the memory allocated for wrappedChunk when this path is taken? Does handleConnError() deal with it ? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] drill pull request #809: Drill-4335: C++ client changes for supporting encry...
GitHub user sohami opened a pull request: https://github.com/apache/drill/pull/809 Drill-4335: C++ client changes for supporting encryption using SASL You can merge this pull request into a Git repository by running: $ git pull https://github.com/sohami/drill DRILL-4335-C++-04_06_2017 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/drill/pull/809.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #809 commit 96bef190ba17655ac07169e22ad5a9a3a3723261 Author: Sorabh Hamirwasia Date: 2017-03-06T08:19:50Z DRILL-4335: C++ Protocol changes commit a30905a6807b739e45b5c673597c7a16727155d7 Author: Sorabh Hamirwasia Date: 2017-03-06T08:21:10Z DRILL-4335: C++ changes to include initial encryption and decryption handler and refactor send/read handler commit ff112495c7ebb99ef9289af4de2085ac4422ff33 Author: Sorabh Hamirwasia Date: 2017-03-01T02:13:20Z DRILL-4335: Adding encryption connection parameter for C++ client commit d83b074b168402a10118c5ea76140652e9c97a8c Author: Sorabh Hamirwasia Date: 2017-04-03T07:26:54Z DRILL-4335: C++ adding auth support in querySubmitter commit 8b711ba72970b51f6d9766626f4c02ac92fcd296 Author: Sorabh Hamirwasia Date: 2017-03-06T19:27:12Z DRILL-4335: C++ side changes to take care of RFC-4422/ compatibility for interoperability with Cyrus-SASL --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---