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.1 by pcg, Wed Apr 2 03:25:17 2003 UTC vs.
Revision 1.6 by pcg, Sun Apr 6 04:17:36 2003 UTC

40#include "util.h" 40#include "util.h"
41#include "vpn.h" 41#include "vpn.h"
42 42
43///////////////////////////////////////////////////////////////////////////// 43/////////////////////////////////////////////////////////////////////////////
44 44
45const char *vpn::script_if_up (int) 45const char *vpn::script_if_up ()
46{ 46{
47 // the tunnel device mtu should be the physical mtu - overhead 47 // the tunnel device mtu should be the physical mtu - overhead
48 // the tricky part is rounding to the cipher key blocksize 48 // the tricky part is rounding to the cipher key blocksize
49 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; 49 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
50 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion 50 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
71} 71}
72 72
73int 73int
74vpn::setup () 74vpn::setup ()
75{ 75{
76 sockinfo si;
77
78 si.set (THISNODE);
79
80 udpv4_fd = -1; 76 udpv4_fd = -1;
81 77
82 if (THISNODE->protocols & PROT_UDPv4) 78 if (THISNODE->protocols & PROT_UDPv4)
83 { 79 {
84 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 80 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
85 81
86 if (udpv4_fd < 0) 82 if (udpv4_fd < 0)
87 return -1; 83 return -1;
88 84
85 // standard daemon practise...
86 {
87 int oval = 1;
88 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
89 }
90
91 sockinfo si (THISNODE, PROT_UDPv4);
92
89 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 93 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
90 { 94 {
91 slog (L_ERR, _("can't bind udpv4 to %s: %s"), (const char *)si, strerror (errno)); 95 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno));
92 exit (1); 96 exit (1);
93 } 97 }
94 98
95#ifdef IP_MTU_DISCOVER 99#ifdef IP_MTU_DISCOVER
96 // this I really consider a linux bug. I am neither connected 100 // this I really consider a linux bug. I am neither connected
100 int oval = IP_PMTUDISC_DONT; 104 int oval = IP_PMTUDISC_DONT;
101 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 105 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
102 } 106 }
103#endif 107#endif
104 108
105 // standard daemon practise...
106 {
107 int oval = 1;
108 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
109 }
110
111 udpv4_ev_watcher.start (udpv4_fd, POLLIN); 109 udpv4_ev_watcher.start (udpv4_fd, POLLIN);
112 } 110 }
113 111
114 ipv4_fd = -1; 112 ipv4_fd = -1;
115 if (THISNODE->protocols & PROT_IPv4) 113 if (THISNODE->protocols & PROT_IPv4)
117 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 115 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto);
118 116
119 if (ipv4_fd < 0) 117 if (ipv4_fd < 0)
120 return -1; 118 return -1;
121 119
120 sockinfo si (THISNODE, PROT_IPv4);
121
122 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 122 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
123 { 123 {
124 slog (L_ERR, _("can't bind ipv4 socket to %s: %s"), (const char *)si, strerror (errno)); 124 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno));
125 exit (1); 125 exit (1);
126 } 126 }
127 127
128#ifdef IP_MTU_DISCOVER 128#ifdef IP_MTU_DISCOVER
129 // this I really consider a linux bug. I am neither connected 129 // this I really consider a linux bug. I am neither connected
136#endif 136#endif
137 137
138 ipv4_ev_watcher.start (ipv4_fd, POLLIN); 138 ipv4_ev_watcher.start (ipv4_fd, POLLIN);
139 } 139 }
140 140
141#if ENABLE_TCP
142 if (THISNODE->protocols & PROT_TCPv4)
143 {
144 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
145
146 if (tcpv4_fd < 0)
147 return -1;
148
149 // standard daemon practise...
150 {
151 int oval = 1;
152 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
153 }
154
155 sockinfo si (THISNODE, PROT_TCPv4);
156
157 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
158 {
159 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno));
160 exit (1);
161 }
162
163 if (listen (tcpv4_fd, 5))
164 {
165 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno));
166 exit (1);
167 }
168
169 tcpv4_ev_watcher.start (tcpv4_fd, POLLIN);
170 }
171#endif
172
141 tap = new tap_device (); 173 tap = new tap_device ();
142 if (!tap) //D this, of course, never catches 174 if (!tap) //D this, of course, never catches
143 { 175 {
144 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 176 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname);
145 exit (1); 177 exit (1);
150 tap_ev_watcher.start (tap->fd, POLLIN); 182 tap_ev_watcher.start (tap->fd, POLLIN);
151 183
152 reconnect_all (); 184 reconnect_all ();
153 185
154 return 0; 186 return 0;
187}
188
189// send a vpn packet out to other hosts
190void
191vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
192{
193 switch (si.prot)
194 {
195 case PROT_IPv4:
196 send_ipv4_packet (pkt, si, tos);
197 break;
198
199 case PROT_UDPv4:
200 send_udpv4_packet (pkt, si, tos);
201 break;
202
203#if ENABLE_TCP
204 case PROT_TCPv4:
205 send_tcpv4_packet (pkt, si, tos);
206 break;
207#endif
208
209 default:
210 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si);
211 abort ();
212 }
155} 213}
156 214
157void 215void
158vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 216vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
159{ 217{
180 if (src == 0 || src > conns.size () 238 if (src == 0 || src > conns.size ()
181 || dst > conns.size () 239 || dst > conns.size ()
182 || pkt->typ () >= vpn_packet::PT_MAX) 240 || pkt->typ () >= vpn_packet::PT_MAX)
183 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 241 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
184 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 242 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
243 else if (dst > conns.size ())
244 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
245 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
185 else 246 else
186 { 247 {
187 connection *c = conns[src - 1]; 248 connection *c = conns[src - 1];
188 249
189 if (dst == 0 && !THISNODE->routerprio) 250 if (dst == 0 && !THISNODE->routerprio)
190 slog (L_WARN, _("%s(%s): received broadcast, but we are no router"), 251 slog (L_WARN, _("%s(%s): received broadcast, but we are no router"),
191 c->conf->nodename, (const char *)rsi); 252 c->conf->nodename, (const char *)rsi);
192 else if (dst != 0 && dst != THISNODE->id) 253 else if (dst != 0 && dst != THISNODE->id)
193 // FORWARDING NEEDED ;) 254 {
255 if (THISNODE->routerprio)
256 // the tos setting gets lost here. who cares.
257 conns[dst - 1]->inject_vpn_packet (pkt);
258 else
194 slog (L_WARN, 259 slog (L_WARN,
195 _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), 260 _("%s(%s): forwarding request (=> %s), but we are no router"),
261 c->conf->nodename, (const char *)rsi,
196 dst, conns[dst - 1]->conf->nodename, 262 conns[dst - 1]->conf->nodename);
197 (const char *)rsi, 263 }
198 THISNODE->id, THISNODE->nodename);
199 else 264 else
200 c->recv_vpn_packet (pkt, rsi); 265 c->recv_vpn_packet (pkt, rsi);
201 } 266 }
202} 267}
203 268
204void 269void
205vpn::udpv4_ev (short revents) 270vpn::udpv4_ev (io_watcher &w, short revents)
206{ 271{
207 if (revents & (POLLIN | POLLERR)) 272 if (revents & (POLLIN | POLLERR))
208 { 273 {
209 vpn_packet *pkt = new vpn_packet; 274 vpn_packet *pkt = new vpn_packet;
210 struct sockaddr_in sa; 275 struct sockaddr_in sa;
211 socklen_t sa_len = sizeof (sa); 276 socklen_t sa_len = sizeof (sa);
212 int len; 277 int len;
213 278
214 len = recvfrom (udpv4_fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 279 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
215 280
216 sockinfo si(sa); 281 sockinfo si(sa, PROT_UDPv4);
217 282
218 if (len > 0) 283 if (len > 0)
219 { 284 {
220 pkt->len = len; 285 pkt->len = len;
221 286
222 recv_vpn_packet (pkt, si); 287 recv_vpn_packet (pkt, si);
223 } 288 }
224 else 289 else
225 { 290 {
226 // probably ECONNRESET or somesuch 291 // probably ECONNRESET or somesuch
227 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 292 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno));
228 } 293 }
229 294
230 delete pkt; 295 delete pkt;
231 } 296 }
232 else if (revents & POLLHUP) 297 else if (revents & POLLHUP)
243 exit (1); 308 exit (1);
244 } 309 }
245} 310}
246 311
247void 312void
248vpn::ipv4_ev (short revents) 313vpn::ipv4_ev (io_watcher &w, short revents)
249{ 314{
250 if (revents & (POLLIN | POLLERR)) 315 if (revents & (POLLIN | POLLERR))
251 { 316 {
252 vpn_packet *pkt = new vpn_packet; 317 vpn_packet *pkt = new vpn_packet;
253 struct sockaddr_in sa; 318 struct sockaddr_in sa;
254 socklen_t sa_len = sizeof (sa); 319 socklen_t sa_len = sizeof (sa);
255 int len; 320 int len;
256 321
257 len = recvfrom (ipv4_fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 322 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
258 323
259 sockinfo si(sa, PROT_IPv4); 324 sockinfo si(sa, PROT_IPv4);
260 325
261 if (len > 0) 326 if (len > 0)
262 { 327 {
290 exit (1); 355 exit (1);
291 } 356 }
292} 357}
293 358
294void 359void
295vpn::tap_ev (short revents) 360vpn::tap_ev (io_watcher &w, short revents)
296{ 361{
297 if (revents & POLLIN) 362 if (revents & POLLIN)
298 { 363 {
299 /* process data */ 364 /* process data */
300 tap_packet *pkt; 365 tap_packet *pkt;
350 else 415 else
351 abort (); 416 abort ();
352} 417}
353 418
354void 419void
355vpn::event_cb (tstamp &ts) 420vpn::event_cb (time_watcher &w)
356{ 421{
357 if (events) 422 if (events)
358 { 423 {
359 if (events & EVENT_SHUTDOWN) 424 if (events & EVENT_SHUTDOWN)
360 { 425 {
377 } 442 }
378 443
379 events = 0; 444 events = 0;
380 } 445 }
381 446
382 ts = TSTAMP_CANCEL; 447 w.at = TSTAMP_CANCEL;
383} 448}
384 449
385void 450void
386vpn::shutdown_all () 451vpn::shutdown_all ()
387{ 452{
468 533
469 slog (L_NOTICE, _("END status dump")); 534 slog (L_NOTICE, _("END status dump"));
470} 535}
471 536
472vpn::vpn (void) 537vpn::vpn (void)
538: event(this, &vpn::event_cb)
473: udpv4_ev_watcher(this, &vpn::udpv4_ev) 539, udpv4_ev_watcher(this, &vpn::udpv4_ev)
474, ipv4_ev_watcher(this, &vpn::ipv4_ev) 540, ipv4_ev_watcher (this, &vpn::ipv4_ev)
475, tap_ev_watcher(this, &vpn::tap_ev) 541, tap_ev_watcher (this, &vpn::tap_ev)
476, event(this, &vpn::event_cb) 542#if ENABLE_TCP
543, tcpv4_ev_watcher(this, &vpn::tcpv4_ev)
544#endif
477{ 545{
478} 546}
479 547
480vpn::~vpn () 548vpn::~vpn ()
481{ 549{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines