1
2
3
4
5
6
7
8
9
10
11
12
13
debug("Erstelle Socket");
$server = IO::Socket::SSL->new(LocalAddr => $HOST,
LocalPort => $PORT,
Proto => 'tcp',
Listen => 10000,
Reuse => 1,
SSL_cert_file => $config{cert_file},
SSL_key_file => $config{key_file},
SSL_ca_file => $config{ca_file},
SSL_ca_path => $config{ca_path}
) or die translate("server_sockerror", { error => $! }) . "\n";
$server->autoflush(1);
$select->add($server);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
sub loop {
foreach our $key( $select->can_read()) { # foreach
if($key eq $server) { # if $bay eq $server
next if $key eq "";
our $bay = $server->accept or next;
my $ip = $bay->peerhost();
my $ident = _uid();
foreach my $key( keys %clients ) {
my $nick = $clients{$key}->{nick};
my $sock = $clients{$key}->{sock};
print "Verbindung von $nick und dem Socket $sock\n";
}
our $buffer = "";
newclient($bay);
$bay->sysread($buffer, 1024);
print "$buffer\n\n";
if($buffer =~ /GET \/\?sid=([a-zA-Z0-9]+)\s/) {
if($1) { # if $1
my $session = $1;
my $safesess = $dbh->quote($session);
my $sta = $dbh->prepare("SELECT session FROM Members WHERE session = $safesess LIMIT 1");
$sta->execute();
my $hassession = $sta->fetchrow_array();
$sta->finish();
$dbh->disconnect();
if($hassession) { # Wenn eine Session existiert dann ..
my %user = loadMemberInfo("", $session);
my $showtime= $user{showtime} == 0 ? 0 : 1;
my $nosmiles= $user{nosmileys} == 0 ? 0 : 1;
my $chatzone = $user{chatzone};
$clients{$ident} = {
sock => $bay,
nick => $user{nick},
sockcreated => &Time::HiRes::time(),
ip => $ip,
lastsrvpost => time,
showtime => $showtime,
nosmileys => $nosmiles,
chatzone => $chatzone,
session => $1,
alivetime => time
};
}
}
}
# Ab hier startet der fork()
defined( my $pid = fork()) or die "fork failed: $!";
$pid and next; # Master
close($server);
1
2
3
4
5
6
7
8
foreach my $ident( keys %clients ) {
my $sock = $clients{$ident}->{sock};
$msg = createFilter($ident, $data);
if( defined $sock ){
$sock->syswrite($msg . "\n");
debug("Sende Nachricht an alle...\n");
}
}
1
2
3
4
write_all VM at entry=vm_unknown
ERROR_SYSCALL(-1): errno()
written so far -1:0 bytes (VM=vm_unknown)
DEBUG: .../IO/Socket/SSL.pm:1203: SSL write errorerror:00000000:lib(0):func(0):reason(0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
next if $key eq "";
our $bay = $server->accept or next;
$bay->close(SSL_no_shutdown=>1);
my $ip = $bay->peerhost();
my $ident = _uid();
foreach my $key( keys %clients ) {
my $nick = $clients{$key}->{nick};
my $sock = $clients{$key}->{sock};
delete $clients{$key} if !defined $nick or !defined $sock;
print "Verbindung von $nick und dem Socket $sock\n";
}
our $buffer = "";
newclient($bay);
my $dag= getSecretKey();
$bay->sysread($buffer, 1024);
print "$buffer\n\n";
if($buffer =~ /GET \/\?sid=([a-zA-Z0-9]+)\s/) {
if($1) { # if $1
my $session = $1;
my $safesess = $dbh->quote($session);
my $sta = $dbh->prepare("SELECT session FROM Members WHERE session = $safesess LIMIT 1");
$sta->execute();
my $hassession = $sta->fetchrow_array();
$sta->finish();
$dbh->disconnect();
if($hassession) { # Wenn eine Session existiert dann ..
my %user = loadMemberInfo("", $session);
my $showtime= $user{showtime} == 0 ? 0 : 1;
my $nosmiles= $user{nosmileys} == 0 ? 0 : 1;
my $chatzone = $user{chatzone};
$clients{$ident} = {
sock => $bay,
nick => $user{nick},
sockcreated => &Time::HiRes::time(),
ip => $ip,
lastsrvpost => time,
showtime => $showtime,
nosmileys => $nosmiles,
chatzone => $chatzone,
session => $1,
alivetime => time
};
my $rickn = $user{nick};
$loggedin{$rickn}{htmlcon} = 1;
}
}
1
2
3
4
5
6
7
DEBUG: .../IO/Socket/SSL.pm:487: no socket yet
DEBUG: .../IO/Socket/SSL.pm:489: accept created normal socket IO::Socket::SSL=GLOB(0x1b59b18)
DEBUG: .../IO/Socket/SSL.pm:505: starting sslifying
DEBUG: .../IO/Socket/SSL.pm:545: Net::SSLeay::accept -> 1
DEBUG: .../IO/Socket/SSL.pm:593: handshake done, socket ready
DEBUG: .../IO/Socket/SSL.pm:493: accept_SSL ok
DEBUG: .../IO/Socket/SSL.pm:1203: Undefined SSL objecterror:00000000:lib(0):func(0):reason(0)
2017-08-20T15:05:16 Sascha2018Also durch das accept wird ja später die Verbindung hergestellt und der Handshake wird gestartet. Nun muss ich irgendwie den Buffer auslesen und den Hash %clients zuordnen.
Würde ich das alles im Child machen dann hätte ich wieder das Problem das ich %clients im Master u. Child habe und daher keine Kommunikation zwischen den beiden stattfindet und der Hash im Master daher nicht aktualisiert wird. Mit IPC::Shareable und Storable sowie auch Parallel::Forkmanager lassen sich keine Sockets sharen.
2017-08-22T07:11:24 MuffiMit SSL hab ich bei Chats noch nicht hantiert.
Aber aus Erfahrungen mit Chats und "normalen" Socketverbindungen:
Vergiss es. Es gibt nix, was dir sicher sagt, ob der Client noch da ist.
Es kann sogar sein, dass du noch erfolgreich schreiben kannst und der Client ist schon weg.
Aber im Regelfall kann man davon ausgehen, wenn der Socket noch da ist, dann funktioniert er auch.
2017-08-22T08:06:02 MuffiFür "mal schnell nen Chat" mag der schon ausreichen.
Es gibt aber auch Situationen, wo nicht nach "mal schnell ein Chat" gefragt ist.