New configfile parser and configuration scheme integrated
[olsrd.git] / src / socket_parser.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: socket_parser.c,v 1.8 2004/10/18 13:13:37 kattemat Exp $
23  *
24  */
25
26
27 #include "socket_parser.h"
28 #include "olsr.h"
29 #include "defs.h"
30
31 #ifdef WIN32
32 #undef EINTR
33 #define EINTR WSAEINTR
34 #undef errno
35 #define errno WSAGetLastError()
36 #undef strerror
37 #define strerror(x) StrError(x)
38 #endif
39
40 static int changes_sockets;
41
42 /**
43  * Add a socket and handler to the socketset
44  * beeing used in the main select(2) loop
45  * in listen_loop
46  *
47  *@param fd the socket
48  *@param pf the processing function
49  */
50 void
51 add_olsr_socket(int fd, void(*pf)(int))
52 {
53   struct olsr_socket_entry *new_entry;
54
55   if((fd == 0) || (pf == NULL))
56     {
57       fprintf(stderr, "Bogus socket entry - not registering...\n");
58       return;
59     }
60   olsr_printf(1, "Adding OLSR socket entry %d\n", fd);
61
62   new_entry = olsr_malloc(sizeof(struct olsr_socket_entry), "Socket entry");
63
64   new_entry->fd = fd;
65   new_entry->process_function = pf;
66
67   changes_sockets = 1;
68
69   /* Queue */
70   new_entry->next = olsr_socket_entries;
71   olsr_socket_entries = new_entry;
72 }
73
74 /**
75  * Remove a socket and handler to the socketset
76  * beeing used in the main select(2) loop
77  * in listen_loop
78  *
79  *@param fd the socket
80  *@param pf the processing function
81  */
82 int
83 remove_olsr_socket(int fd, void(*pf)(int))
84 {
85   struct olsr_socket_entry *entry, *prev_entry;
86
87   if((fd == 0) || (pf == NULL))
88     {
89       olsr_syslog(OLSR_LOG_ERR, "Bogus socket entry - not processing...\n");
90       return 0;
91     }
92   olsr_printf(1, "Removing OLSR socket entry %d\n", fd);
93
94   entry = olsr_socket_entries;
95   prev_entry = NULL;
96
97   while(entry)
98     {
99       if((entry->fd == fd) && (entry->process_function == pf))
100         {
101           if(prev_entry == NULL)
102             {
103               olsr_socket_entries = entry->next;
104               free(entry);
105               changes_sockets = 1;
106             }
107           else
108             {
109               prev_entry->next = entry->next;
110               free(entry);
111               changes_sockets = 1;
112             }
113           return 1;
114         }
115       prev_entry = entry;
116       entry = entry->next;
117     }
118
119   return 0;
120 }
121
122
123
124
125
126 void
127 listen_loop()
128 {
129   fd_set ibits;
130   int hfd, n;
131   struct olsr_socket_entry *olsr_sockets;
132   struct timeval tvp;
133
134   FD_ZERO(&ibits);
135
136   /*
137    *Find highest FD
138    */
139   hfd = 0;
140
141   changes_sockets = 0;
142
143   /* Begin critical section */
144   pthread_mutex_lock(&mutex);
145
146   olsr_sockets = olsr_socket_entries;
147
148   olsr_printf(3, "SOCKETS: ");
149
150   while(olsr_sockets)
151     {
152       olsr_printf(3, "%d ", olsr_sockets->fd);
153       if((olsr_sockets->fd + 1) > hfd)
154         hfd = olsr_sockets->fd + 1;
155       olsr_sockets = olsr_sockets->next;
156     }
157   /* End critical section */
158   pthread_mutex_unlock(&mutex);
159   olsr_printf(3, "\n");
160
161   /* Main listening loop */
162   for (;;)
163     {
164       FD_ZERO(&ibits);
165       /* Adding file-descriptors to FD set */
166       /* Begin critical section */
167       pthread_mutex_lock(&mutex);
168       olsr_sockets = olsr_socket_entries;
169       while(olsr_sockets)
170         {
171           FD_SET(olsr_sockets->fd, &ibits);
172           olsr_sockets = olsr_sockets->next;
173         }
174       /* End critical section */
175       pthread_mutex_unlock(&mutex);
176
177       if(changes_sockets)
178         {
179           hfd = 0;
180           olsr_printf(3, "Recalculating hfd\n");
181           /* Begin critical section */
182           pthread_mutex_lock(&mutex);
183           olsr_sockets = olsr_socket_entries;
184
185           /* Recalculate highest FD */    
186           while(olsr_sockets)
187             {
188               if((olsr_sockets->fd + 1) > hfd)
189                 hfd = olsr_sockets->fd + 1;
190               olsr_sockets = olsr_sockets->next;
191             }
192           /* End critical section */
193           pthread_mutex_unlock(&mutex);
194           changes_sockets = 0;
195         }
196
197
198       /* If there are no registered sockets we
199        * do not call select(2)
200        */
201       if (hfd == 0)
202         {
203           sleep(OLSR_SELECT_TIMEOUT);
204           continue;
205         }
206
207       /* Add timeout to ensure update */
208       tvp.tv_sec = OLSR_SELECT_TIMEOUT;
209       tvp.tv_usec = 0;
210       
211       /* Runnig select on the FD set */
212       n = select(hfd, &ibits, 0, 0, &tvp);
213       
214       /* Did somethig go wrong? */
215       if (n <= 0) 
216         {
217           if (n < 0) 
218             {
219               if (errno == EINTR)
220                 continue;
221               olsr_syslog(OLSR_LOG_ERR, "select: %m");
222               olsr_printf(1, "Error select: %s", strerror(errno));
223             }
224           continue;
225         }
226
227       gettimeofday(&now, NULL);      
228       
229       /* Begin critical section */
230       pthread_mutex_lock(&mutex);
231       olsr_sockets = olsr_socket_entries;
232       while(olsr_sockets)
233         {
234           if(FD_ISSET(olsr_sockets->fd, &ibits))
235             {
236               olsr_sockets->process_function(olsr_sockets->fd);
237             }
238           olsr_sockets = olsr_sockets->next;
239         }
240       /* End critical section */
241       pthread_mutex_unlock(&mutex);
242   
243
244     } /* for(;;) */
245         
246 } /* main */
247
248
249