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.11 by pcg, Sun Apr 13 00:35:46 2003 UTC vs.
Revision 1.20 by pcg, Tue Oct 14 15:48:15 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 "netcompat.h"
41
40#if !HAVE_RAND_PSEUDO_BYTES 42#if !HAVE_RAND_PSEUDO_BYTES
41# define RAND_pseudo_bytes RAND_bytes 43# define RAND_pseudo_bytes RAND_bytes
42#endif 44#endif
43 45
44#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic 46#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic
147 } 149 }
148} 150}
149 151
150////////////////////////////////////////////////////////////////////////////// 152//////////////////////////////////////////////////////////////////////////////
151 153
152void pkt_queue::put (tap_packet *p) 154void pkt_queue::put (net_packet *p)
153{ 155{
154 if (queue[i]) 156 if (queue[i])
155 { 157 {
156 delete queue[i]; 158 delete queue[i];
157 j = (j + 1) % QUEUEDEPTH; 159 j = (j + 1) % QUEUEDEPTH;
160 queue[i] = p; 162 queue[i] = p;
161 163
162 i = (i + 1) % QUEUEDEPTH; 164 i = (i + 1) % QUEUEDEPTH;
163} 165}
164 166
165tap_packet *pkt_queue::get () 167net_packet *pkt_queue::get ()
166{ 168{
167 tap_packet *p = queue[j]; 169 net_packet *p = queue[j];
168 170
169 if (p) 171 if (p)
170 { 172 {
171 queue[j] = 0; 173 queue[j] = 0;
172 j = (j + 1) % QUEUEDEPTH; 174 j = (j + 1) % QUEUEDEPTH;
197// only do action once every x seconds per host whole allowing bursts. 199// only do action once every x seconds per host whole allowing bursts.
198// this implementation ("splay list" ;) is inefficient, 200// this implementation ("splay list" ;) is inefficient,
199// but low on resources. 201// but low on resources.
200struct net_rate_limiter : list<net_rateinfo> 202struct net_rate_limiter : list<net_rateinfo>
201{ 203{
202 static const double ALPHA = 1. - 1. / 180.; // allow bursts 204 static const double ALPHA = 1. - 1. / 600.; // allow bursts
203 static const double CUTOFF = 10.; // one event every CUTOFF seconds 205 static const double CUTOFF = 10.; // one event every CUTOFF seconds
204 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time 206 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time
205 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value 207 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value
206 208
207 bool can (const sockinfo &si) { return can((u32)si.host); } 209 bool can (const sockinfo &si) { return can((u32)si.host); }
208 bool can (u32 host); 210 bool can (u32 host);
209}; 211};
210 212
211net_rate_limiter auth_rate_limiter, reset_rate_limiter; 213net_rate_limiter auth_rate_limiter, reset_rate_limiter;
212 214
475 set_hdr (type, dst); 477 set_hdr (type, dst);
476} 478}
477 479
478bool config_packet::chk_config () const 480bool config_packet::chk_config () const
479{ 481{
480 return prot_major == PROTOCOL_MAJOR 482 if (prot_major != PROTOCOL_MAJOR)
481 && randsize == RAND_SIZE 483 slog (L_WARN, _("major version mismatch (%d <=> %d)"), prot_major, PROTOCOL_MAJOR);
482 && hmaclen == HMACLENGTH 484 else if (randsize != RAND_SIZE)
483 && flags == curflags () 485 slog (L_WARN, _("rand size mismatch (%d <=> %d)"), randsize, RAND_SIZE);
486 else if (hmaclen != HMACLENGTH)
487 slog (L_WARN, _("hmac length mismatch (%d <=> %d)"), hmaclen, HMACLENGTH);
488 else if (flags != curflags ())
489 slog (L_WARN, _("flag mismatch (%x <=> %x)"), flags, curflags ());
484 && challengelen == sizeof (rsachallenge) 490 else if (challengelen != sizeof (rsachallenge))
491 slog (L_WARN, _("challenge length mismatch (%d <=> %d)"), challengelen, sizeof (rsachallenge));
485 && cipher_nid == htonl (EVP_CIPHER_nid (CIPHER)) 492 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER)))
493 slog (L_WARN, _("cipher mismatch (%x <=> %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER));
486 && digest_nid == htonl (EVP_MD_type (RSA_HASH)) 494 else if (digest_nid != htonl (EVP_MD_type (RSA_HASH)))
495 slog (L_WARN, _("digest mismatch (%x <=> %x)"), ntohl (digest_nid), EVP_MD_type (RSA_HASH));
487 && hmac_nid == htonl (EVP_MD_type (DIGEST)); 496 else if (hmac_nid != htonl (EVP_MD_type (DIGEST)))
497 slog (L_WARN, _("hmac mismatch (%x <=> %x)"), ntohl (hmac_nid), EVP_MD_type (DIGEST));
498 else
499 return true;
500
501 return false;
488} 502}
489 503
490struct auth_req_packet : config_packet 504struct auth_req_packet : config_packet
491{ 505{
492 char magic[8]; 506 char magic[8];
565 rekey.start (NOW + ::conf.rekey); 579 rekey.start (NOW + ::conf.rekey);
566 keepalive.start (NOW + ::conf.keepalive); 580 keepalive.start (NOW + ::conf.keepalive);
567 581
568 // send queued packets 582 // send queued packets
569 if (ictx && octx) 583 if (ictx && octx)
584 {
570 while (tap_packet *p = queue.get ()) 585 while (tap_packet *p = (tap_packet *)data_queue.get ())
571 { 586 {
572 send_data_packet (p); 587 send_data_packet (p);
573 delete p; 588 delete p;
574 } 589 }
590
591 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ())
592 {
593 send_vpn_packet (p, si, IPTOS_RELIABILITY);
594 delete p;
595 }
596 }
575 } 597 }
576 else 598 else
577 { 599 {
578 retry_cnt = 0; 600 retry_cnt = 0;
579 establish_connection.start (NOW + 5); 601 establish_connection.start (NOW + 5);
783connection::send_data_packet (tap_packet *pkt, bool broadcast) 805connection::send_data_packet (tap_packet *pkt, bool broadcast)
784{ 806{
785 vpndata_packet *p = new vpndata_packet; 807 vpndata_packet *p = new vpndata_packet;
786 int tos = 0; 808 int tos = 0;
787 809
810 // I am not hilarious about peeking into packets, but so be it.
788 if (conf->inherit_tos 811 if (conf->inherit_tos
789 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP 812 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP
790 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4 813 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
791 tos = (*pkt)[15] & IPTOS_TOS_MASK; 814 tos = (*pkt)[15] & IPTOS_TOS_MASK;
792 815
805 if (ictx && octx) 828 if (ictx && octx)
806 send_data_packet (pkt, broadcast); 829 send_data_packet (pkt, broadcast);
807 else 830 else
808 { 831 {
809 if (!broadcast)//DDDD 832 if (!broadcast)//DDDD
810 queue.put (new tap_packet (*pkt)); 833 data_queue.put (new tap_packet (*pkt));
811 834
812 establish_connection (); 835 establish_connection ();
813 } 836 }
814} 837}
815 838
816void connection::inject_vpn_packet (vpn_packet *pkt, int tos) 839void connection::inject_vpn_packet (vpn_packet *pkt, int tos)
817{ 840{
818 if (ictx && octx) 841 if (ictx && octx)
819 send_vpn_packet (pkt, si, tos); 842 send_vpn_packet (pkt, si, tos);
820 else 843 else
844 {
845 vpn_queue.put (new vpn_packet (*pkt));
846
821 establish_connection (); 847 establish_connection ();
848 }
822} 849}
823 850
824void 851void
825connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 852connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
826{ 853{
885 rsachallenge k; 912 rsachallenge k;
886 913
887 if (0 > RSA_private_decrypt (sizeof (p->encr), 914 if (0 > RSA_private_decrypt (sizeof (p->encr),
888 (unsigned char *)&p->encr, (unsigned char *)&k, 915 (unsigned char *)&p->encr, (unsigned char *)&k,
889 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING)) 916 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
890 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 917 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
891 conf->nodename, (const char *)rsi); 918 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
892 else 919 else
893 { 920 {
894 delete octx; 921 delete octx;
895 922
896 octx = new crypto_ctx (k, 1); 923 octx = new crypto_ctx (k, 1);
903 connection_established (); 930 connection_established ();
904 931
905 break; 932 break;
906 } 933 }
907 } 934 }
935 else
936 slog (L_WARN, _("%s(%s): protocol mismatch"),
937 conf->nodename, (const char *)rsi);
908 938
909 send_reset (rsi); 939 send_reset (rsi);
910 } 940 }
911 941
912 break; 942 break;
925 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 955 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
926 956
927 rsachallenge chg; 957 rsachallenge chg;
928 958
929 if (!rsa_cache.find (p->id, chg)) 959 if (!rsa_cache.find (p->id, chg))
960 {
930 slog (L_ERR, _("%s(%s): unrequested auth response"), 961 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
931 conf->nodename, (const char *)rsi); 962 conf->nodename, (const char *)rsi);
963 break;
964 }
932 else 965 else
933 { 966 {
934 crypto_ctx *cctx = new crypto_ctx (chg, 0); 967 crypto_ctx *cctx = new crypto_ctx (chg, 0);
935 968
936 if (!p->hmac_chk (cctx)) 969 if (!p->hmac_chk (cctx))
970 {
937 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 971 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"), 972 "could be an attack, or just corruption or an synchronization error"),
939 conf->nodename, (const char *)rsi); 973 conf->nodename, (const char *)rsi);
974 break;
975 }
940 else 976 else
941 { 977 {
942 rsaresponse h; 978 rsaresponse h;
943 979
944 rsa_hash (p->id, chg, h); 980 rsa_hash (p->id, chg, h);
1012 c->inject_data_packet (d); 1048 c->inject_data_packet (d);
1013 } 1049 }
1014 1050
1015 if (si != rsi) 1051 if (si != rsi)
1016 { 1052 {
1017 // fast re-sync on conneciton changes, useful especially for tcp/ip 1053 // fast re-sync on connection changes, useful especially for tcp/ip
1018 si = rsi; 1054 si = rsi;
1019 1055
1020 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1056 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1021 conf->nodename, (const char *)si, (const char *)rsi); 1057 conf->nodename, (const char *)si, (const char *)rsi);
1022 } 1058 }
1099 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1135 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1100 { 1136 {
1101 send_ping (si); 1137 send_ping (si);
1102 w.at = NOW + 5; 1138 w.at = NOW + 5;
1103 } 1139 }
1140 else if (NOW < last_activity + ::conf.keepalive + 10)
1141 // hold ondemand connections implicitly a few seconds longer
1142 // should delete octx, though, or something like that ;)
1143 w.at = last_activity + ::conf.keepalive + 10;
1104 else 1144 else
1105 reset_connection (); 1145 reset_connection ();
1106} 1146}
1107 1147
1108void connection::send_connect_request (int id) 1148void connection::send_connect_request (int id)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines