char: don't skip client cleanup if 'connected' flag is unset
PATCH 1/1 char: don't skip client cleanup if 'connected' flag is unset
The tcp_chr_free_connection & tcp_chr_disconnect methods both skip all of their cleanup work unless the 's->connected' flag is set. This flag is set when the incoming client connection is ready to use. Crucially this is *after* the TLS handshake has been completed. So if the TLS handshake fails and we try to cleanup the failed client, all the cleanup is skipped as 's->connected' is still false.
The only important thing that should be skipped in this case is sending of the CHR_EVENT_CLOSED, because we never got as far as sending the corresponding CHR_EVENT_OPENED. Every other bit of cleanup can be robust against being called even when s->connected is false.
--- chardev/char-socket.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
chardev/char-socket.c +17 -14
@@ -332,10 +332,6 @@ static void tcp_chr_free_connection(Chardev *chr)SocketChardev *s =SOCKET_CHARDEV (chr);int i; -if (!s->connected) { -return ; - } -if (s->read_msgfds_num) {for (i =0 ; i < s->read_msgfds_num; i++) {close (s->read_msgfds[i]);
@@ -347,10 +343,14 @@ static void tcp_chr_free_connection(Chardev *chr)tcp_set_msgfds (chr,NULL ,0 );remove_fd_in_watch (chr); -object_unref (OBJECT (s->sioc)); - s->sioc =NULL ; -object_unref (OBJECT (s->ioc)); - s->ioc =NULL ; +if (s->sioc) { +object_unref (OBJECT (s->sioc)); + s->sioc =NULL ; + } +if (s->ioc) { +object_unref (OBJECT (s->ioc)); + s->ioc =NULL ; + }g_free (chr->filename); chr->filename =NULL ; s->connected =0 ;
@@ -394,22 +394,25 @@ static void update_disconnected_filename(SocketChardev *s) s->is_listen, s->is_telnet); } +/* NB may be called even if tcp_chr_connect has not been +* reached, due to TLS or telnet initialization failure, +* so can *not* assume s->connected == true +*/ static void tcp_chr_disconnect (Chardev *chr) {SocketChardev *s =SOCKET_CHARDEV (chr); - -if (!s->connected) { -return ; - } +bool emitClose = s->connected;tcp_chr_free_connection (chr); -if (s->listen_ioc) { +if (s->listen_ioc && s->listen_tag ==0 ) { s->listen_tag =qio_channel_add_watch (QIO_CHANNEL (s->listen_ioc),G_IO_IN , tcp_chr_accept, chr,NULL ); }update_disconnected_filename (s); -qemu_chr_be_event (chr,CHR_EVENT_CLOSED ); +if (emitClose) { +qemu_chr_be_event (chr,CHR_EVENT_CLOSED ); + }if (s->reconnect_time) {qemu_chr_socket_restart_timer (chr); }
Signature · 1 line
2.13.5
Quoted 14 lines · Daniel P. Berrange
The
tcp_chr_free_connection&tcp_chr_disconnectmethods both skip all of their cleanup work unless the 's->connected' flag is set. This flag is set when the incoming client connection is ready to use. Crucially this is *after* the TLS handshake has been completed. So if the TLS handshake fails and we try to cleanup the failed client, all the cleanup is skipped as 's->connected' is still false.The only important thing that should be skipped in this case is sending of the
CHR_EVENT_CLOSED, because we never got as far as sending the correspondingCHR_EVENT_OPENED. Every other bit of cleanup can be robust against being called even whens->connectedis false.
Quoted 5 lines
Signed-off-by Daniel P. Berrange <[email protected]>--- chardev/char-socket.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
Signature · 3 lines
Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Hi
Quoted 40 lines · Daniel P. Berrange
The
tcp_chr_free_connection&tcp_chr_disconnectmethods both skip all of their cleanup work unless the 's->connected' flag is set. This flag is set when the incoming client connection is ready to use. Crucially this is *after* the TLS handshake has been completed. So if the TLS handshake fails and we try to cleanup the failed client, all the cleanup is skipped as 's->connected' is still false.The only important thing that should be skipped in this case is sending of the
CHR_EVENT_CLOSED, because we never got as far as sending the correspondingCHR_EVENT_OPENED. Every other bit of cleanup can be robust against being called even whens->connectedis false.Signed-off-by Daniel P. Berrange <[email protected]>--- chardev/char-socket.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)chardev/char-socket.c +0
-6@@ -332,10 +332,6 @@ static void tcp_chr_free_connection(Chardev *chr)SocketChardev *s =SOCKET_CHARDEV (chr);int i; -if (!s->connected) { -return ; - } -if (s->read_msgfds_num) {for (i =0 ; i < s->read_msgfds_num; i++) {close (s->read_msgfds[i]);@@ -347,10 +343,14 @@ static void tcp_chr_free_connection(Chardev *chr)tcp_set_msgfds (chr,NULL ,0 );remove_fd_in_watch (chr); -object_unref (OBJECT (s->sioc)); - s->sioc =NULL ;
chardev/char-socket.c static void tcp_chr_free_connection(Chardev *chr) · line 353
Quoted 10 lines
chardev/char-socket.c +8
-2-object_unref (OBJECT (s->ioc)); - s->ioc =NULL ; +if (s->sioc) { +object_unref (OBJECT (s->sioc)); + s->sioc =NULL ; + } +if (s->ioc) { +object_unref (OBJECT (s->ioc)); + s->ioc =NULL ; + }
object_unref() and OBJECT() are null-safe.
Quoted 9 lines
chardev/char-socket.c +2
-0g_free (chr->filename); chr->filename =NULL ; s->connected =0 ;@@ -394,22 +394,25 @@ static void update_disconnected_filename(SocketChardev *s) s->is_listen, s->is_telnet); } +/* NB may be called even if tcp_chr_connect has not been +* reached, due to TLS or telnet initialization failure,
chardev/char-socket.c static void update_disconnected_filename(SocketChardev *s) · line 404
Quoted 10 lines
chardev/char-socket.c +3
-4+* so can *not* assume s->connected == true +*/ static void tcp_chr_disconnect (Chardev *chr) {SocketChardev *s =SOCKET_CHARDEV (chr); - -if (!s->connected) { -return ; - } +bool emitClose = s->connected;
ewh, which code style do you pick today? :)
Quoted 17 lines
chardev/char-socket.c +4
-3tcp_chr_free_connection (chr); -if (s->listen_ioc) { +if (s->listen_ioc && s->listen_tag ==0 ) { s->listen_tag =qio_channel_add_watch (QIO_CHANNEL (s->listen_ioc),G_IO_IN , tcp_chr_accept, chr,NULL ); }update_disconnected_filename (s); -qemu_chr_be_event (chr,CHR_EVENT_CLOSED ); +if (emitClose) { +qemu_chr_be_event (chr,CHR_EVENT_CLOSED ); + }if (s->reconnect_time) {qemu_chr_socket_restart_timer (chr); } --
Quoted 3 lines
2.13.5
other than that, looks good to me
Signature · 1 line
Marc-André Lureau
Quoted 63 lines · Marc-André Lureau
Hi
Quoted 40 lines · Daniel P. Berrange
The
tcp_chr_free_connection&tcp_chr_disconnectmethods both skip all of their cleanup work unless the 's->connected' flag is set. This flag is set when the incoming client connection is ready to use. Crucially this is *after* the TLS handshake has been completed. So if the TLS handshake fails and we try to cleanup the failed client, all the cleanup is skipped as 's->connected' is still false.The only important thing that should be skipped in this case is sending of the
CHR_EVENT_CLOSED, because we never got as far as sending the correspondingCHR_EVENT_OPENED. Every other bit of cleanup can be robust against being called even whens->connectedis false.Signed-off-by Daniel P. Berrange <[email protected]>--- chardev/char-socket.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)chardev/char-socket.c +0
-6@@ -332,10 +332,6 @@ static void tcp_chr_free_connection(Chardev *chr)SocketChardev *s =SOCKET_CHARDEV (chr);int i; -if (!s->connected) { -return ; - } -if (s->read_msgfds_num) {for (i =0 ; i < s->read_msgfds_num; i++) {close (s->read_msgfds[i]);@@ -347,10 +343,14 @@ static void tcp_chr_free_connection(Chardev *chr)tcp_set_msgfds (chr,NULL ,0 );remove_fd_in_watch (chr); -object_unref (OBJECT (s->sioc)); - s->sioc =NULL ;chardev/char-socket.c static void tcp_chr_free_connection(Chardev *chr) · line 353
Quoted 10 lines
chardev/char-socket.c +8
-2-object_unref (OBJECT (s->ioc)); - s->ioc =NULL ; +if (s->sioc) { +object_unref (OBJECT (s->sioc)); + s->sioc =NULL ; + } +if (s->ioc) { +object_unref (OBJECT (s->ioc)); + s->ioc =NULL ; + }
object_unref()andOBJECT()are null-safe.Quoted 7 lines
chardev/char-socket.c +0
-0g_free (chr->filename); chr->filename =NULL ; s->connected =0 ;@@ -394,22 +394,25 @@ static void update_disconnected_filename(SocketChardev *s) s->is_listen, s->is_telnet); }
Quoted 14 lines
chardev/char-socket.c static void update_disconnected_filename(SocketChardev *s) · line 404
Quoted 12 lines
chardev/char-socket.c +5
-4+/* NB may be called even if tcp_chr_connect has not been +* reached, due to TLS or telnet initialization failure, +* so can *not* assume s->connected == true +*/ static void tcp_chr_disconnect (Chardev *chr) {SocketChardev *s =SOCKET_CHARDEV (chr); - -if (!s->connected) { -return ; - } +bool emitClose = s->connected;ewh, which code style do you pick today? :)
Which bit don't you like ? The 'bool' or the camelCase, or both ?
Regards,
Daniel
Signature · 3 lines
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
Hi
Quoted 79 lines · Daniel P. Berrange
Quoted 63 lines · Marc-André Lureau
Hi
Quoted 40 lines · Daniel P. Berrange
The
tcp_chr_free_connection&tcp_chr_disconnectmethods both skip all of their cleanup work unless the 's->connected' flag is set. This flag is set when the incoming client connection is ready to use. Crucially this is *after* the TLS handshake has been completed. So if the TLS handshake fails and we try to cleanup the failed client, all the cleanup is skipped as 's->connected' is still false.The only important thing that should be skipped in this case is sending of the
CHR_EVENT_CLOSED, because we never got as far as sending the correspondingCHR_EVENT_OPENED. Every other bit of cleanup can be robust against being called even whens->connectedis false.Signed-off-by Daniel P. Berrange <[email protected]>--- chardev/char-socket.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)chardev/char-socket.c +0
-6@@ -332,10 +332,6 @@ static void tcp_chr_free_connection(Chardev *chr)SocketChardev *s =SOCKET_CHARDEV (chr);int i; -if (!s->connected) { -return ; - } -if (s->read_msgfds_num) {for (i =0 ; i < s->read_msgfds_num; i++) {close (s->read_msgfds[i]);@@ -347,10 +343,14 @@ static void tcp_chr_free_connection(Chardev *chr)tcp_set_msgfds (chr,NULL ,0 );remove_fd_in_watch (chr); -object_unref (OBJECT (s->sioc)); - s->sioc =NULL ;chardev/char-socket.c static void tcp_chr_free_connection(Chardev *chr) · line 353
Quoted 10 lines
chardev/char-socket.c +8
-2-object_unref (OBJECT (s->ioc)); - s->ioc =NULL ; +if (s->sioc) { +object_unref (OBJECT (s->sioc)); + s->sioc =NULL ; + } +if (s->ioc) { +object_unref (OBJECT (s->ioc)); + s->ioc =NULL ; + }
object_unref()andOBJECT()are null-safe.Quoted 7 lines
chardev/char-socket.c +0
-0g_free (chr->filename); chr->filename =NULL ; s->connected =0 ;@@ -394,22 +394,25 @@ static void update_disconnected_filename(SocketChardev *s) s->is_listen, s->is_telnet); }Quoted 14 lines
chardev/char-socket.c static void update_disconnected_filename(SocketChardev *s) · line 404
Quoted 12 lines
chardev/char-socket.c +5
-4+/* NB may be called even if tcp_chr_connect has not been +* reached, due to TLS or telnet initialization failure, +* so can *not* assume s->connected == true +*/ static void tcp_chr_disconnect (Chardev *chr) {SocketChardev *s =SOCKET_CHARDEV (chr); - -if (!s->connected) { -return ; - } +bool emitClose = s->connected;ewh, which code style do you pick today? :)
Quoted 1 line
Which bit don't you like ? The 'bool' or the camelCase, or both ?
the mixedCase, let's stick to lower_case for variables.
Quoted 8 lines
Regards,
Daniel
--|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
Signature · 1 line
Marc-André Lureau