diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/usr.bin/nc/nc.1 | 8 | ||||
| -rw-r--r-- | src/usr.bin/nc/netcat.c | 42 |
2 files changed, 44 insertions, 6 deletions
diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1 index 6a1538cb45..d249aa18b1 100644 --- a/src/usr.bin/nc/nc.1 +++ b/src/usr.bin/nc/nc.1 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $OpenBSD: nc.1,v 1.58 2011/09/17 14:10:05 haesbaert Exp $ | 1 | .\" $OpenBSD: nc.1,v 1.59 2011/10/04 08:34:34 fgsch Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1996 David Sacerdote | 3 | .\" Copyright (c) 1996 David Sacerdote |
| 4 | .\" All rights reserved. | 4 | .\" All rights reserved. |
| @@ -25,7 +25,7 @@ | |||
| 25 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | .\" | 27 | .\" |
| 28 | .Dd $Mdocdate: September 17 2011 $ | 28 | .Dd $Mdocdate: October 4 2011 $ |
| 29 | .Dt NC 1 | 29 | .Dt NC 1 |
| 30 | .Os | 30 | .Os |
| 31 | .Sh NAME | 31 | .Sh NAME |
| @@ -210,9 +210,9 @@ Have | |||
| 210 | .Nm | 210 | .Nm |
| 211 | give more verbose output. | 211 | give more verbose output. |
| 212 | .It Fl w Ar timeout | 212 | .It Fl w Ar timeout |
| 213 | If a connection and stdin are idle for more than | 213 | Connections which cannot be established or are idle timeout after |
| 214 | .Ar timeout | 214 | .Ar timeout |
| 215 | seconds, then the connection is silently closed. | 215 | seconds. |
| 216 | The | 216 | The |
| 217 | .Fl w | 217 | .Fl w |
| 218 | flag has no effect on the | 218 | flag has no effect on the |
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index 952bfb7dda..7880c7f452 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: netcat.c,v 1.102 2011/09/17 14:10:05 haesbaert Exp $ */ | 1 | /* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
| 4 | * | 4 | * |
| @@ -98,6 +98,7 @@ void help(void); | |||
| 98 | int local_listen(char *, char *, struct addrinfo); | 98 | int local_listen(char *, char *, struct addrinfo); |
| 99 | void readwrite(int); | 99 | void readwrite(int); |
| 100 | int remote_connect(const char *, const char *, struct addrinfo); | 100 | int remote_connect(const char *, const char *, struct addrinfo); |
| 101 | int timeout_connect(int, const struct sockaddr *, socklen_t); | ||
| 101 | int socks_connect(const char *, const char *, struct addrinfo, | 102 | int socks_connect(const char *, const char *, struct addrinfo, |
| 102 | const char *, const char *, struct addrinfo, int, const char *); | 103 | const char *, const char *, struct addrinfo, int, const char *); |
| 103 | int udptest(int); | 104 | int udptest(int); |
| @@ -590,7 +591,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) | |||
| 590 | 591 | ||
| 591 | set_common_sockopts(s); | 592 | set_common_sockopts(s); |
| 592 | 593 | ||
| 593 | if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) | 594 | if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) |
| 594 | break; | 595 | break; |
| 595 | else if (vflag) | 596 | else if (vflag) |
| 596 | warn("connect to %s port %s (%s) failed", host, port, | 597 | warn("connect to %s port %s (%s) failed", host, port, |
| @@ -605,6 +606,43 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) | |||
| 605 | return (s); | 606 | return (s); |
| 606 | } | 607 | } |
| 607 | 608 | ||
| 609 | int | ||
| 610 | timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) | ||
| 611 | { | ||
| 612 | struct pollfd pfd; | ||
| 613 | socklen_t optlen; | ||
| 614 | int flags, optval; | ||
| 615 | int ret; | ||
| 616 | |||
| 617 | if (timeout != -1) { | ||
| 618 | flags = fcntl(s, F_GETFL, 0); | ||
| 619 | if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) | ||
| 620 | err(1, "set non-blocking mode"); | ||
| 621 | } | ||
| 622 | |||
| 623 | if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { | ||
| 624 | pfd.fd = s; | ||
| 625 | pfd.events = POLLOUT; | ||
| 626 | if ((ret = poll(&pfd, 1, timeout)) == 1) { | ||
| 627 | optlen = sizeof(optval); | ||
| 628 | if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, | ||
| 629 | &optval, &optlen)) == 0) { | ||
| 630 | errno = optval; | ||
| 631 | ret = optval == 0 ? 0 : -1; | ||
| 632 | } | ||
| 633 | } else if (ret == 0) { | ||
| 634 | errno = ETIMEDOUT; | ||
| 635 | ret = -1; | ||
| 636 | } else | ||
| 637 | err(1, "poll failed"); | ||
| 638 | } | ||
| 639 | |||
| 640 | if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) | ||
| 641 | err(1, "restoring flags"); | ||
| 642 | |||
| 643 | return (ret); | ||
| 644 | } | ||
| 645 | |||
| 608 | /* | 646 | /* |
| 609 | * local_listen() | 647 | * local_listen() |
| 610 | * Returns a socket listening on a local port, binds to specified source | 648 | * Returns a socket listening on a local port, binds to specified source |
