]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
options: add link_rcvbuf variable
authorRoy Marples <roy@marples.name>
Thu, 14 Mar 2019 00:17:26 +0000 (00:17 +0000)
committerRoy Marples <roy@marples.name>
Thu, 14 Mar 2019 00:17:26 +0000 (00:17 +0000)
Sets SO_RCVBUF on the link socket to the designated size.
On a busy system this can be inflated to avoid buffer overflow.

However, dhcpcd *will* cope fine with overflow on NetBSD, OpenBSD
and Linux with a call to getifaddrs(3), but that might be too
heavy weight depending on the libc implementation as most
don't report address flags via this method.

src/dhcpcd.c
src/dhcpcd.conf.5.in
src/dhcpcd.h
src/if-options.c

index f79271401a09d85e8ad86f6f5074178e5da51681..8986a9b455a6ad633d921cf5c738cee3f76042c1 100644 (file)
@@ -1128,6 +1128,22 @@ dhcpcd_checkcarrier(void *arg)
        dhcpcd_handlecarrier(ifp->ctx, LINK_UNKNOWN, ifp->flags, ifp->name);
 }
 
+#ifndef SMALL
+static void
+dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx)
+{
+       socklen_t socklen;
+
+       if (ctx->link_rcvbuf == 0)
+               return;
+
+       socklen = sizeof(ctx->link_rcvbuf);
+       if (setsockopt(ctx->link_fd, SOL_SOCKET,
+           SO_RCVBUF, &ctx->link_rcvbuf, socklen) == -1)
+               logerr(__func__);
+}
+#endif
+
 void
 dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx)
 {
@@ -1148,6 +1164,9 @@ dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx)
                eloop_exit(ctx->eloop, EXIT_FAILURE);
                return;
        }
+#ifndef SMALL
+       dhcpcd_setlinkrcvbuf(ctx);
+#endif
        eloop_event_add(ctx->eloop, ctx->link_fd, dhcpcd_handlelink, ctx);
 
        /* Work out the current interfaces. */
@@ -1993,6 +2012,9 @@ printpidfile:
                logerr("%s: if_opensockets", __func__);
                goto exit_failure;
        }
+#ifndef SMALL
+       dhcpcd_setlinkrcvbuf(&ctx);
+#endif
 
        /* When running dhcpcd against a single interface, we need to retain
         * the old behaviour of waiting for an IP address */
index f792b15ffede8b3073e5061af47711a1f0e467bf..70b38ae5ae8c9c48b177e01e723da063cd544048 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd September 15, 2018
+.Dd March 8, 2019
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -429,6 +429,12 @@ globally but needs to be enabled for one interface.
 .It Ic leasetime Ar seconds
 Request a leasetime of
 .Ar seconds .
+.It Ic link_rcvbuf Ar size
+Override the size of the link receive buffer from the kernel default.
+While
+.Nm dhcpcd
+will recover from link buffer overflows,
+this may not be desirable on heavily loaded systems.
 .It Ic logfile Ar logfile
 Writes to the specified
 .Ar logfile
index df229fd337cb0d59fc19b681baf4aa382556c9ae..4df57a88aaa8295631a2512fc16c60480c7f24ec 100644 (file)
@@ -145,6 +145,9 @@ struct dhcpcd_ctx {
        int pf_inet_fd;
        void *priv;
        int link_fd;
+#ifndef SMALL
+       int link_rcvbuf;
+#endif
        int seq;        /* route message sequence no */
        int sseq;       /* successful seq no sent */
 
index 273546299a623915f8b1c5a33440417649fb63a3..8f6c03721f8bc515ec045e9eb3b495b5b5e76ec8 100644 (file)
@@ -64,7 +64,7 @@
 #define O_IPV6RS               O_BASE + 4
 #define O_NOIPV6RS             O_BASE + 5
 #define O_IPV6RA_FORK          O_BASE + 6
-// unused                      O_BASE + 7
+#define O_LINK_RCVBUF          O_BASE + 7
 // unused                      O_BASE + 8
 #define O_NOALIAS              O_BASE + 9
 #define O_IA_NA                        O_BASE + 10
@@ -204,6 +204,7 @@ const struct option cf_options[] = {
        {"lastleaseextend", no_argument,       NULL, O_LASTLEASE_EXTEND},
        {"inactive",        no_argument,       NULL, O_INACTIVE},
        {"mudurl",          required_argument, NULL, O_MUDURL},
+       {"link_rcvbuf",     required_argument, NULL, O_LINK_RCVBUF},
        {NULL,              0,                 NULL, '\0'}
 };
 
@@ -2173,6 +2174,16 @@ err_sla:
                }
                *ifo->mudurl = (uint8_t)s;
                break;
+       case O_LINK_RCVBUF:
+#ifndef SMALL
+               ARG_REQUIRED;
+               ctx->link_rcvbuf = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e);
+               if (e) {
+                       logerrx("failed to convert link_rcvbuf %s", arg);
+                       return -1;
+               }
+#endif
+               break;
        default:
                return 0;
        }