mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
ctdb-scripts: Use ss instead of netstat for finding TCP connections
ss with a filter is much faster than post-processing output from netstat. CTDB already has a hard dependency on iproute2 for IP address handling, so depending on ss is no big deal. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
parent
4a658440e1
commit
04fe9e2074
@ -531,11 +531,7 @@ get_tcp_connections_for_ip ()
|
||||
{
|
||||
_ip="$1"
|
||||
|
||||
netstat -tn | awk -v ip=$_ip \
|
||||
'index($1, "tcp") == 1 && \
|
||||
(index($4, ip ":") == 1 || index($4, "::ffff:" ip ":") == 1) \
|
||||
&& $6 == "ESTABLISHED" \
|
||||
{print $4" "$5}'
|
||||
ss -tn state established "src [$_ip]" | awk 'NR > 1 {print $3, $4}'
|
||||
}
|
||||
|
||||
########################################################
|
||||
@ -1183,17 +1179,24 @@ update_tickles ()
|
||||
# What public IPs do I hold?
|
||||
_ips=$(ctdb -X ip | awk -F'|' -v pnn=$pnn '$3 == pnn {print $2}')
|
||||
|
||||
# IPs as a regexp choice
|
||||
_ipschoice="($(echo $_ips | sed -e 's/ /|/g' -e 's/\./\\\\./g'))"
|
||||
# IPs and port as ss filters
|
||||
_ip_filter=""
|
||||
for _ip in $_ips ; do
|
||||
_ip_filter="${_ip_filter}${_ip_filter:+ || }src [${_ip}]"
|
||||
done
|
||||
_port_filter="sport == :${_port}"
|
||||
|
||||
# Record connections to our public IPs in a temporary file.
|
||||
# This temporary file is in CTDB's private state directory and
|
||||
# $$ is used to avoid a very rare race involving CTDB's script
|
||||
# debugging. No security issue, nothing to see here...
|
||||
_my_connections="${tickledir}/${_port}.connections.$$"
|
||||
netstat -tn |
|
||||
awk -v destpat="^${_ipschoice}:${_port}\$" \
|
||||
'$1 == "tcp" && $6 == "ESTABLISHED" && $4 ~ destpat {print $5, $4}' |
|
||||
# Parentheses are needed around the filters for precedence but
|
||||
# the parentheses can't be empty!
|
||||
ss -tn state established \
|
||||
"${_ip_filter:+( ${_ip_filter} )}" \
|
||||
"${_port_filter:+( ${_port_filter} )}" |
|
||||
awk 'NR > 1 {print $4, $3}' |
|
||||
sort >"$_my_connections"
|
||||
|
||||
# Record our current tickles in a temporary file
|
||||
|
88
ctdb/tests/eventscripts/stubs/ss
Executable file
88
ctdb/tests/eventscripts/stubs/ss
Executable file
@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
|
||||
prog="ss"
|
||||
|
||||
usage ()
|
||||
{
|
||||
cat >&2 <<EOF
|
||||
Usage: $prog -tn state established [ '(' ip-filter ')' ] [ '(' port-filter ')' ]
|
||||
|
||||
A fake ss stub that prints items depending on the variables
|
||||
FAKE_NETSTAT_TCP_ESTABLISHED and FAKE_NETSTAT_TCP_ESTABLISHED_FILE.
|
||||
|
||||
Note that "-tn state established" must be given.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$1" != "-tn" -o "$2" != "state" -o "$3" != "established" ] ; then
|
||||
usage
|
||||
fi
|
||||
|
||||
shift 3
|
||||
|
||||
# Check if socket has matches in both ok_ips and ok_ports
|
||||
filter_socket ()
|
||||
{
|
||||
ok_ips="$1"
|
||||
ok_ports="$2"
|
||||
socket="$3"
|
||||
|
||||
ip="${socket%:*}"
|
||||
port="${socket##*:}"
|
||||
|
||||
if [ "$ok_ports" != "|" -a "${ok_ports#*|${port}|}" = "$ok_ports" ] ; then
|
||||
return 1
|
||||
fi
|
||||
if [ "$ok_ips" != "|" -a "${ok_ips#*|${ip}|}" = "$ok_ips" ] ; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
ss_tcp_established ()
|
||||
{
|
||||
echo "Recv-Q Send-Q Local Address:Port Peer Address:Port"
|
||||
|
||||
# Very limited implementation:
|
||||
# We only expect to find || inside parentheses
|
||||
# We don't expect to see && - it is implied by juxtaposition
|
||||
# Operator for port comparison is ignored and assumed to be ==
|
||||
|
||||
# Build lists of source ports and source IP addresses where each
|
||||
# entry is surrounded by '|' characters. These lists can be
|
||||
# easily "searched" using the POSIX prefix and suffix removal
|
||||
# operators.
|
||||
in_parens=false
|
||||
sports="|"
|
||||
srcs="|"
|
||||
|
||||
while [ -n "$1" ] ; do
|
||||
case "$1" in
|
||||
\() in_parens=true ; shift ;;
|
||||
\)) in_parens=false ; shift ;;
|
||||
\|\|) if ! $in_parens ; then usage ; fi ; shift ;;
|
||||
sport) p="${3#:}" ; sports="${sports}${p}|" ; shift 3 ;;
|
||||
src) ip="${2#\[}" ; ip="${ip%\]}" ; srcs="${srcs}${ip}|" ; shift 2 ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
for i in $FAKE_NETSTAT_TCP_ESTABLISHED ; do
|
||||
src="${i%|*}"
|
||||
dst="${i#*|}"
|
||||
if filter_socket "$srcs" "$sports" "$src" ; then
|
||||
echo 0 0 "$src" "$dst"
|
||||
fi
|
||||
done
|
||||
while read src dst ; do
|
||||
if filter_socket "$srcs" "$sports" "$src" ; then
|
||||
echo 0 0 "$src" "$dst"
|
||||
fi
|
||||
done <"$FAKE_NETSTAT_TCP_ESTABLISHED_FILE"
|
||||
}
|
||||
|
||||
# Yes, lose the quoting so we can do a hacky parsing job
|
||||
ss_tcp_established $*
|
Loading…
x
Reference in New Issue
Block a user