ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/deliantra/server/ext/tcp.ext
Revision: 1.29
Committed: Fri Sep 19 12:03:49 2025 UTC (13 months, 1 week ago) by root
Branch: MAIN
Changes since 1.28: +11 -7 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.17 #! perl # mandatory
2 root 1.1
3     # this listens for new tcp connections and hands them over to the server core
4    
5     use Socket;
6 root 1.12 use AnyEvent::Socket;
7 root 1.1
8 root 1.20 CONF BIND_ADDRESSES = [[undef, 13327]];
9 root 1.29 CONF DETECT_TIMEOUT = 300; # when to time-out connections
10 root 1.20
11 root 1.25 our $MAX_DETECT; # how many bytes to read to identify the protocol
12 root 1.21
13 root 1.15 our @LISTENERS;
14 root 1.25 our @DETECTORS;
15     our %DETECTORS;
16 root 1.12
17 root 1.25 sub _update_detectors {
18     $MAX_DETECT = List::Util::max map $_->[1], values %DETECTORS;
19 root 1.23 }
20    
21 root 1.25 sub register($$$$) {
22     my ($name, $max_detect, $detect, $serve) = @_;
23    
24 root 1.27 $DETECTORS{$name} = [$max_detect, $detect, $serve, $name];
25 root 1.25 _update_detectors;
26    
27     Guard::guard {
28     delete $DETECTORS{$name};
29 root 1.28 _update_detectors if defined &_update_detectors;
30 root 1.25 }
31     }
32    
33     our $deliantra_detector = ext::tcp::register deliantra => 10, sub {
34     /^..version /s
35     }, sub {
36     my $ns = cf::client::create fileno $_[1], $_[0];
37 root 1.26 $ns->run;
38 root 1.25 $ns->inbuf_append ($_[2]);
39     };
40    
41 root 1.20 for (@$BIND_ADDRESSES) {
42 root 1.12 my ($host, $port) = @$_;
43 root 1.16 cf::info "listening on ", (format_hostport $host, $port), "\n";
44 root 1.12
45 root 1.15 push @LISTENERS, tcp_server $host, $port, sub {
46 root 1.12 my ($fh, $host, $port) = @_
47     or return;
48    
49 root 1.18 my $lhost = AnyEvent::Socket::format_address
50     +(AnyEvent::Socket::unpack_sockaddr getsockname $fh)[1];
51    
52 root 1.21 my $id = format_hostport $host, $port;
53    
54 root 1.25 cf::info "$id: accepted connection.\n"
55 root 1.18 if $lhost ne $host; # do not log connections from the host, e.g. for watchdogs
56 root 1.12
57 root 1.29 my ($buf, $t, $r);
58    
59     $r = AE::io $fh, 0, sub {
60 root 1.21 my $len = sysread $fh, $buf, 512, length $buf;
61    
62     if ($len) {
63 root 1.25 for ($buf) {
64 root 1.27 for my $v (values %DETECTORS) {
65 root 1.25 if (my $cb = $v->[1]()) {
66 root 1.29 undef $r; undef $t;
67 root 1.27 cf::debug "$id: detected protocol $v->[3].\n";
68 root 1.25 $v->[2]($id, $fh, $buf);
69     return;
70     }
71     }
72    
73     if (length >= $MAX_DETECT) { # unable to detect protocol
74 root 1.29 undef $r; undef $t;
75 root 1.25 cf::debug "$id: data received, but cannot detect protocol, closing.\n";
76     }
77 root 1.21 }
78     } else {
79 root 1.29 undef $r; undef $t;
80 root 1.25 cf::info "$id: read error during protocol detection ($!)\n";
81 root 1.21 }
82     };
83 root 1.29 $t = EV::timer $DETECT_TIMEOUT, 0, sub {
84     cf::info "$id: protocol detection tiomeout.\n";
85     shutdown $fh, 0;
86     };
87 root 1.12 };
88 root 1.1 }
89