Skip to content

Commit

Permalink
Connect UDP sockets.
Browse files Browse the repository at this point in the history
Allow Cobalt to connect UDP sockets. This saves kernel CPU time. In the download
benchmark page, this results in ~7% higher achieved bandwidth and ~5% less total
CPU usage.
  • Loading branch information
jellefoks committed Oct 15, 2024
1 parent 1656a0e commit bef1eeb
Showing 1 changed file with 28 additions and 10 deletions.
38 changes: 28 additions & 10 deletions net/socket/udp_socket_starboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ int UDPSocketStarboard::GetLocalAddress(IPEndPoint* address) const {
int UDPSocketStarboard::Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) {
return RecvFrom(buf, buf_len, NULL, std::move(callback));
return RecvFrom(buf, buf_len, nullptr, std::move(callback));
}

int UDPSocketStarboard::RecvFrom(IOBuffer* buf,
Expand Down Expand Up @@ -271,17 +271,34 @@ int UDPSocketStarboard::InternalConnect(const IPEndPoint& address) {
DCHECK(!remote_address_.get());

int rv = 0;
// Cobalt does random bind despite bind_type_ because we do not connect
// UDP sockets but Chromium does. And if a socket does recvfrom() without
// any sendto() before, it needs to be bound to have a local port.
rv = RandomBind(address.GetFamily() == ADDRESS_FAMILY_IPV4 ?
IPAddress::IPv4AllZeros() : IPAddress::IPv6AllZeros());
if (bind_type_ == DatagramSocket::RANDOM_BIND) {
// Construct IPAddress of appropriate size (IPv4 or IPv6) of 0s,
// representing INADDR_ANY or in6addr_any.
rv = RandomBind(address.GetFamily() == ADDRESS_FAMILY_IPV4
? IPAddress::IPv4AllZeros()
: IPAddress::IPv6AllZeros());
}

if (rv != OK)
return rv;

SbSocketAddress storage;
if (!address.ToSbSocketAddress(&storage)) {
return ERR_ADDRESS_INVALID;
}

remote_address_.reset(new IPEndPoint(address));

SbSocketError result = SbSocketConnect(socket_, &storage);
if (result != kSbSocketOk) {
return MapLastSocketError(socket_);
}

LOG(INFO) << __FUNCTION__
<< " UDP CONNECT SUCCEEDED "
"================================================ "
<< address;

return OK;
}

Expand Down Expand Up @@ -459,16 +476,16 @@ int UDPSocketStarboard::InternalRecvFrom(IOBuffer* buf,
int buf_len,
IPEndPoint* address) {
SbSocketAddress sb_address;
int bytes_transferred =
SbSocketReceiveFrom(socket_, buf->data(), buf_len, &sb_address);
int bytes_transferred = SbSocketReceiveFrom(socket_, buf->data(), buf_len,
address ? &sb_address : nullptr);
int result;
if (bytes_transferred >= 0) {
result = bytes_transferred;
// Passing in NULL address is allowed. This is only to align with other
// platform's implementation.
if (address && !address->FromSbSocketAddress(&sb_address)) {
result = ERR_ADDRESS_INVALID;
} else if (bytes_transferred == buf_len) {
} else if (bytes_transferred > buf_len) {
result = ERR_MSG_TOO_BIG;
}
} else {
Expand All @@ -477,7 +494,8 @@ int UDPSocketStarboard::InternalRecvFrom(IOBuffer* buf,

if (result != ERR_IO_PENDING) {
IPEndPoint log_address;
if (result < 0 || !log_address.FromSbSocketAddress(&sb_address)) {
if (result < 0 || !address ||
!log_address.FromSbSocketAddress(&sb_address)) {
LogRead(result, buf->data(), NULL);
} else {
LogRead(result, buf->data(), &log_address);
Expand Down

0 comments on commit bef1eeb

Please sign in to comment.