As for your update, I think the problem is caused by the following snippet in IO::Socket::INET (line 232):
if ($sock->connect(pack_sockaddr_in($rport, $raddr))) {
# ${*$sock}{'io_socket_timeout'} = $timeout;
return $sock;
}
Here, the return value of $sock->connect(...) is your overridden glob/socket (which is correctly connected), but IO::Socket::INET is returning the original glob, which never has been connected (due to your overriding mechanism). This $sock is then propagated back as the return value of ->new(), so that you're calling ->syswrite on an unconnected socket.
Here's a short demo, replacing IO::Socket::Socks with a dummy module "IO::Socket::Foo" (which mimicks IO::Socket::Socks in that it also subclasses IO::Socket::INET), so it can be run standalone without a socks5 server:
BEGIN {
*CORE::GLOBAL::connect = sub(*$) {
my ($socket, $name) = @_;
return CORE::connect($socket, $name) if ref($socket) eq 'IO::S
+ocket::Foo';
$_[0] = IO::Socket::Foo->new('perlmonks.org:80') or return und
+ef;
return 1;
}
}
package IO::Socket::Foo;
use IO::Socket::INET;
use base "IO::Socket::INET";
package main;
$SIG{PIPE} = sub { die "Broken pipe!\n" };
my $sock = IO::Socket::INET->new('perlmonks.org:80')
or die $@;
print "\$sock is: $sock\n";
$sock->syswrite("GET / HTTP/1.0\r\n");
$sock->close();
When you replace the above mentioned snippet in IO::Socket::INET with
if (my $mysock = $sock->connect(pack_sockaddr_in($rport, $radd
+r))) {
print "DEBUG orig glob: $sock\n";
print "DEBUG open glob: $mysock\n";
bless $mysock, ref($sock);
print "DEBUG reblessed: $mysock\n\n";
return $mysock;
}
everything works as expected, and you'll get
$ ./883113.pl
DEBUG orig glob: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG open glob: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG reblessed: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG orig glob: IO::Socket::INET=GLOB(0x992688)
DEBUG open glob: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG reblessed: IO::Socket::INET=GLOB(0x9929e8)
$sock is: IO::Socket::INET=GLOB(0x9929e8)
As you can see, the final socket is the same handle (GLOB(0x9929e8)) that you created/connected with *CORE::GLOBAL::connect.
However, when you return $sock in the above snippet - as done in the original code - you'd get:
$ ./883113.pl
DEBUG orig glob: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG open glob: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG reblessed: IO::Socket::Foo=GLOB(0x9929e8)
DEBUG orig glob: IO::Socket::INET=GLOB(0x992688)
DEBUG open glob: IO::Socket::Foo=GLOB(0x9929e8) <---
DEBUG reblessed: IO::Socket::INET=GLOB(0x9929e8) |
|
$sock is: IO::Socket::INET=GLOB(0x992688) <--- != ---
Broken pipe!
because you're then trying to use the unconnected handle GLOB(0x992688).
Unfortunalely, this won't really help with your aim of socksifying arbitrary modules.. unless you mess with (and have control over) the IO::Socket::INET code. |