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 <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-02-11 14:55:46 +01:00
parent d3162773d5
commit ba3b9dbf06
6 changed files with 29 additions and 20 deletions

View 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_keepalive(int fd) FAST_FUNC;
int setsockopt_broadcast(int fd) FAST_FUNC; int setsockopt_broadcast(int fd) FAST_FUNC;
int setsockopt_bindtodevice(int fd, const char *iface) 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 */ /* NB: returns port in host byte order */
unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC; unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC;
typedef struct len_and_sockaddr { typedef struct len_and_sockaddr {

19
libbb/bb_getsockname.c Normal file
View File

@ -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);
}

View File

@ -363,15 +363,13 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
} else { /* !(option_mask32 & DAD) case */ } else { /* !(option_mask32 & DAD) case */
/* Find IP address on this iface */ /* Find IP address on this iface */
socklen_t alen = sizeof(saddr);
saddr.sin_port = htons(1025); saddr.sin_port = htons(1025);
saddr.sin_addr = dst; saddr.sin_addr = dst;
if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0) if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0)
bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE");
xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); 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: //never happens:
//if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) //if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1)
// bb_perror_msg_and_die("getsockname"); // 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); me.sll_protocol = htons(ETH_P_ARP);
xbind(sock_fd, (struct sockaddr *) &me, sizeof(me)); xbind(sock_fd, (struct sockaddr *) &me, sizeof(me));
{ bb_getsockname(sock_fd, (struct sockaddr *) &me, sizeof(me));
socklen_t alen = sizeof(me);
getsockname(sock_fd, (struct sockaddr *) &me, &alen);
//never happens: //never happens:
//if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1)
// bb_perror_msg_and_die("getsockname"); // bb_perror_msg_and_die("getsockname");
}
if (me.sll_halen == 0) { if (me.sll_halen == 0) {
bb_error_msg(err_str, "is not ARPable (no ll address)"); bb_error_msg(err_str, "is not ARPable (no ll address)");
BUILD_BUG_ON(DAD != 2); BUILD_BUG_ON(DAD != 2);

View File

@ -497,10 +497,9 @@ static void register_rpc(servtab_t *sep)
{ {
int n; int n;
struct sockaddr_in ir_sin; struct sockaddr_in ir_sin;
socklen_t size;
size = sizeof(ir_sin); if (bb_getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, sizeof(ir_sin)) < 0) {
if (getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, &size) < 0) { //TODO: verify that such failure is even possible in Linux kernel
bb_perror_msg("getsockname"); bb_perror_msg("getsockname");
return; return;
} }

View File

@ -132,7 +132,6 @@ static int get_address(char *dev, int *htype)
{ {
struct ifreq ifr; struct ifreq ifr;
struct sockaddr_ll me; struct sockaddr_ll me;
socklen_t alen;
int s; int s;
s = xsocket(PF_PACKET, SOCK_DGRAM, 0); 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_ifindex = ifr.ifr_ifindex;
me.sll_protocol = htons(ETH_P_LOOP); me.sll_protocol = htons(ETH_P_LOOP);
xbind(s, (struct sockaddr*)&me, sizeof(me)); xbind(s, (struct sockaddr*)&me, sizeof(me));
alen = sizeof(me); bb_getsockname(s, (struct sockaddr*)&me, sizeof(me));
getsockname(s, (struct sockaddr*)&me, &alen);
//never happens: //never happens:
//if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) //if (getsockname(s, (struct sockaddr*)&me, &alen) == -1)
// bb_perror_msg_and_die("getsockname"); // bb_perror_msg_and_die("getsockname");

View File

@ -15,16 +15,13 @@
void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
{ {
socklen_t addr_len;
memset(rth, 0, sizeof(*rth)); memset(rth, 0, sizeof(*rth));
rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
rth->local.nl_family = AF_NETLINK; rth->local.nl_family = AF_NETLINK;
/*rth->local.nl_groups = subscriptions;*/ /*rth->local.nl_groups = subscriptions;*/
xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local));
addr_len = sizeof(rth->local); bb_getsockname(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local));
getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len);
/* too much paranoia /* too much paranoia
if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0)