Monks,
This one is doing my head in. The program below is a reduced testcase of something bigger and even uglier, but it exhibits the same baffling behaviour as this one.
I posted a rather badly prepared question along the same lines about a week ago and, shortly after I found a workaround that I can't live with any more. And I'm back looking for a solution.
There is a call to a forking sub 'fork_one' that can be placed in one of two positions in the program. In either position, the 'fork_one' routine behaves exactly as expected. However, when the call is made in the second position, weird stuff happens later on.
In the first position, the 'fork_one' ends up running in an orphaned process, nothing to do with the main daemon. In the second position, it is a child of the main daemon.
Regardless of the positioning of the call to 'fork_one', when the accept receives a connection it calls the forking sub 'fork_three' which does its business and dies.
Depending on the position of the 'fork_one' routine, the accept subsequently either works perfectly normally or just blocks/hangs. The connection is made by the client, but no SSL negotiation happens.
If you don't exit in fork_three, but allow it to return to the main loop and the 'accept', it will correctly accept the next connection. I only say this to say that the socket isn't fundamentally broken, not because I think this is a rational thing to do.
By now I've pretty much forgotten what it was I was actually trying to communicate and in place of a real client, I've been hitting it with:
openssl s_client -cert certs/capsclscert.pem -key certs/capscls_pk.pem
+ -CAfile certs/cacert.pem -connect 10.250.3.242:6023
The test program is:
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::SSL;
use POSIX ":sys_wait_h";
my $pidfilename = 'sftest';
# try monitor fork here:
#fork_one();
# ... and everything is ok
# become a daemon
my $pid;
if (!defined($pid = fork)) {
die "Cannot daemonize myself: $! \n";
}elsif ($pid) {
# I am the parent and the fork suceeded. Duck out now
print "created daemon in $pid. I ($$) am ducking out\n";
exit;
}
# Try the monitor fork here:
fork_one();
#... and the second call to accept hangs
print "I'm daemonized on $$ \n";
sub REAPER {
{} until ( waitpid(-1, WNOHANG) == -1)
}
$SIG{CHLD} =\&REAPER;
my $sock;
if(!($sock = IO::Socket::SSL->new( Listen => 5,
LocalAddr => '10.250.3.242',
LocalPort => '6023',
Proto => 'tcp',
SSL_verify_mode => 0x01,
SSL_cert_file => 'certs/capssvcert.
+pem',
SSL_key_file => 'certs/capssv_pk.p
+em',
Reuse => 1,
)) ) {
die "unable to create socket: ", &IO::Socket::SSL::errstr, "\n";
}
while (1 ) {
my $s;
print "$$ is listening...\n";
if ( $s = $sock->accept() ) {
fork_three($s);
}
}
####################
sub fork_one {
my $pid;
if (!defined($pid = fork)) {
die "Cannot make monitor process: $! \n";
}elsif ($pid) {
# I am the parent and the fork suceeded. Duck out now
print "created monitor process in $pid. I ($$) am resuming \n
+";
return;
}
print "I ($$) am going to loop around doing some fatuous monitoring
+process\n";
while (1) {
sleep 30;
print "$$ is still monitoring\n";
}
}
sub fork_three {
my $s = shift;
my $pid;
if (!defined($pid = fork)) {
die "Cannot make dummy event processor: $! \n";
}elsif ($pid) {
# I am the parent and the fork suceeded. Duck out now
print "created dummy event processor in $pid. I ($$) am resum
+ing \n";
return;
}
print "I ($$) am going to do some dummy event process\n";
$s->close(SSL_no_shutdown => 1);
# my work is done...
exit;
}
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.