/* */ #include "PeerConnection.h" #include "message.h" #include "DlAbortEx.h" #include "PeerMessageUtil.h" #include "Util.h" #include "LogFactory.h" #include "BtHandshakeMessage.h" #include "a2netcompat.h" PeerConnection::PeerConnection(int32_t cuid, const SocketHandle& socket, const Option* op) :cuid(cuid), socket(socket), option(op), logger(LogFactory::getInstance()), resbufLength(0), currentPayloadLength(0), lenbufLength(0) { //logger->debug("PeerConnection::instantiated"); } PeerConnection::~PeerConnection() { //logger->debug("PeerConnection::deleted"); } int32_t PeerConnection::sendMessage(const unsigned char* data, int32_t dataLength) { int32_t writtenLength = 0; if(socket->isWritable(0)) { // TODO fix this socket->writeData((const char*)data, dataLength); writtenLength += dataLength; } return writtenLength; } bool PeerConnection::receiveMessage(unsigned char* data, int32_t& dataLength) { if(!socket->isReadable(0)) { return false; } if(resbufLength == 0 && lenbufLength != 4) { // read payload size, 4-byte integer int32_t remain = 4-lenbufLength; int32_t temp = remain; // TODO fix this socket->readData((char*)lenbuf+lenbufLength, temp); if(temp == 0) { // we got EOF throw new DlAbortEx(EX_EOF_FROM_PEER); } if(remain != temp) { // still 4-temp bytes to go lenbufLength += temp; return false; } //payloadLen = ntohl(nPayloadLen); int32_t payloadLength = ntohl(*((int32_t*)lenbuf)); if(payloadLength > MAX_PAYLOAD_LEN || payloadLength < 0) { throw new DlAbortEx(EX_TOO_LONG_PAYLOAD, payloadLength); } currentPayloadLength = payloadLength; } if(!socket->isReadable(0)) { return false; } // we have currentPayloadLen-resbufLen bytes to read int32_t remaining = currentPayloadLength-resbufLength; if(remaining > 0) { socket->readData((char*)resbuf+resbufLength, remaining); if(remaining == 0) { // we got EOF throw new DlAbortEx(EX_EOF_FROM_PEER); } resbufLength += remaining; if(currentPayloadLength != resbufLength) { return false; } } // we got whole payload. resbufLength = 0; lenbufLength = 0; memcpy(data, resbuf, currentPayloadLength); dataLength = currentPayloadLength; return true; } bool PeerConnection::receiveHandshake(unsigned char* data, int32_t& dataLength, bool peek) { int32_t remain = BtHandshakeMessage::MESSAGE_LENGTH-resbufLength; if(remain != 0 && !socket->isReadable(0)) { dataLength = 0; return false; } int32_t temp = remain; if(remain != 0) { socket->readData((char*)resbuf+resbufLength, temp); if(temp == 0) { // we got EOF throw new DlAbortEx(EX_EOF_FROM_PEER); } } bool retval; if(remain != temp) { retval = false; } else { retval = true; } resbufLength += temp; int32_t writeLength = resbufLength > dataLength ? dataLength : resbufLength; memcpy(data, resbuf, writeLength); dataLength = writeLength; if(retval && !peek) { resbufLength = 0; } return retval; }