Reland "Take out listen support from AsyncPacketSocket"

This is a reland of b141c162ee2ef88a7498ba8cb8bc852287f93ad2

Original change's description:
> Take out listen support from AsyncPacketSocket
>
> Moved to new interface class AsyncListenSocket.
>
> Bug: webrtc:13065
> Change-Id: Ib96ce154ba19979360ecd8144981d947ff5b8b18
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232607
> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#35234}

Bug: webrtc:13065
Change-Id: I88bebdd80ebe6bcf6ac635023924d79fbfb76813
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/235960
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35260}
This commit is contained in:
Niels Möller
2021-10-19 10:11:02 +02:00
committed by WebRTC LUCI CQ
parent b62ee8ce94
commit d30ece1804
11 changed files with 178 additions and 121 deletions

View File

@ -62,16 +62,11 @@ Socket* AsyncTCPSocketBase::ConnectSocket(
}
AsyncTCPSocketBase::AsyncTCPSocketBase(Socket* socket,
bool listen,
size_t max_packet_size)
: socket_(socket),
listen_(listen),
max_insize_(max_packet_size),
max_outsize_(max_packet_size) {
if (!listen_) {
// Listening sockets don't send/receive data, so they don't need buffers.
inbuf_.EnsureCapacity(kMinimumRecvSize);
}
inbuf_.EnsureCapacity(kMinimumRecvSize);
RTC_DCHECK(socket_.get() != nullptr);
socket_->SignalConnectEvent.connect(this,
@ -79,12 +74,6 @@ AsyncTCPSocketBase::AsyncTCPSocketBase(Socket* socket,
socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent);
socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent);
socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent);
if (listen_) {
if (socket_->Listen(kListenBacklog) < 0) {
RTC_LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError();
}
}
}
AsyncTCPSocketBase::~AsyncTCPSocketBase() {}
@ -106,11 +95,7 @@ AsyncTCPSocket::State AsyncTCPSocketBase::GetState() const {
case Socket::CS_CLOSED:
return STATE_CLOSED;
case Socket::CS_CONNECTING:
if (listen_) {
return STATE_BOUND;
} else {
return STATE_CONNECTING;
}
return STATE_CONNECTING;
case Socket::CS_CONNECTED:
return STATE_CONNECTED;
default:
@ -149,7 +134,6 @@ int AsyncTCPSocketBase::SendTo(const void* pv,
}
int AsyncTCPSocketBase::FlushOutBuffer() {
RTC_DCHECK(!listen_);
RTC_DCHECK_GT(outbuf_.size(), 0);
rtc::ArrayView<uint8_t> view = outbuf_;
int res;
@ -189,7 +173,6 @@ int AsyncTCPSocketBase::FlushOutBuffer() {
void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) {
RTC_DCHECK(outbuf_.size() + cb <= max_outsize_);
RTC_DCHECK(!listen_);
outbuf_.AppendData(static_cast<const uint8_t*>(pv), cb);
}
@ -200,62 +183,44 @@ void AsyncTCPSocketBase::OnConnectEvent(Socket* socket) {
void AsyncTCPSocketBase::OnReadEvent(Socket* socket) {
RTC_DCHECK(socket_.get() == socket);
if (listen_) {
rtc::SocketAddress address;
rtc::Socket* new_socket = socket->Accept(&address);
if (!new_socket) {
// TODO(stefan): Do something better like forwarding the error
// to the user.
RTC_LOG(LS_ERROR) << "TCP accept failed with error "
<< socket_->GetError();
return;
size_t total_recv = 0;
while (true) {
size_t free_size = inbuf_.capacity() - inbuf_.size();
if (free_size < kMinimumRecvSize && inbuf_.capacity() < max_insize_) {
inbuf_.EnsureCapacity(std::min(max_insize_, inbuf_.capacity() * 2));
free_size = inbuf_.capacity() - inbuf_.size();
}
HandleIncomingConnection(new_socket);
int len = socket_->Recv(inbuf_.data() + inbuf_.size(), free_size, nullptr);
if (len < 0) {
// TODO(stefan): Do something better like forwarding the error to the
// user.
if (!socket_->IsBlocking()) {
RTC_LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError();
}
break;
}
// Prime a read event in case data is waiting.
new_socket->SignalReadEvent(new_socket);
total_recv += len;
inbuf_.SetSize(inbuf_.size() + len);
if (!len || static_cast<size_t>(len) < free_size) {
break;
}
}
if (!total_recv) {
return;
}
size_t size = inbuf_.size();
ProcessInput(inbuf_.data<char>(), &size);
if (size > inbuf_.size()) {
RTC_LOG(LS_ERROR) << "input buffer overflow";
RTC_NOTREACHED();
inbuf_.Clear();
} else {
size_t total_recv = 0;
while (true) {
size_t free_size = inbuf_.capacity() - inbuf_.size();
if (free_size < kMinimumRecvSize && inbuf_.capacity() < max_insize_) {
inbuf_.EnsureCapacity(std::min(max_insize_, inbuf_.capacity() * 2));
free_size = inbuf_.capacity() - inbuf_.size();
}
int len =
socket_->Recv(inbuf_.data() + inbuf_.size(), free_size, nullptr);
if (len < 0) {
// TODO(stefan): Do something better like forwarding the error to the
// user.
if (!socket_->IsBlocking()) {
RTC_LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError();
}
break;
}
total_recv += len;
inbuf_.SetSize(inbuf_.size() + len);
if (!len || static_cast<size_t>(len) < free_size) {
break;
}
}
if (!total_recv) {
return;
}
size_t size = inbuf_.size();
ProcessInput(inbuf_.data<char>(), &size);
if (size > inbuf_.size()) {
RTC_LOG(LS_ERROR) << "input buffer overflow";
RTC_NOTREACHED();
inbuf_.Clear();
} else {
inbuf_.SetSize(size);
}
inbuf_.SetSize(size);
}
}
@ -283,12 +248,11 @@ AsyncTCPSocket* AsyncTCPSocket::Create(Socket* socket,
const SocketAddress& bind_address,
const SocketAddress& remote_address) {
return new AsyncTCPSocket(
AsyncTCPSocketBase::ConnectSocket(socket, bind_address, remote_address),
false);
AsyncTCPSocketBase::ConnectSocket(socket, bind_address, remote_address));
}
AsyncTCPSocket::AsyncTCPSocket(Socket* socket, bool listen)
: AsyncTCPSocketBase(socket, listen, kBufSize) {}
AsyncTCPSocket::AsyncTCPSocket(Socket* socket)
: AsyncTCPSocketBase(socket, kBufSize) {}
int AsyncTCPSocket::Send(const void* pv,
size_t cb,
@ -343,8 +307,59 @@ void AsyncTCPSocket::ProcessInput(char* data, size_t* len) {
}
}
void AsyncTCPSocket::HandleIncomingConnection(Socket* socket) {
SignalNewConnection(this, new AsyncTCPSocket(socket, false));
AsyncTcpListenSocket::AsyncTcpListenSocket(std::unique_ptr<Socket> socket)
: socket_(std::move(socket)) {
RTC_DCHECK(socket_.get() != nullptr);
socket_->SignalReadEvent.connect(this, &AsyncTcpListenSocket::OnReadEvent);
if (socket_->Listen(kListenBacklog) < 0) {
RTC_LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError();
}
}
AsyncTcpListenSocket::State AsyncTcpListenSocket::GetState() const {
switch (socket_->GetState()) {
case Socket::CS_CLOSED:
return State::kClosed;
case Socket::CS_CONNECTING:
return State::kBound;
default:
RTC_NOTREACHED();
return State::kClosed;
}
}
SocketAddress AsyncTcpListenSocket::GetLocalAddress() const {
return socket_->GetLocalAddress();
}
int AsyncTcpListenSocket::GetOption(Socket::Option opt, int* value) {
return socket_->GetOption(opt, value);
}
int AsyncTcpListenSocket::SetOption(Socket::Option opt, int value) {
return socket_->SetOption(opt, value);
}
void AsyncTcpListenSocket::OnReadEvent(Socket* socket) {
RTC_DCHECK(socket_.get() == socket);
rtc::SocketAddress address;
rtc::Socket* new_socket = socket->Accept(&address);
if (!new_socket) {
// TODO(stefan): Do something better like forwarding the error
// to the user.
RTC_LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError();
return;
}
HandleIncomingConnection(new_socket);
// Prime a read event in case data is waiting.
new_socket->SignalReadEvent(new_socket);
}
void AsyncTcpListenSocket::HandleIncomingConnection(Socket* socket) {
SignalNewConnection(this, new AsyncTCPSocket(socket));
}
} // namespace rtc