3939#include " brpc/policy/most_common_message.h"
4040#include " brpc/policy/http_rpc_protocol.h"
4141#include " brpc/server.h"
42+ #include " brpc/details/server_private_accessor.h"
4243#include " brpc/channel.h"
4344#include " brpc/controller.h"
4445#include " health_check.pb.h"
@@ -59,6 +60,8 @@ DECLARE_bool(socket_keepalive);
5960DECLARE_int32 (socket_keepalive_idle_s);
6061DECLARE_int32 (socket_keepalive_interval_s);
6162DECLARE_int32 (socket_keepalive_count);
63+ DECLARE_int32 (socket_recv_buffer_size);
64+ DECLARE_int32 (socket_send_buffer_size);
6265DECLARE_int32 (socket_tcp_user_timeout_ms);
6366}
6467
@@ -1123,6 +1126,45 @@ void CheckKeepalive(int fd,
11231126 ASSERT_EQ (expected_keepalive_count, keepalive_count);
11241127}
11251128
1129+ struct SocketBufferValues {
1130+ int recv_buffer;
1131+ int send_buffer;
1132+
1133+ SocketBufferValues () : recv_buffer(0 ), send_buffer(0 ) {}
1134+ };
1135+
1136+ void GetSocketBufferValues (int fd, SocketBufferValues* values) {
1137+ socklen_t len = sizeof (values->recv_buffer );
1138+ ASSERT_EQ (0 , getsockopt (fd, SOL_SOCKET , SO_RCVBUF ,
1139+ &values->recv_buffer , &len));
1140+ len = sizeof (values->send_buffer );
1141+ ASSERT_EQ (0 , getsockopt (fd, SOL_SOCKET , SO_SNDBUF ,
1142+ &values->send_buffer , &len));
1143+ }
1144+
1145+ void GetExpectedSocketBufferValues (int buffer_size,
1146+ SocketBufferValues* expected) {
1147+ SocketBufferValues default_values;
1148+ butil::fd_guard default_fd (socket (AF_INET , SOCK_STREAM , 0 ));
1149+ ASSERT_GT (default_fd, 0 );
1150+ GetSocketBufferValues (default_fd, &default_values);
1151+
1152+ butil::fd_guard reference_fd (socket (AF_INET , SOCK_STREAM , 0 ));
1153+ ASSERT_GT (reference_fd, 0 );
1154+ ASSERT_EQ (0 , setsockopt (reference_fd, SOL_SOCKET , SO_RCVBUF , &buffer_size,
1155+ sizeof (buffer_size)));
1156+ ASSERT_EQ (0 , setsockopt (reference_fd, SOL_SOCKET , SO_SNDBUF , &buffer_size,
1157+ sizeof (buffer_size)));
1158+ GetSocketBufferValues (reference_fd, expected);
1159+ }
1160+
1161+ void CheckSocketBufferValues (int fd, const SocketBufferValues& expected) {
1162+ SocketBufferValues actual;
1163+ GetSocketBufferValues (fd, &actual);
1164+ ASSERT_EQ (expected.recv_buffer , actual.recv_buffer );
1165+ ASSERT_EQ (expected.send_buffer , actual.send_buffer );
1166+ }
1167+
11261168TEST_F (SocketTest, keepalive) {
11271169 int default_keepalive = 0 ;
11281170 int default_keepalive_idle = 0 ;
@@ -1425,6 +1467,97 @@ TEST_F(SocketTest, keepalive_input_message) {
14251467 ASSERT_EQ (EBADF , errno);
14261468}
14271469
1470+ TEST_F (SocketTest, socket_buffer_options_before_connect) {
1471+ gflags::FlagSaver flag_saver;
1472+ const int buffer_size = 256 * 1024 ;
1473+ brpc::FLAGS_socket_recv_buffer_size = buffer_size;
1474+ brpc::FLAGS_socket_send_buffer_size = buffer_size;
1475+
1476+ SocketBufferValues expected;
1477+ GetExpectedSocketBufferValues (buffer_size, &expected);
1478+
1479+ butil::EndPoint point;
1480+ ASSERT_EQ (0 , str2endpoint (" 127.0.0.1:0" , &point));
1481+ butil::fd_guard listening_fd (tcp_listen (point));
1482+ ASSERT_GT (listening_fd, 0 ) << berror ();
1483+ ASSERT_EQ (0 , butil::get_local_side (listening_fd, &point));
1484+
1485+ brpc::SocketOptions options;
1486+ options.remote_side = point;
1487+ brpc::SocketId id = brpc::INVALID_SOCKET_ID ;
1488+ ASSERT_EQ (0 , brpc::Socket::Create (options, &id));
1489+
1490+ brpc::SocketUniquePtr ptr;
1491+ ASSERT_EQ (0 , brpc::Socket::Address (id, &ptr)) << " id=" << id;
1492+
1493+ const timespec duetime = butil::milliseconds_from_now (1000 );
1494+ butil::fd_guard connected_fd (ptr->Connect (&duetime, NULL , NULL ));
1495+ ASSERT_GT (connected_fd, 0 );
1496+ CheckSocketBufferValues (connected_fd, expected);
1497+
1498+ ASSERT_EQ (0 , ptr->SetFailed ());
1499+ }
1500+
1501+ TEST_F (SocketTest, socket_buffer_options_before_accept) {
1502+ gflags::FlagSaver flag_saver;
1503+ const int buffer_size = 256 * 1024 ;
1504+ brpc::FLAGS_socket_recv_buffer_size = buffer_size;
1505+ brpc::FLAGS_socket_send_buffer_size = buffer_size;
1506+
1507+ SocketBufferValues expected;
1508+ GetExpectedSocketBufferValues (buffer_size, &expected);
1509+
1510+ butil::EndPoint point;
1511+ ASSERT_EQ (0 , str2endpoint (" 127.0.0.1:0" , &point));
1512+ brpc::Server server;
1513+ ASSERT_EQ (0 , server.Start (point, NULL ));
1514+ point = server.listen_address ();
1515+
1516+ brpc::Acceptor* messenger =
1517+ brpc::ServerPrivateAccessor (&server).acceptor ();
1518+ ASSERT_TRUE (messenger != NULL );
1519+ ASSERT_GT (messenger->listened_fd (), 0 );
1520+ CheckSocketBufferValues (messenger->listened_fd (), expected);
1521+
1522+ // Accepted sockets should inherit the listener's buffer sizes, not use
1523+ // the flags at accept time.
1524+ brpc::FLAGS_socket_recv_buffer_size = buffer_size / 2 ;
1525+ brpc::FLAGS_socket_send_buffer_size = buffer_size / 2 ;
1526+
1527+ brpc::SocketOptions options;
1528+ options.remote_side = point;
1529+ options.connect_on_create = true ;
1530+ brpc::SocketId id = brpc::INVALID_SOCKET_ID ;
1531+ ASSERT_EQ (0 , brpc::Socket::Create (options, &id));
1532+
1533+ const int64_t start_time = butil::cpuwide_time_us ();
1534+ while (messenger->ConnectionCount () < 1 ) {
1535+ bthread_usleep (1000 );
1536+ ASSERT_LT (butil::cpuwide_time_us (), start_time + 1000000L )
1537+ << " Too long!" ;
1538+ }
1539+
1540+ std::vector<brpc::SocketId> connections;
1541+ messenger->ListConnections (&connections);
1542+ ASSERT_EQ (1ul , connections.size ());
1543+
1544+ {
1545+ brpc::SocketUniquePtr accepted_socket;
1546+ ASSERT_EQ (0 , brpc::Socket::Address (connections[0 ], &accepted_socket));
1547+ ASSERT_GT (accepted_socket->fd (), 0 );
1548+ CheckSocketBufferValues (accepted_socket->fd (), expected);
1549+ ASSERT_EQ (0 , accepted_socket->SetFailed ());
1550+ }
1551+
1552+ {
1553+ brpc::SocketUniquePtr client_socket;
1554+ ASSERT_EQ (0 , brpc::Socket::Address (id, &client_socket));
1555+ ASSERT_EQ (0 , client_socket->SetFailed ());
1556+ }
1557+ server.Stop (0 );
1558+ server.Join ();
1559+ }
1560+
14281561#if defined(OS_LINUX)
14291562void CheckTCPUserTimeout (int fd, int expect_tcp_user_timeout) {
14301563 int tcp_user_timeout = 0 ;
0 commit comments