[git commit] libbb: introduce and use bb_getsockname()

Denys Vlasenko vda.linux at googlemail.com
Sun Feb 11 13:55:46 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=ba3b9dbf065438402d89655d7baefb0ccc6f0663
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 <vda.linux at googlemail.com>
---
 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(-)

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)


More information about the busybox-cvs mailing list