1 #include "socket.h" 2 3 #include <errno.h> 4 #include <limits.h> 5 #include <stddef.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <sys/socket.h> 9 10 int pldm_socket_sndbuf_init(struct pldm_socket_sndbuf *ctx, int socket) 11 { 12 FILE *fp; 13 long max_buf_size; 14 char line[128]; 15 char *endptr; 16 17 if (socket == -1) { 18 return -1; 19 } 20 ctx->socket = socket; 21 22 fp = fopen("/proc/sys/net/core/wmem_max", "r"); 23 if (fp == NULL) { 24 return -1; 25 } 26 27 if (fgets(line, sizeof(line), fp) == NULL) { 28 fclose(fp); 29 return -1; 30 } 31 32 errno = 0; 33 max_buf_size = strtol(line, &endptr, 10); 34 if (errno != 0 || endptr == line) { 35 fclose(fp); 36 return -1; 37 } 38 39 fclose(fp); 40 41 if (max_buf_size > INT_MAX) { 42 max_buf_size = INT_MAX; 43 } 44 ctx->max_size = (int)max_buf_size; 45 46 if (pldm_socket_sndbuf_get(ctx)) { 47 return -1; 48 } 49 50 return 0; 51 } 52 53 int pldm_socket_sndbuf_accomodate(struct pldm_socket_sndbuf *ctx, int msg_len) 54 { 55 if (msg_len < ctx->size) { 56 return 0; 57 } 58 /* If message is bigger than the max size, don't return a failure. Set 59 * the buffer to the max size and see what happens. We don't know how 60 * much of the extra space the kernel actually uses so let it tell us if 61 * there wasn't enough space */ 62 if (msg_len > ctx->max_size) { 63 msg_len = ctx->max_size; 64 } 65 if (ctx->size == ctx->max_size) { 66 return 0; 67 } 68 int rc = setsockopt(ctx->socket, SOL_SOCKET, SO_SNDBUF, &(msg_len), 69 sizeof(msg_len)); 70 if (rc == -1) { 71 return -1; 72 } 73 ctx->size = msg_len; 74 return 0; 75 } 76 77 int pldm_socket_sndbuf_get(struct pldm_socket_sndbuf *ctx) 78 { 79 /* size returned by getsockopt is the actual size of the buffer - twice 80 * the size of the value used by setsockopt. So for consistency, return 81 * half of the buffer size */ 82 int buf_size; 83 socklen_t optlen = sizeof(buf_size); 84 int rc = getsockopt(ctx->socket, SOL_SOCKET, SO_SNDBUF, &(buf_size), 85 &optlen); 86 if (rc == -1) { 87 return -1; 88 } 89 ctx->size = buf_size / 2; 90 return 0; 91 } 92