socket_utils_test.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include "src/core/lib/iomgr/port.h"
  19. // This test won't work except with posix sockets enabled
  20. #ifdef GRPC_POSIX_SOCKET_UTILS_COMMON
  21. #include <errno.h>
  22. #include <netinet/in.h>
  23. #include <netinet/ip.h>
  24. #include <string.h>
  25. #include <grpc/support/alloc.h>
  26. #include <grpc/support/log.h>
  27. #include <grpc/support/sync.h>
  28. #include "src/core/lib/gpr/useful.h"
  29. #include "src/core/lib/iomgr/socket_mutator.h"
  30. #include "src/core/lib/iomgr/socket_utils_posix.h"
  31. #include "test/core/util/test_config.h"
  32. struct test_socket_mutator {
  33. grpc_socket_mutator base;
  34. int option_value;
  35. };
  36. static bool mutate_fd(int fd, grpc_socket_mutator* mutator) {
  37. int newval;
  38. socklen_t intlen = sizeof(newval);
  39. struct test_socket_mutator* m =
  40. reinterpret_cast<struct test_socket_mutator*>(mutator);
  41. if (0 != setsockopt(fd, IPPROTO_IP, IP_TOS, &m->option_value,
  42. sizeof(m->option_value))) {
  43. return false;
  44. }
  45. if (0 != getsockopt(fd, IPPROTO_IP, IP_TOS, &newval, &intlen)) {
  46. return false;
  47. }
  48. if (newval != m->option_value) {
  49. return false;
  50. }
  51. return true;
  52. }
  53. static bool mutate_fd_2(const grpc_mutate_socket_info* info,
  54. grpc_socket_mutator* mutator) {
  55. int newval;
  56. socklen_t intlen = sizeof(newval);
  57. struct test_socket_mutator* m =
  58. reinterpret_cast<struct test_socket_mutator*>(mutator);
  59. if (0 != setsockopt(info->fd, IPPROTO_IP, IP_TOS, &m->option_value,
  60. sizeof(m->option_value))) {
  61. return false;
  62. }
  63. if (0 != getsockopt(info->fd, IPPROTO_IP, IP_TOS, &newval, &intlen)) {
  64. return false;
  65. }
  66. if (newval != m->option_value) {
  67. return false;
  68. }
  69. return true;
  70. }
  71. static void destroy_test_mutator(grpc_socket_mutator* mutator) {
  72. struct test_socket_mutator* m =
  73. reinterpret_cast<struct test_socket_mutator*>(mutator);
  74. gpr_free(m);
  75. }
  76. static int compare_test_mutator(grpc_socket_mutator* a,
  77. grpc_socket_mutator* b) {
  78. struct test_socket_mutator* ma =
  79. reinterpret_cast<struct test_socket_mutator*>(a);
  80. struct test_socket_mutator* mb =
  81. reinterpret_cast<struct test_socket_mutator*>(b);
  82. return grpc_core::QsortCompare(ma->option_value, mb->option_value);
  83. }
  84. static const grpc_socket_mutator_vtable mutator_vtable = {
  85. mutate_fd, compare_test_mutator, destroy_test_mutator, nullptr};
  86. static const grpc_socket_mutator_vtable mutator_vtable2 = {
  87. nullptr, compare_test_mutator, destroy_test_mutator, mutate_fd_2};
  88. static void test_with_vtable(const grpc_socket_mutator_vtable* vtable) {
  89. int sock = socket(PF_INET, SOCK_STREAM, 0);
  90. GPR_ASSERT(sock > 0);
  91. struct test_socket_mutator mutator;
  92. grpc_socket_mutator_init(&mutator.base, vtable);
  93. mutator.option_value = IPTOS_LOWDELAY;
  94. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  95. "set_socket_with_mutator",
  96. grpc_set_socket_with_mutator(sock, GRPC_FD_CLIENT_CONNECTION_USAGE,
  97. (grpc_socket_mutator*)&mutator)));
  98. mutator.option_value = IPTOS_THROUGHPUT;
  99. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  100. "set_socket_with_mutator",
  101. grpc_set_socket_with_mutator(sock, GRPC_FD_CLIENT_CONNECTION_USAGE,
  102. (grpc_socket_mutator*)&mutator)));
  103. mutator.option_value = IPTOS_RELIABILITY;
  104. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  105. "set_socket_with_mutator",
  106. grpc_set_socket_with_mutator(sock, GRPC_FD_CLIENT_CONNECTION_USAGE,
  107. (grpc_socket_mutator*)&mutator)));
  108. mutator.option_value = -1;
  109. auto err = grpc_set_socket_with_mutator(
  110. sock, GRPC_FD_CLIENT_CONNECTION_USAGE,
  111. reinterpret_cast<grpc_socket_mutator*>(&mutator));
  112. GPR_ASSERT(err != GRPC_ERROR_NONE);
  113. GRPC_ERROR_UNREF(err);
  114. }
  115. int main(int argc, char** argv) {
  116. int sock;
  117. grpc::testing::TestEnvironment env(argc, argv);
  118. sock = socket(PF_INET, SOCK_STREAM, 0);
  119. GPR_ASSERT(sock > 0);
  120. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_nonblocking",
  121. grpc_set_socket_nonblocking(sock, 1)));
  122. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_nonblocking",
  123. grpc_set_socket_nonblocking(sock, 0)));
  124. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_cloexec",
  125. grpc_set_socket_cloexec(sock, 1)));
  126. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_cloexec",
  127. grpc_set_socket_cloexec(sock, 0)));
  128. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_reuse_addr",
  129. grpc_set_socket_reuse_addr(sock, 1)));
  130. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_reuse_addr",
  131. grpc_set_socket_reuse_addr(sock, 0)));
  132. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_low_latency",
  133. grpc_set_socket_low_latency(sock, 1)));
  134. GPR_ASSERT(GRPC_LOG_IF_ERROR("set_socket_low_latency",
  135. grpc_set_socket_low_latency(sock, 0)));
  136. test_with_vtable(&mutator_vtable);
  137. test_with_vtable(&mutator_vtable2);
  138. close(sock);
  139. return 0;
  140. }
  141. #else /* GRPC_POSIX_SOCKET_UTILS_COMMON */
  142. int main(int argc, char** argv) { return 1; }
  143. #endif /* GRPC_POSIX_SOCKET_UTILS_COMMON */