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.23 by pcg, Wed Oct 22 00:42:53 2003 UTC

1/* 1/*
2 connection.C -- manage a single connection 2 connection.C -- manage a single connection
3 Copyright (C) 2003 Marc Lehmann <pcg@goof.com>
3 4
4 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version. 8 (at your option) any later version.
35#include "slog.h" 36#include "slog.h"
36#include "device.h" 37#include "device.h"
37#include "vpn.h" 38#include "vpn.h"
38#include "connection.h" 39#include "connection.h"
39 40
41#include "netcompat.h"
42
40#if !HAVE_RAND_PSEUDO_BYTES 43#if !HAVE_RAND_PSEUDO_BYTES
41# define RAND_pseudo_bytes RAND_bytes 44# define RAND_pseudo_bytes RAND_bytes
42#endif 45#endif
43 46
44#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic 47#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic
147 } 150 }
148} 151}
149 152
150////////////////////////////////////////////////////////////////////////////// 153//////////////////////////////////////////////////////////////////////////////
151 154
152void pkt_queue::put (tap_packet *p) 155void pkt_queue::put (net_packet *p)
153{ 156{
154 if (queue[i]) 157 if (queue[i])
155 { 158 {
156 delete queue[i]; 159 delete queue[i];
157 j = (j + 1) % QUEUEDEPTH; 160 j = (j + 1) % QUEUEDEPTH;
160 queue[i] = p; 163 queue[i] = p;
161 164
162 i = (i + 1) % QUEUEDEPTH; 165 i = (i + 1) % QUEUEDEPTH;
163} 166}
164 167
165tap_packet *pkt_queue::get () 168net_packet *pkt_queue::get ()
166{ 169{
167 tap_packet *p = queue[j]; 170 net_packet *p = queue[j];
168 171
169 if (p) 172 if (p)
170 { 173 {
171 queue[j] = 0; 174 queue[j] = 0;
172 j = (j + 1) % QUEUEDEPTH; 175 j = (j + 1) % QUEUEDEPTH;
197// only do action once every x seconds per host whole allowing bursts. 200// only do action once every x seconds per host whole allowing bursts.
198// this implementation ("splay list" ;) is inefficient, 201// this implementation ("splay list" ;) is inefficient,
199// but low on resources. 202// but low on resources.
200struct net_rate_limiter : list<net_rateinfo> 203struct net_rate_limiter : list<net_rateinfo>
201{ 204{
202 static const double ALPHA = 1. - 1. / 180.; // allow bursts 205 static const double ALPHA = 1. - 1. / 600.; // allow bursts
203 static const double CUTOFF = 10.; // one event every CUTOFF seconds 206 static const double CUTOFF = 10.; // one event every CUTOFF seconds
204 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time 207 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time
205 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value 208 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value
206 209
207 bool can (const sockinfo &si) { return can((u32)si.host); } 210 bool can (const sockinfo &si) { return can((u32)si.host); }
208 bool can (u32 host); 211 bool can (u32 host);
209}; 212};
210 213
211net_rate_limiter auth_rate_limiter, reset_rate_limiter; 214net_rate_limiter auth_rate_limiter, reset_rate_limiter;
212 215
475 set_hdr (type, dst); 478 set_hdr (type, dst);
476} 479}
477 480
478bool config_packet::chk_config () const 481bool config_packet::chk_config () const
479{ 482{
480 return prot_major == PROTOCOL_MAJOR 483 if (prot_major != PROTOCOL_MAJOR)
481 && randsize == RAND_SIZE 484 slog (L_WARN, _("major version mismatch (remote %d <=> local %d)"), prot_major, PROTOCOL_MAJOR);
482 && hmaclen == HMACLENGTH 485 else if (randsize != RAND_SIZE)
483 && flags == curflags () 486 slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE);
487 else if (hmaclen != HMACLENGTH)
488 slog (L_WARN, _("hmac length mismatch (remote %d <=> local %d)"), hmaclen, HMACLENGTH);
489 else if (flags != curflags ())
490 slog (L_WARN, _("flag mismatch (remote %x <=> local %x)"), flags, curflags ());
484 && challengelen == sizeof (rsachallenge) 491 else if (challengelen != sizeof (rsachallenge))
492 slog (L_WARN, _("challenge length mismatch (remote %d <=> local %d)"), challengelen, sizeof (rsachallenge));
485 && cipher_nid == htonl (EVP_CIPHER_nid (CIPHER)) 493 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER)))
494 slog (L_WARN, _("cipher mismatch (remote %x <=> local %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER));
486 && digest_nid == htonl (EVP_MD_type (RSA_HASH)) 495 else if (digest_nid != htonl (EVP_MD_type (RSA_HASH)))
496 slog (L_WARN, _("digest mismatch (remote %x <=> local %x)"), ntohl (digest_nid), EVP_MD_type (RSA_HASH));
487 && hmac_nid == htonl (EVP_MD_type (DIGEST)); 497 else if (hmac_nid != htonl (EVP_MD_type (DIGEST)))
498 slog (L_WARN, _("hmac mismatch (remote %x <=> local %x)"), ntohl (hmac_nid), EVP_MD_type (DIGEST));
499 else
500 return true;
501
502 return false;
488} 503}
489 504
490struct auth_req_packet : config_packet 505struct auth_req_packet : config_packet
491{ 506{
492 char magic[8]; 507 char magic[8];
565 rekey.start (NOW + ::conf.rekey); 580 rekey.start (NOW + ::conf.rekey);
566 keepalive.start (NOW + ::conf.keepalive); 581 keepalive.start (NOW + ::conf.keepalive);
567 582
568 // send queued packets 583 // send queued packets
569 if (ictx && octx) 584 if (ictx && octx)
585 {
570 while (tap_packet *p = queue.get ()) 586 while (tap_packet *p = (tap_packet *)data_queue.get ())
571 { 587 {
572 send_data_packet (p); 588 send_data_packet (p);
573 delete p; 589 delete p;
574 } 590 }
591
592 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ())
593 {
594 send_vpn_packet (p, si, IPTOS_RELIABILITY);
595 delete p;
596 }
597 }
575 } 598 }
576 else 599 else
577 { 600 {
578 retry_cnt = 0; 601 retry_cnt = 0;
579 establish_connection.start (NOW + 5); 602 establish_connection.start (NOW + 5);
778 reset_connection (); 801 reset_connection ();
779 establish_connection (); 802 establish_connection ();
780} 803}
781 804
782void 805void
783connection::send_data_packet (tap_packet *pkt, bool broadcast) 806connection::send_data_packet (tap_packet *pkt)
784{ 807{
785 vpndata_packet *p = new vpndata_packet; 808 vpndata_packet *p = new vpndata_packet;
786 int tos = 0; 809 int tos = 0;
787 810
788 if (conf->inherit_tos 811 // I am not hilarious about peeking into packets, but so be it.
789 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP 812 if (conf->inherit_tos && pkt->is_ipv4 ())
790 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
791 tos = (*pkt)[15] & IPTOS_TOS_MASK; 813 tos = (*pkt)[15] & IPTOS_TOS_MASK;
792 814
793 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs 815 p->setup (this, conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs
794 send_vpn_packet (p, si, tos); 816 send_vpn_packet (p, si, tos);
795 817
796 delete p; 818 delete p;
797 819
798 if (oseqno > MAX_SEQNO) 820 if (oseqno > MAX_SEQNO)
799 rekey (); 821 rekey ();
800} 822}
801 823
802void 824void
803connection::inject_data_packet (tap_packet *pkt, bool broadcast) 825connection::inject_data_packet (tap_packet *pkt, bool broadcast/*TODO DDD*/)
804{ 826{
805 if (ictx && octx) 827 if (ictx && octx)
806 send_data_packet (pkt, broadcast); 828 send_data_packet (pkt);
807 else 829 else
808 { 830 {
809 if (!broadcast)//DDDD 831 if (!broadcast)//DDDD
810 queue.put (new tap_packet (*pkt)); 832 data_queue.put (new tap_packet (*pkt));
811 833
812 establish_connection (); 834 establish_connection ();
813 } 835 }
814} 836}
815 837
816void connection::inject_vpn_packet (vpn_packet *pkt, int tos) 838void connection::inject_vpn_packet (vpn_packet *pkt, int tos)
817{ 839{
818 if (ictx && octx) 840 if (ictx && octx)
819 send_vpn_packet (pkt, si, tos); 841 send_vpn_packet (pkt, si, tos);
820 else 842 else
843 {
844 vpn_queue.put (new vpn_packet (*pkt));
845
821 establish_connection (); 846 establish_connection ();
847 }
822} 848}
823 849
824void 850void
825connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 851connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
826{ 852{
885 rsachallenge k; 911 rsachallenge k;
886 912
887 if (0 > RSA_private_decrypt (sizeof (p->encr), 913 if (0 > RSA_private_decrypt (sizeof (p->encr),
888 (unsigned char *)&p->encr, (unsigned char *)&k, 914 (unsigned char *)&p->encr, (unsigned char *)&k,
889 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING)) 915 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
916 {
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));
919 break;
920 }
892 else 921 else
893 { 922 {
894 delete octx; 923 delete octx;
895 924
896 octx = new crypto_ctx (k, 1); 925 octx = new crypto_ctx (k, 1);
903 connection_established (); 932 connection_established ();
904 933
905 break; 934 break;
906 } 935 }
907 } 936 }
937 else
938 slog (L_WARN, _("%s(%s): protocol mismatch"),
939 conf->nodename, (const char *)rsi);
908 940
909 send_reset (rsi); 941 send_reset (rsi);
910 } 942 }
911 943
912 break; 944 break;
925 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 957 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
926 958
927 rsachallenge chg; 959 rsachallenge chg;
928 960
929 if (!rsa_cache.find (p->id, chg)) 961 if (!rsa_cache.find (p->id, chg))
962 {
930 slog (L_ERR, _("%s(%s): unrequested auth response"), 963 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
931 conf->nodename, (const char *)rsi); 964 conf->nodename, (const char *)rsi);
965 break;
966 }
932 else 967 else
933 { 968 {
934 crypto_ctx *cctx = new crypto_ctx (chg, 0); 969 crypto_ctx *cctx = new crypto_ctx (chg, 0);
935 970
936 if (!p->hmac_chk (cctx)) 971 if (!p->hmac_chk (cctx))
972 {
937 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 973 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"), 974 "could be an attack, or just corruption or an synchronization error"),
939 conf->nodename, (const char *)rsi); 975 conf->nodename, (const char *)rsi);
976 break;
977 }
940 else 978 else
941 { 979 {
942 rsaresponse h; 980 rsaresponse h;
943 981
944 rsa_hash (p->id, chg, h); 982 rsa_hash (p->id, chg, h);
1001 1039
1002 if (iseqno.recv_ok (seqno)) 1040 if (iseqno.recv_ok (seqno))
1003 { 1041 {
1004 vpn->tap->send (d); 1042 vpn->tap->send (d);
1005 1043
1006 if (p->dst () == 0) // re-broadcast
1007 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
1008 {
1009 connection *c = *i;
1010
1011 if (c->conf != THISNODE && c->conf != conf)
1012 c->inject_data_packet (d);
1013 }
1014
1015 if (si != rsi) 1044 if (si != rsi)
1016 { 1045 {
1017 // fast re-sync on conneciton changes, useful especially for tcp/ip 1046 // fast re-sync on connection changes, useful especially for tcp/ip
1018 si = rsi; 1047 si = rsi;
1019 1048
1020 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1049 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1021 conf->nodename, (const char *)si, (const char *)rsi); 1050 conf->nodename, (const char *)si, (const char *)rsi);
1022 } 1051 }
1048 // send connect_info packets to both sides, in case one is 1077 // send connect_info packets to both sides, in case one is
1049 // behind a nat firewall (or both ;) 1078 // behind a nat firewall (or both ;)
1050 c->send_connect_info (conf->id, si, conf->protocols); 1079 c->send_connect_info (conf->id, si, conf->protocols);
1051 send_connect_info (c->conf->id, c->si, c->conf->protocols); 1080 send_connect_info (c->conf->id, c->si, c->conf->protocols);
1052 } 1081 }
1082 else
1083 c->establish_connection ();
1053 } 1084 }
1054 1085
1055 break; 1086 break;
1056 1087
1057 case vpn_packet::PT_CONNECT_INFO: 1088 case vpn_packet::PT_CONNECT_INFO:
1097 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1128 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1098 { 1129 {
1099 send_ping (si); 1130 send_ping (si);
1100 w.at = NOW + 5; 1131 w.at = NOW + 5;
1101 } 1132 }
1133 else if (NOW < last_activity + ::conf.keepalive + 10)
1134 // hold ondemand connections implicitly a few seconds longer
1135 // should delete octx, though, or something like that ;)
1136 w.at = last_activity + ::conf.keepalive + 10;
1102 else 1137 else
1103 reset_connection (); 1138 reset_connection ();
1104} 1139}
1105 1140
1106void connection::send_connect_request (int id) 1141void connection::send_connect_request (int id)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines