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

Comparing gvpe/src/connection.C (file contents):
Revision 1.10 by pcg, Sun Apr 6 18:12:18 2003 UTC vs.
Revision 1.19 by pcg, Tue Oct 14 03:22:09 2003 UTC

35#include "slog.h" 35#include "slog.h"
36#include "device.h" 36#include "device.h"
37#include "vpn.h" 37#include "vpn.h"
38#include "connection.h" 38#include "connection.h"
39 39
40#include <sys/socket.h>
41#ifdef HAVE_NETINET_IN_H
42# include <netinet/in.h>
43#endif
44#include <arpa/inet.h>
45#include <net/if.h>
46#ifdef HAVE_NETINET_IN_SYSTM_H
47# include <netinet/in_systm.h>
48#endif
49#ifdef HAVE_NETINET_IP_H
50# include <netinet/ip.h>
51#endif
52
53#ifndef IPTOS_TOS_MASK
54# define IPTOS_TOS_MASK (IPTOS_LOWDELAY | IPTOS_THROUGHPUT | IPTOS_RELIABILITY | IPTOS_MINCOST)
55#endif
56
40#if !HAVE_RAND_PSEUDO_BYTES 57#if !HAVE_RAND_PSEUDO_BYTES
41# define RAND_pseudo_bytes RAND_bytes 58# define RAND_pseudo_bytes RAND_bytes
42#endif 59#endif
43 60
44#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic 61#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic
147 } 164 }
148} 165}
149 166
150////////////////////////////////////////////////////////////////////////////// 167//////////////////////////////////////////////////////////////////////////////
151 168
152void pkt_queue::put (tap_packet *p) 169void pkt_queue::put (net_packet *p)
153{ 170{
154 if (queue[i]) 171 if (queue[i])
155 { 172 {
156 delete queue[i]; 173 delete queue[i];
157 j = (j + 1) % QUEUEDEPTH; 174 j = (j + 1) % QUEUEDEPTH;
160 queue[i] = p; 177 queue[i] = p;
161 178
162 i = (i + 1) % QUEUEDEPTH; 179 i = (i + 1) % QUEUEDEPTH;
163} 180}
164 181
165tap_packet *pkt_queue::get () 182net_packet *pkt_queue::get ()
166{ 183{
167 tap_packet *p = queue[j]; 184 net_packet *p = queue[j];
168 185
169 if (p) 186 if (p)
170 { 187 {
171 queue[j] = 0; 188 queue[j] = 0;
172 j = (j + 1) % QUEUEDEPTH; 189 j = (j + 1) % QUEUEDEPTH;
197// only do action once every x seconds per host whole allowing bursts. 214// only do action once every x seconds per host whole allowing bursts.
198// this implementation ("splay list" ;) is inefficient, 215// this implementation ("splay list" ;) is inefficient,
199// but low on resources. 216// but low on resources.
200struct net_rate_limiter : list<net_rateinfo> 217struct net_rate_limiter : list<net_rateinfo>
201{ 218{
202 static const double ALPHA = 1. - 1. / 180.; // allow bursts 219 static const double ALPHA = 1. - 1. / 600.; // allow bursts
203 static const double CUTOFF = 10.; // one event every CUTOFF seconds 220 static const double CUTOFF = 10.; // one event every CUTOFF seconds
204 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time 221 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time
205 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value 222 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value
206 223
207 bool can (const sockinfo &si) { return can((u32)si.host); } 224 bool can (const sockinfo &si) { return can((u32)si.host); }
208 bool can (u32 host); 225 bool can (u32 host);
209}; 226};
210 227
211net_rate_limiter auth_rate_limiter, reset_rate_limiter; 228net_rate_limiter auth_rate_limiter, reset_rate_limiter;
212 229
475 set_hdr (type, dst); 492 set_hdr (type, dst);
476} 493}
477 494
478bool config_packet::chk_config () const 495bool config_packet::chk_config () const
479{ 496{
480 return prot_major == PROTOCOL_MAJOR 497 if (prot_major != PROTOCOL_MAJOR)
481 && randsize == RAND_SIZE 498 slog (L_WARN, _("major version mismatch (%d <=> %d)"), prot_major, PROTOCOL_MAJOR);
482 && hmaclen == HMACLENGTH 499 else if (randsize != RAND_SIZE)
483 && flags == curflags () 500 slog (L_WARN, _("rand size mismatch (%d <=> %d)"), randsize, RAND_SIZE);
501 else if (hmaclen != HMACLENGTH)
502 slog (L_WARN, _("hmac length mismatch (%d <=> %d)"), hmaclen, HMACLENGTH);
503 else if (flags != curflags ())
504 slog (L_WARN, _("flag mismatch (%x <=> %x)"), flags, curflags ());
484 && challengelen == sizeof (rsachallenge) 505 else if (challengelen != sizeof (rsachallenge))
506 slog (L_WARN, _("challenge length mismatch (%d <=> %d)"), challengelen, sizeof (rsachallenge));
485 && cipher_nid == htonl (EVP_CIPHER_nid (CIPHER)) 507 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER)))
508 slog (L_WARN, _("cipher mismatch (%x <=> %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER));
486 && digest_nid == htonl (EVP_MD_type (RSA_HASH)) 509 else if (digest_nid != htonl (EVP_MD_type (RSA_HASH)))
510 slog (L_WARN, _("digest mismatch (%x <=> %x)"), ntohl (digest_nid), EVP_MD_type (RSA_HASH));
487 && hmac_nid == htonl (EVP_MD_type (DIGEST)); 511 else if (hmac_nid != htonl (EVP_MD_type (DIGEST)))
512 slog (L_WARN, _("hmac mismatch (%x <=> %x)"), ntohl (hmac_nid), EVP_MD_type (DIGEST));
513 else
514 return true;
515
516 return false;
488} 517}
489 518
490struct auth_req_packet : config_packet 519struct auth_req_packet : config_packet
491{ 520{
492 char magic[8]; 521 char magic[8];
565 rekey.start (NOW + ::conf.rekey); 594 rekey.start (NOW + ::conf.rekey);
566 keepalive.start (NOW + ::conf.keepalive); 595 keepalive.start (NOW + ::conf.keepalive);
567 596
568 // send queued packets 597 // send queued packets
569 if (ictx && octx) 598 if (ictx && octx)
599 {
570 while (tap_packet *p = queue.get ()) 600 while (tap_packet *p = (tap_packet *)data_queue.get ())
571 { 601 {
572 send_data_packet (p); 602 send_data_packet (p);
573 delete p; 603 delete p;
574 } 604 }
605
606 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ())
607 {
608 send_vpn_packet (p, si, IPTOS_RELIABILITY);
609 delete p;
610 }
611 }
575 } 612 }
576 else 613 else
577 { 614 {
578 retry_cnt = 0; 615 retry_cnt = 0;
579 establish_connection.start (NOW + 5); 616 establish_connection.start (NOW + 5);
783connection::send_data_packet (tap_packet *pkt, bool broadcast) 820connection::send_data_packet (tap_packet *pkt, bool broadcast)
784{ 821{
785 vpndata_packet *p = new vpndata_packet; 822 vpndata_packet *p = new vpndata_packet;
786 int tos = 0; 823 int tos = 0;
787 824
825 // I am not hilarious about peeking into packets, but so be it.
788 if (conf->inherit_tos 826 if (conf->inherit_tos
789 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP 827 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP
790 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4 828 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
791 tos = (*pkt)[15] & IPTOS_TOS_MASK; 829 tos = (*pkt)[15] & IPTOS_TOS_MASK;
792 830
805 if (ictx && octx) 843 if (ictx && octx)
806 send_data_packet (pkt, broadcast); 844 send_data_packet (pkt, broadcast);
807 else 845 else
808 { 846 {
809 if (!broadcast)//DDDD 847 if (!broadcast)//DDDD
810 queue.put (new tap_packet (*pkt)); 848 data_queue.put (new tap_packet (*pkt));
811 849
812 establish_connection (); 850 establish_connection ();
813 } 851 }
814} 852}
815 853
816void connection::inject_vpn_packet (vpn_packet *pkt, int tos) 854void connection::inject_vpn_packet (vpn_packet *pkt, int tos)
817{ 855{
818 if (ictx && octx) 856 if (ictx && octx)
819 send_vpn_packet (pkt, si, tos); 857 send_vpn_packet (pkt, si, tos);
820 else 858 else
859 {
860 vpn_queue.put (new vpn_packet (*pkt));
861
821 establish_connection (); 862 establish_connection ();
863 }
822} 864}
823 865
824void 866void
825connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 867connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
826{ 868{
885 rsachallenge k; 927 rsachallenge k;
886 928
887 if (0 > RSA_private_decrypt (sizeof (p->encr), 929 if (0 > RSA_private_decrypt (sizeof (p->encr),
888 (unsigned char *)&p->encr, (unsigned char *)&k, 930 (unsigned char *)&p->encr, (unsigned char *)&k,
889 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING)) 931 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
890 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 932 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
891 conf->nodename, (const char *)rsi); 933 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
892 else 934 else
893 { 935 {
894 delete octx; 936 delete octx;
895 937
896 octx = new crypto_ctx (k, 1); 938 octx = new crypto_ctx (k, 1);
903 connection_established (); 945 connection_established ();
904 946
905 break; 947 break;
906 } 948 }
907 } 949 }
950 else
951 slog (L_WARN, _("%s(%s): protocol mismatch"),
952 conf->nodename, (const char *)rsi);
908 953
909 send_reset (rsi); 954 send_reset (rsi);
910 } 955 }
911 956
912 break; 957 break;
925 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 970 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
926 971
927 rsachallenge chg; 972 rsachallenge chg;
928 973
929 if (!rsa_cache.find (p->id, chg)) 974 if (!rsa_cache.find (p->id, chg))
975 {
930 slog (L_ERR, _("%s(%s): unrequested auth response"), 976 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
931 conf->nodename, (const char *)rsi); 977 conf->nodename, (const char *)rsi);
978 break;
979 }
932 else 980 else
933 { 981 {
934 crypto_ctx *cctx = new crypto_ctx (chg, 0); 982 crypto_ctx *cctx = new crypto_ctx (chg, 0);
935 983
936 if (!p->hmac_chk (cctx)) 984 if (!p->hmac_chk (cctx))
985 {
937 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 986 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n"
938 "could be an attack, or just corruption or an synchronization error"), 987 "could be an attack, or just corruption or an synchronization error"),
939 conf->nodename, (const char *)rsi); 988 conf->nodename, (const char *)rsi);
989 break;
990 }
940 else 991 else
941 { 992 {
942 rsaresponse h; 993 rsaresponse h;
943 994
944 rsa_hash (p->id, chg, h); 995 rsa_hash (p->id, chg, h);
1012 c->inject_data_packet (d); 1063 c->inject_data_packet (d);
1013 } 1064 }
1014 1065
1015 if (si != rsi) 1066 if (si != rsi)
1016 { 1067 {
1017 // fast re-sync on conneciton changes, useful especially for tcp/ip 1068 // fast re-sync on connection changes, useful especially for tcp/ip
1018 si = rsi; 1069 si = rsi;
1019 1070
1020 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1071 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1021 conf->nodename, (const char *)si, (const char *)rsi); 1072 conf->nodename, (const char *)si, (const char *)rsi);
1022 } 1073 }
1048 // send connect_info packets to both sides, in case one is 1099 // send connect_info packets to both sides, in case one is
1049 // behind a nat firewall (or both ;) 1100 // behind a nat firewall (or both ;)
1050 c->send_connect_info (conf->id, si, conf->protocols); 1101 c->send_connect_info (conf->id, si, conf->protocols);
1051 send_connect_info (c->conf->id, c->si, c->conf->protocols); 1102 send_connect_info (c->conf->id, c->si, c->conf->protocols);
1052 } 1103 }
1104 else
1105 c->establish_connection ();
1053 } 1106 }
1054 1107
1055 break; 1108 break;
1056 1109
1057 case vpn_packet::PT_CONNECT_INFO: 1110 case vpn_packet::PT_CONNECT_INFO:
1097 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1150 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1098 { 1151 {
1099 send_ping (si); 1152 send_ping (si);
1100 w.at = NOW + 5; 1153 w.at = NOW + 5;
1101 } 1154 }
1155 else if (NOW < last_activity + ::conf.keepalive + 10)
1156 // hold ondemand connections implicitly a few seconds longer
1157 // should delete octx, though, or something like that ;)
1158 w.at = last_activity + ::conf.keepalive + 10;
1102 else 1159 else
1103 reset_connection (); 1160 reset_connection ();
1104} 1161}
1105 1162
1106void connection::send_connect_request (int id) 1163void connection::send_connect_request (int id)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines