(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:
106
appl/kx/kx.c
106
appl/kx/kx.c
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user