mirror of
https://salsa.debian.org/ha-team/libqb
synced 2026-08-08 11:14:07 +00:00
High: ipcc: Add abilty to verify dgram kernel buffer size meets max msg value
This commit is contained in:
parent
40e163adba
commit
65d044be18
@ -70,10 +70,33 @@ typedef struct qb_ipcc_connection qb_ipcc_connection_t;
|
||||
* @param name name of the service.
|
||||
* @param max_msg_size biggest msg size.
|
||||
* @return NULL (error: see errno) or a connection object.
|
||||
*
|
||||
* @note It is recommended to do a one time check on the
|
||||
* max_msg_size value using qb_ipcc_verify_dgram_max_msg_size
|
||||
* _BEFORE_ calling the connect function when IPC_SOCKET is in use.
|
||||
* Some distributions while allow large message buffers to be
|
||||
* set on the socket, but not actually honor them because of
|
||||
* kernel state values. The qb_ipcc_verify_dgram_max_msg_size
|
||||
* function both sets the socket buffer size and verifies it by
|
||||
* doing a send/recv.
|
||||
*/
|
||||
qb_ipcc_connection_t*
|
||||
qb_ipcc_connect(const char *name, size_t max_msg_size);
|
||||
|
||||
/**
|
||||
* Test kernel dgram socket buffers to verify the largest size up
|
||||
* to the max_msg_size value a single msg can be. Rounds down to the
|
||||
* nearest 1k.
|
||||
*
|
||||
* @param max_msg_size biggest msg size.
|
||||
* @return -1 if max size can not be detected, positive value
|
||||
* representing the largest single msg up to max_msg_size
|
||||
* that can successfully be sent over a unix dgram socket.
|
||||
*/
|
||||
int32_t
|
||||
qb_ipcc_verify_dgram_max_msg_size(size_t max_msg_size);
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect an IPC connection.
|
||||
*
|
||||
|
||||
@ -107,7 +107,12 @@ set_sock_size(int sockfd, size_t max_msg_size)
|
||||
qb_util_log(LOG_DEBUG, "%d: getsockopt(%d, needed:%d) actual:%d",
|
||||
rc, sockfd, max_msg_size, optval);
|
||||
|
||||
if (rc == 0 && optval < max_msg_size) {
|
||||
/* the optvat <= max_msg_size check is weird...
|
||||
* during testing it was discovered in some instances if the
|
||||
* default optval is exactly equal to our max_msg_size, we couldn't
|
||||
* actually send a message that large unless we explicilty set
|
||||
* it using setsockopt... there is no good explaination for this. */
|
||||
if (rc == 0 && optval <= max_msg_size) {
|
||||
optval = max_msg_size;
|
||||
optlen = sizeof(optval);
|
||||
rc = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &optval, optlen);
|
||||
@ -115,6 +120,59 @@ set_sock_size(int sockfd, size_t max_msg_size)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
dgram_verify_msg_size(size_t max_msg_size)
|
||||
{
|
||||
int rc = -1;
|
||||
int sockets[2];
|
||||
char buf[max_msg_size];
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) {
|
||||
goto cleanup_socks;
|
||||
}
|
||||
|
||||
if (set_sock_size(sockets[0], max_msg_size) != 0) {
|
||||
goto cleanup_socks;
|
||||
}
|
||||
if (set_sock_size(sockets[1], max_msg_size) != 0) {
|
||||
goto cleanup_socks;
|
||||
}
|
||||
|
||||
if ((rc = write(sockets[1], buf, max_msg_size)) < 0) {
|
||||
goto cleanup_socks;
|
||||
}
|
||||
if (read(sockets[0], buf, max_msg_size) != max_msg_size) {
|
||||
goto cleanup_socks;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
cleanup_socks:
|
||||
close(sockets[0]);
|
||||
close(sockets[1]);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_ipcc_verify_dgram_max_msg_size(size_t max_msg_size)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t last = -1;
|
||||
|
||||
if (dgram_verify_msg_size(max_msg_size) == 0) {
|
||||
return max_msg_size;
|
||||
}
|
||||
|
||||
for (i = 1024; i < max_msg_size; i+=1024) {
|
||||
if (dgram_verify_msg_size(i) != 0) {
|
||||
break;
|
||||
}
|
||||
last = i;
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/*
|
||||
* bind to "base_name-local_name"
|
||||
* connect to "base_name-remote_name"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user