/*
- * $Id: dsi_tcp.c,v 1.9 2002-01-24 16:27:31 jmarcus Exp $
+ * $Id: dsi_tcp.c,v 1.10 2005-04-28 20:50:02 bfernhomberg Exp $
*
* Copyright (c) 1997, 1998 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
static void timeout_handler()
{
LOG(log_error, logtype_default, "dsi_tcp_open: connection timed out");
- exit(1);
+ exit(EXITERR_CLNT);
}
+#ifdef ATACC
+#define fork aTaC_fork
+#endif
+
+static struct itimerval itimer;
/* accept the socket and do a little sanity checking */
static int dsi_tcp_open(DSI *dsi)
{
if (dsi->socket < 0)
return -1;
- if ((pid = fork()) == 0) { /* child */
- static const struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
+ getitimer(ITIMER_PROF, &itimer);
+ if (0 == (pid = fork()) ) { /* child */
+ static struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
struct sigaction newact, oldact;
u_int8_t block[DSI_BLOCKSIZ];
size_t stored;
- /* reset a couple signals */
- signal(SIGTERM, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
+ /* reset signals */
+ server_reset_signal();
/* install an alarm to deal with non-responsive connections */
newact.sa_handler = timeout_handler;
newact.sa_flags = 0;
sigemptyset(&oldact.sa_mask);
oldact.sa_flags = 0;
+ setitimer(ITIMER_PROF, &itimer, NULL);
+
if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
(setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
LOG(log_error, logtype_default, "dsi_tcp_open: %s", strerror(errno));
- exit(1);
+ exit(EXITERR_SYS);
}
/* read in commands. this is similar to dsi_receive except
/* read in the first two bytes */
len = dsi_stream_read(dsi, block, 2);
- if (len <= 0 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
+ if (!len ) {
+ /* connection already closed, don't log it (normal OSX 10.3 behaviour) */
+ exit(EXITERR_CLNT);
+ }
+ if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
LOG(log_error, logtype_default, "dsi_tcp_open: invalid header");
- exit(1);
+ exit(EXITERR_CLNT);
}
/* read in the rest of the header */
stored += len;
else {
LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
- exit(1);
+ exit(EXITERR_CLNT);
}
}
stored += len;
else {
LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
- exit(1);
+ exit(EXITERR_CLNT);
}
}
- /* restore signal */
+ /* stop timer and restore signal handler */
+ memset(&timer, 0, sizeof(timer));
+ setitimer(ITIMER_REAL, &timer, NULL);
sigaction(SIGALRM, &oldact, NULL);
LOG(log_info, logtype_default,"ASIP session:%u(%d) from %s:%u(%d)",
#ifdef SO_REUSEADDR
port = 1;
setsockopt(dsi->serversock, SOL_SOCKET, SO_REUSEADDR, &port, sizeof(port));
-#endif /* SO_REUSEADDR */
+#endif
#ifdef USE_TCP_NODELAY
+
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
-#endif /* ! SOL_TCP */
+#endif
+
port = 1;
setsockopt(dsi->serversock, SOL_TCP, TCP_NODELAY, &port, sizeof(port));
#endif /* USE_TCP_NODELAY */
}
}
+ /* Point protocol specific functions to tcp versions */
+ dsi->proto_open = dsi_tcp_open;
+ dsi->proto_close = dsi_tcp_close;
+
/* get real address for GetStatus. we'll go through the list of
* interfaces if necessary. */
- if (!address) {
- if ((host = gethostbyname(hostname))) /* we can resolve the name */
- dsi->server.sin_addr.s_addr = ((struct in_addr *) host->h_addr)->s_addr;
- else {
+
+ if (address) {
+ /* address is a parameter, use it 'as is' */
+ return 1;
+ }
+
+ if (!(host = gethostbyname(hostname)) ) { /* we can't resolve the name */
+
+ LOG(log_info, logtype_default, "dsi_tcp: cannot resolve hostname '%s'", hostname);
+ if (proxy) {
+ /* give up we have nothing to advertise */
+ return 0;
+ }
+ }
+ else {
+ if (((struct in_addr *) host->h_addr)->s_addr != 0x100007F) { /* FIXME ugly check */
+ dsi->server.sin_addr.s_addr = ((struct in_addr *) host->h_addr)->s_addr;
+ return 1;
+ }
+ LOG(log_info, logtype_default, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
+ }
+ {
char **start, **list;
struct ifreq ifr;
/* get it from the interface list */
start = list = getifacelist();
while (list && *list) {
- strncpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name));
- list++;
+ strlcpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name));
+ list++;
#ifndef IFF_SLAVE
#define IFF_SLAVE 0
-#endif /* ! IFF_SLAVE */
- if (ioctl(dsi->serversock, SIOCGIFFLAGS, &ifr) < 0)
- continue;
+#endif
- if (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_SLAVE))
- continue;
+ if (ioctl(dsi->serversock, SIOCGIFFLAGS, &ifr) < 0)
+ continue;
- if ((ifr.ifr_flags & IFF_UP) == 0)
- continue;
+ if (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_SLAVE))
+ continue;
- if (ioctl(dsi->serversock, SIOCGIFADDR, &ifr) < 0)
- continue;
+ if (!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) )
+ continue;
+
+ if (ioctl(dsi->serversock, SIOCGIFADDR, &ifr) < 0)
+ continue;
- dsi->server.sin_addr.s_addr =
- ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
- LOG(log_info, logtype_default, "dsi_tcp: Can't resolve hostname (%s).\n"
- "%s on interface %s will be used instead.", hostname,
+ dsi->server.sin_addr.s_addr =
+ ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
+ LOG(log_info, logtype_default, "dsi_tcp: '%s' on interface '%s' will be used instead.",
inet_ntoa(dsi->server.sin_addr), ifr.ifr_name);
- goto iflist_done;
-
+ goto iflist_done;
}
- LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp)\n\
-Check to make sure %s is in /etc/hosts and the correct domain is in\n\
+ LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp) \
+Check to make sure %s is in /etc/hosts and the correct domain is in \
/etc/resolv.conf: %s", hostname, strerror(errno));
iflist_done:
if (start)
- freeifacelist(start);
- }
+ freeifacelist(start);
}
- /* everything's set up. now point protocol specific functions to
- * tcp versions */
- dsi->proto_open = dsi_tcp_open;
- dsi->proto_close = dsi_tcp_close;
return 1;
}