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 NetworkException( string s_function="<none>", int s_errno=0) function(s_function)66 : function( s_function ), the_errno( s_errno ), 67 my_what(function + ": " + strerror(the_errno)) {} what()68 const char *what() const throw () { return my_what.c_str(); } throw()69 ~NetworkException() throw () {} 70 }; 71 72 enum Direction { 73 TO_SERVER = 0, 74 TO_CLIENT = 1 75 }; 76 77 class Packet { 78 public: 79 const uint64_t seq; 80 Direction direction; 81 uint16_t timestamp, timestamp_reply; 82 string payload; 83 Packet(Direction s_direction,uint16_t s_timestamp,uint16_t s_timestamp_reply,const string & s_payload)84 Packet( Direction s_direction, 85 uint16_t s_timestamp, uint16_t s_timestamp_reply, const string & s_payload ) 86 : seq( Crypto::unique() ), direction( s_direction ), 87 timestamp( s_timestamp ), timestamp_reply( s_timestamp_reply ), payload( s_payload ) 88 {} 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: fd(void)155 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 sock(void)197 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, bool nonblocking ); 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; get_MTU(void)215 int get_MTU( void ) const { return MTU; } 216 217 std::string port( void ) const; get_key(void)218 string get_key( void ) const { return key.printable_key(); } get_has_remote_addr(void)219 bool get_has_remote_addr( void ) const { return has_remote_addr; } 220 221 uint64_t timeout( void ) const; get_SRTT(void)222 double get_SRTT( void ) const { return SRTT; } 223 get_remote_addr(void)224 const Addr &get_remote_addr( void ) const { return remote_addr; } get_remote_addr_len(void)225 socklen_t get_remote_addr_len( void ) const { return remote_addr_len; } 226 get_send_error(void)227 string &get_send_error( void ) 228 { 229 return send_error; 230 } 231 set_last_roundtrip_success(uint64_t s_success)232 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 239