blob: ce8454514655f05ae8559d18c60388a69760c852 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
# Hey Emacs, this is a -*- shell-script -*- !!! :-)
get_src_socket ()
{
local proto="$1"
local dst_socket="$2"
local pid="$3"
local prog="$4"
local pat="^${proto}6?[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+${dst_socket//./\\.}[[:space:]]+ESTABLISHED[[:space:]]+${pid}/${prog}[[:space:]]*\$"
out=$(netstat -tanp |
egrep "$pat" |
awk '{ print $4 }')
[ -n "$out" ]
}
wait_until_get_src_socket ()
{
local proto="$1"
local dst_socket="$2"
local pid="$3"
local prog="$4"
echo "Waiting for ${prog} to establish connection to ${dst_socket}..."
wait_until 5 get_src_socket "$@"
}
#######################################
check_tickles ()
{
local node="$1"
local test_ip="$2"
local test_port="$3"
local src_socket="$4"
try_command_on_node $node ctdb gettickles $test_ip $test_port
# SRC: 10.0.2.45:49091 DST: 10.0.2.143:445
[ "${out/SRC: ${src_socket} /}" != "$out" ]
}
check_tickles_all ()
{
local numnodes="$1"
local test_ip="$2"
local test_port="$3"
local src_socket="$4"
try_command_on_node all ctdb gettickles $test_ip $test_port
# SRC: 10.0.2.45:49091 DST: 10.0.2.143:445
local t="${src_socket//./\\.}"
local count=$(grep -E -c "SRC: ${t} " <<<"$out" || true)
[ $count -eq $numnodes ]
}
#######################################
# filename will be in $tcpdump_filename, pid in $tcpdump_pid
tcpdump_start ()
{
tcpdump_filter="$1" # global
echo "Running tcpdump..."
tcpdump_filename=$(mktemp)
ctdb_test_exit_hook_add "rm -f $tcpdump_filename"
# The only way of being sure that tcpdump is listening is to send
# some packets that it will see. So we use dummy pings - the -U
# option to tcpdump ensures that packets are flushed to the file
# as they are captured.
local dummy_addr="127.3.2.1"
local dummy="icmp and dst host ${dummy_addr} and icmp[icmptype] == icmp-echo"
tcpdump -n -p -s 0 -e -U -w $tcpdump_filename -i any "($tcpdump_filter) or ($dummy)" &
ctdb_test_exit_hook_add "kill $! >/dev/null 2>&1"
echo "Waiting for tcpdump output file to be ready..."
ping -q "$dummy_addr" >/dev/null 2>&1 &
ctdb_test_exit_hook_add "kill $! >/dev/null 2>&1"
tcpdump_listen_for_dummy ()
{
tcpdump -n -r $tcpdump_filename -c 1 "$dummy" >/dev/null 2>&1
}
wait_until 10 tcpdump_listen_for_dummy
}
# By default, wait for 1 matching packet.
tcpdump_wait ()
{
local count="${1:-1}"
local filter="${2:-${tcpdump_filter}}"
tcpdump_check ()
{
local found=$(tcpdump -n -r $tcpdump_filename "$filter" 2>/dev/null | wc -l)
[ $found -ge $count ]
}
echo "Waiting for tcpdump to capture some packets..."
if ! wait_until 30 tcpdump_check ; then
echo "DEBUG AT $(date '+%F %T'):"
local i
for i in "onnode -q 0 $CTDB status" "netstat -tanp" "tcpdump -n -e -r $tcpdump_filename" ; do
echo "$i"
$i || true
done
return 1
fi
}
tcpdump_show ()
{
local filter="${1:-${tcpdump_filter}}"
tcpdump -n -r $tcpdump_filename "$filter" 2>/dev/null
}
tcptickle_sniff_start ()
{
local src="$1"
local dst="$2"
local in="src host ${dst%:*} and tcp src port ${dst##*:} and dst host ${src%:*} and tcp dst port ${src##*:}"
local out="src host ${src%:*} and tcp src port ${src##*:} and dst host ${dst%:*} and tcp dst port ${dst##*:}"
local tickle_ack="${in} and (tcp[tcpflags] & tcp-ack != 0) and (tcp[14] == 4) and (tcp[15] == 210)" # win == 1234
local ack_ack="${out} and (tcp[tcpflags] & tcp-ack != 0)"
tcptickle_reset="${in} and tcp[tcpflags] & tcp-rst != 0"
local filter="(${tickle_ack}) or (${ack_ack}) or (${tcptickle_reset})"
tcpdump_start "$filter"
}
tcptickle_sniff_wait_show ()
{
tcpdump_wait 1 "$tcptickle_reset"
echo "GOOD: here are some TCP tickle packets:"
tcpdump_show
}
gratarp_sniff_start ()
{
tcpdump_start "arp host ${test_ip}"
}
gratarp_sniff_wait_show ()
{
tcpdump_wait 2
echo "GOOD: this should be the some gratuitous ARPs:"
tcpdump_show
}
ctdb_test_check_real_cluster ()
{
[ -z "$TEST_LOCAL_DAEMONS" ] || \
die "ERROR: This test must be run against a real/virtual cluster, not local daemons."
local h=$(hostname)
local i
for i in $(onnode -q all hostname) ; do
[ "$h" != "$i" ] || \
die "ERROR: This test must not be run from a cluster node."
done
}
ping_wrapper ()
{
case "$*" in
*:*) ping6 "$@" ;;
*) ping "$@" ;;
esac
}
|