Короче говоря, тот ACK был отправлен, когда сокет не принадлежал никому. Вместо того, чтобы позволить пакеты, которые принадлежат сокету, который принадлежит пользователю x
, позвольте пакеты, которые принадлежат соединению, которое инициировалось сокетом от пользователя x
.
Более длинная история.
Для понимания проблемы это помогает понять как wget
и Запросы HTTP работают в целом.
В
wget http://cachefly.cachefly.net/10mb.test
wget
устанавливает соединение TCP к cachefly.cachefly.net
, и когда-то установленный отправляет запрос в протоколе HTTP, в котором говорится: "Отправьте мне содержание /10mb.test
(GET /10mb.test HTTP/1.1
) и между прочим, могли Вы не закрывать соединение после того, как Вы будете сделаны (Connection: Keep-alive
). Причина, которую это делает, который является, потому что в случае, если сервер отвечает с перенаправлением для URL на том же IP-адресе, это может снова использовать соединение.
Теперь сервер может ответить с также, "здесь прибывает данные, которые Вы запросили, остерегайтесь, это 10 МБ шириной (Content-Length: 10485760
), и да хорошо, я уеду, соединение открывают". Or if it does not know the size of the data, "Вот данные, извините я не могу оставить соединение открытым, но я скажу, когда можно будет прекратить загружать данные путем закрытия моего конца соединения".
В URL выше, мы в первом случае.
Так, как только wget
получил заголовки для ответа, он знает, что его задание сделано, после того как он загрузил 10 МБ данных.
В основном, что wget
делает считан данные, пока 10 МБ не были получены и выход. Но в той точке, существует больше, чтобы быть сделанным. Что относительно сервера? Этому сказали оставить соединение открытым.
Перед выходом, wget
завершения (close
системный вызов) дескриптор файла для сокета. На, close
, система заканчивает подтверждать данные, отправленные сервером, и отправляет a FIN
сказать: "Я не буду отправлять больше данные". В той точке close
возвраты и wget
выходы. Нет никакого сокета, связанного с соединением TCP больше (по крайней мере, не один принадлежавший никаким пользователем). Однако это еще не закончено. После получения этого FIN
, сервер HTTP видит конец файла при чтении следующего запроса от клиента. В HTTP, который не означает "больше запроса, я закрою свой конец". Таким образом, это отправляет свой FIN также, для высказывания, "Я ничего не буду отправлять также, то соединение уходит".
После получения, что FIN, клиент отправляет "ACK". Но, в той точке, wget
давно в прошлом, так, чтобы ACK не был ни от какого пользователя. Который является, почему это заблокировано Вашим брандмауэром. Поскольку сервер не получает ACK, он собирается отправить FIN много раз, пока он не сдастся, и Вы будете видеть более отброшенный ACKs. Это также означает путем отбрасывания тех ACKs, бесполезное использование ресурсов сервера (который должен поддержать сокет в состоянии последнего ACK), в течение достаточно долгого времени.
Поведение отличалось бы, если бы клиент не запросил "Активный", или сервер не ответил с "Активным".
Как уже упомянуто, если Вы используете средство отслеживания соединения, что Вы хотите сделать, позволен каждый пакет в УСТАНОВЛЕННЫХ и СВЯЗАННЫХ состояниях через, и только волнуйтесь о NEW
пакеты.
Если Вы позволяете NEW
пакеты от пользователя x
но не пакеты от пользователя y
, затем другие пакеты для установленных соединений пользователем x
пройдет, и потому что не может быть установленных соединений пользователем y
(так как мы блокируемся NEW
пакеты, которые установили бы соединение), не будет никакого пакета для пользователя y
прохождение через соединений.
Разветвление нового процесса сохранит среду.
Если необходимо выполнить процесс с данной средой, все процессы, запущенные этим, будут использовать эту среду, также.
Однако Вы могли сохранить незагрязненную окружающую среду в файл: export >original_env
.
Позже Вы могли очистить загрязненное использование среды env -i
и импортируйте старую среду путем определения источника того файла.
Я не уверен, что это оптимально, но я заставил следующее работать в маленьких тестах:
env -i /bin/bash -cl 'COMMAND'
Очевидно, Вы не можете выполнить csh с - статья, потому что-l не может сосуществовать ни с какими другими аргументами..., но в ударе Вы можете.
ETA:
Я думаю, что это - то, что я собираюсь на самом деле использовать:
#!/bin/csh -f
set evs = ""
if ($1 == '--envVars') then
set envs = "$2"
shift
shift
endif
env -i $envs CMD="$*" /bin/bash -c '$CMD'
Это позволяет мне ввести огибающие переменные из командной строки, если я должен, как $PATH и $PYTHONPATH...
Самым легким путем я могу думать, к нет export
Ваши переменные. В зависимости от Вашего сценария использования это может или не может быть выполнимо. Например:
$ cat a.sh
#!/bin/bash
BAR=foo
export BAZ=foo
bash -c 'echo "bash -c : BAR: $BAR, BAZ: $BAZ"'
echo "normal : BAR: $BAR, BAZ: $BAZ"
$ ./a.sh
bash -c : BAR: , BAZ: foo
normal : BAR: foo, BAZ: foo
Поскольку Вы видите в примере выше, оболочка; aunched bash -c
будет только иметь доступ к экспортируемым переменным.
В зависимости от того, что Вы хотите,
env -i PATH="$(getconf PATH)" HOME="$HOME" USER="$USER" SHELL="$SHELL" "$SHELL" -lc "your command"
попытался бы сбросить стандартную среду для Вашей оболочки. Можно также добавить i
к опциям оболочки так, чтобы это было интерактивным.
Кроме того, можно сделать
env > saved.env
...
env -i `cat saved.env` your command
сохранить и восстановить среду. Но необходимо будет обработать saved.env так, чтобы он был правильно заключен в кавычки (у меня есть некоторый огибающий Вар с пробелами и вкладками в их значении).
Единственный способ, который я нашел, это использовать sudo, если вам разрешено это делать:
sudo -u "$USER" path_to_script
Пример скрипта:
#!/bin/sh
set | grep ARGH
Использование:
$ export ARGH=yes
$ sudo -u "$USER" ./check_env
(empty line, so ARGH is not set)