OSDN Git Service

ticket #405 再登録
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7directord / l7directord
index 80eef57..b49fe12 100644 (file)
@@ -77,7 +77,7 @@ use Socket;
 use Socket6;
 
 # current version
-our $VERSION     = '2.1.2-0';
+our $VERSION     = '3.0.0-0';
 our $COPYRIGHT   = 'Copyright (C) 2009 NTT COMWARE CORPORATION';
 
 # default global config values
@@ -992,17 +992,22 @@ sub validate_config {
             my @option_value = split /,/, $value;
             # OPTION:deferaccept,nodelay,cork,quickackon|quickackoff
             for my $option (@option_value) {
-                if($option !~ /deferaccept|nodelay|cork|quickackon|quickackoff/) {
+                if($option !~ /^deferaccept|nodelay|cork|quickackon|quickackoff$/) {
                     config_error($line, 'ERR0124', $config);
                 }
             }
         }
-        elsif ($name eq 'sslconfigfile'
-            || $name eq 'accesslogfile') {
+        elsif ($name eq 'sslconfigfile') {
             if (!defined $value || !-f $value) {
                 config_error($line, 'ERR0116', $config);
             }
         }
+        elsif ( $name eq 'accesslogfile') {
+            if (!defined $value || $value !~ /^\/.*/) {
+                config_error($line, 'ERR0116', $config);
+            }
+    
+        }
         elsif ($name eq 'accesslog_rotate_type') {
             $value = lc $value;
             my $valid_rotate_type = qr{date|size|datesize};
@@ -1017,7 +1022,7 @@ sub validate_config {
         }
         elsif ($name eq 'accesslog_rotate_max_filesize') {
             $value = uc $value;
-            if ( !defined $value || ($value ne '0' && $value !~ /^([1-9]\d{0,2}[KMG]|\d)$/) ) {
+            if ( !defined $value || ($value ne '0' && $value !~ /^([1-9]\d{0,2}[KMG]|\d{1,3})$/) ) {
                 config_error($line, 'ERR0127', $config);
             }
         }
@@ -1034,11 +1039,11 @@ sub validate_config {
             if (!defined $value ) {
                 config_error($line, 'ERR0129', $config);
             }
-            if ($value =~ /^[1-9]\d{0,1}\/[1-9]\d{0,1}\s\d{1,2}:\d{1,2}$/i) {
+            if ($value =~ /^\d{1,2}\/\d{1,2}\s\d{1,2}:\d{1,2}$/) {
                 ## MM/dd hh:mm Check
                 $check = 1;
             }
-            elsif ($value =~ /^[1-9]\d{0,1}\s\d{1,2}:\d{1,2}$/i) {
+            elsif ($value =~ /^\d{1,2}\s\d{1,2}:\d{1,2}$/) {
                 ## dd hh:mm Check
                 $check = 1;
             }
@@ -1046,11 +1051,11 @@ sub validate_config {
                 ## <week> hh:mm Check
                 $check = 1;
             }
-            elsif ($value =~ /^\d{1,2}:\d{1,2}$/i) {
+            elsif ($value =~ /^\d{1,2}:\d{1,2}$/) {
                 ## hh:mm        Check
                 $check = 1;
             }
-            elsif ($value =~ /^\d{1,2}$/i) {
+            elsif ($value =~ /^\d{1,2}$/) {
                 ## mm           Check
                 $check = 1;
             }
@@ -1197,7 +1202,6 @@ sub parse_real {
                          (\S+)               #  receive"
                       )?                     # (optional)
                       $/ix) {
-       print "real:" . $real. "\n";
         config_error($line, 'ERR0114', $config_line);
     }
     my ($ip1, $ip2, $port, $forward, $weight, $request, $receive)
@@ -1328,7 +1332,7 @@ sub ld_setup {
                     $v->{option}{flags} .= ' -q ' . $v->{qosdown};
                 }
                 if ( defined $v->{sslconfigfile} ) {
-                    $v->{option}{flags} .= ' -S ' . $v->{sslconfigfile};
+                    $v->{option}{flags} .= ' -z ' . $v->{sslconfigfile};
                     $v->{other_virtual_key} .= ' ' . $v->{sslconfigfile};
                 }
                 else {
@@ -1389,14 +1393,14 @@ sub ld_setup {
                 if ( defined $v->{accesslog_rotate_rotation_timing_value} ) {
                     $v->{option}{flags}
                        .= ' --ac-rotate-rotation-timing-value '
-                             . $v->{accesslog_rotate_rotation_timing_value};
+                          . q{"}. $v->{accesslog_rotate_rotation_timing_value}. q{"};
                     $v->{other_virtual_key} 
                        .= ' --ac-rotate-rotation-timing-value '
-                             . $v->{accesslog_rotate_rotation_timing_value};
+                          . q{"}. $v->{accesslog_rotate_rotation_timing_value}. q{"};
                     $option_key_flag = 1;
                 }
                 if ( $option_key_flag == 0 ) {
-                    $v->{other_virtual_key} .= ' none ';
+                    $v->{other_virtual_key} .= ' none';
                 }
             }
     
@@ -1444,8 +1448,13 @@ sub ld_setup {
                     # build request URL
                     if ( defined $v->{service} && defined $r->{server} ) {
                         my $port = defined $v->{checkport} ? $v->{checkport} : $r->{server}{port};
+                        my $ipaddress = $r->{server}{ip};
+                        if ( is_ip6($ipaddress)){
+                            $ipaddress = qq{ [$r->{server}{ip}] };
+                        }
                         $r->{url} = sprintf "%s://%s:%s/",
-                                            $v->{service}, $r->{server}{ip}, $port;
+                                            $v->{service}, $ipaddress, $port;
+                        $r->{url} =~ s/\s//g;
                     }
                     if ( !defined $r->{request} && defined $v->{request} ) {
                         $r->{request} = $v->{request};
@@ -1779,18 +1788,24 @@ sub ld_start {
                 return;
             }
     
-            if ( exists( $current_service->{$vip_id} )
-             && (defined $current_service->{$vip_id}{other_virtual_option} 
-               && defined $nv->{other_virtual_key}
-               && $current_service->{$vip_id}{other_virtual_option}
-                eq  $nv->{other_virtual_key} )) {
-                # service already exists, modify it
-                ld_edit_virtual($nv);
+            if ( exists( $current_service->{$vip_id} )){
+                if(( defined $current_service->{$vip_id}{other_virtual_option} 
+                  && defined $nv->{other_virtual_key})
+                  && $current_service->{$vip_id}{other_virtual_option}
+                   ne  $nv->{other_virtual_key} ) {
+                    ld_delete_virtual($nv);
+                    # no such service, create a new one
+                    ld_add_virtual($nv);
+                    $nv->{other_virtual_key}
+                        = $current_service->{$vip_id}{other_virtual_option};
+                }
+                else {
+                    # service already exists, modify it
+                    ld_edit_virtual($nv);
+                }
             }
             else {
                 # no such service, create a new one
-                ld_delete_virtual($nv);
-                # no such service, create a new one
                 ld_add_virtual($nv);
             }
     
@@ -1834,8 +1849,17 @@ sub ld_start {
                 }
             }
     
+            my $work_ip = undef;
             # remove remaining entries for real servers
             for my $remove_real_ip_port (keys %$or) {
+                if ( 'other_virtual_option' eq $remove_real_ip_port ){
+                    next;
+                }
+                $work_ip = $or->{$remove_real_ip_port}{server}{ip};
+                if ( !is_ip ($work_ip) 
+                  && !is_ip6($work_ip)){
+                    next;
+                }
                 ld_delete_real( $nv, $or->{$remove_real_ip_port} );
                 delete $or->{$remove_real_ip_port};
             }
@@ -1926,6 +1950,11 @@ sub ld_stop {
             }
             if ( exists $srv->{$vid} ) {
                 for my $rid ( keys %{ $srv->{$vid} } ) {
+                    if ( defined $rid 
+                      &&(!is_ip ($rid)
+                      && !is_ip6($rid))){
+                        next;
+                    }
                     ld_delete_real( $v, $srv->{$vid}{$rid} );
                 }
             }
@@ -2320,36 +2349,55 @@ sub check_http {
     my $virtualhost = defined $v->{virtualhost} ? $v->{virtualhost} : $host;
 
     ld_debug(2, "check_http: url=\"$r->{url}\" " . "virtualhost=\"$virtualhost\"");
+    my $status_line ;
 
-    my $ua = LWP::UserAgent->new( timeout => $v->{negotiatetimeout} );
-    my $req = new HTTP::Request( $v->{httpmethod}, $r->{url}, [ Host => $virtualhost ] );
-    my $res;
-    {
-        # LWP makes ungaurded calls to eval
-        # which throw a fatal exception if they fail
-        local $SIG{__DIE__} = 'DEFAULT';
-        local $SIG{ALRM} = sub { die "Can't connect to $r->{server}{ip}:$port (connect: timeout)\n"; };
-        eval {
-            alarm $v->{negotiatetimeout};
-            $res = $ua->request($req);
+    if ( is_ip($r->{server}{ip})){
+        my $ua = LWP::UserAgent->new( timeout => $v->{negotiatetimeout} );
+        my $req = new HTTP::Request( $v->{httpmethod}, $r->{url}, [ Host => $virtualhost ] );
+        my $res;
+        {
+            # LWP makes ungaurded calls to eval
+            # which throw a fatal exception if they fail
+            local $SIG{__DIE__} = 'DEFAULT';
+            local $SIG{ALRM} = sub { die "Can't connect to $r->{server}{ip}:$port (connect: timeout)\n"; };
+            eval {
+                alarm $v->{negotiatetimeout};
+                $res = $ua->request($req);
+                alarm 0;
+            };
             alarm 0;
-        };
-        alarm 0;
-    }
-
-    my $status_line = $res->status_line;
-    $status_line =~ s/[\r\n]//g;
+        }
+    
+        $status_line = $res->status_line;
+        $status_line =~ s/[\r\n]//g;
 
-    my $recstr = $r->{receive};
-    if (!$res->is_success) {
-        ld_log( _message( 'WRN1102', $status_line, $r->{server}{ip}, $port ) ) if (!defined $status || $status eq $SERVICE_UP);
-        return $SERVICE_DOWN;
+        my $recstr = $r->{receive};
+        if (!$res->is_success) {
+            ld_log( _message( 'WRN1102', $status_line, $r->{server}{ip}, $port ) ) if (!defined $status || $status eq $SERVICE_UP);
+            return $SERVICE_DOWN;
+        }
+            elsif (defined $recstr && $res->as_string !~ /$recstr/) {
+            ld_log( _message( 'WRN1103', $recstr, $r->{server}{ip}, $port ) ) if (!defined $status || $status eq $SERVICE_UP);
+            ld_debug(3, "Headers " . $res->headers->as_string);
+            ld_debug(2, "check_http: $r->{url} is down\n");
+            return $SERVICE_DOWN;
+        }
     }
-    elsif (defined $recstr && $res->as_string !~ /$recstr/) {
-        ld_log( _message( 'WRN1103', $recstr, $r->{server}{ip}, $port ) ) if (!defined $status || $status eq $SERVICE_UP);
-        ld_debug(3, "Headers " . $res->headers->as_string);
-        ld_debug(2, "check_http: $r->{url} is down\n");
-        return $SERVICE_DOWN;
+    else{
+        ## ipv6 Check
+        ## Wget Comand Check
+        my $https_option = '';
+        if ( $v->{service} eq 'https'){
+            $https_option = '--no-check-certificate';
+        }
+        my $command = "/usr/bin/wget " . "-t 1 --timeout $v->{negotiatetimeout} $https_option ".  $r->{url} . ' > /dev/null 2>&1';
+        if( system_wrapper( $command )) {
+            ld_log( _message( 'WRN1103', 'web', $r->{server}{ip}, $port ) ) if (!defined $status || $status eq $SERVICE_UP);
+            return $SERVICE_DOWN;
+        }
+        $status_line = '200 OK';
+        return $SERVICE_UP ;
+
     }
 
     ld_debug(2, "check_http: $r->{url} is up\n");
@@ -2710,7 +2758,7 @@ sub check_connect {
     my $sock = ld_open_socket( $r->{server}{ip}, $port, $v->{protocol}, $v->{checktimeout} );
     if (!defined $sock) {
         ld_log( _message('WRN3201', $ERRNO, $r->{server}{ip}, $port) ) if (!defined $status || $status eq $SERVICE_UP);
-sleep 1;
+
         return $SERVICE_DOWN;
     }
     close($sock);
@@ -2805,6 +2853,35 @@ sub check_ftp {
 
     my $ip_port = get_ip_port($r, $v->{checkport});
 
+    if (is_ip6($r->{server}{ip}) ){
+        ## IPv6 route
+        ## use 'lftp' Command
+        ## lftp 
+        ##   -e ' set net:max-retries 1;
+        ##        set net:reconnect-interval-multiplier 1;
+        ##        set cmd:fail-exit true;
+        ##        set net:reconnect-interval-base 1;
+        ##        ls;ls ;exit'
+        ##   -u user,passwd ipv6addr >/dev/null 2>&1
+
+        my $ftp_command     = "lftp ";
+        my $ftp_environment1 = "-e \"set net:max-retries 2;";
+        my $ftp_environment2 = "set net:reconnect-interval-multiplier 1;";
+        my $ftp_environment3 = "set cmd:fail-exit true;";
+        my $ftp_environment4 = "set net:reconnect-interval-base $v->{negotiatetimeout};";
+        my $ftp_environment5 = "ls;ls;exit\" ";
+        my $ftp_parameter   = "-u $v->{login},$v->{passwd} $ip_port >/dev/null 2>&1";
+        $ftp_command .= $ftp_environment1 . $ftp_environment2. $ftp_environment3. $ftp_environment4. $ftp_environment5. $ftp_parameter;
+
+## print "ftpCommand:". $ftp_command;
+        if( system_wrapper( $ftp_command )) {
+            ld_log( _message('WRN3101', $v->{checktimeout}, $r->{server}{ip}) ) if (!defined $status || $status eq $SERVICE_UP);
+            return $SERVICE_DOWN;
+        }
+        return $SERVICE_UP ;
+    }
+    ## IPv4 route
+
     ld_debug(2, "Checking ftp server=$ip_port");
     my $debug_flag = $DEBUG_LEVEL ? 1 : 0;
 
@@ -2977,7 +3054,7 @@ sub check_ping {
     else {
     ## IPv6 PingCheck
         my $command
-            = sprintf "ping6 %s -w %d > /dev/null 2>&1",
+            = sprintf "ping6 %s -c %d > /dev/null 2>&1",
                                      $r->{server}{ip},
                                      $v->{checktimeout};
 
@@ -3127,6 +3204,9 @@ sub _status_up {
             my $weight = 0;
             # all real server's weight are zero.
             for my $real ( keys %{ $current_service->{$vid} } ) {
+                if ( 'other_virtual_option' eq $real ){
+                    next;
+                }
                 # already added fallback server.
                 if ( $real eq get_ip_port( $v_r_list->[0][1] ) ) {
                     return 0;
@@ -3177,6 +3257,9 @@ sub _status_down {
             my $fallback_exist = 0;
             # any real server has weight.
             for my $real ( keys %{ $current_service->{$vid} } ) {
+                if ( 'other_virtual_option' eq $real ){
+                    next;
+                }
                 if ( $real eq get_ip_port( $v_r_list->[0][1] ) ) {
                     $fallback_exist = 1;
                 }
@@ -3710,7 +3793,7 @@ sub is_ip {
 
     # If we don't have four, . delimited numbers then we have no hope
     if (!defined $alleged_ip || $alleged_ip !~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) {
-        ld_log( _message('ERR0501') );
+##        ld_log( _message('ERR0501') );
         return 0;
     }
 
@@ -3733,7 +3816,6 @@ sub is_ip6 {
     my $alleged_ip = shift;
     my @return_array = (0, undef);
 
-    # If we don't have four, . delimited numbers then we have no hope
     if (!defined $alleged_ip ) {
         ld_log( _message('ERR0501') );
         return 0;
@@ -3769,7 +3851,6 @@ sub is_ip6 {
                               ([0-9a-fA-F]{1,4}):
                               ([0-9a-fA-F]{1,4}):
                               ([0-9a-fA-F]{1,4})(%.+)?$/x) {
-        ld_log( _message('ERR0501') );
         return 0;
     }
     @return_array = (1, @address);
@@ -3786,29 +3867,29 @@ sub is_ip6 {
 sub ip_to_int {
     my $ip_address = shift;
     my $ip_version = 'ipv4';
-    my @result = undef;
-    my @result2 = undef;
+    my $result = undef;
+    my $result2 = undef;
     my @return_array = (undef, -1);
 
 
     if ( is_ip($ip_address) ) {
         my ($oct1, $oct2, $oct3, $oct4)
             = $ip_address =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
-        @result = (($oct1 << 24) + ($oct2 << 16) + ($oct3 << 8) + $oct4);
+        $result = ($oct1 << 24) + ($oct2 << 16) + ($oct3 << 8) + $oct4;
     }
     else {
         my ( $ret, @address ) = is_ip6($ip_address);
         if ( $ret == 1 ) {
             my ( $hex1, $hex2, $hex3, $hex4, $hex5, $hex6, $hex7, $hex8, $linklocal) = @address;
-            @result = ((hex($hex5) << 48)  + (hex($hex6) << 32) + (hex($hex7) << 16)  + hex($hex8));
-            @result2 = ((hex($hex1) << 48)  + (hex($hex2) << 32) + (hex($hex3) << 16)  + hex($hex4));                      
+            $result  = (hex($hex5) << 48)  + (hex($hex6) << 32) + (hex($hex7) << 16)  + hex($hex8);
+            $result2 = (hex($hex1) << 48)  + (hex($hex2) << 32) + (hex($hex3) << 16)  + hex($hex4);                      
             $ip_version = 'ipv6';
         }
         else {
             return @return_array;
         }
     }
-    @return_array = ($ip_version, @result, @result2);
+    @return_array = ($ip_version, $result, $result2);
     return @return_array;
 }
 
@@ -3837,23 +3918,14 @@ sub int_to_ip {
                          ($ip_address >>  32) & 0xffff,
                          ($ip_address >>  16) & 0xffff,
                          ($ip_address       ) & 0xffff;
-
-##                         ($ip_address >> 112) & 0xffff,
-##                         ($ip_address >>  96) & 0xffff,
-##                         ($ip_address >>  80) & 0xffff,
-##                         ($ip_address >>  64) & 0xffff,
-##                         ($ip_address >>  48) & 0xffff,
-##                         ($ip_address >>  32) & 0xffff,
-##                         ($ip_address >>  16) & 0xffff,
-##                         ($ip_address       ) & 0xffff;
     }
     else {
     ## IPv4 Address Change
         $result = sprintf "%d.%d.%d.%d",
-                         ($ip_address >> 24) & 255,
-                         ($ip_address >> 16) & 255,
-                         ($ip_address >> 8 ) & 255,
-                         ($ip_address      ) & 255;
+                         ($ip_address >> 24) & 0xff,
+                         ($ip_address >> 16) & 0xff,
+                         ($ip_address >> 8 ) & 0xff,
+                         ($ip_address      ) & 0xff;
     }
     return $result;
 }
@@ -3867,6 +3939,9 @@ sub get_ip_port {
     my ($host, $checkport) = @_;
     my $server = defined $host && defined $host->{server} && defined $host->{server}{ip}
                     ? $host->{server}{ip  } : q{};
+    if (is_ip6($server)) {
+        $server = sprintf "[%s]" , $server;
+    }
     my $port   = defined $checkport ? $checkport
                : defined $host && defined $host->{server} && defined $host->{server}{port}
                     ? $host->{server}{port} : q{};
@@ -4122,7 +4197,7 @@ sub ld_gethostservbyname {
         /ix) {
         if ( !defined $hostserv || $hostserv !~ /
                  ^
-                 (\[[a-z0-9.-:]+\])           # host or ip
+            (\[[a-z0-9.-:%]+\]) # host or ip
                  :                           # colon
                  (\d+|[a-z0-9-]+)            # serv or port
                  $
@@ -4835,7 +4910,7 @@ The setting possible value is described.
            In a socket for communication with Client in Session and RealServer, TCP_QUICKACK setting.
 
 example:
-       socketoption=deferaccept nodelay quickackoff
+       socketoption=deferaccept,nodelay,quickackoff
 
 =item B<accesslog = ">I<ACCESSLOG_ROTATE_TYPE>B<">