From a57721d14642291696be4ffd5d8bb0915fbe861b Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 8 Jul 2019 16:02:56 -0700 Subject: bind/connect cleanup. Rename the existing xbind/xconnect to xbindany/xconnectany, to make room for new xbind/xconnect that are more like 'x' versions of the regular bind and connect. Move explicit bind/connect callers over to xbind/xconnect. Of the affected commands, only netcat is actually used by Android. It was the most recent patch to netcat that made the lack of a more traditional xbind/xconnect apparent. --- lib/lib.h | 6 ++++-- lib/net.c | 14 ++++++++++++-- toys/net/ftpget.c | 4 ++-- toys/net/netcat.c | 19 +++++-------------- toys/net/ping.c | 2 +- toys/net/sntp.c | 2 +- toys/other/nbd_client.c | 2 +- toys/pending/arping.c | 9 +++------ toys/pending/dhcp6.c | 10 ++-------- toys/pending/host.c | 5 ++--- toys/pending/tcpsvd.c | 5 ++--- toys/pending/telnet.c | 2 +- toys/pending/telnetd.c | 7 ++----- toys/pending/tftpd.c | 5 ++--- toys/pending/traceroute.c | 16 +++++----------- 15 files changed, 45 insertions(+), 63 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index e354a82a..e744977f 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -348,8 +348,10 @@ int xsocket(int domain, int type, int protocol); void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len); struct addrinfo *xgetaddrinfo(char *host, char *port, int family, int socktype, int protocol, int flags); -int xconnect(struct addrinfo *ai); -int xbind(struct addrinfo *ai); +void xbind(int fd, const struct sockaddr *sa, socklen_t len); +void xconnect(int fd, const struct sockaddr *sa, socklen_t len); +int xconnectany(struct addrinfo *ai); +int xbindany(struct addrinfo *ai); int xpoll(struct pollfd *fds, int nfds, int timeout); int pollinate(int in1, int in2, int out1, int out2, int timeout, int shutdown_timeout); char *ntop(struct sockaddr *sa); diff --git a/lib/net.c b/lib/net.c index 2bb720a4..be69c9a3 100644 --- a/lib/net.c +++ b/lib/net.c @@ -56,17 +56,27 @@ int xconnbind(struct addrinfo *ai_arg, int dobind) return fd; } -int xconnect(struct addrinfo *ai) +int xconnectany(struct addrinfo *ai) { return xconnbind(ai, 0); } -int xbind(struct addrinfo *ai) +int xbindany(struct addrinfo *ai) { return xconnbind(ai, 1); } +void xbind(int fd, const struct sockaddr *sa, socklen_t len) +{ + if (bind(fd, sa, len)) perror_exit("bind"); +} + +void xconnect(int fd, const struct sockaddr *sa, socklen_t len) +{ + if (connect(fd, sa, len)) perror_exit("connect"); +} + int xpoll(struct pollfd *fds, int nfds, int timeout) { int i; diff --git a/toys/net/ftpget.c b/toys/net/ftpget.c index ad3c3030..05c53509 100644 --- a/toys/net/ftpget.c +++ b/toys/net/ftpget.c @@ -105,7 +105,7 @@ void ftpget_main(void) if (!remote) remote = toys.optargs[1]; // connect - TT.fd = xconnect(xgetaddrinfo(*toys.optargs, TT.p, 0, SOCK_STREAM, 0, + TT.fd = xconnectany(xgetaddrinfo(*toys.optargs, TT.p, 0, SOCK_STREAM, 0, AI_ADDRCONFIG)); if (getpeername(TT.fd, (void *)&si6, &sl)) perror_exit("getpeername"); @@ -147,7 +147,7 @@ void ftpget_main(void) if (!s || port<1 || port>65535) error_exit_raw(toybuf); si6.sin6_port = SWAP_BE16(port); // same field size/offset for v4 and v6 port = xsocket(si6.sin6_family, SOCK_STREAM, 0); - if (connect(port, (void *)&si6, sizeof(si6))) perror_exit("connect"); + xconnect(port, (void *)&si6, sizeof(si6)); // RETR blocks until file data read from data port, so use SIZE to check // if file exists before creating local copy diff --git a/toys/net/netcat.c b/toys/net/netcat.c index 65c41ace..0a235d1e 100644 --- a/toys/net/netcat.c +++ b/toys/net/netcat.c @@ -111,16 +111,10 @@ void netcat_main(void) sockaddr.sun_family = AF_UNIX; sockfd = xsocket(AF_UNIX, type | SOCK_CLOEXEC, 0); - if (connect(sockfd, (struct sockaddr*)&sockaddr, - sizeof(sockaddr)) != 0) { - perror_exit("could not bind to unix domain socket"); - } - + xconnect(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); } else { - struct addrinfo *addr = xgetaddrinfo(toys.optargs[0], toys.optargs[1], - family, type, 0, 0); - - sockfd = xconnect(addr); + sockfd = xconnectany(xgetaddrinfo(toys.optargs[0], toys.optargs[1], + family, type, 0, 0)); } // We have a connection. Disarm timeout. @@ -145,13 +139,10 @@ void netcat_main(void) sockaddr.sun_family = AF_UNIX; sockfd = xsocket(AF_UNIX, type | SOCK_CLOEXEC, 0); - if (bind(sockfd, (struct sockaddr*)&sockaddr, - sizeof(struct sockaddr_un)) != 0) { - perror_exit("unable to bind to UNIX domain socket"); - } + xbind(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); } else { sprintf(toybuf, "%ld", TT.p); - sockfd = xbind(xgetaddrinfo(TT.s, toybuf, family, type, 0, 0)); + sockfd = xbindany(xgetaddrinfo(TT.s, toybuf, family, type, 0, 0)); } if (listen(sockfd, 5)) error_exit("listen"); diff --git a/toys/net/ping.c b/toys/net/ping.c index 81dca99f..9ae7c856 100644 --- a/toys/net/ping.c +++ b/toys/net/ping.c @@ -155,7 +155,7 @@ void ping_main(void) } xexit(); } - if (TT.I && bind(TT.sock, sa, sizeof(srcaddr))) perror_exit("bind"); + if (TT.I) xbind(TT.sock, sa, sizeof(srcaddr)); if (toys.optflags&FLAG_m) { int mark = TT.m; diff --git a/toys/net/sntp.c b/toys/net/sntp.c index b1ecb1be..b1f3685f 100644 --- a/toys/net/sntp.c +++ b/toys/net/sntp.c @@ -88,7 +88,7 @@ void sntp_main(void) // Act as server if necessary if (FLAG(S)|FLAG(m)) { - fd = xbind(ai); + fd = xbindany(ai); if (TT.m) { struct ip_mreq group; diff --git a/toys/other/nbd_client.c b/toys/other/nbd_client.c index fcd0fca8..ad3440af 100644 --- a/toys/other/nbd_client.c +++ b/toys/other/nbd_client.c @@ -52,7 +52,7 @@ void nbd_client_main(void) // Find and connect to server - sock = xconnect(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0)); + sock = xconnectany(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0)); temp = 1; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &temp, sizeof(int)); diff --git a/toys/pending/arping.c b/toys/pending/arping.c index 6007845b..68ee5eac 100644 --- a/toys/pending/arping.c +++ b/toys/pending/arping.c @@ -242,15 +242,13 @@ void arping_main(void) saddr.sin_family = AF_INET; if (src_addr.s_addr) { saddr.sin_addr = src_addr; - if (bind(p_fd, (struct sockaddr*)&saddr, sizeof(saddr))) - perror_exit("bind"); + xbind(p_fd, (struct sockaddr*)&saddr, sizeof(saddr)); } else { uint32_t oip; saddr.sin_port = htons(1025); saddr.sin_addr = dest_addr; - if (connect(p_fd, (struct sockaddr *) &saddr, sizeof(saddr))) - perror_exit("cannot connect to remote host"); + xconnect(p_fd, (struct sockaddr *) &saddr, sizeof(saddr)); get_interface(TT.iface, NULL, &oip, NULL); src_addr.s_addr = htonl(oip); } @@ -259,8 +257,7 @@ void arping_main(void) src_pk.sll_family = AF_PACKET; src_pk.sll_protocol = htons(ETH_P_ARP); - if (bind(TT.sockfd, (struct sockaddr *)&src_pk, sizeof(src_pk))) - perror_exit("bind"); + xbind(TT.sockfd, (struct sockaddr *)&src_pk, sizeof(src_pk)); socklen_t alen = sizeof(src_pk); getsockname(TT.sockfd, (struct sockaddr *)&src_pk, &alen); diff --git a/toys/pending/dhcp6.c b/toys/pending/dhcp6.c index c69c4aed..728dc7d1 100644 --- a/toys/pending/dhcp6.c +++ b/toys/pending/dhcp6.c @@ -249,10 +249,7 @@ static void mode_raw() sockll.sll_family = AF_PACKET; sockll.sll_protocol = htons(ETH_P_IPV6); sockll.sll_ifindex = if_nametoindex(TT.interface_name); - if (bind(TT.sock, (struct sockaddr *) &sockll, sizeof(sockll))) { - xclose(TT.sock); - error_exit("MODE RAW : Bind fail.\n"); - } + xbind(TT.sock, (struct sockaddr *) &sockll, sizeof(sockll)); if (setsockopt(TT.sock, SOL_PACKET, PACKET_HOST,&constone, sizeof(int)) < 0) { if (errno != ENOPROTOOPT) error_exit("MODE RAW : Bind fail.\n"); } @@ -575,10 +572,7 @@ void dhcp6_main(void) xsetsockopt(TT.sock1, SOL_SOCKET, SO_REUSEADDR, &constone, sizeof(constone)); - if (bind(TT.sock1, (struct sockaddr *)&sinaddr6, sizeof(sinaddr6))) { - xclose(TT.sock1); - error_exit("bind failed"); - } + xbind(TT.sock1, (struct sockaddr *)&sinaddr6, sizeof(sinaddr6)); mode_raw(); set_timeout(0); diff --git a/toys/pending/host.c b/toys/pending/host.c index fa830a7d..fe0f23aa 100644 --- a/toys/pending/host.c +++ b/toys/pending/host.c @@ -121,9 +121,8 @@ void host_main(void) if ((ret = getaddrinfo(nsname, "53", &ns_hints, &ai)) < 0) error_exit("Error looking up server name: %s", gai_strerror(ret)); - int s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (s < 0 || connect(s, ai->ai_addr, ai->ai_addrlen) < 0) - perror_exit("Socket error"); + int s = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + xconnect(s, ai->ai_addr, ai->ai_addrlen); setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &(struct timeval){ .tv_sec = 5 }, sizeof(struct timeval)); printf("Using domain server %s:\n", nsname); diff --git a/toys/pending/tcpsvd.c b/toys/pending/tcpsvd.c index 31c27610..e5bd76b5 100644 --- a/toys/pending/tcpsvd.c +++ b/toys/pending/tcpsvd.c @@ -248,7 +248,7 @@ static int create_bind_sock(char *host, struct sockaddr *haddr) sockfd = xsocket(rp->ai_family, TT.udp ?SOCK_DGRAM :SOCK_STREAM, 0); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set)); if (TT.udp) setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &set, sizeof(set)); - if ((bind(sockfd, rp->ai_addr, rp->ai_addrlen)) < 0) perror_exit("Bind failed"); + xbind(sockfd, rp->ai_addr, rp->ai_addrlen); if(haddr) memcpy(haddr, rp->ai_addr, rp->ai_addrlen); freeaddrinfo(res); return sockfd; @@ -386,8 +386,7 @@ void tcpsvd_main(void) free(serv); free(clie); } - if (TT.udp && (connect(newfd, (struct sockaddr *)buf, sizeof(buf)) < 0)) - perror_exit("connect"); + if (TT.udp) xconnect(newfd, (struct sockaddr *)buf, sizeof(buf)); close(0); close(1); diff --git a/toys/pending/telnet.c b/toys/pending/telnet.c index e37b982c..b8c9c140 100644 --- a/toys/pending/telnet.c +++ b/toys/pending/telnet.c @@ -306,7 +306,7 @@ void telnet_main(void) } terminal_size(&TT.win_width, &TT.win_height); - TT.sfd = xconnect(xgetaddrinfo(*toys.optargs, port, 0, SOCK_STREAM, + TT.sfd = xconnectany(xgetaddrinfo(*toys.optargs, port, 0, SOCK_STREAM, IPPROTO_TCP, 0)); setsockopt(TT.sfd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set)); setsockopt(TT.sfd, SOL_SOCKET, SO_KEEPALIVE, &set, sizeof(set)); diff --git a/toys/pending/telnetd.c b/toys/pending/telnetd.c index 4198e63f..ad39d8c0 100644 --- a/toys/pending/telnetd.c +++ b/toys/pending/telnetd.c @@ -143,11 +143,8 @@ static int listen_socket(void) if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) == -1) perror_exit("setsockopt"); - if (bind(s, (struct sockaddr *)buf, ((af == AF_INET)? - (sizeof(struct sockaddr_in)):(sizeof(struct sockaddr_in6)))) == -1) { - close(s); - perror_exit("bind"); - } + xbind(s, (struct sockaddr *)buf, ((af == AF_INET)? + (sizeof(struct sockaddr_in)):(sizeof(struct sockaddr_in6)))); if (listen(s, 1) < 0) perror_exit("listen"); return s; diff --git a/toys/pending/tftpd.c b/toys/pending/tftpd.c index 9791ae41..b5d0558f 100644 --- a/toys/pending/tftpd.c +++ b/toys/pending/tftpd.c @@ -252,9 +252,8 @@ void tftpd_main(void) TT.sfd = xsocket(dstaddr.ss_family, SOCK_DGRAM, 0); if (setsockopt(TT.sfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&set, sizeof(set)) < 0) perror_exit("setsockopt failed"); - if (bind(TT.sfd, (void *)&srcaddr, socklen)) perror_exit("bind"); - if (connect(TT.sfd, (void *)&dstaddr, socklen) < 0) - perror_exit("can't connect to remote host"); + xbind(TT.sfd, (void *)&srcaddr, socklen); + xconnect(TT.sfd, (void *)&dstaddr, socklen); // Error condition. if (recvmsg_len<4 || recvmsg_len>TFTPD_BLKSIZE || toybuf[recvmsg_len-1]) { send_errpkt((struct sockaddr*)&dstaddr, socklen, "packet format error"); diff --git a/toys/pending/traceroute.c b/toys/pending/traceroute.c index d5ead9e2..1cfdc480 100644 --- a/toys/pending/traceroute.c +++ b/toys/pending/traceroute.c @@ -587,8 +587,7 @@ void traceroute_main(void) if (setsockopt(TT.snd_sock, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr*)&source, sizeof(struct sockaddr_in))) perror_exit("can't set multicast source interface"); - if (bind(TT.snd_sock,(struct sockaddr*)&source, - sizeof(struct sockaddr_in)) < 0) perror_exit("bind"); + xbind(TT.snd_sock,(struct sockaddr*)&source, sizeof(struct sockaddr_in)); } if(TT.first_ttl > TT.max_ttl) @@ -607,9 +606,7 @@ void traceroute_main(void) if(inet_pton(AF_INET6, TT.src_ip, &(source.sin6_addr)) <= 0) error_exit("bad address: %s", TT.src_ip); - if (bind(TT.snd_sock,(struct sockaddr*)&source, - sizeof(struct sockaddr_in6)) < 0) - error_exit("bind: Cannot assign requested address"); + xbind(TT.snd_sock,(struct sockaddr*)&source, sizeof(struct sockaddr_in6)); } else { struct sockaddr_in6 prb; socklen_t len = sizeof(prb); @@ -617,16 +614,13 @@ void traceroute_main(void) if (toys.optflags & FLAG_i) bind_to_interface(p_fd); ((struct sockaddr_in6 *)&dest)->sin6_port = htons(1025); - if (connect(p_fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_in6)) < 0) - perror_exit("can't connect to remote host"); + xconnect(p_fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_in6)); if(getsockname(p_fd, (struct sockaddr *)&prb, &len)) error_exit("probe addr failed"); close(p_fd); prb.sin6_port = 0; - if (bind(TT.snd_sock, (struct sockaddr*)&prb, - sizeof(struct sockaddr_in6))) perror_exit("bind"); - if (bind(TT.recv_sock, (struct sockaddr*)&prb, - sizeof(struct sockaddr_in6))) perror_exit("bind"); + xbind(TT.snd_sock, (struct sockaddr*)&prb, sizeof(struct sockaddr_in6)); + xbind(TT.recv_sock, (struct sockaddr*)&prb, sizeof(struct sockaddr_in6)); } inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&dest)->sin6_addr, -- cgit v1.2.3