diff options
author | Peter Jones <pjones@redhat.com> | 2007-09-06 15:17:45 +0000 |
---|---|---|
committer | Peter Jones <pjones@redhat.com> | 2007-09-06 15:17:45 +0000 |
commit | f79f9ae3c1c9bc74df2d447b02264d8021621dd4 (patch) | |
tree | 3fcf7745eef5719386bb9b0fb15f1edbe4c0523d /isys | |
parent | 296f45ab04b828d9d3ee425dbba1489809caa206 (diff) | |
download | anaconda-f79f9ae3c1c9bc74df2d447b02264d8021621dd4.tar.gz anaconda-f79f9ae3c1c9bc74df2d447b02264d8021621dd4.tar.xz anaconda-f79f9ae3c1c9bc74df2d447b02264d8021621dd4.zip |
rework netlink_get_interface_ip to handle large recvfrom() responses
without doing its own buffering or leaking memory.
Diffstat (limited to 'isys')
-rw-r--r-- | isys/nl.c | 41 |
1 files changed, 18 insertions, 23 deletions
@@ -257,7 +257,8 @@ int netlink_get_interface_ip(int index, int family, void *addr) { * @return 0 on succes, -1 on error. */ int netlink_init_interfaces_list(void) { - int sock, len, alen, r, bufsz, readsz, havemsg, namelen; + int sock, len, alen, r, namelen; + ssize_t bufsz, readsz; char *buf = NULL; struct nlmsghdr *nlh; struct ifinfomsg *ifi; @@ -283,34 +284,28 @@ int netlink_init_interfaces_list(void) { return -1; } - /* read back messages */ - if ((buf = calloc(BUFSZ, sizeof(char))) == NULL) { - perror("calloc on 1st buf in netlink_init_interfaces_list"); + while ((bufsz = recvfrom(sock, NULL, 0, MSG_PEEK|MSG_TRUNC|MSG_WAITALL, + NULL, 0)) <= 0) { + if (bufsz < 0 && errno != EAGAIN) { + perror("1st recvfrom in netlink_init_interfaces_list"); + close(sock); + return -1; + } + } + + if ((buf = alloca(bufsz)) == NULL) { + perror("calloc on msg buf in netlink_init_interfaces_list"); close(sock); return -1; } + memset(buf, '\0', bufsz); - havemsg = 0; - readsz = BUFSZ; - while (!havemsg) { - bufsz = recvfrom(sock, buf, readsz, 0, NULL, 0); - - if (bufsz < 0) { - perror("recvfrom in netlink_init_interfaces_list"); + recvfrom(sock, buf, bufsz, 0, NULL, 0); + while ((readsz = recvfrom(sock, buf, bufsz, MSG_WAITALL, NULL, 0)) < 0) { + if (errno != EAGAIN) { + perror("2nd recvfrom in netlink_init_interfaces_list"); close(sock); return -1; - } else if (bufsz > readsz) { - free(buf); - buf = NULL; - - readsz = bufsz; - if ((buf = calloc(readsz, sizeof(char))) == NULL) { - perror("calloc on 2nd buf in netlink_init_interfaces_list"); - close(sock); - return -1; - } - } else { - havemsg = 1; } } |