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.58 by root, Tue Feb 15 13:31:23 2011 UTC vs.
Revision 1.62 by root, Sat Dec 17 22:05:34 2011 UTC

147int 147int
148vpn::setup () 148vpn::setup ()
149{ 149{
150 int success = 0; 150 int success = 0;
151 151
152#if 1//D2
152 ipv4_tos = -1; 153 ipv42_tos = -1;
153 ipv4_fd = -1; 154 ipv42_fd = -1;
154 155
155 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 156 if (THISNODE->protocols & PROT_IPv42 && ::conf.ip_proto)
156 { 157 {
157 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto); 158 ipv42_fd = setup_socket (PROT_IPv42, PF_INET, SOCK_RAW, ::conf.ip2_proto);
158 159
159 if (ipv4_fd < 0) 160 if (ipv42_fd < 0)
160 return -1; 161 return -1;
161 162
162#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 163#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
163 // this I really consider a linux bug. I am neither connected 164 // this I really consider a linux bug. I am neither connected
164 // nor do I fragment myself. Linux still sets DF and doesn't 165 // nor do I fragment myself. Linux still sets DF and doesn't
165 // fragment for me sometimes. 166 // fragment for me sometimes.
166 { 167 {
167 int oval = IP_PMTUDISC_DONT; 168 int oval = IP_PMTUDISC_DONT;
168 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 169 setsockopt (ipv42_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
169 } 170 }
170#endif 171#endif
171 172
172 sockinfo si (THISNODE, PROT_IPv4); 173 sockinfo si (THISNODE, PROT_IPv42);
173 174
174 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 175 if (bind (ipv42_fd, si.sav4 (), si.salenv4 ()))
175 { 176 {
176 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno)); 177 slog (L_ERR, _("can't bind ipv42 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
177 return -1; 178 return -1;
178 } 179 }
179 180
180 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 181 ipv42_ev_watcher.start (ipv42_fd, EV_READ);
181 ++success; 182 ++success;
182 } 183 }
183 else 184 else
184 THISNODE->protocols &= ~PROT_IPv4; 185 THISNODE->protocols &= ~PROT_IPv42;
186#endif
185 187
186 udpv4_tos = -1; 188 ipv4_tos = -1;
187 udpv4_fd = -1; 189 ipv4_fd = -1;
188 190
189 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 191 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
190 { 192 {
191 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP); 193 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
192 194
193 if (udpv4_fd < 0) 195 if (ipv4_fd < 0)
194 return -1; 196 return -1;
195
196 // standard daemon practise...
197 {
198 int oval = 1;
199 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
200 }
201 197
202#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 198#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
203 // this I really consider a linux bug. I am neither connected 199 // this I really consider a linux bug. I am neither connected
204 // nor do I fragment myself. Linux still sets DF and doesn't 200 // nor do I fragment myself. Linux still sets DF and doesn't
205 // fragment for me sometimes. 201 // fragment for me sometimes.
206 { 202 {
207 int oval = IP_PMTUDISC_DONT; 203 int oval = IP_PMTUDISC_DONT;
204 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
205 }
206#endif
207
208 sockinfo si (THISNODE, PROT_IPv4);
209
210 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
211 {
212 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
213 return -1;
214 }
215
216 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
217 ++success;
218 }
219 else
220 THISNODE->protocols &= ~PROT_IPv4;
221
222 udpv4_tos = -1;
223 udpv4_fd = -1;
224
225 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
226 {
227 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
228
229 if (udpv4_fd < 0)
230 return -1;
231
232 // standard daemon practise...
233 {
234 int oval = 1;
235 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
236 }
237
238#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
239 // this I really consider a linux bug. I am neither connected
240 // nor do I fragment myself. Linux still sets DF and doesn't
241 // fragment for me sometimes.
242 {
243 int oval = IP_PMTUDISC_DONT;
208 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 244 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
209 } 245 }
210#endif 246#endif
211 247
212 sockinfo si (THISNODE, PROT_UDPv4); 248 sockinfo si (THISNODE, PROT_UDPv4);
399 set_tos (ipv4_fd, ipv4_tos, tos); 435 set_tos (ipv4_fd, ipv4_tos, tos);
400 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 436 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
401 437
402 return true; 438 return true;
403} 439}
440
441#if 1 //D
442bool
443vpn::send_ipv42_packet (vpn_packet *pkt, const sockinfo &si, int tos)
444{
445 set_tos (ipv42_fd, ipv42_tos, tos);
446 sendto (ipv42_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
447
448 return true;
449}
450#endif
404 451
405static u16 452static u16
406ipv4_checksum (u16 *data, unsigned int len) 453ipv4_checksum (u16 *data, unsigned int len)
407{ 454{
408 // use 32 bit accumulator and fold back carry bits at the end 455 // use 32 bit accumulator and fold back carry bits at the end
482 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 529 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
483 530
484 if (src == 0 || src > conns.size () 531 if (src == 0 || src > conns.size ()
485 || dst > conns.size () 532 || dst > conns.size ()
486 || pkt->typ () >= vpn_packet::PT_MAX) 533 || pkt->typ () >= vpn_packet::PT_MAX)
487 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
488 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
489 else if (dst > conns.size ())
490 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), 534 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
491 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 535 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
492 else 536 else
493 { 537 {
494 connection *c = conns[src - 1]; 538 connection *c = conns[src - 1];
515bool 559bool
516vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 560vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
517{ 561{
518 switch (si.prot) 562 switch (si.prot)
519 { 563 {
564#if 1//D2
565 case PROT_IPv42:
566 return send_ipv42_packet (pkt, si, tos);
567#endif
568
520 case PROT_IPv4: 569 case PROT_IPv4:
521 return send_ipv4_packet (pkt, si, tos); 570 return send_ipv4_packet (pkt, si, tos);
522 571
523 case PROT_UDPv4: 572 case PROT_UDPv4:
524 return send_udpv4_packet (pkt, si, tos); 573 return send_udpv4_packet (pkt, si, tos);
540 } 589 }
541 590
542 return false; 591 return false;
543} 592}
544 593
594#if 1//D2
545inline void 595inline void
546vpn::ipv4_ev (ev::io &w, int revents) 596vpn::ipv42_ev (ev::io &w, int revents)
547{ 597{
548 if (revents & EV_READ) 598 if (revents & EV_READ)
549 { 599 {
550 vpn_packet *pkt = new vpn_packet; 600 vpn_packet *pkt = new vpn_packet;
551 struct sockaddr_in sa; 601 struct sockaddr_in sa;
552 socklen_t sa_len = sizeof (sa); 602 socklen_t sa_len = sizeof (sa);
553 int len; 603 int len;
554 604
555 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 605 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
556 606
607 sockinfo si(sa, PROT_IPv42);
608
609 if (len > 0)
610 {
611 pkt->len = len;
612
613 // raw sockets deliver the ipv4 header, but don't expect it on sends
614 pkt->skip_hdr (pkt->ipv4_hdr_len ());
615
616 recv_vpn_packet (pkt, si);
617 }
618 else
619 {
620 // probably ECONNRESET or somesuch
621 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
622 }
623
624 delete pkt;
625 }
626 else
627 {
628 slog (L_ERR,
629 _("FATAL: unknown revents %08x in socket, exiting.\n"),
630 revents);
631 exit (EXIT_FAILURE);
632 }
633}
634#endif
635
636inline void
637vpn::ipv4_ev (ev::io &w, int revents)
638{
639 if (revents & EV_READ)
640 {
641 vpn_packet *pkt = new vpn_packet;
642 struct sockaddr_in sa;
643 socklen_t sa_len = sizeof (sa);
644 int len;
645
646 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
647
557 sockinfo si(sa, PROT_IPv4); 648 sockinfo si(sa, PROT_IPv4);
558 649
559 if (len > 0) 650 if (len > 0)
560 { 651 {
561 pkt->len = len; 652 pkt->len = len;
562 653
563 // raw sockets deliver the ipv4 header, but don't expect it on sends 654 // raw sockets deliver the ipv4 header, but don't expect it on sends
564 pkt->skip_hdr (IP_OVERHEAD); 655 pkt->skip_hdr (pkt->ipv4_hdr_len ());
565 656
566 recv_vpn_packet (pkt, si); 657 recv_vpn_packet (pkt, si);
567 } 658 }
568 else 659 else
569 { 660 {
606 if (hdr->type == ::conf.icmp_type 697 if (hdr->type == ::conf.icmp_type
607 && hdr->code == 255) 698 && hdr->code == 255)
608 { 699 {
609 // raw sockets deliver the ipv4, but don't expect it on sends 700 // raw sockets deliver the ipv4, but don't expect it on sends
610 // this is slow, but... 701 // this is slow, but...
611 pkt->skip_hdr (ICMP_OVERHEAD); 702 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
612 703
613 recv_vpn_packet (pkt, si); 704 recv_vpn_packet (pkt, si);
614 } 705 }
615 } 706 }
616 else 707 else
881vpn::vpn (void) 972vpn::vpn (void)
882{ 973{
883 event .set<vpn, &vpn::event_cb > (this); 974 event .set<vpn, &vpn::event_cb > (this);
884 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this); 975 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
885 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this); 976 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
977#if 1//D2
978 ipv42_ev_watcher .set<vpn, &vpn::ipv42_ev > (this);
979#endif
886#if ENABLE_TCP 980#if ENABLE_TCP
887 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this); 981 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
888#endif 982#endif
889#if ENABLE_ICMP 983#if ENABLE_ICMP
890 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this); 984 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines