fix infinite loop
[l2tpns.git] / l2tpns.c
index dd1e8ae..5947561 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -132,6 +132,7 @@ config_descriptt config_values[] = {
        CONFIG("ppp_restart_time", ppp_restart_time, INT),
        CONFIG("ppp_max_configure", ppp_max_configure, INT),
        CONFIG("ppp_max_failure", ppp_max_failure, INT),
+       CONFIG("ppp_keepalive", ppp_keepalive, BOOL),
        CONFIG("primary_dns", default_dns1, IPv4),
        CONFIG("secondary_dns", default_dns2, IPv4),
        CONFIG("primary_radius", radiusserver[0], IPv4),
@@ -162,6 +163,7 @@ config_descriptt config_values[] = {
        CONFIG("icmp_rate", icmp_rate, INT),
        CONFIG("packet_limit", max_packets, INT),
        CONFIG("cluster_address", cluster_address, IPv4),
+       CONFIG("cluster_port", cluster_port, INT),
        CONFIG("cluster_interface", cluster_interface, STRING),
        CONFIG("cluster_mcast_ttl", cluster_mcast_ttl, INT),
        CONFIG("cluster_hb_interval", cluster_hb_interval, INT),
@@ -194,6 +196,7 @@ config_descriptt config_values[] = {
        CONFIG("dhcp6_preferred_lifetime", dhcp6_preferred_lifetime, INT),
        CONFIG("dhcp6_valid_lifetime", dhcp6_valid_lifetime, INT),
        CONFIG("dhcp6_server_duid", dhcp6_server_duid, INT),
+       CONFIG("dns6_lifetime", dns6_lifetime, INT),
        CONFIG("primary_ipv6_dns", default_ipv6_dns1, IPv6),
        CONFIG("secondary_ipv6_dns", default_ipv6_dns2, IPv6),
        CONFIG("default_ipv6_domain_list", default_ipv6_domain_list, STRING),
@@ -982,7 +985,6 @@ static sessionidt lookup_ipv6map(struct in6_addr ip)
        int s;
        char ipv6addr[INET6_ADDRSTRLEN];
 
-       curnode = &ipv6_hash[ip.s6_addr[0]];
        curnode = &ipv6_hash[((ip.s6_addr[0]) & 0xF0)>>4];
        i = 1;
        s = curnode->sess;
@@ -2714,7 +2716,14 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
                                        result = 2; // general error
                                        error = 3; // reserved field non-zero
                                        msg = 0;
-                                       continue; // next
+                                       if (n == 0)
+                                       {
+                                               // if continue a infinity loop is created.
+                                               LOG(1, s, t, "It's infinite loop protection %02X\n", *b);
+                                               return;
+                                       }
+                                       else
+                                               continue; // next
                                }
                                b += 2;
                                if (*(uint16_t *) (b))
@@ -2724,7 +2733,14 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
                                        result = 2; // general error
                                        error = 6; // generic vendor-specific error
                                        msg = "unsupported vendor-specific";
-                                       continue; // next
+                                       if (n == 0)
+                                       {
+                                               // if continue a infinity loop is created.
+                                               LOG(1, s, t, "It's infinite loop protection %02X\n", *b);
+                                               return;
+                                       }
+                                       else
+                                               continue; // next
                                }
                                b += 2;
                                mtype = ntohs(*(uint16_t *) (b));
@@ -3780,8 +3796,10 @@ static void regular_cleanups(double period)
                }
 
                // No data in ECHO_TIMEOUT seconds, send LCP ECHO
-               if (session[s].ppp.phase >= Establish && (time_now - session[s].last_packet >= config->echo_timeout) &&
-                       (time_now - sess_local[s].last_echo >= ECHO_TIMEOUT))
+               if (session[s].ppp.phase >= Establish &&
+                    ((!config->ppp_keepalive) ||
+                     (time_now - session[s].last_packet >= config->echo_timeout)) &&
+                   (time_now - sess_local[s].last_echo >= ECHO_TIMEOUT))
                {
                        uint8_t b[MAXETHER];
 
@@ -4600,6 +4618,9 @@ static void initdata(int optdebug, char *optconfig)
        // Set default value echo_timeout and idle_echo_timeout
        config->echo_timeout = ECHO_TIMEOUT;
        config->idle_echo_timeout = IDLE_ECHO_TIMEOUT;
+       config->ppp_keepalive = 1;
+       // Set default RDNSS lifetime
+       config->dns6_lifetime = 1200;
 
        log_stream = stderr;
 
@@ -5622,6 +5643,7 @@ static void update_config()
        memcpy(config->old_plugins, config->plugins, sizeof(config->plugins));
        if (!config->multi_read_count) config->multi_read_count = 10;
        if (!config->cluster_address) config->cluster_address = inet_addr(DEFAULT_MCAST_ADDR);
+       if (!config->cluster_port) config->cluster_port = CLUSTERPORT;
        if (!*config->cluster_interface)
                strncpy(config->cluster_interface, DEFAULT_MCAST_INTERFACE, sizeof(config->cluster_interface) - 1);
 
@@ -5916,9 +5938,12 @@ int load_session(sessionidt s, sessiont *new)
        }
 
        // check v6 routing
-       for (i = 0; i < MAXROUTE6 && new->route6[i].ipv6prefixlen; i++)
+       if (new->ppp.ipv6cp == Opened && session[s].ppp.ipv6cp != Opened)
        {
-               route6set(s, new->route6[i].ipv6route, new->route6[i].ipv6prefixlen, 1);
+               for (i = 0; i < MAXROUTE6 && new->route6[i].ipv6prefixlen; i++)
+               {
+                       route6set(s, new->route6[i].ipv6route, new->route6[i].ipv6prefixlen, 1);
+               }
        }
 
        if (new->ipv6address.s6_addr[0] && new->ppp.ipv6cp == Opened && session[s].ppp.ipv6cp != Opened)