On Sat, Feb 25, 2012 at 10:36:49PM +0100, vx8400 wrote: > Собранный из trunk вываливается с той же ошибкой. > Причина в том, что при завершении сессии сервер нештатно разрывает > соединение. > xfreerdp видит, что сокет потерян (Failed to check FreeRDP file descriptor), > но все равно вызывает freerdp_disconnect() -> transport_disconnect() -> > -> tls_disconnect() -> SSL_shutdown(tls->ssl) -> ... > ... -> write(дохлый сокет ...) -> SIGPIPE > > Eсли не вызывать SSL_shutdown() при отвалившемся соединении, то > xfreerdp завершается нормально. Патч для проверки в прицепе. Кстати, при пробросе порта 3389 через ssh эта ошибка у меня не воспроизводится (с сервером 2008 R2, где TLS, похоже, по умолчанию всегда используется и выдаёт хотя бы самоподписанный сертификат). > Ошибка в remmina с разрывом соединения, возможно, не связана: Да, там дело явно не в TLS (кстати, в опциях соединения там тоже можно отключить TLS) - remmina валится даже в том случае, если поддержка TLS на серверной стороне отключена. > --- a/libfreerdp-core/tls.c 2012-02-10 03:01:42.000000000 +0100 > +++ b/libfreerdp-core/tls.c 2012-02-25 21:32:00.381001657 +0100 > @@ -22,6 +22,9 @@ > > #include "tls.h" > > +#include > +#include > + > boolean tls_connect(rdpTls* tls) > { > int connection_status; > @@ -120,9 +123,18 @@ > return true; > } > > +char _buf_[8]; > + > boolean tls_disconnect(rdpTls* tls) > { > - SSL_shutdown(tls->ssl); > + int n = read(tls->ssl->wbio->num,_buf_,0); > + if (errno) { Вообще вызов read() нулевой длины не обязан проверять что-либо на ошибки, а имеет право просто возвращать 0, ничего больше не проверяя. Ещё нужна проверка (n == -1), поскольку в errno может лежать код ошибки от предыдущих операций (либо перед вызовом read() нужно самостоятельно сделать errno = 0). Хотя в любом случае всё это не поможет, поскольку закрытие соединения со стороны сервера может произойти после проверки, но перед вызовом SSL_shutdown(). Единственный надёжный способ борьбы с проблемой - игнорировать сигнал SIGPIPE и обрабатывать ошибку EPIPE от write(); странно, почему xfreerdp этого не делает.