zeek/auxil/libunistd/portable/ipc/BsdSocketClient.cpp
Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

125 lines
2.9 KiB
C++

// BsdSocketClient.cpp
// Created by Robin Rowe on 11/27/2015
// Copyright (c) 2015 Robin.Rowe@CinePaint.org
// License open source MIT
#include "BsdSocketClient.h"
#include "../Logger.h"
namespace portable
{
void BsdSocketClient::Run()
{ isGo = true;
std::unique_ptr<char[]> buffer(new char[bufsize]);
PacketReader packet(buffer.get(),bufsize);
unsigned totalBytes = 0;
while(isGo)
{ const int recvBytes = RecvFrom(buffer.get(),bufsize-totalBytes,totalBytes);
if(recvBytes<=0)
{ printf("ERROR: socket received %i bytes (closed)\n",recvBytes);
Stop();
continue;
}
totalBytes += recvBytes;
const unsigned consumedBytes = OnPacket(totalBytes,packet);
if(!consumedBytes)
{ continue;
}
if(consumedBytes==totalBytes)
{ totalBytes = 0;
}
else
{ const unsigned remainingBytes = totalBytes - consumedBytes;
// printf("memmove(buffer,buffer+%u,%u)\n",consumedBytes,remainingBytes);
memmove(buffer.get(),buffer.get()+consumedBytes,remainingBytes);
totalBytes = remainingBytes;
}
}
OnStop();
}
unsigned BsdSocketClient::OnPacket(unsigned bytes,portable::PacketReader& packet)
{
#if 0
printf("bytes: %i packetSize: %i\n",bytes,packetSize);
#endif
//LogMsg("Receive packet");
while(bytes)
{ if(!packet.ReadPacketHeader(bytes))
{ stats.fragments++;
return bytes;
}
#if 1
if(!stats.GetLast())
#endif
{ printf("reading packet #%u\n",packet.header.packetId);
}
if(!packet.header.packetSize)
{ error_msg("invalid packet");
return bytes;
}
if(0==packet.header.packetId)
{ trace_msg("Reading header");
if(!ReadHeader(packet))
{ //stats.Print(packet.header.packetId,bytes,packet.header.packetSize, capacity);
SocketReset("Packet header corrupted",packet);
return 0;
} }
else
{// LogMsg("Reading frame");
ReadFrame(packet,packet.header.packetId);
}
stats.Transmit(packet.header.packetId);
#if 0
const unsigned readOffset=packet.GetReadOffset();
if(readOffset!=packetSize || bytes<packetSize)
{ std::string s("readOffset/packetSize = ");
s+=std::to_string(readOffset);
s+="/";
s+=std::to_string(packetSize);
puts(s.c_str());
}
#endif
bytes-=packet.header.packetSize;
if(!bytes)
{ return 0;
}
stats.pipelined++;
packet.NextInPipeline();
#if 0
std::string msg("Pipelining #");
msg+=std::to_string(packetId);
msg+=": ";
msg+=std::to_string(bytes);
msg+=" of ";
msg+=std::to_string(packetSize);
puts(msg.c_str());
#endif
if(bytes<=sizeof(unsigned))
{// stats.Print(packetId,bytes,packetSize, capacity);
SocketReset("Packet receive underflow bytes",packet);
return bytes;
}
// packet>>packetSize;
// packetSize=packet.GetPacketSize(bytes);
#if 0
msg="Pipelined packetSize = ";
msg+=std::to_string(packetSize);
puts(msg.c_str());
#endif
}
return 0;
}
void BsdSocketClient::SocketReset(const char* msg,portable::PacketReader& packet)
{ (void)msg;
packet.Dump();
PacketSocket bsdSocket(socketfd);
bsdSocket.Close();
socketfd = 0;
Stop();
}
}