svn commit: r330781 - head/lib/libipsec

Andrey V. Elsukov ae at FreeBSD.org
Sun Mar 11 19:26:35 UTC 2018


Author: ae
Date: Sun Mar 11 19:26:34 2018
New Revision: 330781
URL: https://svnweb.freebsd.org/changeset/base/330781

Log:
  Update pfkey_open() function to set socket's write buffer size to
  128k and receive buffer size to 2MB. In case if system has bigger
  default values, do not lower them.
  
  This should partially solve the problem, when setkey(8) returns
  EAGAIN error on systems with many SAs or SPs.
  
  PR:		88336
  Obtained from:	NetBSD/ipsec-tools
  MFC after:	2 weeks

Modified:
  head/lib/libipsec/pfkey.c

Modified: head/lib/libipsec/pfkey.c
==============================================================================
--- head/lib/libipsec/pfkey.c	Sun Mar 11 19:22:58 2018	(r330780)
+++ head/lib/libipsec/pfkey.c	Sun Mar 11 19:26:34 2018	(r330781)
@@ -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;


More information about the svn-src-head mailing list