timeout_client.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (C) 2022 Amazon.com Inc. or its affiliates. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <arpa/inet.h>
  6. #include <errno.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/socket.h>
  10. #include <sys/time.h>
  11. #include <unistd.h>
  12. #ifdef __wasi__
  13. #include <wasi_socket_ext.h>
  14. #endif
  15. int
  16. main(int argc, char *argv[])
  17. {
  18. int socket_fd;
  19. struct sockaddr_in addr;
  20. struct timeval tv = { 0, 1 };
  21. const int snd_buf_len = 8;
  22. const int data_buf_len = 1000000;
  23. char *buffer = (char *)malloc(sizeof(char) * data_buf_len);
  24. int result;
  25. socklen_t opt_len = sizeof(snd_buf_len);
  26. struct timeval snd_start_time, snd_end_time;
  27. int bool_opt = 1;
  28. if (buffer == NULL) {
  29. perror("Allocation failed, please re-run with larger heap size");
  30. return EXIT_FAILURE;
  31. }
  32. /* 127.0.0.1:1234 */
  33. addr.sin_family = AF_INET;
  34. addr.sin_port = htons(1234);
  35. addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  36. if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  37. perror("Create socket failed");
  38. goto fail1;
  39. }
  40. if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &bool_opt,
  41. sizeof(bool_opt))
  42. == -1) {
  43. perror("Failed setting SO_REUSEADDR");
  44. goto fail2;
  45. }
  46. if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
  47. perror("Failed setting SO_RCVTIMEO");
  48. goto fail2;
  49. }
  50. if (setsockopt(socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
  51. perror("Failed setting SO_SNDTIMEO");
  52. goto fail2;
  53. }
  54. if (setsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, &data_buf_len,
  55. sizeof(data_buf_len))
  56. == -1) {
  57. perror("Failed setting SO_SNDBUF");
  58. goto fail2;
  59. }
  60. if (connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  61. perror("Connect failed");
  62. goto fail2;
  63. }
  64. if (getsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, (void *)&data_buf_len,
  65. &opt_len)
  66. == -1) {
  67. perror("Failed getting SO_SNDBUF");
  68. goto fail2;
  69. }
  70. printf("Waiting on recv, which should timeout\n");
  71. result = recv(socket_fd, buffer, 1, 0);
  72. if (result != -1 || errno != EAGAIN) {
  73. perror("Recv did not timeout as expected");
  74. goto fail2;
  75. }
  76. printf("Waiting on send, which should timeout\n");
  77. gettimeofday(&snd_start_time, NULL);
  78. result = send(socket_fd, buffer, data_buf_len, 0);
  79. gettimeofday(&snd_end_time, NULL);
  80. if (result >= data_buf_len
  81. || snd_start_time.tv_sec != snd_end_time.tv_sec) {
  82. perror("Send did not timeout as expected");
  83. goto fail2;
  84. }
  85. printf("Success. Closing socket \n");
  86. close(socket_fd);
  87. free(buffer);
  88. return EXIT_SUCCESS;
  89. fail2:
  90. close(socket_fd);
  91. fail1:
  92. free(buffer);
  93. return EXIT_FAILURE;
  94. }