|
|
c1c61d |
diff -up stunnel-4.56/src/client.c.pollhup stunnel-4.56/src/client.c
|
|
|
c1c61d |
--- stunnel-4.56/src/client.c.pollhup 2016-03-31 17:17:01.438314029 +0200
|
|
|
c1c61d |
+++ stunnel-4.56/src/client.c 2016-03-31 17:25:48.573618470 +0200
|
|
|
c1c61d |
@@ -595,35 +595,6 @@ static void transfer(CLI *c) {
|
|
|
c1c61d |
}
|
|
|
c1c61d |
}
|
|
|
c1c61d |
|
|
|
c1c61d |
- /****************************** check for hangup conditions */
|
|
|
c1c61d |
- if(s_poll_hup(c->fds, c->sock_rfd->fd)) {
|
|
|
c1c61d |
- s_log(LOG_INFO, "Read socket closed (hangup)");
|
|
|
c1c61d |
- sock_open_rd=0;
|
|
|
c1c61d |
- }
|
|
|
c1c61d |
- if(s_poll_hup(c->fds, c->sock_wfd->fd)) {
|
|
|
c1c61d |
- if(c->ssl_ptr) {
|
|
|
c1c61d |
- s_log(LOG_ERR,
|
|
|
c1c61d |
- "Write socket closed (hangup) with %d unsent byte(s)",
|
|
|
c1c61d |
- c->ssl_ptr);
|
|
|
c1c61d |
- longjmp(c->err, 1); /* reset the socket */
|
|
|
c1c61d |
- }
|
|
|
c1c61d |
- s_log(LOG_INFO, "Write socket closed (hangup)");
|
|
|
c1c61d |
- sock_open_wr=0;
|
|
|
c1c61d |
- }
|
|
|
c1c61d |
- if(s_poll_hup(c->fds, c->ssl_rfd->fd) ||
|
|
|
c1c61d |
- s_poll_hup(c->fds, c->ssl_wfd->fd)) {
|
|
|
c1c61d |
- /* hangup -> buggy (e.g. Microsoft) peer:
|
|
|
c1c61d |
- * SSL socket closed without close_notify alert */
|
|
|
c1c61d |
- if(c->sock_ptr) {
|
|
|
c1c61d |
- s_log(LOG_ERR,
|
|
|
c1c61d |
- "SSL socket closed (hangup) with %d unsent byte(s)",
|
|
|
c1c61d |
- c->sock_ptr);
|
|
|
c1c61d |
- longjmp(c->err, 1); /* reset the socket */
|
|
|
c1c61d |
- }
|
|
|
c1c61d |
- s_log(LOG_INFO, "SSL socket closed (hangup)");
|
|
|
c1c61d |
- SSL_set_shutdown(c->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
|
|
|
c1c61d |
- }
|
|
|
c1c61d |
-
|
|
|
c1c61d |
/****************************** retrieve results from c->fds */
|
|
|
c1c61d |
sock_can_rd=s_poll_canread(c->fds, c->sock_rfd->fd);
|
|
|
c1c61d |
sock_can_wr=s_poll_canwrite(c->fds, c->sock_wfd->fd);
|
|
|
c1c61d |
@@ -828,6 +799,36 @@ static void transfer(CLI *c) {
|
|
|
c1c61d |
}
|
|
|
c1c61d |
}
|
|
|
c1c61d |
|
|
|
c1c61d |
+ /****************************** check for hangup conditions */
|
|
|
c1c61d |
+ if(s_poll_rdhup(c->fds, c->sock_rfd->fd) &&
|
|
|
c1c61d |
+ !s_poll_canread(c->fds, c->sock_rfd->fd)) {
|
|
|
c1c61d |
+ s_log(LOG_INFO, "Read socket closed (hangup)");
|
|
|
c1c61d |
+ sock_open_rd=0;
|
|
|
c1c61d |
+ }
|
|
|
c1c61d |
+ if(s_poll_hup(c->fds, c->sock_wfd->fd)) {
|
|
|
c1c61d |
+ if(c->ssl_ptr) {
|
|
|
c1c61d |
+ s_log(LOG_ERR,
|
|
|
c1c61d |
+ "Write socket closed (hangup) with %d unsent byte(s)",
|
|
|
c1c61d |
+ c->ssl_ptr);
|
|
|
c1c61d |
+ longjmp(c->err, 1); /* reset the socket */
|
|
|
c1c61d |
+ }
|
|
|
c1c61d |
+ s_log(LOG_INFO, "Write socket closed (hangup)");
|
|
|
c1c61d |
+ sock_open_wr=0;
|
|
|
c1c61d |
+ }
|
|
|
c1c61d |
+ if((s_poll_hup(c->fds, c->ssl_rfd->fd) && !s_poll_canread(c->fds, c->sock_rfd->fd)) ||
|
|
|
c1c61d |
+ s_poll_hup(c->fds, c->ssl_wfd->fd)) {
|
|
|
c1c61d |
+ /* hangup -> buggy (e.g. Microsoft) peer:
|
|
|
c1c61d |
+ * SSL socket closed without close_notify alert */
|
|
|
c1c61d |
+ if(c->sock_ptr) {
|
|
|
c1c61d |
+ s_log(LOG_ERR,
|
|
|
c1c61d |
+ "SSL socket closed (hangup) with %d unsent byte(s)",
|
|
|
c1c61d |
+ c->sock_ptr);
|
|
|
c1c61d |
+ longjmp(c->err, 1); /* reset the socket */
|
|
|
c1c61d |
+ }
|
|
|
c1c61d |
+ s_log(LOG_INFO, "SSL socket closed (hangup)");
|
|
|
c1c61d |
+ SSL_set_shutdown(c->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
|
|
|
c1c61d |
+ }
|
|
|
c1c61d |
+
|
|
|
c1c61d |
/****************************** check write shutdown conditions */
|
|
|
c1c61d |
if(sock_open_wr && SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN && !c->ssl_ptr) {
|
|
|
c1c61d |
sock_open_wr=0; /* no further write allowed */
|
|
|
c1c61d |
diff -up stunnel-4.56/src/network.c.pollhup stunnel-4.56/src/network.c
|
|
|
c1c61d |
--- stunnel-4.56/src/network.c.pollhup 2013-03-13 14:41:02.000000000 +0100
|
|
|
c1c61d |
+++ stunnel-4.56/src/network.c 2016-03-31 17:25:48.574618494 +0200
|
|
|
c1c61d |
@@ -79,8 +79,12 @@ void s_poll_add(s_poll_set *fds, int fd,
|
|
|
c1c61d |
fds->ufds[i].events=0;
|
|
|
c1c61d |
fds->nfds++;
|
|
|
c1c61d |
}
|
|
|
c1c61d |
- if(rd)
|
|
|
c1c61d |
+ if(rd) {
|
|
|
c1c61d |
fds->ufds[i].events|=POLLIN;
|
|
|
c1c61d |
+#ifdef POLLRDHUP
|
|
|
c1c61d |
+ fds->ufds[i].events|=POLLRDHUP;
|
|
|
c1c61d |
+#endif
|
|
|
c1c61d |
+ }
|
|
|
c1c61d |
if(wr)
|
|
|
c1c61d |
fds->ufds[i].events|=POLLOUT;
|
|
|
c1c61d |
}
|
|
|
c1c61d |
@@ -103,12 +107,27 @@ int s_poll_canwrite(s_poll_set *fds, int
|
|
|
c1c61d |
return 0; /* not listed in fds */
|
|
|
c1c61d |
}
|
|
|
c1c61d |
|
|
|
c1c61d |
+/* best doc: http://lxr.free-electrons.com/source/net/ipv4/tcp.c#L456 */
|
|
|
c1c61d |
+
|
|
|
c1c61d |
int s_poll_hup(s_poll_set *fds, int fd) {
|
|
|
c1c61d |
unsigned int i;
|
|
|
c1c61d |
|
|
|
c1c61d |
for(i=0; i<fds->nfds; i++)
|
|
|
c1c61d |
if(fds->ufds[i].fd==fd)
|
|
|
c1c61d |
- return fds->ufds[i].revents&POLLHUP;
|
|
|
c1c61d |
+ return fds->ufds[i].revents&POLLHUP; /* read and write closed */
|
|
|
c1c61d |
+ return 0; /* not listed in fds */
|
|
|
c1c61d |
+}
|
|
|
c1c61d |
+
|
|
|
c1c61d |
+int s_poll_rdhup(s_poll_set *fds, int fd) {
|
|
|
c1c61d |
+ unsigned int i;
|
|
|
c1c61d |
+
|
|
|
c1c61d |
+ for(i=0; i<fds->nfds; i++)
|
|
|
c1c61d |
+ if(fds->ufds[i].fd==fd)
|
|
|
c1c61d |
+#ifdef POLLRDHUP
|
|
|
c1c61d |
+ return fds->ufds[i].revents&POLLRDHUP; /* read closed */
|
|
|
c1c61d |
+#else
|
|
|
c1c61d |
+ return fds->ufds[i].revents&POLLHUP; /* read and write closed */
|
|
|
c1c61d |
+#endif
|
|
|
c1c61d |
return 0; /* not listed in fds */
|
|
|
c1c61d |
}
|
|
|
c1c61d |
|
|
|
c1c61d |
@@ -336,6 +355,12 @@ int s_poll_hup(s_poll_set *fds, int fd)
|
|
|
c1c61d |
return 0; /* FIXME: how to detect HUP condition with select()? */
|
|
|
c1c61d |
}
|
|
|
c1c61d |
|
|
|
c1c61d |
+int s_poll_rdhup(s_poll_set *fds, int fd) {
|
|
|
c1c61d |
+ (void)fds; /* skip warning about unused parameter */
|
|
|
c1c61d |
+ (void)fd; /* skip warning about unused parameter */
|
|
|
c1c61d |
+ return 0; /* FIXME: how to detect RDHUP condition with select()? */
|
|
|
c1c61d |
+}
|
|
|
c1c61d |
+
|
|
|
c1c61d |
int s_poll_error(s_poll_set *fds, int fd) {
|
|
|
c1c61d |
/* error conditions are signaled as read, but apparently *not* in Winsock:
|
|
|
c1c61d |
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx */
|
|
|
c1c61d |
diff -up stunnel-4.56/src/prototypes.h.pollhup stunnel-4.56/src/prototypes.h
|
|
|
c1c61d |
--- stunnel-4.56/src/prototypes.h.pollhup 2013-03-19 18:30:55.000000000 +0100
|
|
|
c1c61d |
+++ stunnel-4.56/src/prototypes.h 2016-03-31 17:25:48.574618494 +0200
|
|
|
c1c61d |
@@ -385,6 +385,7 @@ void s_poll_add(s_poll_set *, int, int,
|
|
|
c1c61d |
int s_poll_canread(s_poll_set *, int);
|
|
|
c1c61d |
int s_poll_canwrite(s_poll_set *, int);
|
|
|
c1c61d |
int s_poll_hup(s_poll_set *, int);
|
|
|
c1c61d |
+int s_poll_rdhup(s_poll_set *, int);
|
|
|
c1c61d |
int s_poll_error(s_poll_set *, int);
|
|
|
c1c61d |
int s_poll_wait(s_poll_set *, int, int);
|
|
|
c1c61d |
|