tcp: endpoint.Write has to send all data that has been read from payload

io.Reader.ReadFull returns the number of bytes copied and an error if fewer
bytes were read.

PiperOrigin-RevId: 360247614
This commit is contained in:
Andrei Vagin
2021-03-01 12:17:20 -08:00
committed by gVisor bot
parent 037bb2f45a
commit 865ca64ee8
3 changed files with 27 additions and 2 deletions
+3 -2
View File
@@ -1552,10 +1552,11 @@ func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcp
return nil, nil
}
v := make([]byte, avail)
if _, err := io.ReadFull(p, v); err != nil {
n, err := p.Read(v)
if err != nil && err != io.EOF {
return nil, &tcpip.ErrBadBuffer{}
}
return v, nil
return v[:n], nil
}()
if len(v) == 0 || err != nil {
return nil, 0, err
+1
View File
@@ -2384,6 +2384,7 @@ cc_library(
"@com_google_absl//absl/memory",
"@com_google_absl//absl/time",
gtest,
"//test/util:temp_path",
"//test/util:test_util",
"//test/util:thread_util",
],
@@ -29,6 +29,7 @@
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "test/syscalls/linux/socket_test_util.h"
#include "test/util/temp_path.h"
#include "test/util/test_util.h"
#include "test/util/thread_util.h"
@@ -1059,6 +1060,28 @@ TEST_P(TCPSocketPairTest, SpliceToPipe) {
SyscallSucceedsWithValue(buf.size()));
EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0);
}
#include <sys/sendfile.h>
TEST_P(TCPSocketPairTest, SendfileFromRegularFileSucceeds) {
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
const FileDescriptor in_fd =
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR));
// Fill with some random data.
std::vector<char> buf(kPageSize / 2);
RandomizeBuffer(buf.data(), buf.size());
ASSERT_THAT(pwrite(in_fd.get(), buf.data(), buf.size(), 0),
SyscallSucceedsWithValue(buf.size()));
EXPECT_THAT(
sendfile(sockets->first_fd(), in_fd.get(), nullptr, buf.size() + 1),
SyscallSucceedsWithValue(buf.size()));
std::vector<char> rbuf(buf.size() + 1);
ASSERT_THAT(read(sockets->second_fd(), rbuf.data(), rbuf.size()),
SyscallSucceedsWithValue(buf.size()));
EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0);
}
#endif // __linux__
TEST_P(TCPSocketPairTest, SetTCPWindowClampBelowMinRcvBufConnectedSocket) {