Line data Source code
1 : /* 2 : Mosh: the mobile shell 3 : Copyright 2012 Keith Winstein 4 : 5 : This program is free software: you can redistribute it and/or modify 6 : it under the terms of the GNU General Public License as published by 7 : the Free Software Foundation, either version 3 of the License, or 8 : (at your option) any later version. 9 : 10 : This program is distributed in the hope that it will be useful, 11 : but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : GNU General Public License for more details. 14 : 15 : You should have received a copy of the GNU General Public License 16 : along with this program. If not, see <http://www.gnu.org/licenses/>. 17 : 18 : In addition, as a special exception, the copyright holders give 19 : permission to link the code of portions of this program with the 20 : OpenSSL library under certain conditions as described in each 21 : individual source file, and distribute linked combinations including 22 : the two. 23 : 24 : You must obey the GNU General Public License in all respects for all 25 : of the code used other than OpenSSL. If you modify file(s) with this 26 : exception, you may extend this exception to your version of the 27 : file(s), but you are not obligated to do so. If you do not wish to do 28 : so, delete this exception statement from your version. If you delete 29 : this exception statement from all source files in the program, then 30 : also delete it here. 31 : */ 32 : 33 : #ifndef NETWORK_HPP 34 : #define NETWORK_HPP 35 : 36 : #include <stdint.h> 37 : #include <deque> 38 : #include <sys/socket.h> 39 : #include <netinet/in.h> 40 : #include <string> 41 : #include <math.h> 42 : #include <vector> 43 : #include <assert.h> 44 : #include <exception> 45 : #include <string.h> 46 : 47 : #include "crypto.h" 48 : 49 : using namespace Crypto; 50 : 51 : namespace Network { 52 : static const unsigned int MOSH_PROTOCOL_VERSION = 2; /* bumped for echo-ack */ 53 : 54 : uint64_t timestamp( void ); 55 : uint16_t timestamp16( void ); 56 : uint16_t timestamp_diff( uint16_t tsnew, uint16_t tsold ); 57 : 58 : class NetworkException : public std::exception { 59 : public: 60 : string function; 61 : int the_errno; 62 : private: 63 : string my_what; 64 : public: 65 0 : NetworkException( string s_function="<none>", int s_errno=0) 66 0 : : function( s_function ), the_errno( s_errno ), 67 0 : my_what(function + ": " + strerror(the_errno)) {} 68 0 : const char *what() const throw () { return my_what.c_str(); } 69 0 : ~NetworkException() throw () {} 70 : }; 71 : 72 : enum Direction { 73 : TO_SERVER = 0, 74 : TO_CLIENT = 1 75 : }; 76 : 77 8021236 : class Packet { 78 : public: 79 : const uint64_t seq; 80 : Direction direction; 81 : uint16_t timestamp, timestamp_reply; 82 : string payload; 83 : 84 8005333 : Packet( Direction s_direction, 85 : uint16_t s_timestamp, uint16_t s_timestamp_reply, const string & s_payload ) 86 8005333 : : seq( Crypto::unique() ), direction( s_direction ), 87 8005333 : timestamp( s_timestamp ), timestamp_reply( s_timestamp_reply ), payload( s_payload ) 88 8000000 : {} 89 : 90 : Packet( const Message & message ); 91 : 92 : Message toMessage( void ); 93 : }; 94 : 95 : union Addr { 96 : struct sockaddr sa; 97 : struct sockaddr_in sin; 98 : struct sockaddr_in6 sin6; 99 : struct sockaddr_storage ss; 100 : }; 101 : 102 : class Connection { 103 : private: 104 : /* 105 : * For IPv4, guess the typical (minimum) header length; 106 : * fragmentation is not dangerous, just inefficient. 107 : */ 108 : static const int IPV4_HEADER_LEN = 20 /* base IP header */ 109 : + 8 /* UDP */; 110 : /* 111 : * For IPv6, we don't want to ever have MTU issues, so make a 112 : * conservative guess about header size. 113 : */ 114 : static const int IPV6_HEADER_LEN = 40 /* base IPv6 header */ 115 : + 16 /* 2 minimum-sized extension headers */ 116 : + 8 /* UDP */; 117 : /* Application datagram MTU. For constructors and fallback. */ 118 : static const int DEFAULT_SEND_MTU = 500; 119 : /* 120 : * IPv4 MTU. Don't use full Ethernet-derived MTU, 121 : * mobile networks have high tunneling overhead. 122 : * 123 : * As of July 2016, VPN traffic over Amtrak Acela wifi seems to be 124 : * dropped if tunnelled packets are 1320 bytes or larger. Use a 125 : * 1280-byte IPv4 MTU for now. 126 : * 127 : * We may have to implement ICMP-less PMTUD (RFC 4821) eventually. 128 : */ 129 : static const int DEFAULT_IPV4_MTU = 1280; 130 : /* IPv6 MTU. Use the guaranteed minimum to avoid fragmentation. */ 131 : static const int DEFAULT_IPV6_MTU = 1280; 132 : 133 : static const uint64_t MIN_RTO = 50; /* ms */ 134 : static const uint64_t MAX_RTO = 1000; /* ms */ 135 : 136 : static const int PORT_RANGE_LOW = 60001; 137 : static const int PORT_RANGE_HIGH = 60999; 138 : 139 : static const unsigned int SERVER_ASSOCIATION_TIMEOUT = 40000; 140 : static const unsigned int PORT_HOP_INTERVAL = 10000; 141 : 142 : static const unsigned int MAX_PORTS_OPEN = 10; 143 : static const unsigned int MAX_OLD_SOCKET_AGE = 60000; 144 : 145 : static const int CONGESTION_TIMESTAMP_PENALTY = 500; /* ms */ 146 : 147 : bool try_bind( const char *addr, int port_low, int port_high ); 148 : 149 : class Socket 150 : { 151 : private: 152 : int _fd; 153 : 154 : public: 155 38417 : int fd( void ) const { return _fd; } 156 : Socket( int family ); 157 : ~Socket(); 158 : 159 : Socket( const Socket & other ); 160 : Socket & operator=( const Socket & other ); 161 : }; 162 : 163 : std::deque< Socket > socks; 164 : bool has_remote_addr; 165 : Addr remote_addr; 166 : socklen_t remote_addr_len; 167 : 168 : bool server; 169 : 170 : int MTU; /* application datagram MTU */ 171 : 172 : Base64Key key; 173 : Session session; 174 : 175 : void setup( void ); 176 : 177 : Direction direction; 178 : uint16_t saved_timestamp; 179 : uint64_t saved_timestamp_received_at; 180 : uint64_t expected_receiver_seq; 181 : 182 : uint64_t last_heard; 183 : uint64_t last_port_choice; 184 : uint64_t last_roundtrip_success; /* transport layer needs to tell us this */ 185 : 186 : bool RTT_hit; 187 : double SRTT; 188 : double RTTVAR; 189 : 190 : /* Error from send()/sendto(). */ 191 : string send_error; 192 : 193 : Packet new_packet( const string &s_payload ); 194 : 195 : void hop_port( void ); 196 : 197 7659 : int sock( void ) const { assert( !socks.empty() ); return socks.back().fd(); } 198 : 199 : void prune_sockets( void ); 200 : 201 : string recv_one( int sock_to_recv ); 202 : 203 : void set_MTU( int family ); 204 : 205 : public: 206 : /* Network transport overhead. */ 207 : static const int ADDED_BYTES = 8 /* seqno/nonce */ + 4 /* timestamps */; 208 : 209 : Connection( const char *desired_ip, const char *desired_port ); /* server */ 210 : Connection( const char *key_str, const char *ip, const char *port ); /* client */ 211 : 212 : void send( const string & s ); 213 : string recv( void ); 214 : const std::vector< int > fds( void ) const; 215 5329 : int get_MTU( void ) const { return MTU; } 216 : 217 : std::string port( void ) const; 218 452 : string get_key( void ) const { return key.printable_key(); } 219 65370 : bool get_has_remote_addr( void ) const { return has_remote_addr; } 220 : 221 : uint64_t timeout( void ) const; 222 3385 : double get_SRTT( void ) const { return SRTT; } 223 : 224 : const Addr &get_remote_addr( void ) const { return remote_addr; } 225 : socklen_t get_remote_addr_len( void ) const { return remote_addr_len; } 226 : 227 5640 : string &get_send_error( void ) 228 : { 229 5640 : return send_error; 230 : } 231 : 232 5281 : void set_last_roundtrip_success( uint64_t s_success ) { last_roundtrip_success = s_success; } 233 : 234 : static bool parse_portrange( const char * desired_port_range, int & desired_port_low, int & desired_port_high ); 235 : }; 236 : } 237 : 238 : #endif