Set errno on response when syscall actually fails

This prevents setting stale errno on responses.

Also fixes TestDiscardsUDPPacketsWithMcastSourceAddressV6 to use correct
multicast addresses in test.

Fixes #3793

PiperOrigin-RevId: 329391155
This commit is contained in:
Jay Zhuang
2020-08-31 15:31:42 -07:00
committed by gVisor bot
parent 6cdfa4fee0
commit 170560cec0
2 changed files with 46 additions and 16 deletions
+42 -14
View File
@@ -116,7 +116,9 @@ class PosixImpl final : public posix_server::Posix::Service {
socklen_t addrlen = sizeof(addr);
response->set_fd(accept(request->sockfd(),
reinterpret_cast<sockaddr *>(&addr), &addrlen));
response->set_errno_(errno);
if (response->fd() < 0) {
response->set_errno_(errno);
}
return sockaddr_to_proto(addr, addrlen, response->mutable_addr());
}
@@ -137,7 +139,9 @@ class PosixImpl final : public posix_server::Posix::Service {
response->set_ret(
bind(request->sockfd(), reinterpret_cast<sockaddr *>(&addr), addr_len));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -145,7 +149,9 @@ class PosixImpl final : public posix_server::Posix::Service {
const ::posix_server::CloseRequest *request,
::posix_server::CloseResponse *response) override {
response->set_ret(close(request->fd()));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -165,7 +171,9 @@ class PosixImpl final : public posix_server::Posix::Service {
response->set_ret(connect(request->sockfd(),
reinterpret_cast<sockaddr *>(&addr), addr_len));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -173,7 +181,9 @@ class PosixImpl final : public posix_server::Posix::Service {
const ::posix_server::FcntlRequest *request,
::posix_server::FcntlResponse *response) override {
response->set_ret(::fcntl(request->fd(), request->cmd(), request->arg()));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -185,7 +195,9 @@ class PosixImpl final : public posix_server::Posix::Service {
socklen_t addrlen = sizeof(addr);
response->set_ret(getsockname(
request->sockfd(), reinterpret_cast<sockaddr *>(&addr), &addrlen));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return sockaddr_to_proto(addr, addrlen, response->mutable_addr());
}
@@ -227,7 +239,9 @@ class PosixImpl final : public posix_server::Posix::Service {
return ::grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Unknown SockOpt Type");
}
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -235,7 +249,9 @@ class PosixImpl final : public posix_server::Posix::Service {
const ::posix_server::ListenRequest *request,
::posix_server::ListenResponse *response) override {
response->set_ret(listen(request->sockfd(), request->backlog()));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -244,7 +260,9 @@ class PosixImpl final : public posix_server::Posix::Service {
::posix_server::SendResponse *response) override {
response->set_ret(::send(request->sockfd(), request->buf().data(),
request->buf().size(), request->flags()));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -265,7 +283,9 @@ class PosixImpl final : public posix_server::Posix::Service {
response->set_ret(::sendto(request->sockfd(), request->buf().data(),
request->buf().size(), request->flags(),
reinterpret_cast<sockaddr *>(&addr), addr_len));
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -299,7 +319,9 @@ class PosixImpl final : public posix_server::Posix::Service {
return ::grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Unknown SockOpt Type");
}
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -308,14 +330,18 @@ class PosixImpl final : public posix_server::Posix::Service {
::posix_server::SocketResponse *response) override {
response->set_fd(
socket(request->domain(), request->type(), request->protocol()));
response->set_errno_(errno);
if (response->fd() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
::grpc::Status Shutdown(grpc_impl::ServerContext *context,
const ::posix_server::ShutdownRequest *request,
::posix_server::ShutdownResponse *response) override {
response->set_errno_(shutdown(request->fd(), request->how()));
if (shutdown(request->fd(), request->how()) < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
@@ -328,7 +354,9 @@ class PosixImpl final : public posix_server::Posix::Service {
if (response->ret() >= 0) {
response->set_buf(buf.data(), response->ret());
}
response->set_errno_(errno);
if (response->ret() < 0) {
response->set_errno_(errno);
}
return ::grpc::Status::OK;
}
};
@@ -53,6 +53,7 @@ func TestDiscardsUDPPacketsWithMcastSourceAddressV4(t *testing.T) {
t,
testbench.IPv4{SrcAddr: testbench.Address(tcpip.Address(mcastAddr.To4()))},
testbench.UDP{},
&testbench.Payload{Bytes: []byte("test payload")},
)
ret, payload, errno := dut.RecvWithErrno(context.Background(), t, remoteFD, 100, 0)
@@ -76,14 +77,15 @@ func TestDiscardsUDPPacketsWithMcastSourceAddressV6(t *testing.T) {
net.IPv6interfacelocalallnodes,
net.IPv6linklocalallnodes,
net.IPv6linklocalallrouters,
net.ParseIP("fe01::42"),
net.ParseIP("fe02::4242"),
net.ParseIP("ff01::42"),
net.ParseIP("ff02::4242"),
} {
t.Run(fmt.Sprintf("srcaddr=%s", mcastAddr), func(t *testing.T) {
conn.SendIPv6(
t,
testbench.IPv6{SrcAddr: testbench.Address(tcpip.Address(mcastAddr.To16()))},
testbench.UDP{},
&testbench.Payload{Bytes: []byte("test payload")},
)
ret, payload, errno := dut.RecvWithErrno(context.Background(), t, remoteFD, 100, 0)
if errno != syscall.EAGAIN || errno != syscall.EWOULDBLOCK {