Skip to content

Commit f7a6397

Browse files
committed
BSD: Loop when pulling routes into our buffer if no memory
We need to make two sysctls to pull the route table from the kernel. The first one works out the size of the buffer required and the second one populates it. It's possible for more routes to be added between these two calls causing the second call to fail with ENOMEM. If this happens, just re-query the size needed and try again. Fixes #466.
1 parent b7105e1 commit f7a6397

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/if-bsd.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -965,19 +965,24 @@ if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af)
965965
struct rt_msghdr *rtm;
966966
int mib[6] = { CTL_NET, PF_ROUTE, 0, af, NET_RT_DUMP, 0 };
967967
size_t bufl;
968-
char *buf, *p, *end;
968+
char *buf = NULL, *p, *end;
969969
struct rt rt, *rtn;
970970

971+
again:
971972
if (if_sysctl(ctx, mib, __arraycount(mib), NULL, &bufl, NULL, 0) == -1)
972-
return -1;
973-
if (bufl == 0)
973+
goto err;
974+
if (bufl == 0) {
975+
free(buf);
974976
return 0;
975-
if ((buf = malloc(bufl)) == NULL)
976-
return -1;
977+
}
978+
if ((p = realloc(buf, bufl)) == NULL)
979+
goto err;
980+
buf = p;
977981
if (if_sysctl(ctx, mib, __arraycount(mib), buf, &bufl, NULL, 0) == -1)
978982
{
979-
free(buf);
980-
return -1;
983+
if (errno == ENOMEM)
984+
goto again;
985+
goto err;
981986
}
982987

983988
end = buf + bufl;
@@ -1001,6 +1006,10 @@ if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af)
10011006
}
10021007
free(buf);
10031008
return p == end ? 0 : -1;
1009+
1010+
err:
1011+
free(buf);
1012+
return -1;
10041013
}
10051014

10061015
#ifdef INET

0 commit comments

Comments
 (0)