diff options
author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-10-31 09:31:46 +0000 |
---|---|---|
committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-10-31 09:31:46 +0000 |
commit | f9ece60e489d3250dac2887a0f0b6ba62b8a158c (patch) | |
tree | bacb9f48301189de134d9f8edc2f1f45c65086c5 | |
parent | ab8f96331f5f70a30edc2e6232b8ae668b4bac8a (diff) | |
download | busybox-w32-f9ece60e489d3250dac2887a0f0b6ba62b8a158c.tar.gz busybox-w32-f9ece60e489d3250dac2887a0f0b6ba62b8a158c.tar.bz2 busybox-w32-f9ece60e489d3250dac2887a0f0b6ba62b8a158c.zip |
Rework wget, the xconnect interface, and its various clients
in order to fix the problems with round robin DNS reported
by Andrew Flegg:
http://busybox.net/lists/busybox/2003-October/009579.html
This removes the ipv6 specific xconnect dns lookups. I do
not see why that would need to be special cased for ipv6 as
was done, but that will just have to be tested.
So IPV6 people -- please test this change!
-Erik
git-svn-id: svn://busybox.net/trunk/busybox@7735 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | include/libbb.h | 8 | ||||
-rw-r--r-- | libbb/safe_write.c | 2 | ||||
-rw-r--r-- | libbb/xconnect.c | 86 | ||||
-rw-r--r-- | networking/telnet.c | 4 | ||||
-rw-r--r-- | networking/wget.c | 30 | ||||
-rw-r--r-- | util-linux/rdate.c | 7 |
6 files changed, 70 insertions, 67 deletions
diff --git a/include/libbb.h b/include/libbb.h index 7587a407c..53062de4d 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -109,9 +109,9 @@ extern int is_directory(const char *name, int followLinks, struct stat *statBuf) | |||
109 | extern int remove_file(const char *path, int flags); | 109 | extern int remove_file(const char *path, int flags); |
110 | extern int copy_file(const char *source, const char *dest, int flags); | 110 | extern int copy_file(const char *source, const char *dest, int flags); |
111 | extern ssize_t safe_read(int fd, void *buf, size_t count); | 111 | extern ssize_t safe_read(int fd, void *buf, size_t count); |
112 | extern ssize_t safe_write(int fd, void *buf, size_t count); | ||
113 | extern ssize_t bb_full_write(int fd, const void *buf, size_t len); | ||
114 | extern ssize_t bb_full_read(int fd, void *buf, size_t len); | 112 | extern ssize_t bb_full_read(int fd, void *buf, size_t len); |
113 | extern ssize_t safe_write(int fd, const void *buf, size_t count); | ||
114 | extern ssize_t bb_full_write(int fd, const void *buf, size_t len); | ||
115 | extern int recursive_action(const char *fileName, int recurse, | 115 | extern int recursive_action(const char *fileName, int recurse, |
116 | int followLinks, int depthFirst, | 116 | int followLinks, int depthFirst, |
117 | int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData), | 117 | int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData), |
@@ -294,7 +294,9 @@ extern struct hostent *xgethostbyname(const char *name); | |||
294 | extern struct hostent *xgethostbyname2(const char *name, int af); | 294 | extern struct hostent *xgethostbyname2(const char *name, int af); |
295 | extern int create_icmp_socket(void); | 295 | extern int create_icmp_socket(void); |
296 | extern int create_icmp6_socket(void); | 296 | extern int create_icmp6_socket(void); |
297 | extern int xconnect(const char *host, const char *port); | 297 | extern int xconnect(struct sockaddr_in *s_addr); |
298 | extern int bb_getport(char *port); | ||
299 | extern void bb_lookup_host(struct sockaddr_in *s_in, char *host, char *port); | ||
298 | 300 | ||
299 | //#warning wrap this? | 301 | //#warning wrap this? |
300 | char *dirname (char *path); | 302 | char *dirname (char *path); |
diff --git a/libbb/safe_write.c b/libbb/safe_write.c index dd35f35ae..0ac6c2d96 100644 --- a/libbb/safe_write.c +++ b/libbb/safe_write.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | 27 | ||
28 | 28 | ||
29 | ssize_t safe_write(int fd, void *buf, size_t count) | 29 | ssize_t safe_write(int fd, const void *buf, size_t count) |
30 | { | 30 | { |
31 | ssize_t n; | 31 | ssize_t n; |
32 | 32 | ||
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 2945d760f..27459791e 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -11,69 +11,57 @@ | |||
11 | #include <stdlib.h> | 11 | #include <stdlib.h> |
12 | #include <sys/types.h> | 12 | #include <sys/types.h> |
13 | #include <sys/socket.h> | 13 | #include <sys/socket.h> |
14 | #include <errno.h> | ||
14 | #include <netdb.h> | 15 | #include <netdb.h> |
16 | #include <sys/socket.h> | ||
15 | #include <netinet/in.h> | 17 | #include <netinet/in.h> |
18 | #include <arpa/inet.h> | ||
16 | #include "libbb.h" | 19 | #include "libbb.h" |
17 | 20 | ||
18 | int xconnect(const char *host, const char *port) | 21 | int bb_getport(char *port) |
19 | { | 22 | { |
20 | #ifdef CONFIG_FEATURE_IPV6 | 23 | int port_nr; |
21 | struct addrinfo hints; | 24 | char *endptr; |
22 | struct addrinfo *res; | 25 | struct servent *tserv; |
23 | struct addrinfo *addr_info; | ||
24 | int error; | ||
25 | int s; | ||
26 | 26 | ||
27 | memset(&hints, 0, sizeof(hints)); | 27 | if (!port) { |
28 | /* set-up hints structure */ | 28 | return -1; |
29 | hints.ai_family = PF_UNSPEC; | ||
30 | hints.ai_socktype = SOCK_STREAM; | ||
31 | error = getaddrinfo(host, port, &hints, &res); | ||
32 | if (error||!res) | ||
33 | bb_perror_msg_and_die(gai_strerror(error)); | ||
34 | addr_info=res; | ||
35 | while (res) { | ||
36 | s=socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||
37 | if (s<0) | ||
38 | { | ||
39 | error=s; | ||
40 | res=res->ai_next; | ||
41 | continue; | ||
42 | } | ||
43 | /* try to connect() to res->ai_addr */ | ||
44 | error = connect(s, res->ai_addr, res->ai_addrlen); | ||
45 | if (error >= 0) | ||
46 | break; | ||
47 | close(s); | ||
48 | res=res->ai_next; | ||
49 | } | 29 | } |
50 | freeaddrinfo(addr_info); | 30 | port_nr=strtol(port, &endptr, 10); |
51 | if (error < 0) | 31 | if (errno != 0 || *endptr!='\0' || endptr==port || port_nr < 1 || port_nr > 65536) |
52 | { | 32 | { |
53 | bb_perror_msg_and_die("Unable to connect to remote host (%s)", host); | 33 | if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL) { |
34 | port_nr = tserv->s_port; | ||
35 | } else { | ||
36 | return -1; | ||
37 | } | ||
38 | } else { | ||
39 | port_nr = htons(port_nr); | ||
54 | } | 40 | } |
55 | return s; | 41 | return port_nr; |
56 | #else | 42 | } |
57 | struct sockaddr_in s_addr; | ||
58 | int s = socket(AF_INET, SOCK_STREAM, 0); | ||
59 | struct servent *tserv; | ||
60 | int port_nr=htons(atoi(port)); | ||
61 | struct hostent * he; | ||
62 | |||
63 | if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL) | ||
64 | port_nr = tserv->s_port; | ||
65 | 43 | ||
66 | memset(&s_addr, 0, sizeof(struct sockaddr_in)); | 44 | void bb_lookup_host(struct sockaddr_in *s_in, char *host, char *port) |
67 | s_addr.sin_family = AF_INET; | 45 | { |
68 | s_addr.sin_port = port_nr; | 46 | struct hostent *he; |
69 | 47 | ||
48 | memset(s_in, 0, sizeof(struct sockaddr_in)); | ||
49 | s_in->sin_family = AF_INET; | ||
70 | he = xgethostbyname(host); | 50 | he = xgethostbyname(host); |
71 | memcpy(&s_addr.sin_addr, he->h_addr, sizeof s_addr.sin_addr); | 51 | memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length); |
72 | 52 | ||
73 | if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0) | 53 | if (port) { |
54 | s_in->sin_port=bb_getport(port); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | int xconnect(struct sockaddr_in *s_addr) | ||
59 | { | ||
60 | int s = socket(AF_INET, SOCK_STREAM, 0); | ||
61 | if (connect(s, (struct sockaddr_in *)s_addr, sizeof(struct sockaddr_in)) < 0) | ||
74 | { | 62 | { |
75 | bb_perror_msg_and_die("Unable to connect to remote host (%s)", host); | 63 | bb_perror_msg_and_die("Unable to connect to remote host (%s)", |
64 | inet_ntoa(s_addr->sin_addr)); | ||
76 | } | 65 | } |
77 | return s; | 66 | return s; |
78 | #endif | ||
79 | } | 67 | } |
diff --git a/networking/telnet.c b/networking/telnet.c index ac6ec98de..92ddfaebf 100644 --- a/networking/telnet.c +++ b/networking/telnet.c | |||
@@ -573,6 +573,7 @@ extern int telnet_main(int argc, char** argv) | |||
573 | char *host; | 573 | char *host; |
574 | char *port; | 574 | char *port; |
575 | int len; | 575 | int len; |
576 | struct sockaddr_in s_in; | ||
576 | #ifdef USE_POLL | 577 | #ifdef USE_POLL |
577 | struct pollfd ufds[2]; | 578 | struct pollfd ufds[2]; |
578 | #else | 579 | #else |
@@ -601,7 +602,8 @@ extern int telnet_main(int argc, char** argv) | |||
601 | 602 | ||
602 | host = argv[1]; | 603 | host = argv[1]; |
603 | 604 | ||
604 | G.netfd = xconnect(host, port); | 605 | bb_lookup_host(&s_in, host, port); |
606 | G.netfd = xconnect(&s_in); | ||
605 | 607 | ||
606 | setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one); | 608 | setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one); |
607 | 609 | ||
diff --git a/networking/wget.c b/networking/wget.c index 597d61097..08026915e 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -40,7 +40,7 @@ struct host_info { | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | static void parse_url(char *url, struct host_info *h); | 42 | static void parse_url(char *url, struct host_info *h); |
43 | static FILE *open_socket(char *host, int port); | 43 | static FILE *open_socket(struct sockaddr_in *s_in, int port); |
44 | static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc); | 44 | static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc); |
45 | static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf); | 45 | static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf); |
46 | 46 | ||
@@ -155,6 +155,7 @@ int wget_main(int argc, char **argv) | |||
155 | int extra_headers_left = sizeof(extra_headers); | 155 | int extra_headers_left = sizeof(extra_headers); |
156 | int which_long_opt = 0, option_index = -1; | 156 | int which_long_opt = 0, option_index = -1; |
157 | struct host_info server, target; | 157 | struct host_info server, target; |
158 | struct sockaddr_in s_in; | ||
158 | 159 | ||
159 | FILE *sfp = NULL; /* socket to web/ftp server */ | 160 | FILE *sfp = NULL; /* socket to web/ftp server */ |
160 | FILE *dfp = NULL; /* socket to ftp server (data) */ | 161 | FILE *dfp = NULL; /* socket to ftp server (data) */ |
@@ -290,6 +291,15 @@ int wget_main(int argc, char **argv) | |||
290 | do_continue = 0; | 291 | do_continue = 0; |
291 | } | 292 | } |
292 | 293 | ||
294 | /* We want to do exactly _one_ DNS lookup, since some | ||
295 | * sites (i.e. ftp.us.debian.org) use round-robin DNS | ||
296 | * and we want to connect to only one IP... */ | ||
297 | bb_lookup_host(&s_in, server.host, NULL); | ||
298 | if (quiet_flag==FALSE) { | ||
299 | fprintf(stdout, "Connecting to %s[%s]:%d\n", | ||
300 | server.host, inet_ntoa(s_in.sin_addr), server.port); | ||
301 | } | ||
302 | |||
293 | if (proxy || !target.is_ftp) { | 303 | if (proxy || !target.is_ftp) { |
294 | /* | 304 | /* |
295 | * HTTP session | 305 | * HTTP session |
@@ -304,7 +314,7 @@ int wget_main(int argc, char **argv) | |||
304 | * Open socket to http server | 314 | * Open socket to http server |
305 | */ | 315 | */ |
306 | if (sfp) fclose(sfp); | 316 | if (sfp) fclose(sfp); |
307 | sfp = open_socket(server.host, server.port); | 317 | sfp = open_socket(&s_in, server.port); |
308 | 318 | ||
309 | /* | 319 | /* |
310 | * Send HTTP request. | 320 | * Send HTTP request. |
@@ -416,7 +426,7 @@ read_response: | |||
416 | if (! target.user) | 426 | if (! target.user) |
417 | target.user = bb_xstrdup("anonymous:busybox@"); | 427 | target.user = bb_xstrdup("anonymous:busybox@"); |
418 | 428 | ||
419 | sfp = open_socket(server.host, server.port); | 429 | sfp = open_socket(&s_in, server.port); |
420 | if (ftpcmd(NULL, NULL, sfp, buf) != 220) | 430 | if (ftpcmd(NULL, NULL, sfp, buf) != 220) |
421 | close_delete_and_die("%s", buf+4); | 431 | close_delete_and_die("%s", buf+4); |
422 | 432 | ||
@@ -459,7 +469,7 @@ read_response: | |||
459 | port = atoi(s+1); | 469 | port = atoi(s+1); |
460 | s = strrchr(buf, ','); | 470 | s = strrchr(buf, ','); |
461 | port += atoi(s+1) * 256; | 471 | port += atoi(s+1) * 256; |
462 | dfp = open_socket(server.host, port); | 472 | dfp = open_socket(&s_in, port); |
463 | 473 | ||
464 | if (do_continue) { | 474 | if (do_continue) { |
465 | sprintf(buf, "REST %ld", beg_range); | 475 | sprintf(buf, "REST %ld", beg_range); |
@@ -584,14 +594,16 @@ void parse_url(char *url, struct host_info *h) | |||
584 | } | 594 | } |
585 | 595 | ||
586 | 596 | ||
587 | FILE *open_socket(char *host, int port) | 597 | FILE *open_socket(struct sockaddr_in *s_in, int port) |
588 | { | 598 | { |
589 | int fd; | 599 | int fd; |
590 | FILE *fp; | 600 | FILE *fp; |
591 | char port_str[10]; | ||
592 | 601 | ||
593 | snprintf(port_str, sizeof(port_str), "%d", port); | 602 | if (port>0 && port < 65536) { |
594 | fd=xconnect(host, port_str); | 603 | s_in->sin_port=htons(port); |
604 | } | ||
605 | |||
606 | fd=xconnect(s_in); | ||
595 | 607 | ||
596 | /* | 608 | /* |
597 | * Get the server onto a stdio stream. | 609 | * Get the server onto a stdio stream. |
@@ -838,7 +850,7 @@ progressmeter(int flag) | |||
838 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 850 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
839 | * SUCH DAMAGE. | 851 | * SUCH DAMAGE. |
840 | * | 852 | * |
841 | * $Id: wget.c,v 1.60 2003/09/15 08:33:37 andersen Exp $ | 853 | * $Id: wget.c,v 1.61 2003/10/31 09:31:43 andersen Exp $ |
842 | */ | 854 | */ |
843 | 855 | ||
844 | 856 | ||
diff --git a/util-linux/rdate.c b/util-linux/rdate.c index 8d156cc78..a822f42ff 100644 --- a/util-linux/rdate.c +++ b/util-linux/rdate.c | |||
@@ -47,17 +47,16 @@ static void socket_timeout(int sig) | |||
47 | static time_t askremotedate(const char *host) | 47 | static time_t askremotedate(const char *host) |
48 | { | 48 | { |
49 | unsigned long int nett, localt; | 49 | unsigned long int nett, localt; |
50 | const char *port="37"; | 50 | struct sockaddr_in addr s_in; |
51 | int fd; | 51 | int fd; |
52 | 52 | ||
53 | if (getservbyname("time", "tcp") != NULL) | 53 | bb_lookup_host(&s_in, host, "time"); |
54 | port="time"; | ||
55 | 54 | ||
56 | /* Add a timeout for dead or non accessable servers */ | 55 | /* Add a timeout for dead or non accessable servers */ |
57 | alarm(10); | 56 | alarm(10); |
58 | signal(SIGALRM, socket_timeout); | 57 | signal(SIGALRM, socket_timeout); |
59 | 58 | ||
60 | fd = xconnect(host, port); | 59 | fd = xconnect(s_in); |
61 | 60 | ||
62 | if (safe_read(fd, (void *)&nett, 4) != 4) /* read time from server */ | 61 | if (safe_read(fd, (void *)&nett, 4) != 4) /* read time from server */ |
63 | bb_error_msg_and_die("%s did not send the complete time", host); | 62 | bb_error_msg_and_die("%s did not send the complete time", host); |