Commit 87e27571 authored by Mike Hibler's avatar Mike Hibler

Fix a file descriptor leak in the proxy.

In the case the upstream server was not responding, this would slowly eat
away FDs and ephemeral ports.
parent c6596287
...@@ -143,6 +143,16 @@ static int progress = 0; ...@@ -143,6 +143,16 @@ static int progress = 0;
static int waitfor = 0; static int waitfor = 0;
static sigjmp_buf progtimo; static sigjmp_buf progtimo;
/*
* do{tcp,udp} all open a socket for sending a request and getting a reply.
* If we timeout during one of those functions, that socket will be left open.
* For a normal use of tmcc, we will immediately exit if a timeout happens so
* this is not a problem. However, in the proxy case, a timeout is not fatal,
* so we will have to close the socket. Note that the proxy does not use
* dounix, so we do not augment that function.
*/
volatile int reqsock = -1;
static void static void
tooktoolong(void) tooktoolong(void)
{ {
...@@ -657,6 +667,9 @@ dotcp(char *data, int outfd, struct in_addr serverip) ...@@ -657,6 +667,9 @@ dotcp(char *data, int outfd, struct in_addr serverip)
return -1; return -1;
} }
/* XXX see comment on declaration of reqsock */
reqsock = sock;
/* Create name. */ /* Create name. */
name.sin_family = AF_INET; name.sin_family = AF_INET;
name.sin_addr = serverip; name.sin_addr = serverip;
...@@ -669,9 +682,11 @@ dotcp(char *data, int outfd, struct in_addr serverip) ...@@ -669,9 +682,11 @@ dotcp(char *data, int outfd, struct in_addr serverip)
if (errno != ECONNREFUSED) { if (errno != ECONNREFUSED) {
perror("connecting stream socket"); perror("connecting stream socket");
CLOSE(sock); CLOSE(sock);
reqsock = -1;
return -1; return -1;
} }
CLOSE(sock); CLOSE(sock);
reqsock = -1;
} }
if (debug) if (debug)
fprintf(stderr, fprintf(stderr,
...@@ -744,6 +759,7 @@ dotcp(char *data, int outfd, struct in_addr serverip) ...@@ -744,6 +759,7 @@ dotcp(char *data, int outfd, struct in_addr serverip)
goto bad; goto bad;
} }
CLOSE(sock); CLOSE(sock);
reqsock = -1;
goto again; goto again;
} }
progress += cc; progress += cc;
...@@ -751,9 +767,11 @@ dotcp(char *data, int outfd, struct in_addr serverip) ...@@ -751,9 +767,11 @@ dotcp(char *data, int outfd, struct in_addr serverip)
goto bad; goto bad;
} }
CLOSE(sock); CLOSE(sock);
reqsock = -1;
return 0; return 0;
bad: bad:
CLOSE(sock); CLOSE(sock);
reqsock = -1;
return -1; return -1;
} }
...@@ -775,6 +793,9 @@ doudp(char *data, int outfd, struct in_addr serverip, int portnum) ...@@ -775,6 +793,9 @@ doudp(char *data, int outfd, struct in_addr serverip, int portnum)
return -1; return -1;
} }
/* XXX see comment on declaration of reqsock */
reqsock = sock;
/* Create name. */ /* Create name. */
name.sin_family = AF_INET; name.sin_family = AF_INET;
name.sin_addr = serverip; name.sin_addr = serverip;
...@@ -791,6 +812,7 @@ doudp(char *data, int outfd, struct in_addr serverip, int portnum) ...@@ -791,6 +812,7 @@ doudp(char *data, int outfd, struct in_addr serverip, int portnum)
else else
fprintf(stderr, "short write (%d != %d)\n", cc, n); fprintf(stderr, "short write (%d != %d)\n", cc, n);
close(sock); close(sock);
reqsock = -1;
return -1; return -1;
} }
connected = 1; connected = 1;
...@@ -801,9 +823,11 @@ doudp(char *data, int outfd, struct in_addr serverip, int portnum) ...@@ -801,9 +823,11 @@ doudp(char *data, int outfd, struct in_addr serverip, int portnum)
if (cc < 0) { if (cc < 0) {
perror("Reading from socket"); perror("Reading from socket");
close(sock); close(sock);
reqsock = -1;
return -1; return -1;
} }
close(sock); close(sock);
reqsock = -1;
progress += cc; progress += cc;
if (dooutput(outfd, buf, cc) < 0) if (dooutput(outfd, buf, cc) < 0)
return -1; return -1;
...@@ -1044,7 +1068,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial) ...@@ -1044,7 +1068,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial)
*/ */
while (1) { while (1) {
int rval; int rval;
volatile int useudp = 0; volatile int usingudp = 0;
fd_set fds; fd_set fds;
fds = rfds; fds = rfds;
...@@ -1093,7 +1117,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial) ...@@ -1093,7 +1117,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial)
close(newsock); close(newsock);
continue; continue;
} }
useudp = 1; usingudp = 1;
} else } else
newsock = -1; newsock = -1;
} else { } else {
...@@ -1127,7 +1151,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial) ...@@ -1127,7 +1151,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial)
strstr(bp, "VNODEID=")) strstr(bp, "VNODEID="))
continue; continue;
if (strstr(bp, "USEUDP=1")) { if (strstr(bp, "USEUDP=1")) {
useudp = 1; usingudp = 1;
continue; continue;
} }
strcat(command, bp); strcat(command, bp);
...@@ -1136,8 +1160,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial) ...@@ -1136,8 +1160,7 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial)
if (debug) { if (debug) {
fprintf(stderr, "%sREQ: %s\n", fprintf(stderr, "%sREQ: %s\n",
(udpsock >= 0 || useudp ? "UDP " : "TCP "), usingudp ? "UDP " : "TCP ", command);
command);
fflush(stderr); fflush(stderr);
} }
...@@ -1147,16 +1170,26 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial) ...@@ -1147,16 +1170,26 @@ beproxy(int tcpsock, int udpsock, struct in_addr serverip, char *partial)
if (waitfor) { if (waitfor) {
if (sigsetjmp(progtimo, 1) != 0) { if (sigsetjmp(progtimo, 1) != 0) {
fprintf(stderr, fprintf(stderr,
"Server request timeout on: %s\n", "Server %s request timeout on: %s\n",
command); usingudp ? "UDP" : "TCP", command);
if (newsock >= 0) if (newsock >= 0)
close(newsock); close(newsock);
if (reqsock >= 0) {
fprintf(stderr,
"Closing service socket %d\n",
reqsock);
if (usingudp)
close(reqsock);
else
CLOSE(reqsock);
reqsock = -1;
}
continue; continue;
} }
signal(SIGALRM, (sig_t)tooktoolong); signal(SIGALRM, (sig_t)tooktoolong);
alarm(waitfor); alarm(waitfor);
} }
if (useudp) if (usingudp)
rval = doudp(command, newsock, serverip, portlist[0]); rval = doudp(command, newsock, serverip, portlist[0]);
else else
rval = dotcp(command, newsock, serverip); rval = dotcp(command, newsock, serverip);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment