Имитация TCP Tarpit - PullRequest
       20

Имитация TCP Tarpit

0 голосов
/ 29 мая 2019

Я хочу смоделировать тестовые сбои / тайм-ауты кроссплатформенного соединения, начиная с блокировки connect() s:

#!/usr/bin/python3

import socket

s = socket.socket()
endpoint = ('localhost', 28813)
s.bind((endpoint))
# listen for connections, accept 0 connections kept waiting (backlog)
# all other connect()s should block indefinitely
s.listen(0)

for i in range(1,1000):
    c = socket.socket()
    c.connect(endpoint)
    # print number of successfully connected sockets
    print(i)

В Linux он печатает «1» и зависает бесконечно (то есть, поведение, которое я хочу).
В Windows (Server 2012) он печатает «1» и прерывает работу с ConnectionRefusedError.
В macOS он печатает все числа от 1 до 128, а затем зависает на неопределенное время.

Таким образом, я мог бы согласиться с тем, что macOS игнорирует параметр backlog и просто подключить достаточно сокетов, чтобы клиенты могли блокировать новые подключения.

Как заставить Windows также блокировать connect() попытки?

1 Ответ

0 голосов
/ 31 мая 2019

В Windows опция сокета SO_CONDITIONAL_ACCEPT позволяет приложению ожидать входящих подключений до тех пор, пока оно не станет accept() ed. Константа (SO_CONDITIONAL_ACCEPT=0x3002) не выставляется в модуле Python, но может быть предоставлена ​​вручную:

s.bind(endpoint)
s.setsockopt(socket.SOL_SOCKET, 0x3002, 1)
s.listen(0)

Это настолько эффективно, что даже первое соединение остается в ожидании.

В macOS backlog=0 сбрасывается на backlog=SOMAXCONN, backlog=1 сохраняет все соединения, кроме первого ожидания.

...