How to decrease TCP connect() system call timeout?

女生的网名这么多〃 提交于 2019-12-05 13:44:13

It is determined by TCP. It can be decreased on a per-socket basis by application code.

NB The timeout only takes effect if there is no response at all. If there is a connection refusal, the error occurs immediately.

It's not possible in Bash without modifying the source as already mentioned, although here is the workaround by using timeout command, e.g.:

$ timeout 1 bash -c "</dev/tcp/stackoverflow.com/80" && echo Port open. || echo Port closed.
Port open.
$ timeout 1 bash -c "</dev/tcp/stackoverflow.com/81" && echo Port open. || echo Port closed.
Port closed.

Using this syntax, the timeout command will kill the process after the given time.

See: timeout --help for more options.

No: there is no way of changing timeout by using /dev/tcp/

Yes, you could change default timeout for TCP connection in any programming language.

But, is not a programming language!

You could have a look into source code (see: Bash Homepage), you may find lib/sh/netopen.c file where you could read in _netopen4 function:

s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0);

You could read this file carefully, there are no consideration of connection timeout.

Without patching bash sources, there is no way of changing connection timeout by a bash script.

Simple HTTP client using netcat (near pure bash)

There is a little sample HTTP client written in pure bash, but using netcat:

#!/bin/bash

tmpfile=$(mktemp -p $HOME .netbash-XXXXXX)
exec 7> >(nc -w 3 -q 0 stackoverflow.com 80 >$tmpfile)
exec 6<$tmpfile
rm $tmpfile

printf >&7 "GET %s HTTP/1.0\r\nHost: stackoverflow.com\r\n\r\n" \
    /questions/24317341/how-to-decrease-tcp-connect-system-call-timeout

timeout=100;
while ! read -t .001 -u 6 status ; do read -t .001 foo;done
echo STATUS: $status

[ "$status" ] && [ -z "${status//HTTP*200 OK*}" ] || exit 1

echo HEADER:
while read -u 6 -a head && [ "${head//$'\r'}" ]; do
    printf "%-20s : %s\n" ${head%:} "${head[*]:1}"
    done

echo TITLE:
sed '/<title>/s/<[^>]*>//gp;d' <&6

exec 7>&-
exec 6<&-

This could render:

STATUS: HTTP/1.1 200 OK
HEADER:
Cache-Control        : private
Content-Type         : text/html; charset=utf-8
X-Frame-Options      : SAMEORIGIN
X-Request-Guid       : 46d55dc9-f7fe-425f-a560-fc49d885a5e5
Content-Length       : 91642
Accept-Ranges        : bytes
Date                 : Wed, 19 Oct 2016 13:24:35 GMT
Via                  : 1.1 varnish
Age                  : 0
Connection           : close
X-Served-By          : cache-fra1243-FRA
X-Cache              : MISS
X-Cache-Hits         : 0
X-Timer              : S1476883475.343528,VS0,VE100
X-DNS-Prefetch-Control : off
Set-Cookie           : prov=ff1129e3-7de5-9375-58ee-5f739eb73449; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
TITLE:
bash - How to decrease TCP connect() system call timeout? - Stack Overflow
Some explanations:

We create first a temporary file (under private directory for security reason), bind and delete before using them.

$ tmpfile=$(mktemp -p $HOME .netbash-XXXXXX)
$ exec 7> >(nc -w 3 -q 0 stackoverflow.com 80 >$tmpfile)
$ exec 6<$tmpfile
$ rm $tmpfile

$ ls $tmpfile
ls: cannot access /home/user/.netbash-rKvpZW: No such file or directory

$ ls -l /proc/self/fd
lrwx------ 1 user user 64 Oct 19 15:20 0 -> /dev/pts/1
lrwx------ 1 user user 64 Oct 19 15:20 1 -> /dev/pts/1
lrwx------ 1 user user 64 Oct 19 15:20 2 -> /dev/pts/1
lr-x------ 1 user user 64 Oct 19 15:20 3 -> /proc/30237/fd
lr-x------ 1 user user 64 Oct 19 15:20 6 -> /home/user/.netbash-rKvpZW (deleted)
l-wx------ 1 user user 64 Oct 19 15:20 7 -> pipe:[2097453]

$ echo GET / HTTP/1.0$'\r\n\r' >&7
$ read -u 6 foo
$ echo $foo
HTTP/1.1 500 Domain Not Found

$ exec 7>&-
$ exec 6>&-
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!