blob: 8c5dd0105e7fe3848c919ffae72d94090ec921be [file] [log] [blame]
Rashmica Gupta04273e92023-06-16 16:03:37 +10001#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
10int 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");
Rashmica Gupta178531a2023-07-06 12:21:20 +100023 if (fp == NULL) {
24 return -1;
25 }
26
27 if (fgets(line, sizeof(line), fp) == NULL) {
Rashmica Gupta04273e92023-06-16 16:03:37 +100028 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
53int 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
77int 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}