void PacketTunnelIOGateway :: HandleIncomingMessage(AbstractGatewayMessageReceiver & receiver, const ByteBufferRef & buf, const IPAddressAndPort & fromIAP) { if (_slaveGateway()) { DataIORef oldIO = _slaveGateway()->GetDataIO(); // save slave gateway's old state _fakeReceiveIO.SetBuffer(buf); (void) _fakeReceiveIO.Seek(0, SeekableDataIO::IO_SEEK_SET); _slaveGateway()->SetDataIO(DataIORef(&_fakeReceiveIO, false)); uint32 slaveBytesRead = 0; while(slaveBytesRead < buf()->GetNumBytes()) { _scratchReceiver = &receiver; _scratchReceiverArg = (void *) &fromIAP; int32 nextBytesRead = _slaveGateway()->DoInput(*this, buf()->GetNumBytes()-slaveBytesRead); if (nextBytesRead > 0) slaveBytesRead += nextBytesRead; else break; } _slaveGateway()->SetDataIO(oldIO); // restore slave gateway's old state _fakeReceiveIO.SetBuffer(ByteBufferRef()); } else { MessageRef inMsg = GetMessageFromPool(); if ((inMsg())&&(inMsg()->UnflattenFromByteBuffer(*buf()) == B_NO_ERROR)) receiver.CallMessageReceivedFromGateway(inMsg, (void *) &fromIAP); } }
int32 SLIPFramedDataMessageIOGateway :: DoInputImplementation(AbstractGatewayMessageReceiver & receiver, uint32 maxBytes) { int32 ret = RawDataMessageIOGateway::DoInputImplementation(*this, maxBytes); if (_pendingMessage()) { MessageRef msg; muscleSwap(_pendingMessage, msg); // paranoia wrt re-entrancy receiver.CallMessageReceivedFromGateway(msg); } return ret; }
void PlainTextMessageIOGateway :: FlushInput(AbstractGatewayMessageReceiver & receiver) { if (_incomingText.HasChars()) { MessageRef inMsg = GetMessageFromPool(PR_COMMAND_TEXT_STRINGS); if ((inMsg())&&(inMsg()->AddString(PR_NAME_TEXT_LINE, _incomingText) == B_NO_ERROR)) { _incomingText.Clear(); receiver.CallMessageReceivedFromGateway(inMsg); } } }
int32 PlainTextMessageIOGateway :: DoInputImplementation(AbstractGatewayMessageReceiver & receiver, uint32 maxBytes) { TCHECKPOINT; int32 ret = 0; const int tempBufSize = 2048; char buf[tempBufSize]; int32 bytesRead = GetDataIO()()->Read(buf, muscleMin(maxBytes, (uint32)(sizeof(buf)-1))); if (bytesRead < 0) { FlushInput(receiver); return -1; } if (bytesRead > 0) { uint32 filteredBytesRead = bytesRead; FilterInputBuffer(buf, filteredBytesRead, sizeof(buf)-1); ret += filteredBytesRead; buf[filteredBytesRead] = '\0'; MessageRef inMsg; // demand-allocated int32 beginAt = 0; for (uint32 i=0; i<filteredBytesRead; i++) { char nextChar = buf[i]; if ((nextChar == '\r')||(nextChar == '\n')) { buf[i] = '\0'; // terminate the string here if ((nextChar == '\r')||(_prevCharWasCarriageReturn == false)) inMsg = AddIncomingText(inMsg, &buf[beginAt]); beginAt = i+1; } _prevCharWasCarriageReturn = (nextChar == '\r'); } if (beginAt < (int32)filteredBytesRead) { if (_flushPartialIncomingLines) inMsg = AddIncomingText(inMsg, &buf[beginAt]); else _incomingText += &buf[beginAt]; } if (inMsg()) receiver.CallMessageReceivedFromGateway(inMsg); } return ret; }
int32 PlainTextMessageIOGateway :: DoInputImplementation(AbstractGatewayMessageReceiver & receiver, uint32 maxBytes) { TCHECKPOINT; int32 ret = 0; const int tempBufSize = 2048; char buf[tempBufSize]; const uint32 mtuSize = GetMaximumPacketSize(); if (mtuSize > 0) { // Packet-IO implementation char * pbuf = buf; int pbufSize = tempBufSize; ByteBufferRef bigBuf; if (mtuSize > tempBufSize) { // Just in case our MTU size is too big for our on-stack buffer bigBuf = GetByteBufferFromPool(mtuSize); if (bigBuf()) { pbuf = (char *) bigBuf()->GetBuffer(); pbufSize = bigBuf()->GetNumBytes(); } } while(true) { IPAddressAndPort sourceIAP; const int32 bytesRead = GetPacketDataIO()->ReadFrom(pbuf, muscleMin(maxBytes, (uint32)(pbufSize-1)), sourceIAP); if (bytesRead < 0) return (ret > 0) ? ret : -1; else if (bytesRead > 0) { uint32 filteredBytesRead = bytesRead; FilterInputBuffer(pbuf, filteredBytesRead, pbufSize-1); ret += filteredBytesRead; pbuf[filteredBytesRead] = '\0'; bool prevCharWasCarriageReturn = false; // deliberately a local var, since UDP packets should be independent of each other MessageRef inMsg; // demand-allocated int32 beginAt = 0; for (uint32 i=0; i<filteredBytesRead; i++) { char nextChar = pbuf[i]; if ((nextChar == '\r')||(nextChar == '\n')) { pbuf[i] = '\0'; // terminate the string here if ((nextChar == '\r')||(prevCharWasCarriageReturn == false)) inMsg = AddIncomingText(inMsg, &pbuf[beginAt]); beginAt = i+1; } prevCharWasCarriageReturn = (nextChar == '\r'); } if (beginAt < (int32)filteredBytesRead) inMsg = AddIncomingText(inMsg, &pbuf[beginAt]); if (inMsg()) { (void) inMsg()->AddFlat(PR_NAME_PACKET_REMOTE_LOCATION, sourceIAP); receiver.CallMessageReceivedFromGateway(inMsg); inMsg.Reset(); } ret += bytesRead; } else return ret; } } else { // Stream-IO implementation const int32 bytesRead = GetDataIO()()->Read(buf, muscleMin(maxBytes, (uint32)(sizeof(buf)-1))); if (bytesRead < 0) { FlushInput(receiver); return -1; } if (bytesRead > 0) { uint32 filteredBytesRead = bytesRead; FilterInputBuffer(buf, filteredBytesRead, sizeof(buf)-1); ret += filteredBytesRead; buf[filteredBytesRead] = '\0'; MessageRef inMsg; // demand-allocated int32 beginAt = 0; for (uint32 i=0; i<filteredBytesRead; i++) { char nextChar = buf[i]; if ((nextChar == '\r')||(nextChar == '\n')) { buf[i] = '\0'; // terminate the string here if ((nextChar == '\r')||(_prevCharWasCarriageReturn == false)) inMsg = AddIncomingText(inMsg, &buf[beginAt]); beginAt = i+1; } _prevCharWasCarriageReturn = (nextChar == '\r'); } if (beginAt < (int32)filteredBytesRead) { if (_flushPartialIncomingLines) inMsg = AddIncomingText(inMsg, &buf[beginAt]); else _incomingText += &buf[beginAt]; } if (inMsg()) receiver.CallMessageReceivedFromGateway(inMsg); } } return ret; }