← Commit list

c8860532dd

Graham Campbell
Graham Campbell
2026-07-24
SUCCESS Duration: 182s

Subject

tests: fix the FTP check for unexpected RST

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

tests/http/test_30_vsftpd.py+2 -2
@@ -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'
tests/http/test_31_vsftpds.py+2 -2
@@ -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'
tests/http/test_32_ftps_vsftpd.py+2 -2
@@ -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'
tests/http/testenv/curl.py+16 -3
@@ -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
tests/http/testenv/vsftpd.py+5 -4
@@ -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))]