/* connection.h -- header for connection.C Copyright (C) 2003-2005 Marc Lehmann This file is part of GVPE. GVPE is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GVPE_CONNECTION_H__ #define GVPE_CONNECTION_H__ #include #include "global.h" #include "conf.h" #include "sockinfo.h" #include "util.h" #include "device.h" struct vpn; // called after HUP etc. to (re-)initialize global data structures void connection_init (); struct rsaid { u8 id[RSA_IDLEN]; // the challenge id }; typedef rsaclear rsachallenge; // challenge data; typedef rsacrypt rsaencrdata; // encrypted challenge typedef u8 rsaresponse[RSA_RESLEN]; // the encrypted ripemd160 hash //////////////////////////////////////////////////////////////////////////////////////// struct crypto_ctx; struct hmac_packet : net_packet { u8 hmac[HMACLENGTH]; // each and every packet has a hmac field, but that is not (yet) checked everywhere void hmac_set (crypto_ctx * ctx); bool hmac_chk (crypto_ctx * ctx); private: static unsigned char hmac_digest[EVP_MAX_MD_SIZE]; void hmac_gen (crypto_ctx * ctx); }; struct vpn_packet : hmac_packet { enum ptype { PT_RESET = 0, PT_DATA_UNCOMPRESSED, PT_DATA_COMPRESSED, PT_PING, PT_PONG, // wasting namespace space? ;) PT_AUTH_REQ, // authentification request PT_AUTH_RES, // authentification response PT_CONNECT_REQ, // want other node to contact me PT_CONNECT_INFO, // request connection to some node PT_DATA_BRIDGED, // uncompressed packet with foreign mac pot. larger than path mtu (NYI) PT_MAX }; u8 type; u8 srcdst, src1, dst1; void set_hdr (ptype type_, unsigned int dst); unsigned int src () const { return src1 | ((srcdst >> 4) << 8); } unsigned int dst () const { return dst1 | ((srcdst & 0xf) << 8); } ptype typ () const { return (ptype) type; } }; //////////////////////////////////////////////////////////////////////////////////////// // a very simple fifo pkt-queue class pkt_queue { int i, j; int max_queue; double max_ttl; struct pkt { ev_tstamp tstamp; net_packet *pkt; } *queue; void expire_cb (ev::timer &w, int revents); ev::timer expire; public: void put (net_packet *p); net_packet *get (); bool empty () { return i == j; } pkt_queue (double max_ttl, int max_queue); ~pkt_queue (); }; enum { FEATURE_COMPRESSION = 0x01, FEATURE_ROHC = 0x02, FEATURE_BRIDGING = 0x04, }; struct connection { conf_node *conf; struct vpn *vpn; sockinfo si; // the current(!) destination ip to send packets to int retry_cnt; tstamp last_activity; // time of last packet received tstamp last_establish_attempt; u32 oseqno; sliding_window iseqno; u8 protocol; u8 features; pkt_queue data_queue, vpn_queue; crypto_ctx *octx, *ictx; #if ENABLE_DNS struct dns_connection *dns; void dnsv4_reset_connection (); #endif enum conf_node::connectmode connectmode; u8 prot_minor; // minor number of other side void reset_si (); const sockinfo &forward_si (const sockinfo &si) const; void shutdown (); void connection_established (); void reset_connection (); void establish_connection_cb (ev::timer &w, int revents); ev::timer establish_connection; void rekey_cb (ev::timer &w, int revents); ev::timer rekey; // next rekying (actually current reset + reestablishing) void keepalive_cb (ev::timer &w, int revents); ev::timer keepalive; // next keepalive probe void send_connect_request (int id); void send_auth_request (const sockinfo &si, bool initiate); void send_auth_response (const sockinfo &si, const rsaid &id, const rsachallenge &chg); void send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols); void send_reset (const sockinfo &dsi); void send_ping (const sockinfo &dsi, u8 pong = 0); void send_data_packet (tap_packet *pkt); void post_inject_queue (); void inject_data_packet (tap_packet *pkt); void inject_vpn_packet (vpn_packet *pkt, int tos = 0); // for forwarding void recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi); void send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos = 0); void script_init_env (const char *ext); void script_init_connect_env (); const char *script_node_up (); const char *script_node_down (); void dump_status (); connection (struct vpn *vpn, conf_node *conf); ~connection (); }; #endif