add pid_file as in Debian package
[l2tpns.git] / l2tpns.c
index 4e8d095..60b5497 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -4,7 +4,7 @@
 // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
 // vim: sw=8 ts=8
 
 // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
 // vim: sw=8 ts=8
 
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.61 2004/11/29 03:55:21 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.63 2004/12/09 00:50:45 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -1254,7 +1254,7 @@ static void tunnelshutdown(tunnelidt t, char *reason)
        // TBA - should we wait for sessions to stop?
        {                            // Send StopCCN
                controlt *c = controlnew(4); // sending StopCCN
        // TBA - should we wait for sessions to stop?
        {                            // Send StopCCN
                controlt *c = controlnew(4); // sending StopCCN
-               control16(c, 1, 1, 1);    // result code (admin reasons - TBA make error, general error, add message
+               control16(c, 1, 1, 1);    // result code (admin reasons - TBA make error, general error, add message)
                control16(c, 9, t, 1);    // assigned tunnel (our end)
                controladd(c, t, 0);      // send the message
        }
                control16(c, 9, t, 1);    // assigned tunnel (our end)
                controladd(c, t, 0);      // send the message
        }
@@ -1731,7 +1731,7 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
                                case 39:    // seq required - we control it as an LNS anyway...
                                        break;
                                case 36:    // Random Vector
                                case 39:    // seq required - we control it as an LNS anyway...
                                        break;
                                case 36:    // Random Vector
-                                       LOG(4, s, t, "   Random Vector received. Enabled AVP Hiding.\n");
+                                       LOG(4, s, t, "   Random Vector received.  Enabled AVP Hiding.\n");
                                        memset(session[s].random_vector, 0, sizeof(session[s].random_vector));
                                        memcpy(session[s].random_vector, b, n);
                                        session[s].random_vector_length = n;
                                        memset(session[s].random_vector, 0, sizeof(session[s].random_vector));
                                        memcpy(session[s].random_vector, b, n);
                                        session[s].random_vector_length = n;
@@ -1912,12 +1912,6 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
                        return;
                }
 
                        return;
                }
 
-               if (session[s].die)
-               {
-                       LOG(3, s, t, "Session %d is closing. Don't process PPP packets\n", s);
-// I'm pretty sure this isn't right -- mo.
-//                     return;              // closing session, PPP not processed
-               }
                if (prot == PPPPAP)
                {
                        session[s].last_packet = time_now;
                if (prot == PPPPAP)
                {
                        session[s].last_packet = time_now;
@@ -1950,12 +1944,19 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
                }
                else if (prot == PPPIP)
                {
                }
                else if (prot == PPPIP)
                {
+                       if (session[s].die)
+                       {
+                               LOG(4, s, t, "Session %d is closing.  Don't process PPP packets\n", s);
+                               return;              // closing session, PPP not processed
+                       }
+
                        session[s].last_packet = time_now;
                        if (session[s].walled_garden && !config->cluster_iam_master)
                        {
                                master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
                                return;
                        }
                        session[s].last_packet = time_now;
                        if (session[s].walled_garden && !config->cluster_iam_master)
                        {
                                master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
                                return;
                        }
+
                        processipin(t, s, p, l);
                }
                else
                        processipin(t, s, p, l);
                }
                else
@@ -2232,7 +2233,7 @@ static int still_busy(void)
        // We stop waiting for radius after BUSY_WAIT_TIME 1/10th seconds
        if (abs(TIME - start_busy_wait) > BUSY_WAIT_TIME)
        {
        // We stop waiting for radius after BUSY_WAIT_TIME 1/10th seconds
        if (abs(TIME - start_busy_wait) > BUSY_WAIT_TIME)
        {
-               LOG(1, 0, 0, "Giving up waiting for RADIUS to be empty. Shutting down anyway.\n");
+               LOG(1, 0, 0, "Giving up waiting for RADIUS to be empty.  Shutting down anyway.\n");
                return 0;
        }
 
                return 0;
        }
 
@@ -2266,7 +2267,7 @@ static void mainloop(void)
        clockt next_cluster_ping = 0;   // send initial ping immediately
        time_t next_clean = time_now + config->cleanup_interval;
 
        clockt next_cluster_ping = 0;   // send initial ping immediately
        time_t next_clean = time_now + config->cleanup_interval;
 
-       LOG(4, 0, 0, "Beginning of main loop. udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
+       LOG(4, 0, 0, "Beginning of main loop.  udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
                udpfd, tunfd, cluster_sockfd, controlfd);
 
        FD_ZERO(&readset);
                udpfd, tunfd, cluster_sockfd, controlfd);
 
        FD_ZERO(&readset);
@@ -2339,60 +2340,101 @@ static void mainloop(void)
                else if (n)
                {
                        struct sockaddr_in addr;
                else if (n)
                {
                        struct sockaddr_in addr;
-                       int alen = sizeof(addr);
-                       if (FD_ISSET(udpfd, &r))
-                       {
-                               int c, n;
-                               for (c = 0; c < config->multi_read_count; c++)
-                               {
-                                       if ((n = recvfrom(udpfd, buf, sizeof(buf), 0, (void *) &addr, &alen)) > 0)
-                                               processudp(buf, n, &addr);
-                                       else
-                                               break;
-                               }
-                       }
-                       if (FD_ISSET(tunfd, &r))
+                       int alen, c, s;
+
+                       // nsctl commands
+                       if (FD_ISSET(controlfd, &r))
                        {
                        {
-                               int c, n;
-                               for (c = 0; c < config->multi_read_count; c++)
-                               {
-                                       if ((n = read(tunfd, buf, sizeof(buf))) > 0)
-                                               processtun(buf, n);
-                                       else
-                                               break;
-                               }
+                               alen = sizeof(addr);
+                               processcontrol(buf, recvfrom(controlfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen), &addr, alen);
+                               n--;
                        }
 
                        }
 
+                       // RADIUS responses
                        if (config->cluster_iam_master)
                        if (config->cluster_iam_master)
+                       {
                                for (i = 0; i < config->num_radfds; i++)
                                for (i = 0; i < config->num_radfds; i++)
+                               {
                                        if (FD_ISSET(radfds[i], &r))
                                        if (FD_ISSET(radfds[i], &r))
+                                       {
                                                processrad(buf, recv(radfds[i], buf, sizeof(buf), 0), i);
                                                processrad(buf, recv(radfds[i], buf, sizeof(buf), 0), i);
+                                               n--;
+                                       }
+                               }
+                       }
 
 
-                       if (FD_ISSET(cluster_sockfd, &r))
+                       // CLI connections
+                       if (FD_ISSET(clifd, &r))
                        {
                        {
-                               int size;
-                               size = recvfrom(cluster_sockfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen);
-                               processcluster(buf, size, addr.sin_addr.s_addr);
+                               int cli;
+                               
+                               alen = sizeof(addr);
+                               if ((cli = accept(clifd, (struct sockaddr *)&addr, &len)) >= 0)
+                               {
+                                       cli_do(cli);
+                                       close(cli);
+                               }
+                               else
+                                       LOG(0, 0, 0, "accept error: %s\n", strerror(errno));
+
+                               n--;
                        }
 
                        }
 
-                       if (FD_ISSET(controlfd, &r))
-                               processcontrol(buf, recvfrom(controlfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen), &addr, alen);
+#ifdef BGP
+                       for (i = 0; i < BGP_NUM_PEERS; i++)
+                       {
+                               int isr = bgp_set[i] ? FD_ISSET(bgp_peers[i].sock, &r) : 0;
+                               int isw = bgp_set[i] ? FD_ISSET(bgp_peers[i].sock, &w) : 0;
+                               bgp_process(&bgp_peers[i], isr, isw);
+                               if (isr) n--;
+                               if (isw) n--;
+                       }
+#endif /* BGP */
 
 
-                       if (FD_ISSET(clifd, &r))
+                       for (c = 0; n && c < config->multi_read_count; c++)
                        {
                        {
-                               struct sockaddr_in addr;
-                               int sockfd;
-                               int len = sizeof(addr);
+                               // L2TP
+                               if (FD_ISSET(udpfd, &r))
+                               {
+                                       alen = sizeof(addr);
+                                       if ((s = recvfrom(udpfd, buf, sizeof(buf), 0, (void *) &addr, &alen)) > 0)
+                                       {
+                                               processudp(buf, s, &addr);
+                                       }
+                                       else
+                                       {
+                                               FD_CLR(udpfd, &r);
+                                               n--;
+                                       }
+                               }
 
 
-                               if ((sockfd = accept(clifd, (struct sockaddr *)&addr, &len)) <= 0)
+                               // incoming IP
+                               if (FD_ISSET(tunfd, &r))
                                {
                                {
-                                       LOG(0, 0, 0, "accept error: %s\n", strerror(errno));
-                                       continue;
+                                       if ((n = read(tunfd, buf, sizeof(buf))) > 0)
+                                       {
+                                               processtun(buf, n);
+                                       }
+                                       else
+                                       {
+                                               FD_CLR(tunfd, &r);
+                                               n--;
+                                       }
                                }
                                }
-                               else
+
+                               // cluster
+                               if (FD_ISSET(cluster_sockfd, &r))
                                {
                                {
-                                       cli_do(sockfd);
-                                       close(sockfd);
+                                       alen = sizeof(addr);
+                                       if ((s = recvfrom(cluster_sockfd, buf, sizeof(buf), MSG_WAITALL, (void *) &addr, &alen)) > 0)
+                                       {
+                                               processcluster(buf, s, addr.sin_addr.s_addr);
+                                       }
+                                       else
+                                       {
+                                               FD_CLR(cluster_sockfd, &r);
+                                               n--;
+                                       }
                                }
                        }
                }
                                }
                        }
                }
@@ -2444,15 +2486,6 @@ static void mainloop(void)
                                next_clean = time_now + config->cleanup_interval; // Did. Move to next interval.
                        }
                }
                                next_clean = time_now + config->cleanup_interval; // Did. Move to next interval.
                        }
                }
-
-#ifdef BGP
-               for (i = 0; i < BGP_NUM_PEERS; i++)
-               {
-                       bgp_process(&bgp_peers[i],
-                               bgp_set[i] ? FD_ISSET(bgp_peers[i].sock, &r) : 0,
-                               bgp_set[i] ? FD_ISSET(bgp_peers[i].sock, &w) : 0);
-               }
-#endif /* BGP */
        }
 
                // Are we the master and shutting down??
        }
 
                // Are we the master and shutting down??
@@ -3069,7 +3102,7 @@ int main(int argc, char *argv[])
                {
                        if ((ret = sched_setscheduler(0, SCHED_FIFO, &params)) == 0)
                        {
                {
                        if ((ret = sched_setscheduler(0, SCHED_FIFO, &params)) == 0)
                        {
-                               LOG(1, 0, 0, "Using FIFO scheduler. Say goodbye to any other processes running\n");
+                               LOG(1, 0, 0, "Using FIFO scheduler.  Say goodbye to any other processes running\n");
                        }
                        else
                        {
                        }
                        else
                        {
@@ -3612,11 +3645,11 @@ int sessionsetup(tunnelidt t, sessionidt s)
                assign_ip_address(s);
                if (!session[s].ip)
                {
                assign_ip_address(s);
                if (!session[s].ip)
                {
-                       LOG(0, s, t, "   No IP allocated. The IP address pool is FULL!\n");
+                       LOG(0, s, t, "   No IP allocated.  The IP address pool is FULL!\n");
                        sessionshutdown(s, "No IP addresses available");
                        return 0;
                }
                        sessionshutdown(s, "No IP addresses available");
                        return 0;
                }
-               LOG(3, s, t, "   No IP allocated. Assigned %s from pool\n",
+               LOG(3, s, t, "   No IP allocated.  Assigned %s from pool\n",
                        fmtaddr(htonl(session[s].ip), 0));
        }
 
                        fmtaddr(htonl(session[s].ip), 0));
        }