libbb: introduce and use bb_getsockname()
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 11 Feb 2018 13:55:46 +0000 (14:55 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 11 Feb 2018 13:55:46 +0000 (14:55 +0100)
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@googlemail.com>
include/libbb.h
libbb/bb_getsockname.c [new file with mode: 0644]
networking/arping.c
networking/inetd.c
networking/libiproute/iplink.c
networking/libiproute/libnetlink.c

index e2bedaf41674dd9bf4d870998daad6aec840ca97..2c34859a25a1ad5e26d4c1249c151f79a2819e61 100644 (file)
@@ -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 (file)
index 0000000..1af9b39
--- /dev/null
@@ -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);
+}
index a16f04b9f73ba1f0b5864d33ea89e87a03d80ec0..59092a7d75a84b521e020419511546a1af2140ff 100644 (file)
@@ -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);
index 4dfa0089a6c92934182bfb5b09d5c0058a8c2811..6843845fb83d25c2af2bd095269b9dc5cc69bc39 100644 (file)
@@ -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;
        }
index aef5f6490edbaaa90513dc2c163710d3939b8dbe..f38fba055b3d0ba400773c5765bbccb5f2b2f7d2 100644 (file)
@@ -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");
index f08d862d0589993b541386a637ea4b97077354eb..40955fcae63eb92cb3ec5161701495c2186dac01 100644 (file)
 
 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)