mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-02-01 15:35:00 +00:00
*: always set SO_SNDBUF and SO_RCVBUF using a best effort approach
If we fail to set any socket's buffer size, try again with a smaller value and keep going until it succeeds. This is better than just giving up or, even worse, abort the creation of a socket (ospf6d and ripd). Fix broken ospf6d on FreeBSD. Signed-off-by: Renato Westphal <renato@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
de587d745e
commit
6228a3b874
@ -151,28 +151,6 @@ bgp_md5_unset (struct peer *peer)
|
||||
return bgp_md5_set_password (peer, NULL);
|
||||
}
|
||||
|
||||
/* Update BGP socket send buffer size */
|
||||
static void
|
||||
bgp_update_sock_send_buffer_size (int fd)
|
||||
{
|
||||
int size = BGP_SOCKET_SNDBUF_SIZE;
|
||||
int optval;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0)
|
||||
{
|
||||
zlog_err("getsockopt of SO_SNDBUF failed %s\n", safe_strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (optval < size)
|
||||
{
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0)
|
||||
{
|
||||
zlog_err("Couldn't increase send buffer: %s\n", safe_strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
|
||||
{
|
||||
@ -341,7 +319,7 @@ bgp_accept (struct thread *thread)
|
||||
}
|
||||
|
||||
/* Set socket send buffer size */
|
||||
bgp_update_sock_send_buffer_size(bgp_sock);
|
||||
setsockopt_so_sendbuf (bgp_sock, BGP_SOCKET_SNDBUF_SIZE);
|
||||
|
||||
/* Check remote IP address */
|
||||
peer1 = peer_lookup (bgp, &su);
|
||||
@ -604,7 +582,7 @@ bgp_connect (struct peer *peer)
|
||||
set_nonblocking (peer->fd);
|
||||
|
||||
/* Set socket send buffer size */
|
||||
bgp_update_sock_send_buffer_size(peer->fd);
|
||||
setsockopt_so_sendbuf (peer->fd, BGP_SOCKET_SNDBUF_SIZE);
|
||||
|
||||
if (bgp_set_socket_ttl (peer, peer->fd) < 0)
|
||||
return -1;
|
||||
|
||||
@ -29,30 +29,30 @@
|
||||
#include "sockopt.h"
|
||||
#include "sockunion.h"
|
||||
|
||||
int
|
||||
void
|
||||
setsockopt_so_recvbuf (int sock, int size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ( (ret = setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *)
|
||||
&size, sizeof (int))) < 0)
|
||||
zlog_err ("fd %d: can't setsockopt SO_RCVBUF to %d: %s",
|
||||
sock,size,safe_strerror(errno));
|
||||
int orig_req = size;
|
||||
|
||||
return ret;
|
||||
while (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) == -1)
|
||||
size /= 2;
|
||||
|
||||
if (size != orig_req)
|
||||
zlog_warn ("%s: fd %d: SO_RCVBUF set to %d (requested %d)", __func__, sock,
|
||||
size, orig_req);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
setsockopt_so_sendbuf (const int sock, int size)
|
||||
{
|
||||
int ret = setsockopt (sock, SOL_SOCKET, SO_SNDBUF,
|
||||
(char *)&size, sizeof (int));
|
||||
|
||||
if (ret < 0)
|
||||
zlog_err ("fd %d: can't setsockopt SO_SNDBUF to %d: %s",
|
||||
sock, size, safe_strerror (errno));
|
||||
int orig_req = size;
|
||||
|
||||
return ret;
|
||||
while (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) == -1)
|
||||
size /= 2;
|
||||
|
||||
if (size != orig_req)
|
||||
zlog_warn ("%s: fd %d: SO_SNDBUF set to %d (requested %d)", __func__, sock,
|
||||
size, orig_req);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@ -24,8 +24,8 @@
|
||||
|
||||
#include "sockunion.h"
|
||||
|
||||
extern int setsockopt_so_recvbuf (int sock, int size);
|
||||
extern int setsockopt_so_sendbuf (const int sock, int size);
|
||||
extern void setsockopt_so_recvbuf (int sock, int size);
|
||||
extern void setsockopt_so_sendbuf (const int sock, int size);
|
||||
extern int getsockopt_so_sendbuf (const int sock);
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
|
||||
@ -118,8 +118,6 @@ ospf6_sso (ifindex_t ifindex, struct in6_addr *group, int option)
|
||||
struct ipv6_mreq mreq6;
|
||||
int ret;
|
||||
int bufsize = (8 * 1024 * 1024);
|
||||
int optval;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
assert (ifindex);
|
||||
mreq6.ipv6mr_interface = ifindex;
|
||||
@ -134,40 +132,8 @@ ospf6_sso (ifindex_t ifindex, struct in6_addr *group, int option)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = setsockopt (ospf6_sock, SOL_SOCKET, SO_SNDBUF,
|
||||
&bufsize, sizeof (bufsize))) < 0)
|
||||
{
|
||||
zlog_err ("Couldn't increase raw wbuf size: %s\n", safe_strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = getsockopt (ospf6_sock, SOL_SOCKET, SO_SNDBUF,
|
||||
&optval, &optlen)) < 0)
|
||||
{
|
||||
zlog_err ("getsockopt of SO_SNDBUF failed with error %s\n", safe_strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
else if (optval < bufsize)
|
||||
{
|
||||
zlog_err ("Unable to SO_SNDBUF to %d, set to %d\n", bufsize, optval);
|
||||
}
|
||||
|
||||
if ((ret = setsockopt (ospf6_sock, SOL_SOCKET, SO_RCVBUF,
|
||||
&bufsize, sizeof (bufsize))) < 0)
|
||||
{
|
||||
zlog_err ("Couldn't increase raw rbuf size: %s\n", safe_strerror(errno));
|
||||
}
|
||||
|
||||
if ((ret = getsockopt (ospf6_sock, SOL_SOCKET, SO_RCVBUF,
|
||||
&optval, &optlen)) < 0)
|
||||
{
|
||||
zlog_err ("getsockopt of SO_RCVBUF failed with error %s\n", safe_strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
else if (optval < bufsize)
|
||||
{
|
||||
zlog_err ("Unable to SO_RCVBUF to %d, set to %d\n", bufsize, optval);
|
||||
}
|
||||
setsockopt_so_sendbuf (ospf6_sock, bufsize);
|
||||
setsockopt_so_recvbuf (ospf6_sock, bufsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -161,8 +161,6 @@ ospf_sock_init (void)
|
||||
int ospf_sock;
|
||||
int ret, hincl = 1;
|
||||
int bufsize = (8 * 1024 * 1024);
|
||||
int optval;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
if ( ospfd_privs.change (ZPRIVS_RAISE) )
|
||||
zlog_err ("ospf_sock_init: could not raise privs, %s",
|
||||
@ -222,38 +220,8 @@ ospf_sock_init (void)
|
||||
safe_strerror (errno) );
|
||||
}
|
||||
|
||||
if ((ret = setsockopt (ospf_sock, SOL_SOCKET, SO_RCVBUF,
|
||||
&bufsize, sizeof (bufsize))) < 0)
|
||||
{
|
||||
zlog_err ("Couldn't increase raw rbuf size: %s\n", safe_strerror(errno));
|
||||
}
|
||||
setsockopt_so_sendbuf (ospf_sock, bufsize);
|
||||
setsockopt_so_recvbuf (ospf_sock, bufsize);
|
||||
|
||||
if ((ret = getsockopt (ospf_sock, SOL_SOCKET, SO_RCVBUF,
|
||||
&optval, &optlen)) < 0)
|
||||
{
|
||||
zlog_err("getsockopt of SO_RCVBUF failed with error %s\n", safe_strerror(errno));
|
||||
}
|
||||
if (optval < bufsize)
|
||||
{
|
||||
zlog_err("Unable to SO_RCVBUF to %d, set to %d\n", bufsize, optval);
|
||||
}
|
||||
|
||||
|
||||
if ((ret = setsockopt (ospf_sock, SOL_SOCKET, SO_SNDBUF,
|
||||
&bufsize, sizeof (bufsize))) < 0)
|
||||
{
|
||||
zlog_err ("Couldn't increase raw wbuf size: %s\n", safe_strerror(errno));
|
||||
}
|
||||
|
||||
if ((ret = getsockopt (ospf_sock, SOL_SOCKET, SO_SNDBUF,
|
||||
&optval, &optlen)) < 0)
|
||||
{
|
||||
zlog_err ("getsockopt of SO_SNDBUF failed with error %s\n", safe_strerror(errno));
|
||||
}
|
||||
if (optval < bufsize)
|
||||
{
|
||||
zlog_err ("Unable to SO_SNDBUF to %d, set to %d\n", bufsize, optval);
|
||||
}
|
||||
|
||||
return ospf_sock;
|
||||
}
|
||||
|
||||
@ -111,9 +111,7 @@ ripng_make_socket (void)
|
||||
return sock;
|
||||
}
|
||||
|
||||
ret = setsockopt_so_recvbuf (sock, 8096);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
setsockopt_so_recvbuf (sock, 8096);
|
||||
ret = setsockopt_ipv6_pktinfo (sock, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user