Линк был в самом первом посте. RFC тут никаким боком, это системный API. К сожалению, какой-либо более «официальной» документации по Linux для случая l_linger=0 я не знаю, но в микрософтовской документации четко сказано, что удаленный конец при таком закрытии (abortive close) получает именно reset.
При нулевом лингере удаленному концу принудительно шлется RST и соединение закрывается, на все последующие пакеты приходят RST. При ненулевом лингере на пакеты, которые пришли в рамках соединения, даже если это ретрансмиты после FIN, RST не шлется.
по strace'у что-то немного странное. Обычно в nfds пишется sock+1, если sock — максимальный сокет в FD_SET, почему там 16, если 15й сокет не в списке — какой-то подвох. Если б меня сильно интересовал вопрос — таки я бы заглянул в сорсы и посмотрел что там за select и что происходит по Ctrl+C.
Еще можно проверить nmap'ом — если на попытку ACK-скана на недавно закрытый порт RST возвращается, значит причину точно следует искать в лингерах.
When enabled, a close(2) or shutdown(2) will not return until all queued messages for the socket have been successfully sent or the linger timeout has been reached. Otherwise, the call returns immediately and the closing is done in the background. When the socket is closed as part of exit(2), it always lingers in the background.
Это классический пример, когда assert(), традиционно используемый для перестраховки, реально сработал. Довольно долго было принято считать что seteuid(getuid( )) работает всегда, а потому ситуацию обычно не обрабатывали никак. Но таки «перестраховщики» вставляли под это дело assert() и в учебниках обычно рекомендовали. В результате, когда вылезла вполне практичная атака, при которой исчерпавались ulimit'ы юзера, а потом вызывалось suid-приложение, в результате seteuid не срабатывал из-за превышения ulimit'ов — перестраховщики оказались в плюсе. А сейчас уже — да, ситуацию принято отдельно обрабатывать, т.к. она документирована и использование в ней assert() это уже дурной тон.
Т.е. на практике, если речь идет не об отладке, assert() реально используется для подстраховки, когда есть минимальные сомнения в результате а ответственность высокая. А вот проверять им результат возведения в квадрат в не-отладочной версии программы таки немного странно.
Автоматически — может и не распознает. Но если ссылка есть, то во-первых пользователь нажмет не «это спам», а щелкнет по линку, во-вторых, даже если он нажмет «это спам», то спам-аналитик увидит, что рассылка легальна. По тем же причинам, настоятельно рекомендуется генерировать все заголовки письма в полном соответствии со стандартами, в частности From: не должен вводить в заблуждение и должен идентифицировать ресурс, Message-ID должен быть уникальным. Preceedence: должен быть bulk. IP должен иметь внятную PTR-запись. Очень желательно создать SPF-запись для домена и не плохо бы подписывать исходящие письма DKIM. Т.е. если письма рассылаются массово, то необходимо как можно больше информации, подтверждающей их легитимность, иначе она будет определяться только на основании жалоб пользователей, т.к. другой информации нет.