PageRenderTime 62ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/tor6tun/tor6tun.cpp

https://gitlab.com/cg909/tor6tun
C++ | 942 lines | 776 code | 83 blank | 83 comment | 146 complexity | 530aec8690b557af27bd87d4c2ecf93b MD5 | raw file
  1. /****************************************************************************
  2. * Copyright (c) 2016 by Christoph Grenz *
  3. * christophg@grenz-bonn.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or *
  6. * modify it under the terms of the GNU General Public License as *
  7. * published by the Free Software Foundation; either version 3 of *
  8. * the License, or (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 GNU *
  13. * 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. ****************************************************************************
  19. * Main application: *
  20. * Connection management, IPv6 packet rewriting, callbacks, etc. *
  21. ****************************************************************************/
  22. #include "tor6tun.h"
  23. #include "base32.h"
  24. #include "call.h"
  25. #include "getaddrinfo.h"
  26. #include "if_addrs.h"
  27. #include "ip_packets.h"
  28. #include "logging.h"
  29. #include "packetbuffer.h"
  30. #include "util.h"
  31. #include <sstream>
  32. #include <netinet/in.h>
  33. #include <netinet/icmp6.h>
  34. class socks_error: public std::runtime_error
  35. {
  36. int c;
  37. public:
  38. socks_error(const char *what, int code=-1): std::runtime_error(what), c(code) {}
  39. int code() const noexcept
  40. {
  41. return c;
  42. }
  43. };
  44. static Socket socks_open(const std::string &socks_server, sockaddr_in6 &socks_addr)
  45. {
  46. // Create and connect socket
  47. Socket sock(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
  48. try {
  49. sock.connect(socks_addr);
  50. } catch (std::system_error &exc) {
  51. // On recoverable errors, iterate through all addrinfo records
  52. // trying to connect to every address of the host until it
  53. // succedes.
  54. int code = exc.code().value();
  55. bool retry = false;
  56. switch (code) {
  57. case EACCES:
  58. case EPERM:
  59. case ECONNREFUSED:
  60. case ENETUNREACH:
  61. case ETIMEDOUT:
  62. retry = true;
  63. break;
  64. default:
  65. break;
  66. }
  67. if (retry) {
  68. for (auto &&item : getaddrinfo(socks_server, AI_V4MAPPED|AI_IDN, AF_INET6, SOCK_STREAM)) {
  69. std::memcpy(&socks_addr, item.ai_addr, sizeof(sockaddr_in6));
  70. try {
  71. sock.connect(socks_addr);
  72. } catch (std::system_error &exc) {
  73. if (item.ai_next == nullptr) {
  74. // If no address works, bail out
  75. throw;
  76. }
  77. continue;
  78. }
  79. break;
  80. }
  81. }
  82. else {
  83. throw;
  84. }
  85. }
  86. sock.set_cloexec(true);
  87. // Send SOCKS 5 anonymous auth command
  88. bytevector buffer({0x05, 1, 0});
  89. sock.send(buffer);
  90. return sock;
  91. }
  92. static std::string ipv6_to_onion(const IPv6Address &addr)
  93. {
  94. std::string onion = b32encode(&addr.s6_addr[6], 10);
  95. onion.append(".onion");
  96. return onion;
  97. }
  98. static void socks_connect_1(AsyncSocket& sock, const IPv6Address &addr, uint16_t port)
  99. {
  100. bytevector buffer;
  101. sock.recv(buffer, 2);
  102. if (buffer[0] != 5 or buffer[1] != 0)
  103. throw socks_error("SOCKS 5 auth failed");
  104. // Send SOCKS 5 connection request
  105. buffer = {0x05, 1, 0, 4};
  106. sock.send(buffer);
  107. buffer.resize(16);
  108. std::memcpy(&buffer[0], &addr, 16);
  109. sock.send(buffer);
  110. buffer = {static_cast<uint8_t>(port>>8), static_cast<uint8_t>(port&0xFF)};
  111. sock.send(buffer);
  112. sock.flush();
  113. }
  114. static void socks_connect_1(AsyncSocket& sock, const std::string &onion, uint16_t port)
  115. {
  116. bytevector buffer;
  117. sock.recv(buffer, 2);
  118. if (buffer[0] != 5 or buffer[1] != 0)
  119. throw socks_error("SOCKS 5 auth failed");
  120. // Send SOCKS 5 connection request
  121. buffer = {0x05, 1, 0, 3, static_cast<uint8_t>(onion.length())};
  122. sock.send(buffer);
  123. sock.send(onion);
  124. buffer = {static_cast<uint8_t>(port>>8), static_cast<uint8_t>(port&0xFF)};
  125. sock.send(buffer);
  126. sock.flush();
  127. }
  128. static void socks_connect_2(AsyncSocket &sock)
  129. {
  130. bytevector buffer;
  131. sock.recv(buffer, 4);
  132. int status = -1, tmp;
  133. if (buffer[0] != 5)
  134. throw socks_error("SOCKS 5 invalid connect response");
  135. status = buffer[1];
  136. switch (buffer[3]) {
  137. case 1:
  138. sock.recv(buffer, 6);
  139. break;
  140. case 3:
  141. sock.recv(buffer, 1);
  142. tmp = buffer[0];
  143. sock.recv(buffer, tmp+2);
  144. case 4:
  145. sock.recv(buffer, 18);
  146. break;
  147. default:
  148. throw socks_error("SOCKS 5 invalid connect response");
  149. }
  150. if (status != 0)
  151. throw socks_error("SOCKS 5 connect failed", status);
  152. }
  153. std::ostream& operator << (std::ostream &lhs, const ConnKey &rhs)
  154. {
  155. return lhs << "<[" << rhs.addr << "]:" << rhs.port << '>';
  156. }
  157. Tor6TunApplication::Tor6TunApplication(
  158. const std::string &tun_name,
  159. const std::string &socks_server,
  160. const IPv6Network &onion_net,
  161. const std::string &port
  162. )
  163. : socks_server(socks_server), onion_network(onion_net), tun(tun_name),
  164. max_connections(65535), max_connreqs(65535), last_router_adv(0),
  165. in_shutdown(false)
  166. {
  167. // Setup sockets
  168. tun.set_cloexec(true);
  169. tcp_sock.open(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
  170. tcp_sock.set_cloexec(true);
  171. // Setup TUN
  172. std::string addrstr { setup_tun() };
  173. log::debug("tun device ", tun.get_name(), " opened");
  174. // Bind tcp loopback socket
  175. struct sockaddr_in6 addr;
  176. for (auto &&item : getaddrinfo(addrstr, port, AI_PASSIVE, AF_INET6, SOCK_STREAM)) {
  177. addr = *reinterpret_cast<sockaddr_in6*>(item.ai_addr);
  178. break;
  179. }
  180. tcp_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1);
  181. tcp_sock.setsockopt(SOL_SOCKET, SO_OOBINLINE, 1);
  182. tcp_sock.setsockopt(SOL_SOCKET, SO_DONTROUTE, 1);
  183. try {
  184. tcp_sock.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, tun.get_name());
  185. } catch (std::system_error &exc) {
  186. if (exc.code().value() != EPERM)
  187. throw;
  188. log::debug("SO_BINDTODEVICE on internal TCP socket failed");
  189. }
  190. tcp_sock.setsockopt<struct linger>(SOL_SOCKET, SO_LINGER, {0, 2});
  191. tcp_sock.bind<struct sockaddr_in6>(addr);
  192. tcp_sock.listen(16);
  193. addr = tcp_sock.getsockname<sockaddr_in6>();
  194. tunnel_proxy_port = ntohs(addr.sin6_port);
  195. // Set transfer network
  196. transfer_network = "fe90::0/12";
  197. log::debug("using TCP port ", tunnel_proxy_port, " for internal purposes");
  198. log::debug(".onion urls are mapped to IPv6 network ", onion_network);
  199. // Set tor server address
  200. for (auto &&item : getaddrinfo(socks_server, AI_V4MAPPED|AI_IDN, AF_INET6, SOCK_STREAM)) {
  201. socks_addr = *reinterpret_cast<sockaddr_in6*>(item.ai_addr);
  202. break;
  203. }
  204. // Set event handlers
  205. selector.read.add(tun, std::bind(&Tor6TunApplication::on_tun_packet, this));
  206. selector.read.add(tcp_sock, std::bind(&Tor6TunApplication::on_new_connection, this));
  207. }
  208. std::string Tor6TunApplication::setup_tun()
  209. {
  210. // Discover IPv6 addresses on tun interface
  211. IPv6Address tun_addr;
  212. bool tun_is_up = false;
  213. std::string tun_name { tun.get_name() };
  214. IPv6Address mask {"ffc0::"};
  215. IPv6Network net {"fe80::/10"};
  216. for (auto &ifaddr: getifaddrs()) {
  217. if (!ifaddr.ifa_addr or ifaddr.ifa_addr->sa_family != AF_INET6)
  218. continue;
  219. if (tun_name != ifaddr.ifa_name)
  220. continue;
  221. sockaddr_in6 *saddr = reinterpret_cast<sockaddr_in6*>(ifaddr.ifa_addr);
  222. sockaddr_in6 *smask = reinterpret_cast<sockaddr_in6*>(ifaddr.ifa_netmask);
  223. IPv6Address addr {saddr->sin6_addr};
  224. log::info(addr);
  225. if (addr.is_in(net) and mask == smask->sin6_addr) {
  226. tun_addr = addr;
  227. tun_is_up = ifaddr.ifa_flags & IFF_UP;
  228. break;
  229. }
  230. }
  231. // Activate TUN network interface, if needed
  232. if (!tun_is_up) {
  233. log::debug("activating ", tun_name);
  234. check_call({"ip", "link", "set", tun_name, "up"});
  235. }
  236. // Set interface address, if needed
  237. if (!tun_addr) {
  238. log::debug("adding IPv6 address fe80::1/10 to ", tun_name);
  239. check_call({"ip", "-6", "addr", "add", "fe80::1/10", "scope", "link", "dev", tun_name});
  240. tun_addr = "fe80::1";
  241. }
  242. return tun_addr.to_string()+"%"+tun_name;
  243. }
  244. unsigned long Tor6TunApplication::get_max_connreqs()
  245. { return max_connreqs; }
  246. unsigned long Tor6TunApplication::get_max_connections()
  247. { return max_connections; }
  248. void Tor6TunApplication::set_max_connreqs(unsigned long v)
  249. { max_connreqs = v; }
  250. void Tor6TunApplication::set_max_connections(unsigned long v)
  251. { max_connections = v; }
  252. void Tor6TunApplication::process()
  253. {
  254. /* Send unsolicited router advertisements */
  255. time_t current_time = time(nullptr);
  256. if (last_router_adv < current_time-59) {
  257. send_router_adv();
  258. last_router_adv = current_time;
  259. }
  260. /* Handle socket events */
  261. selector.select(16);
  262. /* Cleanup */
  263. cleanup_closing_connections();
  264. }
  265. bool Tor6TunApplication::shutdown()
  266. {
  267. bool had_connections = connections.empty();
  268. time_t current_time = time(nullptr);
  269. in_shutdown = true;
  270. send_router_adv(false);
  271. for (auto &pair: closing) {
  272. if (pair.first > current_time+2)
  273. pair.first = current_time+2;
  274. }
  275. for (auto &pair: connections) {
  276. Connection& conn = pair.second;
  277. if (conn.socks_socket.fileno() != -1)
  278. conn.socks_socket.flush();
  279. else
  280. continue;
  281. if (conn.client_socket.fileno() != -1)
  282. conn.client_socket.flush();
  283. selector.read.remove(conn.client_socket);
  284. selector.read.remove(conn.socks_socket);
  285. selector.write.remove(conn.client_socket);
  286. selector.write.remove(conn.socks_socket);
  287. log::debug("connection [", conn.socks_socket.fileno(), "] closing");
  288. conn.client_socket.close();
  289. conn.socks_socket.close();
  290. // Append to closing list
  291. closing.push_back(
  292. std::make_pair(current_time+2, pair.first)
  293. );
  294. }
  295. while (!connections.empty()) {
  296. had_connections = true;
  297. selector.select(0.10);
  298. cleanup_closing_connections();
  299. }
  300. return had_connections;
  301. }
  302. void Tor6TunApplication::cleanup_closing_connections()
  303. {
  304. time_t current_time = time(nullptr);
  305. size_t closed_count = 0;
  306. auto end_it = --closing.begin();
  307. for (auto it = --closing.end(); it != end_it; --it) {
  308. if (it->first <= current_time) {
  309. connections.erase(it->second);
  310. closing.erase(it);
  311. closed_count++;
  312. }
  313. }
  314. if (closed_count)
  315. log::debug("closed ", closed_count, " lingering connection(s)");
  316. if (closing.capacity() > (closing.size()+1)*120/100)
  317. closing.shrink_to_fit();
  318. }
  319. void Tor6TunApplication::on_tun_packet()
  320. {
  321. static thread_local bytevector buffer;
  322. buffer.reserve(2052);
  323. if (!tun.recv(buffer))
  324. return;
  325. if (buffer.size() < 5) {
  326. log::warn("too small packet on TUN interface");
  327. return;
  328. }
  329. PacketBufferView packet(buffer);
  330. tun_frame_header &tun_header = packet.next<tun_frame_header>();
  331. // IPv6
  332. if (tun_header.proto == htons(ETH_P_IPV6)) {
  333. IPv6Header &ipv6_header = packet.peek<IPv6Header>();
  334. auto source = ipv6_header.source();
  335. auto destination = ipv6_header.destination();
  336. // Skip packets from ::
  337. if (!source) {
  338. return;
  339. }
  340. // Skip non-ICMP packets to multicast
  341. if (destination.s6_addr[0] == 0xFF && ipv6_header.next_header() != IPPROTO_ICMPV6) {
  342. return;
  343. }
  344. // Verify payload size and skip truncated packets
  345. if (ipv6_header.payload_length() != packet.size()-40) {
  346. return;
  347. }
  348. if (destination.is_in(transfer_network)) {
  349. // Packets from SOCKS tunnel to outside
  350. if (ipv6_header.next_header() == IPPROTO_TCP) {
  351. handle_tun_tcp_reply(packet, buffer);
  352. }
  353. } else if (!source.is_in(transfer_network)) {
  354. // Packets from outside to SOCKS tunnel
  355. switch (ipv6_header.next_header()) {
  356. case IPPROTO_TCP:
  357. handle_tun_tcp_packet(packet, buffer);
  358. break;
  359. case IPPROTO_UDP:
  360. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT);
  361. break;
  362. case IPPROTO_ICMPV6:
  363. handle_tun_icmpv6_packet(packet);
  364. break;
  365. default:
  366. send_icmpv6_error(packet, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, 40);
  367. break;
  368. }
  369. }
  370. } else if (tun_header.proto == htons(ETH_P_IP)) {
  371. // For now ignore IPv4 packets
  372. }
  373. // Ignore all non-IP packets
  374. }
  375. void Tor6TunApplication::on_new_connection()
  376. {
  377. // accept and match to pending connections
  378. auto pair = tcp_sock.accept<struct sockaddr_in6>();
  379. IPv6Address addr(pair.second.sin6_addr);
  380. pair.first.set_cloexec(true);
  381. pair.first.set_blocking(false);
  382. auto it = connections.find({pair.second.sin6_addr, ntohs(pair.second.sin6_port)});
  383. if (it->second.socks_socket.fileno() == -1) {
  384. // Reuse of a closing address combination
  385. log::warn("address-port combination ", it->first," already in cooldown phase. TCP connection aborted.");
  386. pair.first.close();
  387. return;
  388. }
  389. Connection& conn = it->second;
  390. conn.client_socket = std::move(pair.first);
  391. log::debug("connection [", conn.socks_socket.fileno(),"] established");
  392. // Add callbacks
  393. selector.read.add(conn.client_socket, std::bind(
  394. &Tor6TunApplication::on_conn_recv,
  395. this,
  396. std::ref(it->first),
  397. std::ref(conn.client_socket),
  398. std::ref(conn.socks_socket)
  399. ));
  400. selector.read.add(conn.socks_socket, std::bind(
  401. &Tor6TunApplication::on_conn_recv,
  402. this,
  403. std::ref(it->first),
  404. std::ref(conn.socks_socket),
  405. std::ref(conn.client_socket)
  406. ));
  407. }
  408. void Tor6TunApplication::handle_tun_tcp_reply(PacketBufferView packet, bytevector &buffer)
  409. {
  410. IPv6Header &ipv6 = packet.next<IPv6Header>();
  411. TCPHeader &tcp = packet.next<TCPHeader>();
  412. if (tcp.source_port() != tunnel_proxy_port)
  413. return;
  414. auto it = connections.find({ipv6.destination(), tcp.destination_port()});
  415. if (it == connections.end())
  416. return;
  417. Connection &conn = it->second;
  418. ipv6.destination() = conn.source;
  419. ipv6.source() = conn.destination;
  420. tcp.source_port(conn.dport);
  421. tcp.set_checksum(ipv6);
  422. tun.send(buffer);
  423. }
  424. void Tor6TunApplication::handle_tun_tcp_packet(PacketBufferView packet, bytevector &buffer)
  425. {
  426. IPv6Header &ipv6 = packet.next<IPv6Header>();
  427. TCPHeader &tcp = packet.next<TCPHeader>();
  428. if ((tcp.flags() & 0x3F) == 2) { // SYN
  429. if (in_shutdown)
  430. return;
  431. if (connreqs.size() >= max_connreqs) {
  432. return;
  433. }
  434. if (connections.size() >= max_connections)
  435. return;
  436. IPv6Address key_addr = ipv6.source();
  437. key_addr.renumber(transfer_network);
  438. // Initiate connection to SOCKS proxy
  439. Socket socks_socket;
  440. try {
  441. socks_socket = socks_open(socks_server, socks_addr);
  442. } catch (std::system_error &exc) {
  443. log::warn("SOCKS connection error: ", exc.what());
  444. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
  445. return;
  446. }
  447. // Create connection get_name
  448. std::ostringstream stream;
  449. stream << '[' << ipv6.source() << "]:" << tcp.source_port() << " => ";
  450. if (ipv6.destination().is_in(onion_network))
  451. stream << ipv6_to_onion(ipv6.destination()) << ':' << tcp.destination_port();
  452. else
  453. stream << '[' << ipv6.destination() << "]:" << tcp.destination_port();
  454. // Add connection to list
  455. auto result = connections.insert(std::make_pair<ConnKey, Connection>(
  456. {key_addr, tcp.source_port()},
  457. {
  458. ipv6.source(), ipv6.destination(),
  459. tcp.source_port(), tcp.destination_port(),
  460. {}, std::move(socks_socket)
  461. }
  462. ));
  463. if (result.second == false)
  464. return;
  465. if (ipv6.destination().is_in(onion_network))
  466. log::debug("new TCP connection [", result.first->second.socks_socket.fileno(),
  467. "]: from [", ipv6.source(), "]:", tcp.source_port(), " to ",
  468. ipv6_to_onion(ipv6.destination()), ':', tcp.destination_port()
  469. );
  470. else
  471. log::debug("new TCP connection [", result.first->second.socks_socket.fileno(),
  472. "]: from [", ipv6.source(), "]:", tcp.source_port(), " to [",
  473. ipv6.destination(), "]:", tcp.destination_port()
  474. );
  475. // Record SYN packet
  476. bytevector tmp;
  477. tmp.swap(buffer);
  478. tmp.shrink_to_fit();
  479. auto result2 = connreqs.insert(std::make_pair<ConnKey, bytevector>(
  480. {key_addr, tcp.source_port()},
  481. std::move(tmp)
  482. ));
  483. if (result2.second == false) {
  484. connections.erase(result.first);
  485. return;
  486. }
  487. // Set callback
  488. selector.read.add(
  489. result.first->second.socks_socket,
  490. std::bind(
  491. &Tor6TunApplication::on_socks_auth,
  492. this,
  493. std::ref(result.first->first),
  494. std::ref(result.first->second.socks_socket)
  495. )
  496. );
  497. return;
  498. } else if ((tcp.flags() & 0x04)) { // RST
  499. // Build connection key
  500. IPv6Address key_addr = ipv6.source();
  501. key_addr.renumber(transfer_network);
  502. // Check if matching connection
  503. ConnKey key {key_addr, tcp.source_port()};
  504. auto it = connections.find(key);
  505. if (it != connections.end()) {
  506. // If not an established connection
  507. if (it->second.client_socket.fileno() == -1) {
  508. // try to remove connection request
  509. auto it2 = connreqs.find(key);
  510. if (it2 != connreqs.end())
  511. connreqs.erase(it2);
  512. // Remove listeners
  513. selector.read.remove(it->second.socks_socket);
  514. selector.write.remove(it->second.socks_socket);
  515. // Log it
  516. log::debug("connection [", it->second.socks_socket.fileno(),
  517. "] reset"
  518. );
  519. // Erase connection
  520. connections.erase(it);
  521. return;
  522. }
  523. }
  524. // else fallthrough, let kernel handle RST
  525. }
  526. // Rewrite source and destination
  527. ipv6.source().renumber(transfer_network);
  528. ipv6.destination() = "fe80::1";
  529. tcp.destination_port(tunnel_proxy_port);
  530. tcp.set_checksum(ipv6);
  531. // Forward packet
  532. tun.send(buffer);
  533. }
  534. void Tor6TunApplication::on_socks_auth(const ConnKey &key, AsyncSocket &sock)
  535. {
  536. auto it = connections.find(key);
  537. auto it2 = connreqs.find(key);
  538. // Consistence checks
  539. if (it == connections.end()) {
  540. connreqs.erase(key);
  541. selector.read.remove(sock);
  542. return;
  543. }
  544. else if (sock.fileno() == -1) {
  545. connreqs.erase(key);
  546. connections.erase(it);
  547. selector.read.remove(sock);
  548. return;
  549. }
  550. if (it2 == connreqs.end()) {
  551. connections.erase(it);
  552. selector.read.remove(sock);
  553. return;
  554. }
  555. PacketBufferView packet(it2->second);
  556. packet.next<tun_frame_header>();
  557. // Continue SOCKS connection setup
  558. Connection &conn = it->second;
  559. try {
  560. if (conn.destination.is_in(onion_network)) {
  561. // To onion address
  562. std::string onion = ipv6_to_onion(conn.destination);
  563. socks_connect_1(sock, onion, conn.dport);
  564. } else {
  565. socks_connect_1(sock, conn.destination, conn.dport);
  566. }
  567. } catch (socks_error &exc) {
  568. int code = exc.code();
  569. log::warn("SOCKS connection failed with error code ", code);
  570. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
  571. connreqs.erase(key);
  572. connections.erase(it);
  573. selector.read.remove(sock);
  574. return;
  575. } catch (std::system_error &exc) {
  576. log::warn("SOCKS connection error: ", exc.what());
  577. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
  578. connreqs.erase(key);
  579. connections.erase(it);
  580. selector.read.remove(sock);
  581. return;
  582. }
  583. selector.read.replace(sock, std::bind(&Tor6TunApplication::on_socks_assoc, this, std::ref(key), std::ref(sock)));
  584. }
  585. void Tor6TunApplication::on_socks_assoc(const ConnKey &key, AsyncSocket &sock)
  586. {
  587. auto it = connections.find(key);
  588. auto it2 = connreqs.find(key);
  589. // Consistence checks
  590. if (it == connections.end()) {
  591. connreqs.erase(key);
  592. selector.read.remove(sock);
  593. return;
  594. }
  595. else if (sock.fileno() == -1) {
  596. connreqs.erase(key);
  597. connections.erase(it);
  598. selector.read.remove(sock);
  599. return;
  600. }
  601. if (it2 == connreqs.end()) {
  602. connections.erase(key);
  603. selector.read.remove(sock);
  604. return;
  605. }
  606. // Get saved SYN packet
  607. bytevector buffer;
  608. buffer.swap(it2->second);
  609. connreqs.erase(it2);
  610. PacketBufferView packet(buffer);
  611. packet.next<tun_frame_header>();
  612. // Complete SOCKS connection setup
  613. Connection &conn = it->second;
  614. try {
  615. socks_connect_2(sock);
  616. } catch (socks_error &exc) {
  617. int code = exc.code();
  618. if (code == 5 or code == 1) {
  619. log::debug("connection [", conn.socks_socket.fileno(),"] failed: connection refused");
  620. send_tcp_rst(packet);
  621. } else if (code == 2) {
  622. log::debug("connection [", conn.socks_socket.fileno(),"] failed: not allowed");
  623. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
  624. } else if (code == 3 or code == 8) {
  625. log::debug("connection [", conn.socks_socket.fileno(),"] failed: network unreachable");
  626. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
  627. } else if (code == 4) {
  628. log::debug("connection [", conn.socks_socket.fileno(),"] failed: host unreachable");
  629. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
  630. } else if (code == 6) {
  631. log::debug("connection [", conn.socks_socket.fileno(),"] failed: timeout");
  632. send_icmpv6_error(packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
  633. } else {
  634. log::warn("SOCKS connection [", conn.socks_socket.fileno(),"] failed with error code ", code);
  635. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
  636. }
  637. selector.read.remove(sock);
  638. connections.erase(it);
  639. return;
  640. } catch (std::system_error &exc) {
  641. log::warn("SOCKS connection [", conn.socks_socket.fileno(),"] error: ", exc.what());
  642. send_icmpv6_error(packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
  643. connections.erase(it);
  644. selector.read.remove(sock);
  645. return;
  646. }
  647. sock.set_blocking(false);
  648. // Send SYN packet
  649. IPv6Header &ipv6 = packet.next<IPv6Header>();
  650. TCPHeader &tcp = packet.next<TCPHeader>();
  651. ipv6.source().renumber(transfer_network);
  652. ipv6.destination() = "fe80::1";
  653. tcp.destination_port(tunnel_proxy_port);
  654. tcp.set_checksum(ipv6);
  655. tun.send(buffer);
  656. log::debug("connection [", conn.socks_socket.fileno(),"] accepted");
  657. // Remove from set until client connection is accepted
  658. selector.read.remove(sock);
  659. }
  660. void Tor6TunApplication::on_conn_recv(const ConnKey &key, AsyncSocket &src, AsyncSocket &dst)
  661. {
  662. static thread_local bytevector buffer;
  663. if (src.fileno() == -1 || dst.fileno() == -1) {
  664. return;
  665. }
  666. buffer.reserve(4096);
  667. try {
  668. if (src.recv(buffer)) {
  669. if (dst.send(buffer)) {
  670. dst.flush();
  671. } else {
  672. selector.read.remove(src);
  673. selector.write.add(dst, std::bind(
  674. &Tor6TunApplication::on_conn_send,
  675. this,
  676. std::ref(key),
  677. std::ref(src),
  678. std::ref(dst)
  679. ));
  680. }
  681. }
  682. } catch (connection_closed &) {
  683. selector.read.remove(src);
  684. selector.read.remove(dst);
  685. selector.write.remove(src);
  686. selector.write.remove(dst);
  687. auto it = connections.find(key);
  688. if (it != connections.end())
  689. log::debug("connection [", it->second.socks_socket.fileno(), "] closing");
  690. else
  691. log::debug("connection [?] closing");
  692. src.close();
  693. dst.close();
  694. // Append to closing list
  695. closing.push_back(
  696. std::make_pair(time(nullptr)+10, key)
  697. );
  698. }
  699. }
  700. void Tor6TunApplication::on_conn_send(const ConnKey &key, AsyncSocket &src, AsyncSocket &dst)
  701. {
  702. try {
  703. if (dst.flush()) {
  704. selector.write.remove(dst);
  705. selector.read.add(src, std::bind(
  706. &Tor6TunApplication::on_conn_recv,
  707. this,
  708. std::ref(key),
  709. std::ref(src),
  710. std::ref(dst)
  711. ));
  712. }
  713. } catch (connection_closed &) {
  714. selector.read.remove(src);
  715. selector.read.remove(dst);
  716. selector.write.remove(src);
  717. selector.write.remove(dst);
  718. auto it = connections.find(key);
  719. if (it != connections.end())
  720. log::debug("connection [", it->second.socks_socket.fileno(), "] closing");
  721. else
  722. log::debug("connection [?] closing");
  723. src.close();
  724. dst.close();
  725. // Append to closing list
  726. closing.push_back(
  727. std::make_pair(time(nullptr)+10, key)
  728. );
  729. }
  730. }
  731. void Tor6TunApplication::handle_tun_icmpv6_packet(PacketBufferView packet)
  732. {
  733. PacketBufferView orig_view = packet;
  734. IPv6Header &header = packet.next<IPv6Header>();
  735. ICMPv6Header &icmpv6 = packet.peek<ICMPv6Header>();
  736. // Verify checksum and skip damaged packets
  737. if (!icmpv6.verify_checksum(header))
  738. return;
  739. // Skip error messages and redirects
  740. uint8_t type = icmpv6.type();
  741. if (type < 128 || type == 137)
  742. return;
  743. // Handle other packets
  744. if (type == 133) {
  745. // Send Router Advertisements on Solicitations
  746. time_t current_time = time(nullptr);
  747. if (last_router_adv < current_time) {
  748. send_router_adv();
  749. last_router_adv = current_time;
  750. }
  751. } else if (header.destination().s6_addr[0] != 0xFF) {
  752. // Send error response to non-multicast messages
  753. send_icmpv6_error(orig_view, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT);
  754. }
  755. }
  756. void Tor6TunApplication::send_icmpv6_error(const PacketBufferView old_packet, uint8_t type, uint8_t code, uint32_t data)
  757. {
  758. bytevector buffer;
  759. buffer.resize(std::min(4+40+8+old_packet.size(), static_cast<size_t>(1280u)));
  760. PacketBufferView packet(buffer);
  761. tun_frame_header &tun_header = packet.next<tun_frame_header>();
  762. tun_header.proto = htons(ETH_P_IPV6);
  763. const IPv6Header &old_header = old_packet.peek<IPv6Header>();
  764. IPv6Header &ipv6_header = packet.next<IPv6Header>();
  765. ipv6_header.version(6);
  766. ipv6_header.payload_length(packet.size());
  767. ipv6_header.next_header(IPPROTO_ICMPV6);
  768. ipv6_header.hop_limit(64);
  769. ipv6_header.source() = old_header.destination();
  770. ipv6_header.destination() = old_header.source();
  771. ICMPv6Header &icmpv6_header = packet.next<ICMPv6Header>();
  772. icmpv6_header.type(type);
  773. icmpv6_header.code(code);
  774. packet.next<uint32_t>() = htonl(data);
  775. packet.fill_from(old_packet);
  776. icmpv6_header.set_checksum(ipv6_header);
  777. tun.send(buffer);
  778. }
  779. void Tor6TunApplication::send_tcp_rst(PacketBufferView old_packet)
  780. {
  781. bytevector buffer;
  782. buffer.resize(4+40+20);
  783. PacketBufferView packet(buffer);
  784. tun_frame_header &tun_header = packet.next<tun_frame_header>();
  785. tun_header.proto = htons(ETH_P_IPV6);
  786. const IPv6Header &old_header = old_packet.next<IPv6Header>();
  787. IPv6Header &ipv6_header = packet.next<IPv6Header>();
  788. ipv6_header.version(6);
  789. ipv6_header.payload_length(packet.size());
  790. ipv6_header.next_header(IPPROTO_TCP);
  791. ipv6_header.hop_limit(64);
  792. ipv6_header.source() = old_header.destination();
  793. ipv6_header.destination() = old_header.source();
  794. const TCPHeader &old_tcp = old_packet.next<TCPHeader>();
  795. TCPHeader &tcp = packet.next<TCPHeader>();
  796. tcp.source_port(old_tcp.destination_port());
  797. tcp.destination_port(old_tcp.source_port());
  798. tcp.data_offset(5);
  799. uint32_t seq = old_tcp.ack();
  800. uint32_t ack = old_tcp.seq();
  801. if ((old_tcp.flags() & 0x3F) == 2) { // SYN
  802. ack += 1;
  803. seq = 0;
  804. }
  805. tcp.seq(seq);
  806. tcp.ack(ack);
  807. tcp.flags(4+16);
  808. tcp.set_checksum(ipv6_header);
  809. tun.send(buffer);
  810. }
  811. void Tor6TunApplication::send_router_adv(bool active)
  812. {
  813. bytevector buffer;
  814. buffer.resize(4+40+4+12+32+32+24);
  815. PacketBufferView packet(buffer);
  816. tun_frame_header &tun_header = packet.next<tun_frame_header>();
  817. tun_header.proto = htons(ETH_P_IPV6);
  818. IPv6Header &ipv6_header = packet.next<IPv6Header>();
  819. ipv6_header.version(6);
  820. ipv6_header.payload_length(packet.size());
  821. ipv6_header.next_header(IPPROTO_ICMPV6);
  822. ipv6_header.hop_limit(255);
  823. ipv6_header.source() = "fe90::";
  824. ipv6_header.destination() = "ff02::1";
  825. ICMPv6Header &icmpv6_header = packet.next<ICMPv6Header>();
  826. icmpv6_header.type(134);
  827. icmpv6_header.code(0);
  828. RouterAdvertisementHeader &ra_header = packet.next<RouterAdvertisementHeader>();
  829. ra_header.hop_limit(8);
  830. ra_header.flags(24);
  831. ra_header.router_lifetime(0);
  832. ra_header.reachable_time(0);
  833. ra_header.retrans_timer(0);
  834. NDPrefixInformation &ra_prefix1 = packet.next<NDPrefixInformation>();
  835. ra_prefix1.type(3);
  836. ra_prefix1.length(32);
  837. ra_prefix1.prefix_length(48);
  838. ra_prefix1.flags(active ? 128 : 0);
  839. ra_prefix1.valid_lifetime(active ? 120 : 1);
  840. ra_prefix1.preferred_lifetime(active ? 90 : 0);
  841. ra_prefix1.prefix() = onion_network;
  842. NDPrefixInformation &ra_prefix2 = packet.next<NDPrefixInformation>();
  843. ra_prefix2.type(3);
  844. ra_prefix2.length(32);
  845. ra_prefix2.prefix_length(10);
  846. ra_prefix2.flags(active ? 128 : 0);
  847. ra_prefix2.valid_lifetime(-1);
  848. ra_prefix2.preferred_lifetime(-1);
  849. ra_prefix2.prefix() = "fe80::";
  850. NDRouteInformation &ra_route = packet.next<NDRouteInformation>();
  851. ra_route.type(24);
  852. ra_route.length(24);
  853. ra_route.prefix_length(48);
  854. ra_route.flags(8);
  855. ra_route.route_lifetime(active ? 120 : 0);
  856. ra_route.prefix() = onion_network;
  857. icmpv6_header.set_checksum(ipv6_header);
  858. tun.send(buffer);
  859. }