(connect_host): Try all addresses of `host'

(connect_host): Turn on TCP_NODELAY.
(doit): prepare for TCP-only hosts.
(usage,main): add `-t'
(main): Passive mode is possible again.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@848 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1996-10-14 19:18:02 +00:00
parent f4d7d83ecd
commit b8bc4e17af

View File

@@ -76,6 +76,7 @@ connect_host (char *host, des_cblock *key, des_key_schedule schedule,
int s; int s;
u_char b; u_char b;
char tmp[16]; char tmp[16];
char **p;
hostent = gethostbyname (host); hostent = gethostbyname (host);
if (hostent == NULL) { if (hostent == NULL) {
@@ -86,18 +87,35 @@ connect_host (char *host, des_cblock *key, des_key_schedule schedule,
memset (&thataddr, 0, sizeof(thataddr)); memset (&thataddr, 0, sizeof(thataddr));
thataddr.sin_family = AF_INET; thataddr.sin_family = AF_INET;
thataddr.sin_port = k_getportbyname ("kx", "tcp", htons(KX_PORT)); thataddr.sin_port = k_getportbyname ("kx", "tcp", htons(KX_PORT));
memcpy (&thataddr.sin_addr, hostent->h_addr, sizeof(thataddr.sin_addr)); for(p = hostent->h_addr_list; *p; ++p) {
int one = 1;
memcpy (&thataddr.sin_addr, *p, hostent->h_length);
s = socket (AF_INET, SOCK_STREAM, 0); s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0) { if (s < 0) {
fprintf (stderr, "%s: socket failed: %s\n", prog, strerror(errno)); fprintf (stderr, "%s: socket failed: %s\n",
return -1; prog,
}
if (connect (s, (struct sockaddr *)&thataddr, sizeof(thataddr)) < 0) {
fprintf (stderr, "%s: connect(%s) failed: %s\n", prog, host,
strerror(errno)); strerror(errno));
return -1; return -1;
} }
#ifdef TCP_NODELAY
setsockopt (s, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
#endif
if (connect (s, (struct sockaddr *)&thataddr, sizeof(thataddr)) < 0) {
fprintf (stderr, "%s: connect(%s) failed: %s\n", prog, host,
strerror(errno));
close (s);
continue;
} else {
break;
}
}
if (*p == NULL)
return -1;
addrlen = sizeof(thisaddr); addrlen = sizeof(thisaddr);
if (getsockname (s, (struct sockaddr *)&thisaddr, &addrlen) < 0 || if (getsockname (s, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
addrlen != sizeof(thisaddr)) { addrlen != sizeof(thisaddr)) {
@@ -263,45 +281,45 @@ passive (int fd, char *host, des_cblock *iv, des_key_schedule schedule)
*/ */
static int static int
doit (char *host, int passivep, int debugp) doit (char *host, int passivep, int debugp, int tcpp)
{ {
des_key_schedule schedule; des_key_schedule schedule;
des_cblock key; des_cblock key;
int rendez_vous; int rendez_vous1 = 0, rendez_vous2 = 0;
int (*fn)(int fd, char *host, des_cblock *iv, int (*fn)(int fd, char *host, des_cblock *iv,
des_key_schedule schedule); des_key_schedule schedule);
pid_t pid;
if (passivep) { if (passivep) {
struct sockaddr_in newaddr; struct sockaddr_in newaddr;
int addrlen; int addrlen;
u_char b = passivep; u_char b = passivep;
int otherside; int otherside;
pid_t pid;
otherside = connect_host (host, &key, schedule, passivep); otherside = connect_host (host, &key, schedule, passivep);
if (otherside < 0) if (otherside < 0)
return 1; return 1;
rendez_vous = socket (AF_INET, SOCK_STREAM, 0); rendez_vous1 = socket (AF_INET, SOCK_STREAM, 0);
if (rendez_vous < 0) { if (rendez_vous1 < 0) {
fprintf (stderr, "%s: socket failed: %s\n", prog, fprintf (stderr, "%s: socket failed: %s\n", prog,
strerror(errno)); strerror(errno));
return 1; return 1;
} }
memset (&newaddr, 0, sizeof(newaddr)); memset (&newaddr, 0, sizeof(newaddr));
if (bind (rendez_vous, (struct sockaddr *)&newaddr, if (bind (rendez_vous1, (struct sockaddr *)&newaddr,
sizeof(newaddr)) < 0) { sizeof(newaddr)) < 0) {
fprintf (stderr, "%s: bind: %s\n", prog, strerror(errno)); fprintf (stderr, "%s: bind: %s\n", prog, strerror(errno));
return 1; return 1;
} }
addrlen = sizeof(newaddr); addrlen = sizeof(newaddr);
if (getsockname (rendez_vous, (struct sockaddr *)&newaddr, if (getsockname (rendez_vous1, (struct sockaddr *)&newaddr,
&addrlen) < 0) { &addrlen) < 0) {
fprintf (stderr, "%s: getsockname: %s\n", prog, fprintf (stderr, "%s: getsockname: %s\n", prog,
strerror(errno)); strerror(errno));
return 1; return 1;
} }
if (listen (rendez_vous, SOMAXCONN) < 0) { if (listen (rendez_vous1, SOMAXCONN) < 0) {
fprintf (stderr, "%s: listen: %s\n", prog, strerror(errno)); fprintf (stderr, "%s: listen: %s\n", prog, strerror(errno));
return 1; return 1;
} }
@@ -317,6 +335,17 @@ doit (char *host, int passivep, int debugp)
} }
/* close (otherside); */ /* close (otherside); */
fn = passive; fn = passive;
} else {
display_num = get_xsockets (&rendez_vous1,
tcpp ? &rendez_vous2 : NULL);
if (display_num < 0)
return 1;
strncpy(xauthfile, tempnam("/tmp", NULL), sizeof(xauthfile));
if (create_and_write_cookie (xauthfile, cookie, cookie_len))
return 1;
fn = active;
}
if(debugp) if(debugp)
printf ("%d\t%d\t%s\n", getpid(), display_num, xauthfile); printf ("%d\t%d\t%s\n", getpid(), display_num, xauthfile);
else { else {
@@ -331,18 +360,28 @@ doit (char *host, int passivep, int debugp)
fclose(stdout); fclose(stdout);
} }
} }
} else {
display_num = get_xsockets (&rendez_vous, NULL);
if (display_num < 0)
return 1;
fn = active;
}
for (;;) { for (;;) {
fd_set fdset;
pid_t child; pid_t child;
int fd; int fd, thisfd;
int zero = 0; int zero = 0;
int one = 1;
fd = accept (rendez_vous, NULL, &zero); FD_ZERO(&fdset);
if (rendez_vous1)
FD_SET(rendez_vous1, &fdset);
if (rendez_vous2)
FD_SET(rendez_vous2, &fdset);
if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) <= 0)
continue;
if (rendez_vous1 && FD_ISSET(rendez_vous1, &fdset))
thisfd = rendez_vous1;
else if (rendez_vous2 && FD_ISSET(rendez_vous2, &fdset))
thisfd = rendez_vous2;
else
continue;
fd = accept (thisfd, NULL, &zero);
if (fd < 0) if (fd < 0)
if (errno == EINTR) if (errno == EINTR)
continue; continue;
@@ -351,6 +390,9 @@ doit (char *host, int passivep, int debugp)
strerror(errno)); strerror(errno));
return 1; return 1;
} }
#ifdef TCP_NODELAY
setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
#endif
++nchild; ++nchild;
child = fork (); child = fork ();
if (child < 0) { if (child < 0) {
@@ -358,7 +400,10 @@ doit (char *host, int passivep, int debugp)
strerror(errno)); strerror(errno));
continue; continue;
} else if (child == 0) { } else if (child == 0) {
close (rendez_vous); if (rendez_vous1)
close (rendez_vous1);
if (rendez_vous2)
close (rendez_vous2);
return (*fn)(fd, host, &key, schedule); return (*fn)(fd, host, &key, schedule);
} else { } else {
close (fd); close (fd);
@@ -369,7 +414,7 @@ doit (char *host, int passivep, int debugp)
static void static void
usage(void) usage(void)
{ {
fprintf (stderr, "Usage: %s [-d] host\n", prog); fprintf (stderr, "Usage: %s [-d] [-t] host\n", prog);
exit (1); exit (1);
} }
@@ -384,15 +429,18 @@ main(int argc, char **argv)
{ {
int passivep; int passivep;
char *disp; char *disp;
int debugp = 0; int debugp = 0, tcpp = 0;
int c; int c;
prog = argv[0]; prog = argv[0];
while((c = getopt(argc, argv, "d")) != EOF) { while((c = getopt(argc, argv, "td")) != EOF) {
switch(c) { switch(c) {
case 'd' : case 'd' :
debugp = 1; debugp = 1;
break; break;
case 't' :
tcpp = 1;
break;
case '?': case '?':
default: default:
usage(); usage();
@@ -407,12 +455,8 @@ main(int argc, char **argv)
disp = getenv("DISPLAY"); disp = getenv("DISPLAY");
passivep = disp != NULL && passivep = disp != NULL &&
(*disp == ':' || strncmp(disp, "unix", 4) == 0); (*disp == ':' || strncmp(disp, "unix", 4) == 0);
/* non passive mode has not been tested and I'm not sure it works
* at all, so better disable it.
*/
passivep = 1;
signal (SIGCHLD, childhandler); signal (SIGCHLD, childhandler);
signal (SIGUSR1, usr1handler); signal (SIGUSR1, usr1handler);
signal (SIGUSR2, usr2handler); signal (SIGUSR2, usr2handler);
return doit (argv[0], passivep, debugp); return doit (argv[0], passivep, debugp, tcpp);
} }