diff options
author | mbajpai <mbajpai@nvidia.com> | 2014-10-30 15:00:56 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-30 22:01:12 +0000 |
commit | 97bfef2c02f89b66e3b5d48cdca796796062fc62 (patch) | |
tree | 6a6b214a00ad61e9057fe9cd4db53a12b4547a5a | |
parent | ab997839d3c3b55ddf158db57f0ec87e01762975 (diff) | |
download | chromium_src-97bfef2c02f89b66e3b5d48cdca796796062fc62.zip chromium_src-97bfef2c02f89b66e3b5d48cdca796796062fc62.tar.gz chromium_src-97bfef2c02f89b66e3b5d48cdca796796062fc62.tar.bz2 |
Add support for modifying TCP and UDP socket buffer size in nacl_io
setsockopt() can now be called with these options:
SO_RCVBUF
SO_SNDBUF
BUG=none
Review URL: https://codereview.chromium.org/304373008
Cr-Commit-Position: refs/heads/master@{#302167}
4 files changed, 103 insertions, 0 deletions
diff --git a/native_client_sdk/src/libraries/nacl_io/socket/tcp_node.cc b/native_client_sdk/src/libraries/nacl_io/socket/tcp_node.cc index 445dfe7..28a3740 100644 --- a/native_client_sdk/src/libraries/nacl_io/socket/tcp_node.cc +++ b/native_client_sdk/src/libraries/nacl_io/socket/tcp_node.cc @@ -365,6 +365,28 @@ Error TcpNode::SetSockOpt(int lvl, AUTO_LOCK(node_lock_); tcp_nodelay_ = *static_cast<const int*>(optval) != 0; return SetNoDelay_Locked(); + } else if (lvl == SOL_SOCKET && optname == SO_RCVBUF) { + if (static_cast<size_t>(len) < sizeof(int)) + return EINVAL; + AUTO_LOCK(node_lock_); + int bufsize = *static_cast<const int*>(optval); + int32_t error = + TCPInterface()->SetOption(socket_resource_, + PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE, + PP_MakeInt32(bufsize), + PP_BlockUntilComplete()); + return PPErrorToErrno(error); + } else if (lvl == SOL_SOCKET && optname == SO_SNDBUF) { + if (static_cast<size_t>(len) < sizeof(int)) + return EINVAL; + AUTO_LOCK(node_lock_); + int bufsize = *static_cast<const int*>(optval); + int32_t error = + TCPInterface()->SetOption(socket_resource_, + PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE, + PP_MakeInt32(bufsize), + PP_BlockUntilComplete()); + return PPErrorToErrno(error); } return SocketNode::SetSockOpt(lvl, optname, optval, len); diff --git a/native_client_sdk/src/libraries/nacl_io/socket/udp_node.cc b/native_client_sdk/src/libraries/nacl_io/socket/udp_node.cc index ad70878..c84d212 100644 --- a/native_client_sdk/src/libraries/nacl_io/socket/udp_node.cc +++ b/native_client_sdk/src/libraries/nacl_io/socket/udp_node.cc @@ -203,6 +203,37 @@ void UdpNode::QueueOutput() { stream()->EnqueueWork(work); } +Error UdpNode::SetSockOpt(int lvl, + int optname, + const void* optval, + socklen_t len) { + if (lvl == SOL_SOCKET && optname == SO_RCVBUF) { + if (static_cast<size_t>(len) < sizeof(int)) + return EINVAL; + AUTO_LOCK(node_lock_); + int bufsize = *static_cast<const int*>(optval); + int32_t error = + UDPInterface()->SetOption(socket_resource_, + PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE, + PP_MakeInt32(bufsize), + PP_BlockUntilComplete()); + return PPErrorToErrno(error); + } else if (lvl == SOL_SOCKET && optname == SO_SNDBUF) { + if (static_cast<size_t>(len) < sizeof(int)) + return EINVAL; + AUTO_LOCK(node_lock_); + int bufsize = *static_cast<const int*>(optval); + int32_t error = + UDPInterface()->SetOption(socket_resource_, + PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE, + PP_MakeInt32(bufsize), + PP_BlockUntilComplete()); + return PPErrorToErrno(error); + } + + return SocketNode::SetSockOpt(lvl, optname, optval, len); +} + Error UdpNode::Bind(const struct sockaddr* addr, socklen_t len) { if (0 == socket_resource_) return EBADF; diff --git a/native_client_sdk/src/libraries/nacl_io/socket/udp_node.h b/native_client_sdk/src/libraries/nacl_io/socket/udp_node.h index 9abae91..b3da0f44 100644 --- a/native_client_sdk/src/libraries/nacl_io/socket/udp_node.h +++ b/native_client_sdk/src/libraries/nacl_io/socket/udp_node.h @@ -35,6 +35,11 @@ class UdpNode : public SocketNode { const struct sockaddr* addr, socklen_t len); + virtual Error SetSockOpt(int lvl, + int optname, + const void* optval, + socklen_t len); + protected: virtual Error Recv_Locked(void* buf, size_t len, diff --git a/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc b/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc index 6f4dbe8..f5ab432 100644 --- a/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc +++ b/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc @@ -594,6 +594,20 @@ TEST_F(SocketTestUDP, Listen) { EXPECT_EQ(errno, ENOTSUP); } +TEST_F(SocketTestUDP, Sockopt_BUFSIZE) { + int option = 1024*1024; + socklen_t len = sizeof(option); + + ASSERT_EQ(0, Bind(sock1_, LOCAL_HOST, ANY_PORT)); + + // Modify the test to verify the change by calling getsockopt + // once UDPInterface supports GetOption() call + ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_RCVBUF, &option, len)) + << "failed with: " << strerror(errno); + ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_SNDBUF, &option, len)) + << "failed with: " << strerror(errno); +} + TEST_F(SocketTestTCP, Listen) { sockaddr_in addr; socklen_t addrlen = sizeof(addr); @@ -856,4 +870,35 @@ TEST_F(SocketTestTCP, SendBufferedDataAfterShutdown) { ASSERT_EQ(0, ki_close(new_sock)); } +TEST_F(SocketTestTCP, Sockopt_BUFSIZE) { + int option = 1024*1024; + socklen_t len = sizeof(option); + sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + + int server_sock = sock1_; + int client_sock = sock2_; + + // bind and listen + ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1)); + ASSERT_EQ(0, ki_listen(server_sock, 10)) + << "listen failed with: " << strerror(errno); + + // connect to listening socket + IP4ToSockAddr(LOCAL_HOST, PORT1, &addr); + ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen)) + << "Failed with " << errno << ": " << strerror(errno); + + addrlen = sizeof(addr); + int new_sock = ki_accept(server_sock, (sockaddr*)&addr, &addrlen); + ASSERT_NE(-1, new_sock); + + // Modify the test to verify the change by calling getsockopt + // once TCPInterface supports GetOption() call + ASSERT_EQ(0, ki_setsockopt(sock2_, SOL_SOCKET, SO_RCVBUF, &option, len)) + << "failed with: " << strerror(errno); + ASSERT_EQ(0, ki_setsockopt(sock2_, SOL_SOCKET, SO_SNDBUF, &option, len)) + << "failed with: " << strerror(errno); +} + #endif // PROVIDES_SOCKET_API |