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.24 by pcg, Wed Oct 22 01:05:23 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);
652connection::send_auth_request (const sockinfo &si, bool initiate) 675connection::send_auth_request (const sockinfo &si, bool initiate)
653{ 676{
654 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); 677 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols);
655 678
656 rsachallenge chg; 679 rsachallenge chg;
657
658 rsa_cache.gen (pkt->id, chg); 680 rsa_cache.gen (pkt->id, chg);
659 681 rsa_encrypt (conf->rsa_key, chg, pkt->encr);
660 if (0 > RSA_public_encrypt (sizeof chg,
661 (unsigned char *)&chg, (unsigned char *)&pkt->encr,
662 conf->rsa_key, RSA_PKCS1_OAEP_PADDING))
663 fatal ("RSA_public_encrypt error");
664 682
665 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); 683 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si);
666 684
667 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly 685 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly
668 686
778 reset_connection (); 796 reset_connection ();
779 establish_connection (); 797 establish_connection ();
780} 798}
781 799
782void 800void
783connection::send_data_packet (tap_packet *pkt, bool broadcast) 801connection::send_data_packet (tap_packet *pkt)
784{ 802{
785 vpndata_packet *p = new vpndata_packet; 803 vpndata_packet *p = new vpndata_packet;
786 int tos = 0; 804 int tos = 0;
787 805
788 if (conf->inherit_tos 806 // I am not hilarious about peeking into packets, but so be it.
789 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP 807 if (conf->inherit_tos && pkt->is_ipv4 ())
790 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
791 tos = (*pkt)[15] & IPTOS_TOS_MASK; 808 tos = (*pkt)[15] & IPTOS_TOS_MASK;
792 809
793 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs 810 p->setup (this, conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs
794 send_vpn_packet (p, si, tos); 811 send_vpn_packet (p, si, tos);
795 812
796 delete p; 813 delete p;
797 814
798 if (oseqno > MAX_SEQNO) 815 if (oseqno > MAX_SEQNO)
799 rekey (); 816 rekey ();
800} 817}
801 818
802void 819void
803connection::inject_data_packet (tap_packet *pkt, bool broadcast) 820connection::inject_data_packet (tap_packet *pkt, bool broadcast/*TODO DDD*/)
804{ 821{
805 if (ictx && octx) 822 if (ictx && octx)
806 send_data_packet (pkt, broadcast); 823 send_data_packet (pkt);
807 else 824 else
808 { 825 {
809 if (!broadcast)//DDDD 826 if (!broadcast)//DDDD
810 queue.put (new tap_packet (*pkt)); 827 data_queue.put (new tap_packet (*pkt));
811 828
812 establish_connection (); 829 establish_connection ();
813 } 830 }
814} 831}
815 832
816void connection::inject_vpn_packet (vpn_packet *pkt, int tos) 833void connection::inject_vpn_packet (vpn_packet *pkt, int tos)
817{ 834{
818 if (ictx && octx) 835 if (ictx && octx)
819 send_vpn_packet (pkt, si, tos); 836 send_vpn_packet (pkt, si, tos);
820 else 837 else
838 {
839 vpn_queue.put (new vpn_packet (*pkt));
840
821 establish_connection (); 841 establish_connection ();
842 }
822} 843}
823 844
824void 845void
825connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 846connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
826{ 847{
882 if (p->initiate) 903 if (p->initiate)
883 send_auth_request (rsi, false); 904 send_auth_request (rsi, false);
884 905
885 rsachallenge k; 906 rsachallenge k;
886 907
887 if (0 > RSA_private_decrypt (sizeof (p->encr), 908 if (!rsa_decrypt (::conf.rsa_key, p->encr, k))
888 (unsigned char *)&p->encr, (unsigned char *)&k, 909 {
889 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
890 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 910 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
891 conf->nodename, (const char *)rsi); 911 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
912 break;
913 }
892 else 914 else
893 { 915 {
894 delete octx; 916 delete octx;
895 917
896 octx = new crypto_ctx (k, 1); 918 octx = new crypto_ctx (k, 1);
903 connection_established (); 925 connection_established ();
904 926
905 break; 927 break;
906 } 928 }
907 } 929 }
930 else
931 slog (L_WARN, _("%s(%s): protocol mismatch"),
932 conf->nodename, (const char *)rsi);
908 933
909 send_reset (rsi); 934 send_reset (rsi);
910 } 935 }
911 936
912 break; 937 break;
925 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 950 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
926 951
927 rsachallenge chg; 952 rsachallenge chg;
928 953
929 if (!rsa_cache.find (p->id, chg)) 954 if (!rsa_cache.find (p->id, chg))
955 {
930 slog (L_ERR, _("%s(%s): unrequested auth response"), 956 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
931 conf->nodename, (const char *)rsi); 957 conf->nodename, (const char *)rsi);
958 break;
959 }
932 else 960 else
933 { 961 {
934 crypto_ctx *cctx = new crypto_ctx (chg, 0); 962 crypto_ctx *cctx = new crypto_ctx (chg, 0);
935 963
936 if (!p->hmac_chk (cctx)) 964 if (!p->hmac_chk (cctx))
965 {
937 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 966 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"), 967 "could be an attack, or just corruption or an synchronization error"),
939 conf->nodename, (const char *)rsi); 968 conf->nodename, (const char *)rsi);
969 break;
970 }
940 else 971 else
941 { 972 {
942 rsaresponse h; 973 rsaresponse h;
943 974
944 rsa_hash (p->id, chg, h); 975 rsa_hash (p->id, chg, h);
1001 1032
1002 if (iseqno.recv_ok (seqno)) 1033 if (iseqno.recv_ok (seqno))
1003 { 1034 {
1004 vpn->tap->send (d); 1035 vpn->tap->send (d);
1005 1036
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) 1037 if (si != rsi)
1016 { 1038 {
1017 // fast re-sync on conneciton changes, useful especially for tcp/ip 1039 // fast re-sync on connection changes, useful especially for tcp/ip
1018 si = rsi; 1040 si = rsi;
1019 1041
1020 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1042 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1021 conf->nodename, (const char *)si, (const char *)rsi); 1043 conf->nodename, (const char *)si, (const char *)rsi);
1022 } 1044 }
1099 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1121 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1100 { 1122 {
1101 send_ping (si); 1123 send_ping (si);
1102 w.at = NOW + 5; 1124 w.at = NOW + 5;
1103 } 1125 }
1126 else if (NOW < last_activity + ::conf.keepalive + 10)
1127 // hold ondemand connections implicitly a few seconds longer
1128 // should delete octx, though, or something like that ;)
1129 w.at = last_activity + ::conf.keepalive + 10;
1104 else 1130 else
1105 reset_connection (); 1131 reset_connection ();
1106} 1132}
1107 1133
1108void connection::send_connect_request (int id) 1134void connection::send_connect_request (int id)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines