add FEATURE_UNIX_LOCAL. By Ingo van Lil (inguin AT gmx.de)
This commit is contained in:
		@@ -9,6 +9,7 @@
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <net/if.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include "libbb.h"
 | 
			
		||||
 | 
			
		||||
void FAST_FUNC setsockopt_reuseaddr(int fd)
 | 
			
		||||
@@ -160,13 +161,26 @@ IF_FEATURE_IPV6(sa_family_t af,)
 | 
			
		||||
		int ai_flags)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	len_and_sockaddr *r = NULL;
 | 
			
		||||
	len_and_sockaddr *r;
 | 
			
		||||
	struct addrinfo *result = NULL;
 | 
			
		||||
	struct addrinfo *used_res;
 | 
			
		||||
	const char *org_host = host; /* only for error msg */
 | 
			
		||||
	const char *cp;
 | 
			
		||||
	struct addrinfo hint;
 | 
			
		||||
 | 
			
		||||
	if (ENABLE_FEATURE_UNIX_LOCAL && strncmp(host, "local:", 6) == 0) {
 | 
			
		||||
		struct sockaddr_un *sun;
 | 
			
		||||
 | 
			
		||||
		r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_un));
 | 
			
		||||
		r->len = sizeof(struct sockaddr_un);
 | 
			
		||||
		r->u.sa.sa_family = AF_UNIX;
 | 
			
		||||
		sun = (struct sockaddr_un *)&r->u.sa;
 | 
			
		||||
		safe_strncpy(sun->sun_path, host + 6, sizeof(sun->sun_path));
 | 
			
		||||
		return r;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = NULL;
 | 
			
		||||
 | 
			
		||||
	/* Ugly parsing of host:addr */
 | 
			
		||||
	if (ENABLE_FEATURE_IPV6 && host[0] == '[') {
 | 
			
		||||
		/* Even uglier parsing of [xx]:nn */
 | 
			
		||||
@@ -188,6 +202,7 @@ IF_FEATURE_IPV6(sa_family_t af,)
 | 
			
		||||
	}
 | 
			
		||||
	if (cp) { /* points to ":" or "]:" */
 | 
			
		||||
		int sz = cp - host + 1;
 | 
			
		||||
 | 
			
		||||
		host = safe_strncpy(alloca(sz), host, sz);
 | 
			
		||||
		if (ENABLE_FEATURE_IPV6 && *cp != ':') {
 | 
			
		||||
			cp++; /* skip ']' */
 | 
			
		||||
@@ -371,6 +386,13 @@ static char* FAST_FUNC sockaddr2str(const struct sockaddr *sa, int flags)
 | 
			
		||||
	int rc;
 | 
			
		||||
	socklen_t salen;
 | 
			
		||||
 | 
			
		||||
	if (ENABLE_FEATURE_UNIX_LOCAL && sa->sa_family == AF_UNIX) {
 | 
			
		||||
		struct sockaddr_un *sun = (struct sockaddr_un *)sa;
 | 
			
		||||
		return xasprintf("local:%.*s",
 | 
			
		||||
				(int) sizeof(sun->sun_path),
 | 
			
		||||
				sun->sun_path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	salen = LSA_SIZEOF_SA;
 | 
			
		||||
#if ENABLE_FEATURE_IPV6
 | 
			
		||||
	if (sa->sa_family == AF_INET)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,13 @@ config FEATURE_IPV6
 | 
			
		||||
	  Enable IPv6 support in busybox.
 | 
			
		||||
	  This adds IPv6 support in the networking applets.
 | 
			
		||||
 | 
			
		||||
config FEATURE_UNIX_LOCAL
 | 
			
		||||
	bool "Enable Unix domain socket support"
 | 
			
		||||
	default n
 | 
			
		||||
	help
 | 
			
		||||
	  Enable Unix domain socket support in all busybox networking
 | 
			
		||||
	  applets.
 | 
			
		||||
 | 
			
		||||
config FEATURE_PREFER_IPV4_ADDRESS
 | 
			
		||||
	bool "Prefer IPv4 addresses from DNS queries"
 | 
			
		||||
	default y
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,6 @@ int nc_main(int argc, char **argv)
 | 
			
		||||
	IF_NOT_NC_EXTRA (const) unsigned delay = 0;
 | 
			
		||||
	IF_NOT_NC_EXTRA (const int execparam = 0;)
 | 
			
		||||
	IF_NC_EXTRA     (char **execparam = NULL;)
 | 
			
		||||
	len_and_sockaddr *lsa;
 | 
			
		||||
	fd_set readfds, testfds;
 | 
			
		||||
	int opt; /* must be signed (getopt returns -1) */
 | 
			
		||||
 | 
			
		||||
@@ -44,17 +43,17 @@ int nc_main(int argc, char **argv)
 | 
			
		||||
		while ((opt = getopt(argc, argv,
 | 
			
		||||
		        "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0
 | 
			
		||||
		) {
 | 
			
		||||
			if (ENABLE_NC_SERVER && opt=='l')
 | 
			
		||||
			if (ENABLE_NC_SERVER && opt == 'l')
 | 
			
		||||
				IF_NC_SERVER(do_listen++);
 | 
			
		||||
			else if (ENABLE_NC_SERVER && opt=='p')
 | 
			
		||||
			else if (ENABLE_NC_SERVER && opt == 'p')
 | 
			
		||||
				IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt=='w')
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt == 'w')
 | 
			
		||||
				IF_NC_EXTRA( wsecs = xatou(optarg));
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt=='i')
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt == 'i')
 | 
			
		||||
				IF_NC_EXTRA( delay = xatou(optarg));
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt=='f')
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt == 'f')
 | 
			
		||||
				IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt=='e' && optind <= argc) {
 | 
			
		||||
			else if (ENABLE_NC_EXTRA && opt == 'e' && optind <= argc) {
 | 
			
		||||
				/* We cannot just 'break'. We should let getopt finish.
 | 
			
		||||
				** Or else we won't be able to find where
 | 
			
		||||
				** 'host' and 'port' params are
 | 
			
		||||
@@ -80,9 +79,12 @@ int nc_main(int argc, char **argv)
 | 
			
		||||
		argc -= optind;
 | 
			
		||||
		// -l and -f don't mix
 | 
			
		||||
		if (do_listen && cfd) bb_show_usage();
 | 
			
		||||
		// Listen or file modes need zero arguments, client mode needs 2
 | 
			
		||||
		if (do_listen || cfd) {
 | 
			
		||||
		// File mode needs need zero arguments, listen mode needs zero or one,
 | 
			
		||||
		// client mode needs one or two
 | 
			
		||||
		if (cfd) {
 | 
			
		||||
			if (argc) bb_show_usage();
 | 
			
		||||
		} else if (do_listen) {
 | 
			
		||||
			if (argc > 1) bb_show_usage();
 | 
			
		||||
		} else {
 | 
			
		||||
			if (!argc || argc > 2) bb_show_usage();
 | 
			
		||||
		}
 | 
			
		||||
@@ -99,24 +101,20 @@ int nc_main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
	if (!cfd) {
 | 
			
		||||
		if (do_listen) {
 | 
			
		||||
			/* create_and_bind_stream_or_die(NULL, lport)
 | 
			
		||||
			 * would've work wonderfully, but we need
 | 
			
		||||
			 * to know lsa */
 | 
			
		||||
			sfd = xsocket_stream(&lsa);
 | 
			
		||||
			if (lport)
 | 
			
		||||
				set_nport(lsa, htons(lport));
 | 
			
		||||
			setsockopt_reuseaddr(sfd);
 | 
			
		||||
			xbind(sfd, &lsa->u.sa, lsa->len);
 | 
			
		||||
			sfd = create_and_bind_stream_or_die(argv[0], lport);
 | 
			
		||||
			xlisten(sfd, do_listen); /* can be > 1 */
 | 
			
		||||
#if 0  /* nc-1.10 does not do this (without -v) */
 | 
			
		||||
			/* If we didn't specify a port number,
 | 
			
		||||
			 * query and print it after listen() */
 | 
			
		||||
			if (!lport) {
 | 
			
		||||
				getsockname(sfd, &lsa->u.sa, &lsa->len);
 | 
			
		||||
				lport = get_nport(&lsa->u.sa);
 | 
			
		||||
				len_and_sockaddr lsa;
 | 
			
		||||
				lsa.len = LSA_SIZEOF_SA;
 | 
			
		||||
				getsockname(sfd, &lsa.u.sa, &lsa.len);
 | 
			
		||||
				lport = get_nport(&lsa.u.sa);
 | 
			
		||||
				fdprintf(2, "%d\n", ntohs(lport));
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			close_on_exec_on(sfd);
 | 
			
		||||
			free(lsa);
 | 
			
		||||
 accept_again:
 | 
			
		||||
			cfd = accept(sfd, NULL, 0);
 | 
			
		||||
			if (cfd < 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -377,9 +377,7 @@ create new one, and bind() it. TODO */
 | 
			
		||||
		socklen_t x = sizeof(optbuf);
 | 
			
		||||
 | 
			
		||||
		rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x);
 | 
			
		||||
		if (rr < 0)
 | 
			
		||||
			bb_perror_msg("getsockopt failed");
 | 
			
		||||
		else if (x) {    /* we've got options, lessee em... */
 | 
			
		||||
		if (rr >= 0 && x) {    /* we've got options, lessee em... */
 | 
			
		||||
			bin2hex(bigbuf_net, optbuf, x);
 | 
			
		||||
			bigbuf_net[2*x] = '\0';
 | 
			
		||||
			fprintf(stderr, "IP options: %s\n", bigbuf_net);
 | 
			
		||||
@@ -603,7 +601,10 @@ Debug("got %d from the net, errno %d", rr, errno);
 | 
			
		||||
	 mobygrams are kinda fun and exercise the reassembler. */
 | 
			
		||||
			if (rr <= 0) {                        /* at end, or fukt, or ... */
 | 
			
		||||
				FD_CLR(STDIN_FILENO, &ding1);                /* disable and close stdin */
 | 
			
		||||
				close(0);
 | 
			
		||||
				close(STDIN_FILENO);
 | 
			
		||||
// Does it make sense to shutdown(net_fd, SHUT_WR)
 | 
			
		||||
// to let other side know that we won't write anything anymore?
 | 
			
		||||
// (and what about keeping compat if we do that?)
 | 
			
		||||
			} else {
 | 
			
		||||
				rzleft = rr;
 | 
			
		||||
				zp = bigbuf_in;
 | 
			
		||||
@@ -768,7 +769,12 @@ int nc_main(int argc, char **argv)
 | 
			
		||||
	setsockopt_reuseaddr(netfd);
 | 
			
		||||
	if (o_udpmode)
 | 
			
		||||
		socket_want_pktinfo(netfd);
 | 
			
		||||
	xbind(netfd, &ouraddr->u.sa, ouraddr->len);
 | 
			
		||||
	if (!ENABLE_FEATURE_UNIX_LOCAL
 | 
			
		||||
	 || o_listen
 | 
			
		||||
	 || ouraddr->u.sa.sa_family != AF_UNIX
 | 
			
		||||
	) {
 | 
			
		||||
		xbind(netfd, &ouraddr->u.sa, ouraddr->len);
 | 
			
		||||
	}
 | 
			
		||||
#if 0
 | 
			
		||||
	setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf);
 | 
			
		||||
	setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user