aboutsummaryrefslogtreecommitdiff
path: root/lib/libipsec
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libipsec')
-rw-r--r--lib/libipsec/pfkey.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c
index 02c58813a18d..d1aae7321c2e 100644
--- a/lib/libipsec/pfkey.c
+++ b/lib/libipsec/pfkey.c
@@ -1595,10 +1595,12 @@ pfkey_send_x5(so, type, spid)
* others : success and return value of socket.
*/
int
-pfkey_open()
+pfkey_open(void)
{
int so;
- const int bufsiz = 128 * 1024; /*is 128K enough?*/
+ int bufsiz_current, bufsiz_wanted;
+ int ret;
+ socklen_t len;
if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
__ipsec_set_strerror(strerror(errno));
@@ -1609,8 +1611,28 @@ pfkey_open()
* This is a temporary workaround for KAME PR 154.
* Don't really care even if it fails.
*/
- (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
- (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
+ /* Try to have 128k. If we have more, do not lower it. */
+ bufsiz_wanted = 128 * 1024;
+ len = sizeof(bufsiz_current);
+ ret = getsockopt(so, SOL_SOCKET, SO_SNDBUF,
+ &bufsiz_current, &len);
+ if ((ret < 0) || (bufsiz_current < bufsiz_wanted))
+ (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF,
+ &bufsiz_wanted, sizeof(bufsiz_wanted));
+
+ /* Try to have have at least 2MB. If we have more, do not lower it. */
+ bufsiz_wanted = 2 * 1024 * 1024;
+ len = sizeof(bufsiz_current);
+ ret = getsockopt(so, SOL_SOCKET, SO_RCVBUF,
+ &bufsiz_current, &len);
+ if (ret < 0)
+ bufsiz_current = 128 * 1024;
+
+ for (; bufsiz_wanted > bufsiz_current; bufsiz_wanted /= 2) {
+ if (setsockopt(so, SOL_SOCKET, SO_RCVBUF,
+ &bufsiz_wanted, sizeof(bufsiz_wanted)) == 0)
+ break;
+ }
__ipsec_errcode = EIPSEC_NO_ERROR;
return so;