From ba3b9dbf065438402d89655d7baefb0ccc6f0663 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Feb 2018 14:55:46 +0100 Subject: [PATCH] libbb: introduce and use bb_getsockname() function old new delta bb_getsockname - 18 +18 xrtnl_open 88 83 -5 do_iplink 1216 1209 -7 arping_main 1686 1668 -18 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/3 up/down: 18/-30) Total: -12 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/bb_getsockname.c | 19 +++++++++++++++++++ networking/arping.c | 15 +++++---------- networking/inetd.c | 5 ++--- networking/libiproute/iplink.c | 4 +--- networking/libiproute/libnetlink.c | 5 +---- 6 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 libbb/bb_getsockname.c diff --git a/include/libbb.h b/include/libbb.h index e2bedaf41..2c34859a2 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -636,6 +636,7 @@ void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */ int setsockopt_keepalive(int fd) FAST_FUNC; int setsockopt_broadcast(int fd) FAST_FUNC; int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC; +int bb_getsockname(int sockfd, void *addr, socklen_t addrlen) FAST_FUNC; /* NB: returns port in host byte order */ unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC; typedef struct len_and_sockaddr { diff --git a/libbb/bb_getsockname.c b/libbb/bb_getsockname.c new file mode 100644 index 000000000..1af9b39b9 --- /dev/null +++ b/libbb/bb_getsockname.c @@ -0,0 +1,19 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//kbuild:lib-y += bb_getsockname.o + +#include "libbb.h" + +int FAST_FUNC bb_getsockname(int sockfd, void *addr, socklen_t addrlen) +{ + /* The usefullness of this function is that for getsockname(), + * addrlen must go on stack (to _have_ an address to be passed), + * but many callers do not need its modified value. + * By using this shim, they can avoid unnecessary stack spillage. + */ + return getsockname(sockfd, (struct sockaddr *)addr, &addrlen); +} diff --git a/networking/arping.c b/networking/arping.c index a16f04b9f..59092a7d7 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -363,15 +363,13 @@ int arping_main(int argc UNUSED_PARAM, char **argv) xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); } else { /* !(option_mask32 & DAD) case */ /* Find IP address on this iface */ - socklen_t alen = sizeof(saddr); - saddr.sin_port = htons(1025); saddr.sin_addr = dst; if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0) bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); - getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); + bb_getsockname(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); //never happens: //if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) // bb_perror_msg_and_die("getsockname"); @@ -387,13 +385,10 @@ int arping_main(int argc UNUSED_PARAM, char **argv) me.sll_protocol = htons(ETH_P_ARP); xbind(sock_fd, (struct sockaddr *) &me, sizeof(me)); - { - socklen_t alen = sizeof(me); - getsockname(sock_fd, (struct sockaddr *) &me, &alen); - //never happens: - //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) - // bb_perror_msg_and_die("getsockname"); - } + bb_getsockname(sock_fd, (struct sockaddr *) &me, sizeof(me)); + //never happens: + //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) + // bb_perror_msg_and_die("getsockname"); if (me.sll_halen == 0) { bb_error_msg(err_str, "is not ARPable (no ll address)"); BUILD_BUG_ON(DAD != 2); diff --git a/networking/inetd.c b/networking/inetd.c index 4dfa0089a..6843845fb 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -497,10 +497,9 @@ static void register_rpc(servtab_t *sep) { int n; struct sockaddr_in ir_sin; - socklen_t size; - size = sizeof(ir_sin); - if (getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, &size) < 0) { + if (bb_getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, sizeof(ir_sin)) < 0) { +//TODO: verify that such failure is even possible in Linux kernel bb_perror_msg("getsockname"); return; } diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index aef5f6490..f38fba055 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -132,7 +132,6 @@ static int get_address(char *dev, int *htype) { struct ifreq ifr; struct sockaddr_ll me; - socklen_t alen; int s; s = xsocket(PF_PACKET, SOCK_DGRAM, 0); @@ -146,8 +145,7 @@ static int get_address(char *dev, int *htype) me.sll_ifindex = ifr.ifr_ifindex; me.sll_protocol = htons(ETH_P_LOOP); xbind(s, (struct sockaddr*)&me, sizeof(me)); - alen = sizeof(me); - getsockname(s, (struct sockaddr*)&me, &alen); + bb_getsockname(s, (struct sockaddr*)&me, sizeof(me)); //never happens: //if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) // bb_perror_msg_and_die("getsockname"); diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c index f08d862d0..40955fcae 100644 --- a/networking/libiproute/libnetlink.c +++ b/networking/libiproute/libnetlink.c @@ -15,16 +15,13 @@ void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) { - socklen_t addr_len; - memset(rth, 0, sizeof(*rth)); rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); rth->local.nl_family = AF_NETLINK; /*rth->local.nl_groups = subscriptions;*/ xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); - addr_len = sizeof(rth->local); - getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len); + bb_getsockname(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); /* too much paranoia if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0)