svn commit: trunk/busybox: include libbb networking scripts

vda at busybox.net vda at busybox.net
Fri Jan 12 10:35:24 UTC 2007


Author: vda
Date: 2007-01-12 02:35:23 -0800 (Fri, 12 Jan 2007)
New Revision: 17257

Log:
next part of ipv6-ization is here: wget & httpd


Modified:
   trunk/busybox/include/libbb.h
   trunk/busybox/libbb/xconnect.c
   trunk/busybox/networking/httpd.c
   trunk/busybox/networking/nc.c
   trunk/busybox/networking/telnet.c
   trunk/busybox/networking/tftp.c
   trunk/busybox/networking/wget.c
   trunk/busybox/scripts/defconfig


Changeset:
Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/include/libbb.h	2007-01-12 10:35:23 UTC (rev 17257)
@@ -531,6 +531,7 @@
 int inflate(int in, int out);
 
 
+/* NB: returns port in host byte order */
 unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port);
 void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
 

Modified: trunk/busybox/libbb/xconnect.c
===================================================================
--- trunk/busybox/libbb/xconnect.c	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/libbb/xconnect.c	2007-01-12 10:35:23 UTC (rev 17257)
@@ -38,7 +38,7 @@
  * default_port */
 unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port)
 {
-	unsigned port_nr = htons(default_port);
+	unsigned port_nr = default_port;
 	if (port) {
 		int old_errno;
 
@@ -49,13 +49,11 @@
 		if (errno || port_nr > 65535) {
 			struct servent *tserv = getservbyname(port, protocol);
 			if (tserv)
-				port_nr = tserv->s_port;
-		} else {
-			port_nr = htons(port_nr);
+				port_nr = ntohs(tserv->s_port);
 		}
 		errno = old_errno;
 	}
-	return port_nr;
+	return (uint16_t)port_nr;
 }
 
 
@@ -148,7 +146,7 @@
 	r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen);
 	r->len = result->ai_addrlen;
 	memcpy(&r->sa, result->ai_addr, result->ai_addrlen);
-	set_port(r, port);
+	set_port(r, htons(port));
 	freeaddrinfo(result);
 	return r;
 }
@@ -237,6 +235,7 @@
 			flags | NI_NUMERICSERV /* do not resolve port# */
 	);
 	if (rc) return NULL;
+// We probably need to use [%s]:%s for IPv6...
 	return xasprintf("%s:%s", host, serv);
 }
 

Modified: trunk/busybox/networking/httpd.c
===================================================================
--- trunk/busybox/networking/httpd.c	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/networking/httpd.c	2007-01-12 10:35:23 UTC (rev 17257)
@@ -142,7 +142,7 @@
 
 	unsigned int rmt_ip;
 #if ENABLE_FEATURE_HTTPD_CGI || DEBUG
-	char rmt_ip_str[16];     /* for set env REMOTE_ADDR */
+	char *rmt_ip_str;        /* for set env REMOTE_ADDR */
 #endif
 	unsigned port;           /* server initial port and for
 						      set env REMOTE_PORT */
@@ -817,30 +817,11 @@
  ****************************************************************************/
 static int openServer(void)
 {
-	struct sockaddr_in lsocket;
 	int fd;
 
 	/* create the socket right now */
-	/* inet_addr() returns a value that is already in network order */
-	memset(&lsocket, 0, sizeof(lsocket));
-	lsocket.sin_family = AF_INET;
-	lsocket.sin_addr.s_addr = INADDR_ANY;
-	lsocket.sin_port = htons(config->port);
-	fd = xsocket(AF_INET, SOCK_STREAM, 0);
-	/* tell the OS it's OK to reuse a previous address even though */
-	/* it may still be in a close down state.  Allows bind to succeed. */
-#ifdef SO_REUSEPORT
-	{
-		static const int on = 1;
-		setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
-				(void *)&on, sizeof(on));
-	}
-#else
-	setsockopt_reuseaddr(fd);
-#endif
-	xbind(fd, (struct sockaddr *)&lsocket, sizeof(lsocket));
+	fd = create_and_bind_stream_or_die(NULL, config->port);
 	xlisten(fd, 9);
-	signal(SIGCHLD, SIG_IGN);   /* prevent zombie (defunct) processes */
 	return fd;
 }
 
@@ -1070,7 +1051,19 @@
 		setenv1("SERVER_SOFTWARE", httpdVersion);
 		putenv("SERVER_PROTOCOL=HTTP/1.0");
 		putenv("GATEWAY_INTERFACE=CGI/1.1");
-		setenv1("REMOTE_ADDR", config->rmt_ip_str);
+		/* Having _separate_ variables for IP and port defeats
+		 * the purpose of having socket abstraction. Which "port"
+		 * are you using on Unix domain socket?
+		 * IOW - REMOTE_PEER="1.2.3.4:56" makes much more sense.
+		 * Oh well... */
+		{
+			char *p = config->rmt_ip_str ? : "";
+			char *cp = strrchr(p, ':');
+			if (ENABLE_FEATURE_IPV6 && cp && strchr(cp, ']'))
+				cp = NULL;
+			if (cp) *cp = '\0'; /* delete :PORT */
+			setenv1("REMOTE_ADDR", p);
+		}
 #if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
 		setenv_long("REMOTE_PORT", config->port);
 #endif
@@ -1330,17 +1323,17 @@
 	for (cur = config->ip_a_d; cur; cur = cur->next) {
 #if DEBUG
 		fprintf(stderr, "checkPermIP: '%s' ? ", config->rmt_ip_str);
+		fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n",
+			(unsigned char)(cur->ip >> 24),
+			(unsigned char)(cur->ip >> 16),
+			(unsigned char)(cur->ip >> 8),
+			(unsigned char)(cur->ip),
+			(unsigned char)(cur->mask >> 24),
+			(unsigned char)(cur->mask >> 16),
+			(unsigned char)(cur->mask >> 8),
+			(unsigned char)(cur->mask)
+		);
 #endif
-		if (DEBUG)
-			fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n",
-				(unsigned char)(cur->ip >> 24),
-				(unsigned char)(cur->ip >> 16),
-				(unsigned char)(cur->ip >> 8),
-				                cur->ip & 0xff,
-				(unsigned char)(cur->mask >> 24),
-				(unsigned char)(cur->mask >> 16),
-				(unsigned char)(cur->mask >> 8),
-				                cur->mask & 0xff);
 		if ((config->rmt_ip & cur->mask) == cur->ip)
 			return cur->allow_deny == 'A';   /* Allow/Deny */
 	}
@@ -1765,6 +1758,8 @@
  ****************************************************************************/
 static int miniHttpd(int server)
 {
+	static const int on = 1;
+
 	fd_set readfd, portfd;
 
 	FD_ZERO(&portfd);
@@ -1772,9 +1767,13 @@
 
 	/* copy the ports we are watching to the readfd set */
 	while (1) {
-		int on, s;
-		socklen_t fromAddrLen;
-		struct sockaddr_in fromAddr;
+		int s;
+		union {
+			struct sockaddr sa;
+			struct sockaddr_in sin;
+			USE_FEATURE_IPV6(struct sockaddr_in6 sin6;)
+		} fromAddr;
+		socklen_t fromAddrLen = sizeof(fromAddr);
 
 		/* Now wait INDEFINITELY on the set of sockets! */
 		readfd = portfd;
@@ -1782,27 +1781,31 @@
 			continue;
 		if (!FD_ISSET(server, &readfd))
 			continue;
-		fromAddrLen = sizeof(fromAddr);
-		s = accept(server, (struct sockaddr *)&fromAddr, &fromAddrLen);
+		s = accept(server, &fromAddr.sa, &fromAddrLen);
 		if (s < 0)
 			continue;
 		config->accepted_socket = s;
-		config->rmt_ip = ntohl(fromAddr.sin_addr.s_addr);
+		config->rmt_ip = 0;
+		config->port = 0;
 #if ENABLE_FEATURE_HTTPD_CGI || DEBUG
-		sprintf(config->rmt_ip_str, "%u.%u.%u.%u",
-				(unsigned char)(config->rmt_ip >> 24),
-				(unsigned char)(config->rmt_ip >> 16),
-				(unsigned char)(config->rmt_ip >> 8),
-				config->rmt_ip & 0xff);
-		config->port = ntohs(fromAddr.sin_port);
+		free(config->rmt_ip_str);
+		config->rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddrLen);
 #if DEBUG
-		bb_error_msg("connection from IP=%s, port %u",
-				config->rmt_ip_str, config->port);
+		bb_error_msg("connection from '%s'", config->rmt_ip_str);
 #endif
 #endif /* FEATURE_HTTPD_CGI */
+		if (fromAddr.sa.sa_family == AF_INET) {
+			config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
+			config->port = ntohs(fromAddr.sin.sin_port);
+		}
+#if ENABLE_FEATURE_IPV6
+		if (fromAddr.sa.sa_family == AF_INET6) {
+			//config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
+			config->port = ntohs(fromAddr.sin6.sin6_port);
+		}
+#endif
 
 		/* set the KEEPALIVE option to cull dead connections */
-		on = 1;
 		setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
 
 		if (DEBUG || fork() == 0) {
@@ -1823,19 +1826,30 @@
 /* from inetd */
 static int miniHttpd_inetd(void)
 {
-	struct sockaddr_in fromAddrLen;
-	socklen_t sinlen = sizeof(struct sockaddr_in);
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sin;
+		USE_FEATURE_IPV6(struct sockaddr_in6 sin6;)
+	} fromAddr;
+	socklen_t fromAddrLen = sizeof(fromAddr);
 
-	getpeername(0, (struct sockaddr *)&fromAddrLen, &sinlen);
-	config->rmt_ip = ntohl(fromAddrLen.sin_addr.s_addr);
-#if ENABLE_FEATURE_HTTPD_CGI
-	sprintf(config->rmt_ip_str, "%u.%u.%u.%u",
-				(unsigned char)(config->rmt_ip >> 24),
-				(unsigned char)(config->rmt_ip >> 16),
-				(unsigned char)(config->rmt_ip >> 8),
-				                config->rmt_ip & 0xff);
+	getpeername(0, &fromAddr.sa, &fromAddrLen);
+	config->rmt_ip = 0;
+	config->port = 0;
+#if ENABLE_FEATURE_HTTPD_CGI || DEBUG
+	free(config->rmt_ip_str);
+	config->rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddrLen);
 #endif
-	config->port = ntohs(fromAddrLen.sin_port);
+	if (fromAddr.sa.sa_family == AF_INET) {
+		config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
+		config->port = ntohs(fromAddr.sin.sin_port);
+	}
+#if ENABLE_FEATURE_IPV6
+	if (fromAddr.sa.sa_family == AF_INET6) {
+		//config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
+		config->port = ntohs(fromAddr.sin6.sin6_port);
+	}
+#endif
 	handleIncoming();
 	return 0;
 }
@@ -1945,6 +1959,7 @@
 
 	xchdir(home_httpd);
 	if (!(opt & OPT_INETD)) {
+		signal(SIGCHLD, SIG_IGN);
 		config->server_socket = openServer();
 #if ENABLE_FEATURE_HTTPD_SETUID
 		/* drop privileges */

Modified: trunk/busybox/networking/nc.c
===================================================================
--- trunk/busybox/networking/nc.c	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/networking/nc.c	2007-01-12 10:35:23 UTC (rev 17257)
@@ -37,7 +37,10 @@
 		        "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0
 		) {
 			if (ENABLE_NC_SERVER && opt=='l')      USE_NC_SERVER(do_listen++);
-			else if (ENABLE_NC_SERVER && opt=='p') USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
+			else if (ENABLE_NC_SERVER && opt=='p') {
+				USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
+				USE_NC_SERVER(lport = htons(lport));
+			}
 			else if (ENABLE_NC_EXTRA  && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg));
 			else if (ENABLE_NC_EXTRA  && opt=='i') USE_NC_EXTRA( delay = xatou(optarg));
 			else if (ENABLE_NC_EXTRA  && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
@@ -119,6 +122,7 @@
 
 			address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
 			address.sin_port = bb_lookup_port(argv[1], "tcp", 0);
+			address.sin_port = htons(address.sin_port);
 
 			xconnect(sfd, (struct sockaddr *) &address, sizeof(address));
 			cfd = sfd;

Modified: trunk/busybox/networking/telnet.c
===================================================================
--- trunk/busybox/networking/telnet.c	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/networking/telnet.c	2007-01-12 10:35:23 UTC (rev 17257)
@@ -617,19 +617,17 @@
 #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN
 	if (1 & getopt32(argc, argv, "al:", &autologin))
 		autologin = getenv("USER");
-
-	if (optind < argc) {
-		host = argv[optind++];
-		port = bb_lookup_port((optind < argc) ? argv[optind++] :
-				"telnet", "tcp", 23);
-		if (optind < argc)
-			bb_show_usage();
-	} else
-		bb_show_usage();
+	argv += optind;
 #else
-	host = argv[1];
-	port = bb_lookup_port((argc > 2) ? argv[2] : "telnet", "tcp", 23);
+	argv++;
 #endif
+	if (!*argv)
+		bb_show_usage();
+	host = *argv++;
+	port = bb_lookup_port(*argv ? *argv++ : "telnet", "tcp", 23);
+	if (*argv) /* extra params?? */
+		bb_show_usage();
+
 	G.netfd = create_and_connect_stream_or_die(host, port);
 
 	setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one);

Modified: trunk/busybox/networking/tftp.c
===================================================================
--- trunk/busybox/networking/tftp.c	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/networking/tftp.c	2007-01-12 10:35:23 UTC (rev 17257)
@@ -132,7 +132,7 @@
 #endif
 		const len_and_sockaddr *peer_lsa,
 		const char *remotefile, const int localfd,
-		const unsigned port, int tftp_bufsize)
+		unsigned port, int tftp_bufsize)
 {
 	struct timeval tv;
 	fd_set rfds;
@@ -154,6 +154,8 @@
 	char *xbuf = xmalloc(tftp_bufsize += 4);
 	char *rbuf = xmalloc(tftp_bufsize);
 
+	port = htons(port);
+
 	socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0);
 
 	/* build opcode */

Modified: trunk/busybox/networking/wget.c
===================================================================
--- trunk/busybox/networking/wget.c	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/networking/wget.c	2007-01-12 10:35:23 UTC (rev 17257)
@@ -24,7 +24,7 @@
 };
 
 static void parse_url(char *url, struct host_info *h);
-static FILE *open_socket(struct sockaddr_in *s_in);
+static FILE *open_socket(len_and_sockaddr *lsa);
 static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc);
 static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf);
 
@@ -90,7 +90,7 @@
 {
 	char buf[512];
 	struct host_info server, target;
-	struct sockaddr_in s_in;
+	len_and_sockaddr *lsa;
 	int n, status;
 	int port;
 	int try = 5;
@@ -189,7 +189,7 @@
 	if (!fname_out) {
 		// Dirty hack. Needed because bb_get_last_path_component
 		// will destroy trailing / by storing '\0' in last byte!
-		if (*target.path && target.path[strlen(target.path)-1] != '/') {
+		if (!last_char_is(target.path, '/')) {
 			fname_out =
 #if ENABLE_FEATURE_WGET_STATUSBAR
 				curfile =
@@ -233,11 +233,11 @@
 	/* We want to do exactly _one_ DNS lookup, since some
 	 * sites (i.e. ftp.us.debian.org) use round-robin DNS
 	 * and we want to connect to only one IP... */
-	bb_lookup_host(&s_in, server.host);
-	s_in.sin_port = server.port;
+	lsa = host2sockaddr(server.host, server.port);
 	if (!(opt & WGET_OPT_QUIET)) {
-		fprintf(stderr, "Connecting to %s[%s]:%d\n",
-				server.host, inet_ntoa(s_in.sin_addr), ntohs(server.port));
+		fprintf(stderr, "Connecting to %s [%s]\n", server.host,
+				xmalloc_sockaddr2dotted(&lsa->sa, lsa->len));
+		/* We leak xmalloc_sockaddr2dotted result */
 	}
 
 	if (use_proxy || !target.is_ftp) {
@@ -254,26 +254,29 @@
 			 * Open socket to http server
 			 */
 			if (sfp) fclose(sfp);
-			sfp = open_socket(&s_in);
+			sfp = open_socket(lsa);
 
 			/*
 			 * Send HTTP request.
 			 */
 			if (use_proxy) {
-				const char *format = "GET %stp://%s:%d/%s HTTP/1.1\r\n";
-#if ENABLE_FEATURE_WGET_IP6_LITERAL
-				if (strchr(target.host, ':'))
-					format = "GET %stp://[%s]:%d/%s HTTP/1.1\r\n";
-#endif
-				fprintf(sfp, format,
+//				const char *format = "GET %stp://%s:%d/%s HTTP/1.1\r\n";
+//#if ENABLE_FEATURE_WGET_IP6_LITERAL
+//				if (strchr(target.host, ':'))
+//					format = "GET %stp://[%s]:%d/%s HTTP/1.1\r\n";
+//#endif
+//				fprintf(sfp, format,
+//					target.is_ftp ? "f" : "ht", target.host,
+//					ntohs(target.port), target.path);
+				fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",
 					target.is_ftp ? "f" : "ht", target.host,
-					ntohs(target.port), target.path);
+					target.path);
 			} else {
 				fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);
 			}
 
-			fprintf(sfp, "Host: %s:%u\r\nUser-Agent: %s\r\n",
-				target.host, target.port, user_agent);
+			fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
+				target.host, user_agent);
 
 #if ENABLE_FEATURE_WGET_AUTHENTICATION
 			if (target.user) {
@@ -357,8 +360,8 @@
 							server.host = target.host;
 							server.port = target.port;
 						}
-						bb_lookup_host(&s_in, server.host);
-						s_in.sin_port = server.port;
+						free(lsa);
+						lsa = host2sockaddr(server.host, server.port);
 						break;
 					}
 				}
@@ -375,7 +378,7 @@
 		if (!target.user)
 			target.user = xstrdup("anonymous:busybox@");
 
-		sfp = open_socket(&s_in);
+		sfp = open_socket(lsa);
 		if (ftpcmd(NULL, NULL, sfp, buf) != 220)
 			bb_error_msg_and_die("%s", buf+4);
 
@@ -429,8 +432,8 @@
 		s = strrchr(buf, ',');
 		if (!s) goto pasv_error;
 		port += xatou_range(s+1, 0, 255) * 256;
-		s_in.sin_port = htons(port);
-		dfp = open_socket(&s_in);
+		set_port(lsa, htons(port));
+		dfp = open_socket(lsa);
 
 		if (beg_range) {
 			sprintf(buf, "REST %"OFF_FMT"d", beg_range);
@@ -564,36 +567,37 @@
 
 	sp = h->host;
 
-#if ENABLE_FEATURE_WGET_IP6_LITERAL
-	if (sp[0] == '[') {
-		char *ep;
-
-		ep = sp + 1;
-		while (*ep == ':' || isxdigit(*ep))
-			ep++;
-		if (*ep == ']') {
-			h->host++;
-			*ep = '\0';
-			sp = ep + 1;
-		}
-	}
-#endif
-
-	p = strchr(sp, ':');
-	if (p != NULL) {
-		*p = '\0';
-		h->port = htons(xatou16(p + 1));
-	}
+//host2sockaddr does this itself
+//#if ENABLE_FEATURE_WGET_IP6_LITERAL
+//	if (sp[0] == '[') {
+//		char *ep;
+//
+//		ep = sp + 1;
+//		while (*ep == ':' || isxdigit(*ep))
+//			ep++;
+//		if (*ep == ']') {
+//			h->host++;
+//			*ep = '\0';
+//			sp = ep + 1;
+//		}
+//	}
+//#endif
+//
+//	p = strchr(sp, ':');
+//	if (p != NULL) {
+//		*p = '\0';
+//		h->port = htons(xatou16(p + 1));
+//	}
 }
 
 
-static FILE *open_socket(struct sockaddr_in *s_in)
+static FILE *open_socket(len_and_sockaddr *lsa)
 {
 	FILE *fp;
 
 	/* glibc 2.4 seems to try seeking on it - ??! */
 	/* hopefully it understands what ESPIPE means... */
-	fp = fdopen(xconnect_tcp_v4(s_in), "r+");
+	fp = fdopen(xconnect_stream(lsa), "r+");
 	if (fp == NULL)
 		bb_perror_msg_and_die("fdopen");
 

Modified: trunk/busybox/scripts/defconfig
===================================================================
--- trunk/busybox/scripts/defconfig	2007-01-11 23:26:13 UTC (rev 17256)
+++ trunk/busybox/scripts/defconfig	2007-01-12 10:35:23 UTC (rev 17257)
@@ -580,7 +580,6 @@
 CONFIG_WGET=y
 CONFIG_FEATURE_WGET_STATUSBAR=y
 CONFIG_FEATURE_WGET_AUTHENTICATION=y
-CONFIG_FEATURE_WGET_IP6_LITERAL=y
 CONFIG_FEATURE_WGET_LONG_OPTIONS=y
 CONFIG_ZCIP=y
 




More information about the busybox-cvs mailing list