Skip Menu |

This queue is for tickets about the IO-Multiplex CPAN distribution.

Report information
The Basics
Id: 77513
Status: open
Priority: 0/
Queue: IO-Multiplex

People
Owner: Nobody in particular
Requestors: tomas.zerolo [...] axelspringer.de
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



CC: <tomas [...] tuxteam.de>
Subject: [PATCH] IO::Multiplex and IO::Socket::SSL
Date: Tue, 29 May 2012 10:37:37 +0200
To: <bug-IO-Multiplex [...] rt.cpan.org>
From: Tomas Zerolo <tomas.zerolo [...] axelspringer.de>
Hi, I'm trying to build an asynchronous SSL client around IO::Multiplex. I refer to the version 1.13 of IO::Multiplex as distributed by Debian Wheezy (libio-multiplex-perl 1.13-1). I managed to get at a point where I "see" a garbage answer from the server (which might be encripted stuff. Looking into IO::Multiplex's source, I see that it POSIX::read()s from and POSIX::write()s to the underlying file descriptor, thus bypassing the SSL layer bound onto it by IO::Socket::SSL. My attempt to solve it is by trying to delegate to the READ and WRITE methods of the bound object (and to fall back to POSIX::read and POSIX::write if the socket wasn't bound). See <http://www.perlmonks.org/?node_id=972687> for a more detailed write-up. Here's a tentative patch which "has been seen to work once": --- original/perl5/IO/Multiplex.pm 2011-04-15 08:40:23.000000000 +0200 +++ modified/perl5/IO/Multiplex.pm 2012-05-29 09:47:51.821377686 +0200 @@ -362,6 +362,7 @@ $self->{_fhs}{"$fh"}{inbuffer} = ''; $self->{_fhs}{"$fh"}{outbuffer} = ''; $self->{_fhs}{"$fh"}{fileno} = fileno($fh); + $self->{_fhs}{"$fh"}{oldtie} = tied(*$fh) if defined(tied(*$fh)); $self->{_handles}{"$fh"} = $fh; tie *$fh, "IO::Multiplex::Handle", $self, $fh; return $fh; @@ -645,7 +646,9 @@ $self->{_fhs}{"$fh"}{udp_peer} = $rv; } } else { - $rv = &POSIX::read(fileno($fh), $data, BUFSIZ); + $rv = ($self->{_fhs}{"$fh"}{oldtie}) + ? $self->{_fhs}{"$fh"}{oldtie}->READ($data, BUFSIZ) + : &POSIX::read(fileno($fh), $data, BUFSIZ); } if (defined($rv) && length($data)) { @@ -699,8 +702,12 @@ if ($obj && $obj->can("mux_outbuffer_empty")); next; } - $rv = &POSIX::write(fileno($fh), - $self->{_fhs}{"$fh"}{outbuffer}, + $rv = ($self->{_fhs}{"$fh"}{oldtie}) + ? $self->{_fhs}{"$fh"}{oldtie}->WRITE( + $self->{_fhs}{"$fh"}{outbuffer}, + length($self->{_fhs}{"$fh"}{outbuffer})) + : &POSIX::write(fileno($fh), + $self->{_fhs}{"$fh"}{outbuffer}, length($self->{_fhs}{"$fh"}{outbuffer})); unless (defined($rv)) { # We got an error writing to it. If it's BTW: thanks for IO::Multiplex! -- Tomás Zerolo Axel Springer AG Axel Springer media Systems BILD Produktionssysteme Axel-Springer-Straße 65 10888 Berlin Tel.: +49 (30) 2591-72875 tomas.zerolo@axelspringer.de www.axelspringer.de Axel Springer AG, Sitz Berlin, Amtsgericht Charlottenburg, HRB 4998 Vorsitzender des Aufsichtsrats: Dr. Giuseppe Vita Vorstand: Dr. Mathias Döpfner (Vorsitzender) Jan Bayer, Ralph Büchi, Lothar Lanz, Dr. Andreas Wiele
Subject: Re: [rt.cpan.org #77513] [PATCH] IO::Multiplex and IO::Socket::SSL
Date: Tue, 29 May 2012 09:03:35 -0600
To: bug-IO-Multiplex [...] rt.cpan.org
From: Rob Brown <bbb [...] cpan.org>
Close. But I don't think this considers the case where an IO::Socket::SSL object will not appear to be readable according to select() but in real life it would not block if you actually tried to read from it due to the fact that there is still something in the ->pending buffer. Maybe we can add a special hard coded case just for IO::Socket::SSL objects, but I'm not sure what the best way to handle this is. -- Rob On Tue, May 29, 2012 at 2:37 AM, Tomas Zerolo via RT <bug-IO-Multiplex@rt.cpan.org> wrote: Show quoted text
> Tue May 29 04:37:07 2012: Request 77513 was acted upon. > Transaction: Ticket created by tomas.zerolo@axelspringer.de >       Queue: IO-Multiplex >     Subject: [PATCH] IO::Multiplex and IO::Socket::SSL >   Broken in: (no value) >    Severity: (no value) >       Owner: Nobody >  Requestors: tomas.zerolo@axelspringer.de >      Status: new >  Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=77513 > > > > Hi, > > I'm trying to build an asynchronous SSL client around IO::Multiplex. > > I refer to the version 1.13 of IO::Multiplex as distributed by > Debian Wheezy (libio-multiplex-perl 1.13-1). > > I managed to get at a point where I "see" a garbage answer from the > server (which might be encripted stuff.
CC: <tomas [...] tuxteam.de>
Subject: Re: [rt.cpan.org #77513] [PATCH] IO::Multiplex and IO::Socket::SSL
Date: Wed, 30 May 2012 10:01:07 +0200
To: Rob Brown via RT <bug-IO-Multiplex [...] rt.cpan.org>
From: Tomas Zerolo <tomas.zerolo [...] axelspringer.de>
On Tue, May 29, 2012 at 11:03:49AM -0400, Rob Brown via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=77513 > > > Close. But I don't think this considers the case where an > IO::Socket::SSL object will not appear to be readable according to > select() but in real life it would not block if you actually tried to > read from it due to the fact that there is still something in the > ->pending buffer. Maybe we can add a special hard coded case just for > IO::Socket::SSL objects, but I'm not sure what the best way to handle > this is.
There is some special-casing for SSL already there, which seems to try to cope with that. My fu isn't strong enough to "see" whether this works without resorting to experiments (and experiments I'm doing at the moment, mind you ;-) At the beginning of methoe IO::Multiplex::loop, around line 586: foreach my $fh (values %{$self->{_handles}}) { fd_set($rdready, $fh, 1) if ref($fh) =~ /SSL/ && $fh->can("pending") && $fh->pending; } it resorts to querying the socket's "pending" method whenever it smells like SSL. On a personal note, I'd tend to just query the "pending" method and try to establish a convention that those filtering sockets à la SSL all implement a similar method: that would make things more general. But back to it: it seems IO::Multiplex already tries. There seems to be some lack of symmetry -- maybe IO::Socket::SSL also want to *write* behind our backs (and I don't see this case here). But I don't know for sure -- yet. Thanks, Regards -- tomás