ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
(Generate patch)

Comparing gvpe/src/vpn.C (file contents):
Revision 1.53 by pcg, Fri Aug 15 17:50:10 2008 UTC vs.
Revision 1.54 by pcg, Mon Mar 23 15:22:00 2009 UTC

120 120
121 return filename; 121 return filename;
122} 122}
123 123
124int 124int
125vpn::setup_socket (u8 prot, int family, int type, int proto)
126{
127 int fd = socket (family, type, proto);
128
129 if (fd < 0)
130 {
131 slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno));
132 return fd;
133 }
134
135 fcntl (fd, F_SETFL, O_NONBLOCK);
136 fcntl (fd, F_SETFD, FD_CLOEXEC);
137
138#ifdef SO_MARK
139 if (::conf.nfmark)
140 setsockopt (ipv4_fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark);
141#endif
142
143 return fd;
144}
145
146int
125vpn::setup () 147vpn::setup ()
126{ 148{
127 int success = 0; 149 int success = 0;
128 150
129 ipv4_tos = -1; 151 ipv4_tos = -1;
130 ipv4_fd = -1; 152 ipv4_fd = -1;
131 153
132 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 154 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
133 { 155 {
134 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 156 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
135 157
136 if (ipv4_fd < 0) 158 if (ipv4_fd < 0)
137 return -1; 159 return -1;
138
139 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
140 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
141 160
142#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 161#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
143 // this I really consider a linux bug. I am neither connected 162 // this I really consider a linux bug. I am neither connected
144 // nor do I fragment myself. Linux still sets DF and doesn't 163 // nor do I fragment myself. Linux still sets DF and doesn't
145 // fragment for me sometimes. 164 // fragment for me sometimes.
152 sockinfo si (THISNODE, PROT_IPv4); 171 sockinfo si (THISNODE, PROT_IPv4);
153 172
154 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 173 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
155 { 174 {
156 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno)); 175 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
157 exit (EXIT_FAILURE); 176 return -1;
158 } 177 }
159 178
160 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 179 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
161 ++success; 180 ++success;
162 } 181 }
166 udpv4_tos = -1; 185 udpv4_tos = -1;
167 udpv4_fd = -1; 186 udpv4_fd = -1;
168 187
169 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 188 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
170 { 189 {
171 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 190 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
172 191
173 if (udpv4_fd < 0) 192 if (udpv4_fd < 0)
174 return -1; 193 return -1;
175
176 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
177 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
178 194
179 // standard daemon practise... 195 // standard daemon practise...
180 { 196 {
181 int oval = 1; 197 int oval = 1;
182 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 198 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
195 sockinfo si (THISNODE, PROT_UDPv4); 211 sockinfo si (THISNODE, PROT_UDPv4);
196 212
197 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 213 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
198 { 214 {
199 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 215 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
200 exit (EXIT_FAILURE); 216 return -1;
201 } 217 }
202 218
203 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 219 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
204 ++success; 220 ++success;
205 } 221 }
210 icmpv4_fd = -1; 226 icmpv4_fd = -1;
211 227
212#if ENABLE_ICMP 228#if ENABLE_ICMP
213 if (THISNODE->protocols & PROT_ICMPv4) 229 if (THISNODE->protocols & PROT_ICMPv4)
214 { 230 {
215 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 231 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
216 232
217 if (icmpv4_fd < 0) 233 if (icmpv4_fd < 0)
218 return -1; 234 return -1;
219
220 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
221 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
222 235
223#ifdef ICMP_FILTER 236#ifdef ICMP_FILTER
224 { 237 {
225 icmp_filter oval; 238 icmp_filter oval;
226 oval.data = 0xffffffff; 239 oval.data = 0xffffffff;
244 sockinfo si (THISNODE, PROT_ICMPv4); 257 sockinfo si (THISNODE, PROT_ICMPv4);
245 258
246 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 259 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
247 { 260 {
248 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 261 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
249 exit (EXIT_FAILURE); 262 return -1;
250 } 263 }
251 264
252 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 265 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
253 ++success; 266 ++success;
254 } 267 }
257 tcpv4_fd = -1; 270 tcpv4_fd = -1;
258 271
259#if ENABLE_TCP 272#if ENABLE_TCP
260 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 273 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
261 { 274 {
262 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 275 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
263 276
264 if (tcpv4_fd < 0) 277 if (tcpv4_fd < 0)
265 return -1; 278 return -1;
266 279
267 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
268 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
269
270 // standard daemon practise... 280 // standard daemon practise...
271 { 281 {
272 int oval = 1; 282 int oval = 1;
273 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 283 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
274 } 284 }
276 sockinfo si (THISNODE, PROT_TCPv4); 286 sockinfo si (THISNODE, PROT_TCPv4);
277 287
278 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 288 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
279 { 289 {
280 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 290 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
281 exit (EXIT_FAILURE); 291 return -1;
282 } 292 }
283 293
284 if (listen (tcpv4_fd, 5)) 294 if (listen (tcpv4_fd, 5))
285 { 295 {
286 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 296 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
287 exit (EXIT_FAILURE); 297 return -1;
288 } 298 }
289 299
290 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 300 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
291 ++success; 301 ++success;
292 } 302 }
300#if ENABLE_DNS 310#if ENABLE_DNS
301 if (THISNODE->protocols & PROT_DNSv4) 311 if (THISNODE->protocols & PROT_DNSv4)
302 { 312 {
303 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 313 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
304 314
305 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 315 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
306 316
307 if (dnsv4_fd < 0) 317 if (dnsv4_fd < 0)
308 return -1; 318 return -1;
309
310 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
311 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
312 319
313# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 320# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
314 // this I really consider a linux bug. I am neither connected 321 // this I really consider a linux bug. I am neither connected
315 // nor do I fragment myself. Linux still sets DF and doesn't 322 // nor do I fragment myself. Linux still sets DF and doesn't
316 // fragment for me sometimes. 323 // fragment for me sometimes.
331 PROT_DNSv4); 338 PROT_DNSv4);
332 339
333 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 340 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
334 { 341 {
335 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 342 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
336 exit (EXIT_FAILURE); 343 return -1;
337 } 344 }
338 345
339 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 346 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
340 ++success; 347 ++success;
341 } 348 }
343 350
344 ///////////////////////////////////////////////////////////////////////////// 351 /////////////////////////////////////////////////////////////////////////////
345 352
346 if (!success) 353 if (!success)
347 { 354 {
348 slog (L_ERR, _("no protocols enabled, exiting.")); 355 slog (L_ERR, _("no protocols enabled."));
349 exit (EXIT_FAILURE); 356 return -1;
350 } 357 }
351 358
352 reconnect_all (); 359 reconnect_all ();
353 360
354 ///////////////////////////////////////////////////////////////////////////// 361 /////////////////////////////////////////////////////////////////////////////
355 362
356 tap = new tap_device (); 363 tap = new tap_device ();
357 if (!tap) //D this, of course, never catches 364 if (!tap) //D this, of course, never catches
358 { 365 {
359 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname); 366 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
360 exit (EXIT_FAILURE); 367 return -1;
361 } 368 }
362 369
363 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 370 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
364 371
365 run_script_cb cb; 372 run_script_cb cb;
366 cb.set<vpn, &vpn::script_if_init> (this); 373 cb.set<vpn, &vpn::script_if_init> (this);
367 374
368 if (tap->if_up () && 375 if (tap->if_up () &&
369 !run_script (cb, true)) 376 !run_script (cb, true))
370 { 377 {
371 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 378 slog (L_ERR, _("interface initialization command '%s' failed."),
372 tap->if_up ()); 379 tap->if_up ());
373 exit (EXIT_FAILURE); 380 return -1;
374 } 381 }
375 382
376 cb.set<vpn, &vpn::script_if_up> (this); 383 cb.set<vpn, &vpn::script_if_up> (this);
377 if (!run_script (cb, true)) 384 if (!run_script (cb, true))
378 { 385 {
379 slog (L_ERR, _("if-up command execution failed, exiting.")); 386 slog (L_ERR, _("if-up command execution failed."));
380 exit (EXIT_FAILURE); 387 return -1;
381 } 388 }
382 389
383 tap_ev_watcher.start (tap->fd, EV_READ); 390 tap_ev_watcher.start (tap->fd, EV_READ);
384 391
385 return 0; 392 return 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines