tests: fix the FTP check for unexpected RST
No binary (build failed)
—
(log yok)
| @@ -161,7 +161,7 @@ class TestVsFTPD: | |
| # look only at ports from DATA connection. | |
| data_ports = vsftpd.get_data_ports(r) | |
| assert len(data_ports), f'unable to find FTP data port connected to\n{r.dump_logs()}' | |
| - | assert len(r.tcpdump.get_rsts(ports=data_ports)) == 0, 'Unexpected TCP RST packets' |
| + | assert len(r.tcpdump.get_rsts(port_pairs=data_ports)) == 0, 'Unexpected TCP RST packets' |
| # check with `tcpdump` if curl causes any TCP RST packets | |
| @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") | |
| @@ -182,7 +182,7 @@ class TestVsFTPD: | |
| # look only at ports from DATA connection. | |
| data_ports = vsftpd.get_data_ports(r) | |
| assert len(data_ports), f'unable to find FTP data port connected to\n{r.dump_logs()}' | |
| - | assert len(r.tcpdump.get_rsts(ports=data_ports)) == 0, 'Unexpected TCP RST packets' |
| + | assert len(r.tcpdump.get_rsts(port_pairs=data_ports)) == 0, 'Unexpected TCP RST packets' |
| def test_30_08_active_download(self, env: Env, vsftpd: VsFTPD): | |
| docname = 'data-10k' | |
| @@ -177,7 +177,7 @@ class TestVsFTPD: | |
| # look only at ports from DATA connection. | |
| data_ports = vsftpds.get_data_ports(r) | |
| assert len(data_ports), f'unable to find FTP data port connected to\n{r.dump_logs()}' | |
| - | assert len(r.tcpdump.get_rsts(ports=data_ports)) == 0, 'Unexpected TCP RST packets' |
| + | assert len(r.tcpdump.get_rsts(port_pairs=data_ports)) == 0, 'Unexpected TCP RST packets' |
| # check with `tcpdump` if curl causes any TCP RST packets | |
| @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") | |
| @@ -197,7 +197,7 @@ class TestVsFTPD: | |
| # look only at ports from DATA connection. | |
| data_ports = vsftpds.get_data_ports(r) | |
| assert len(data_ports), f'unable to find FTP data port connected to\n{r.dump_logs()}' | |
| - | assert len(r.tcpdump.get_rsts(ports=data_ports)) == 0, 'Unexpected TCP RST packets' |
| + | assert len(r.tcpdump.get_rsts(port_pairs=data_ports)) == 0, 'Unexpected TCP RST packets' |
| def test_31_08_upload_ascii(self, env: Env, vsftpds: VsFTPD): | |
| docname = 'upload-ascii' | |
| @@ -187,7 +187,7 @@ class TestFtpsVsFTPD: | |
| # look only at ports from DATA connection. | |
| data_ports = vsftpds.get_data_ports(r) | |
| assert len(data_ports), f'unable to find FTP data port connected to\n{r.dump_logs()}' | |
| - | assert len(r.tcpdump.get_rsts(ports=data_ports)) == 0, 'Unexpected TCP RST packets' |
| + | assert len(r.tcpdump.get_rsts(port_pairs=data_ports)) == 0, 'Unexpected TCP RST packets' |
| # check with `tcpdump` if curl causes any TCP RST packets | |
| @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") | |
| @@ -207,7 +207,7 @@ class TestFtpsVsFTPD: | |
| # look only at ports from DATA connection. | |
| data_ports = vsftpds.get_data_ports(r) | |
| assert len(data_ports), f'unable to find FTP data port connected to\n{r.dump_logs()}' | |
| - | assert len(r.tcpdump.get_rsts(ports=data_ports)) == 0, 'Unexpected TCP RST packets' |
| + | assert len(r.tcpdump.get_rsts(port_pairs=data_ports)) == 0, 'Unexpected TCP RST packets' |
| def test_32_08_upload_ascii(self, env: Env, vsftpds: VsFTPD): | |
| docname = 'upload-ascii' | |
| @@ -36,7 +36,7 @@ from datetime import datetime, timedelta, timezone | |
| from functools import cmp_to_key | |
| from statistics import fmean, mean | |
| from threading import Thread | |
| - | from typing import Any, Dict, List, Optional, Union |
| + | from typing import Any, Dict, List, Optional, Tuple, Union |
| from urllib.parse import urlparse | |
| import psutil | |
| @@ -188,9 +188,19 @@ class RunTcpDump: | |
| self._stdoutfile = os.path.join(self._run_dir, 'tcpdump.out') | |
| self._stderrfile = os.path.join(self._run_dir, 'tcpdump.err') | |
| - | def get_rsts(self, ports: Optional[List[int]] = None) -> Optional[List[str]]: |
| + | def get_rsts(self, ports: Optional[List[int]] = None, |
| + | port_pairs: Optional[List[Tuple[int, int]]] = None |
| + | ) -> Optional[List[str]]: |
| if self._proc: | |
| raise Exception('tcpdump still running') | |
| + | # a pair matches only a RST between exactly these two ports, while |
| + | # a port in `ports` matches any RST it is involved in |
| + | pairs = None |
| + | if port_pairs is not None: |
| + | pairs = set() |
| + | for p1, p2 in port_pairs: |
| + | pairs.add((p1, p2)) |
| + | pairs.add((p2, p1)) |
| lines = [] | |
| with open(self._stdoutfile) as fd: | |
| for line in fd: | |
| @@ -198,7 +208,10 @@ class RunTcpDump: | |
| if m: | |
| sport = int(m.group(1)) | |
| dport = int(m.group(2)) | |
| - | if ports is None or sport in ports or dport in ports: |
| + | if pairs is not None: |
| + | if (sport, dport) in pairs: |
| + | lines.append(line) |
| + | elif ports is None or sport in ports or dport in ports: |
| lines.append(line) | |
| return lines | |
| @@ -31,7 +31,7 @@ import socket | |
| import subprocess | |
| import time | |
| from datetime import datetime, timedelta | |
| - | from typing import Dict, List |
| + | from typing import Dict, List, Tuple |
| from .curl import CurlClient, ExecResult | |
| from .env import Env | |
| @@ -226,6 +226,7 @@ class VsFTPD: | |
| with open(self._conf_file, 'w') as fd: | |
| fd.write("\n".join(conf)) | |
| - | def get_data_ports(self, r: ExecResult) -> List[int]: |
| - | return [int(m.group(1)) for line in r.trace_lines if |
| - | (m := re.match(r'.*Established 2nd connection to .* \(\S+ port (\d+)\)', line))] |
| + | def get_data_ports(self, r: ExecResult) -> List[Tuple[int, int]]: |
| + | return [(int(m.group(1)), int(m.group(2))) for line in r.trace_lines if |
| + | (m := re.match(r'.*Established 2nd connection to .* ' |
| + | r'\(\S+ port (\d+)\) from \S+ port (\d+)', line))] |