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.57 by root, Tue Feb 8 23:13:48 2011 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 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
141 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
142#endif
143
144 return fd;
145}
146
147int
125vpn::setup () 148vpn::setup ()
126{ 149{
127 int success = 0; 150 int success = 0;
128 151
129 ipv4_tos = -1; 152 ipv4_tos = -1;
130 ipv4_fd = -1; 153 ipv4_fd = -1;
131 154
132 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 155 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
133 { 156 {
134 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 157 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
135 158
136 if (ipv4_fd < 0) 159 if (ipv4_fd < 0)
137 return -1; 160 return -1;
138
139 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
140 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
141 161
142#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 162#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
143 // this I really consider a linux bug. I am neither connected 163 // this I really consider a linux bug. I am neither connected
144 // nor do I fragment myself. Linux still sets DF and doesn't 164 // nor do I fragment myself. Linux still sets DF and doesn't
145 // fragment for me sometimes. 165 // fragment for me sometimes.
152 sockinfo si (THISNODE, PROT_IPv4); 172 sockinfo si (THISNODE, PROT_IPv4);
153 173
154 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 174 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
155 { 175 {
156 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno)); 176 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
157 exit (EXIT_FAILURE); 177 return -1;
158 } 178 }
159 179
160 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 180 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
161 ++success; 181 ++success;
162 } 182 }
166 udpv4_tos = -1; 186 udpv4_tos = -1;
167 udpv4_fd = -1; 187 udpv4_fd = -1;
168 188
169 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 189 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
170 { 190 {
171 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 191 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
172 192
173 if (udpv4_fd < 0) 193 if (udpv4_fd < 0)
174 return -1; 194 return -1;
175
176 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
177 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
178 195
179 // standard daemon practise... 196 // standard daemon practise...
180 { 197 {
181 int oval = 1; 198 int oval = 1;
182 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 199 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
195 sockinfo si (THISNODE, PROT_UDPv4); 212 sockinfo si (THISNODE, PROT_UDPv4);
196 213
197 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 214 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
198 { 215 {
199 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 216 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
200 exit (EXIT_FAILURE); 217 return -1;
201 } 218 }
202 219
203 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 220 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
204 ++success; 221 ++success;
205 } 222 }
210 icmpv4_fd = -1; 227 icmpv4_fd = -1;
211 228
212#if ENABLE_ICMP 229#if ENABLE_ICMP
213 if (THISNODE->protocols & PROT_ICMPv4) 230 if (THISNODE->protocols & PROT_ICMPv4)
214 { 231 {
215 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 232 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
216 233
217 if (icmpv4_fd < 0) 234 if (icmpv4_fd < 0)
218 return -1; 235 return -1;
219
220 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
221 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
222 236
223#ifdef ICMP_FILTER 237#ifdef ICMP_FILTER
224 { 238 {
225 icmp_filter oval; 239 icmp_filter oval;
226 oval.data = 0xffffffff; 240 oval.data = 0xffffffff;
244 sockinfo si (THISNODE, PROT_ICMPv4); 258 sockinfo si (THISNODE, PROT_ICMPv4);
245 259
246 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 260 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
247 { 261 {
248 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 262 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
249 exit (EXIT_FAILURE); 263 return -1;
250 } 264 }
251 265
252 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 266 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
253 ++success; 267 ++success;
254 } 268 }
257 tcpv4_fd = -1; 271 tcpv4_fd = -1;
258 272
259#if ENABLE_TCP 273#if ENABLE_TCP
260 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 274 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
261 { 275 {
262 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 276 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
263 277
264 if (tcpv4_fd < 0) 278 if (tcpv4_fd < 0)
265 return -1; 279 return -1;
266
267 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
268 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
269 280
270 // standard daemon practise... 281 // standard daemon practise...
271 { 282 {
272 int oval = 1; 283 int oval = 1;
273 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 284 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
276 sockinfo si (THISNODE, PROT_TCPv4); 287 sockinfo si (THISNODE, PROT_TCPv4);
277 288
278 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 289 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
279 { 290 {
280 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 291 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
281 exit (EXIT_FAILURE); 292 return -1;
282 } 293 }
283 294
284 if (listen (tcpv4_fd, 5)) 295 if (listen (tcpv4_fd, 5))
285 { 296 {
286 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 297 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
287 exit (EXIT_FAILURE); 298 return -1;
288 } 299 }
289 300
290 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 301 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
291 ++success; 302 ++success;
292 } 303 }
300#if ENABLE_DNS 311#if ENABLE_DNS
301 if (THISNODE->protocols & PROT_DNSv4) 312 if (THISNODE->protocols & PROT_DNSv4)
302 { 313 {
303 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 314 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
304 315
305 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 316 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
306 317
307 if (dnsv4_fd < 0) 318 if (dnsv4_fd < 0)
308 return -1; 319 return -1;
309
310 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
311 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
312 320
313# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 321# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
314 // this I really consider a linux bug. I am neither connected 322 // this I really consider a linux bug. I am neither connected
315 // nor do I fragment myself. Linux still sets DF and doesn't 323 // nor do I fragment myself. Linux still sets DF and doesn't
316 // fragment for me sometimes. 324 // fragment for me sometimes.
331 PROT_DNSv4); 339 PROT_DNSv4);
332 340
333 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 341 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
334 { 342 {
335 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 343 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
336 exit (EXIT_FAILURE); 344 return -1;
337 } 345 }
338 346
339 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 347 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
340 ++success; 348 ++success;
341 } 349 }
343 351
344 ///////////////////////////////////////////////////////////////////////////// 352 /////////////////////////////////////////////////////////////////////////////
345 353
346 if (!success) 354 if (!success)
347 { 355 {
348 slog (L_ERR, _("no protocols enabled, exiting.")); 356 slog (L_ERR, _("no protocols enabled."));
349 exit (EXIT_FAILURE); 357 return -1;
350 } 358 }
351 359
352 reconnect_all (); 360 reconnect_all ();
353 361
354 ///////////////////////////////////////////////////////////////////////////// 362 /////////////////////////////////////////////////////////////////////////////
355 363
356 tap = new tap_device (); 364 tap = new tap_device ();
357 if (!tap) //D this, of course, never catches 365 if (!tap) //D this, of course, never catches
358 { 366 {
359 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname); 367 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
360 exit (EXIT_FAILURE); 368 return -1;
361 } 369 }
362 370
363 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 371 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
364 372
365 run_script_cb cb; 373 run_script_cb cb;
366 cb.set<vpn, &vpn::script_if_init> (this); 374 cb.set<vpn, &vpn::script_if_init> (this);
367 375
368 if (tap->if_up () && 376 if (tap->if_up () &&
369 !run_script (cb, true)) 377 !run_script (cb, true))
370 { 378 {
371 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 379 slog (L_ERR, _("interface initialization command '%s' failed."),
372 tap->if_up ()); 380 tap->if_up ());
373 exit (EXIT_FAILURE); 381 return -1;
374 } 382 }
375 383
376 cb.set<vpn, &vpn::script_if_up> (this); 384 cb.set<vpn, &vpn::script_if_up> (this);
377 if (!run_script (cb, true)) 385 if (!run_script (cb, true))
378 { 386 {
379 slog (L_ERR, _("if-up command execution failed, exiting.")); 387 slog (L_ERR, _("if-up command execution failed."));
380 exit (EXIT_FAILURE); 388 return -1;
381 } 389 }
382 390
383 tap_ev_watcher.start (tap->fd, EV_READ); 391 tap_ev_watcher.start (tap->fd, EV_READ);
384 392
385 return 0; 393 return 0;
513 return send_ipv4_packet (pkt, si, tos); 521 return send_ipv4_packet (pkt, si, tos);
514 522
515 case PROT_UDPv4: 523 case PROT_UDPv4:
516 return send_udpv4_packet (pkt, si, tos); 524 return send_udpv4_packet (pkt, si, tos);
517 525
518#if ENABLE_TCP 526#if ENABLE_TCP
519 case PROT_TCPv4: 527 case PROT_TCPv4:
520 return send_tcpv4_packet (pkt, si, tos); 528 return send_tcpv4_packet (pkt, si, tos);
521#endif 529#endif
522#if ENABLE_ICMP 530#if ENABLE_ICMP
523 case PROT_ICMPv4: 531 case PROT_ICMPv4:
750 758
751 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 759 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
752 (*c)->establish_connection (); 760 (*c)->establish_connection ();
753} 761}
754 762
763bool
755bool vpn::can_direct (conf_node *src, conf_node *dst) const 764vpn::can_direct (conf_node *src, conf_node *dst) const
756{ 765{
757 return src != dst 766 return src != dst
758 && src->may_direct (dst) 767 && src->may_direct (dst)
759 && dst->may_direct (src) 768 && dst->may_direct (src)
760 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS) 769 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
761 || (src->protocols & dst->connectable_protocols ())); 770 || (src->protocols & dst->connectable_protocols ()));
762} 771}
763 772
764// only works for indirect and routed connections: find a router 773// only works for indirect and routed connections: find a router
765// from THISNODE to dst 774// from THISNODE to dst
775connection *
766connection *vpn::find_router_for (const connection *dst) 776vpn::find_router_for (const connection *dst)
767{ 777{
768 connection *router = 0; 778 connection *router = 0;
769 779
770 // first try to find a router with a direct connection, route there 780 // first try to find a router with a direct connection, route there
771 // regardless of any other considerations. 781 // regardless of any other considerations.
810 } 820 }
811 821
812 return router; 822 return router;
813} 823}
814 824
825void
815void vpn::connection_established (connection *c) 826vpn::connection_established (connection *c)
816{ 827{
817 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 828 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
818 { 829 {
819 connection *o = *i; 830 connection *o = *i;
820 831
828 o->rekey (); 839 o->rekey ();
829 } 840 }
830 } 841 }
831} 842}
832 843
844void
833void vpn::send_connect_request (connection *c) 845vpn::send_connect_request (connection *c)
834{ 846{
835 connection *r = find_router_for (c); 847 connection *r = find_router_for (c);
836 848
837 if (r) 849 if (r)
838 { 850 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines