Updated UniK olsrd to olsr.org in licence headers
[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
23
24 #include "socket_parser.h"
25 #include "olsr.h"
26 #include "defs.h"
27
28 #ifdef WIN32
29 #undef EINTR
30 #define EINTR WSAEINTR
31 #undef errno
32 #define errno WSAGetLastError()
33 #undef strerror
34 #define strerror(x) StrError(x)
35 #endif
36
37 int changes_sockets;
38
39 /**
40  * Add a socket and handler to the socketset
41  * beeing used in the main select(2) loop
42  * in listen_loop
43  *
44  *@param fd the socket
45  *@param pf the processing function
46  */
47 void
48 add_olsr_socket(int fd, void(*pf)(int))
49 {
50   struct olsr_socket_entry *new_entry;
51
52   if((fd == 0) || (pf == NULL))
53     {
54       fprintf(stderr, "Bogus socket entry - not registering...\n");
55       return;
56     }
57   olsr_printf(1, "Adding OLSR socket entry %d\n", fd);
58
59   new_entry = olsr_malloc(sizeof(struct olsr_socket_entry), "Socket entry");
60
61   new_entry->fd = fd;
62   new_entry->process_function = pf;
63
64   changes_sockets = 1;
65
66   /* Queue */
67   new_entry->next = olsr_socket_entries;
68   olsr_socket_entries = new_entry;
69 }
70
71 /**
72  * Remove a socket and handler to the socketset
73  * beeing used in the main select(2) loop
74  * in listen_loop
75  *
76  *@param fd the socket
77  *@param pf the processing function
78  */
79 int
80 remove_olsr_socket(int fd, void(*pf)(int))
81 {
82   struct olsr_socket_entry *entry, *prev_entry;
83
84   if((fd == 0) || (pf == NULL))
85     {
86       olsr_syslog(OLSR_LOG_ERR, "Bogus socket entry - not processing...\n");
87       return 0;
88     }
89   olsr_printf(1, "Removing OLSR socket entry %d\n", fd);
90
91   entry = olsr_socket_entries;
92   prev_entry = NULL;
93
94   while(entry)
95     {
96       if((entry->fd == fd) && (entry->process_function == pf))
97         {
98           if(prev_entry == NULL)
99             {
100               olsr_socket_entries = entry->next;
101               free(entry);
102               changes_sockets = 1;
103             }
104           else
105             {
106               prev_entry->next = entry->next;
107               free(entry);
108               changes_sockets = 1;
109             }
110           return 1;
111         }
112       prev_entry = entry;
113       entry = entry->next;
114     }
115
116   return 0;
117 }
118
119
120
121
122
123 void
124 listen_loop()
125 {
126   fd_set ibits;
127   int hfd, n;
128   struct olsr_socket_entry *olsr_sockets;
129   struct timeval tvp;
130
131   FD_ZERO(&ibits);
132
133   /*
134    *Find highest FD
135    */
136   hfd = 0;
137
138   changes_sockets = 0;
139
140   /* Begin critical section */
141   pthread_mutex_lock(&mutex);
142
143   olsr_sockets = olsr_socket_entries;
144
145   olsr_printf(3, "SOCKETS: ");
146
147   while(olsr_sockets)
148     {
149       olsr_printf(3, "%d ", olsr_sockets->fd);
150       if((olsr_sockets->fd + 1) > hfd)
151         hfd = olsr_sockets->fd + 1;
152       olsr_sockets = olsr_sockets->next;
153     }
154   /* End critical section */
155   pthread_mutex_unlock(&mutex);
156   olsr_printf(3, "\n");
157
158   /* Main listening loop */
159   for (;;)
160     {
161       FD_ZERO(&ibits);
162       /* Adding file-descriptors to FD set */
163       /* Begin critical section */
164       pthread_mutex_lock(&mutex);
165       olsr_sockets = olsr_socket_entries;
166       while(olsr_sockets)
167         {
168           FD_SET(olsr_sockets->fd, &ibits);
169           olsr_sockets = olsr_sockets->next;
170         }
171       /* End critical section */
172       pthread_mutex_unlock(&mutex);
173
174       if(changes_sockets)
175         {
176           hfd = 0;
177           olsr_printf(3, "Recalculating hfd\n");
178           /* Begin critical section */
179           pthread_mutex_lock(&mutex);
180           olsr_sockets = olsr_socket_entries;
181
182           /* Recalculate highest FD */    
183           while(olsr_sockets)
184             {
185               if((olsr_sockets->fd + 1) > hfd)
186                 hfd = olsr_sockets->fd + 1;
187               olsr_sockets = olsr_sockets->next;
188             }
189           /* End critical section */
190           pthread_mutex_unlock(&mutex);
191           changes_sockets = 0;
192         }
193
194
195       /* If there are no registered sockets we
196        * do not call select(2)
197        */
198       if (hfd == 0)
199         {
200           sleep(OLSR_SELECT_TIMEOUT);
201           continue;
202         }
203
204       /* Add timeout to ensure update */
205       tvp.tv_sec = OLSR_SELECT_TIMEOUT;
206       tvp.tv_usec = 0;
207       
208       /* Runnig select on the FD set */
209       n = select(hfd, &ibits, 0, 0, &tvp);
210       
211       /* Did somethig go wrong? */
212       if (n <= 0) 
213         {
214           if (n < 0) 
215             {
216               if (errno == EINTR)
217                 continue;
218               olsr_syslog(OLSR_LOG_ERR, "select: %m");
219               olsr_printf(1, "Error select: %s", strerror(errno));
220             }
221           continue;
222         }
223
224       gettimeofday(&now, NULL);      
225       
226       /* Begin critical section */
227       pthread_mutex_lock(&mutex);
228       olsr_sockets = olsr_socket_entries;
229       while(olsr_sockets)
230         {
231           if(FD_ISSET(olsr_sockets->fd, &ibits))
232             {
233               olsr_sockets->process_function(olsr_sockets->fd);
234             }
235           olsr_sockets = olsr_sockets->next;
236         }
237       /* End critical section */
238       pthread_mutex_unlock(&mutex);
239   
240
241     } /* for(;;) */
242         
243 } /* main */
244
245
246