diff --git a/scapy/automaton.py b/scapy/automaton.py index 303db73a38d..35a10e30a23 100644 --- a/scapy/automaton.py +++ b/scapy/automaton.py @@ -92,9 +92,19 @@ def select_objects(inputs, remain): return select.select(inputs, [], [], remain)[0] inputs = list(inputs) events = [] + events_to_inputs = [] created = [] results = set() for i in inputs: + if i.fileno() < 0: + # Special case: On Windows, we consider that an object that returns + # a negative fileno (impossible), is always readable. This is used + # in very few places but important (e.g. PcapReader), where we have + # no valid fileno (and will stop on EOFError). + results.add(i) + remain = 0 + continue + events_to_inputs.append(i) if getattr(i, "__selectable_force_select__", False): # Native socket.socket object. We would normally use select.select. evt = ctypes.windll.ws2_32.WSACreateEvent() @@ -110,13 +120,6 @@ def select_objects(inputs, remain): else: # Fallback to normal event events.append(i.fileno()) - elif i.fileno() < 0: - # Special case: On Windows, we consider that an object that returns - # a negative fileno (impossible), is always readable. This is used - # in very few places but important (e.g. PcapReader), where we have - # no valid fileno (and will stop on EOFError). - results.add(i) - remain = 0 else: events.append(i.fileno()) if events: @@ -140,7 +143,7 @@ def select_objects(inputs, remain): remainms ) if res != 0xFFFFFFFF and res != 0x00000102: # Failed or Timeout - results.add(inputs[res]) + results.add(events_to_inputs[res]) if len(events) > 1: # Now poll the others, if any for i, evt in enumerate(events): @@ -149,7 +152,7 @@ def select_objects(inputs, remain): 0 # poll: don't wait ) if res == 0: - results.add(inputs[i]) + results.add(events_to_inputs[i]) # Cleanup created events, if any for evt in created: ctypes.windll.ws2_32.WSACloseEvent(evt) diff --git a/test/scapy/layers/tls/tlsclientserver.uts b/test/scapy/layers/tls/tlsclientserver.uts index 0ec3fa70bf5..78942bb1620 100644 --- a/test/scapy/layers/tls/tlsclientserver.uts +++ b/test/scapy/layers/tls/tlsclientserver.uts @@ -510,7 +510,7 @@ def run_tls_native_test_server(post_handshake_auth=False, def ssl_server(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server.settimeout(1) + server.settimeout(5) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(("0.0.0.0", 0)) server.listen(5) @@ -566,11 +566,11 @@ def test_tls_client_native(post_handshake_auth=False, # debug=4, ) # First request - pkt = a.sr1(REQS[0], timeout=1, verbose=0) - assert pkt.load == b"Please login" + pkt = a.sr1(REQS[0], timeout=5, verbose=0) + assert pkt is not None and pkt.load == b"Please login" # Second request - pkt = a.sr1(REQS[1], timeout=1, verbose=0) - assert pkt.load == b"Welcome" + pkt = a.sr1(REQS[1], timeout=5, verbose=0) + assert pkt is not None and pkt.load == b"Welcome" # Close a.close() # Wait for server to close diff --git a/test/windows.uts b/test/windows.uts index 394376be0c2..5f060793fab 100644 --- a/test/windows.uts +++ b/test/windows.uts @@ -21,6 +21,17 @@ a = ObjectPipe() a.send("test") assert select_objects([a], 0) == [a] +if WINDOWS: + class _NegFileno(object): + def fileno(self): + return -1 + neg = _NegFileno() + assert select_objects([neg], 0) == [neg] + assert set(select_objects([a, neg], 0)) == {neg, a} + b = ObjectPipe() + b.send("test2") + assert set(select_objects([neg, a, b], 0)) == {neg, a, b} + ############ ############ + Windows arch unit tests